Titanic生还预测分析

# coding: utf-8
# 本文预测泰坦尼克号生还率,鉴于前边学习了简单线性回归,逻辑回归,本案例对这两种方法进行运用
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt


# 
提纲思路:
# 第一步:导入数据,查看数据内容
# 第二步:数据清洗
#    1.数据预处理
#    2.数据特征提取
# 第三步:建立模型
# 第四步:模型评估
# 第五步:方案实施
#    1.提交到kaggle
#    2.撰写分析报告 # 忽略警告提示 import warnings warnings.filterwarnings('ignore') # 第一步:
# 导入数据,查看数据内容 # 这里的训练数据集和测试数据集已经分割好了,直接导入 trainDF = pd.read_csv('../机器学习(入门)/3.泰坦尼克号/train.csv') testDF = pd.read_csv('../机器学习(入门)/3.泰坦尼克号/test.csv') print(trainDF.shape,testDF.shape) trainDF.head() testDF.head() # 记录下原始数据量 rowNum_train = trainDF.shape[0] rowNum_test = testDF.shape[0] print('训练数据量为:',rowNum_train) print('测试数据量为:',rowNum_test) # 合并数据集,方便对两个数据集同时清洗(此处合并除了少了一部分清洗工作,还有什么别的功能?) integDF = pd.concat([trainDF,testDF],axis = 0,ignore_index = True) integDF.shape integDF.head() # 查看数据描述信息 integDF.describe() # 为了查看每一列的数据状态,我们用info方法 integDF.info() # 信息解释:(共有1309条数据)
# 1.年龄:1046条非空数据,也就是有263条缺失数据,缺失占比:20.09%
# 2.舱位:295条非空数据,缺失较多,缺失占比:77.46%
# 3.登船入口:2条缺失
# 4.船票价格:1条缺失
# 5.生还数据:891条非空数据,缺失418条数据,缺失占比:31.93%
# 6.其他数据:完整
# 第二步(1):
# 对数据的预处理
# 对于缺失数据的处理,是一个很重要的问题,由于个人能力所限,仅用最简单的填充方法 # 对于数值类型的数据,用平均值来填充 integDF['Age'] = integDF['Age'].fillna(integDF['Age'].mean()) integDF['Fare'] = integDF['Fare'].fillna(integDF['Fare'].mean()) integDF.info() # 对于登船入口的填充,这里用最简单(事实上也是不太靠谱)的方法:填充出现频次最高的信息 # 但是由于只有两条缺失,影响也不是很大 integDF['Embarked'].value_counts() # s的出现频次最高,我们用s填充 integDF['Embarked'] = integDF['Embarked'].fillna('S') integDF.head() # 对于Cabin舱位的缺失值,用‘未知’来代替,‘U' integDF['Cabin'] = integDF['Cabin'].fillna('U') integDF.head() # 检查清洗完毕的数据,除去标签数据’Survived‘需要预测,特征数据全部整理完毕 integDF.info() # 第二步(2):
# 特征提取 ''' 首先对特征数据进行分类,由以上信息可见有: 1.数值型信息(计量型):Age,Fare(船票价格),PassengerId,Parch(不同代直系亲属人数),SibSp(同代直系亲属人数) 2.时间序列:无 3.分类型信息: 1)直接分类信息: 乘客性别(Sex):男性male,女性female 登船港口(Embarked):S,Q,C 客舱等级(Pclass):1=1等舱,2=2等舱,3=3等舱 2)无固定分类,待提取分类: 乘客姓名(Name) 客舱号(Cabin) 船票编号(Ticket) '''
# 对直接类别分类,用数字代替字符串
# 对于Age特征,两变量分类直接用01代替
sex_map={'male':1,'female':0}
integDF['Sex'] = integDF['Sex'].map(sex_map)
integDF.head()


# 对于Embarked登船港口,有三个变量:S,C,Q
# 对此可以采用生成虚拟变量的方式,即分为三类,是:1,否:0
EmbarkedDF = pd.get_dummies(integDF['Embarked'],prefix='Embarked')
EmbarkedDF.head()

# 以上方法叫做独热编码one_hot encoding,对于一个特征,如果有n个可能值,独热处理后则会变成n个二元特征
# 分类之后,我们需要将新的特征插入,删除旧特征
integDF = pd.concat([integDF,EmbarkedDF],axis=1)
integDF.drop(labels='Embarked',axis=1,inplace=True)
integDF.shape


# 对于客舱等级,同样采取独热处理的方法,因为虽然是数字,还是不能清晰分类
PclassDF = pd.get_dummies(integDF['Pclass'],prefix='Pclass')
PclassDF.head()

# 联结新特征,抛掉旧特征
integDF = pd.concat([integDF,PclassDF],axis=1)
integDF.drop(labels='Pclass',axis=1,inplace=True)
integDF.shape
integDF.head()


# 接下来要对无固定分类的数据进行提取有效信息
# 乘客姓名(Name)
# 客舱号(Cabin)
# 船票编号(Ticket)
# 先对名字下手,查看一下名字有什么特征 [name for name in integDF['Name'].head(15)] # 可以看到名字列中有头衔,Mr,Miss,Mrs,Master 等等,我们可以正则匹配出此头衔,然后加入新列表作为特征值 import re L = [] pat = r',\s+(.+)\.' for name in integDF['Name']: d = re.findall(pat,name) try: L.append(d[0]) except: print(name) continue print(L[:15]) # 将提取出的称谓加入数据框 TitleDF = pd.DataFrame(L,columns=['Title']) len(TitleDF) # 查看称谓数量 TitleDF['Title'].value_counts() ''' 在kaggle项目内容介绍中查看头衔类别: Officer政府官员 Royalty王室(皇室) Mr已婚男士 Mrs已婚妇女 Miss年轻未婚女子 Master有技能的人/教师 ''' #姓名中头衔字符串与定义头衔类别的映射关系 title_map = { "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" } TitleDF['Title'] = TitleDF['Title'].map(title_map) TitleDF.head() # 使用独热编码方式分类 TitleDF = pd.get_dummies(TitleDF['Title'],prefix='Title') TitleDF.head() # 将新产生的特征数据框插入原数据框 integDF = pd.concat([integDF,TitleDF],axis=1) integDF.drop(labels='Name',axis=1,inplace=True) integDF.head() # 接下来从客舱号中提取客舱类别 # 查看客舱名称规律 integDF['Cabin'].value_counts() # 决定用首字母来区分客舱类别,由于是字符串类型,可以切片 CabinDF = pd.DataFrame() CabinDF['Cabin'] = integDF['Cabin'].map(lambda a : a[0]) CabinDF['Cabin'].value_counts() # one-hot 独热编码处理 CabinDF = pd.get_dummies(CabinDF['Cabin'],prefix='Cabin') CabinDF.head() # 将处理好的舱位数据加入原数据框 integDF = pd.concat([integDF,CabinDF],axis=1) # 删除原有仓位信息 integDF.drop(labels=['Cabin'],axis=1,inplace=True) integDF.head() # 接下来要处理的是每个人家庭人数问题,有Parch(不同代直系亲属人数),SibSp(同代直系亲属人数) # 此步骤的目的是将特征按照家庭人数分割,家庭人数包括了直系和非直系 familyList = [] for i in range(len(integDF)): s = integDF['Parch'][i] + integDF['SibSp'][i] + 1 familyList.append(s) familyList[:15] familyDF = pd.DataFrame(familyList,columns=['num']) familyDF.head() # 此步骤按照家庭人数分类:1,2~5,5以上 familyDF['family_single'] = familyDF['num'].map(lambda a : 1 if a==1 else 0) familyDF['family_small'] = familyDF['num'].map(lambda a : 1 if 15 else 0) familyDF.head() # 删除num,并加入原有数据框 familyDF.drop(labels=['num'],axis=1,inplace=True) integDF = pd.concat([integDF,familyDF],axis=1) integDF.drop(labels=['Parch','SibSp'],axis=1,inplace=True) integDF.head() integDF.info() # 到此为止,数据整理完毕
# 第二步(3):
# 数据特征提取 #
# 建立相关性矩阵 corrDF = integDF.corr() corrDF # 查看各个特征与标签之间的相关性系数 orderList=corrDF['Survived'].sort_values(ascending=False) orderList # 根据相关性大小,选择一些相关系数绝对值较大的特征进行模型的输入:
# 头衔(前面所在的数据集TitleDF)、客舱等级(PclassDF)、家庭大小(familyDF)、
# 船票价格(Fare)、船舱号(CabinDF)、登船港口(EmbarkedDF)、性别(Sex)
X_integer = pd.concat([TitleDF,PclassDF,familyDF,CabinDF,EmbarkedDF,integDF['Fare'],integDF['Sex']],axis=1) X_integer.head() X_integer.info() # 第三步:
# 建立模型 #
# 数据处理完成后,需要将原始数据和测试数据分离开来,前边并没有做过排序,因此顺序没有改变,直接取前891行就是原始数据 # 原始数据 source_X = X_integer.iloc[:891,:] pred_X = X_integer.iloc[891:,:] # 此处要注意,ix切片时属于闭区间切片 source_y = integDF.ix[:890,'Survived'] source_X.shape source_y.shape pred_X.shape # 选取完数据,下面进行建模分析 from sklearn.cross_validation import train_test_split X_train,X_test,y_train,y_test = train_test_split(source_X,source_y,test_size=0.2) #输出数据集大小 print ('原始数据集特征:',source_X.shape, '训练数据集特征:',X_train.shape , '测试数据集特征:',X_test.shape) print ('原始数据集标签:',source_y.shape, '训练数据集标签:',y_train.shape , '测试数据集标签:',y_test.shape) # 建立模型,逻辑回归 from sklearn.linear_model import LogisticRegression model = LogisticRegression() model.fit(X_train,y_train) model.score(X_test,y_test) X_integer.info() pred_y = model.predict(pred_X)

type(pred_y)

pred_y.dtype

pred_y = pred_y.astype('int')

pred_y.dtype

integDF['PassengerId'].dtype

passengerID = integDF.ix[891:,'PassengerId']
print(len(passengerID),len(pred_y))

passengerID.tail()

print(pred_y.shape)
print(passengerID.shape)
print(type(pred_y))
print(type(passengerID))


predDF = pd.DataFrame({'passengerID':passengerID,'Survived':pred_y})
predDF.head()

# 导入文件
predDF.to_csv('titanic_pred.csv',index=False )


 
 

你可能感兴趣的:(数据分析)