R語言數據預處理操作——離散化(分箱)
一、項目環境
開發工具:RStudio
R:3.5.2
相關包:infotheo,discretization,smbinning,dplyr,sqldf
二、導入數據
# 這裡我們使用的是鳶尾花數據集(iris) data(iris) head(iris)
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species | |
---|---|---|---|---|---|
1 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
2 | 4.9 | 3.0 | 1.4 | 0.2 | setosa |
3 | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
4 | 4.6 | 3.1 | 1.5 | 0.2 | setosa |
5 | 5.0 | 3.6 | 1.4 | 0.2 | setosa |
6 | 5.4 | 3.9 | 1.7 | 0.4 | setosa |
相關數據解釋:
Sepal.Length:萼片長度
Sepal.Width:萼片寬度
Petal.Length:花瓣長度
Petal.Width:花瓣寬度
Species:鳶尾花品種
三、 數據劃分
library(dplyr) library(sqldf) # 為數據集增加序號列(id) iris$id <- c(1:nrow(iris)) # 將鳶尾花數據集中70%的數據劃分為訓練集 iris_train <- sample_frac(iris, 0.7, replace = TRUE) # 使用sql語句將剩下的30%花費為測試集 iris_test <- sqldf(" select * from iris where id not in ( select id from iris_train ) ") # 去除序號列(id) iris_train <- iris_train[,-6] iris_test <- iris_test[,-6]
【註】:這裡使用到sqldf包的函數sqldf函數來時間在R語言中使用SQL語句
四、 無監督分箱
常見的幾種無監督分箱方法
等寬分箱法
等頻分箱法
kmeans分箱法
1、 分箱前準備法
# 導入無監督分箱包——infotheo library(infotheo) # 分成幾個區域 nbins <- 3
2、 等寬分箱法
### 等寬分箱的原理非常簡單,就是按照相同的間距將數據分成相應的等分 # 將連續型數據分成三份,並以1、2、3賦值 equal_width <- discretize(iris_train$Sepal.Width,"equalwidth",nbins) ### 查看分箱情況 # 查看各分類數量 table(equal_width) # 用顏色表明是等寬分箱 plot(iris_train$Sepal.Width, col = equal_width$X) ### 保存每個等分切割點的值(闕值) # 計算各個分類相應的切割點 width <- (max(iris_train$Sepal.Width)-min(iris_train$Sepal.Width))/nbins # 保存闕值 depreciation <- width * c(1:nbins) + min(iris_train$Sepal.Width)
3、 等頻分箱
### 等頻分箱是將數據均勻的分成相應的等分(數量不一定是完全相同的) # 將連續型數據分成三份,並以1、2、3賦值 equal_freq <- discretize(iris_train$Sepal.Width,"equalfreq",nbins) ### 查看分箱情況 # 查看各分類數量 table(equal_width) # 用顏色表明是等頻分箱 plot(iris_train$Sepal.Width, col = equal_freq$X) ### 保存每個等分切割點的值(闕值) data <- iris_train$Sepal.Width[order(iris_train$Sepal.Width)] depreciation <- as.data.frame(table(equal_freq))$Freq
4、kmeans分箱法
# kmeans分箱法,先給定中心數,將觀察點利用歐式距離計算與中心點的距離進行歸類,再重新計算中心點,直到中心點# 不再發生變化,以歸類的結果做為分箱的結果。 # 將連續型數據分成三份,並以1、2、3賦值 k_means <- kmeans(iris_train$Sepal.Width, nbins) # 查看各分類數量 table(k_means$cluster) # 查看實際分箱狀況 k_means$cluster # 保存闕值 # rev() 的作用是倒置數據框 # 統一從左往右,從大到小 depreciation <- rev(k_means$centers)
五、 有監督分箱
discretization提供瞭幾個主要的離散化的工具函數:
chiM,ChiM算法進行離散化
chi2, Chi2算法進行離散化
mdlp,最小描述長度原理(MDLP)進行離散化
modChi2,改進的Chi2方法離散數值屬性
disc.Topdown,自上而下的離散化
extendChi2,擴展Chi2算法離散數值屬性
smbinning提供的工具函數:
smbinning ,基於構造條件推斷樹ctree的監督式分箱
1、chiM算法進行離散化
### 有監督的數據離散化 library(discretization)# 有監督分箱 # 使用ChiMerge算法基於卡方檢驗進行自下而上的合並 chi1 <- chiM(iris_train, alpha = 0.05) # alpha 為顯著性指標 apply(chi1$Disc.data,2,table) # 保存闕值 depreciation <- chi1$cutp[[2]] ## 其他有監督分享算法 # chi2 <- chi2(iris,alp=0.5,del=0.05) # chi2()算法 # chi3 <- modChi2(iris,alp=0.5) # modChi2()算法 # chi4 <- extendChi2(iris,alp = 0.5) # extendChi2()算法 # m1 <- mdlp(iris) # 使用熵準則將最小描述長度作為停止規則來離散化 # d1 <- disc.Topdown(iris,method=1) # 該功能實現瞭三種自上而下的離散化算法(CAIM,CACC,Ameva)
2、基於構造條件推斷樹ctree的監督式分箱
# 分箱前數據準備 library(smbinning) # 查看測試用例 head(smbsimdf1)
fgood | cbs1 | cbs2 | cbinq | cbline | cbterm | cblineut | cbtob | cbdpd | cbnew | pmt | tob | dpd | dep | dc | od | home | inc | dd | online | rnd | period |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 60.11 | NA | 02 | 2 | 00 | 47.51361 | 5 | No | No | M | 2 | 00No | 10481.40 | 20 | 01 | No | W06 | 00 | Yes | 0.46641029 | 2018-03-31 |
1 | 45.62 | 66.72 | 02 | 2 | 02 | 52.36222 | 4 | No | No | A | 1 | 02Hi | 10182.43 | 17 | 01 | No | W10 | 00 | Yes | 0.91980286 | 2018-05-31 |
1 | 30.86 | 66.94 | 02 | 2 | 00 | 35.89640 | 5 | No | Yes | M | 2 | 02Hi | 9645.37 | 23 | 00 | No | W05 | 00 | Yes | 0.33804009 | 2018-07-31 |
1 | 62.38 | 49.12 | 02 | 3 | 01 | 41.93578 | 6 | No | No | P | 4 | 00No | 13702.76 | 31 | 01 | No | 00 | Yes | 0.76475600 | 2017-12-31 | |
1 | 54.36 | 41.22 | 00 | 1 | 00 | 44.23662 | 5 | No | No | P | 4 | 00No | 18720.09 | 26 | 02 | Yes | W08 | 01 | Yes | 0.58563795 | 2018-02-28 |
1 | 68.78 | 50.80 | 00 | 0 | 00 | 43.59248 | 7 | Yes | Yes | A | 4 | 01Lo | 10217.07 | 31 | 00 | No | W09 | 00 | Yes | 0.05756396 | 2018-03-31 |
【註】:這裡之所以不適用鳶尾花數據集的原因在於,這個函數的使用條件較為苛刻。首先它不允許數據集的列名中含有 “.” ,比如 鳶尾花數據集中的“Sepal.Width”就不可以。
其次它要求用於學習的列必須是二分類,且數據類型必須是numeric,二分類的值也必須是(0, 1) 。也是因為這些原因,為瞭方便在這裡使用包中自帶的數據集。
# 使用smbinning函數進行分箱,df 為原始數據,y表示目標標簽,x表示需要分箱的標簽result <- smbinning(df = smbsimdf1,y = "fgood",x = "cbs1") # 查看分箱結果的分佈情況,不良率和證據權重 par(mfrow=c(2,2)) boxplot(smbsimdf1$cbs1~smbsimdf1$fgood,horizontal=T, frame=F, col="lightgray",main="Distribution") smbinning.plot(result,option="dist") smbinning.plot(result,option="badrate") smbinning.plot(result,option="WoE")
result$ivtable # 相關重要信息 result$ctree # 決策樹 result$cuts # 闕值 smbinning.sql(result) # 輸出相應的sql語句
# 使用訓練好的函數對數據進行分箱(訓練集和測試集都需要) smbsimdf1 <- smbinning.gen(smbsimdf1, result, chrname = "gcbs1") # 查看分箱情況 table(smbsimdf1$gcbs1)
【註】:除此之外也可以用smbinning.sql(result) 生成的sql語句,配合sqldf包進行數據分箱操作。
六、 使用闕值對測試集進行分箱操作
上述方法中,除瞭最後一種方法,我們都沒有將訓練好的函數用於測試集。但是在實際的分析,我們讓數據離散化最主要的目的更多的是為瞭降低機器學習的負擔。
因此我們除瞭需要對訓練集進行分箱操作之外,將同樣的分箱方法作用與測試集。那麼下面我們就將使用之前得到的闕值,對測試集進行分享操作。
### 對測試集進行分箱操作 # 使用之前保存的闕值 # 這裡之所以要前後加上Inf,是為瞭讓它的范圍能夠向正負無窮延伸 # (-Inf, a],[b, Inf) break1<-c(-Inf,depreciation,Inf) labels = c("差", "中", "良", "優") # 第一個值是數據 # 第一個值是分箱的區間 # 第三個值是替換成的數 # ordered_result表示被替換成的數是否有前後順序 iris_test$Sepal.Width <- cut(iris_test$Sepal.Width,break1,labels,ordered_result = T) iris_test$Sepal.Width
七、 結語
本文更多的是從實際操作的角度進行說明,之間涉及到的很多算法的原理沒有進行過多的說明。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- R語言 實現data.frame 分組計數、求和等
- R語言實現支持向量機SVM應用案例
- 前端AI機器學習在瀏覽器中訓練模型
- Python matplotlib繪制散點圖配置(萬能模板案例)
- 使用R語言繪制散點圖結合邊際分佈圖教程