PU Learning简介:对无标签数据进行半监督分类

当只有几个正样本,你如何分类无标签数据

假设您有一个交易业务数据集。有些交易被标记为欺诈,其余交易被标记为真实交易,因此您需要设计一个模型来区分欺诈交易和真实交易。 假设您有足够的数据和良好的特征,这似乎是一项简单的分类任务。 但是,假设数据集中只有15%的数据被标记,并且标记的样本仅属于一类,即训练集15%的样本标记为真实交易,而其余样本未标记,可能是真实交易样本,也可能是欺诈样本。您将如何对其进行分类? 样本不均衡问题是否使这项任务变成了无监督学习问题? 好吧,不一定。

此问题通常被称为PU(正样本和未标记)分类问题,首先要将该问题与两个相似且常见的“标签问题”相区别,这两个问题使许多分类任务复杂化。第一个也是最常见的标签问题是小训练集问题。当您有大量数据但实际上只有一小部分被标记时,就会出现这种情况。这个问题有很多种类和许多特定的训练方法。另一个常见的标签问题(通常与PU问题混为一谈)是,训练的数据集是被完全标记的但只有一个类别。例如,假设我们拥有的只是一个非欺诈性交易的数据集,并且我们需要使用该数据集来训练一个模型,以区分非欺诈性交易和欺诈性交易。这也是一个常见问题,通常被视为无监督的离群点检测问题,在机器学习领域中也有很多工具专门用于处理这些情况(OneClassSVM可能是最著名的)。

相比之下,PU分类问题涉及的训练集,其中仅部分数据被标记为正,而其余数据未标记,可能为正或负。 例如,假设您在银行工作,可以获得很多交易数据,但只能确认其中一部分是100%真实的。 我将要举的例子将与伪钞相关。这个例子包含一个1200张钞票的数据集,其中大部分未标记,只有一部分被确认为真钞。 尽管PU问题也很普遍,但是与前面提到的两个分类问题相比,这个问题被讨论的次数通常要少得多,而且很少有实际的示例或库可供使用。

这篇文章的目的是提出一种可行的办法来解决PU问题,这个方法我最近在一个分类项目中使用过。 它基于Charles Elkan和Keith Noto的论文《Learning classifiers from only positive and unlabeled data》(2008年),以及Alexandre Drouin撰写的一些代码。 尽管在科学出版物中有更多的PU学习方法(我打算在以后的文章中讨论另一种颇受欢迎的方法),但是Elkan和Noto(E&N)的方法非常简单,并且可以在Python中轻松实现。

一点点理论


E&N方法本质上认为,在给定一个具有正样本和未标记样本的数据集的情况下,某个样本为正的概率[P(y = 1 | x)]等于一个样本被标记的概率[P(s = 1 | x)]除以一个正样本被标记的概率[P(s = 1 | y = 1)]。
如果这个说法是正确的(我并不会去证明或反驳它-您可以阅读论文本身的证明并验证代码),那么实现起来似乎相对容易。 之所以这样,是因为尽管我们没有足够的标记数据来训练分类器来告诉我们样本是正还是负,但在PU问题中,我们有足够的标记数据来告诉我们一个正样本是否可能被标记。根据E&N的方法,这足以估算一个样本是否是正样本
更正式地讲,给定一个未标记的数据集,其中只有一组样本被标记为正样本。幸运的是,如果我们可以估计P(s = 1 | x)/ P(s = 1 | y = 1),那么就可以根据以下步骤使用任何基于sklearn的分类器进行估算:
(1)将分类器使用在包含标签和无标签样本的数据集上,同时使用已标记的指示器作为目标y,以这种方式拟合分类器对其进行训练,以预测给定样本x被标记的概率P(s = 1 | x)。
(2)使用分类器来预测数据集中已知正样本被标记的概率,使用预测的结果表示对正样本被标记的概率— P(s = 1 | y = 1 | x)
计算这些预测概率的均值,得到P(s=1|y=1).
在估计了P(s = 1 | y = 1)之后,为了根据E&N方法预测数据点k为正样本的概率,我们要做的就是估计P(s = 1 | k)或K被标记的概率,这正是分类器(1)所做的。
(3)使用我们训练的分类器(1)来估计K被标记的概率或者P(s=1|k)
(4)一旦我们估计了P(s = 1 | k),我们就可以通过将k除以在步骤(2)中估计的P(s = 1 | y = 1)来对k进行分类,然后获得它属于这两个类的实际概率。

现在编写代码并进行测试

上述1-4可按如下方式实施:

# prepare data
x_data = the training set
y_data = target var (1for the positives and not-1for the rest)
# fit the classifier and estimate P(s=1|y=1)
classifier, ps1y1 =
       fit_PU_estimator(x_data, y_data, 0.2, Estimator())
# estimate the prob that x_data is labeled P(s=1|X)
predicted_s = classifier.predict_proba(x_data)
# estimate the actual probabilities that X is positive# by calculating P(s=1|X) / P(s=1|y=1)
predicted_y = estimated_s / ps1y1

让我们从这里的主要方法开始:fit_PU_estimator()方法。
fit_PU_estimator()方法完成了2个主要任务:它适合您在正样本和未标记样本的数据集中选择合适的分类器,然后估计正样本被标记的概率。相应地,它返回一个拟合的分类器(已学会估计给定样本被标记的概率)和估计概率P(s = 1 | y = 1)。 之后,我们要做的就是找到P(s = 1 | x)或x被标记的概率。因为分类器被这样训练过,所以我们只需要调用其predict_proba()方法即可。最后,为了对样本x进行实际分类,我们只需要将结果除以已经得到的P(s = 1 | y = 1)。
用代码表示为:

pu_estimator, probs1y1 = fit_PU_estimator(
  x_train,
  y_train,
  0.2,
  xgb.XGBClassifier())

predicted_s = pu_estimator.predict_proba(x_train)
predicted_s = predicted_s[:,1]
predicted_y = predicted_s / probs1y1

fit_PU_estimator()方法本身的实现是非常简单的

deffit_PU_estimator(X,y, hold_out_ratio, estimator):# The training set will be divided into a fitting-set that will be used # to fit the estimator in order to estimate P(s=1|X) and a held-out set of positive samples# that will be used to estimate P(s=1|y=1)# --------# find the indices of the positive/labeled elementsassert (type(y) == np.ndarray), "Must pass np.ndarray rather than list as y"
    positives = np.where(y == 1.)[0]
    # hold_out_size = the *number* of positives/labeled samples # that we will use later to estimate P(s=1|y=1)
    hold_out_size = int(np.ceil(len(positives) * hold_out_ratio))
    np.random.shuffle(positives)
    # hold_out = the *indices* of the positive elements # that we will later use  to estimate P(s=1|y=1)
    hold_out = positives[:hold_out_size]
    # the actual positive *elements* that we will keep aside
    X_hold_out = X[hold_out]
    # remove the held out elements from X and y
    X = np.delete(X, hold_out,0)
    y = np.delete(y, hold_out)
    # We fit the estimator on the unlabeled samples + (part of the) positive and labeled ones.# In order to estimate P(s=1|X) or  what is the probablity that an element is *labeled*
    estimator.fit(X, y)
    # We then use the estimator for prediction of the positive held-out set # in order to estimate P(s=1|y=1)
    hold_out_predictions = estimator.predict_proba(X_hold_out)
    #take the probability that it is 1
    hold_out_predictions = hold_out_predictions[:,1]
    # save the mean probability
    c = np.mean(hold_out_predictions)
    return estimator, c

defpredict_PU_prob(X, estimator, prob_s1y1):
    prob_pred = estimator.predict_proba(X)
    prob_pred = prob_pred[:,1]
    return prob_pred / prob_s1y1

为了对此进行测试,我使用了钞票数据集,该数据集基于从真实和伪造钞票的图像中提取的4个数据点。 我首先在标记的数据集上使用分类器以设置基线,然后删除75%的样本的标签以测试其在P&U数据集上的表现。如输出所示,确实该数据集并不是最难分类的数据集,但是您可以看到,尽管PU分类器仅了解约153个正样本,而其余所有1219均未标记,但与全标签分类器相比,它的表现相当出色 。 但是,它确实损失了大约17%的召回率,因此损失了很多正样本。但是,我相信与其他方案相比,这个结果是令人相当满意的。

===>> load data set <<===data size: (1372, 5)Target variable (fraud or not):
07621610===>> create baseline classification results <<===Classification results:f1: 99.57%
roc: 99.57%
recall: 99.15%
precision: 100.00%===>> classify on all the data set <<===Target variable (labeled or not):
-112191153Classification results:f1: 90.24%
roc: 91.11%
recall: 82.62%

几个要点

首先,这种方法的性能很大程度上取决于数据集的大小。 在此示例中,我使用了大约150个正样本和大约1200个未标记的样本。 这远不是该方法的理想数据集。 例如,如果我们只有100个样本,则分类器的效果会非常差。 其次,如随附的笔记所示,有一些变量需要调整(例如要设置的样本大小,用于分类的概率阈值等),但是最重要的可能是选择的分类器及其参数。 我之所以选择使用XGBoost,是因为它在特征少的小型数据集上的性能相对较好,但是需要注意的是,它并非在每种情况下都表现得很好,并且测试正确的分类器也很重要。

作者:Alon Agmon
Deephub翻译组:gkkkkkk

原文地址:https://www.cnblogs.com/deephub/p/12588819.html

时间: 2024-07-30 12:49:26

PU Learning简介:对无标签数据进行半监督分类的相关文章

机器学习中的标签数据和无标签数据

今天在数据人网上看到一篇文章.区分监督学习和无监督学习,监督学习的数据就是有标签数据,无监督学习的数据就是无标签数据.这是我的理解,欢迎指教. 原文链接http://www.shujuren.org/article/62.html 原文如下 监督式和非监督式机器学习算法 作者Frankchen 什么是监督式机器学习,它与和非监督式机器学习有什么关联呢? 本文中你将了解到监督式学习,非监督式学习和半监督式学习在阅读本文之后你将知道如下知识: 有关分类和回归的监督式学习问题 关于聚类和关联非监督式学

mahout贝叶斯算法拓展篇3---分类无标签数据

代码测试环境:Hadoop2.4+Mahout1.0 前面博客:mahout贝叶斯算法开发思路(拓展篇)1和mahout贝叶斯算法开发思路(拓展篇)2 分析了Mahout中贝叶斯算法针对数值型数据的处理.在前面这两篇博客中并没有关于如何分类不带标签的原始数据的处理.下面这篇博客就针对这样的数据进行处理. 最新版(适合Hadoop2.4+mahout1.0环境)源码以及jar包可以在这里下载Mahout贝叶斯分类不含标签数据: 下载后参考使用里面的jar包中的fz.bayes.model.Baye

Coursera《machine learning》--(14)数据降维

本笔记为Coursera在线课程<Machine Learning>中的数据降维章节的笔记. 十四.降维 (Dimensionality Reduction) 14.1 动机一:数据压缩 本小节主要介绍第二种无监督学习方法:dimensionality reduction,从而实现数据的压缩,这样不仅可以减少数据所占磁盘空间,还可以提高程序的运行速度.如下图所示的例子,假设有一个具有很多维特征的数据集(虽然下图只画出2个特征),可以看到x1以cm为单位,x2以inches为单位,它们都是测量长

hive不同格式数据大小,无重复数据

-- 重点,目标表无重复数据 -- dbName.num_result 无重复记录 -- 插入数据 CREATE TABLE dbName.test_textfile( `key` string, `value` string, `p_key` string, `p_key2` string) STORED AS textfile ; insert overwrite table dbName.test_textfile select * from dbName.num_result where

使用tensorflow api生成one-hot标签数据

转自:http://www.terrylmay.com/2017/06/generate-one-hot-data/ 使用tensorflow api生成one-hot标签数据 在刚开始学习tensorflow的时候, 会有一个最简单的手写字符识别的程序供新手开始学习, 在tensorflow.example.tutorial.mnist中已经定义好了mnist的训练数据以及测试数据. 并且标签已经从原来的List变成了one-hot的二维矩阵的格式.看了源码的就知道mnist.input_da

[转]概念:结构化数据、半结构化数据、非结构数据

原:http://blog.csdn.net/liangyihuai/article/details/54864952 结构化数据.半结构化数据和非结构化数据 结构化数据 结构化的数据是指可以使用关系型数据库表示和存储,表现为二维形式的数据.一般特点是:数据以行为单位,一行数据表示一个实体的信息,每一行数据的属性是相同的.举一个例子: id name age gender 1 lyh 12 male 2 liangyh 13 female 3 liang 18 male 所以,结构化的数据的存储

Day47:HTML(简介及常用标签)

一.HTML简介 html是什么? 超文本标记语言(Hypertext Markup Language,HTML)通过标签语言来标记要显示的网页中的各个部分.一套规则,浏览器认识的规则. 浏览器按顺序渲染网页文件,然后根据标记符解释和显示内容.但需要注意的是,对于不同的浏览器,对同一标签可能会有不完全相同的解释(兼容性). 静态网页文件扩展名:.html 或 .htm. HTML 不是一种编程语言,而是一种标记语言 (markup language).HTML 使用标记标签来描述网页. html

HTML(简介及常用标签)

一.HTML简介 1.1 html是什么? 超文本标记语言(Hypertext Markup Language,HTML)通过标签语言来标记要显示的网页中的各个部分.一套规则,浏览器认识的规则. 浏览器按顺序渲染网页文件,然后根据标记符解释和显示内容.但需要注意的是,对于不同的浏览器,对同一标签可能会有不完全相同的解释(兼容性). 静态网页文件扩展名:.html 或 .htm. HTML 不是一种编程语言,而是一种标记语言 (markup language).HTML 使用标记标签来描述网页.

jsp获取标签数据

初写项目,发现了一些东西. 在jsp里面 ,获取标签的数据.如果标签里面的数据使用map集合先设置好的,那么获取的话需要用  $("#allpage").text(data.allpage); 如果标签里面的数据是用普通集合设置的话,那么需要用$("#allpage").val(data.allpage); 首先,data是从servlet传来的数据, PrintWriter out = response.getWriter(); ObjectMapper obje