Semi-Supervised(半監督式學習)

機器學習共分為三類,監督式學習、非監督式學習以及半監督式學習
監督式學習:帶入的數據全部具有標籤,試圖從這些標籤過的資料模擬真實情形,接著將要預測的未標籤資料帶入模型。
非監督式學習:帶入的數據全部沒有標籤,試圖找尋數據中相同屬性(複數)的分群,並作為新的標籤。例如:{富士山蘋果、椪柑、青森蘋果、橘子、桶柑},在未標籤的情形下不曉得如何分類這組數據,試圖找出相同的屬性,{椪柑、橘子、桶柑}都是橘色,{富士山蘋果、青森蘋果}都是紅色,接著就能夠分出兩群,之後帶入新的數據,就能以這屬性去做分類。
半監督式學習:帶入的數據少量有標籤,其餘的沒有標籤,先從有標籤的進行分類,接著帶入沒有標籤的對分類器進行修正優化,例如:有標籤{富士山蘋果、椪柑}、未標籤{青森蘋果、橘子、桶柑、綠蘋果},從有標籤的數據屬性進行分類,富士山蘋果其一屬性是紅色的屬於蘋果、椪柑則是橘色的屬於柑橘,分為兩類,接著將未標籤的數據帶入修正模型,而最後一個綠蘋果會修正此模型,在屬性維度上會較接近蘋果那群,將會修正蘋果’紅色’這個屬性,也將’綠色’作為蘋果的屬性優化此模型。
註:半監督式學習可以進一步劃分為兩類-“Semi-supervised learning” 與“transductive learning”,前者假設訓練集裡的未標籤數據不是待預測數據,而後者假設訓練集裡的未標籤數據是待預測數據。
library(RSSL)
library(grid)
library(ggplot2)
library(knitr)
library(dplyr)
隨機產生200筆常態分佈數據,d維度為2,變異數為0.5
set.seed(4)
df <- generate2ClassGaussian(200,d = 2,var = 0.5)
kable(head(df[,c(3,1,2)]))
Class X1 X2
-1 -1.4842281 -0.8467312
-1 -0.9186025 -1.3836002
-1 -0.7479340 -0.3698656
-1 -0.9252082 -0.5785781
-1 -1.0317369 0.1565566
-1 0.2205888 -0.5126087
par(mfrow = c(1,2))
plot(density(df$X1)); plot(density(df$X2))

隨機刪除98%的標籤
df1 <- add_missinglabels_mar(df,Class ~ .,prob = 0.98)
kable(head(df1[complete.cases(df1),]))
Class X1 X2
9 -1 -0.2232379 0.3410562
98 -1 -2.0444178 -1.4084008
179 1 0.8749089 0.5055805
196 1 1.7951606 0.1601956

為了比較修正過的差異,分成兩部分:

1. g_nm:使用最鄰近法,因為formula = Class~.,所以自然只能分成2群。
2. g_self:將未標籤的數據帶入,並指定方法為最鄰近法。
g_nm <- NearestMeanClassifier(Class ~. ,df1)
g_self <- SelfLearning(Class ~ .,df,method = NearestMeanClassifier)
上圖是只針對標籤用最鄰近法進行分類,分為兩類,而下圖是帶入所有數據後,將為標籤數據用最鄰近法進行修正,產生新的分類器。
g1 <- ggplot(df1,aes(x = X1,y = X2,color = Class,size = Class)) +
    geom_point() +
    coord_equal(ratio = 1) +
    coord_cartesian(xlim = c(-3,3),ylim = c(-3,3)) +
    scale_size_manual(values = c("-1" = 3,"1" = 3),na.value = 1) +
    geom_linearclassifier("Supervised" = g_nm) +
    ggtitle("NearestMean(labeled)") +
    theme(plot.title = element_text(size = 20))
g2 <- ggplot(df1,aes(x = X1,y = X2,color = Class,size = Class)) +
    geom_point() +
    coord_equal(ratio = 1) +
    coord_cartesian(xlim = c(-3,3),ylim = c(-3,3)) +
    scale_size_manual(values = c("-1" = 3,"1" = 3),na.value = 1) +
    geom_linearclassifier("Supervised" = g_nm,
                          "Semi-supervised" = g_self) +
    ggtitle("Semi-supervised(labeled,unlabeled)") +
    theme(plot.title = element_text(size = 20))
g3 <- ggplot(df,aes(x = X1,y = X2,color = Class,size = Class)) +
    geom_point() +
    coord_equal(ratio = 1) +
    coord_cartesian(xlim = c(-3,3),ylim = c(-3,3)) +
    scale_size_manual(values = c("-1" = 3,"1" = 3),na.value = 1) +
    geom_linearclassifier("Supervised" = g_nm,
                          "Semi-supervised" = g_self)
grid.draw(rbind(ggplotGrob(g1),ggplotGrob(g2),ggplotGrob(g3),size = "last"))

Semi-supervised

df.pre <- predict(g_self,df1[!complete.cases(df1),])
df.orig <- df[df1[!complete.cases(df1),] %>% rownames(),][,"Class"]
(df.table <- table("Predict" = df.pre, "Original" = df.orig))
##        Original
## Predict -1  1
##      -1 94  2
##      1   4 96
sum(diag(df.table))/sum(df.table)
## [1] 0.9693878

Supervised

x <- predict(g_nm,df1[!complete.cases(df1),])
(y <- table("Predict" = x,"Original" = df.orig))
##        Original
## Predict -1  1
##      -1 93  3
##      1   5 95
sum(diag(y))/sum(y)
## [1] 0.9591837
半監督式學習有許多種方法,例如:EM with generative mixture models、self-training、co-training、transductive support vector machines以及graph-based methods等等。
1. 上面使用的就是self-training,在self-training中,分類器會先用少量標籤數據訓練,再對未標籤數據進行訓練,他會依照method來挑選最有信心的未標籤數據作為預測標籤加入訓練集裡,並重複此過程,簡而言之,就是使用自己的預測來訓練自己。
2. EM with generative mixture models(EM生成混合模型):
原理:https://goo.gl/KW3VW8

{r, message=FALSE, warning=FALSE} library(mixtools) x <- c(rnorm(200, 10, 3), rnorm(200, 25,3), rnorm(200,35,3), rnorm(200,80,5), rpois(50,30)) y <- c(rnorm(800, 30, 2), rpois(50,30)) df <- cbind (x, y) out <- mvnormalmixEM(df,k = 4) plot(out,density = TRUE,alpha = c(0.01,0.05,0.1,0.12,0.15),marginal = TRUE)