close

這篇要記錄邏輯斯迴歸分析(Logistic Regression Analysis),

一種延伸線性迴歸分析(Linear Regression Analysis)的概念, 

 

※※※線性迴歸分析的概念※※※

從我們有興趣的目標群體收集變數, 包含 反應變數(Response Variable)與預測變數(Predictive Variable),

用符號來表示, Y就是反應變數, {X1,...,XP} 就是預測變數. 我們希望了解, Y的數值表現是不是與X有關?

也就是想要知道, 是否存在某一個函數f, 可以把Y與X的關係建立起來:

                         Y=f(X)

或者更簡單一點說, Y的數值變化是不是能用X的線性組合來描述? 就像是下面所示:

            Y=b0+b1*X1+b2*X2+...+bP*XP

上式很清楚表達了, X1變動1個單位, Y會變動 b1個單位. (因為 Y=b1*1, 其他相對而言都是常數, 不會變動)

當然,  這樣的線性組合無法合理解釋真實世界呈現的風貌, 所以 就給他加了隨機誤差在等式的右邊. 變成了

           Y=b0+b1*X1+b2*X2+...+bP*XP+E

這個E是隨機誤差的意思, 條件鬆一點來說, 我們要求 E 的平均數是0就好了, 而標準教科書通常會假設E會服從常態分配!!

 

舉個最簡單例子:  身高能夠預測體重嗎?

 

通常, 身高較高的人體重較重, 可是總有人是天生竹竿身材,

因此, 這個隨機誤差就是要用來描述 虛胖/結實/苗條/過瘦 情況, 也就是:

         就算一樣是175公分的人(X=175.0), 體重不一定會相同(可能是y=80.0公斤, 或者 y=70.0公斤)

用個虛擬的數據化個圖來看看,

可以看到, 身高越高, 體重會緩緩上升, 而整體趨勢就是用最小平方法求出來的估計的迴歸線:

               Weight=16.9588+0.3195*Height

也就是我們可以用這條估計出來的迴歸線, 猜測身高170公分的人的體重.

              16.9588+0.3195*170=71.2738

大概是71公斤!!!

 

※※※線性迴歸分析應注意事項※※※

在進行線性迴歸分析前, 要注意一些事:

1.反應變數是連續型變數嗎? 如果不是連續型變數, 而是Binary data, 上面介紹的迴歸分析是不恰當的

   這一個問題就延伸出 邏輯斯迴歸分析.

 

2.通常會假設反應變數是服從常態分配, 不過有分析過實際資料的人都知道, 數據怎麼可能是常態麻

   雖然這個假設在估計迴歸係數值不需要, 但在做統計推論時就非常重要.

 

3.有發現我們關心的變數間是如何被連結起來嗎?

   我們直接假設體重是身高的直線函數,

          Weight=b0+b1*Height+E

   也就是我們將身高與體重的關係「直接」連結起來了!

   然而, 在現實生活中不可能有這麼簡單的事發生.

 

※※※邏輯斯迴歸分析的概念※※※

現在換個問題:

       有什麼條件的車主會額外加買保險?

 

這問題點典型的商業智慧分析應用. 保險公司希望提高客戶投保率, 不希望亂槍打鳥的讓業務員去拜訪客戶,

將時間浪費在投保意願低的客戶身上.

這時候一樣會去收集數據, 會有反應變數Y與預測變數{X1,...,XP}

不過, 想解決的問題是「會不會加買保險?」, 所以收集的Y最直接就是 買/不買 兩種.

在統計上, 習慣用數字來表示這兩種購買行為. 1表示 會購買保險, 0表示 不會購買保險.

然後預測變數可能就是 性別/職業/薪水/已購買壽險數量...等等.

線姓迴歸有辦法處理這樣的問題嗎?

假設現在收集的預測變數是已購買的壽險數(有投保觀念的人或許比較有可能額外加保車險).

在線性迴歸的表示是:

       加保車險=b0+b1*已購買的壽險數+E

散布圖是

可以看到,  購買不同壽險張數的客戶都有加保的意願

然而我們是無法從這張圖看到到底是壽險買多比較有意願加保, 還是買少的加保意願強?

如果還是估計線性迴歸的參數就變成:

       是否加保=0.057840+0.025833*已購買的壽險數

現在有個新客戶已知他有購買壽險保單2張, 那你要不花點時間推銷他加保車險?

應用估計出來的迴歸式:

       0.057840+0.025833*2=0.1095

 

這.....0.1095我怎麼知道他是買不買啊?

這個就是線性迴歸應用在二元反應變數的問題之一: 預測值不在合理的解釋範圍/空間中    

 

換個角度想, 我們可以用列連表來看一下購買比例如何

                                     NLI
Purchase      0           1            2            3             4
     No      94.12%  95.38%   90.00%   81.82%   62.50%
     Yes       5.88%    4.62%    10.00%  18.18%   37.50%

 

上表的每一行總和都是100%, 因為我的計算方式是: 在相同已購買保單數下, 是否加保車險的比例.

顯然, 加保的比例隨著原本已購買壽險的張數提高(從5.88%到最後的37.5%), 看來真的是有投保觀念的人買車容易再加保啊!!! 

這時, 統計學家就想到, 那為什麼我們不轉個彎, 換不同的方向問問題呢?

           「已購買壽險數量是不是會影響加保車險的機率?」

所以目標變成:

           加保機率=f(已購買壽險數量)

 

如果要像線性迴歸模型一樣有合理的統計模型, 首先要考慮的兩件事就是

     ●f這個數值可能範圍只能在0到1之間, 因為機率值最大就是100%, 最小就是0%.

     ●模仿線性迴歸模型, 我們希望b0+b1*X1+b2*X2+...+bP*XP的取值是從負無窮到正無窮.

       如此一來, 在做數值分析求估計值時, 不收斂問題會少一點.

為了要做到這兩件事, 不失一般性, 考慮b0+b1*X1就好!!

因為,

            負無窮 < b0+b1*X1 < 正無窮  隱含 負無窮 < -(b0+b1*X1) < 正無窮

所以,

             0 <  exp[-(b0+b1*X1)] < 正無窮,  其中的exp()是自然指數的意思.

再來, 全部加1

             1 <  1+exp[-(b0+b1*X1)] < 正無窮

最後, 取倒數

             0 <  exp(b0+b1*X1)/[1+exp(b0+b1*X1)] < 1

這樣就滿足上面兩條件,

所以, 我們就直接把會加保車險的機率P(X)連結成

         P(X1)= exp(b0+b1*X1)/[1+exp(b0+b1*X1)]

其實,上面的等號右邊是個邏輯斯函數(Logistic function)

所以, 我們可以合理化問題轉成邏輯斯迴歸:

       加保機率=exp(b0+b1*已購買壽險數量)/[1+exp(b0+b1*已購買壽險數量)]

而b0跟b1可以用概似函數估算出來, 估計後帶入上式就可以估計會加保車險的機率.

在實際應用上面, 我們可以反求具有什麼特點的客戶會有夠高機會加保車險.

如此, 就可以提高販售出保險的比例,  不用亂槍打鳥, 白做工.

 

 

※※※邏輯斯迴歸分析的R程式碼※※※

延續上面的例子, 我們進入正式數據分析

#載入ISLR資料庫, 我們需要的資料在這資料庫裏面
library(ISLR) 

#看一下"Caravan",大型敞篷車投保資料集,的樣本數有多少?(5822),收集的變數有幾個?(86)
dim(Caravan)

#可以看一下收集的86個變數名稱. 注意到最後一個是反應變數Purchase
names(Caravan)

 

#我們選擇其中的ALEVEN變數, 這一個是「購買壽險的數量」, 其中第775筆是購買八張保單的客戶
#因為在5822中只有一個買8張保單的客戶, 其餘客戶購買數皆不超過4張, 所以我們先不考慮該客戶

attach(Caravan)
ALEVEN<-ALEVEN[-775]
YN<-as.numeric(Purchase[-775])-1

#使用R中的glm函數估計邏輯迴歸函數, 記得在family指定binomial
fit<-summary(glm(YN~ALEVEN,family=binomial))
fit

                    Estimate    Std. Error    z value    Pr(>|z|)    
(Intercept)    -2.78810     0.05711    -48.821  < 2e-16 ***
ALEVEN         0.33485     0.11340        2.953  0.00315 ** 

 

所以估計的邏輯斯迴歸是

      加保機率=exp(-2.788+0.3349*已購買壽險數量)/[1+exp(-2.788+0.3349*已購買壽險數量)]

如果求加保機率要超過1成才優先考慮為高機率加保潛在客戶, 那我們就可以反求

        exp(-2.788+0.3349*已購買壽險數量)/[1+exp(-2.788+0.3349*已購買壽險數量)] > 0.1

==>已購買壽險數量 > [log(0.1/0.9)+2.788]/0.3349 = 1.76

 

我們發現, 如果購買壽險保單達2張, 那該客戶就有高達1成以上機率會加購車險, 

所以, 具有已購買兩張或以上的壽險客戶是優先推銷加保車險客戶!!!

 

 

※※※邏輯斯迴歸分析的R程式碼與機器學習※※※

與KNN使用相同資料, 所以以下某些陳述也與KNN演算法相同, 對KNN演算法有興趣讀者請自行連結過去

#載入ISLR資料庫, 我們需要的資料在這資料庫裏面
library(ISLR) 

#看一下"Caravan",大型敞篷車投保資料集,的樣本數有多少?(5822),收集的變數有幾個?(86)
dim(Caravan)

#可以看一下收集的86個變數名稱. 注意到最後一個是反應變數Purchase
names(Caravan)

#先看一下變數的敘述統計量
summary(Caravan)

#計算會購買保險的比例是多少?(5.977%)
table(Caravan$Purchase)/dim(Caravan)[1]
 

使用訓練與測試82法則, 則取訓練筆數:測試筆數=4650:1172

 

#進行資料整理與分割
Purchase.01<-as.numeric(Caravan[,"Purchase"])-1
train.index<-1:4650
train.X<-Caravan[train.index,-86]
train.Y<-Purchase.01[train.index]
test.X<-Caravan[-train.index,-86]
test.Y<-Purchase.01[-train.index]

train.D<-data.frame(train.X,train.Y)

#進行邏輯斯迴歸估計
logistic<-glm(train.Y~.,data=train.D,family=binomial)
summary(logistic)

#將測試集的預測機率估計出來
pred<-predict(logistic,newdata=test.X,type="response")
pred[1:10]

#設定會加保車險的機率超過10%就是潛在會加保的客戶,把這些人識別出來
Index<-which(pred>=0.1)
predict.01<-rep(0,length(test.Y))
predict.01[Index]<-1

#建立混淆矩陣
Confusion.matrix<-table(Truth=test.Y,Prediction=predict.01)


#我們真正關心的是, 在我們預測會加保的客戶中, 實際上真的有購買的比例是多少? 答案是18.37%
Confusion.matrix[2,2]/sum(Confusion.matrix[,2])

 

#我們可以試著找找看, 預測的機率值超過多少當作值得拜訪客戶的門檻值?
#最後, 發現只要新進客戶的預測加保機率估計值超過5%就值得去推銷拜訪


Pro<-seq(0.01,0.9,0.01)
Success.Rate<-numeric(length(Pro))
for(i in 1:length(Pro))
{
Index<-which(pred>=Pro[i])
predict.01<-rep(0,length(test.Y))
predict.01[Index]<-1
Confusion.matrix<-table(Truth=test.Y,Prediction=predict.01)
Success.Rate[i]<-Confusion.matrix[2,2]/sum(Confusion.matrix[,2])
print(c(i,Success.Rate[i]))
}

Pro[min(which(Success.Rate>=0.05977*2))]

#以圖形展現不同門檻值對預測成功率的變化
plot(Pro,Success.Rate,pch=19,lwd=3,ylab="針對測試集的成功預測機率值",xlab="值得拜訪的機率門檻值")
lines(Pro,Success.Rate,lwd=1,lty=2,col=4)
abline(h=0.05977,col=2)
abline(h=0.05977*2,col=2,lwd=2,lty=2)
text(0.2,0.07,"隨機拜訪成功率5.977%")
text(0.2,0.13,"比隨機拜訪成功率多2倍,11.954%")

abline(v=0.05,col=6,lwd=2,lty=2)
 

 

arrow
arrow

    逗滾仔 發表在 痞客邦 留言(0) 人氣()