| ##### 5.2 數據預處理 ##### |
|
| #數據分割、缺失值處理、剔除近零方差變量、剔除高度線性相關變量、數據標準化 |
|
|
|
| ### 載入數據和相應包 ### |
| # 清空工作目錄 |
| rm(list = ls()) |
| # 加載機器學習包 |
| # install.packages(caret) |
| library(caret) |
|
|
| ##1.讀入數據 |
| # 加載數據 |
| dat = read.csv('相親數據2.csv', fileEncoding = "UTF-8") |
| dim(dat) |
| head(dat) |
|
|
| ##2.分割訓練集和測試集 |
|
| #(1)留出法 |
| #將樣本分為兩個互斥的子集,80%為訓練集,剩下20%為測試集 |
|
|
| createDatePartition() |
| #保證訓練集和測試集中Y的比例是一致的 |
| #按照Y進行分層抽樣 |
|
| ## 按照因變量進行分層抽樣 ## |
| # 數據劃分為訓練集和測試集 |
|
| # 設置隨機種子 |
| set.seed(1234) |
| # 將數據集的80%劃分為訓練集,20%劃分為測試集 |
| trainIndex = createDataPartition(dat$決定, p = .8,? |
| ???????????????????????????????? list = FALSE,? |
| ???????????????????????????????? times = 1) |
| # createDataPartition會自動從y的各個level隨機取出等比例的數據來,組成訓練集,可理解為分層抽樣; |
| datTrain = dat[trainIndex, ] |
| # 訓練集 |
| datTest = dat[-trainIndex, ] |
| # 測試集 |
|
|
| #(2)交叉驗證法 |
| #將原始數據分成K組(一般是均分) |
| #每次訓練將其中一組作為測試集,另外K-1組作為訓練集 |
|
| set.seed(1234) |
| index = createFolds(dat$決定, k = 3, list = FALSE, returnTrain = TRUE) |
| index? |
| ##?? [1] 2 3 2 1 1 1 1 3 2 1 3 3 2 3 2 |
| testIndex = which(index == 1) |
| datTraincv = dat[-testIndex, ] |
| # 訓練集 |
| datTestcv = dat[testIndex, ] |
| # 測試集 |
|
|
| #(3)Bootstrap法 |
| #Bootstrap抽樣 |
| #從給定訓練集中有放回的均勻抽樣 |
|
| createResample()#times參數用于設定生成幾份隨機樣本 |
|
| set.seed(1234) |
| createResample(dat$決定, times = 3, list = F) |
|
|
| #(4)分割時間序列 |
|
| createTimesSlices() |
| #initialWindow參數表示第一個訓練集中的樣本數 |
| #horizon參數表示每個測試集中的樣本數 |
| #fixedWindow參數表示每個訓練集中的樣本數是否相同 |
|
|
| # 加載數據 |
| growdata = read.csv('水哥成長日記.csv', fileEncoding = "UTF-8") |
| head(growdata) |
|
| (timeSlices = createTimeSlices(1:nrow(growdata),? |
| ?????????????????????????????? initialWindow = 5, horizon = 2, fixedWindow = TRUE)) |
| # 5表示初始的window,2表示測試集是訓練集后的2位;fixedwindow表示都是訓練集寬度一致,如果想遞每次都從第一個樣本開始,那么就得設置為FALSE,默認為TRUE。 |
|
|
| ##3.處理缺失值 |
| preProcess()#該函數提供了三種缺失值填補的方法,即K近鄰方法、Bagging樹集成方法和中位數法 |
| # 需要注意的是,采用K近鄰方法時,會對原始數據進行標準化,如果需要返回原始值,還需將標準化公式倒推回來; |
| # 使用Bagging樹集成方法,理論上對缺失值的填補更權威,但其效率比較低; |
| # 使用中位數方法,速度非常快,但填補的準確率有待驗證。 |
| # 如果你想使用多重插補法,不妨也可以試試mice包,其操作原理是基于MC(蒙特卡洛模擬法)。 |
| # preProcess can be used to impute data sets based only on information in the training #set,注意只能用訓練集信息。 |
|
|
| #(1) 中位數法 ## |
| #用訓練集的中位數代替缺失值 |
|
| imputation_k = preProcess(datTrain,method = 'medianImpute') |
| datTrain1 = predict(imputation_k, datTrain) |
| (datTest1 = predict(imputation_k, datTest)) |
|
|
| median(datTrain$智力, na.rm = T) |
| # 顯然中位數這個填補方法不太合理,除非樣本取值比較均勻;注意這里用的也是訓練集的中位數 |
|
|
| #(2) K近鄰方法 ## |
| #對于需要插值的記錄,基于歐氏距離計算k個和它最近的觀測, |
| #然后利用k個近鄰的數據來填補缺失值 |
|
|
| imputation_k = preProcess(datTrain, method = 'knnImpute') |
| ##? Warning in preProcess.default(datTrain, method = "knnImpute"): These |
| ##? variables have zero variances: 是否喜歡矮矬窮, 對方是否喜歡矮矬窮 |
| datTrain1 = predict(imputation_k, datTrain) |
| datTest1 = predict(imputation_k, datTest) |
| datTrain$智力 = datTrain1$智力 * sd(datTrain$智力, na.rm = T) + mean(datTrain$智力, na.rm = T) |
| datTest$智力 = datTest1$智力 * sd(datTrain$智力, na.rm = T) + mean(datTrain$智力, na.rm = T) |
| datTest |
| # 注意,這里自動用的是訓練集的mean和sd對測試集進行標準化 |
| #所以最后得到的數據是標準化之后的 |
| #如果想看原始值,那么還需要將其去標準化倒推回去 |
|
|
| ##4.處理0方差變量(刪除近零方差) |
| nearZeroVar()#找出近零方差的變量 |
|
|
| dim(datTrain) |
| (nzv = nearZeroVar(datTrain)) |
| datTrain = datTrain[, -nzv] |
|
|
| ##5.刪除共線性變量 |
| findCorrelation()#自動找到高度共線性的變量,并給出建議剔除的變量 |
| #數據中不能有缺失值 |
| #只能包含數值型變量 |
|
|
| # 數據中不能有NA |
| datTrain1 = datTrain[, -c(1, 6)] |
| (descrCor = cor(datTrain1)) |
|
| highlyCorDescr = findCorrelation(descrCor, cutoff = .75, names = F, verbose = T) |
| highlyCorDescr |
| filteredTrain = datTrain1[, -highlyCorDescr] |
| # input只能是numeric型的dataframe或者matrix,且無缺失值(在此之前必須處理缺失值) |
|
|
|
| ##6.標準化 |
| preProcValues = preProcess(datTrain, method = c("center", "scale")) |
| trainTransformed = predict(preProcValues, datTrain) |
| testTransformed = predict(preProcValues, datTest) |
| # 利用訓練集的均值和方差對測試集進行標準化 |