李家翔 2019-02-26
数据来自
from sklearn.datasets.samples_generator import make_blobs
以下实验的目的是检验当部分正样本和全部负样本未知的情况下,比较PU Learning 的模型效果和 已经全部正负样本下的模型结果。
如果两个结果差异不大,表示 PU Learning 明显效果不错。
suppressMessages(library(tidyverse))
x <- read_csv("datasets/make_circles_x.csv")
## Parsed with column specification:
## cols(
## feature1 = col_double(),
## feature2 = col_double()
## )
y <- read_csv("datasets/make_circles_y.csv")
## Parsed with column specification:
## cols(
## y = col_double()
## )
table(y)
## y
## 0 1
## 3000 3000
head(x)
## # A tibble: 6 x 2
## feature1 feature2
## <dbl> <dbl>
## 1 0.789 3.79
## 2 6.66 5.88
## 3 0.440 -1.47
## 4 0.334 4.32
## 5 4.92 4.28
## 6 5.82 2.74
假设 2700 个正样本是未知的,所有的负样本是未知的。
set.seed(123)
unlabelled_index <- sample(x = which(y == 1),size = 2700,replace = F)
y_new <- y
y_new[unlabelled_index,]$y <- 0
data <- bind_cols(y_new,x)
table(data$y)
##
## 0 1
## 5700 300
table(y)
## y
## 0 1
## 3000 3000
library(randomForest)
## randomForest 4.6-14
## Type rfNews() to see new features/changes/bug fixes.
##
## Attaching package: 'randomForest'
## The following object is masked from 'package:dplyr':
##
## combine
## The following object is masked from 'package:ggplot2':
##
## margin
model <- randomForest(as.factor(y) ~ feature1 + feature2, data = data)
yhat <- predict(model,type = 'prob')[,2]
ks_table <- function(yhat, y) {
library(tidyverse)
pred <- ROCR::prediction(yhat, y)
perf <- ROCR::performance(pred, 'tpr', 'fpr')
# tpr true positive rate
# fpr false positive rate
perf_df <- data.frame(perf@x.values, perf@y.values)
names(perf_df) <- c("fpr", "tpr")
per_df2 <-
perf_df %>%
mutate(cutoff = 1:nrow(.)/nrow(.)) %>%
mutate(ks = tpr - fpr)
return(per_df2)
}
ks_table(yhat,y) %>%
gather(key,value, tpr,fpr,ks) %>%
ggplot(aes(x = cutoff, y = value, col = key)) +
geom_line()
看到 KS 可以达到 70% 左右,因此模型效果并不差。
那么假设正样本和负样本完全已知的情况下,对比简单模型效果。
data2 <- bind_cols(y,x)
model2 <- randomForest(as.factor(y) ~ feature1 + feature2, data = data2)
yhat2 <- predict(model2,type = 'prob')[,2]
ks_table(yhat2,y) %>%
gather(key,value, tpr,fpr,ks) %>%
ggplot(aes(x = cutoff, y = value, col = key)) +
geom_line()
KS 为 100%,这是因为 feature1 和 feature2 本身是完全有效的两个变量。 对比前者 KS 差异 1/3 的准确性,因此是可以接受的。
PU Learning 的结果并不差。