從零開始學Python【26】--Logistic回歸(理論部分)
從零開始學Python【25】--嶺回歸及LASSO回歸(實戰部分)
從零開始學Python【24】--嶺回歸及LASSO回歸(理論部分)
從零開始學Python【23】--線性回歸診斷(第二部分)
從零開始學Python【22】--線性回歸診斷(第一部分)
從零開始學Python【21】--線性回歸(實戰部分)
從零開始學Python【20】--線性回歸(理論部分)
基於上一期的理論知識,我們本期跟大家分享一下如何通過Python和R語言完成Logistic回歸分類器的構建。大家都知道,Logistic模型主要是用來解決二元分類問題,通過構建分類器,計算每一個樣本為目標分類的概率,一般而言,我們會將概率值0.5作為分類的閾值,即概率值P大於等於0.5時判別為目標分類,否則為另一種分類。
本次分享的數據是基於用戶信息(年齡、性別和年收入)來判斷其是否發生購買,數據來源於GitHub(文末有數據連結可供下載)。接下來,讓我們看看Logistic模型是如何完成二分類問題的落地。本次分享會涉及模型的構建、測試集的預測及模型的驗證三個方面。
數據查閱import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
from sklearn.cross_validation import train_test_split
from sklearn import metrics
from ggplot import *
purchase = pd.read_csv(r'E:\Jupyter\ML\Logistic-Regression-master\Social_Network_Ads.csv')
purchase.dtypes
purchase.isnull().sum()
從上圖結果可知,除Gender變量,其餘變量均為數值型變量,那麼待會再構建入模變量時,需要對Gender變量創建啞變量;一般在做數據探索時,需要檢查各變量是否存在缺失的情況(如果缺失需要藉助於刪除法、替換法、插值法等完成缺失值的處理,具體可以參考文章【如何使用R語言解決可惡的髒數據】),很顯然上面的結果並沒有顯示數據中含有缺失值。
變量處理dummy = pd.get_dummies(purchase.Gender)
dummy_drop = dummy.drop('Female', axis = 1)
purchase = purchase.drop(['User ID','Gender'], axis = 1)
purchase['Intercept'] = 1
model_data = pd.concat([dummy_drop,purchase], axis = 1)model_data
上面所做的處理無非是構建啞變量,然後從啞變量中再剔除一個水平變量(這個非常重要,為了防止多重共線性);同時還要剔除沒有意義的變量User ID和不再使用的Gender變量(因為已經拆分為啞變量了)。OK,整理之後的數據集就如上圖所示,接下來我們要基於這個數據集進行Logistic模型的創建。
X = model_data.drop('Purchased', axis = 1)y = model_data['Purchased']
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size = 0.75, random_state=0)
logistic = smf.Logit(y_train,X_train).fit()logistic.summary()
經過7次迭代後,模型係數的計算實現收斂,完成了Logistic分類器的創建。從上圖的結果看,除Male這個啞變量不顯著(說明性別這個變量並不能構成用戶是否購買的因素)外,其餘的偏回歸係數均為顯著。下面,我們不妨將Male變量剔除,再做一次Logistic模型。
logistic2 = smf.logit('Purchased~Age+EstimatedSalary', data = pd.concat([y_train,X_train], axis = 1)).fit()logistic2.summary()print(logistic.aic)print(logistic2.aic)
很明顯,通過變量的剔除,在保證了所有變量顯著的情況下,也降低了模型的AIC,說明,Male啞變量的刪除是合理的。
np.exp(logistic2.params)
接下來,再來看看模型的係數解釋(優勢比),在其他變量不變的情況下,用戶年齡每增加一個單位(歲),用戶購買的概率是不夠買概率的1.25倍;用戶的年收入每增加一個單位(元),用戶購買的概率與不夠買概率幾乎相等(因為這裡只是計算年收入增加1元的概率比,如果對收入變量壓縮10000倍,那這個概率比肯定就會上升了,因為此時收入上升一個單位就是一萬元了)。
模型預測與驗證prob = logistic2.predict(exog = X_test.drop('Male', axis = 1))
pred = np.where(prob >= 0.5, 1, 0)
cm = metrics.confusion_matrix(y_test, pred, labels=[0,1])cm
accuracy = cm.diagonal().sum()/cm.sum()accuracy
應用分類器對測試數據集進行預測,這裡將概率值設為0.5,如果概率大於等於0.5則判用戶會購買,否則不會發生購買。通過這個概率值的設定,我們發現模型的準確率還是非常高的(混淆矩陣對角線代表預測正確的數量)。可是單看混淆矩陣還不夠,因為當數據不平衡時,計算的準確率也同樣會高,並不代表模型就會好,所以我們進一步的藉助於ROC曲線下的面積來衡量模型時候合理。
fpr, tpr, _ = metrics.roc_curve(y_test, pred)df = pd.DataFrame(dict(fpr=fpr, tpr=tpr))ggplot(df, aes(x='fpr', y='tpr')) +\ geom_area(alpha=0.5, fill = 'steelblue') +\ geom_line() +\ geom_abline(linetype='dashed',color = 'red') +\ labs(x = '1-specificity', y = 'Sensitivity',title = 'ROC Curve AUC=%.3f' % metrics.auc(fpr,tpr))
是不是很激動,對於熟悉R語言的你,Python中也有ggplot2的繪圖語法!從上面的ROC曲線結果可知,AUC的值超過了0.85,這進一步說明模型的預測效果是非常不錯的(一般AUC>0.8就比較好了)。
到此,關於使用Python構建Logistic分類器的實戰我們就介紹到這裡,接下來將使用R語言重新復現一遍,希望對R語言熟悉的朋友有一點的幫助。如下是R語言的復現腳本:
# 加載第三方包
library(pROC)
library(ggplot2)
purchase <- read.csv(file = file.choose())purchase$Purchased = factor(purchase$Purchased)
str(purchase)
sapply(purchase, function(x) sum(is.na(x)))
set.seed(0)idx = sample(1:nrow(purchase), size = 0.75*nrow(purchase))train = purchase[idx,]test = purchase[-idx,]
logit = glm(Purchased ~ ., data = train[,-1], family = binomial(link = "logit"))summary(logit)
train2 = purchase[idx,-c(1,2)]test2 = purchase[-idx,-c(1,2)]
logit2 = glm(Purchased ~ ., data = train2, family = binomial(link = "logit"))summary(logit2)
prob = predict(logit2, newdata = test2)pred = factor(ifelse(prob >= 0.5, 1, 0), levels = c(0, 1), ordered = TRUE)
Freq = table(test$Purchased, pred)
sum(diag(Freq))/sum(Freq)
ROC = roc(factor(test2$Purchased, levels=c(0,1), ordered = TRUE), pred)df = data.frame(x = 1-ROC$specificities, y = ROC$sensitivities)ggplot(df, aes(x = x, y = y)) + geom_area(alpha=0.5, fill = 'steelblue') + geom_line() + geom_abline(linetype='dashed',color = 'red') + labs(x = '1-specificity', y = 'Sensitivity', title = paste0('ROC Curve AUC=', round(ROC$auc,3))) + theme(plot.title = element_text(hjust = 0.5, face = 'bold'))
OK,關於使用Python和R語言完成Logistic回歸的實戰我們就分享到這裡,如果你有任何問題,歡迎在公眾號的留言區域表達你的疑問。同時,也歡迎各位朋友繼續轉發與分享文中的內容,讓更多的人學習和進步。
關注「每天進步一點點2015」,與小編同進步!
數據連結:
連結: https://pan.baidu.com/s/1eSo3Y2Q 密碼: cd7f