本周学习了第九章
监督学习和非监督学习
机器学习的常用方法,主要分为有监督学习(supervised learning)和无监督学习(unsupervised learning)。
监督学习
监督学习,就是人们常说的分类,通过已有的训练样本(即已知数据以及其对应的输出)去训练得到一个最优模型(这个模型属于某个函数的集合,最优则表示在某个评价准则下是最佳的),再利用这个模型将所有的输入映射为相应的输出,对输出进行简单的判断从而实现分类的目的,也就具有了对未知数据进行分类的能力。在人对事物的认识中,我们从孩子开始就被大人们教授这是鸟啊、那是猪啊、那是房子啊,等等。我们所见到的景物就是输入数据,而大人们对这些景物的判断结果(是房子还是鸟啊)就是相应的输出。当我们见识多了以后,脑子里就慢慢地得到了一些泛化的模型,这就是训练得到的那个(或者那些)函数,从而不需要大人在旁边指点的时候,我们也能分辨的出来哪些是房子,哪些是鸟。
监督学习里典型的例子就是KNN、SVM。
无监督学习
无监督学习(也有人叫非监督学习,反正都差不多)则是另一种研究的比较多的学习方法,它与监督学习的不同之处,在于我们事先没有任何训练样本,而需要直接对数据进行建模。这听起来似乎有点不可思议,但是在我们自身认识世界的过程中很多处都用到了无监督学习。比如我们去参观一个画展,我们完全对艺术一无所知,但是欣赏完多幅作品之后,我们也能把它们分成不同的派别(比如哪些更朦胧一点,哪些更写实一些,即使我们不知道什么叫做朦胧派,什么叫做写实派,但是至少我们能把他们分为两个类)。无监督学习里典型的例子就是聚类了。聚类的目的在于把相似的东西聚在一起,而我们并不关心这一类是什么。因此,一个聚类算法通常只需要知道如何计算相似度就可以开始工作了。
聚类任务
聚类:将数据集中的样本划分成不相交的子集。每个子集称为一个“簇”(cluster)。通过这样的划分,每个簇可能对应与一些潜在的概念(类别)。这些概念对聚类算法而言事先是未知的,聚类过程仅能自动形成簇结构。聚类既能作为一个单独的过程,用于寻找数据内在的分布结构,也可作为分类等其它学习任务的前驱过程。
簇:一个子集。
聚类由使用者定义,自动形成簇结构。
簇的结果用簇标记向量λ=(λ1;λ2;...;λm)。
聚类算法,不是分类算法。
分类算法是给一个数据,然后判断这个数据属于已分好的类中的具体哪一类。
聚类算法是给一大堆原始数据,然后通过算法将其中具有相似特征的数据聚为一类。
K-means算法
这里的k-means聚类,是事先给出原始数据所含的类数,然后将含有相似特征的数据聚为一个类中。
首先给出原始数据{x1,x2,...,xn},这些数据没有被标记的。
初始化k个随机数据u1,u2,...,uk。这些xn和uk都是向量。
根据下面两个公式迭代就能求出最终所有的u,这些u就是最终所有类的中心位置。
公式一:
意思就是求出所有数据和初始化的随机数据的距离,然后找出距离每个初始数据最近的数据。
公式二:
意思就是求出所有和这个初始数据最近原始数据的距离的均值。
然后不断迭代两个公式,直到所有的u都不怎么变化了,就算完成了。
步骤
代码
clear all;
close all;
clc;
%第一类数据
mu1=[0 0 0]; %均值
S1=[0.3 0 0;0 0.35 0;0 0 0.3]; %协方差
data1=mvnrnd(mu1,S1,100); %产生高斯分布数据
%%第二类数据
mu2=[1.25 1.25 1.25];
S2=[0.3 0 0;0 0.35 0;0 0 0.3];
data2=mvnrnd(mu2,S2,100);
%第三个类数据
mu3=[-1.25 1.25 -1.25];
S3=[0.3 0 0;0 0.35 0;0 0 0.3];
data3=mvnrnd(mu3,S3,100);
%显示数据
plot3(data1(:,1),data1(:,2),data1(:,3),'+');
hold on;
plot3(data2(:,1),data2(:,2),data2(:,3),'r+');
plot3(data3(:,1),data3(:,2),data3(:,3),'g+');
grid on;
%三类数据合成一个不带标号的数据类
data=[data1;data2;data3]; %这里的data是不带标号的
%k-means聚类
[u re]=KMeans(data,3); %最后产生带标号的数据,标号在所有数据的最后,意思就是数据再加一维度
[m n]=size(re);
KMeans.m
%N是数据一共分多少类
%data是输入的不带分类标号的数据
%u是每一类的中心
%re是返回的带分类标号的数据
function [u re]=KMeans(data,N)
[m n]=size(data); %m是数据个数,n是数据维数
ma=zeros(n); %每一维最大的数
mi=zeros(n); %每一维最小的数
u=zeros(N,n); %随机初始化,最终迭代到每一类的中心位置
for i=1:n
ma(i)=max(data(:,i)); %每一维最大的数
mi(i)=min(data(:,i)); %每一维最小的数
for j=1:N
u(j,i)=ma(i)+(mi(i)-ma(i))*rand(); %随机初始化,不过还是在每一维[min,max]中初始化好些
end
end
while 1
pre_u=u; %上一次求得的中心位置
for i=1:N
tmp{i}=[]; % 公式一中的x(i)-uj,为公式一实现做准备
for j=1:m
tmp{i}=[tmp{i};data(j,:)-u(i,:)];
end
end
quan=zeros(m,N);
for i=1:m %公式一的实现
c=[];
for j=1:N
c=[c norm(tmp{j}(i,:))];
end
[junk index]=min(c);
quan(i,index)=norm(tmp{index}(i,:));
end
for i=1:N %公式二的实现
for j=1:n
u(i,j)=sum(quan(:,i).*data(:,j))/sum(quan(:,i));
end
end
if norm(pre_u-u)<0.1 %不断迭代直到位置不再变化
break;
end
end
re=[];
for i=1:m
tmp=[];
for j=1:N
tmp=[tmp norm(data(i,:)-u(j,:))];
end
[junk index]=min(tmp);
re=[re;data(i,:) index];
end
end
距离计算
“距离度量”:满足 非负性,同一性,对称性,直递性。
常用“闵可夫斯基距离”
属性划分:
有序:可以直接在属性值上计算距离
使用闵科夫斯基距离
无序:不能直接在属性值上计算距离
使用VDM距离
“非量度距离”:不满足直递性
学习向量量化LVQ
LVQ假设样本带有类别标记
高斯混合聚类
密度聚类
DBSCN算法
层次聚类
在不同层次对数据集进行划分,从而形成树形聚类结构。
划分采用:
“自底向上”聚合策略
“自顶向下”拆分策略
MATLAB中提供了cluster, clusterdata, cophenet, inconsistent等相关函数。
cluster用于剪裁完全版的聚类树,产生具有一定cutoff的可用于参考的树。
clusterdata可以认为是pdist,linkage,cluster的综合,当然更简易一点。
cophenet和inconsistent用来计算某些系数,前者用于检验一定算法下产生的二叉聚类树和实际
情况的相符程度(就是检测二叉聚类树中各元素间的距离和pdist计算产生的实际的距离之间有
多大的相关性),inconsistent则是量化某个层次的聚类上的节点间的差异性(可用于作为cluster的剪裁标准)。
Y=pdist(X,’metric’)
用 ‘metric’指定的方法计算 X 数据矩阵中对象之间的距离。
X:一个m×n的矩阵,它是由m个对象组成的数据集,每个对象的大小为n。
metric’取值如下:
‘euclidean’:欧氏距离(默认);
‘seuclidean’:标准化欧氏距离;
‘mahalanobis’:马氏距离;
‘cityblock’:布洛克距离;
‘minkowski’:明可夫斯基距离;
‘cosine’:
‘correlation’:
‘hamming’:
‘jaccard’:
‘chebychev’:Chebychev距离。
Z=linkage(Y,’method’)
用‘method’参数指定的算法计算系统聚类树。
Y:pdist函数返回的距离向量;
method:可取值如下:
‘single’:最短距离法(默认);
‘complete’:最长距离法;
‘average’:未加权平均距离法;
‘weighted’: 加权平均法;
‘centroid’: 质心距离法;
‘median’:加权质心距离法;
‘ward’:内平方距离法(最小方差算法)
返回:Z为一个包含聚类树信息的(m-1)×3的矩阵。
[H,T,…]=dendrogram(Z,p,…)
生成只有顶部p个节点的冰柱图(谱系图)。
c = cluster( HC,'maxclust', Ncluster );
输入参数Z是由linkage 函数创建的系统聚类树
clear all
clc
close all
[m,n]=textread('data.txt','%f%f',100);
xx=[m,n];
%二维的坐标,第一列为x轴坐标,第二列为y轴坐标
%获取数据的个数存至number
[number, row]=size(xx);
%获取距离矩阵,第二参数指定距离计算方法
%可选参数有'euclidean':欧氏距离(默认);'seuclidean':标准化欧氏距离;
%'mahalanobis':马氏距离;'cityblock':布洛克距离;'minkowski':明可夫斯基距离;
%'cosine':余弦距离 'correlation':相关性 'hamming':汉明距离 'jaccard':Jaccard相似度
%'chebychev':Chebychev距离。
yy=pdist(xx,'euclidean');
%获取聚类,第二参数指定层次聚类方式
%'single':单连通,最短距离法(默认);'complete':全连通,最长距离法;'average':未加权平均距离法;
%'weighted': 加权平均法;'centroid': 质心距离法;'median':加权质心距离法;'ward':内平方距离法(最小方差算法)
zz=linkage(yy,'single');
%指定获取簇类个数
Ncluster=input('输入类个数
');
%获取指定Ncluster个数的聚类结果
c = cluster( zz,'maxclust', Ncluster );
%获取绘图所需颜色
%需要用到linspecer.m文件
if(Ncluster>12)
Color = linspecer( Ncluster );
else
%lineStyles = linspecer(N,'qualitative');强制颜色都可以区分(最多12个)
Color = linspecer( Ncluster, 'qualitative' );
end
for i=1:Ncluster
for j = 1:number
if(c(j) == i)
hold on
plot(xx(j,1),xx(j,2),'o','color',Color(i,:))
end
end
end
c=cophenetic(Z,Y)
利用pdist函数生成的Y和linkage函数生成的Z计算cophenet相关系数。
%用pdist函数计算相似矩阵,有多种方法可以计算距离,进行计算之前最好先将数据用zscore函数进行标准化。
X=randn(6,2);
X2=zscore(X); %标准化数据
Y2=pdist(X2); %计算距离
%pdist之后的Y是一个行向量,15个元素分别代表X的第1点与2-6
点、第2点与3-6点,......这样的距离。
% squareform(Y2)函数可转成矩阵
Z2=linkage(Y2);
%评价聚类信息
C2=cophenet(Z2,Y2); %0.94698
%创建聚类,并作出谱系图
T=cluster(Z2,6);
H=dendrogram(Z2);
T=clusterdata(X,…)
利用 clusterdata函数对样本数据进行一次聚类,其缺点为可供用户选择的面较窄,不能更改距离的计算方法
说明:根据数据创建分类。
T=clusterdata(X,cutoff)与下面的一组命令等价:
Y=pdist(X,’euclid’);
Z=linkage(Y,’single’);
T=cluster(Z,cutoff);
X=[ 1.1978 5.7500
0.0013 0.0068
0.0094 0.0238
3.1908 1.5900];
T=clusterdata(X,0.5)
自底向上聚合的AGNES算法
补充
z = mvnrnd(mu,sigma,n);
z = mvnrnd(mu,sigma,n)
产生多维正态随机数,mu为期望向量,sigma为协方差矩阵,n为规模。
Mu = [0 0]';%均值,也就是数据的中心,控制生成点的总体位置
Sigma = eye(2)*0.1;%协方差矩阵,控制总体形状。方差为0.1,Sigma必定对称正定
p = mvnrnd(Mu,Sigma,2500);%生成2500个点
plot(p(:,1),p(:,2),'b.',Mu(1),Mu(2),'r*','MarkerSize',4);
注意:根据实际情况调整Mu和Sigma可控制生成点的总体位置及形状。
3维和多维的类似。
matlab中() [] {} 区别
[]中括号用来构建向量(Vectors)或者是矩阵(Matrices)。如[6.9 9.64 sqrt(-1)] 就是一个有三个元素的向量。[11 12 13; 21 22 23] 是一个二乘三的矩阵。分号(;)用来结束一行。中括号的另一个作用是在函数中,分配输出参数。
{}大括号,用于cell型的数组的分配或引用。比如 A(2,1) = {[1 2 3; 4 5 6]}, or A{2,2} = ('str')。
()小括号,用于引用数组的元素。如 X(3)就是X的第三个元素。 X([1 2 3])就是X的头三个元素。
Expmple:
A = [ 1 2 3 ]
%A就是一个三个元素的数值数组。中括号用于构建非cell数组。
%数组的引用用小括号
A(1,2)
%A(1,2)得到A数组第一行第二列的元素。
B = {A A}
%B为1一行两列的数组,数组的元素为cell
%数组的引用依然用小括号
B(1)
%这时B(1)为一个cell,cell内容的引用需要用大括号。
%B{1}则为cell 1的内容,此时为 1 2 3,cell内容为数值数组的,继续用小括号引用其内容
B{1}(1,3)
%B{1}(1,3)的内容为3.
D={B B}
D =
{1x2 cell} {1x2 cell}
此时D的某个元素内容的引用则为
D{1}{1,2}(1)
cell层都需要用大括号引用。