您的位置:

Semi-Supervised的深入探讨

Semi-Supervised学习是一种机器学习方法,利用未标记数据来改进监督学习任务。它是监督学习和无监督学习的中间点,兼具两者的优点。这篇文章将详细阐述Semi-Supervised学习的各个方面,包括其定义、应用、算法等,帮助读者理解并深入了解这一方法。

一、Semi-Supervised的定义

Semi-Supervised学习的核心思想是:在监督学习中,除了具有已标记数据之外,还存在着未标记的数据,而这些未标记的数据通常比已标记的数据多得多。Semi-Supervised学习通过利用未标记数据,来解决监督学习中困难的分类问题。

在Semi-Supervised学习中,通常将已标记数据称为有标记数据,将未标记数据称为无标记数据。这其中,有标记数据数量通常很少,而无标记数据数量则会更多。

二、Semi-Supervised的应用领域

Semi-Supervised学习在很多领域具有广泛应用:

1. 图像和视频标注:在计算机视觉领域,标注大量的图像和视频是一项费时费力且昂贵的工作。而Semi-Supervised学习可以通过利用未标记的图像和视频进行标注,从而大大减少标注的工作量。

2. 文本分类:在文本分类领域,Semi-Supervised学习可以使用未标记的语料库来学习一个表征,进而提高分类器的性能。

3. 金融风险控制:Semi-Supervised学习可以帮助金融机构更准确地评估风险和欺诈行为。

三、Semi-Supervised的算法

1. Self-training


def self_training(X_l, y_l, X_u, classifier):
    classifier.fit(X_l, y_l)
    while True:
        y_u_pred = classifier.predict(X_u)
        y_u_proba = classifier.predict_proba(X_u)
        sort_proba = np.sort(y_u_proba, axis=1)[:, ::-1]
        sort_ind = np.argsort(y_u_proba, axis=1)[:, ::-1]
        high_proba = sort_proba[:, 0]
        high_ind = sort_ind[:, 0]
        cond = high_proba > 0.9
        if not np.any(cond):
            break
        X_l = np.vstack([X_l, X_u[cond]])
        y_l = np.concatenate([y_l, y_u_pred[cond]])
        X_u = X_u[np.logical_not(cond)]
    return classifier

Self-Training算法中,首先使用有标记数据来训练分类器。然后,利用分类器对无标记数据进行预测,并筛选出分类器高度确信的样本。接着将这些高度确信的样本用作有标记数据再次训练分类器。这个过程不断迭代,直到高度确信的样本数目无法再增加为止。

2. Co-Training


def co_training(X_l, y_l, X_u, classifier1, classifier2):
    data_labeled1 = X_l.tolist()
    label_labeled1 = y_l.tolist()
    data_labeled2 = X_l.tolist()
    label_labeled2 = y_l.tolist()
    while X_u.shape[0] > 0:
        classifier1.fitting(data_labeled1, label_labeled1)
        classifier2.fitting(data_labeled2, label_labeled2)
        confident_samples1 = [(ind, x) for ind, x in enumerate(X_u) if abs(classifier1.predict_proba(x)[0][0] - 0.5) > confidence_threshold]
        confident_samples2 = [(ind, x) for ind, x in enumerate(X_u) if abs(classifier2.predict_proba(x)[0][0] - 0.5) > confidence_threshold]
        if len(confident_samples1) == 0 or len(confident_samples2) == 0:
            break
        c1_indices, c1_data = zip(*confident_samples1)
        c2_indices, c2_data = zip(*confident_samples2)
        classifier1_data = np.concatenate(data_labeled1 + list(c1_data))
        classifier1_label = np.concatenate(label_labeled1 + classifier2.predict(c1_data).tolist())
        classifier2_data = np.concatenate(data_labeled2 + list(c2_data))
        classifier2_label = np.concatenate(label_labeled2 + classifier1.predict(c2_data).tolist())
        data_labeled1, label_labeled1, data_labeled2, label_labeled2 = classifier1_data.tolist(), classifier1_label.tolist(), classifier2_data.tolist(), classifier2_label.tolist()
        X_u = np.delete(X_u, c1_indices + c2_indices, axis=0)
    return classifier1, classifier2

Co-Training算法假设有两个分类器,每个分类器针对样本的一部分特征进行训练。每个分类器都在已标记的样本上进行训练,并且在无标记数据上进行预测。每个分类器都将样本分成两部分:高度确信的和确信度较低的。传统的Co-training算法假设两个分类器所看到的数据不同,而且为互补的。高度确信的样本被认为是正确的,它们将被用来扩充已标记的数据。当已标记数据中没有高度确信的数据时,算法就停止。

3. S3VM


def s3vm(X_l, y_l, X_u):
    unlabeled_indicator = np.ones(X_u.shape[0], dtype=bool)
    Y_l, Y_u = y_l.astype(float), np.zeros(X_u.shape[0], dtype=float)

    for i in range(10):
        clf = svm.SVC(kernel='linear', probability=True, max_iter=500)
        Y = np.concatenate([Y_l, Y_u])
        X = np.vstack([X_l, X_u])
        clf.fit(X, Y)
        delta = np.abs(clf.decision_function(X_u))
        margin = np.abs(delta - 1.0)
        high_margin_ind = margin > 1e-10
        low_margin_ind = ~high_margin_ind
        if low_margin_ind.sum() == 0:
            break
        furthest_ind = delta.argmax()
        high_confidence_indicatory = np.zeros(X_u.shape[0], dtype=bool)
        high_confidence_indicatory[furthest_ind] = True
        high_confidence_indicatory[high_margin_ind] = True
        low_confidence_indicatory = np.zeros(X_u.shape[0], dtype=bool)
        low_confidence_indicatory[low_margin_ind] = True
        clf.fit(X[high_confidence_indicatory | (Y > 0.5)], Y[high_confidence_indicatory | (Y > 0.5)])
        r = clf.score(X[high_confidence_indicatory | (Y > 0.5)], Y[high_confidence_indicatory | (Y > 0.5)])
        p = clf.score(X[low_confidence_indicatory], Y[low_confidence_indicatory])
        pred = clf.predict(X)
        Y_u[unlabeled_indicator] = pred[y_l.shape[0]:]
        Y_u[high_confidence_indicatory] = pred[y_l.shape[0]:][high_confidence_indicatory]
        Y_l_new, Y_u_new = Y_l.copy(), Y_u.copy()
        Y_l_new[Y_u > 0.5] = 1.0
        Y_l_new[Y_u <= 0.5] = 0.0
        if ((Y_l_new - Y_l) ** 2).sum() < 1e-6:
            break

    return clf

S3VM(Smoothed Semi-supervised Support Vector Machine)算法假设所有的类别都是连续的正数值,并且使用加权的线性梯度下降法来训练分类器。通过在训练过程中使用未标记数据的信息来平滑边界,S3VM算法可以在一定程度上减少过拟合问题。

四、总结

本文详细阐述了Semi-Supervised学习的定义、应用和算法,并详细讲述了Self-training, Co-Training和S3VM等Semi-Supervised算法的实现原理和代码示例。通过对Semi-Supervised学习的深入了解,可以看出它在许多实际领域中的应用很广泛,并且也提供了一种解决监督学习问题的有力方法。