笔者结合机器学习过程中利用MATLAB编程所实现的一些算法来对一些常见算法进行了函数封装便于初学人士进行参考和利用,这里简要介绍算法的概念和主要方法,适用于初学者去理解算法!注意!是理解算法,本文主要以例子来讲述算法,更加注重实际应用。更加详细算法的实现请见其他博客。
一、ML-KNN算法
算法概要介绍。
多标签学习算法是基于KNN算法的一种改进算法,这里大概介绍一下ML—KNN算法的实现过程,结合一种例子方便不了解的人士来学习,直接上例子,便于大家去理解,
问题引出 先给出一列三维样本特征及其三维坐标点
序号 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
样本 | x ( 1 ) x(1) x(1) | x ( 2 ) x(2) x(2) | x ( 3 ) x(3) x(3) | x ( 4 ) x(4) x(4) | x ( 5 ) x(5) x(5) | x ( 6 ) x(6) x(6) |
样本特征 | 1 | 0 | 0 | 1 | 1 | 0 |
样本坐标 | (0,1,1) | (1,0,1) | (0,0,0) | (1,1,1) | (1,0,0) | (0,0,1) |
下面请读者思考以下问题:给你一个样本x(7),它的坐标是(1,0,2)请问它属于那个样本特征里面呢?
显然这个问题我们可以通过经典的K近邻算法来实现的,但是这样势必不是一个完美的办法,在K近邻基础上产生了更加高端的方法——MLKNN算法。直接进入正题。
ML-KNN解决该算法的步骤
①首先去求先验概率,即标签集合中特征为
t
t
t的概率有多大,这里我们的例子里面
t
t
t只可能取0和1,假定用n代表我们的样本数量有多少,我们计算先验概率的公式如下:
P
(
t
)
=
∑
i
=
1
n
I
(
x
i
=
t
)
+
s
n
+
2
s
P(t)={\sum_{i=1}^nI(x_i=t)+s\over n+2s}
P(t)=n+2s∑i=1nI(xi=t)+s
其中,
∑
i
=
1
n
I
(
x
i
=
t
)
\sum_{i=1}^nI(x_i=t)
∑i=1nI(xi=t)代表所有样本中有多少个样本特征是
t
t
t的个数。
s
s
s为平滑系数,一般取为1。
例如本题中:
P
(
t
=
1
)
=
∑
i
=
1
n
I
(
x
i
=
t
)
+
s
n
+
2
s
=
3
+
1
6
+
2
=
1
2
P(t=1)={\sum_{i=1}^nI(x_i=t)+s\over n+2s}={3+1\over 6+2}={1\over 2}
P(t=1)=n+2s∑i=1nI(xi=t)+s=6+23+1=21
P
(
t
=
0
)
=
∑
i
=
1
n
I
(
x
i
=
t
)
+
s
n
+
2
s
=
3
+
1
6
+
2
=
1
2
P(t=0)={\sum_{i=1}^nI(x_i=t)+s\over n+2s}={3+1\over 6+2}={1\over 2}
P(t=0)=n+2s∑i=1nI(xi=t)+s=6+23+1=21
②分类并寻找K近邻,我们需要手动设置K值是多少,换而言之,如果我们设置K=2,那么我们需要找到每个样本的2个最近点是什么,如果设置K=3那么我们需要找到每个样本的3个最近点都是什么,这里的每个样本是指分类之后的样本?那么会有人问了,什么叫做分类样本?分类就是指的是按照样本特征分类的样本。如本题就将样本分成了两类——1和0两类,其中:
样本特征为1的样本是:
x
(
1
)
,
x
(
4
)
,
x
(
5
)
x(1),x(4),x(5)
x(1),x(4),x(5)。特征为1的总数
n
1
n_1
n1=3
样本特征为0的样本是:
x
(
2
)
,
x
(
3
)
,
x
(
6
)
x(2),x(3),x(6)
x(2),x(3),x(6)。特征为2的总数
n
2
n_2
n2=3
接下来就要找他们的K近邻样本都是什么了,这K近邻指的是距离最近,即各类样本距离最近的都是谁?并把他们的样本特征合起来存储起来这样能够通俗的理解了。
根据题意不难理解不同特征的样本他们对应的最近分别是谁了。我们规定K=2.
首先是特征为1的样本类别:
x
(
1
)
x(1)
x(1):
x
(
4
)
x(4)
x(4),
x
(
6
)
x(6)
x(6)
⟶
\longrightarrow
⟶对应特征分别为1和0
⟶
\longrightarrow
⟶样本特征和为1
x
(
4
)
x(4)
x(4):
x
(
1
)
x(1)
x(1),
x
(
2
)
x(2)
x(2)
⟶
\longrightarrow
⟶对应特征分别为1和0
⟶
\longrightarrow
⟶样本特征和为1
x
(
5
)
x(5)
x(5):
x
(
2
)
x(2)
x(2),
x
(
3
)
x(3)
x(3)
⟶
\longrightarrow
⟶对应特征分别为0和0
⟶
\longrightarrow
⟶样本特征和为0
接下来是特征为0的样本类别:
x
(
2
)
x(2)
x(2):
x
(
4
)
x(4)
x(4),
x
(
5
)
x(5)
x(5)
⟶
\longrightarrow
⟶对应特征分别为1和1
⟶
\longrightarrow
⟶样本特征和为2
x
(
3
)
x(3)
x(3):
x
(
5
)
x(5)
x(5),
x
(
6
)
x(6)
x(6)
⟶
\longrightarrow
⟶对应特征分别为1和0
⟶
\longrightarrow
⟶样本特征和为1
x
(
6
)
x(6)
x(6):
x
(
1
)
x(1)
x(1),
x
(
2
)
x(2)
x(2)
⟶
\longrightarrow
⟶对应特征分别为1和0
⟶
\longrightarrow
⟶样本特征和为1
对于类别为1的样本,特征和为1出现了2次,特征和为0出现了一次
对于类别为0的样本,特征和为1出现了2次,特征和为2出现了一次
设为用
C
C
C和
C
′
C'
C′来分别表示两个类别对应样本数量
C
[
0
]
C[0]
C[0]=1,
C
[
1
]
C[1]
C[1]=2,
C
[
2
]
C[2]
C[2]=0
C
′
[
0
]
C'[0]
C′[0]=0,
C
′
[
1
]
C'[1]
C′[1]=2,
C
′
[
2
]
C'[2]
C′[2]=1,
③接下来找到我们所要求的样本点的K个近邻,我们要求的样本点是:
x
(
7
)
x(7)
x(7),它的坐标是(1,0,2)那么它的K近邻是
x
(
7
)
x(7)
x(7):
x
(
2
)
x(2)
x(2),
x
(
6
)
x(6)
x(6)
⟶
\longrightarrow
⟶对应特征分别为0和0
⟶
\longrightarrow
⟶样本特征和为0。一般的,设它的样本之和为
Q
Q
Q
由Bayes公式,计算概率公式如下:
P
(
认
为
该
样
本
特
征
为
=
1
)
=
C
[
Q
]
+
s
n
1
+
(
K
+
1
)
s
P
(
t
=
1
)
P(认为该样本特征为=1)={C[Q]+s\over n_1+(K+1)s}P(t=1)
P(认为该样本特征为=1)=n1+(K+1)sC[Q]+sP(t=1)
P
(
认
为
该
样
本
特
征
为
=
0
)
=
C
′
[
Q
]
+
s
n
2
+
(
K
+
1
)
s
P
(
t
=
0
)
P(认为该样本特征为=0)={C'[Q]+s\over n_2+(K+1)s}P(t=0)
P(认为该样本特征为=0)=n2+(K+1)sC′[Q]+sP(t=0)
那么我们可以知道针对本题而言:
P
(
认
为
该
样
本
特
征
为
=
1
)
=
1
+
1
3
+
(
2
+
1
)
P
(
t
=
1
)
=
1
6
P(认为该样本特征为=1)={1+1\over 3+(2+1)}P(t=1)={1\over6}
P(认为该样本特征为=1)=3+(2+1)1+1P(t=1)=61
P
(
认
为
该
样
本
特
征
为
=
0
)
=
0
+
1
3
+
(
2
+
1
)
P
(
t
=
0
)
=
1
12
P(认为该样本特征为=0)={0+1\over 3+(2+1)}P(t=0)={1\over12}
P(认为该样本特征为=0)=3+(2+1)0+1P(t=0)=121
那么我们更应该认为样本特征是1的可能性更大。
这样大家就会算了吧!下面附上MATLAB实例代码大家供大家参考
笔者已经验证过准确性和正确性了。
MATLAB代码实例:
function [P1,P2,C,C1] = ML_KNN(A,B,K,S,I,T)
%A是特征矩阵,按行存储坐标信息,B是标签矩阵,按行存储每个个体标签信息
%K为选择K邻近样本,S为平滑系数,I为待预测的T的第I个特征
%T为待测样本特征,列数一定要与A相同。
[length1,length2]=size(A)%用于存储A,B的行和列,length1代表训练样本的总数量
sum1=0;%计数器1,用于存储哪些是标签1的样本
sum2=0;%计数器2,用于存储哪些是标签0的样本
Matrix1=[];%%用于存储第I标签值为1的向量
Matrix2=[];%%用于存储第I标签值为0的向量
for range1=1:1:length1
if(B(range1,I)==1)
sum1=sum1+1;
Matrix1(sum1,:)=A(range1,:);
else
sum2=sum2+1;
Matrix2(sum2,:)=A(range1,:);
end
end
H_1_1=((S+sum1)/(2*S+length1));
H_0_1=1-H_1_1;
C=[];C1=[];
C=(0:1:K);C1=(0:1:K)%最后用于算的矩阵,必须保证大小为K个
C(2,1:1:K+1)=0;C1(2,1:1:K+1)=0;
for range2=1:1:sum1%先从Matrix1算起
distance=[]
for range3=1:1:length1
if(norm(Matrix1(range2,:)-A(range3,:))==0)
distance(1,range3)=9999999;%为了保证不出现这个排序进去
else
distance(1,range3)=norm(Matrix1(range2,:)-A(range3,:));
end
end
summer=0;%暂存变量,存储1的个数用的
for range4=1:1:K
[p,q]=min(distance);%找那个最小的和它的位置
if(B(q,I)==1)
summer=summer+1;
end
distance(q)=9999999;
end
C(2,summer+1)=C(2,summer+1)+1;%对应的C[i]增加一个。
end
for range5=1:1:sum2
distance=[]
for range6=1:1:length1
if(norm(Matrix2(range5,:)-A(range6,:))==0)
distance(1,range6)=9999999;%为了保证不出现这个排序进去
else
distance(1,range6)=norm(Matrix2(range5,:)-A(range6,:));
end
end
summer2=0;%暂存变量,存储1的个数用的
for range7=1:1:K
[p,q]=min(distance);%找那个最小的和它的位置
if(B(q,I)==1)
summer2=summer2+1;
end
distance(q)=9999999;
end
C1(2,summer2+1)=C1(2,summer2+1)+1;%对应的C1[i]增加一个。
end
distance1=[];
for range8=1:1:length1
distance1(1,range8)=norm(A(range8,:)-T);
end
summer1=0;%暂存变量,存储1的个数用的
for range9=1:1:K
[p,q]=min(distance1);
if(B(q,I)==1)
summer1=summer1+1;
end
distance1(q)=9999999;
end
P1=((C(2,summer1+1)+S)/(sum1+(S*(K+1))))*H_1_1;
P2=((C1(2,summer1+1)+S)/(sum2+(S*(K+1))))*H_0_1;
end
希望大家支持!笔者在此深表感谢,如有不对之处恳请各位读者批评指正!