机器学习之半监督学习

让学习器不依赖外界交互、自动地利用未标记样本来提升学习性能,就是半监督学习(semi-supervised learning)。

1、术语

未标记样本
未标记样本的数据分布与类别标记相联系的假设:
聚类假设 (cluster assumption) ,即假设数据存在簇结构,同一个簇的样本属于同一个类别。
流形假设 (manifold assumption) ,即假设数据分布在一个流形结构上,邻近的样本拥有相似的输出值。
以上本质都是假设:“相似的样本拥有相似的输出”。
生成式方法
生成式方法(generative methods)是直接基于生成式模型的方法。此类方法假设所有数据(无论是否有标记)都是由同一个潜在的模型"生成"的。这个假设使得我们能通过潜在模型的参数将未标记数据与学习目标联系起来,而未标记数据的标记则可看作模型的缺失参数,通常可基于EM 算法进行极大似然估计求解。
半监督SVM
半监督支持向量机(Semi-Supervised Support Vector Machine,简称S3VM) 是支持向量机在半监督学习上的推广,试图找到能将两类有标记样本分开,且穿过数据低密度区域的划分超平面。代表算法:二分类TSVM (Transductive Support VectorMachine)
图半监督学习
基于矩阵运算进行半监督学习算法的推导与分析。
标记传播(label propagation)
半监督聚类
聚类任务中获得的监督信息大致有两种类型

  • 第一种类型是"必连"(must-link) 与"勿连" ( cannot-link) 约束,前者是指样本必属于同一个簇,后者是指样本必不属于同一个簇;代表:约束k 均值(Constrained k-means) 算法。
  • 第二种类型的监督信息则是少量的有标记样本。代表:约束种子k 均值(Constrained Seed k-means) 算法

2、Sklearn代码实现

sklearn库提供了两种标签传播模型: LabelPropagation 和 LabelSpreading ,以及SelfTrainingClassifier类(This class allows a given supervised classifier to function as a semi-supervised classifier, allowing it to learn from unlabeled data)。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.semi_supervised import LabelPropagation


def plot_iris(title, labels):
    """
    绘制散点图
    :param title: 标题
    :param labels: 标记
    :return:
    """
    plt.title(title)
    for i in np.unique(labels):
        # 按簇循环绘制
        x_tmp = x[labels == i]
        # 样本的前两个特征值
        plt.scatter(x_tmp[:, 0], x_tmp[:, 1], marker=markers[i % 4], color=colors[i % 5],
                    alpha=0.6,
                    label='label({})'.format(i))
        # 图例
        plt.legend()


if __name__ == '__main__':
    # 加载数据
    iris = datasets.load_iris()
    # 使用样本的所有特征(4)
    x = iris.data
    y = iris.target
    label_dict = iris.target_names
    feature_dict = iris.feature_names
    print('原始的各簇样本数目')
    print(pd.Series(y).value_counts())

    # Random values in a given shape
    rng = np.random.RandomState(37)
    y_rand = rng.rand(y.shape[0])
    # 根据随机数小于0.2的值,设置未标记样本
    y_20 = np.copy(y)
    y_20[y_rand < 0.2] = -1

    # 标签传播,图半监督学习
    model = LabelPropagation()
    model.fit(x, y_20)
    print('标签传播训练后簇数', len(model.classes_))
    print('标签传播训练后score', model.score(x, y))
    print('训练后的各簇样本数目')
    print(pd.Series(model.transduction_).value_counts())

    # 散点颜色
    colors = ['r', 'b', 'g', 'c', 'm']
    # 散点形状
    markers = ['o', 's', '^', 'x']
    # 画布大小
    fig1 = plt.figure(figsize=(15, 6))
    # 原始数据绘图
    plt.subplot(131)
    plot_iris('IRIS Data Sets', y)
    # 随机设置的未标记样本
    plt.subplot(132)
    plot_iris('IRIS Unlabel Data Sets', y_20)
    # 训练后数据
    plt.subplot(133)
    plot_iris('IRIS Label Propagation', model.transduction_)
    plt.show()

运行结果,如下:
机器学习之半监督学习_第1张图片

机器学习之半监督学习_第2张图片
从散点图可以看出有两个点标记错误(参见红框处),也可以通过得分0.98667计算出。

你可能感兴趣的:(Python,机器学习)