数据加载及探索性数据分析
数据及背景:
从Kaggle泰坦尼克号项目页面下载数据:https://www.kaggle.com/c/titanic
在这次项目中,先在Kaggle上下载所需要的训练数据集和测试数据集,通过训练数据集分析什么类型的人能在这场灾难中生存下来,建立机器学习的模型,再使用这个模型预测测试数据集中所有人的生存情况。
本次项目属于一个典型的二分分类问题,可以采用逻辑回归的方法建立机器学习模型。
数据加载
有两种方法:pd.read_csv(),pd.read_table()
pd.read_csv():读取以‘,’分割的文件到DataFrame,用于读取csv文件(csv用逗号符分隔字符段)
pd.read_table():读取以‘\t’分割的文件到DataFrame,用于读取tsv文件(tsv用制表符分隔字符段)
实质上两个方法都是通用的,函数中参数sep可以选定分隔符的类型
- 导入numpy、pandas和matplotlib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
- 载入数据
data_path = 'C:/Users/87569/Desktop/Titanic/' #设置数据集路径
train_data = pd.read_csv(data_path + 'train.csv',delimiter = ',')
test_data = pd.read_csv(data_path + 'test.csv',delimiter = ',')
-
简略观察数据情况
对应的数据名称
train_data.info()
info()熟悉数据类型
通过info()来了解数据每列的type,有助于了解是否存在除了nan以外的特殊符号异常。也能观察到数据的shape,例如图中可以看见数据为891行,12列。train_data.sample(10) #随机抽取10行数据展示
train_data.describe()
describe()熟悉相关统计量
describe()中包含每列的统计量,个数(count)、平均值(mean)、方差(std)、最小值(min)、中位数(25% 50% 75%)、最大值(max)等。通过观察以上指标,可以瞬间掌握数据的大概范围和每个值的异常值的判断 。
分块读取
chunker = pd.read_csv('train.csv', chunksize=10) #逐块读取
read_csv()中有参数chunksize可以逐块读取数据,chunksize=10时就是每10行读取一次,直到读完。这样可以有效降低内存负荷,能够用来读取大数据文件。
-
将表头改成中文,索引改为乘客ID
4.1 通过read_csv中names参数修改df = pd.read_csv('train.csv', names=['乘客ID','是否幸存','仓位等级','姓名','性别','年龄','兄弟姐妹个数','父母子女个数','船票信息','票价','客舱','登船港口'],index_col='乘客ID',header=0) df.sample(10)
4.2 修改DataFrame的columns或index属性值
df2.columns = ['乘客ID','是否幸存','仓位等级','姓名','性别','年龄','兄弟姐妹个数','父母子女个数','船票信息','票价','客舱','登船港口'] df2.sample(5)
4.3 pandas.DataFrame.rename()函数
rename函数是专门为了修改DataFrame坐标轴标签函数。rename函数的优点:可以选择性的修改某行某列的标签。函数/字典中的值必须是唯一的(1对1)。 未包含在字典/Series中的标签将保留原样。列出的额外标签不会引发错误。
DataFrame.rename(self, mapper=None, index=None, columns=None, axis=None, copy=True, nplace=False, level=None, errors='ignore')
查看数据情况
- 查看缺失值
missing_data = df.isnull().sum()missing_data = missing_data[missing_data>0]print(missing_data)missing_data.plot.bar()
isnull() 若值为空则返回1,否则返回0
isnull().sum() 可以计算缺失值并输出缺失值个数
-
查看每种数据的差异数
df['仓位等级'].unique()
保存数据
df.to_csv('train_chinese.csv')
查看test.csv文件
测试集的缺失值情况:
探索性数据分析EDA
探索性数据分析(Exploratory Data Analysis,EDA)是指对已有数据在尽量少的先验假设下通过作图、制表、方程拟合、计算特征量等手段探索数据的结构和规律的一种数据分析方法。
EDA的目标:
- 熟悉数据集,了解数据集,对数据集进行验证来确定所获得数据集可以用于接下来的机器学习或者深度学习使用。
- 了解变量间的相互关系以及变量与预测值之间的存在关系。
- 引导数据科学从业者进行数据处理以及特征工程的步骤,使数据集的结构和特征集让接下来的预测问题更加可靠。
通过前面的步骤已经初步窥探了整个数据集的样貌,现在进一步的深入这个数据集。
缺失值处理
通过前面可以知道,训练集缺失值的情况如下:
年龄(age) 177
客舱(Cabin) 687
登船港口(Embarked) 2
测试集的缺失值情况如下:
Age 86
Fare 1
Cabin 327
通过上面的结果发现数据总共有1390行,其中数值类型列:年龄(Age)、船舱号(Cabin)里面有较多缺失数据:
① 年龄(Age)里面数据总数是1046条,缺失了1309-1046=263,缺失率263/1309=20%;
② 船票价格(Fare)里面数据总数是1308条,缺失了1条数据;
字符串列:
③ 登船港口(Embarked)里面数据总数是1307,只缺失了2条数据,缺失比较少;
④ 客舱(Cabin)里面数据总数是295,缺失了1309-295=1014,缺失率=1014/1309=77.5%,缺失比较大。
下面对缺失值进行简单的处理。(很多模型对缺失值有自己的方法处理,若选用此类模型则不需要处理缺失值)
fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
-
参数:value : 变量, 字典, Series, or DataFrame
用于填充缺失值(例如0),或者指定为每个索引(对于Series)或列(对于DataFrame)使用哪个字典/Serise/DataFrame的值。(不在字典/Series/DataFrame中的值不会被填充)这个值不能是一个列表。 -
method : {‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, 默认值 None ; 在Series中使用方法填充空白(‘backfill’, ‘bfill’向前填充,‘pad’, ‘ffill’向后填充)
-
axis : {0 or ‘index’, 1 or ‘columns’}
-
inplace : boolean, 默认值 False。如果为Ture,在原地填满。注意:这将修改次对象上的任何其他视图(例如,DataFrame中的列的无复制贴片)
-
limit : int, 默认值 None; 如果指定了方法,则这是连续的NaN值的前向/后向填充的最大数量。 换句话说,如果连续NaN数量超过这个数字,它将只被部分填充。 如果未指定方法,则这是沿着整个轴的最大数量,其中NaN将被填充。 如果不是无,则必须大于0。
-
downcast : dict, 默认是 None; 如果可能的话,把 item->dtype 的字典将尝试向下转换为适当的相等类型的字符串(例如,如果可能的话,从float64到int64)
##训练集和测试集合并处理
full_data = train_data.append(test_data,ignore_index='Ture')
full_data.info()
填充Age
##数值型缺失值处理
full_data['Age'].fillna(midage,inplace=True) ##通过平均值来填补缺失值print(full_data['Age'].isnull().sum()) #0
填充Fare
看下 Fare 数据的缺失情况:只有一条缺失记录,而这个乘客的Ticket只有他一个人在使用,无法通过查找相同票号的价格来填补。
船票的价格显然是跟 Pclass (客舱等级)及 Cabin(客舱号)有关的,因此使用具有相同Pclass和Cabin的中位数来填补:
df.where(df[‘Fare’].not_eq(nil) & df[‘Pclass’].eq(3) & df[‘Cabin’].eq(nil) )[‘Fare’].median => 8.05
填充Cabin
Cabin 缺失的比较多,但发现相同Cabin的Ticket也相同,因此可以反推具有相同Ticket的乘客也会住在同一个Cabin内,因此可以找出具有相同Ticket但Cabin不为空的乘客数据来填补:
df[‘Cabin’].missing => 1014 same_cabins = 0 df.where(df[‘Cabin’].eq(nil)).each_row_with_index do |row, idx| same_cabin = df.where( df[‘Cabin’].not_eq(nil) & df[‘Ticket’].eq(row[‘Ticket’]) ) if same_cabin.size != 0 same_cabins = 1 end end same_cabins # => 16
在这里插入代码片
发现无法全部填充,未填充的缺失值不确定性太多放弃填补。