專案目標
泰坦尼克號的沉沒是歷史上最著名的還難事件之一,在船上的2224名乘客和機組人員中,共造成1502人死亡。本次專案的目標是運用機器學習工具來預測哪些乘客能夠倖免於難。
專案過程
- 匯入並探索資料
- 處理缺失值,刪除與預測無關的特徵
- 將分類變數轉換為數值型變數
- 例項化模型並進行交叉驗證
- 模型預測
- 調參,得到最好的超引數
專案程式碼(Jupyter)
import pandas as pd from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split from sklearn.model_selection import GridSearchCV from sklearn.model_selection import cross_val_score import matplotlib.pyplot as plt
data = pd.read_csv("Taitanic data.csv") data.head()
data.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 891 entries, 0 to 890 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 PassengerId 891 non-null int64 1 Survived 891 non-null int64 2 Pclass 891 non-null int64 3 Name 891 non-null object 4 Sex 891 non-null object 5 Age 714 non-null float64 6 SibSp 891 non-null int64 7 Parch 891 non-null int64 8 Ticket 891 non-null object 9 Fare 891 non-null float64 10 Cabin 204 non-null object 11 Embarked 889 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 83.7+ KB
# 這裡首先我們看看這些標籤代表著什麼 # PassengerId => 乘客ID # Pclass => 乘客等級(1/2/3等艙位) # Name => 乘客姓名 # Sex => 性別 # Age => 年齡 # SibSp => 堂兄弟/妹個數 # Parch => 父母與小孩個數 # Ticket => 船票資訊 # Fare => 票價 # Cabin => 客艙 # Embarked => 登船港口
# 刪除缺失值過多的列,以及和預測的y沒有關係的列 data.drop(["Cabin", "Name", "Ticket"], inplace=True, axis=1) # 處理缺失值,對於缺失較多的列進行填補,對於缺失較少的列可以直接刪除該條記錄 data["Age"] = data["Age"].fillna(data["Age"].mean()) data = data.dropna() # 刪除缺失值後重置索引 data.index = range(len(data)) data.tail()
data.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 889 entries, 0 to 888 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 PassengerId 889 non-null int64 1 Survived 889 non-null int64 2 Pclass 889 non-null int64 3 Sex 889 non-null object 4 Age 889 non-null float64 5 SibSp 889 non-null int64 6 Parch 889 non-null int64 7 Fare 889 non-null float64 8 Embarked 889 non-null object dtypes: float64(2), int64(5), object(2) memory usage: 62.6+ KB
# 將分類變數轉換為數值型變數 # 在說分類變數轉數值型變數之前,我們首先要清楚資料的型別 # 資料可以分為定量資料和定性資料,定性資料又可以分為有序資料和無序資料,定量資料可以分為離散型資料和連續型資料 # 這個專案中我們要處理的資料是Sex和Embarked,前者屬於定性資料中的無序資料,後者屬於定性資料中的有序資料 # 在sklearn中可以進行變數轉換的類有三個:OneHotEncoder\OrdinalEncoder\LableEncoder # 三者的區別在於: # 1.OneHotEncoder用於編碼無序資料(針對特徵) # 2.OrdinalEncoder用於編碼有序資料(針對特徵),可以保留資料的大小意義 # 3.LableEncoder用於編碼標籤變數,不會保留資料的大小意義
#將分類變數轉換為數值型變數 from sklearn.preprocessing import OneHotEncoder,OrdinalEncoder # 編碼Sex ohe = OneHotEncoder(sparse=False) data_Sex = ohe.fit_transform(data["Sex"].values.reshape(-1, 1)) # 檢視編碼後對應的特徵名稱並轉換為DataFrame ohe.get_feature_names() data_Sex_df = pd.DataFrame(data_Sex, columns=["female","male"]) # 編碼Embarked並轉換為DataFrame oe = OrdinalEncoder() data_Embarked = oe.fit_transform(data["Embarked"].values.reshape(-1, 1)) data_Embarked_df = pd.DataFrame(data_Embarked, columns=["Embarked"])
print(data_Sex.shape) print(data_Embarked.shape) print(data.shape)
(889, 2) (889, 1) (889, 9)
# 刪除Sex和Embarked data.drop(["Sex", "Embarked"], inplace=True, axis=1) # 將編碼後的資料合併到原資料 newdata = pd.concat([data, data_Sex_df, data_Embarked_df], axis=1) newdata
# 劃分特徵與標籤 X = newdata.iloc[:, newdata.columns != "Survived"] y = newdata.iloc[:,newdata.columns == "Survived"] # 劃分訓練集與測試集 Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y) clf = DecisionTreeClassifier(random_state=666) clf.fit(Xtrain, Ytrain) score_ = clf.score(Xtest, Ytest) score_
0.7713004484304933
# 交叉驗證 cv_score = [] for i in range(2,10): score = cross_val_score(clf,X,y,cv=i).mean() cv_score.append(score) best_cv = cv_score.index(max(cv_score)) + 2 best_cv
5
# 網格搜尋 parameters = {"splitter":('best','random') ,"max_depth":[*range(1,5)] ,"min_samples_leaf":[*range(1,10)] } clf = DecisionTreeClassifier(random_state=666) GS = GridSearchCV(clf, parameters, cv=best_cv) GS.fit(Xtrain,Ytrain) GS.best_score_
0.8138143867130513
GS.best_params_
{'max_depth': 3, 'min_samples_leaf': 1, 'splitter': 'best'}