項目目標
泰坦尼克號的沉沒是歷史上最著名的還難事件之一,在船上的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'}