在数据科学和机器学习的探索性数据分析(EDA)阶段,我们经常面临一个挑战:如何高效地理解数据集中多个变量之间的关系?当我们面对包含数十个特征的数据集时,单独审视每一对变量不仅耗时,而且难以捕捉到全局的模式。这就是 Pair Plot(配对图) 发挥作用的地方。
通过将所有数值特征两两配对并在矩阵中展示,我们可以直观地发现数据中的相关性、聚类趋势以及潜在的异常值。在这篇文章中,我们将深入探讨如何利用 Pandas 中的 scatter_matrix 函数来构建这些强大的可视化图表,并分享一些在实战中积累的经验和技巧。
为什么需要散点矩阵?
在数据预处理中,检查属性之间的共线性是至关重要的一步。如果我们发现两个特征之间存在极强的线性相关性(例如相关系数接近 1 或 -1),这通常意味着多重共线性问题的存在。在训练线性回归或逻辑回归模型时,多重共线性会导致模型系数估计不稳定,从而影响模型的解释性和预测能力。
为了更好地理解这些相关性,一个直观的办法是为每一对属性创建散点图。想象一下,如果你有 5 个数值特征,手动创建并排列这些图表将是非常繁琐的。Pandas 为此专门提供了一个高效的解决方案——scatter_matrix() 函数。它不仅自动布局这些图表,还能在对角线上自动绘制每个特征的分布情况(通常是直方图或核密度图),帮助我们在同一视图中同时把握变量的分布特征和相互关系。
准备工作与环境配置
在开始编写代码之前,请确保你的环境中已安装必要的库。虽然 Pandas 自带了强大的绘图功能,但其底层依赖于 Matplotlib。因此,我们通常需要结合使用这两个库。
为了确保图表在 Jupyter Notebook 或其他环境中能够清晰显示,建议配置 Matplotlib 的内联显示模式,并设置中文字体以避免中文标签显示为方框的问题(这在实际数据分析中是一个常见的困扰)。
数据集介绍:加利福尼亚州房价数据
为了让演示更加贴近实战,我们将使用经典的加利福尼亚州房价数据集。这个数据集包含了加利福尼亚州各地区房屋的价格以及其他相关的统计数据,如地理位置(经纬度)、房龄、房间总数、卧室总数、人口、家庭数量以及收入中位数。
这是一个典型的回归问题数据集,非常适合用来探索特征之间的关系。首先,让我们加载数据并进行初步的检查。
#### 示例 1:加载数据与基础信息查看
在开始可视化之前,我们必须先了解数据的结构。info() 方法是我们的第一扇窗,它能告诉我们每一列的数据类型以及是否存在缺失值。
import pandas as pd
# 加载数据集
# 假设文件在当前目录下,如果是远程URL请使用对应的URL字符串
data = pd.read_csv(‘housing.csv‘)
# 检查数据的基本信息
# 这一步非常关键,它能帮助我们了解哪些列是数值型(用于绘图),哪些是分类型
data.info()
输出解析:
运行上述代码后,你将看到类似如下的输出。请注意观察 Dtype 列。
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 longitude 20640 non-null float64
1 latitude 20640 non-null float64
2 housing_median_age 20640 non-null float64
3 total_rooms 20640 non-null float64
4 total_bedrooms 20433 non-null float64
5 population 20640 non-null float64
6 households 20640 non-null float64
7 median_income 20640 non-null float64
8 median_house_value 20640 non-null float64
9 ocean_proximity 20640 non-null object
dtypes: float64(9), object(1)
memory usage: 1.6+ MB
从输出中我们可以提取出关键信息:
- 数据类型:除了 INLINECODE920b079d 是 INLINECODE85518dfd 类型(字符串/分类特征)外,其余 9 个特征都是 INLINECODE1c822c6c 类型的数值特征。这意味着我们可以对这 9 个特征进行 INLINECODE6066299f 绘图。
- 缺失值:注意
total_bedrooms列只有 20433 个非空值,意味着存在缺失值。在进行可视化和建模前,我们通常需要处理这些缺失值(例如填充均值或中位数),否则绘图函数可能会报错或产生警告。
基础散点矩阵绘制
现在,让我们进入正题。如果我们直接对所有 9 个数值特征绘制散点矩阵,生成的图表将会非常巨大且难以阅读(9×9 的网格)。因此,在实际操作中,我们通常会先挑选几个最感兴趣的特征进行探索。
假设我们要研究房价(INLINECODEad0a5d66)与房龄(INLINECODEeef69925)、收入(median_income)之间的关系。
#### 示例 2:绘制基础的三维特征散点矩阵
让我们选择这三个数值列进行绘图。请注意,Pandas 的绘图功能依赖于 Matplotlib,因此我们需要先导入它,并在绘图后调用 plt.show() 来确保图表在脚本模式下也能正确渲染。
import matplotlib.pyplot as plt
from pandas.plotting import scatter_matrix
# 为了演示清晰,我们先从数据集中选择三个数值特征
# 这种做法在特征维度极高时尤其有用,可以帮助我们聚焦于关键变量
selected_features = [‘median_house_value‘, ‘housing_median_age‘, ‘median_income‘]
# 绘制散点矩阵
# alpha 参数用于控制点的透明度,0.2 表示 20% 不透明度
# 当数据点重叠时,透明度能帮助我们看出数据的密集程度
scatter_matrix(data[selected_features], alpha=0.2, figsize=(10, 10))
plt.show()
图表解读:
运行上述代码后,你将看到一个 3×3 的矩阵图表。让我们深入理解图表中的每一部分:
- 非对角线位置:这里是真正的散点图。例如,INLINECODEbee7f74b (x轴) 与 INLINECODE9ec69934 (y轴) 的交叉点。
* 观察点:我们可以清晰地看到,随着收入中位数的增加,房屋中位价也呈现出明显的上升趋势。这种正相关关系对于特征工程非常重要。
* 异常值:你可能会注意到在最顶端有一条直线。这通常是因为数据被截断了(例如房价超过 50 万美元的都被记录为 500001),这属于数据截断产生的异常值模式。
- 对角线位置:这里通常是直方图。
* 它展示了该特征自身的分布情况。例如,housing_median_age 可能呈现双峰分布,说明有些区域房子很新,有些区域房子很旧。
* 这种分布检查对于后续是否需要对数据进行标准化或对数转换至关重要。
进阶技巧:美化和自定义图表
虽然基础图表很有用,但在专业的数据分析报告或演示中,我们通常需要更美观、信息量更大的图表。scatter_matrix 提供了丰富的参数让我们进行定制。
#### 示例 3:添加对角线核密度估计 (KDE) 和 调整颜色
直方图虽然直观,但有时显得粗糙。我们可以将对角线的图表更改为核密度估计图,这能更平滑地展示数据分布。此外,调整颜色和标记大小可以提升可读性。
import matplotlib.pyplot as plt
from pandas.plotting import scatter_matrix
# 定义特征集
features = [‘median_house_value‘, ‘housing_median_age‘, ‘median_income‘]
# 绘制带有自定义参数的散点矩阵
# diagonal=‘kde‘:对角线显示核密度估计图,比直方图更平滑
# figsize=(12, 12):增大画布尺寸,防止标签重叠
# color=‘blue‘:设置散点颜色
# marker=‘o‘:设置点的形状为圆形
# grid=True:显示网格,辅助读数
scatter_matrix(
data[features],
alpha=0.5,
figsize=(12, 12),
diagonal=‘kde‘,
color=‘blue‘,
marker=‘o‘,
grid=True
)
plt.suptitle(‘加利福尼亚房价特征关系矩阵图‘, y=1.02) # 添加总标题
plt.show()
进阶解读:
通过设置 INLINECODE77aa1b5e,我们看到了平滑的概率密度曲线。如果曲线呈现明显的“长尾”分布(比如 INLINECODE895eedc9 右侧有长尾),这提示我们在建模前可能需要对数据进行对数转换,以使其更符合正态分布假设,从而提高许多机器学习算法的性能。
实战应用:处理多列与海量数据
当我们有信心要查看更多特征时,可以扩展矩阵的维度。但是,当特征数量增加时,例如达到 7 或 8 个,生成的组合图数量会呈平方级增长(8×8=64 个子图),这将导致图表非常拥挤。
#### 示例 4:处理更多维度的数据
在这个例子中,我们将尝试加入更多特征,并演示如何处理包含缺失值的数据(因为之前的 INLINECODE50d91cd0 显示 INLINECODE2d942374 有缺失)。
import matplotlib.pyplot as plt
from pandas.plotting import scatter_matrix
# 复制一份数据以避免修改原始数据集
data_clean = data.copy()
# 数据清洗:用中位数填充缺失值
# scatter_matrix 无法直接处理 NaN 值,必须先处理
data_clean[‘total_bedrooms‘].fillna(data_clean[‘total_bedrooms‘].median(), inplace=True)
# 选择更多特征进行综合分析
extended_features = [
‘median_house_value‘,
‘housing_median_age‘,
‘median_income‘,
‘total_rooms‘,
‘population‘
]
# 绘制更复杂的矩阵
# 这里我们减小了 alpha 值,因为数据点更多了,防止重叠成黑色一团
scatter_matrix(
data_clean[extended_features],
alpha=0.1,
figsize=(15, 15),
diagonal=‘kde‘,
marker=‘.‘,
hist_kwds={‘bins‘: 20} # 如果切换回直方图,可以指定分箱数量
)
plt.show()
实战观察:
在这个高维矩阵中,我们要寻找的是:
- 线性关系:哪些特征组合在一起看起来像一条直线?例如 INLINECODEb2bc42f0 和 INLINECODE41182ad1 通常高度相关。如果相关性太高(>0.95),我们可能会考虑在特征工程中剔除其中一个,以减少冗余。
- 分散关系:如果散点图呈现云状分布,说明两者相关性较弱,这对模型来说是提供了独立的信息。
常见错误与解决方案
在使用 scatter_matrix 时,你可能会遇到以下几个“坑”,这里我们提前给出解决方案。
1. 代码运行没有报错,但图表不显示?
这通常发生在 Python 脚本模式(.py 文件)下。确保你在代码最后添加了 INLINECODE394a9473。如果你使用的是 Jupyter Notebook,确保在代码块开头写了 INLINECODEab906405。
2. 图表文字重叠,看不清标签?
当特征名称很长时,轴标签会挤在一起。解决方法有两个:
- 增大 INLINECODEf1542eb7,例如 INLINECODE9be554fe。
- 使用
plt.tight_layout()自动调整布局。
3. 数据量太大(例如 10万行以上),图表生成极慢?
散点图在浏览器或 Matplotlib 中渲染大量点非常消耗资源。
- 解决方案:在绘图前对数据进行采样。例如:
# 随机采样 1000 行数据进行快速预览
sample_data = data.sample(n=1000, random_state=42)
scatter_matrix(sample_data[features], ...)
这样既能看清分布趋势,又能瞬间提升生成速度。
4. ValueError: np.nan is not allowed?
正如前文提到的,Pandas 绘图不支持 INLINECODE85882d23。在调用函数前,必须使用 INLINECODEc183ae56 或 fillna() 清洗数据。
性能优化与最佳实践
最后,让我们总结一下如何高效地使用这一工具。
- 数据先行:不要对包含缺失值或非数值类型的数据直接运行 INLINECODEc59c7e5e。先用 INLINECODEbdc4afa2 筛选出数值列。
n2. 适度采样:面对大数据集,不要试图渲染所有点。采样不仅加快速度,有时还能减少“过 plotting”带来的视觉干扰。
- 关注对角线:不要只盯着散点图看。对角线上的分布图能告诉你是否需要进行数据标准化或对数变换,这对模型效果的影响往往比特征选择更大。
- 结合 Seaborn:虽然 Pandas 自带的 INLINECODE8b9d8c64 很方便,但如果你需要更美观的样式或更复杂的回归线拟合,可以尝试使用 Seaborn 库中的 INLINECODE1b7775ce 函数,它的功能更为强大,语法也类似。
结语
通过这篇文章,我们不仅学习了如何使用 Pandas 的 scatter_matrix 函数绘制散点矩阵,更重要的是,我们探讨了如何通过可视化来洞察数据的内在结构。从简单的相关性检查到复杂的分布特征分析,Pair Plot 是每一位数据科学家武器库中必不可少的利器。
接下来,当你拿到一个新的数据集时,不妨先试着画出它的散点矩阵。你会发现,许多原本隐藏在枯燥数字背后的模式和异常,都会在这些图表中无所遁形。希望你在实践中能灵活运用这些技巧,让数据分析工作变得更加得心应手。