1 引言
各位朋友大家好,欢迎来到月来客栈,我是掌柜空字符。
在上一篇文章中,掌柜介绍了一种基于图结构的标签传播算法(Label Propagation)。标签传播算法的核心思想认为,在样本空间中距离越相近的样本点越有可能具有相同的标签。因此,对于样本空间中的所有样本点,可以通过构建一个有向完全图来表示样本点之间的位置关系,并以此为基础构建一个概率转移矩阵来确定未知标签的所属类别。
在这篇文章我们继续来学习另外一种同样也是基于图结构的标签传播算法(Label Spreading)[1],为了区分两者下文分别用LP和LS来进行指代。从本质上来讲,LP和LS这两种算法在思想上并没有太大的差别,都是基于样本点的空间位置来构造得到概率转移矩阵,然后通过概率转移矩阵用已知标签的样本点来确定未知标签样本点的类别。
同时,对于如何快速入门机器学习可以参考下面这篇文章:
2 标签传播算法
相比较于LP标签传播算法来说,LS算法的改进点表现在两个方面:使用了标准化的拉普拉斯矩阵来作为概率转移矩阵;加入了类似于正则化策略的惩罚参数来增加模型的泛化能力。由于LS算法在思想上与LP算法并没有什么本质区别,下面我们就直接来看LS算法的原理部分。
2.1 算法原理
设为已知标签的数据样本,其中
是样本点对应的标签;同时样本的类别数为
,并且假定所有的类别均出现在
中。继续,设为不含标签的样本点,其中未知,且通常情况下
。此时有
,且
。
首先,我们同样需要先计算任意两个点之间的权重距离,如式
所示
从式
中可以看出,当
时,即同一个样本点之间的权重距离为0,这样处理是为了避免样本点自身权重过大的问题。同时可以知道,
是一个形状为
的对称矩阵。
进一步,根据式
来构造样本点之间概率转移矩阵
其中
为一个对角矩阵,对角线上每个值为权重
中对应行所有所有元素的和,即
。同时,
是标准化后的拉普拉斯矩阵,形状与权重矩阵
相同。
接着,再定义一个形状为
的标签矩阵
,其每一行用于表示每个样本属于各个类别的概率分布。
最后,只需要迭代式
便可以求解得到未知标签样本的预测结果:
其中
,
用来平衡模型在迭代过程中对于初始标签矩阵的依赖程度,
越大则表示模型更加依赖于样本的分布情况(即式
中等式右边的第一项),这样可以一定程度上增强模型的泛化能力。
2.2 示例代码
在sklearn中,我们可以从中来导入标签传播算法模块。接下来,需要构造半监督学习所需要使用到的训练集,即将部分样本的标签置为-1(这是由模型在实现时所确定),代码如下:
在上述代码中,第2-4行是导入原始并进行训练集和测试集的划分;第5-8行则是将训练集中
样本的标签重置为-1,同时也保留了原始重置之前的标签便于后续在训练集上测试模型的效果;第9行是返回最后各个部分的结果。
所有完整代码均可从本仓库获取:https://github.com/moon-hotel/MachineLearningWithMe
进一步,便可以导入进行模型训练和测试,代码如下:
上述代码运行结束后便会得到类似如下所示的结果:
在学会模块的使用后,我们再来对比一下LS和LP算法各自在包含噪音数据上的表现。下面以sklearn中的手写体数据集为例来构造相应的训练和测试样本,代码如下:
在上述代码中,第1-2行是导入手写体数据集和特征标准化模块;第5-8行是导入10个类别的数据集,并将其中
用作训练集;第9-12行是将训练集中
的样本重置为无标签样本;第13-19行则是将训练样本中,有真实标签样本中的替换为随机标签(即制造噪音样本);第20-22行是对训练集和测试集进行标准化处理;第23行是返回最后处理完成的结果。
进一步,可以定义一个函数来对两个模型的结果进行对比,实现代码如下:
在上述代码中,第2行是载入手写体数据集,并将训练集中有标签样本的
设定为随机标签;第3-7行是LP算法分别在训练集和测试集上的表现结果;第9-16行分别是LS算法在训练集和测试集上的结果,同时这里使用了网格搜索与交叉验证来寻找超参数
(这部分内容可以参考文章K近邻算法与原理第5.3.2节内容)。在上述代码中运行结束后便会得到类似如下所示的结果:
从上述结果可以看出,无论是在训练集上还是测试集上LS算法的表现结果都要明显好于LP算法。同时,经过网格搜索后可知,当
时模型的效果最优。
3 从零实现标签传播算法
在介绍完LS算法的基本原理后,我们再来看看如何从零实现。由于LS算法和LP算法在整个梳理逻辑上非常类似,所以只需要在LP算法的实现上稍作改动即可。
3.1 迭代法实现
同时LP算法一样,LS算法既可以通过以迭代的方式来求解标签矩阵,也可以直接通过收敛后的计算公式来求解。下面,开始对迭代法的实现过程进行介绍。
核函数实现
首先,根据式
可知需要先定义一个函数来求解样本点之间的权重值,在sklearn实现中称之为核函数,实现代码如下:
在上述代码中,第1行是导入模块来快速实现样本点之间距离的计算;第3-4行判断是否为空,如果为空则取特征维度数的倒数;第5-7行是根据式
来计算权重矩阵,其中等价于。由于
是一个常数,因此在实现过程中可以直接将其视为一个参数。
概率转移矩阵实现
在实现权重矩阵的计算之后,我们便可以定义一个类来构建完整的算法模型。首先实现概率转移矩阵的计算过程,代码如下:
在上述代码中,第2-7行是定义模型的4个基本参数;第9-10行是返回构造完成的权重矩阵,需要注意的是这里的不是指的训练标签而是另外一个矩阵,当为时(即模型训练时)计算的是训练样本中各个样本点两两之间的权重距离,当不为时(即模型预测时)计算的是训练中各个样本与测试样本中各个样本之间的权重距离;第12-17行是根据返回的权重矩阵通过式
计算得到概率转移矩阵(拉普拉斯矩阵
)。
模型拟合实现
在构建完成概率转移矩阵后,我们便可以根据式
来迭代完成标签矩阵的计算过程,实现代码如下:
在上述代码中,第1行表示训练样本形状为,表示训练标签形状为,同时未知标签样本的标签需要用进行标识;第2-3行是得到概率转移矩阵,形状为;第4-6行用于得到标签类别的取值情况以及样本数;第10-12行是初始化标签矩阵用来记录训练集中每个样本的类别所属概率,然后再在已知的标签中把对应类别置为1,最后会得到类似下面这样一个矩阵:
其中全0表示该样本没有标签。
第14-15行是计算式
中的第2项;第16-28行是根据式
迭代计算标签矩阵,其中第17-18行判断误差是否小于阈值,满足条件则退出迭代;第20-21行是完成一次式
的计算过程。第25-27行是对最后的标签矩阵进行标准化,其中第29行为平滑处理;第28行则是得到训练集中每个样本对应的标签。
模型预测实现
在完成模型拟合的代码实现后,我们便可以来预测新样本的所属类别,实现代码如下:
在上述代码中,第1行是待预测的样本,形状为;第2行是计算训练样本到预测样本的权重距离,其形状为;第3-6行则是计算测试数据中每个样本点所属类别的概率值,同时由于第2行中计算的训练样本点到测试样本点的单向权重距离,并不是所有样本点两两之间的权重距离,因此并不需要计算概率转移矩阵;第7行是返回计算后的概率值。
这里值得一提的是,因为在训练过程训练集中既含有已知标签的样本也含有未知标签的样本,因此是通过来建立各个样本点之间的权重距离;而在测试时训练集中的所有样本均已知标签,因此是通过来建立各个样本点(已知标签和未知标签样本点)之间的权重距离。
所有完整代码均可从本仓库获取:https://github.com/moon-hotel/MachineLearningWithMe
最后,只需要再定义一个预测函数来取中最大值对应的标签即可,实现代码如下:
在实现完整个模型之后,可以通过如下方式进行使用:
上述代码运行结束可以得到类似如下所示的结果:
3.2 收敛性证明
在介绍完LS算法的实现过程后,我们再来简单看一下为什么算法多次迭代后便会收敛结论。根据式
可知,此时有
进一步可得
又因为
所以有
因此
由于对于分类任务来说,
表示的样本所属类别的概率分布,所以式
还可以等价写为
也就是说,式
的整个迭代过程将会等价地收敛域式
中的结果,因此在实现LS算法时还可以通过式
来直接计算得到标签概率矩阵。
接着再来看式
中极限结果的证明,此时有
最终,根据式
便可以得到式
所示的结果。
4 总结
在这篇文章,掌柜延续上一篇文章的内容介绍了同样是基于图结构的标签传播算法(Label Spreading)。首先介绍了LS算法的基本原理以及其在sklearn中的使用示例;然后通过手写体分类对比实验验证了LS算法在泛化能力上优于LP算法;最后,掌柜进一步详细地介绍了如何从零开始实现LS标签传播算法以及其收敛性证明。
领取专属 10元无门槛券
私享最新 技术干货