import pandas as pdimport numpy as npimport seaborn as snsimport matplotlib.pyplot as plt%matplotlib inline
探索性数据分析:
目的是了解数据集的要点,即对数据的初步了解。当你收到一个数据集时,你需要对数据集的变量、数据类型和变量之间的关系有一个概念。在大多数情况下,我们会在数据集中发现不完整的数据,原因可能是用户可能不想填写数据,在互联网上传输时数据丢失,或者用户可能没有数据可以填写。这是需要解决的第一步。不匹配的数据类型,如DateTime变量一般被读成对象(String),或者有时整数被读成浮点数,反之亦然。
df = pd.read_csv("D:/data_training/train.csv")
df.head(10)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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()
<class 'pandas.core.frame.DataFrame'>RangeIndex: 891 entries, 0 to 890Data columns (total 12 columns):PassengerId 891 non-null int64Survived 891 non-null int64Pclass 891 non-null int64Name 891 non-null objectSex 891 non-null objectAge 714 non-null float64SibSp891 non-null int64Parch891 non-null int64Ticket 891 non-null objectFare 891 non-null float64Cabin204 non-null objectEmbarked 889 non-null objectdtypes: float64(2), int64(5), object(5)memory usage: 83.7+ KB
# 也可以通过isunll()的命令更直观地查看缺失值情况df.isnull().sum()
PassengerId0Survived 0Pclass 0Name 0Sex 0Age 177SibSp 0Parch 0Ticket 0Fare 0Cabin687Embarked 2dtype: int64
# Age是数值变量,可以考虑用中位数或者平均值进行数据填充,考虑到性别和飞机舱位对乘客特征具有重要影响,因此采用该两个特征变量分组下的均值or中位数填充,df.groupby(["Pclass","Sex"])["Age"].mean()
Pclass Sex 1 female 34.611765male41.2813862 female 28.722973male30.7407073 female 21.750000male26.507589Name: Age, dtype: float64
df.groupby(["Pclass","Sex"])["Age"].median()
Pclass Sex 1 female 35.0male40.02 female 28.0male30.03 female 21.5male25.0Name: Age, dtype: float64
# 可以看到平均数和中位数相差不大,更好的选择是中位数df.loc[df.Age.isnull() & (df.Sex == "male") & (df.Pclass == 1),"Age"] = 40.0df.loc[df.Age.isnull() & (df.Sex == "female") & (df.Pclass == 1),"Age"] = 35.0df.loc[df.Age.isnull() & (df.Sex=="male") & (df.Pclass == 2),"Age"] = 30.0df.loc[df.Age.isnull() & (df.Sex == "female") & (df.Pclass == 2),"Age"] = 28.0df.loc[df.Age.isnull() & (df.Sex=="male") & (df.Pclass == 3),"Age"] = 25.0df.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 644C 168Q77Name: Embarked, dtype: int64
# 可以看出,S类别最常见,S=Southampton ,表示登船港口为南安普顿df["Embarked"] = df["Embarked"].fillna("S")
# 船舱号Cabin,先看一下数据情况df['Cabin'].head()
0NaN1C852NaN3 C1234NaNName: Cabin, dtype: object
# 缺失数据较多,Cabin缺失值用U填充,表示未知(Unknow)df['Cabin']=df['Cabin'].fillna("U")
# 检查数据填充后是否正常df.head()
# 再次查看缺失值情况,可以看到不再存在缺失值df.info()
<class 'pandas.core.frame.DataFrame'>RangeIndex: 891 entries, 0 to 890Data columns (total 12 columns):PassengerId 891 non-null int64Survived 891 non-null int64Pclass 891 non-null int64Name 891 non-null objectSex 891 non-null objectAge 891 non-null float64SibSp891 non-null int64Parch891 non-null int64Ticket 891 non-null objectFare 891 non-null float64Cabin891 non-null objectEmbarked 891 non-null objectdtypes: float64(2), int64(5), object(5)memory usage: 83.7+ KB
变量分析
单变量的分布情况,发展趋势,占比等情况,两个或者多个变量之间关系的初步发现
做好这一步需要深刻洞悉数据的模式,挖掘出数据的本质特征,这样在特征选取并用机器学习去训练时才能获得更好的效果
# 把船上幸存的乘客总数可视化,如图所示。891人中只有350多人幸存sns.countplot(x='Survived',data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x17f239be488>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QSec0DJo-1670256264642)(output_19_1.png)]
# "Embarked"变量是分类类型,用countplot方法绘制,下图表示在不同港口上船的人数sns.set_style("whitegrid")sns.countplot(x="Embarked",data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x17f23cbad08>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fIuJyySV-1670256264643)(output_20_1.png)]
# 对乘客的性别可视化,男性大概是女性人数的两倍sns.countplot(x="Sex",data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x17f23d46988>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Rkysjvq-1670256264643)(output_21_1.png)]
# 我们也可以对数字变量使用countplot方法。绘制'SibSp'(配偶和兄弟姐妹)变量,如图所示,600人是单独旅行,200人以上有1个兄弟姐妹或配偶,以此类推。sns.countplot(x="SibSp",data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x17f23da4048>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HGBiEhIx-1670256264643)(output_22_1.png)]
# 双变量分析是用来寻找两个变量之间的关系。# 生存率是否与乘客所乘坐的舱位有关?如图所示,一等舱的人生存机会明显高于二等、三等舱sns.countplot(x="Pclass",hue="Survived",data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x17f242d1788>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QMzCD2Qj-1670256264644)(output_23_1.png)]
# 性别是否会影响生存率?女性的生存机会显然比男性更高sns.countplot(x="Sex",hue="Survived",data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x17f244e01c8>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Spip2eIb-1670256264644)(output_24_1.png)]
sns.countplot(x="Embarked",hue="Survived",data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x17f25c368c8>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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)
<matplotlib.axes._subplots.AxesSubplot at 0x20b3aa62e88>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X7JoNf5m-1670256264646)(output_29_1.png)]
使用热图法,我们可以用二维的形式来表示数据。数据值在图中被表示为颜色,同时还有变量之间的数字相关性。在这里使用泰坦尼克号数据集,我们试图表示变量之间是否有任何相关性。下图显示,这些变量之间没有太大的相关性,而且它们是相互独立的。
# 柱状图是最常见的一种图表类型。它显示了数字变量和分类变量之间的关系# 为了初步分析舱位与生存率之间的关系,可以看出,头等舱的乘客生存率更高sns.barplot(x="Pclass",y="Survived",data=df,ci=None)
<matplotlib.axes._subplots.AxesSubplot at 0x17f23ede848>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gLyb2wp8-1670256264647)(output_31_1.png)]
# 多变量分析同时使用两个以上的变量,有时单变量和双变量分析并不能提供太多的信息,所以这里我们可以使用多变量分析。# 将性别及他们的存活率与他们所乘坐的舱位等级一起绘制出来sns.barplot(x="Sex",y="Survived",hue="Pclass",data=df,ci=None)
<matplotlib.axes._subplots.AxesSubplot at 0x17f23f80188>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-712cgVaU-1670256264648)(output_32_1.png)]
可以看到,与男性相比,女性乘客的存活率更高,而且Pclass 1和Pclass 2的存活率也更高。
# 也可以用散点图来进行多变量分析sns.relplot(x="Age",y="Fare",hue="Survived",data=df)
<seaborn.axisgrid.FacetGrid at 0x17f24047808>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7kRe4IoY-1670256264648)(output_34_1.png)]
可以看出,高票价的人比低票价的人存活率更高