ISLR系列:(2)分類 Logistic Regression & LDA & QDA & KNN


   Classification

此博文是 An Introduction to Statistical Learning with Applications in R 的系列讀書筆記,作為本人的一份學習總結,也希望和朋友們進行交流學習。

該書是The Elements of Statistical Learning 的R語言簡明版,包含了對算法的簡明介紹以及其R實現,最讓我感興趣的是算法的R語言實現

  【轉載時請注明來源】:http://www.cnblogs.com/runner-ljt/

   Ljt   勿忘初心  無畏未來

   作為一個初學者,水平有限,歡迎交流指正。


     前一篇博文講的線性回歸模型主要針對因變量是定量的情形,而對於因變量是定性的情況則需要采用分類算法。

     本篇將講述三類常用的分類算法:邏輯回歸   Logistic Regression(LR) 

                                                  線性/二次判別分析   Linear Discriminant Analysis(LDA) / Quadratic Discriminant Analysis(QDA)

                                                  K最近鄰法   K-nearest neighbors(KNN) 

     首先,本文將從整體上來比較這三類分類算法:

    (1) 當真實的分類邊界是線性時,LR和LDA通常會表現更好;當真實的分類邊界是一般的非線性時,QDA通常會表現更好;當真實的分類邊界

             更為復雜時, KNN 通常會表現的更好。

    (2) LR和LDA 都將產生線性分類邊界,兩種唯一的不同是LR的系數估計是通過極大似然法,而LDA的系數是運用正態分布的均值和方差的估計

             值計算得到的;LR適用於二分類問題,對於多分類問題,LDA則更為常見。

    (3) 當樣本能夠被完全線性分類時,LR的參數估計將會出現不穩定情況,此時LR方法不適用(詳細見另一篇博文 廣義線性模型 R--glm函數),

             LDA參數估計則不會出現這種情況;當樣本量較小且自變量的分布近似於狀態分布時,LDA會比LR表現的更好。

    (4) LDA和QDA都是建立在自變量服從正態分布的假設上,所以當自變量的分布確實是幾乎服從正態分布時,這兩種方法會表現的較好;

             LDA和QDA 的區別在於LDA假設所有類別的自變量都服從方差相同的正態分布,而QDA假設對於因變量屬於不同類別的自變量服從方差不

             同的正態分布,選擇LDA和QDA的關鍵在於偏置--方差的權衡。

    (5) QDA可以認為是非參數學習法KNN和具有線性分類邊界的LR及LDA方法的折中,QDA假設分類邊界是二次的,所以它能夠比線性模型更准

             確的為更多的問題建立模型;同時由於其二次邊界的額外假設,當樣本量較小時,其能夠優於KNN方法。

    (6) KNN是非參數學習方法,因此它不對分類邊界做任何假設,當分類邊界為高度非線性是便會優於RL和LDA,但是其不能反映每個自變量對因

             變量的影響。

    (7) LR可以適用於含有定性自變量的模型,對於定性的自變量LR會將其轉換為虛擬變量,但是LDA、QDA及KNN都不適用於定性的自變量。

 


 Logistic Regression

  (1)廣義線性回歸:glm(formula, family = gaussian, data, subset)

       family: binomial(link = "logit")  因變量服從伯努利分布,連接函數為logit;

                        gaussian(link = "identity")  因變量服從高斯分布,連接函數為identity

                        poisson(link = "log")  因變量服從泊松分布,連接函數為log.

         subset :可選向量,用於指定data中用於測試的數據集 .

  (2)預測函數:predict(object, newdata = NULL, type = c("link", "response", "terms"))

       newdata:預測樣本數據,當為NULL時預測樣本為測試樣本,data.frame格式;

       type : link --- 連接函數 ΘX 的值 【  p(y=1)=1/(1+e-ΘX ) 】  ;

                response ---預測結果是樣本類別為1的概率  ;

                terms  ---  The 'terms' option returns a matrix giving the fitted values of each term in the model formula

                                 on the linear predictor scale.

  (3)虛擬變量設置:contrasts(x)

       在預測結果中的概率為樣本結果是1類的概率(即虛擬變量為1所代表的類別)

 

> library(ISLR)
> head(Smarket)
  Year   Lag1   Lag2   Lag3   Lag4   Lag5 Volume  Today Direction
1 2001  0.381 -0.192 -2.624 -1.055  5.010 1.1913  0.959        Up
2 2001  0.959  0.381 -0.192 -2.624 -1.055 1.2965  1.032        Up
3 2001  1.032  0.959  0.381 -0.192 -2.624 1.4112 -0.623      Down
4 2001 -0.623  1.032  0.959  0.381 -0.192 1.2760  0.614        Up
5 2001  0.614 -0.623  1.032  0.959  0.381 1.2057  0.213        Up
6 2001  0.213  0.614 -0.623  1.032  0.959 1.3491  1.392        Up
> 
>glm.fit<-glm(Direction~Lag1+Lag2+Lag3+Lag4+Lag5+Volume,data=Smarket,family=binomial)
> summary(glm.fit)

Call:
glm(formula = Direction ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 + 
    Volume, family = binomial, data = Smarket)

Deviance Residuals: 
   Min      1Q  Median      3Q     Max  
-1.446  -1.203   1.065   1.145   1.326  

Coefficients:
             Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.126000   0.240736  -0.523    0.601
Lag1        -0.073074   0.050167  -1.457    0.145
Lag2        -0.042301   0.050086  -0.845    0.398
Lag3         0.011085   0.049939   0.222    0.824
Lag4         0.009359   0.049974   0.187    0.851
Lag5         0.010313   0.049511   0.208    0.835
Volume       0.135441   0.158360   0.855    0.392

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 1731.2  on 1249  degrees of freedom
Residual deviance: 1727.6  on 1243  degrees of freedom
AIC: 1741.6

Number of Fisher Scoring iterations: 3

> 
> #預測
> glm.probs<-predict(glm.fit,type='response')
> glm.probs[1:10]
        1         2         3         4         5         6         7         8         9        10 
0.5070841 0.4814679 0.4811388 0.5152224 0.5107812 0.5069565 0.4926509 0.5092292 0.5176135 0.4888378 
> contrasts(Smarket$Direction)
     Up
Down  0
Up    1
> #衡量模型效果
> glm.pred<-rep('Down',1250)
> glm.pred[glm.probs>0.5]<-'Up'
> table(glm.pred,Direction)
Error in table(glm.pred, Direction) : object 'Direction' not found
> table(glm.pred,Smarket$Direction)
        
glm.pred Down  Up
    Down  145 141
    Up    457 507
> 

 


 Linear Discriminant Analysis

   (1) 線性判別分析 lda(formula, data, ..., subset)        

          返回結果: 先驗概率 Prior probabilities of groups
                             各類別種每個自變量的均值 Group means
                             判別邊界系數  Coefficients of linear discriminants
                                                    y= - 0.7567605*Lag1 - 0.4707872*Lag2

  (2) 預測:predict(lda.fit)
          返回結果:預測類別class
                             類的后驗概率 posterior (每一樣本屬於各類別的后驗概率,通常以0.5為界進行分類,但可以指定后驗概率為α來分類)

> library(MASS)
> lda.fit<-lda(Direction~Lag1+Lag2,data=Smarket)
> lda.fit
Call:
lda(Direction ~ Lag1 + Lag2, data = Smarket)

Prior probabilities of groups:
  Down     Up 
0.4816 0.5184 

Group means:
            Lag1        Lag2
Down  0.05068605  0.03229734
Up   -0.03969136 -0.02244444

Coefficients of linear discriminants:
            LD1
Lag1 -0.7567605
Lag2 -0.4707872
> #預測
> lda.pred<-predict(lda.fit)
> names(lda.pred)
[1] "class"     "posterior" "x"        
> lda.class<-lda.pred$class
> lda.class[1:10]
 [1] Up   Down Down Up   Up   Up   Down Up   Up   Down
Levels: Down Up
> table(lda.class)
lda.class
Down   Up 
 216 1034 
> table(lda.class,Smarket$Direction)
         
lda.class Down  Up
     Down  114 102
     Up    488 546
> #改變判別准則
> lda.pred$posterior[1:10,]
        Down        Up
1  0.4861024 0.5138976
2  0.5027466 0.4972534
3  0.5104516 0.4895484
4  0.4817860 0.5182140
5  0.4854771 0.5145229
6  0.4920394 0.5079606
7  0.5085978 0.4914022
8  0.4896886 0.5103114
9  0.4774690 0.5225310
10 0.5049515 0.4950485
> #將概率大於0.5就判為UP類在准則改為大於0.51
> sum(lda.pred$posterior[,2]>0.51)
[1] 822

 


 Quadratic Discriminant Analysis

     二次判別分析 qda(formula, data, ..., subset)

> 
> library(MASS)
> qda.fit<-qda(Direction~Lag1+Lag2,data=Smarket)
> qda.fit
Call:
qda(Direction ~ Lag1 + Lag2, data = Smarket)

Prior probabilities of groups:
  Down     Up 
0.4816 0.5184 

Group means:
            Lag1        Lag2
Down  0.05068605  0.03229734
Up   -0.03969136 -0.02244444
> qda.pred<-predict(qda.fit,Smarket)
> names(qda.pred)
[1] "class"     "posterior"
> qda.pred$class[1:10]
 [1] Up   Up   Down Up   Up   Up   Down Up   Up   Up  
Levels: Down Up
> qda.pred$posterior[1:10,]
        Down        Up
1  0.4754475 0.5245525
2  0.4944981 0.5055019
3  0.5083068 0.4916932
4  0.4780731 0.5219269
5  0.4773961 0.5226039
6  0.4836726 0.5163274
7  0.5013701 0.4986299
8  0.4916379 0.5083621
9  0.4675238 0.5324762
10 0.4967838 0.5032162
> table(qda.pred$class,Smarket$Direction)
      
       Down  Up
  Down  109  94
  Up    493 554
> 

 


K-Nearest Neighbors

      K最近鄰 knn(train, test, cl, k = 1)

                       測試集(matrix/data.frame)   train  ;    訓練集(matrix/data.frame)   test    ;   測試集的正確類 cl    ;   參考的鄰近元個數 k

        在使用knn(...)之前需要設置隨機種子,因為當最K鄰近元的個數超過K時,對第K最鄰近元會隨機選擇,設置隨機種子可以保證模型結果的可重復

> 
> library(class)
> attach(Smarket)
> train<-Year<2005
> #測試集和訓練集
> train.X<-cbind(Lag1,Lag2)[train,]
> test.X<-cbind(Lag1,Lag2)[!train,]
> train.Y<-Direction[train]
> #設置隨機種子
> set.seed(1)
> knn.pred<-knn(train.X,test.X,train.Y,k=1)
> knn.pred[1:10]
 [1] Up   Down Up   Up   Up   Down Down Down Down Up  
Levels: Down Up
>#K=1
> table(knn.pred,Direction[!train])
        
knn.pred Down Up
    Down   43 58
    Up     68 83
> #K=3
> knn.pred<-knn(train.X,test.X,train.Y,k=3)
> table(knn.pred,Direction[!train])
        
knn.pred Down Up
    Down   48 54
    Up     63 87
> 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM