| ##### 5.2 數(shù)據(jù)預處理 ##### |
|
| #數(shù)據(jù)分割、缺失值處理、剔除近零方差變量、剔除高度線性相關(guān)變量、數(shù)據(jù)標準化 |
|
|
|
| ### 載入數(shù)據(jù)和相應包 ### |
| # 清空工作目錄 |
| rm(list = ls()) |
| # 加載機器學習包 |
| # install.packages(caret) |
| library(caret) |
|
|
| ##1.讀入數(shù)據(jù) |
| # 加載數(shù)據(jù) |
| dat = read.csv('相親數(shù)據(jù)2.csv', fileEncoding = "UTF-8") |
| dim(dat) |
| head(dat) |
|
|
| ##2.分割訓練集和測試集 |
|
| #(1)留出法 |
| #將樣本分為兩個互斥的子集,80%為訓練集,剩下20%為測試集 |
|
|
| createDatePartition() |
| #保證訓練集和測試集中Y的比例是一致的 |
| #按照Y進行分層抽樣 |
|
| ## 按照因變量進行分層抽樣 ## |
| # 數(shù)據(jù)劃分為訓練集和測試集 |
|
| # 設(shè)置隨機種子 |
| set.seed(1234) |
| # 將數(shù)據(jù)集的80%劃分為訓練集,20%劃分為測試集 |
| trainIndex = createDataPartition(dat$決定, p = .8,? |
| ???????????????????????????????? list = FALSE,? |
| ???????????????????????????????? times = 1) |
| # createDataPartition會自動從y的各個level隨機取出等比例的數(shù)據(jù)來,組成訓練集,可理解為分層抽樣; |
| datTrain = dat[trainIndex, ] |
| # 訓練集 |
| datTest = dat[-trainIndex, ] |
| # 測試集 |
|
|
| #(2)交叉驗證法 |
| #將原始數(shù)據(jù)分成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參數(shù)用于設(shè)定生成幾份隨機樣本 |
|
| set.seed(1234) |
| createResample(dat$決定, times = 3, list = F) |
|
|
| #(4)分割時間序列 |
|
| createTimesSlices() |
| #initialWindow參數(shù)表示第一個訓練集中的樣本數(shù) |
| #horizon參數(shù)表示每個測試集中的樣本數(shù) |
| #fixedWindow參數(shù)表示每個訓練集中的樣本數(shù)是否相同 |
|
|
| # 加載數(shù)據(jù) |
| 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表示都是訓練集寬度一致,如果想遞每次都從第一個樣本開始,那么就得設(shè)置為FALSE,默認為TRUE。 |
|
|
| ##3.處理缺失值 |
| preProcess()#該函數(shù)提供了三種缺失值填補的方法,即K近鄰方法、Bagging樹集成方法和中位數(shù)法 |
| # 需要注意的是,采用K近鄰方法時,會對原始數(shù)據(jù)進行標準化,如果需要返回原始值,還需將標準化公式倒推回來; |
| # 使用Bagging樹集成方法,理論上對缺失值的填補更權(quán)威,但其效率比較低; |
| # 使用中位數(shù)方法,速度非常快,但填補的準確率有待驗證。 |
| # 如果你想使用多重插補法,不妨也可以試試mice包,其操作原理是基于MC(蒙特卡洛模擬法)。 |
| # preProcess can be used to impute data sets based only on information in the training #set,注意只能用訓練集信息。 |
|
|
| #(1) 中位數(shù)法 ## |
| #用訓練集的中位數(shù)代替缺失值 |
|
| imputation_k = preProcess(datTrain,method = 'medianImpute') |
| datTrain1 = predict(imputation_k, datTrain) |
| (datTest1 = predict(imputation_k, datTest)) |
|
|
| median(datTrain$智力, na.rm = T) |
| # 顯然中位數(shù)這個填補方法不太合理,除非樣本取值比較均勻;注意這里用的也是訓練集的中位數(shù) |
|
|
| #(2) K近鄰方法 ## |
| #對于需要插值的記錄,基于歐氏距離計算k個和它最近的觀測, |
| #然后利用k個近鄰的數(shù)據(jù)來填補缺失值 |
|
|
| 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對測試集進行標準化 |
| #所以最后得到的數(shù)據(jù)是標準化之后的 |
| #如果想看原始值,那么還需要將其去標準化倒推回去 |
|
|
| ##4.處理0方差變量(刪除近零方差) |
| nearZeroVar()#找出近零方差的變量 |
|
|
| dim(datTrain) |
| (nzv = nearZeroVar(datTrain)) |
| datTrain = datTrain[, -nzv] |
|
|
| ##5.刪除共線性變量 |
| findCorrelation()#自動找到高度共線性的變量,并給出建議剔除的變量 |
| #數(shù)據(jù)中不能有缺失值 |
| #只能包含數(shù)值型變量 |
|
|
| # 數(shù)據(jù)中不能有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) |
| # 利用訓練集的均值和方差對測試集進行標準化 |