kaggle--泰坦尼克存活预测(机器学习入门)
今天为大家带来的是kaggle上的入门题目--泰坦尼克号存活预测,根据提供的乘客信息来预测乘客能否幸存。
最近在琢磨机器学习方面,之前唯一接触过的python相关只有写了几个简单爬虫和脚本,因为课程不涉及相关内容,之前根本不知道机器学习是怎么回事,希望可以通过这个简单的例子练练手,最近因该也会更新相关内容,希望和大家一起学习成长。
代码参考来源:YouTube@neuralNine
目录
题目概括
以泰塔尼克号沉没为背景,现提供了船上乘客的个人信息(ID,性别,pclass等等......),需要你建立一个预测模型并预测具有什么条件的乘客最可能幸存。相对陌生词语如pclass等题目做了详细解释,有兴趣可以去研究一下。
说人话就是:我们现在可以从题目获取三个文件,train是我们的机器学习素材,完成机器学习模型后代入test数据进行预测,gender_submission是本题答案,我们预测得出的文件最后可以和答案对比准确度(一般不会是100%)
数据分析
【原博主教学使用的编译软件是jupyter,我这里使用的PyCharm,其实用啥都行没啥影响】
第一步,先下需要的包:numpy,pands,seaborn,scikit-learn,matplotlib
然后导包读取文件
这里用train数据生成了一个相关性热力图(如下),用来参考具体是哪些条件影响了幸存率(这个自己做题时能提供思路很有帮助,但是如果本身对python和相关数学知识了解不多,学习比较吃力的不打算深入学习这方面的,这道题可以直接从给的答案推题目)
sns.heatmap(titanic_data.corr(numeric_only=True),cmap='coolwarm')
plt.show()

数据处理
这一步,对训练数据和测试数据进行分层抽样并分别装成两个数据集,并且比对抽样分布图作为验证手段(下图左test,右train),如果相似性较高则抽样有效,数据集可用(用来找最优模型)。
split=StratifiedShuffleSplit(n_splits=1, test_size=0.2)
for train_indices, test_indices in split.split(titanic_data,titanic_data[["Survived","Pclass","Sex"]]):
strat_train_set=titanic_data.loc[train_indices]
strat_test_set = titanic_data.loc[test_indices]
plt.subplot(1,2,1)
strat_test_set["Survived"].hist()
strat_test_set["Pclass"].hist()
plt.subplot(1,2,2)
strat_train_set["Survived"].hist()
strat_train_set["Pclass"].hist()
plt.show()

这里我们定义三个类进行数据的修缮,主要有三点:
1.数据缺失的部分比如年龄,我们用均值mean进行补充。
2.对于一些不好处理的数据(特指数据非整型数据的),我们给他们用独热编码器进行编码,便于计算机进行理解(毕竟机器不认识男女老少,只知道0123...)
3.对于相关性差的冗余数据,我们直接删掉
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.impute import SimpleImputer
class AgeImputer(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
imputer = SimpleImputer(strategy="mean")
X['Age'] = imputer.fit_transform(X[['Age']])
return X
from sklearn.preprocessing import OneHotEncoder
class FeatureEncoder(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
encoder = OneHotEncoder()
matrix = encoder.fit_transform(X[['Embarked']]).toarray()
column_names=["C","S","Q","N"]
for i in range(len(matrix.T)):
X[column_names[i]]=matrix.T[i]
matrix=encoder.fit_transform(X[['Sex']]).toarray()
column_names=["Female","Male"]
for i in range(len(matrix.T)):
X[column_names[i]] = matrix.T[i]
return X
class FeatureDropper(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
return X.drop(["Embarked","Name","Ticket","Cabin","Sex","N"],axis=1,errors="ignore")
最后用定义的方法处理数据
pipeline = Pipeline([("ageimputer",AgeImputer()),
("featureencoder",FeatureEncoder()),
("featuredropper",FeatureDropper())])
strat_train_set=pipeline.fit_transform(strat_train_set)
删除原有的结果,并且消除数据之间可能存在的过大差异(如男女数据范围0-1,年龄范围0-100)把他们转化为平均0方差1的形式,转换标签格式使之符合所用包的需要。
from sklearn.preprocessing import StandardScaler
x=strat_train_set.drop(['Survived'],axis=1)
y=strat_train_set['Survived']
scaler = StandardScaler()
X_data=scaler.fit_transform(x)
y_data=y.to_numpy()
模型训练
这里使用了森林分布器和网格搜索工具,并用三折交叉验证,准确率为指标进行评价来找出最佳模型,找到最优模型后,我们去除数据集标签,评估所找模型的准确性,这里比较复杂,具体看注释
# 初始化随机森林分类器
clf = RandomForestClassifier()
# 定义参数网格:用于网格搜索最优参数
param_grid = [
{"n_estimators": [10, 100, 200, 500],
"max_depth": [None, 5, 10],
"min_samples_split": [2, 3, 4]}
]
# cv=3:3折交叉验证;scoring="accuracy":以准确率为评价指标
grid_search = GridSearchCV(clf, param_grid, cv=3, scoring="accuracy", return_train_score=True)
grid_search.fit(X_data, y_data) # 在训练集上拟合
# 获取最优模型
final_clf = grid_search.best_estimator_
# 用管道处理测试集(仅转换,不重新拟合,避免数据泄露)
strat_test_set = pipeline.transform(strat_test_set)
#去标签并标准化数据集
X_test=strat_test_set.drop(['Survived'],axis=1)
y_test=strat_test_set['Survived']
scaler=StandardScaler()
X_data_test=scaler.fit_transform(X_test)
y_data_test=y_test.to_numpy()
#在测试集上评估最优模型的准确率
final_clf.score(X_data_test,y_data_test)
final_data=pipeline.fit_transform(titanic_data)
我们去除全部数据集标签,用找到并验证的这个最佳模型对全部数据进行模型训练,得到训练好的最终模型(做到这一步就算真正训练出了机器模型,不容易啊!)
#分离全部数据的特征和标签
X_final=final_data.drop(['Survived'],axis=1)
y_final=final_data['Survived']
scaler=StandardScaler()
X_data_final=scaler.fit_transform(X_final)
y_data_final=y_final.to_numpy()
#用全部数据训练
prod_clf=RandomForestClassifier()
param_grid=[
{"n_estimators":[10,100,200,500],"max_depth":[None,5,10],"min_samples_split":[2,3,4]},
]
grid_search=GridSearchCV(prod_clf,param_grid,cv=3,scoring="accuracy",return_train_score=True)
grid_search.fit(X_data_final,y_data_final)
#获取最终用于预测的最优模型
prod_final_clf=grid_search.best_estimator_
最后我们对test数据进行规范化处理,就可以进行预测啦,生成并保存最后的文件,这个文件就是我们最后可以提交的结果,在kaggle网站测试与所给完整数据相似度78%以上
# 读取测试集数据(这里文件路径需要是自己文件下载解压的位置)
titanic_test_data = pd.read_csv('E:/ttnkdatas/titanic/test.csv')
final_test_data = pipeline.fit_transform(titanic_test_data)
# 准备测试集特征,填充可能的缺失值(向前填充)
X_final_test = final_test_data
X_final_test = X_final_test.fillna(method='ffill')
# 标准化测试集特征
scaler = StandardScaler()
X_data_final_test = scaler.fit_transform(X_final_test)
# 用最终模型预测测试集的存活情况
predictions = prod_final_clf.predict(X_data_final_test)
# 生成提交文件:包含乘客ID和预测结果
final_df = pd.DataFrame(final_test_data['PassengerId'], columns=['PassengerId'])
final_df['Survived'] = predictions
# 保存同样保存在自己能找见的地方
final_df.to_csv("E:/ttnkdatas/titanic/predictions.csv", index=False)
源码
最后附上完整源码(没写注释,有不懂的请看上面部分的代码注释)
from os.path import split
from typing import final
from xml.etree.ElementPath import prepare_predicate
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from joblib.testing import param
titanic_data=pd.read_csv('E:/ttnkdatas/titanic/train.csv')
import seaborn as sns
sns.heatmap(titanic_data.corr(numeric_only=True),cmap='coolwarm')
plt.show()
from sklearn.model_selection import StratifiedShuffleSplit
split=StratifiedShuffleSplit(n_splits=1, test_size=0.2)
for train_indices, test_indices in split.split(titanic_data,titanic_data[["Survived","Pclass","Sex"]]):
strat_train_set=titanic_data.loc[train_indices]
strat_test_set = titanic_data.loc[test_indices]
plt.subplot(1,2,1)
strat_test_set["Survived"].hist()
strat_test_set["Pclass"].hist()
plt.subplot(1,2,2)
strat_train_set["Survived"].hist()
strat_train_set["Pclass"].hist()
plt.show()
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.impute import SimpleImputer
class AgeImputer(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
imputer = SimpleImputer(strategy="mean")
X['Age'] = imputer.fit_transform(X[['Age']])
return X
from sklearn.preprocessing import OneHotEncoder
class FeatureEncoder(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
encoder = OneHotEncoder()
matrix = encoder.fit_transform(X[['Embarked']]).toarray()
column_names=["C","S","Q","N"]
for i in range(len(matrix.T)):
X[column_names[i]]=matrix.T[i]
matrix=encoder.fit_transform(X[['Sex']]).toarray()
column_names=["Female","Male"]
for i in range(len(matrix.T)):
X[column_names[i]] = matrix.T[i]
return X
class FeatureDropper(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
return X.drop(["Embarked","Name","Ticket","Cabin","Sex","N"],axis=1,errors="ignore")
from sklearn.pipeline import Pipeline
pipeline = Pipeline([("ageimputer",AgeImputer()),
("featureencoder",FeatureEncoder()),
("featuredropper",FeatureDropper())])
strat_train_set=pipeline.fit_transform(strat_train_set)
from sklearn.preprocessing import StandardScaler
x=strat_train_set.drop(['Survived'],axis=1)
y=strat_train_set['Survived']
scaler = StandardScaler()
X_data=scaler.fit_transform(x)
y_data=y.to_numpy()
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
clf=RandomForestClassifier()
param_grid=[
{"n_estimators":[10,100,200,500],"max_depth":[None,5,10],"min_samples_split":[2,3,4]},
]
grid_search=GridSearchCV(clf,param_grid,cv=3,scoring="accuracy",return_train_score=True)
grid_search.fit(X_data,y_data)
final_clf=grid_search.best_estimator_
strat_test_set=pipeline.transform(strat_test_set)
X_test=strat_test_set.drop(['Survived'],axis=1)
y_test=strat_test_set['Survived']
scaler=StandardScaler()
X_data_test=scaler.fit_transform(X_test)
y_data_test=y_test.to_numpy()
final_clf.score(X_data_test,y_data_test)
final_data=pipeline.fit_transform(titanic_data)
X_final=final_data.drop(['Survived'],axis=1)
y_final=final_data['Survived']
scaler=StandardScaler()
X_data_final=scaler.fit_transform(X_final)
y_data_final=y_final.to_numpy()
prod_clf=RandomForestClassifier()
param_grid=[
{"n_estimators":[10,100,200,500],"max_depth":[None,5,10],"min_samples_split":[2,3,4]},
]
grid_search=GridSearchCV(prod_clf,param_grid,cv=3,scoring="accuracy",return_train_score=True)
grid_search.fit(X_data_final,y_data_final)
prod_final_clf=grid_search.best_estimator_
titanic_test_data=pd.read_csv('E:/ttnkdatas/titanic/test.csv')
final_test_data=pipeline.fit_transform(titanic_test_data)
X_final_test=final_test_data
X_final_test=X_final_test.fillna(method='ffill')
scaler=StandardScaler()
X_data_final_test=scaler.fit_transform(X_final_test)
predictions=prod_final_clf.predict(X_data_final_test)
final_df=pd.DataFrame(final_test_data['PassengerId'],columns=['PassengerId'])
final_df['Survived']=predictions
final_df.to_csv("E:/ttnkdatas/titanic/predictions.csv",index=False)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)