import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
目的是了解数据集的要点,即对数据的初步了解。当你收到一个数据集时,你需要对数据集的变量、数据类型和变量之间的关系有一个概念。在大多数情况下,我们会在数据集中发现不完整的数据,原因可能是用户可能不想填写数据,在互联网上传输时数据丢失,或者用户可能没有数据可以填写。这是需要解决的第一步。不匹配的数据类型,如DateTime变量一般被读成对象(String),或者有时整数被读成浮点数,反之亦然。
df = pd.read_csv("D:/data_training/train.csv")
df.head(10)
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 |
5 | 6 | 0 | 3 | Moran, Mr. James | male | NaN | 0 | 0 | 330877 | 8.4583 | NaN | Q |
6 | 7 | 0 | 1 | McCarthy, Mr. Timothy J | male | 54.0 | 0 | 0 | 17463 | 51.8625 | E46 | S |
7 | 8 | 0 | 3 | Palsson, Master. Gosta Leonard | male | 2.0 | 3 | 1 | 349909 | 21.0750 | NaN | S |
8 | 9 | 1 | 3 | Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) | female | 27.0 | 0 | 2 | 347742 | 11.1333 | NaN | S |
9 | 10 | 1 | 2 | Nasser, Mrs. Nicholas (Adele Achem) | female | 14.0 | 1 | 0 | 237736 | 30.0708 | NaN | C |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZ4BYUxI-1670256264640)(attachment:data%20dictionary.png)]
Variable Notes
pclass: A proxy for socio-economic status (SES)
1st = Upper
2nd = Middle
3rd = Lower
age: Age is fractional if less than 1. If the age is estimated, is it in the form of xx.5
sibsp: The dataset defines family relations in this way…
Sibling = brother, sister, stepbrother, stepsister
Spouse = husband, wife (mistresses and fiancés were ignored)
parch: The dataset defines family relations in this way…
Parent = mother, father
Child = daughter, son, stepdaughter, stepson
Some children travelled only with a nanny, therefore parch=0 for them.
# 查看行列
df.shape
(891, 12)
# 查看各个变量的情况,发现Age以及Cabin存在大量缺失值,Embarked存在少量缺失值
df.info()
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId 891 non-null int64
Survived 891 non-null int64
Pclass 891 non-null int64
Name 891 non-null object
Sex 891 non-null object
Age 714 non-null float64
SibSp 891 non-null int64
Parch 891 non-null int64
Ticket 891 non-null object
Fare 891 non-null float64
Cabin 204 non-null object
Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
# 也可以通过isunll()的命令更直观地查看缺失值情况
df.isnull().sum()
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2
dtype: int64
# Age是数值变量,可以考虑用中位数或者平均值进行数据填充,考虑到性别和飞机舱位对乘客特征具有重要影响,因此采用该两个特征变量分组下的均值or中位数填充,
df.groupby(["Pclass","Sex"])["Age"].mean()
Pclass Sex
1 female 34.611765
male 41.281386
2 female 28.722973
male 30.740707
3 female 21.750000
male 26.507589
Name: Age, dtype: float64
df.groupby(["Pclass","Sex"])["Age"].median()
Pclass Sex
1 female 35.0
male 40.0
2 female 28.0
male 30.0
3 female 21.5
male 25.0
Name: Age, dtype: float64
# 可以看到平均数和中位数相差不大,更好的选择是中位数
df.loc[df.Age.isnull() & (df.Sex == "male") & (df.Pclass == 1),"Age"] = 40.0
df.loc[df.Age.isnull() & (df.Sex == "female") & (df.Pclass == 1),"Age"] = 35.0
df.loc[df.Age.isnull() & (df.Sex=="male") & (df.Pclass == 2),"Age"] = 30.0
df.loc[df.Age.isnull() & (df.Sex == "female") & (df.Pclass == 2),"Age"] = 28.0
df.loc[df.Age.isnull() & (df.Sex=="male") & (df.Pclass == 3),"Age"] = 25.0
df.loc[df.Age.isnull() & (df.Sex=="female") & (df.Pclass == 3),"Age"] = 21.5
# 这种一个个根据条件筛选出来再进行填充的方式较为繁杂,若是分组类别较少还好,一旦分组类别较多,则会非常麻烦,因此采用函数形式进行简化
df["Age"] = data.groupby(["Pclass","Sex"])["Age"].transform(lambda x : x.fillna(x.median()))
# 以上两种方法得到的结果完全一致
现在我们已经填补了Age变量的缺失值,但是Embarked(登船港口)和Cabin(船舱号)属于分类数据,无法像数值类型数据采用均值填充;
它只是船上的一个座位分配,这个变量对乘客的生存没有任何影响,所以我们可以使用drop方法放弃这个变量。再次绘图并检查是否有遗漏值。现在可以看到’Age’列没有任何空值,如下图所示,甚至’Cabin’列也被删除了:
# 分类变量Embarked,用最常见的类别进行填充
df['Embarked'].value_counts()
S 644
C 168
Q 77
Name: Embarked, dtype: int64
# 可以看出,S类别最常见,S=Southampton ,表示登船港口为南安普顿
df["Embarked"] = df["Embarked"].fillna("S")
# 船舱号Cabin,先看一下数据情况
df['Cabin'].head()
0 NaN
1 C85
2 NaN
3 C123
4 NaN
Name: Cabin, dtype: object
# 缺失数据较多,Cabin缺失值用U填充,表示未知(Unknow)
df['Cabin']=df['Cabin'].fillna("U")
# 检查数据填充后是否正常
df.head()
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 | U | 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 | U | 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 | U | S |
# 再次查看缺失值情况,可以看到不再存在缺失值
df.info()
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId 891 non-null int64
Survived 891 non-null int64
Pclass 891 non-null int64
Name 891 non-null object
Sex 891 non-null object
Age 891 non-null float64
SibSp 891 non-null int64
Parch 891 non-null int64
Ticket 891 non-null object
Fare 891 non-null float64
Cabin 891 non-null object
Embarked 891 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
单变量的分布情况,发展趋势,占比等情况,两个或者多个变量之间关系的初步发现
做好这一步需要深刻洞悉数据的模式,挖掘出数据的本质特征,这样在特征选取并用机器学习去训练时才能获得更好的效果
# 把船上幸存的乘客总数可视化,如图所示。891人中只有350多人幸存
sns.countplot(x='Survived',data=df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QSec0DJo-1670256264642)(output_19_1.png)]
# "Embarked"变量是分类类型,用countplot方法绘制,下图表示在不同港口上船的人数
sns.set_style("whitegrid")
sns.countplot(x="Embarked",data=df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fIuJyySV-1670256264643)(output_20_1.png)]
# 对乘客的性别可视化,男性大概是女性人数的两倍
sns.countplot(x="Sex",data=df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Rkysjvq-1670256264643)(output_21_1.png)]
# 我们也可以对数字变量使用countplot方法。绘制'SibSp'(配偶和兄弟姐妹)变量,如图所示,600人是单独旅行,200人以上有1个兄弟姐妹或配偶,以此类推。
sns.countplot(x="SibSp",data=df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HGBiEhIx-1670256264643)(output_22_1.png)]
# 双变量分析是用来寻找两个变量之间的关系。
# 生存率是否与乘客所乘坐的舱位有关?如图所示,一等舱的人生存机会明显高于二等、三等舱
sns.countplot(x="Pclass",hue="Survived",data=df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QMzCD2Qj-1670256264644)(output_23_1.png)]
# 性别是否会影响生存率?女性的生存机会显然比男性更高
sns.countplot(x="Sex",hue="Survived",data=df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Spip2eIb-1670256264644)(output_24_1.png)]
sns.countplot(x="Embarked",hue="Survived",data=df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oV31lF0S-1670256264645)(output_25_1.png)]
# 为寻找'Fare'和'Age'变量之间的关系,我们可以使用relplot方法
sns.set_style("darkgrid")
g = sns.relplot("Age","Fare",data=df)
g.fig.set_figwidth(12)
g.fig.set_figheight(6)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FxLwbq7T-1670256264645)(output_26_0.png)]
由上述散点图,可以看到年龄范围从0到80,大部分票价都落在0到100的范围内,同时,38岁的人有一个500以上的票价的离群值。较少变量落在200到300的范围内
# 线形图
g = sns.relplot("Age","Fare",kind="line",data=df)
g.fig.set_figwidth(12)
g.fig.set_figheight(6)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TFLlEDP2-1670256264646)(output_28_0.png)]
# 热图
corr = df.corr()
sns.heatmap(corr)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X7JoNf5m-1670256264646)(output_29_1.png)]
使用热图法,我们可以用二维的形式来表示数据。数据值在图中被表示为颜色,同时还有变量之间的数字相关性。在这里使用泰坦尼克号数据集,我们试图表示变量之间是否有任何相关性。下图显示,这些变量之间没有太大的相关性,而且它们是相互独立的。
# 柱状图是最常见的一种图表类型。它显示了数字变量和分类变量之间的关系
# 为了初步分析舱位与生存率之间的关系,可以看出,头等舱的乘客生存率更高
sns.barplot(x="Pclass",y="Survived",data=df,ci=None)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gLyb2wp8-1670256264647)(output_31_1.png)]
# 多变量分析同时使用两个以上的变量,有时单变量和双变量分析并不能提供太多的信息,所以这里我们可以使用多变量分析。
# 将性别及他们的存活率与他们所乘坐的舱位等级一起绘制出来
sns.barplot(x="Sex",y="Survived",hue="Pclass",data=df,ci=None)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-712cgVaU-1670256264648)(output_32_1.png)]
可以看到,与男性相比,女性乘客的存活率更高,而且Pclass 1和Pclass 2的存活率也更高。
# 也可以用散点图来进行多变量分析
sns.relplot(x="Age",y="Fare",hue="Survived",data=df)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7kRe4IoY-1670256264648)(output_34_1.png)]
可以看出,高票价的人比低票价的人存活率更高