半监督学习

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录


介绍

半监督学习(Semi-Supervised Learning,SSL)是机器学习领域中的一个重要分支,它结合了监督学习和无监督学习的思想,用于处理标签数据稀缺而无标签数据丰富的场景。

常用方法:

  • Self Training自训练
  • Label Propagation标签传播
  • Label Spreading标签扩散

一、Self Training自训练

1、介绍

Self Training自训练是一种简单的半监督学习方法,它首先使用已标记的数据训练一个监督学习模型。然后,该模型用于预测未标记数据的标签。预测最自信的标签可以被选择添加到训练集中,然后模型在新的、更大的训练集上重新训练。先训练一个小模型,再继续预测标签,类似于迁移学习。当无标签数据和有标签数据分布相同时,使用自训练方法效果最佳。

2、代码示例

  • 读入数据

    from IPython.core.interactiveshell import InteractiveShell
    InteractiveShell.ast_node_interactivity = "all"

    import numpy as np
    import pandas as pd
    import warnings
    warnings.filterwarnings("ignore")

    数据预处理计算函数

    def preprocessing(df):
    from sklearn.impute import SimpleImputer
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import OrdinalEncoder
    from sklearn.compose import ColumnTransformer

      cat_cols= df.select_dtypes(include=["object"])   # 分类型变量
      num_cols= df.select_dtypes(include=["int", "float"])   # 数值型变量
    
      # 连续型数据
      num_imp= SimpleImputer(strategy='mean')  # 缺失值
      num_std= StandardScaler()  # 标准化
      num_pipeline= Pipeline(steps=[("num_imp", num_imp), ("num_std", num_std)])
      # 分类型数据
      cat_imp= SimpleImputer(strategy="most_frequent")  # 缺失值
      cat_encode= OrdinalEncoder()   # 数据编码
      cat_pipeline= Pipeline(steps=[("cat_imp", cat_imp), ("cat_encode", cat_encode)])
    
      col_trans= ColumnTransformer(transformers=[("num_pipeline", num_pipeline, num_cols.columns),
                                             ("cat_pipeline", cat_pipeline, cat_cols.columns),])
      # 数据集处理的计算
      transfer= col_trans.fit(df)
      return transfer
    

    读入数据

    raw_data= pd.read_csv('半监督学习.csv')
    labels= raw_data.pop("resp_flag") # 标签

  • 缺失数据对比

    print("缺失值/总样本:"+str(labels.isnull().sum())+"/"+str(len(labels)))

  • 数据处理
    注意:切分的测试数据集一定是有标签的样本

    sklearn中的半监督学习算法要求,所有缺失的标签必须用-1填充

    labels_fill= labels.fillna(-1)

    特征数据处理

    transfer= preprocessing(raw_data)
    data_trans= transfer.transform(raw_data)

    data_concat= pd.concat([labels_fill, pd.DataFrame(data_trans)], axis= 1)

    保存一部分有标签样本作为测试集

    mask_labeled= (labels_fill != -1)
    mask_unlabeled= (labels_fill == -1)

    data_labeled= data_concat[mask_labeled]
    data_unlabeled= data_concat[mask_unlabeled]

    切分测试集

    from sklearn.model_selection import train_test_split
    train, test= train_test_split(data_labeled, test_size=0.2, stratify= data_labeled["resp_flag"], random_state= 42)

    Xtrain= pd.concat([train, data_unlabeled])
    Ytrain= Xtrain.pop("resp_flag")

  • 使用模型

    from sklearn.ensemble import RandomForestClassifier
    RF= RandomForestClassifier(oob_score=True)

    Self Training

    from sklearn.semi_supervised import SelfTrainingClassifier
    RF_self_training= SelfTrainingClassifier(RF)
    RF_self_training.fit(Xtrain, Ytrain)

    测试集模型评估

    Xtest= test
    Ytest= Xtest.pop("resp_flag")

    from sklearn.metrics import roc_auc_score
    print("AUC: ", roc_auc_score(Ytest, RF_self_training.predict_proba(Xtest)[:, 1]))

3、参数解释

base_estimator: BaseEstimator,# 基学习器
threshold: Float = 0.75,# 默认阈值0.75,大于0.75,小于0.25会被打标签,该参数比k_best更为常用
criterion: Literal['threshold', 'k_best'] = "threshold",# 默认值threshold,为该值时和threshold参数相同,即设阈值,k_best超参数阈值,如为10,则不考虑预测概率,只取排名前10的打标签
k_best: Int = 10,# 超参数阈值,如为10,则不考虑预测概率,只取排名前10的打标签
max_iter: int | None = 10,# 最大迭代次数
verbose: bool = False

二、Label Propagation(标签传播)

在sklearn中,基于图算法的半监督学习有Label Propagation和Label Spreading两种。他们的主要区别是第二种方法带有正则化机制。

1、介绍

Label Propagation(标签传播)基本原理:Label Propagation算法基于图理论。算法首先构建一个图,其中每个节点代表一个数据点,无论是标记的还是未标记的。节点之间的边代表数据点之间的相似性。算法的目的是通过图传播标签信息,使未标记数据获得标签。

关键特点:

相似性度量:通常使用K近邻(KNN)或者基于核的方法来定义数据点之间的相似性。

标签传播:标签信息从标记数据点传播到未标记数据点,通过迭代过程实现。

适用场景:适合于数据量较大、标记数据稀缺的情况。

  • 以环形数据为例,绿色全是为打标签的数据:

    打标签后数据结果如图:

    from sklearn.semi_supervised import LabelPropagation

    label_propagation = LabelPropagation(kernel="knn")
    label_propagation.fit(X, labels)

    output= np.asarray(label_propagation.transduction_)
    outer_numbers = np.where(output == outer)[0]
    inner_numbers = np.where(output == inner)[0]

    plt.figure(figsize=(4, 4))
    plt.scatter(X[outer_numbers, 0], X[outer_numbers, 1],)
    plt.scatter(X[inner_numbers, 0], X[inner_numbers, 1],);

2、代码示例

from sklearn.semi_supervised import LabelPropagation

label_propagation = LabelPropagation(kernel="knn")
label_propagation.fit(Xtrain, Ytrain)

Ytrain_propagation= label_propagation.transduction_

from sklearn.ensemble import RandomForestClassifier
RF_propagation= RandomForestClassifier(oob_score=True)
RF_propagation.fit(Xtrain, Ytrain_propagation)

print("AUC: ", roc_auc_score(Ytest, RF_propagation.predict_proba(Xtest)[:, 1]))

3、参数解释

    kernel: ((...) -> Any) | Literal['knn', 'rbf'] = "rbf",# knn:k近邻,RBF核用于计算图中节点之间的相似度。这些相似度值随后用于传播标签信息,从而根据相邻节点的标签来预测未知节点的标签,rbf函数和正态分布比较相似
    *,
    gamma: Float = 20, # rbf函数的系数,可以简单理解为正态分布的方差
    n_neighbors: Int = 7, # 附近的7个样本,哪个样本多,就打成哪个标签,为knn时生效
    max_iter: Int = 1000,# 迭代次数
    tol: float = 0.001,# 算法收敛的阈值
    n_jobs: Int | None = None

三、Label Spreading(标签扩散)

1、介绍

基本原理:Label Spreading和Label Propagation非常相似,但在处理标签信息和正则化方面有所不同。它同样基于构建图来传播标签。

关键特点:

正则化机制:Label Spreading引入了正则化参数,可以控制标签传播的过程,使算法更加健壮。

稳定性:由于正则化的存在,Label Spreading在面对噪声数据时通常比Label Propagation更稳定。

适用场景:同样适用于有大量未标记数据的情况,尤其当数据包含噪声或者不完全标记时。

2、代码示例

from sklearn.semi_supervised import LabelSpreading

label_spreading = LabelSpreading(kernel="knn", alpha= 0.2)
label_spreading.fit(Xtrain, Ytrain)

Ytrain_spreading= label_spreading.transduction_

from sklearn.ensemble import RandomForestClassifier
RF_spreading= RandomForestClassifier(oob_score=True)
RF_spreading.fit(Xtrain, Ytrain_spreading)

print("AUC: ", roc_auc_score(Ytest, RF_spreading.predict_proba(Xtest)[:, 1]))

3、参数解释

	kernel: ((...) -> Any) | Literal['rbf', 'knn'] = "rbf",
    *,
    gamma: Float = 20,
    n_neighbors: Int = 7,
    alpha: Float = 0.2, # 正则化参数,用于控制算法对标签平滑的程度,值较小时,会更强调邻居节点信息,值较大时,更倾向于保持原始标签
    max_iter: Int = 30,
    tol: Float = 0.001, # 算法收敛的阈值
    n_jobs: Int | None = None
相关推荐
Tony聊跨境8 分钟前
独立站SEO类型及优化:来检查这些方面你有没有落下
网络·人工智能·tcp/ip·ip
懒惰才能让科技进步14 分钟前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
yyfhq22 分钟前
sdnet
python
Qspace丨轻空间25 分钟前
气膜场馆:推动体育文化旅游创新发展的关键力量—轻空间
大数据·人工智能·安全·生活·娱乐
没有不重的名么26 分钟前
门控循环单元GRU
人工智能·深度学习·gru
测试199830 分钟前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
love_and_hope30 分钟前
Pytorch学习--神经网络--搭建小实战(手撕CIFAR 10 model structure)和 Sequential 的使用
人工智能·pytorch·python·深度学习·学习
Chef_Chen33 分钟前
从0开始学习机器学习--Day14--如何优化神经网络的代价函数
神经网络·学习·机器学习
芊寻(嵌入式)43 分钟前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
2403_875736871 小时前
道品科技智慧农业中的自动气象检测站
网络·人工智能·智慧城市