8.1 探索性数据分析 (EDA) 案例 Seaborn 探索性数据分析 (EDA) 案例详解 引言 1. EDA 的重要性与流程 在深入 Seaborn 的实践之前,我们先简要回顾 EDA 的重要性及其基本流程。 1.1 EDA 的重要性 理解数据: EDA 帮助我们从整体上把握数据的特性,例如数据类型、分布、缺失情况等。 发现模式和关系: 通过可视化,我们可以发现变量之间的潜在关系,例如相关性、趋势等,这对于特征选择和模型构建至关重要。 检测异常值和错误: EDA 可以帮助我们识别数据中的异常值和错误数据,从而进行数据清洗和预处理。 提出假设和问题: EDA 过程中的发现可以帮助我们提出关于数据的假设和问题,指导后续的深入分析和建模。
引言
1. EDA 的重要性与流程
在深入 Seaborn 的实践之前,我们先简要回顾 EDA 的重要性及其基本流程。
1.1 EDA 的重要性
理解数据: EDA 帮助我们从整体上把握数据的特性,例如数据类型、分布、缺失情况等。
发现模式和关系: 通过可视化,我们可以发现变量之间的潜在关系,例如相关性、趋势等,这对于特征选择和模型构建至关重要。
检测异常值和错误: EDA 可以帮助我们识别数据中的异常值和错误数据,从而进行数据清洗和预处理。
提出假设和问题: EDA 过程中的发现可以帮助我们提出关于数据的假设和问题,指导后续的深入分析和建模。
沟通洞见: 清晰的可视化结果能够有效地向非技术人员传达数据分析的洞见。
1.2 EDA 的基本流程
EDA 通常是一个迭代的过程,没有固定的步骤,但一般包含以下几个阶段:
问题定义与目标设定: 明确分析的目标,例如预测用户流失、识别客户细分等。
数据收集: 收集相关的数据集。
数据理解与清洗: 加载数据,查看数据概况,处理缺失值、重复值等,保证数据质量。
单变量分析: 分析单个变量的分布情况,例如均值、中位数、标准差、频率等。
双变量/多变量分析: 分析变量之间的关系,例如相关性、分组对比等。
缺失值与异常值处理: 深入分析缺失值和异常值的原因,并进行相应的处理。
特征工程与选择: 基于 EDA 的发现,进行特征构建、转换和选择。
模型构建与评估: 选择合适的模型进行训练和评估。
结果解释与报告: 解释模型结果,并生成报告。
在上述流程中,数据理解与清洗 和 可视化探索 是 EDA 的核心环节,Seaborn 正是在这两个环节中发挥着关键作用。
2. Seaborn 在 EDA 中的应用
Seaborn 提供了丰富的可视化函数,可以帮助我们高效地进行 EDA。以下是一些常用的 Seaborn 函数及其在 EDA 中的应用场景:
单变量分布分析:
sns.histplot(): 绘制直方图,展示数值变量的分布情况。
sns.kdeplot(): 绘制核密度估计图,平滑地展示数值变量的分布。
sns.boxplot(): 绘制箱线图,展示数值变量的分布、中位数、四分位数和异常值。
sns.violinplot(): 绘制小提琴图,结合了箱线图和核密度估计图,更全面地展示数值变量的分布。
sns.countplot(): 绘制计数图,展示分类变量的频数分布。
sns.displot(): 功能强大的分布图,可以绘制直方图、核密度估计图、经验累积分布函数等,并支持分组展示。
双变量/多变量关系分析:
sns.scatterplot(): 绘制散点图,展示两个数值变量之间的关系。
sns.lineplot(): 绘制线图,展示两个数值变量之间的趋势关系,常用于时间序列数据。
sns.jointplot(): 绘制联合分布图,同时展示两个变量的边缘分布和联合分布。
sns.pairplot(): 绘制成对关系图,展示数据集中所有数值变量两两之间的关系。
sns.heatmap(): 绘制热力图,展示矩阵数据的分布,例如相关性矩阵、混淆矩阵等。
sns.barplot(): 绘制柱状图,展示分类变量分组的数值变量均值或计数。
sns.pointplot(): 绘制点图,类似于柱状图,但更强调点的位置,可以展示更细粒度的分组对比。
sns.boxplot()/sns.violinplot(): 可以用于展示分类变量分组的数值变量分布对比。
sns.catplot(): 功能强大的分类图,可以绘制多种分类图,例如箱线图、小提琴图、柱状图、点图等,并支持多维度分组。
sns.relplot(): 功能强大的关系图,可以绘制散点图、线图等,并支持多维度分组。
3. EDA 案例:泰坦尼克号乘客生存分析
为了更具体地展示 Seaborn 在 EDA 中的应用,我们选择经典的泰坦尼克号数据集作为案例,进行乘客生存分析。
3.1 数据集介绍
泰坦尼克号数据集包含了泰坦尼克号乘客的个人信息以及生存情况。数据集通常包含以下字段:
PassengerId: 乘客ID
Survived: 生存情况 (0 = 未生存, 1 = 生存) ** (目标变量)**
Pclass: 乘客船舱等级 (1 = 1st, 2 = 2nd, 3 = 3rd)
Name: 乘客姓名
Sex: 性别 (male, female)
Age: 年龄
SibSp: 兄弟姐妹/配偶在船上的数量
Parch: 父母/子女在船上的数量
Ticket: 船票号码
Fare: 船票价格
Cabin: 船舱号
Embarked: 登船港口 (C = Cherbourg, Q = Queenstown, S = Southampton)
3.2 代码实践与内容详解
3.2.1 数据加载与初步观察
首先,导入必要的库,并加载数据集。
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据集 titanic_df = pd.read_csv('titanic.csv') # 假设 titanic.csv 文件在当前目录下 # 显示数据集的前几行 print(titanic_df.head()) # 查看数据集信息 print(titanic_df.info()) # 查看数值型变量的统计描述 print(titanic_df.describe()) # 查看object类型变量的统计描述 print(titanic_df.describe(include=['O']))
代码详解:
import pandas as pd: 导入 Pandas 库,用于数据处理和分析。
import seaborn as sns: 导入 Seaborn 库,用于数据可视化。
import matplotlib.pyplot as plt: 导入 Matplotlib 库的 pyplot 模块,用于更精细的图形控制。
titanic_df = pd.read_csv('titanic.csv'): 使用 Pandas 的 read_csv() 函数加载 CSV 文件到 DataFrame titanic_df 中。
print(titanic_df.head()): 显示 DataFrame 的前 5 行,快速了解数据的大致内容。
print(titanic_df.info()): 打印 DataFrame 的详细信息,包括列名、数据类型、非空值数量、内存占用等,有助于了解数据结构和缺失情况。
print(titanic_df.describe()): 使用 Pandas 的 describe() 函数,对数值型变量进行统计描述,包括计数、均值、标准差、最小值、四分位数、最大值等,帮助了解数值变量的分布范围和集中趋势。
print(titanic_df.describe(include=['O'])): 使用 describe(include=['O']) 对 object 类型(通常是字符串)变量进行统计描述,包括计数、唯一值数量、最频繁值、最频繁值的频率等,了解分类变量的分布情况。
初步观察解读:
通过 head(), info(), 和 describe() 的输出,我们可以初步了解数据集的结构和内容:
数据集包含乘客 ID、生存情况、船舱等级、姓名、性别、年龄等信息。
数据集中包含数值型变量 (如 Age, Fare) 和分类变量 (如 Survived, Pclass, Sex, Embarked)。
Age, Cabin, Embarked 列存在缺失值,需要进一步处理。
数值型变量的统计描述提供了变量的中心趋势和离散程度信息。
Object 类型变量的统计描述提供了分类变量的类别分布信息。
3.2.2 目标变量分析 (Survived)
首先,我们分析目标变量 Survived (生存情况) 的分布。
# 生存情况计数图 sns.countplot(x='Survived', data=titanic_df) plt.title('Survival Count') plt.show() # 生存比例 survival_rate = titanic_df['Survived'].value_counts(normalize=True) * 100 print("\nSurvival Rate:\n", survival_rate)
代码详解:
sns.countplot(x='Survived', data=titanic_df): 使用 Seaborn 的 countplot() 函数,绘制 Survived 列的计数图。x='Survived' 指定 x 轴为 Survived 列,data=titanic_df 指定数据来源为 titanic_df。
plt.title('Survival Count'): 使用 Matplotlib 的 title() 函数设置图表标题。
plt.show(): 显示绘制的图表。
titanic_df['Survived'].value_counts(normalize=True) * 100: 使用 Pandas 的 value_counts(normalize=True) 函数计算 Survived 列中每个值的频率,normalize=True 将结果转换为比例,乘以 100 转换为百分比。
生存情况分析解读:
计数图直观地展示了未生存 (0) 和生存 (1) 的乘客数量,可以看出未生存人数多于生存人数。
生存比例的输出结果显示了更精确的生存率,例如,大约 38% 的乘客幸存下来。
3.2.3 单变量分析 (其他特征)
接下来,我们分析其他一些重要特征的分布情况。
a) 乘客等级 (Pclass)
sns.countplot(x='Pclass', data=titanic_df, palette='viridis') # 使用viridis调色板 plt.title('Passenger Class Distribution') plt.show()
b) 性别 (Sex)
sns.countplot(x='Sex', data=titanic_df, palette='muted') # 使用muted调色板 plt.title('Gender Distribution') plt.show()
c) 年龄 (Age)
sns.histplot(titanic_df['Age'].dropna(), kde=True, bins=30, color='skyblue') # 绘制直方图和核密度估计图,并处理缺失值 plt.title('Age Distribution') plt.xlabel('Age') plt.ylabel('Frequency') plt.show() sns.boxplot(y='Age', data=titanic_df, color='lightcoral') # 绘制箱线图 plt.title('Age Boxplot') plt.ylabel('Age') plt.show()
单变量分析解读:
Pclass: 计数图显示,3rd 舱的乘客数量最多,其次是 1st 舱,最后是 2nd 舱。这反映了泰坦尼克号乘客的社会阶层结构。
Sex: 计数图显示,男性乘客数量远多于女性乘客数量。
Age:
直方图和核密度估计图展示了年龄的分布,可以看到年龄分布大致呈正态分布,但略微右偏,存在一些年龄较大的乘客。
箱线图展示了年龄的分布范围、中位数和四分位数,以及潜在的异常值(箱线图上方的点)。
3.2.4 双变量分析 (特征与生存情况的关系)
现在,我们分析不同特征与生存情况之间的关系。
a) 乘客等级 (Pclass) vs 生存情况 (Survived)
sns.barplot(x='Pclass', y='Survived', data=titanic_df, palette='plasma') # 绘制柱状图,展示不同Pclass的生存率 plt.title('Survival Rate by Passenger Class') plt.ylabel('Survival Rate') plt.show() # 交叉表分析 class_survival_crosstab = pd.crosstab(titanic_df['Pclass'], titanic_df['Survived'], normalize='index') * 100 print("\nSurvival Rate by Passenger Class (Crosstab):\n", class_survival_crosstab)
b) 性别 (Sex) vs 生存情况 (Survived)
sns.barplot(x='Sex', y='Survived', data=titanic_df, palette='magma') # 绘制柱状图,展示不同性别的生存率 plt.title('Survival Rate by Gender') plt.ylabel('Survival Rate') plt.show() # 交叉表分析 sex_survival_crosstab = pd.crosstab(titanic_df['Sex'], titanic_df['Survived'], normalize='index') * 100 print("\nSurvival Rate by Gender (Crosstab):\n", sex_survival_crosstab)
c) 年龄 (Age) vs 生存情况 (Survived)
sns.boxplot(x='Survived', y='Age', data=titanic_df, palette='Set2') # 绘制箱线图,对比不同生存情况的年龄分布 plt.title('Age Distribution by Survival') plt.xlabel('Survived') plt.ylabel('Age') plt.show() sns.violinplot(x='Survived', y='Age', data=titanic_df, palette='Set3') # 绘制小提琴图,更细致地对比不同生存情况的年龄分布 plt.title('Age Distribution by Survival (Violin Plot)') plt.xlabel('Survived') plt.ylabel('Age') plt.show()
双变量分析解读:
Pclass vs Survived: 柱状图和交叉表都显示,乘客等级越高,生存率越高。1st 舱的生存率最高,3rd 舱的生存率最低。这表明社会经济地位对生存机会有显著影响。
Sex vs Survived: 柱状图和交叉表都显示,女性的生存率远高于男性。这印证了“妇女儿童优先”的原则在泰坦尼克号灾难中的体现。
Age vs Survived:
箱线图和小提琴图显示,生存下来的人的年龄中位数略低于未生存的人。
小提琴图更清晰地展示了年龄分布的差异,可以看到在较低年龄段,生存下来的乘客比例更高。这可能与“儿童优先”的原则有关。
3.2.5 多变量分析 (引入更多特征)
我们可以进一步引入更多特征,进行多变量分析,例如,同时考虑性别和乘客等级对生存率的影响。
sns.catplot(x='Pclass', y='Survived', hue='Sex', kind='bar', data=titanic_df, palette='dark') # 使用catplot绘制分组柱状图 plt.title('Survival Rate by Passenger Class and Gender') plt.ylabel('Survival Rate') plt.show()
多变量分析解读:
分组柱状图清晰地展示了在不同乘客等级下,男性和女性的生存率差异。
可以看到,在所有乘客等级中,女性的生存率都远高于男性。
即使在 3rd 舱,女性的生存率也高于 1st 和 2nd 舱的男性生存率。
3.2.6 缺失值可视化
为了更直观地了解缺失值的情况,我们可以使用热力图可视化缺失值。
sns.heatmap(titanic_df.isnull(), cbar=False, cmap='viridis') # 绘制热力图,可视化缺失值 plt.title('Missing Value Heatmap') plt.show()
缺失值可视化解读:
热力图中,颜色较浅的区域表示缺失值。可以看到,Age 和 Cabin 列存在明显的缺失值,Embarked 列也有少量缺失值。
这种可视化方式可以帮助我们快速定位缺失值集中的列,为后续的缺失值处理提供依据。
4. 总结与结论
通过上述 EDA 案例,我们利用 Seaborn 进行了泰坦尼克号乘客生存数据的探索性分析。我们:
初步了解了数据集的结构和特征。
分析了目标变量 (Survived) 的分布情况。
探索了单变量的分布特征 (Pclass, Sex, Age)。
分析了不同特征与生存情况之间的关系 (Pclass vs Survived, Sex vs Survived, Age vs Survived)。
进行了多变量分析 (Pclass, Sex vs Survived)。
可视化了缺失值情况。
EDA 关键发现:
乘客等级 (Pclass) 与生存率正相关: 乘客等级越高,生存率越高。
性别 (Sex) 与生存率显著相关: 女性生存率远高于男性。
年龄 (Age) 对生存率有一定影响: 年龄较小的乘客生存率可能更高。
Age, Cabin, Embarked 列存在缺失值,需要进行处理。
EDA 总结与后续方向:
本次 EDA 案例有效地利用 Seaborn 提供的可视化工具,帮助我们深入理解了泰坦尼克号乘客生存数据的特征和模式。这些发现为后续的特征工程和模型构建提供了重要的方向:
特征工程: 可以考虑将 Pclass, Sex, Age 等特征作为模型输入,并可以基于这些特征进行更复杂的特征工程,例如创建年龄段、家庭人数等衍生特征。
缺失值处理: 需要针对 Age, Cabin, Embarked 列的缺失值进行合理的处理,例如填充缺失值或删除包含缺失值的行/列。
模型选择: 可以尝试使用分类模型,例如逻辑回归、决策树、随机森林等,预测乘客的生存情况。
结语
Seaborn 作为一个强大的数据可视化库,在 EDA 过程中发挥着至关重要的作用。通过本案例的实践,我们可以看到 Seaborn 能够帮助我们快速生成各种信息丰富的统计图形,从而有效地进行数据探索和分析,为后续的数据科学任务奠定坚实的基础。希望本文能够帮助读者更好地理解和应用 Seaborn 进行 EDA。