下载数据
地址:[kaggle](https://www.kaggle.com/c/titanic)
处理数据
import pandas as pd
import numpy as np
df_train = pd.read_csv('./data/train.csv')
df_train_test = pd.read_csv('./data/test.csv')
# DataFrame 行添加 append
df_train = df_train.append(df_train_test,ignore_index=True)
df_train.info()
查看数据
df_train.shape
df_train.describe()
df_train.info()
image.png
- 可以看出 Age, Cabin, Embarked, Fare 数据缺失,由于Survived 为目标值只存在于train集,及只有891行数据
- 查询数据是否为空
df_train.isnull() df_train.apply(lambda x:x.isnull(),axis=0) #判断 df_train.isnull().any() #判断列是否有空值 df_train['Age'].isnull().count() #统计某列数据空值个数
- 数据预处理
- 数值型用平均值替换
- 分类用最常见类别取代
df_train['Age'].fillna(df_train['Age'].mean(),inplace=True) #船票价格(Fare) df_train['Fare'] = df_train['Fare'].fillna( df_train['Fare'].mean() ) df_train['Cabin'].value_counts() #统计Cabin类别 df_train['Embarked'].value_counts()
有结果可以看出 Embarked类别有三类,最多为S类
df_train['Embarked'].fillna('S',inplace=True) #填充缺失值
df_train['Cabin'].fillna('U',inplace=True)
特征提取
三种数据类型:
1.数值型
2.时间序列(无)
3.分类数据
df_train['Sex'].head()
# 将性别分类数据 转换为数值型 男1,女0
sex_maple={'male':1,'female':0}
# df_train['Sex'] = df_train['Sex'].map(sex_maple)
result = df_train['Sex'].map(sex_maple)
df_train.Sex = result.values
df_train['Sex']
# 直接类别登船港口(Embarked)进行one-hot编码,性别也可以用此方法
#存放提取后的特征 prefix 指定提取后编码的 前缀名称
embarkedDf = pd.DataFrame()
embarkedDf = pd.get_dummies(df_train['Embarked'], prefix='Embarked')
embarkedDf.head()
# 添加one-hot编码 到 原始数据集,并删掉原始列(即替换)
df_train = pd.concat([df_train,embarkedDf],axis=1)
df_train.drop(['Embarked'],axis=1,inplace=True)
df_train.head(3)
同理:
# 客舱等级 Pclass
pclassDf = pd.DataFrame()
pclassDf = pd.get_dummies(df_train['Pclass'], prefix='Pclass')
# pclassDf.head()
df_train = pd.concat([df_train,pclassDf],axis=1)
df_train.drop(['Pclass'],axis=1,inplace=True)
df_train.head(3)
# 乘客姓名 中间具有一定信息
def getTitle(name): #自定义函数
str1 = name.split(',')[1]
str2 = str1.split('.')[0] #Mr
str3 = str2.strip()
return str3
# 提取姓名中信息
titleDf = pd.DataFrame()
titleDf['Title'] = df_train['Name'].map(getTitle)
titleDf.head()
titleDf.groupby('Title').count() #统计姓名中信息数量
定义以下几种头衔类别:
- Officer政府官员
- Royalty王室(皇室)
- Mr已婚男士
- Mrs已婚妇女
- Miss年轻未婚女子
- Master有技能的人/教师
#姓名中头衔字符串与定义头衔类别的映射关系
title_mapDict = {
"Capt": "Officer",
"Col": "Officer",
"Major": "Officer",
"Jonkheer": "Royalty",
"Don": "Royalty",
"Sir" : "Royalty",
"Dr": "Officer",
"Rev": "Officer",
"the Countess":"Royalty",
"Dona": "Royalty",
"Mme": "Mrs",
"Mlle": "Miss",
"Ms": "Mrs",
"Mr" : "Mr",
"Mrs" : "Mrs",
"Miss" : "Miss",
"Master" : "Master",
"Lady" : "Royalty"
}
#map函数:对Series每个数据应用自定义的函数计算
titleDf['Title'] = titleDf['Title'].map(title_mapDict)
#使用get_dummies进行one-hot编码
titleDf = pd.get_dummies(titleDf['Title'])
titleDf.head()
# 添加one-hot编码 到 原始数据集,并删掉原始列(即替换)
df_train = pd.concat([df_train,titleDf],axis=1)
df_train.drop('Name',axis=1,inplace=True)
df_train.head()
# 客舱号(Cabin)设定同一字母客舱号在一起
cabinDf = pd.DataFrame()
df_train['Cabin'] = df_train['Cabin'].map(lambda x:x[0])
cabinDf = pd.get_dummies(df_train['Cabin'],prefix='Cabin')
cabinDf.head(3)
# 对客舱号(Cabin)进行one-hot 编码
df_train = pd.concat([df_train,cabinDf],axis=1)
df_train.drop('Cabin',axis=1,inplace=True)
df_train.head(3)
家庭数量影响
家庭人数=同代直系亲属数(Parch)+不同代直系亲属数(SibSp)+乘客自己
(因为乘客自己也是家庭成员的一个,所以这里加1)
家庭类别:
小家庭Family_Single:家庭人数=1
中等家庭Family_Small: 2<=家庭人数<=4
大家庭Family_Large: 家庭人数>=5
familyDf = pd.DataFrame()
familyDf['FamilySize'] = df_train['Parch']+df_train['SibSp']+1
familyDf['Family_Single'] = familyDf['FamilySize'].map(lambda x: 1 if x == 1 else 0)
familyDf['Family_Small'] = familyDf['FamilySize'].map( lambda x : 1 if 2 <= x <= 4 else 0)
familyDf['Family_Large'] = familyDf['FamilySize'].map(lambda x: 1 if x>=5 else 0)
familyDf.head(3)
# 添加familyDf 到 原始数据集,并删掉原始列(即替换)
df_train = pd.concat([df_train,familyDf],axis=1)
df_train.head(3)
特征选择
计算各个特征的相关系数
#相关性矩阵
corrDf = df_train.corr()
corrDf
'''
查看各个特征与生成情况(Survived)的相关系数,
ascending=False表示按降序排列
'''
corrDf['Survived'].sort_values(ascending =False)
image.png
根据各个特征与生成情况(Survived)的相关系数大小,我们选择了这几个特征作为模型的输入 头衔(前面所在的数据集titleDf)、客舱等级(pclassDf)、家庭大小(familyDf)、船票价格(Fare)、船舱号(cabinDf)、登船港口(embarkedDf)、性别(Sex)
特征选择
full_x = pd.concat( [titleDf,#头衔
pclassDf,#客舱等级
familyDf,#家庭大小
df_train['Fare'],#船票价格
cabinDf,#船舱号
embarkedDf,#登船港口
df_train['Sex']#性别
] , axis=1 )
full_x.head()
构建模型
- 将训练集拆分为 训练集+验证集
sourceRow = 891
#原始数据集:特征
source_x = full_x.loc[0:sourceRow-1,:]
# #原始数据集:标签(结果)
source_y = df_train.loc[0:sourceRow-1,'Survived']
#预测数据集:特征
pred_x = full_x.loc[sourceRow:,:]
#查看train集数据
print('train数据集个数:', source_x.shape[0])
print('验证数据集个数:', source_y.shape[0])
print('test数据集个数:', pred_x.shape[0])
- 数据拆分
from sklearn.model_selection import train_test_split
#建立模型需要的训练集,及验证集
train_x,test_x,train_y,test_y = train_test_split(source_x,source_y,test_size=0.2)
print('原始数据集特征:',train_x.shape,
'验证数据集特征:',test_x.shape
)
print('原始数据集标签:',train_y.shape,
'验证数据集标签:',test_y.shape
)
- 选择机器学习算法
# 1.导入算法
from sklearn.linear_model import LogisticRegression
# 2.创建模型,逻辑回归
model = LogisticRegression(solver='liblinear')
#随机森林Random Forests Model
#from sklearn.ensemble import RandomForestClassifier
#model = RandomForestClassifier(n_estimators=100)
#支持向量机Support Vector Machines
#from sklearn.svm import SVC, LinearSVC
#model = SVC()
#Gradient Boosting Classifier
#from sklearn.ensemble import GradientBoostingClassifier
#model = GradientBoostingClassifier()
#K-nearest neighbors
#from sklearn.neighbors import KNeighborsClassifier
#model = KNeighborsClassifier(n_neighbors = 3)
# Gaussian Naive Bayes
#from sklearn.naive_bayes import GaussianNB
#model = GaussianNB()
- 训练模型
model.fit(train_x,train_y)
- 模型评估
model.score(test_x,test_y)
- 使用预测集数据
pred_y = model.predict(pred_x)
#生成的预测值是浮点数(0.0,1,0)
#如果需要整型(0,1)
#则要对数据类型进行转换
pred_y = pred_y.astype(int)
#乘客id
passenger_id = df_train.loc[sourceRow:,'PassengerId']
predDf = pd.DataFrame(
{'PassengerId':passenger_id,
'Survived':pred_y}
)
predDf.shape
predDf.head()
- 保存结果
predDf.to_csv('./data/titanic_pred.csv',index=False)
网友评论