R語言進行機器學習方法及實例(一)

版權聲明:本文爲博主原創文章,轉載請註明出處算法

  機器學習的研究領域是發明計算機算法,把數據轉變爲智能行爲。機器學習和數據挖掘的區別多是機器學習側重於執行一個已知的任務,而數據發掘是在大數據中尋找有價值的東西。數據庫

機器學習通常步驟

  • 收集數據,將數據轉化爲適合分析的電子數據
  • 探索和準備數據,機器學習中許多時間花費在數據探索中,它要學習更多的數據信息,識別它們的微小差別
  • 基於數據訓練模型,根據你要學習什麼的設想,選擇你要使用的一種或多種算法
  • 評價模型的性能,須要依據必定的檢驗標準
  • 改進模型的性能,有時候須要利用更高級的方法,有時候須要更換模型

機器學習算法

有監督學習算法

用於分類:k近鄰,樸素貝葉斯,決策樹,規則學習,神經網絡,支持向量機
用於數值預測:線性迴歸,迴歸樹,模型樹,神經網絡,支持向量機網絡

無監督學習算法

用於模式識別(數據之間聯繫的緊密性):關聯規則
用於聚類:k均值聚類app

R語言機器學習算法實現

kNN(k-Nearest Neighbors,k近鄰)

  • 原理:計算距離,找到測試數據的k個近鄰,根據k個近鄰的分類預測測試數據的分類
  • 應用k近鄰須要將各個特徵轉換爲一個標準的範圍(歸一化處理),能夠應用min-max標準化(全部值落在0~1範圍,新數據=(原數據-最小值)/(最大值-最小值)),也能夠應用z-score 標準化(新數據=(原數據-均值)/標準差)。
  • 對於名義變量(表示類別),能夠進行啞變量編碼,其中1表示一個類別,0表示其它類別,對於n個類別的名義變量,能夠用n-1個特徵進行啞變量編碼,好比(高,中,低),能夠用高、中兩類的啞變量表示這三類(高:1是,0 其它,中:1是,0,其它)
  • 優勢:簡單且有效,對數據分佈沒有要求,訓練階段很快;
  • 缺點:不產生模型,在發現特徵之間的關係上的能力有限,分類階段很慢,須要大量的內存,名義變量和缺失數據須要額外處理
  • R代碼:
    使用class包的knn函數,對於測試數據中的每個實例,該函數使用歐氏距離標識k個近鄰,而後選出k個近鄰中大多數所屬的那個類,若是票數相等,測試實例會被隨機分配。
       dt_pred <- knn(train = dt_train,test = dt_test,class = dt_train_labels,k = 3) #train:一個包含數值型訓練數據的數據庫;test:一個包含數值型測試數據的數據框;class訓練數據每一行分類的一個因子變量;k:標識最近鄰數據的一個整數(一般取實例數的平方根); 該函數返回一個向量,該向量含有測試數據框中每一行的預測分類
      儘管kNN是並無進行任何學習的簡單算法,可是卻能處理及其複雜的任務,好比識別腫瘤細胞的腫塊。
  • 對R自帶iris數據用kNN進行訓練、預測並與實際結果對比
llibrary(class)
library(gmodels)

#prepare data
set.seed(12345) #set random seed in order to repeat the result
iris_rand <- iris[order(runif(150)),]
iris_z <- as.data.frame(scale(iris_rand[,-5])) #z score normalize
train <- iris_z[1:105,]
test <- iris_z[106:150,]
train.label <- iris_rand[1:105,5]
test.label <- iris_rand[106:150,5]

#kNN
pred <- knn(train,test,train.label,k=10)

#comfusion matrix 
CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)


  這個結果顯示kNN對測試數據所有預測正確dom

樸素貝葉斯分類

  • 原理:基於樸素貝葉斯定理,根據先驗機率計算預測實例的屬於不一樣類別的總似然,再將某類別的似然除以不一樣類別似然的和獲得預測實例在某類別的機率
  • 應用樸素貝葉斯算法每一個特徵必須是分類變量,對於數值型變量,能夠將數值型特徵離散化(分段),能夠根據直方圖查看數據明顯的分隔點,若是沒有明顯的分隔點,可使用三分位數,四分位數,五分位數,分段太少會把重要信息丟失
  • 拉普拉斯估計:對於某些歷來沒有出現的機率爲0的,會影響機率的估計,拉普拉斯估計本質上是在機率表的每一個計數加上一個較小的數,這樣保證每一類中每一個特徵發生的機率是非零的。
  • 優勢:簡單、快速、有效;能處理噪聲數據和缺失數據;須要用來訓練的例子相對較少,但一樣能處理好大量的例子;很容易得到一個預測的估計機率值;
  • 缺點:依賴於一個經常使用的錯誤假設,即同樣的重要性和獨立特徵;應用在大量數值特徵的數據集時並不理想;機率的估計值相對於預測的類而言更加不可靠。
  • R代碼:
    使用維也納理工大學統計系開發的e1071添加包中的naiveBayes
      m <- naiveBayes(train,class,laplace=0) #train:數據框或者包含訓練數據的矩陣,class:包含訓練數據每一行的分類的一個因子向量,laplace:控制拉普拉斯估計的一個數值,能夠進行調節看是否會提升模型性能;該函數返回一個樸素貝葉斯模型對象,該對象可以用於預測
       p <- predict(m,test,type="class") #m:由函數naiveBays( )訓練的一個模型 ,test:數據框或者包含測試數據的矩陣,包含與用來創建分類器的訓練數據的相同特徵;type:值爲"class"或者"raw",標識預測向量最可能的類別值或者原始預測的機率值
library(e1071)
library(gmodels)

set.seed(12345) #set random seed in order to repeat the result
iris_rand <- iris[order(runif(150)),]
train <- iris_rand[1:105,-5]
test <- iris_rand[106:150,-5]
train.label <- iris_rand[1:105,5]
test.label <- iris_rand[106:150,5]

#tranform numerical variable to classified variable
conver_counts <- function(x){
  q <- quantile(x)
  sect1 <- which(q[1] <= x & x<= q[2])
  sect2 <- which(q[2 ]< x & x <= q[3])
  sect3 <- which(q[3]< x & x <= q[4])
  sect4 <- which(q[4]< x & x <= q[5])
  x[sect1] <- 1
  x[sect2] <- 2
  x[sect3] <- 3
  x[sect4] <- 4
  return(x)
}
train <- apply(train,2,conver_counts)

#naiveBayes
m <- naiveBayes(train,train.label,laplace=1)
pred <- predict(m,test,type="class") 

#comfusion matrix 
CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)

可見對第一類(setosa)分類上預測錯誤率很高,這可能反映了樸素貝葉斯算法的缺點,對於處理大量數值特徵數據集時並不理想機器學習

決策樹

  • 原理:以樹形結構創建模型。使用一種稱爲遞歸劃分的探索法。這種方法一般稱爲分而治之,由於它利用特徵的值將數據分解爲具備類似類的較小的子集。從表明整個數據集的數據結點開始,該算法選擇最能預測目標類的特徵,而後,這些案例將被劃分到這一特徵的不一樣值的組中,這一決定造成了第一組樹枝。該算法繼續分而治之其餘結點,每次選擇最佳的候選特徵,直到達到中止的標準。若是一個節點中止,它可能具備下列狀況:節點上全部(幾乎全部)的案例都屬於同一類,沒有剩餘的特徵來分辯案例之間的區別,決策樹已經達到了預先定義的大小限制。
  • C5.0算法,時最知名的決策樹算法之一,單線程版本的源代碼是公開的,R中有編寫好的該程序。C5.0算法已經成爲生成決策樹的行業標準,由於它適用於大多數類型的問題,而且能夠直接使用。與其它先進的機器學習模型(神經網絡和支持向量機)相比,通常表現的幾乎同樣,而且更容易理解和部署
  • 選擇最佳的分割,須要確立分割的標準,有信息增益,基尼係數,卡方統計量,和增益比,C5.0算法使用信息增益
  • 修剪決策樹:若是決策樹增加過大,將會使決策過於具體,模型將會過分擬合訓練數據,解決這個問題的一種方法是一旦達到必定數量的決策,或者決策節點僅含有少許的案例,咱們就中止樹的增加,這叫作提早中止法,或者預剪枝決策樹法。分爲預剪枝(提早規定樹的大小)和後剪枝(一旦樹生長的過大,就根據節點處的錯誤率使用修剪準則將決策樹減小到更合適的大小,一般比預剪枝更有效)。
  • 自適應加強算法:進行許屢次嘗試,在決策樹中是創建許多決策樹,而後這些決策樹經過投票表決的方法爲每一個案例選擇最佳的分類。
  • 優勢:一個適用於大多數問題的通用分類器;高度自動化的學習過程,能夠處理數值型數據、名義特徵以及缺失數據;只使用最重要的特徵;能夠用於只有相對較少訓練案例的數據或者有至關多訓練案例的數據;沒有數學背景也可解釋一個模型的結果(對於比較小的樹);比其餘複雜的模型更有效
  • 缺點:決策樹模型在根據具備大量水平的特徵進行劃分時每每是有偏的;很容易過分擬合或者不能充分擬合模型;由於依賴於軸平行分割,因此在對一些關係創建模型時會有困難;訓練數據中的小變化可能致使決策邏輯的較大的變化;大的決策樹可能難以理解,給出的決策可能看起來違反直覺。
  • R代碼:
    使用R包C50的函數C5.0
      m <- C5.0(train,class,trials=1,costs=NULL) #train:一個包含訓練數據的數據框;class:包含訓練數據每一行的分類的一個因子;trials:爲一個可選數值,用於控制自適應加強循環的次數(默認值爲1),通常用10,由於研究標明,這能下降關於測試數據大約25%的機率;costs:爲一個可選矩陣,用於給出與各類類型錯誤相對應的成本,和混淆矩陣稍微不一樣,行用來表示預測值,列用來表示實際值);函數返回一個C5.0模型對象,該對象可以用於預測
      p <- predict(m,test,type="class") #m:有函數C5.0()訓練的一個模型;test:一個包含訓練數據的數據框,該數據框和用來建立分類其的數據框有一樣的特徵;type:取值爲"class"或者"prob",表識預測是最可能的類別值或者是原始的預測機率;該函數返回一個向量,根據參數type的取值,該向量含有預測的類別值或者原始預測的機率值
library(C50)
library(gmodels)

set.seed(12345) #set random seed in order to repeat the result
iris_rand <- iris[order(runif(150)),]
train <- iris_rand[1:105,-5]
test <- iris_rand[106:150,-5]
train.label <- iris_rand[1:105,5]
test.label <- iris_rand[106:150,5]

#C50
m <- C5.0(train,train.label,trials = 10)
pred <- predict(m,test,type="class") 

#comfusion matrix 
CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)

規則學習分類

  • 原理:規則學習算法使用了一種稱爲獨立而治之的探索法。這個過程包括肯定訓練數據中覆蓋一個案例子集的規則,而後再從剩餘的數據中分離出該分區。隨着規則的增長,更多的數據子集會被分離,直到整個數據集都被覆蓋,再也不有案例殘留,獨立而治之和決策樹的分而治之區別很小,決策樹的每一個決策節點會受到過去決策歷史的影響,而規則學習不存在這樣的沿襲。隨着規則的增長,更多的數據子集會被分離,知道整個數據集都被覆蓋,再也不有案例被保留
單規則(1R)算法
  • ZeroR,一個規則學習算法,從字面上看沒有規則學習,對於一個未標記的案例,不用考慮它的特徵值就會把它預測爲最多見的類
  • 單規則算法(1R或OneR)在ZeroR的基礎上添加一個規則。像K近鄰同樣雖然簡單,可是每每表現的比你預期的要好。
  • 優勢:能夠生成一個單一的、易於理解的、人類可讀的經驗法則(大拇指法則);表現每每出奇的好;能夠做爲更復雜算法的一個基準;
  • 缺點:只使用了一個單一的特徵;可能會過於簡單
  • R代碼:
    使用R包RWeka中OneR()函數來實現1R算法
      m <- OneR(class ~ predictors,data = mydata) #class:是mydata數據框中須要預測的那一列;predictors:爲一個公式,用來指定mydata數據框中用來進行預測的特徵;data:爲包含一個class和predictors所要求的數據的數據框;該函數返回一個1R模型對象,該對象可以用於預測
      p <- predict(m,test) #m:由函數OneR()訓練的一個模型;test:一個包含測試數據的數據框,該數據框和用來建立分類器的訓練數據有着相同的特徵;該函數返回一個含有預測的類別的向量
library(RWeka)
library(gmodels)

set.seed(12345) #set random seed in order to repeat the result
iris_rand <- iris[order(runif(150)),]
train <- iris_rand[1:105,]
test <- iris_rand[106:150,-5]
test.label <- iris_rand[106:150,5]

m <- OneR(Species ~ .,data=train)
pred <- predict(m,test)
CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)

查看生成的規則,按照Petal的寬度,分紅三類,正確分類了105個裏面的101個

對於測試數據的混合矩陣以下

可見只使用了一個規則也能,也作到了不錯的效果ide

RIPPER算法

  對於複雜的任務,只考慮單個規則可能過於簡單,考慮多個因素的更復雜的規則學習算法可能會有用,但也可能所以會變得更加難以理解。早期的規則學習算法速度慢,而且對於噪聲數據每每不許確,後來出現增量減小偏差修剪算法(IREP),使用了生成複雜規則的預剪枝和後剪枝方法的組合,並在案例從所有數據集分離以前進行修剪。雖然這提升了性能,可是仍是決策樹表現的更好。直到1995年出現了重複增量修剪算法(RIPPER),它對IREP算法進行改進後再生成規則,它的性能與決策樹至關,甚至超過決策樹。函數

  • 原理:能夠籠統的理解爲一個三步過程:生長,修剪,優化。生長過程利用獨立而治之技術,對規則貪婪地添加條件,直到該規則能徹底劃分出一個數據子集或者沒有屬性用於分割。與決策樹相似,信息增益準則可用於肯定下一個分割的屬性,當增長一個特指的規則而熵值再也不減小時,該規則須要當即修剪。重複第一步和第二步,直到達到一箇中止準則,而後,使用各類探索法對整套的規則進行優化。
  • 優勢:生成易於理解的、人類可讀的規則;對大數據集和噪聲數據有效;一般比決策樹產生的模型更簡單
  • 缺點:可能會致使違反常理或這專家知識的規則;處理數值型數據可能不太理想;性能有可能不如複雜的模型
  • R代碼:
    使用R包RWeka中JRip()函數,是基於Java實現的RIPPER規則學習算法
      m<JRip(class ~ predictors,data = my data) #class:是mydata數據框中須要預測的那一列;predictors:爲一個R公式,用來指定mydata數據框中用來進行預測的特徵;data:爲包含class和predictors所要求的數據的數據框;該函數返回一個RIPPER模型對象,該對象可以用於預測。
      p <- predict(m , test) #m:由函數JRip()訓練的一個模型;test:一個包含測試數據的數據框,該數據框和用來建立分類器的訓練數據有一樣的特徵;該函數返回一個含有預測的類別值的向量。
library(RWeka)
library(gmodels)

set.seed(12345) #set random seed in order to repeat the result
iris_rand <- iris[order(runif(150)),]
train <- iris_rand[1:105,]
test <- iris_rand[106:150,-5]
test.label <- iris_rand[106:150,5]

m <- JRip(Species ~ .,data=train)
pred <- predict(m,test)
CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)


此次使用了三個規則,(Petal.Width >= 1.8爲virginica ,Petal.Length >= 3爲versicolor,其它爲setosa

可見雖然增長了規則可是並無提升模型的性能性能

預測數值型數據

線性迴歸

  迴歸主要關注一個惟一的因變量(須要預測的值)和一個或多個數值型自變量之間的關係。學習

  • 若是隻有一個自變量,稱爲一元線性迴歸或者簡單線性迴歸,不然,稱爲多元迴歸。
  • 原理:對線性參數的估計使用最小二乘估計
  • 廣義線性迴歸:它們對線性模型進行了兩方面的推廣:經過設定一個鏈接函數,將響應變量的指望與線性變量相聯繫,以及對偏差的分佈給出一個偏差函數。這些推廣容許許多線性的方法可以被用於通常的問題。好比邏輯迴歸能夠用來對二元分類的結果建模;而泊松迴歸能夠對整型的計數數據進行建模。
  • 優勢:迄今爲止,它是數值型數據建模最經常使用的方法;可適用於幾乎全部的數據;提供了特徵(變量)之間關係的強度和大小的估計
  • 缺點:對數據做出了很強的假設;該模型的形式必須由使用者事先指定;不能很好地處理缺失數據;只能處理數值特徵,因此分類數據須要額外的處理;須要一些統計學知識來理解模型。
  • LASSO迴歸算法:LASSO迴歸的特色是在擬合廣義線性模型的同時進行變量篩選(只選擇對因變量有顯著影響的自變量)和複雜度調整(經過參數控制模型複雜度,避免過分擬合)。它經過懲罰最大似然來擬合廣義線性模型,正則化路徑是經過正則化參數lambda的值的網格上計算lasso或者彈性網絡懲戒,lambda越大對變量較多的線性模型的懲罰力度就越大,從而最終得到一個變量較少的模型。
  • R代碼:
    使用R包glmnet中glmnet()函數擬合LASSO迴歸模型
      glmnet(x, y, family=c("gaussian","binomial","poisson","multinomial","cox","mgaussian"),
        weights, offset=NULL, alpha = 1, nlambda = 100,
         lambda.min.ratio = ifelse(nobs<nvars,0.01,0.0001), lambda=NULL,
         standardize = TRUE, intercept=TRUE, thresh = 1e-07, dfmax = nvars + 1,
         pmax = min(dfmax * 2+20, nvars), exclude, penalty.factor = rep(1, nvars),
        lower.limits=-Inf, upper.limits=Inf, maxit=100000,
        type.gaussian=ifelse(nvars<500,"covariance","naive"),
         type.logistic=c("Newton","modified.Newton"),
         standardize.response=FALSE, type.multinomial=c("ungrouped","grouped"))

  x: 輸入矩陣,每列表示變量(特徵),每行表示一個觀察向量,也支持輸入稀疏矩陣(Matrix中的稀疏矩陣類);
  y: 反應變量,對於gaussian或者poisson分佈族,是相應的量;對於binomial分佈族,要求是兩水平的因子,或者兩列的矩陣,第一列是計數或者是比例,第二列是靶向分類;對於因子來講,最後的水平是按照字母表排序的分類;對於multinomial分佈族,能有超過兩水平的因子。不管binomial或者是multinomial,若是y是向量的話,會強制轉化爲因子。對於cox分佈族,y要求是兩列,分別是time和status,後者是二進制變兩,1表示死亡,0表示截尾,survival包帶的Surv()函數能夠產生這樣的矩陣。對於mgaussian分佈族,y是量化的反應變量的矩陣;
  family: 反應類型,參數family規定了迴歸模型的類型:family="gaussian"適用於一維連續因變量(univariate)family="mgaussian",適用於多維連續因變量(multivariate),family="poisson"適用於非負次數因變量(count),family="binomial"適用於二元離散因變量(binary),family="multinomial"適用於多元離散因變量(category)
  weights: 權重,觀察的權重。若是反應變量是比例矩陣的話,權重是總計數;默認每一個觀察權重都是1;
  offset: 包含在線性預測中的和觀察向量一樣長度的向量,在poisson分佈族中使用(好比log後的暴露時間),或者是對於已經擬合的模型的從新定義(將舊模型的因變量做爲向量放入offset中)。默認是NULL,若是提供了值,該值也必須提供給predict函數;
  alpha: 彈性網絡混合參數,0 <= a <=1,懲罰定義爲(1-α)/2||β||_2^2+α||β||_1.其中alpha等於1是lasso懲罰,alpha等於0是ridge(嶺迴歸)的懲罰;
  nlambda:lambda值個數;擬合出n個係數不一樣的模型
  lambda.min.ratio:lambda的最小值,lambda.max的比例形式,好比所有係數都是0的時候的最小值。默認值依賴於觀察的個數和特徵的個數,若是觀察個數大於特徵個數,默認值是0.0001,接近0,若是觀察個數小於特徵個數,默認值是0.01。在觀察值個數小於特徵個數的狀況下,很是小的lambda.min.ratio會致使過擬合,在binominal和multinomial分佈族性,這個值未定義,若是解釋變異百分比老是1的話程序會自動退出;
  lambda:用戶提供的lambda序列。一個典型的用法基於nlambada和lambda.min.ratio來計算自身lambda序列。若是提供lambda序列,提供的lambda序列會覆蓋這個。需謹慎使用,不要提供單個值給lambda(對於CV步驟後的預測,應使用predict()函數替代)。glmnet依賴於緩慢開始,而且它用於擬合全路徑比計算單個擬合更快;
  standardize:對於x變量是否標準化的邏輯標誌,傾向於擬合模型序列。 係數老是在原有規模返回,默認standardize=TRUE。若是變量已是同一單位,你可能並不能獲得想要的標準化結果。
  intercept:是否擬合截距,默認TRUE,或者設置爲0(FALSE)
  thresh:座標降低的收斂域值,每一個內部座標降低一直進行循環,直到係數更新後的最大改變值比thresh值乘以默認變異要小,默認thresh爲1E-7;
  dfmax:在模型中的最大變量數,對於大量的變量數的模型但咱們只須要部分變量時能夠起到做用;
  pmax:限制非零變量的最大數目;
  exclude:要從模型中排除的變量的索引,等同於一個無限的懲罰因子;
  penalty.factor:懲罰因子,分開的懲罰因子可以應用到每個係數。這是一個數字,乘以lambda來容許不一樣的收縮。對於一些變量來講能夠是0,意味着無收縮,默認對所有變量是1,對於列在exlude裏面的變量是無限大。注意:懲罰因子是內部對nvars(n個變量)的和進行從新調整,而且lambda序列將會影響這個改變;
  lower.limits:對於每一個係數的更低限制的向量,默認是無窮小。向量的每一個值須非正值。也能夠以單個值呈現(將會重複),或者是(nvars長度);
  upper.limit:對於每一個係數的更高限制的向量,默認是無窮大;
  maxit:全部lambda值的數據最大傳遞數;
  type.gaussian:支持高斯分佈族的兩種算法類型,默認nvar < 500使用"covariance「,而且保留全部內部計算的結果。這種方式比"naive"快,"naive"經過對nobs(n個觀察)進行循環,每次內部計算一個結果,對於nvar >> nobs或者nvar > 500的狀況下,後者每每更高效;
  type.logistic:若是是"Newton「,會使用準確的hessian矩陣(默認),當用的是"modified.Newton「時,只使用hession矩陣的上界,會更快;
  standardize.response:這個參數時對於"mgaussian「分佈族來講的,容許用戶標準化應答變量;
  type.multinomial:若是是"grouped",在多項式係數的變量使用分佈lasso懲罰,這樣能確保它們徹底在一塊兒,默認是"ungrouped"。

glmnet返回S3類,"glmnet","*","*"能夠是elnet,lognet,multnet,fishnet(poisson),merlnet
  call:產生這個對象的調用;
  a0:截距;
  beta:對於elnet, lognet, fishnet和coxnet模型,返回稀疏矩陣格式的係數矩陣(CsparseMatrix),對於multnet和mgaussian模型,返回列表,包括每一類的矩陣;
  lambda:使用的lambda值的實際序列;當alpha=0時,最大的lambda值並不僅僅等於0係數(原則上labda等於無窮大),相反使用alpha=0.01的lambda,由此導出lambda值;
  dev.ratio:表示由模型解釋的變異的百分比(對於elnet,使用R-sqare)。若是存在權重,變異計算會加入權重,變異定義爲2x(loglike_sat-loglike),loglike_sat是飽和模型(每一個觀察值具備自由參數的模型)的log似然。所以dev.ratio=1-dev/nulldev;越接近1說明模型的表現越好
  nulldev:NULL變異(每一個觀察值),這個定義爲2*(loglike_sat-loglike(Null));NULL模型是指截距模型,除了Cox(0 模型);
  df:對於每一個lambda的非零係數的數量。對於multnet這是對於一些類的變量數目;
  dfmat:僅適用於multnet和mrelnet。一個包括每一類的非零向量數目的矩陣;
  dim:係數矩陣的維度;
  nobs:觀察的數量;
  npasses:所有lambda值加和的數據的總的通量;
  offset:邏輯變量,顯示模型中是否包含偏移;
  jerr:錯誤標記,用來警告和報錯(很大部分用於內部調試驗)
  而直接顯示的結果有三列,分別是df,%Dev (就是dev.ratio),lambda是每一個模型對應的λ值

predict(object,newx,s=NULL,type=c("link","reponse","coefficients","nonzero","class"),exact=FALSE,offset,...)
  coef(object,s=NULL,exact=FALSE)
  object:glmnet返回的對象;
  newx:用來預測的矩陣,也能夠是係數矩陣;這個參數不能用於type=c(""coefficents","nonzero");
  s:懲罰參數lambda的值,默認是用來建立模型的所有lambda值;
  type:預測值的類型;"link」類型給"binomial",「multinomial","poisson"或者"cov"模型線性預測的值,對於"gaussian」模型給擬合值。"response"類型,對於"binominal「和"multinomial」給擬合的機率,對於"poisson「,給擬合的均值,對於"cox",給擬合的相對未及;對於"gaussion",response等同於"link「類型。"coefficients"類型對於需求的s值計算係數。注意,對於"binomial」模型來講,結果僅僅對因子應答的第二個水平的類返回。「class"類型僅僅應用於"binomial」和"multinomial「模型,返回最大可能性的分類標籤。"nonzero」類型對每一個s中的值返回一個列表,其中包含非0參數的索引;
  exact:這個參數僅僅對於用於預測的s(lambda)值不一樣於原始模型的擬合的值時,這個參數起到做用。若是exact=FALSE(默認),預測函數使用線性解釋來對給的s(lambda)值進行預測。這時一個很是接近的結果,只是稍微有點粗糙。若是exact=TRUE,這些不一樣的s值和擬合對象的lambda值進行sorted和merged,在做出預測以前進行模型的從新擬合。在這種狀況下,強烈建議提供原始的數據x=和y=做爲額外的命名參數給perdict()或者coef(),predict.glmnet()須要升級模型,而且指望用於建立接近它的數據。儘管不提供這些額外的參數它也會運行的很好,在調用函數中使用嵌套序列極可能會中斷。
  offset:若是使用offset參數來擬合,必須提供一個offset參數來做預測。除了類型"coefficients"或者"nonzero「
  ...:能夠提供參數其它參數的機制,好比x=when exact=TRUE,seeexact參數。

library(glmnet )
library(psych)

#dummy variable encoding
iris$issetosa <- ifelse(iris$Species=="setosa",1,0)
iris$isversicolor <- ifelse(iris$Species=="versicolor",1,0)
iris_dt <- iris[,-5]
pairs.panels(iris_dt) #scatterplot matrix

  pairs.panel畫出散點圖矩陣,對角線上方顯示的是變量之間的相關係數,每一個散點圖中呈橢圓形的對象稱爲相關橢圓,它提供一種變量之間是如何密切相關的可視化信息。位於橢圓中間的的點表示x軸變量和y軸變量的均值所肯定的點。兩個變量之間的相關性由橢圓的形狀表示,橢圓越被拉伸,其相關性就越強。散點圖中繪製的曲線稱爲局部迴歸平滑,它表示x軸和y軸變量之間的通常關係。iris數據畫出的散點圖矩陣中的相關係數和散點圖曲線均可見Petal.Length和Petal.Width有着強的相關性,而從散點圖曲線也可看出,彷佛Sepal.Length超出必定閾值後,Sepal.Length增長,Petal.Length也增長,而且也和品種是setosa或者versicolor也有關係。以Petal.Width做爲因變量做線性迴歸。

library(glmnet )

#dummy variable encoding
iris$issetosa <- ifelse(iris$Species=="setosa",1,0)
iris$isversicolor <- ifelse(iris$Species=="versicolor",1,0)

#divided into training sets and test sets
set.seed(12345) #set random seed in order to repeat the result
iris_rand <- iris[order(runif(150)),]
train <- iris_rand[1:105,-c(4,5)]
test <- iris_rand[106:150,-c(4,5)]
train_value  <- iris_rand[1:105,4]
test_value  <- iris_rand[106:150,4]

#lasso
m_lasso <- glmnet(as.matrix(train),train_value,family = "gaussian")

plot(data.frame(df=m_lasso$df,dev.ratio=m_lasso$dev.ratio),type="b",cex=0.6)
coef(m_lasso, s=0.0497000)  #min df

查看變量個數與模型解釋變異百分比的點圖,發如今df=1時已經開始平緩,已經能夠解釋93%的變異。所以取df=1的能夠解釋最大變異的lambda,0.0452800,查看係數發現使用了兩個特徵,其中一個係數很是低,並非咱們須要的,所以lambda改成第二個解釋最大變異的lambda,0.0497000.
用coef取出參數以下
lambda=0.0452800

lambda=0.0497000

用選出的lambda值進行預測

pred <- predict(m_lasso,newx=as.matrix(test),s=0.0497000)
summary(pred)
summary(test_value)
cor(test_value,pred)
MAE <- mean(abs(pred - test_value))
mean(abs(mean(train_value) - test_value))

發現預測值和真實值範圍很是接近

相關係數高

MAE(平均絕對偏差,反映預測值和真實值的差距)僅爲0.1981803,若是隻是拿訓練集的均值預測的話,MAE高達0.6551746)

綜合以上的度量標準,說明咱們的模型預測的不錯。

迴歸樹和模型樹
  • 決策樹用於數值預測分爲兩類,第一類稱爲迴歸樹,第二類稱爲模型樹。
  • 迴歸樹做爲分類迴歸樹的一部分引入,迴歸樹並無使用線性迴歸的辦法,而是基於到達節點的案例的平均值進行預測。
  • 模型樹,比迴歸樹晚幾年引入,可是或許功能更增強大。模型樹和迴歸樹以大體相同的方式生長,可是在每一個葉節點,根據到達該節點的案例創建多元線性迴歸模型。根據葉節點的數目,一棵模型樹可能會創建幾十個甚至幾百個這樣的模型,這可能會使模型樹更加難以理解,但好處是它們也許能創建一個更加精確的模型。
  • 優勢:將決策樹的優勢與數值型數據創建模型的能力相結合;能自動選擇特徵,容許該方法和大量特徵一塊兒使用;不須要使用者事先指定模型;擬合某些類型的數據可能會比線性迴歸好得多;不要求用統計的知識來解釋模型。
  • 缺點:不像線性迴歸那樣經常使用;須要大量的訓練數據;難以肯定單個特徵對於結果的整體淨影響;可能比迴歸模型更難解釋。
  • 原理:用於數值預測的決策樹的創建方式與用於分類的決策樹的創建方式大體相同。從根節點開始,按照特徵使用分而治之的策略對數據進行劃分,在進行一次分割後,將會致使數據最大化的均勻增加。而在分類決策樹中,一致性(均勻性)是由熵值來度量的,而對於數值型的數據是未定義的,對於數值型決策樹,一致性能夠經過統計量(好比方差、標準差或者平均絕對誤差)來度量。不一樣的決策樹生長算法,一致性度量可能會有所不一樣,但原理是基本相同的。
  • 一種常見的分割標準是標準誤差減小,就是原始值的標準差減去分割後不一樣類的數據加權後的標準差,這裏的加權就是該類的數目比上總的數目。決策樹中止生長後,假如一個案例使用特徵B進行分割,落入某一組B1中,那麼該案例的預測值將取B1組的平均值。模型樹要多走一步,使用落入B1組的訓練案例和落入B2組的訓練案例,創建一個相對於其它特徵(特徵A)的線性迴歸模型。
  • R代碼:
      在R包rpart(遞歸劃分)中提供了像CART(分類迴歸樹)團隊中所描述的最可靠的迴歸樹的實現,
      m.rpart <- rpart(dv ~ iv, data = mydata) #dv 是mydata 數據框中須要建模的因變量;iv 爲一個R公式,用來指定mydata數據框中的自變量;data:爲包含變量dv和變量iv的數據框
      p <- predict(m,test,type=c("vector", "prob", "class", "matrix")) #m是有函數rpart訓練的一個模型;test一個包含測試數據的數據框,該數據框和用來創建模型的數據具備相同的特徵;type:給定返回的預測值的類型,prob返回預測的機率。matrix返回矩陣的形式包括各種的機率。class返回樹的分類。不然返回一個向量的結果。
      可使用R包rpart.plot中rpart.plot函數對迴歸樹結果可視化。
      目前模型樹中最早進的算法是M5'算法,能夠經過R包Rweka中M5P函數實現;
      m <- M5P(dv ~ iv, data = mydata) #dv 是mydata 數據框中須要建模的因變量;iv 爲一個R公式,用來指定mydata數據框中的自變量;data:爲包含變量dv和變量iv的數據框
      p <- predict(m,test) #m是有函數rpart訓練的一個模型;test一個包含測試數據的數據框,該數據框和用來創建模型的數據具備相同的特徵
library(rpart)
library(RWeka)
library(rpart.plot)

#dummy variable encoding
iris$issetosa <- ifelse(iris$Species=="setosa",1,0)
iris$isversicolor <- ifelse(iris$Species=="versicolor",1,0)

#divided into training sets and test sets
set.seed(12345) #set random seed in order to repeat the result
iris_rand <- iris[order(runif(150)),]
train_dt <- iris_rand[1:105,-5]
test <- iris_rand[106:150,-c(4,5)]
test_value  <- iris_rand[106:150,4]

#rpart
m.rpart <- rpart(Petal.Width ~ Sepal.Length+Sepal.Width+Petal.Length+issetosa+isversicolor,data = train_dt)
summary(m.rpart)
rpart.plot(m.rpart)
pred <- predict(m.rpart,test)
cor(test_value,pred)
mean(abs(pred - test_value)) #rpart MAE
mean(abs(mean(train_dt$Petal.Width) -  test_value)) #mean MAE

#M5P
m.M5P <- M5P(Petal.Width ~ Sepal.Length+Sepal.Width+Petal.Length+issetosa+isversicolor,data = train_dt)
summary(m.M5P)
pred <- predict(m.M5P,test)
cor(test_value,pred)
mean(abs(pred - test_value)) #rpart MAE
mean(abs(mean(train_dt$Petal.Width) -  test_value)) #mean MAE

迴歸樹的結果以下

rpart.plot結果

  相關性到達0.9797762,迴歸樹(MAF0.1242998)明顯比直接用均值預測(MAF0.7255238)更接近於真實的Petal.Width
模型樹的結果以下

  相關係數到達0.9714331,MAF0.1410668,在這個模型樹中,只有一個根節點,相應創建了一個線性模型,直接用Sepal.Length ,Sepal.Width ,Petal.Length三個特徵進行預測,和lasso迴歸模型同樣,特徵前面的係數表明該特徵對Petal.Width的靜影響,注意,這裏的淨影響是指在當前節點這個線性模型中的淨影響,在這個線性模型中,每增長一點Sepal.Width和Petal.Length,Petal.Width都會增長,而係數小於0的Sepal.Length ,意味着每增長一點Sepal.Length,Petal.Width就會減小。從結果能夠看出,在這個案例中,模型樹沒有迴歸樹的效果好。
  此處模型樹在沒有生成多個樹節點的狀況下,只是對特徵作了線性迴歸,MAF達到0.1410668,和以前對數據做線性迴歸的lasso模型結果(MAF0.1981803)相比,貌似作的更好,但其實以前的lasso迴歸模型咱們限制了特徵值個數來避免過擬合,若是增長特徵值數量和調整labda參數,同樣能夠達到比較小的MAF。

小結

  本文主要講了機器學習的一些基本概念,還有部分機器學習方法的基本原理及R語言實現。包括用於分類的機器學習方法:k近鄰,樸素貝葉斯,決策樹,規則學習;用於數值預測的機器學習方法:lasso迴歸,迴歸樹,模型樹,它們都屬於監督學習。下篇文章會說到監督學習中的神經網絡和支持向量機,還有其餘非監督學習的一些方法。
  本文能夠做爲一個速查和簡單的入門,一些函數只列舉了部分重要的參數,具體的使用參數能夠經過查看R裏面的幫助得到。另外若是要用於實踐,還須要瞭解一些K折交叉檢驗,kappa統計量,ROC曲線內容,以對模型的性能進行評價和對不一樣的模型進行對比。

參考資料

Brett Lantz:機器學習與R語言
薛毅,陳立萍: 統計建模與R軟件(下冊)
侯澄鈞:熱門數據挖掘模型應用入門(一): LASSO : https://cosx.org/2016/10/data-mining-1-lasso
slade_sha的博客 Lasso算法理論介紹 :http://blog.csdn.net/slade_sha/article/details/53164905

相關文章
相關標籤/搜索