Liz's Blog

Python學習筆記#13:機器學習之邏輯迴歸實作篇

| Comments

邏輯迴歸被視為一種Classification(分類)的方法,處理像是貸款預設(借還是不借)、疾病診斷等問題。當事件發生只有發生與不發生的可能,使用線性迴歸,就顯得不合時宜,反而應該把這條線轉為邏輯迴歸曲線(S函數)來處理。做法是,事件只有0或1,在0.5設一條中心線,低於這條線視為不發生(0),高於這條線,視為發生(1),建立完模型後,放進測試組資料來看模型表現,再用confusion matrix來評估分類的好壞。

Udemy
課程名稱:Python for Data Science and Machine Learning Bootcamp
講師:Jose Portilla

1.載入套件

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

2.使用Kaggle上鐵達尼號的資料集,和之前學R練習邏輯迴歸的處理邏輯類似

train = pd.read_csv('titanic_train.csv')
train.head()

3.探索資料

#用heatmap(.isnull())來找出缺失的資料在哪些欄位。Age似乎約有五分之一資料缺失,可能可以用合理的資料補充,但Cabin的缺失資料多到可能無法用。
sns.heatmap(train.isnull(),yticklabels=False,cbar=False,cmap='viridis')

#用countplot來看性別是否影響最後存活。女性存活比例比男性高。
sns.countplot(x='Survived',hue='Sex',data=train,palette='RdBu_r')

#艙等似乎也影響著存活。
sns.countplot(x='Survived',hue='Pclass',data=train)

#用直方圖看年齡分佈。缺失資料在此不計。
sns.distplot(train['Age'].dropna(),kde=False,bins=30)

#SibSp代表兄弟姐妹或眷屬的人數。
sns.countplot(x='SibSp',data=train)

#用直方圖看票價的分佈
train['Fare'].hist(bins=40,figsize=(10,4))

#也使用cufflinks作為練習
import cufflinks as cf
cf.go_offline()
train['Fare'].iplot(kind='hist',bins=30)

4.資料清理
(1)剛有看到年齡資料約有五分之一缺失,一種做法是棄之不用,一種可以考慮把年齡平均放進去。

#使用盒鬚圖來看年齡和艙等的分佈。看起來頭等艙年齡較高,隨之降低。
plt.figure(figsize=(12,6))
sns.boxplot(x='Pclass',y='Age',data=train)

#把艙等平均年齡填入缺失的資料中
def impute_age(cols):
    Age = cols[0]
    Pclass = cols[1]
    
    if pd.isnull(Age):
        
        if Pclass == 1:
            return 37
        elif Pclass == 2:
            return 29
        else:
            return 24
    else:
        return Age

train['Age'] = train[['Age','Pclass']].apply(impute_age,axis=1)

#用heatmap查看年齡是否還有缺失的資料
sns.heatmap(train.isnull(),yticklabels=False,cbar=False,cmap='viridis')

(2)Cabin的資料太多缺失,在此先棄用

train.drop('Cabin',axis=1,inplace=True)
train.dropna(inplace=True)

(3)虛擬變數

#使用pandas將性別從類別資料轉換為虛擬變數。本來若有k個level,drop_first=True會只剩下k-1個level,降低共線性的可能。
sex = pd.get_dummies(train['Sex'],drop_first=True)
sex.head()

#使用pandas將上船的港口從類別資料轉換為虛擬變數
embark = pd.get_dummies(train['Embarked'],drop_first=True)
embark.head()

#將性別及上船港口的虛擬變數和原始的data結合
train = pd.concat([train,sex,embark],axis=1)
train.head()

#將原始的性別、登船港口、票號、姓名欄位棄用
train.drop(['Sex','Embarked','Name','Ticket'],axis=1,inplace=True)

#因為PassengerId在此只是排序,因此也棄用
train.drop('PassengerId',axis=1,inplace=True)

5.建立邏輯迴歸模型

X = train.drop('Survived', axis=1)
y = train['Survived']

#載入訓練組及測試組分組套件
from sklearn.model_selection import train_test_split

#設定隨機種子為101,測試組比例佔30%
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.30,random_state=101)

#載入邏輯迴歸
from sklearn.linear_model import LogisticRegression

#建立訓練組邏輯迴歸模型
logmodel = LogisticRegression()
logmodel.fit(X_train,y_train)

6.預測(classification_report可參考這篇

#使用模型來預測
predictions = logmodel.predict(X_test)

#載入classification_report來看預測和實際數值的差異,包含precision、recall、f1-score及support
from sklearn.metrics import classification_report
print(classification_report(y_test,predictions))

#利用confusion_matrix來看
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test,predictions)
Confusion Matrix 預測 (No) 預測(Yes)
實際(No) TN=40 FP=15
實際(Yes) FN=15 TP=100

TN=True Negative; FP=False Positive, FN=False Negative; TP=True Positive

precison = TP / (TP + FP)
recall = TP / (TP + FN)
accuracy = (TP + TN) / (TN + FP + FN + TP)
F-beta score可視為precision和recall加權平均的值,數值介於0-1,最好是1。
support代表在測試組y實際值的發生次數。

Comments

comments powered by Disqus