数据集来源于kaggle经典竞赛数据集
一、目的
根据数据集中的信息,利用python机器学习对泰坦尼克乘客是否生还进行预测。
二、数据集
我的数据集有三个,test、train、genderclassmodel,都是csv格式
test和train数据集中的字段:
从左到右依次是,乘客编号、是否生还、仓位、姓名、性别、年龄、船上同辈亲属的人数、乘客有父母或孩子的人数、船票号、旅费、船舱号、上船的港口(C = Cherbourg, Q = Queenstown, S = Southampton)
genderclassmodel是测试集的实际生还结果:
三、训练思路
通过对数据集的观察以及经验,在数据集中如乘客姓名、船票号、编号这些属性和结果明显无关,是无用的信息,可以先去除掉。数据中有很多空值,缺失值也可以先进行处理。对于船舱号的样本太少,可以不考虑这个特征,先进性删除。
我们选用KNN和随机森林进行训练。
四、数据清洗和特征处理`
引入训练集和测试集、删除姓名、床票号、船舱号的列
import numpy as np
import pandas as pd
#1数据引入
df_train=pd.read_csv('data/titanic/train.csv')
df_train=df_train.drop(['Name','Ticket','Cabin'],axis=1)
df_test=pd.read_csv('data/titanic/test.csv')
df_test=df_test.drop(['Name','Ticket','Cabin'],axis=1)
对缺失值进行处理,age和fare的缺失值比较多,我用平均值填充,而上船港口有两个缺失值,就直接删除了。
#2、缺失值处理
df_train['Age']=df_train['Age'].fillna(df_train['Age'].mean())
df_train['Fare']=df_train['Fare'].fillna(df_train['Fare'].mean())
df_train=df_train.dropna()
df_test['Age']=df_test['Age'].fillna(df_test['Age'].mean())
df_test['Fare']=df_test['Fare'].fillna(df_test['Fare'].mean())
特征值的归一化和标准化
由于性别和上船港口是字符串类型,我们需要将其转化为数值,用0、1、2代替。而其他的值我用归一化将其转化为0-1之间的数。
#3、特征处理
from sklearn.preprocessing import MinMaxScaler,StandardScaler
from sklearn.preprocessing import LabelEncoder,OneHotEncoder
from sklearn.preprocessing import LabelEncoder,OneHotEncoder
scaler_list=[Age,Fare,Pclass,SibSp,Parch]
column_list=['Age','Fare','Pclass','SibSp','Parch']
for i in range(len(scaler_list)):
if not scaler_list[i]:
df_train[column_list[i]]=MinMaxScaler().fit_transform(df_train[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
df_test[column_list[i]]=MinMaxScaler().fit_transform(df_test[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
else:
df_train[column_list[i]]=StandardScaler().fit_transform(df_train[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
df_test[column_list[i]]=StandardScaler().fit_transform(df_test[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
scaler_list=[Sex,Embarked]
column_list=['Sex','Embarked']
for i in range(len(scaler_list)):
if scaler_list[i]:
df_train[column_list[i]]=LabelEncoder().fit_transform(df_train[column_list[i]])
df_train[column_list[i]]=MinMaxScaler().fit_transform(df_train[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
df_test[column_list[i]]=LabelEncoder().fit_transform(df_test[column_list[i]])
df_test[column_list[i]]=MinMaxScaler().fit_transform(df_test[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
return df_train,test
def main():
print(titanic_processing())
if __name__=='__main__':
main()
显示结果
特征处理好了之后就可以开始进行建模啦
这里我选择额三种模型进行训练,KNN、支持向量机SVM和随机森林,该模型是生还的判别,所以我们选用分类模型进行预测。
这里值得一提的事,我获取到的数据中,训练集里包含标注Survived,首先要把它去除掉,第一步处理就是分出训练集、测试集的特征部分和标注部分。
y_train=df_train['Survived'].values
x_train=df_train.drop('Survived',axis=1).values
y_class=pd.read_csv('data/titanic/genderclassmodel.csv')
y_test=y_class['Survived'].values
x_test=df_test.values
然后开始建模,我们要选择三种模型,对每种模型的评分进行比较,所以我创建了一个models 的list。
from sklearn.ensemble import RandomForestClassifier,AdaBoostClassifier
from sklearn.svm import SVC
from sklearn.neighbors import NearestNeighbors,KNeighborsClassifier
from sklearn.metrics import accuracy_score,recall_score,f1_score
models=[]
models.append(('KNN',KNeighborsClassifier(n_neighbors=3)))
models.append(('SVM',SVC(C=100)))
models.append(('Ramdomforest',RandomForestClassifier()))
然后进行模型拟合和预测。
for clf_name,clf in models:
clf.fit(x_train,y_train)
xy_list=[(x_train,y_train),(x_test,y_test)]
for i in range(len(xy_list)):
x_part=xy_list[i][0]
y_part=xy_list[i][1]
y_pred=clf.predict(x_part)
print(i)
print(clf_name,'ACC:',accuracy_score(y_part,y_pred))
print(clf_name,'REC:',recall_score(y_part,y_pred))
print(clf_name,'f1:',f1_score(y_part,y_pred))
完整代码如下:
import numpy as np
import pandas as pd
#1数据引入
def titanic_processing(Age=False,Fare=False,Pclass=False,SibSp=False,Parch=False,Sex=True,Embarked=True):
df_train=pd.read_csv('data/titanic/train.csv')
df_train=df_train.drop(['Name','Ticket','Cabin','PassengerId'],axis=1)
df_test=pd.read_csv('data/titanic/test.csv')
df_test=df_test.drop(['Name','Ticket','Cabin','PassengerId'],axis=1)
#2、缺失值处理
df_train['Age']=df_train['Age'].fillna(df_train['Age'].mean())
df_train['Fare']=df_train['Fare'].fillna(df_train['Fare'].mean())
df_train=df_train.dropna()
df_test['Age']=df_test['Age'].fillna(df_test['Age'].mean())
df_test['Fare']=df_test['Fare'].fillna(df_test['Fare'].mean())
#3、特征处理
from sklearn.preprocessing import MinMaxScaler,StandardScaler
from sklearn.preprocessing import LabelEncoder,OneHotEncoder
from sklearn.preprocessing import LabelEncoder,OneHotEncoder
scaler_list=[Age,Fare,Pclass,SibSp,Parch]
column_list=['Age','Fare','Pclass','SibSp','Parch']
for i in range(len(scaler_list)):
if not scaler_list[i]:
df_train[column_list[i]]=MinMaxScaler().fit_transform(df_train[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
df_test[column_list[i]]=MinMaxScaler().fit_transform(df_test[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
else:
df_train[column_list[i]]=StandardScaler().fit_transform(df_train[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
df_test[column_list[i]]=StandardScaler().fit_transform(df_test[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
scaler_list=[Sex,Embarked]
column_list=['Sex','Embarked']
for i in range(len(scaler_list)):
if scaler_list[i]:
df_train[column_list[i]]=LabelEncoder().fit_transform(df_train[column_list[i]])
df_train[column_list[i]]=MinMaxScaler().fit_transform(df_train[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
df_test[column_list[i]]=LabelEncoder().fit_transform(df_test[column_list[i]])
df_test[column_list[i]]=MinMaxScaler().fit_transform(df_test[column_list[i]].values.reshape(-1,1)).reshape(1,-1)[0]
return df_train,df_test
def titanic_model(df_train,df_test):
y_train=df_train['Survived'].values
x_train=df_train.drop('Survived',axis=1).values
y_class=pd.read_csv('data/titanic/genderclassmodel.csv')
y_test=y_class['Survived'].values
x_test=df_test.values
from sklearn.ensemble import RandomForestClassifier,AdaBoostClassifier
from sklearn.svm import SVC
from sklearn.neighbors import NearestNeighbors,KNeighborsClassifier
from sklearn.metrics import accuracy_score,recall_score,f1_score
models=[]
models.append(('KNN',KNeighborsClassifier(n_neighbors=3)))
models.append(('SVM',SVC(C=100)))
models.append(('Ramdomforest',RandomForestClassifier()))
for clf_name,clf in models:
clf.fit(x_train,y_train)
xy_list=[(x_train,y_train),(x_test,y_test)]
for i in range(len(xy_list)):
x_part=xy_list[i][0]
y_part=xy_list[i][1]
y_pred=clf.predict(x_part)
print(i)
print(clf_name,'ACC:',accuracy_score(y_part,y_pred))
print(clf_name,'REC:',recall_score(y_part,y_pred))
print(clf_name,'f1:',f1_score(y_part,y_pred))
def main():
df_train,df_test=titanic_processing()
titanic_model(df_train,df_test)
if __name__=='__main__':
main()
我们来看评价结果:
0
KNN ACC: 0.875140607424072
KNN REC: 0.8
KNN f1: 0.8305343511450382
1
KNN ACC: 0.8181818181818182
KNN REC: 0.8156028368794326
KNN f1: 0.7516339869281047
0
SVM ACC: 0.84251968503937
SVM REC: 0.6764705882352942
SVM f1: 0.7666666666666666
1
SVM ACC: 0.8779904306220095
SVM REC: 0.8014184397163121
SVM f1: 0.8158844765342961
0
Ramdomforest ACC: 0.9820022497187851
Ramdomforest REC: 0.9647058823529412
Ramdomforest f1: 0.9761904761904762
1
Ramdomforest ACC: 0.7990430622009569
Ramdomforest REC: 0.6950354609929078
Ramdomforest f1: 0.7
0
KNN ACC: 0.875140607424072
KNN REC: 0.8
KNN f1: 0.8305343511450382
1
KNN ACC: 0.8181818181818182
KNN REC: 0.8156028368794326
KNN f1: 0.7516339869281047
0
SVM ACC: 0.84251968503937
SVM REC: 0.6764705882352942
SVM f1: 0.7666666666666666
1
SVM ACC: 0.8779904306220095
SVM REC: 0.8014184397163121
SVM f1: 0.8158844765342961
0
Ramdomforest ACC: 0.9820022497187851
Ramdomforest REC: 0.9647058823529412
Ramdomforest f1: 0.9761904761904762
1
Ramdomforest ACC: 0.7990430622009569
Ramdomforest REC: 0.6950354609929078
Ramdomforest f1: 0.7