1. 程式人生 > >【機器學習】R語言進行機器學習方法及例項

【機器學習】R語言進行機器學習方法及例項

R語言進行機器學習方法及例項


機器學習的研究領域是發明計算機演算法,把資料轉變為智慧行為。機器學習和資料探勘的區別可能是機器學習側重於執行一個已知的任務,而資料發掘是在大資料中尋找有價值的東西。

機器學習一般步驟

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

機器學習演算法

有監督學習演算法

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

無監督學習演算法

用於模式識別(資料之間聯絡的緊密性):關聯規則
用於聚類:k均值聚類

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對測試資料全部預測正確

樸素貝葉斯分類

  • 原理:基於樸素貝葉斯定理,根據先驗概率計算預測例項的屬於不同類別的總似然,再將某類別的似然除以不同類別似然的和得到預測例項在某類別的概率
  • 應用樸素貝葉斯演算法每個特徵必須是分類變數,對於數值型變數,可以將數值型特徵離散化(分段),可以根據直方圖檢視資料明顯的分隔點,如果沒有明顯的分隔點,可以使用三分位數,四分位數,五分位數,分段太少會把重要資訊丟失
  • 拉普拉斯估計:對於某些從來沒有出現的概率為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個

對於測試資料的混合矩陣如下

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

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

原文連結:https://www.cnblogs.com/ywliao/p/7182090.html