每个Kaggle竞赛中都遵守着一个基本的模版
1.了解问题和数据
2.数据清理和格式化
3.探索性数据分析
4.基准模型
5.改进的模型
6.模型解释
接下来,我将按照这跟模版对Titanic survival进行操作
一、了解问题和数据
数据:
- survival:定义生存乘客是否存活,用0,1表示,0为已死亡,1为存活
- pclass:定义船票为第几类,有三种,1为一等船票,2为二等船票,3为三等船票
- sex:乘客的性别,男-male,女-female
- Age:乘客的年例
- sibsp:船上的兄弟姐妹/配偶的数量
ps:数据集定义这样的家庭关系.兄弟姐妹=兄弟,姐妹,同父异母的弟弟,义妹
配偶=丈夫,妻子(包二奶和未婚夫被忽略) - parch:船上的上的父母/孩子的数量
- ticket:船票上的的号码
- fare:乘客票价
- cabin:客舱号码
- embarked:登船港口(C =瑟堡,Q =皇后镇,S =南安普敦)
- PassengerId:定义为乘客的id号码
我们在上面已对数据有所了解,现在让我们读入数据,查看数据上的问题,数据问题会使我们之后的学习模型无法读取或者出现各种异常而影响精准度。
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
import seaborn as sns
import matplotlib.pyplot as plt
#导入需要使用的基本模块
titanic_df = pd.read_csv('train.csv') # 读取训练集数据
test_df = pd.read_csv('test.csv') # 读取测试集数据
print(titanic_df.describe()) # 对我们即将进行处理的训练集进行描述性统计
输出结果:
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
1 2 1 1 ... 71.2833 C85 C
2 3 1 3 ... 7.9250 NaN S
3 4 1 1 ... 53.1000 C123 S
4 5 0 3 ... 8.0500 NaN S
[5 rows x 12 columns]
PassengerId Survived ... Parch Fare
count 891.000000 891.000000 ... 891.000000 891.000000
mean 446.000000 0.383838 ... 0.381594 32.204208
std 257.353842 0.486592 ... 0.806057 49.693429
min 1.000000 0.000000 ... 0.000000 0.000000
25% 223.500000 0.000000 ... 0.000000 7.910400
50% 446.000000 0.000000 ... 0.000000 14.454200
75% 668.500000 1.000000 ... 0.000000 31.000000
max 891.000000 1.000000 ... 6.000000 512.329200
[8 rows x 7 columns]
在这里我的编译器出现了问题,每行中间出现了省略号,我自行google了一下
他说,这里看到每一行中间都会出现一个“...”省略号,这是因为模块对于每一行的显示限制,以内存最小形式来显示,所以会以省略号代替其中间的内容。
如果数据行很多的话,对于pandas模块是自动默认只显示100行数据,如果超100行,例如120行,则中间的20行会被“ ... ”替代!
所以解决方法:先对数据读取后,再用以下代码对省略号进行处理:
pd.set_option('display.width',None)
加上,成功显示
所有结果如下:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
PassengerId Survived Pclass Age SibSp Parch Fare
count 891.000000 891.000000 891.000000 714.000000 891.000000 891.000000 891.000000
mean 446.000000 0.383838 2.308642 29.699118 0.523008 0.381594 32.204208
std 257.353842 0.486592 0.836071 14.526497 1.102743 0.806057 49.693429
min 1.000000 0.000000 1.000000 0.420000 0.000000 0.000000 0.000000
25% 223.500000 0.000000 2.000000 20.125000 0.000000 0.000000 7.910400
50% 446.000000 0.000000 3.000000 28.000000 0.000000 0.000000 14.454200
75% 668.500000 1.000000 3.000000 38.000000 1.000000 0.000000 31.000000
max 891.000000 1.000000 3.000000 80.000000 8.000000 6.000000 512.329200
看到上述数据,我们可以开始对其进行分析了,在上面,我看到了以下问题
1.sex 性别 Male 和 female 是模型无法识别的字符,我们需要将它更改为0,1
2.Embarked与sex一样是模型无法识别的支付,我们需要将它更改为0,1,2
3.票价浮动很大,这样会出现的数据很明显会散的很开,不利于我们的统计
但是数据描述显示不是很明显,我们让他显示一下柱状图,这样就可以更加直观地看出浮动有多大
sns.distplot(titanic_df["Fare"])
看出到上述问题,我们进入下一步
二、数据清理和格式化
检查缺失值,这个很重要,因为假如有缺失值我们没发现的话,有很多字符处理也没有作用,并且在后面使用学习模型时,有可能无法读取数据从而产生不好的影响,
统计缺失值和统计各个类数据的缺失值占有的百分比:
# 计算丢失值的函数
def missing_values_table(df):
# 总缺失值
mis_val = df.isnull().sum()
# 计算缺失值的百分比
mis_val_percent = 100 * df.isnull().sum() / len(df)
# 显示结果的表格
mis_val_table = pd.concat([mis_val, mis_val_percent], axis=1)
# 重命名列
mis_val_table_ren_columns = mis_val_table.rename(
columns = {0 : 'Missing Values', 1 : '% of Total Values'})
# 按下降百分比对表进行排序
mis_val_table_ren_columns = mis_val_table_ren_columns[
mis_val_table_ren_columns.iloc[:,1] != 0].sort_values(
'% of Total Values', ascending=False).round(1)
# 显示部分信息
print ("Your selected dataframe has " + str(df.shape[1]) + " columns.\n"
"There are " + str(mis_val_table_ren_columns.shape[0]) +
" columns that have missing values.")
# 返回缺少的信息值
return mis_val_table_ren_columns
# 统计缺失值
missing_values = missing_values_table(titanic_df)
print(missing_values.head(20))
最后得出结果:
我从结果图中,可以清晰地看到,Cabin、Age、Embarked这三个数据都有缺失值,并且Cabin缺失值占比例高达77%,而Embarked才达2%,现在让我开始处理它们
三、探索性数据分析
从少的入手,第一个,Embarked这个缺失值才占比例0.2,这个就只用登船地点人数最多来填补,大概率事件嘛
print(titanic_df['Embarked'].describe()) # 对训练集进行描述性统计
从结果图中,我可以看到最多人登船的为S,所以我将S填入缺失值中
titanic_df['Embarked'] = titanic_df['Embarked'].fillna('S') # 将S填入缺失值
现在Embarked缺失值搞定,我顺手把Embarked的字符问题完成,对于这种少量的编码,我只需要使用标签编码就可以了,但是当一个类数据需要对很多数据标签时,就需要用完独热编码:
titanic_df.loc[titanic_df['Embarked'] == 'S', 'Embarked'] = 0 # 0代替S字符表达
titanic_df.loc[titanic_df['Embarked'] == 'C', 'Embarked'] = 1 # 1代替C字符表达
titanic_df.loc[titanic_df['Embarked'] == 'Q', 'Embarked'] = 2 # 2代替Q字符表达
对了,性别没有缺失值,我也可以顺便将性别的字符问题完成:
titanic_df.loc[titanic_df['Sex'] == 'male', 'Sex'] = 0
titanic_df.loc[titanic_df['Sex'] == 'female', 'Sex'] = 1
处理第二个有缺失值的数据,Age
Age的缺失值百分比介于15%到30%之间,这样的缺失值,无法用大概率替换,且无法直接除掉这个数据,所以可以选择判断Age年龄与各个数据的相关性来进行关系性填充,但是以我现在的知识量,我暂时无法良好使用相关性,甚至有可能产生负效果,所以我还是选择了用Age现有数据的平均值填充NAN的值
# 处理Age
print(titanic_df.head())
Age_ave = np.mean(titanic_df['Age'])
titanic_df['Embarked'] = titanic_df['Age'].fillna(Age_ave) # 将Age_ave填入缺失值
最后一个缺失值Cabin
从百分比来看,Cabin的缺失值高达77%,缺失值占有如此高的比例情况下,我们可以选择直接删除这个数据
不使用Cabin
四、基准模型
建立逻辑回归模型
#选择我们要用到的特征
X = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]
y = titanic_df['Survived']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=101)
log_model = LogisticRegression()
log_model.fit(X_train,y_train)
log_model_Predict = log_model.predict(X_test)
print('Confusion Matrix \n',confusion_matrix(y_test,log_model_Predict))
print('\n')
print('Classsification Report \n',classification_report(y_test,log_model_Predict))
网友评论