pu-learning 方式实现半监督分类
概述
使用 1-DNF 加 Logistic Regression 实现 PU-Learning
此实现参考论文 https://pdfs.semanticscholar.org/9181/bd6d6c3332ed5ad8ebd941eb9c9d9f7739fe.pdf
PU-Learning 可以用于解决只含有正标签数据和无标签数据的二分类问题,P 即 positive,U 即 Unlabeled
PU-Learning 分两步:
- 从无标签数据中选出一个可靠的负数据集合 RN (Reliable Negative)
我这里使用的方法是 1-DNF
-
使用 P (Positive) 和 RN (Reliable Negative) 训练一个分类器,使用该分类器对 U (Unlabeled) 进行分类,将被判定为负数据的部分 W 合并到 RN 中,循环直至 W 为空集。
每次循环都会得到一个分类器,通过设定规则选出最终的分类器。
我这里用的分类器是逻辑回归模型分类器
1-DNF
使用 1-DNF 选出一个可靠的负标签数据集
描述:
- 获取 P, U 中的所有特征 (all features)
-
对于每个特征,若它在 P 中出现的频率高于在 U 中出现的频率,则将它归入正特征集 PF (Positive Features) 中
-
对于 U 中的每条数据,若它不包含 PF 中的特征,则将它归入可靠的负数据集 RN (Reliable Negative) 中,否则归入集合 Q 中
训练分类器
训练 Logistic Regression 分类器
描述:
- P 和 RN 组成训练集 X_train
-
P 给定标签 1,RN 给定标签 0,组成训练集标签 y_train
-
用 X_train 和 y_train 训练逻辑回归模型 model
1model.fit(X_train, y_train)
用 model 对 Q 进行预测(分类)得到结果 result
1result = model.predict(Q)
找出 Q 中被判定为负的数据组成集合 W
1result = np.where(result<0.5, 0, 1).T[0]
2negative_index = np.where(result == 0)
3W = Q[negative_index]
- 将 W 和 RN 合并作为新的 RN,同时将 W 从 Q 中排除
1RN = np.concatenate((RN, W)) # RN = RN + W
2Q = np.delete(Q, negative_index, axis=0) # Q = Q - W
-
用新的 RN 和 P 组成新的 X_train,对应生成新的 y_train
-
继续训练模型,扩充 RN,直至 W 为空集,循环结束。其中每次循环都会得到一个分类器
选择一个最终分类器
从每次循环生成的分类器中选出一个最终的分类器
这里有两种方式,一种是直接选用最后一次循环的分类器,另一种是设置规则选出一个最佳分类器。
直接选用最后一次循环得到的分类器:
1final_model = models[-1]
利用规则选出一个最佳分类器:
用最后一次循环得到的分类器 S-last 对 P 进行分类,若分类结果中有超过 8% 条数据被判定为负,则选用第一次循环的分类器 S-1 作为最终分类器,否则继续选用 S-last 作为最终分类器
1neg_predict = models[-1].predict(P)
2neg_predict = np.where(neg_predict<0.5, 0, 1).T[0]
3if list(neg_predict).count(0)/neg_predict.shape[0] > 0.08:
4 final_model = models[0]
5else:
6 final_model = models[-1]
对测试数据集进行分类
得到最终的分类器就可以对测试数据进行分类了,然后得到测试数据的分类结果
1result = final_model.predict(X_test)