今天完成了本周练习kaggle的任务,动手实践了经典项目 Tiantic
相关代码如下所示:
# coding: utf-8
# 项目背景:
#
# 根据数据集合,来预测哪些人群最有可能生还
#
# 字段详解:
# survival : 是否生还 0----没有,1----生还
# pclass: 船票等级 1=1st,2=2nd,3=3rd
# sex
# age
# sibsp: 船上的配偶们
# parch: 船上的孩子们
# ticket: ticket number
#
#
#
# In[33]:
import pandas as pd
import numpy as np
import random as rnd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC,LinearSVC
from sklearn.ensemble import RandomForestClassifier
# In[3]:
#读入相关数据
train_df=pd.read_csv(r'C:\\Users\\Lenovo\\Desktop\\hands-on-machine-learning\\ml of finding job\\train.csv')
test_df=pd.read_csv(r'C:\\Users\\Lenovo\\Desktop\\hands-on-machine-learning\\ml of finding job\\test.csv')
combine=[train_df,test_df]
train_df.shape##891行12列
test_df.shape ##418行11列
train_df.head(10)
train_df.info()#可以看到非空数据的个数,以及相应的数据类型
# In[41]:
##可能跟生还有关的属性为 性别,年龄,以及船票类型
train_df[['Pclass','Survived']].groupby(['Pclass'],as_index=False).sum().sort_values(by='Survived',ascending=False)##as_index 默认为True,将会以groupby 对象维索引
##头等舱的人最容易生还
train_df[['Sex','Survived']].groupby(['Sex'],as_index=False).sum().sort_values(by='Survived',ascending=False)##as_index 默认为True,将会以groupby 对象维索引
#女性最容易生还
# In[42]:
#下面用sns.FaceGride 来进行作图,他的好处就是可以根据指定的情况建立多个图形,分块展示
grid=sns.FacetGrid(train_df,col='Pclass',row='Survived',aspect=1.6,)
#aspect 横纵坐标轴比,col_order=[],传入列表,是列对应的值,hue='Pclass'则会在右侧显示,变成图例标签
vis1=grid.map(plt.hist,'Age',alpha=0.5,bins=20,color='g')
vis1.add_legend()
# In[4]:
grid = sns.FacetGrid(train_df, row='Embarked', size=2.2, aspect=1.6)#row,col
grid.map(sns.pointplot,'Pclass','Survived','Sex', palette='deep',markers='o')##map 中指定行和列
grid.add_legend()
# In[5]:
##删除我们认为i不会对生还结果产生影响的特征参数
train_df = train_df.drop(['Ticket', 'Cabin'], axis=1)
test_df = test_df.drop(['Ticket', 'Cabin'], axis=1)
combine = [train_df, test_df]
train_df.shape
test_df.shape
# combine[0].shape
# combine[1].shape
# In[7]:
# for dataset in combine:##其实就是分别到处训练集合和测试集合
# pass
# print(dataset.Name
"""
观察名字的结构,一般都为Mr.什么
下面要做的就是把诸如Mr,Mrs等的提取出来,采用的额就是正则表达式
"""
for dataset in combine:
dataset['title']=dataset.Name.str.extract('([A-Za-z]+)\.',expand=False)#以Series 的形式返回,加号不能丢
"""
下面使用交叉表,可以汇总看一下
男女 不同的是性的个数
参数 index 指定行键名
columns 指定列键名称
"""
pd.crosstab(train_df.title,train_df.Sex)##这个方法非常管用,发现MR,MISS居多
# In[8]:
##根据上述的结果,将名称做一些改动
for dataset in combine:
dataset['title'] = dataset['title'].replace(['Lady', 'Countess','Capt', 'Col', 'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')##少见的标记为rare
dataset['title'] = dataset['title'].replace('Mlle', 'Miss')
dataset['title'] = dataset['title'].replace('Ms', 'Miss')
dataset['title'] = dataset['title'].replace('Mme', 'Mrs')
#然后看一下不同姓氏,也就是不同社会等级的生还率
train_df[['title','Survived']].groupby(['title'],as_index=False).mean()#as_index=True 表示没有 0,1,2,3,作为索引
"""
方法2采用map 方法实现,便捷有效
map 方法传入的是字典,键所在的列调用map 方法,返回的%%bash键对应的值名称
apply 则适用于某行数值的统一计算,一般结合lambda 使用
"""
title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}
for dataset in combine:
dataset['title'] = dataset['title'].map(title_mapping)
dataset['title'] = dataset['title'].fillna(0)
train_df.head()
# In[47]:
##因为我们已经修改类Name ,于是可以大胆的舍弃Name,列,而Passengerid 也是没什么用,因此也扔掉
train_df = train_df.drop(['Name', 'PassengerId'], axis=1)#axis=1 表示列
test_df = test_df.drop(['Name'], axis=1)
combine = [train_df, test_df]
train_df.shape, test_df.shape
# In[9]:
##将性别转化为整形的0,1
for dataset in combine:
dataset['Sex'] = dataset['Sex'].map( {'female': 1, 'male': 0} ).astype(int)
train_df.head()
# In[10]:
train_df.info()
##发现 Age 有 100多个缺失值,因此需要进行缺失值的填充
"""
我们发现,不同的船票等级和性别不同
年龄的分布也是不一样的
那我们是不是可以根据这两%%javascript标签来预测年龄呢
从而填充缺失值
步骤
1. 看一下不同的pclass\sex %xde的年龄分布
2.生成一个初始化矩阵,用于填充 不同 pclass\sex 下的年龄预测值
3.进行缺失值的填充
"""
# In[50]:
grid=sns.FacetGrid(train_df,row='Pclass',col='Sex',aspect=1.6)
grid.map(plt.hist,'Age',alpha=0.5,bins=20)
grid.add_legend()
# In[12]:
#第二步生成一个相关的矩阵,用于存放预测年龄
guess_ages=np.zeros((2,3))
guess_ages
# In[29]:
#第三步,进行相关的缺失值的填充
for dataset in combine:
for i in range(2):#用于限定性别
for j in range(3):#用于限定 pclass
guess_df=dataset[(dataset['Sex']==i)& (dataset['Pclass']==j+1)]['Age'].dropna()
# age_mean = guess_df.mean()
# age_std = guess_df.std()
# age_guess = rnd.uniform(age_mean - age_std, age_mean + age_stds
age_guess=guess_df.median()
guess_ages[i,j] = int( age_guess/0.5 + 0.5 ) * 0.5 #下面就将该值进行相关的填充
dataset.loc[(dataset.Age.isnull())&(dataset.Sex==i)&(dataset.Pclass==j+1),'Age']=guess_ages[i,j]
dataset['Age']=dataset['Age'].astype(int)#转化为整述
# return dataset 只能卸载定义函数里面
train_df.info()##发现缺失值被全部填充完毕
train_df.head(5)
##将牛按铃段分成几个区间
train_df['ageband']=pd.cut(train_df.Age,5)
train_df.ageband
train_df[['ageband','Survived']].groupby(by='ageband',as_index=False).mean()
# In[69]:
#用标签表示
for dataset in combine:
dataset.loc[ dataset['Age'] <= 16, 'Age'] = 0
dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
dataset.loc[ dataset['Age'] > 64, 'Age']
train_df.head()
# train_df.drop(['ageband'],axis=1,inplace=True)
combine=[train_df,test_df]
train_df
##自己还可以探索一下其他维度,方法同上都差不多
train_df = train_df.drop(['PassengerId'], axis=1)
combine = [train_df, test_df]
train_df.head()
# In[71]:
####下面进入模型预测阶段,准备数据集合
X_train = train_df.drop("Survived", axis=1)
Y_train = train_df["Survived"].apply(lambda x:int(x))
X_test = test_df.drop("PassengerId", axis=1).copy()
X_train.shape, Y_train.shape, X_test.shape
# In[73]:
logreg = LogisticRegression()
logreg.fit(X_train, Y_train)
Y_pred = logreg.predict(X_test)
acc_log = round(logreg.score(X_train, Y_train) * 100, 2)
acc_log