数据集
1、分析需求
2、探索性数据分析(EDA)
性别:是离散型变量
Age:连续型变量
Fare:票价,连续型变量,可以使用箱线图或者小提琴图看分布
Pclass
Embarked:离散型变量
3、特征工程
特征抽取
抽取 Title 特征
抽取家庭规模
缺失值填充
Age:根据 Sex、Pclass 和 Title 分组,如果落在相同的组别里,就用这个组别的中位数填充
Fare:缺失值较多,使用平均值填充。(本人水平不够,先略过)
编辑
编辑
编辑
离散型变量处理成独热编码
编辑
编辑
编辑
4、模型训练与评估
测试数据集
https://download.csdn.net/download/llf000000/86732641
训练数据集
https://download.csdn.net/download/llf000000/86732643
1.os.listdir()
描述
os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表
只支持在 Unix, Windows 下使用
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
print(os.listdir(r"C:\Users\10596\课程作业\泰坦尼克号"))
没加“r”之前,出现这样的报错
SyntaxError: (unicode error) ‘unicodeescape‘ codec can‘t decode bytes in position 2-3: truncated \UX
问题点:python中\是转义的也是,必须去掉转义
方法一:加r强制不转义可写为:
fd = os.open(r"C:\Users\eric\Desktop\python\foot.txt", os.O_RDWR|os.O_CREAT )
方法二:加
fd = os.open(“C:\Users\eric\Desktop\python\foot.txt”, os.O_RDWR|os.O_CREAT )
方法三:正斜杠法/
fd = os.open(“C:/Users/eric/Desktop/python/foot.txt”, os.O_RDWR|os.O_CREAT )
data_train = pd.read_csv("train.csv")
data_test = pd.read_csv("test.csv")
data_train.head()
data_test.head()
data_train.shape, data_test.shape
data_train.info()
data_test.info()
data_train.describe()
data_test.describe()
参数说明:
x: x轴上的条形图,以x标签划分统计个数y:y轴上的条形图,以y标签划分统计个数
hue:在x或y标签划分的同时,再以hue标签划分统计个数
data:df或array或array列表,用于绘图的数据集,x或y缺失时,data参数为数据集,同时x或y不可缺少,必须要有其中一个
palette:使用不同的调色板
color = {0: 'r', 1: 'g'}
sns.countplot(data=data_train,x='Sex', hue='Survived', palette=color)
plt.show()
下面这一步是创建列联表,然后进行卡方检验,以检测“性别”对“是否幸存”是否有影响
scipy.stats
scipy.stats 是 scipy 专门用于统计的函数库,所有的统计函数都位于子包 scipy.stats 中,可以使用 scipy.info(scipy.stats) 函数获得这些函数的完整列表。
sex_survived_pivot_table = pd.pivot_table(
data_train,
index='Sex',
columns='Survived',
values='PassengerId',
aggfunc='count')
sex_survived_pivot_table
from scipy.stats import chi2_contingency
chi2_contingency(sex_survived_pivot_table.values)[1]
可以看到p值为1.1973570627755645e − 58,远小于0.05,因此“性别 ” 和 “ 幸存 ” 的确不是独立的, “ 性别” 是一项预测 “ 是否幸存 ” 的重要特征。
fig, axes = plt.subplots(nrows=1, ncols=2)
fig.set_size_inches(18, 6)
data_train[data_train['Survived'] == 1]['Age'].hist(color='g', ax=axes[0])
axes[0].set_title('Survived Age hist', size=18)
data_train[data_train['Survived'] == 0]['Age'].hist(color='r', ax=axes[1])
axes[1].set_title('Died Age hist', size=18)
plt.show()
set_size_inches设置
plt.figure().set_size_inches(6,8)#6,8分别对应宽和高
可以看出,年轻人幸存较多
sns.boxplot( data=data_train,x="Survived", y="Fare", palette={0: 'r', 1: 'g'})
plt.show()
fig,ax = plt.subplots()等价于:
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
fig, ax = plt.subplots(1,3),其中参数1和3分别代表子图的行数和列数,一共有 1x3 个子图像。函数返回一个figure图像和子图ax的array列表。
fig, ax = plt.subplots(1,3,1),最后一个参数1代表第一个子图。
如果想要设置子图的宽度和高度可以在函数内加入figsize值
fig, ax = plt.subplots(1,3,figsize=(15,7)),这样就会有1行3个15x7大小的子图。
我们准备区间化两组数据:第一组是被救上来的人的船票价格,第二组是没被救上来的船票价格。都需要DataFrame格式。这就用到之前对DateFrame的选择了,还用到了布尔下标:
s1=train[train['Survived']==1]['Fare']
s2=train[train['Survived']==0]['Fare']
注意,布尔下标不能直接是'Survived'==1,要把train加上。这样我们就分别得到了两组数据。
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(18, 8))
sns.distplot(data_train[data_train['Survived'] == 1]['Fare'], color='g', ax=axes[0])
sns.distplot(data_train[data_train['Survived'] == 0]['Fare'], color='r', ax=axes[1])
plt.show()
plt.figure(figsize=(18, 8))
sns.distplot(data_train[data_train['Survived'] == 1]['Fare'], color='g')
sns.distplot(data_train[data_train['Survived'] == 0]['Fare'], color='r')
plt.show()
可以看出,票价比较低的,遇难的人数比较多,因此票价是一个重要的特征。
color = {0: 'r', 1: 'g'}
sns.countplot(x='Pclass', hue='Survived', palette=color, data=data_train)
plt.show()
pclass_survived_pivot_table = pd.pivot_table(
data_train,
index='Pclass',
columns='Survived',
values=['PassengerId'],
aggfunc='count')
pclass_survived_pivot_table
chi2_contingency(pclass_survived_pivot_table.values)[1]
plt.figure(figsize=(18, 6))
sns.boxplot(x='Pclass', y='Fare', data=data_train, hue='Survived', palette=color)
plt.show()
乘客等级为 1 的,票价相对较高。
data_train['Embarked'].unique()
在处理数据中,如果希望查看列中的去重之后的不同值或者唯一值,这可以使用 Pandasunique()函数来完成。Python的Pandas库Series.unique方法会返回Series中的唯一值。这些值是按照出现顺序排序的,它返回一个
NumPy
数组。
sns.countplot(x='Embarked', hue='Survived', palette=color, data=data_train)
plt.show()
S 登船港口罹难者多,C 登船港口幸存者多。
plt.figure(figsize=(18, 6))
sns.boxplot(
x='Embarked', y='Fare', data=data_train, hue='Survived', palette=color)
plt.show()
embarked_survived_pivot_table = pd.pivot_table(
data=data_train,
index='Embarked',
columns='Survived',
values='PassengerId',
aggfunc='count')
embarked_survived_pivot_table
chi2_contingency(embarked_survived_pivot_table.values)[1]
data_train.head()
data_test.head()
pandas 中 inplace 参数在很多函数中都会有,它的作用是:是否在原对象基础上进行修改
inplace = True:不创建新的对象,直接对原始对象进行修改;
inplace = False:对数据进行修改,创建并返回新的对象承载其修改结果。
默认是False,即创建新的对象进行修改,原对象不变,和深复制和浅复制有些类似。
y = data_train.Survived
PassengerId = data_test.PassengerId
data_train.drop(['Survived'], axis=1, inplace=True)
combined = pd.concat([data_train, data_test], sort=False, axis=0)
combined.shape
combined.drop(['PassengerId'], inplace=True, axis=1)
combined.shape
combined['title'] = combined['Name'].map(
lambda x: x.split(',')[1].split('.')[0].strip())
map函数。此时lambda函数用于指定对列表中每一个元素的共同操作。例如map(lambda x: x+1, [1, 2,3])将列表[1, 2, 3]中的元素分别加1,其结果[2, 3, 4]。
1、strip()方法
strip() 方法用于移除字符串头尾指定的字符(默认为空格)。
strip()方法语法:str.strip([c])
c指的是字符串头尾指定的字符str = "FFF I am a zhulang FFF";
print str.strip( 'FFF' );
输出:I am a student2、split()方法
split()方法通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串
split()方法语法:str.split(str="", num=string.count(str)).
参数:
str – 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
num – 分割次数。str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
print str.split( );
print str.split(' ', 1 );
输出:
[‘Line1-abcdef’, ‘Line2-abc’, ‘Line4-abcd’]
[‘Line1-abcdef’, ‘\nLine2-abc \nLine4-abcd’]
combined['title'].value_counts()
# 再根据这些 title 细分,是官员,还是皇室,还是女士、先生、小姐
combined['title'].unique()
Title_Dictionary = {
"Mr": "Mr",
"Mrs": "Mrs",
"Miss": "Miss",
"Master": "Master",
"Don": "Royalty",
"Rev": "Officer",
"Dr": "Officer",
"Mme": "Mrs",
"Ms": "Mrs",
"Major": "Officer",
"Lady": "Royalty",
"Sir": "Royalty",
"Mlle": "Miss",
"Col": "Officer",
"Capt": "Officer",
"the Countess": "Royalty",
"Jonkheer": "Royalty",
"Dona": 'Mrs'
}
combined['Title'] = combined['title'].map(Title_Dictionary)
combined['Title'].value_counts()
del combined['Name']
del combined['title']
combined.head()
combined['FamilySize'] = combined['SibSp'] + combined['Parch'] + 1
print(combined['FamilySize'].head())
def deal_with_family_size(num):
if num == 1:
return 'Singleton'
elif num <= 4:
return 'SmallFamily'
elif num >= 5:
return 'LargeFamily'
return num
combined['FamilySize'] = combined['FamilySize'].map(deal_with_family_size)
combined.isnull().sum()
根据 Sex、Pclass 和 Title 分组,如果落在相同的组别里,就用这个组别的平均数填充。
combined.groupby(['Sex', 'Pclass', 'Title'])['Age'].mean()
age_group_mean = combined.groupby(['Sex', 'Pclass', 'Title'])['Age'].mean().reset_index()
age_group_mean
def select_group_age_median(row):
condition = ((row['Sex'] == age_group_mean['Sex']) &
(row['Pclass'] == age_group_mean['Pclass']) &
(row['Title'] == age_group_mean['Title']))
return age_group_mean[condition]['Age'].values[0]
# 针对每一行做映射,所以要加上 `axis=1`
combined['Age'] = combined.apply(
lambda x: select_group_age_median(x) if np.isnan(x['Age']) else x['Age'],
axis=1)
combined['age_bin'].head()
combined.isnull().sum()
combined['Fare'].fillna(combined['Fare'].mean(), inplace=True)
combined['Embarked'].fillna(combined['Embarked'].mode(), inplace=True)
combined.head()
combined.loc[combined['Cabin'].notnull(), 'Cabin'] = 'yes'
combined.loc[combined['Cabin'].isnull(), 'Cabin'] = 'no'
combined['Cabin'].value_counts()
combined.head()
combined = pd.get_dummies(
combined,
columns=[
'Sex', 'Cabin', 'Pclass', 'Embarked', 'Title', 'FamilySize', 'age_bin'
],
drop_first=True)
combined.drop(['Ticket'], axis=1, inplace=True)
X_train = combined.iloc[:891]
X_test = combined.iloc[891:]
X_train.head()
X_test.head()
from sklearn.ensemble import RandomForestClassifier#随机森林分类
rfc = RandomForestClassifier(n_estimators=100, max_features='sqrt')
from sklearn.model_selection import cross_val_score
scores = cross_val_score(rfc, X_train, y, cv=10)
scores
scores.mean()
rfc.fit(X_train, y)
rfc.feature_importances_
X_train.columns
feature_importances = pd.Series(rfc.feature_importances_, X_train.columns)
feature_importances.sort_values(ascending=False, inplace=True)
feature_importances
feature_importances.plot(kind='barh')#kind='barch'(水平柱状图)即可生成柱状图
plt.show()