项目目标
泰坦尼克号的沉没是历史上最著名的还难事件之一,在船上的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'}