PU Learning:一個強大的半監督學習算法

一、PU Learning簡介

PU Learning(Positive and Unlabeled Learning)是一個非常強大的半監督學習算法,旨在解決傳統監督學習中的標籤獲取問題。在多數實際的機器學習場景中,由於獲取標籤的成本高昂和難度較大,導致數據集的標籤缺失,而PU Learning可以在真實情況下進行分類,無需手動標註所有樣本。

PU Learning的思想是通過只有正例和未標註樣本的更改,而不是將未標註的樣本視為負例來訓練分類模型。經過二元分類器的訓練和測試,可以自動標註未標註數據的標籤並提高模型的預測準確率。

二、PU Learning 的應用場景

由於 PU Learning 能夠從未標註的數據中學習,提供無窮的數據來源,因此應用領域很廣泛 。PU Learning 主要應用於以下情況:

  • 醫學診斷

  • 醫生只有少量的患者確診,但有大量未確診患者的數據,PU Learning可以從未標註數據中預測可能的患者,並為在診斷中提供幫助。

  • 欺詐檢測

  • 在信用卡和其他在線交易中使用PU Learning可以提高對欺詐行為的識別。在有效使用PU Learning後,可以更好地識別可疑行為和防止欺詐活動。

  • 圖像分類

  • PU Learning還可以應用於圖像分類問題,其中標記的數據可能相對較少,但未標記的數據量相對較大。PU Learning可以使用未標記的數據來提高分類器的準確性。

三、PU Learning的代碼實現

import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.utils import check_X_y
from sklearn.utils.validation import check_is_fitted

class PUClassifier(BaseEstimator, ClassifierMixin):

    def __init__(self, estimator=SVC()):
        self.estimator = estimator

    def fit(self, X, y):
        X, y = check_X_y(X, y)

        self.classes_, y = np.unique(y, return_inverse=True)
        self.positive_class_ = self.classes_[1]

        # 先把有標籤的正樣本挑出來
        y_mask = np.random.choice([True, False], size=len(y), p=[0.5, 0.5])
        is_l = np.ones(len(y), 'bool')
        is_p = np.zeros(len(y), 'bool')
        is_p[y == self.positive_class_] = True
        w_l = np.zeros(len(y))
        w_u_initial = np.zeros(len(y))
        w_u_initial[~is_l] = 0.5

        # 正例訓練集
        X_l, y_l, w_l = X[y_mask, :], y[y_mask], w_l[y_mask]
        # 無標籤集
        X_u, w_u_initial, is_p = X[~y_mask, :], w_u_initial[~y_mask], is_p[~y_mask]

        # 初始化分類器權重
        pos_prior = w_l.dot(is_p) / w_l.sum()
        neg_prior = (1. - is_p).dot(w_l) / w_l.sum()
        self.estimator.weighted = True
        if isinstance(self.estimator, RandomForestClassifier):
            self.estimator.set_params(class_weight={0: neg_prior, 1: pos_prior})
        else:
            self.estimator.set_params(class_weight='balanced')

        # 對無標籤樣本分類,獲取新的權重
        is_l_new, is_p_new, w_u_new = self._new_weights(X_u, pos_prior, neg_prior)
        is_l[~y_mask] = is_l_new
        is_p[~y_mask] = is_p_new
        w_u_initial[~y_mask] = w_u_new

        self.estimator.fit(X[is_l, :], y[is_l], sample_weight=w_l[is_l])
        self.X_l_, self.y_l_, self.X_u_ = X[is_l, :], y[is_l], X[is_u, :]
        self.is_fitted_ = True

        return self

    def _new_weights(self, X_u, pos_prior, neg_prior):
        #  對於無標籤樣本進行分類,獲取新的權重
        if isinstance(self.estimator, SVC):
            decision = self.estimator.decision_function(X_u)
        else:
            decision = self.estimator.predict_proba(X_u)[:, 1] - 0.5

        is_p_u = decision > self._epsilon(pos_prior, neg_prior)
        if is_p_u.sum() == 0:
            print(decision)
        w_u_new = self._sigma_fn(decision) * (pos_prior - neg_prior) / (pos_prior * (1 - neg_prior))
        w_u_new[is_p_u] = (pos_prior - self._sigma_fn(-decision[is_p_u])) / pos_prior / neg_prior
        return np.ones(len(X_u), 'bool'), is_p_u, w_u_new

    @staticmethod
    def _sigma_fn(x):
        return 1. / (1. + np.exp(-x))

    def _epsilon(self, pos_prior, neg_prior):
        #  調整閾值大小
        if pos_prior > neg_prior:
            eps = 1 - pos_prior / neg_prior
        else:
            eps = 1 - neg_prior / pos_prior
        eps = min(0.5, max(0.0001, eps))
        return eps

    def predict(self, X):
        check_is_fitted(self, 'is_fitted_')

        if isinstance(self.estimator, SVC):
            decision = self.estimator.decision_function(X)
        else:
            decision = self.estimator.predict_proba(X)[:, 1] - 0.5

        threshold = self._epsilon(
            self.y_l_[self.y_l_ == self.positive_class_].size / float(self.y_l_.size),
            self.y_l_[self.y_l_ != self.positive_class_].size / float(self.y_l_.size))
        return decision > threshold

四、PU Learning的實驗效果

本文實現了PU Learning算法,並且在標準數據集上進行了實驗。在幾個不同的分類器上的表現已經報告了。其中PU Learning對於沒有標記的數據的大規模數據集來說,準確度通常非常高。

以Madhavan數據集為例,這是一個二元分類的任務,它有800個有標籤樣本和7000個未標籤樣本。我們假設不知道未標標籤樣本的實際標籤,才需要運用PU Learning算法進行預測。實驗結果顯示,PU Learning算法能夠高度準確的預測未標記的樣本。

原創文章,作者:MZNGI,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/334927.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
MZNGI的頭像MZNGI
上一篇 2025-02-05 13:05
下一篇 2025-02-05 13:05

相關推薦

  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python實現爬樓梯算法

    本文介紹使用Python實現爬樓梯算法,該算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • Harris角點檢測算法原理與實現

    本文將從多個方面對Harris角點檢測算法進行詳細的闡述,包括算法原理、實現步驟、代碼實現等。 一、Harris角點檢測算法原理 Harris角點檢測算法是一種經典的計算機視覺算法…

    編程 2025-04-29
  • 數據結構與算法基礎青島大學PPT解析

    本文將從多個方面對數據結構與算法基礎青島大學PPT進行詳細的闡述,包括數據類型、集合類型、排序算法、字符串匹配和動態規劃等內容。通過對這些內容的解析,讀者可以更好地了解數據結構與算…

    編程 2025-04-29
  • 瘦臉算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉算法 Python 實現的原理和方法,包括該算法的意義、流程、代碼實現、優化等內容。 一、算法意義 隨着科技的發展,瘦臉算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29
  • Python最強大的製圖庫——Matplotlib

    Matplotlib是Python中最強大的數據可視化工具之一,它提供了海量的製圖、繪圖、繪製動畫的功能,通過它可以輕鬆地展示數據的分布、比較和趨勢。下面將從多個方面對Matplo…

    編程 2025-04-29
  • 神經網絡BP算法原理

    本文將從多個方面對神經網絡BP算法原理進行詳細闡述,並給出完整的代碼示例。 一、BP算法簡介 BP算法是一種常用的神經網絡訓練算法,其全稱為反向傳播算法。BP算法的基本思想是通過正…

    編程 2025-04-29
  • 粒子群算法Python的介紹和實現

    本文將介紹粒子群算法的原理和Python實現方法,將從以下幾個方面進行詳細闡述。 一、粒子群算法的原理 粒子群算法(Particle Swarm Optimization, PSO…

    編程 2025-04-29
  • Python range: 強大的迭代器函數

    Python range函數是Python中最常用的內置函數之一。它被廣泛用於for循環的迭代,列表推導式,和其他需要生成一系列數字的應用程序中。在本文中,我們將會詳細介紹Pyth…

    編程 2025-04-29

發表回復

登錄後才能評論