Pandas & NumPy Academy · 课时

双变量与相关性分析

使用散点图、箱线图和相关性热力图,探索成对列之间的关系。

第 3 / 4 课13 个步骤

双变量与相关性分析 是 CoddyKit 上的免费 Pandas & NumPy Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Pandas & NumPy Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Pandas & NumPy Academy 课程共包含 4 节课。

从一个变量到两个变量

双变量分析每次考察恰好两列之间的关系。在分别分析每一列(单变量分析)之后,您要问的是:这两个变量之间有什么关系?分析方法取决于变量类型的组合:数值与数值(散点图 + 相关性)、分类与数值(箱线图/小提琴图),或分类与分类(交叉表 + 卡方检验)。每种组合都需要不同的技术。

import pandas as pd
import seaborn as sns

df = sns.load_dataset('titanic')

# Relationship types present in the dataset
print('Numeric columns:', df.select_dtypes('number').columns.tolist())
print('Categorical columns:', df.select_dtypes('object').columns.tolist())
print('Boolean columns:', df.select_dtypes('bool').columns.tolist())

数值与数值:散点图

对于两个数值变量,散点图是主要的双变量分析工具。它将每个观测值显示为坐标 (x, y) 上的一个点,从而揭示关系的方向、强度和形式。在计算相关系数之前,请始终先查看图形——相关性为 0 仍可能表示很强的非线性(曲线)关系,而相关系数无法捕捉这种关系。

import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')

sns.scatterplot(data=df, x='age', y='fare', alpha=0.4)
plt.title('Age vs. Fare — Is There a Linear Relationship?')
plt.xlabel('Age')
plt.ylabel('Fare ($)')
plt.show()

皮尔逊相关系数

皮尔逊 r量化两个数值变量之间线性关系的强度和方向。您可以使用 df[['col1', 'col2']].corr() 或 scipy.stats.pearsonr(x, y) 进行计算,后者还会返回用于显著性检验的 p 值。请始终将 r 与散点图结合起来分析——较高的 r 可能由少数异常值造成,而相同的 r 可能对应截然不同的散点形状(安斯科姆四重奏对此有经典展示)。

import pandas as pd
import seaborn as sns
from scipy import stats

df = sns.load_dataset('titanic').dropna(subset=['age', 'fare'])

# Pearson correlation
r, p = stats.pearsonr(df['age'], df['fare'])
print(f'Pearson r = {r:.3f}, p-value = {p:.4f}')

# Spearman for robustness check
rho, p_sp = stats.spearmanr(df['age'], df['fare'])
print(f'Spearman rho = {rho:.3f}, p-value = {p_sp:.4f}')

分类与数值:箱线图和小提琴图

当一个变量为分类变量、另一个为数值变量时,问题是:数值分布是否因类别不同而有所差异?请使用箱线图或小提琴图进行比较。例如,生存状态是否会影响支付的票价?乘客舱位是否会影响年龄?这些图可以立即显示类别归属是否与数值变量的较高或较低取值相关。

import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')

fig, axes = plt.subplots(1, 2, figsize=(12, 5))

sns.boxplot(data=df, x='class', y='fare',
            order=['First', 'Second', 'Third'], ax=axes[0])
axes[0].set_title('Fare by Passenger Class')

sns.violinplot(data=df, x='survived', y='age',
               inner='quartile', ax=axes[1])
axes[1].set_title('Age Distribution by Survival')

plt.tight_layout()
plt.show()

分类与数值的 GroupBy 统计量

请使用 groupby 通过数值分组统计量补充可视化比较。计算每个类别的平均值、中位数和计数,以量化图中所见的差异。请关注平均值和中位数存在明显差异的类别(说明组内存在异常值),并检查各组大小是否均衡——非常小的组(<5 条观测)会使比较结果不可靠。

import pandas as pd
import seaborn as sns

df = sns.load_dataset('titanic')

stats = df.groupby('class')['fare'].agg(['mean', 'median', 'std', 'count'])
stats.columns = ['Mean Fare', 'Median Fare', 'Std Fare', 'Count']
print(stats.round(2))

print('\nSurvival rate by class:')
print(df.groupby('class')['survived'].mean().round(3))

分类与分类:交叉表

对于两个分类变量,请使用 pd.crosstab(df['var1'], df['var2']) 创建频数表,显示每种类别组合中有多少条观测。使用 normalize='index' 或 normalize='columns' 按行或按列进行归一化,以获得比例而不是计数。这是研究两个分类变量是否相互独立或存在关联的基础。

import pandas as pd
import seaborn as sns

df = sns.load_dataset('titanic')

# Frequency table
counts = pd.crosstab(df['class'], df['survived'])
counts.columns = ['Died', 'Survived']
print('Counts:')
print(counts)

# Row-normalised proportions (survival rate per class)
props = pd.crosstab(df['class'], df['survived'], normalize='index')
props.columns = ['Died', 'Survived']
print('\nSurvival Rate per Class:')
print(props.round(3))

将交叉表可视化为热力图

将交叉表转换为热力图,即可直观比较各单元格的频数。当类别组合很多时,热力图比打印出的表格更便于快速浏览。使用 annot=True 在每个单元格中标注其值,并选择连续型颜色映射(例如 'YlOrRd'),因为所有值都为非负数。对按行归一化的比例绘制热力图,可以有效显示给定一个类别时另一个类别的条件分布。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')
props = pd.crosstab(df['class'], df['sex'], normalize='index')

sns.heatmap(props, annot=True, fmt='.2f', cmap='YlOrRd')
plt.title('Gender Mix by Passenger Class (Row %)')
plt.xlabel('Sex')
plt.ylabel('Class')
plt.show()

独立性卡方检验

独立性卡方检验用于检查两个分类变量在统计上是否相互独立。scipy.stats.chi2_contingency(crosstab) 会返回卡方统计量、p 值、自由度和期望频数。较小的 p 值(通常 < 0.05)意味着两个变量之间存在统计上显著的关联——一个变量的分布会随另一个变量系统性地变化。

import pandas as pd
import seaborn as sns
from scipy.stats import chi2_contingency

df = sns.load_dataset('titanic')

# Test if passenger class and survival are independent
crosstab = pd.crosstab(df['class'], df['survived'])
chi2, p, dof, expected = chi2_contingency(crosstab)

print(f'Chi-squared: {chi2:.2f}')
print(f'P-value: {p:.6f}')
print(f'Degrees of freedom: {dof}')
print(f'\nConclusion: {"Significant association" if p < 0.05 else "No significant association"}')

数值列的完整相关矩阵

与其一次只检查一对列,不如计算所有数值列的完整相关矩阵,并将其可视化为热力图。这样可以一眼看出哪些变量对具有较强的相关性。独立特征之间的高相关性(多重共线性)可能会给回归模型带来问题——及早了解这些关系,便可以在建模前删除或合并冗余特征。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

df = sns.load_dataset('titanic')
corr = df.select_dtypes('number').corr()
mask = np.triu(np.ones_like(corr, dtype=bool))

sns.heatmap(corr, mask=mask, annot=True, fmt='.2f',
            cmap='coolwarm', vmin=-1, vmax=1,
            linewidths=0.5, square=True)
plt.title('Correlation Matrix — Titanic Numeric Columns')
plt.tight_layout()
plt.show()

子群体之间的交互作用

有时,两个变量之间的关系会因子群体不同而出现显著差异,这种现象称为辛普森悖论。例如,年龄与票价之间的相关性对头等舱乘客可能为正,而对三等舱乘客可能为负。请始终按照关键分类变量对双变量分析进行分组(在 Seaborn 中使用 hue,或分别进行 groupby 聚合),以检查这种关系在不同子群体中是否一致,或是否会发生反转。

import seaborn as sns
import matplotlib.pyplot as plt

df = sns.load_dataset('titanic')

# Scatter coloured by passenger class
sns.scatterplot(
    data=df.dropna(subset=['age', 'fare']),
    x='age',
    y='fare',
    hue='class',
    alpha=0.5,
    palette='deep'
)
plt.title('Age vs Fare — Does Class Change the Relationship?')
plt.legend(title='Class')
plt.yscale('log')  # log scale due to fare skewness
plt.show()

记录双变量分析结果

完成双变量分析后,请记录关键发现:哪些特征对之间存在相关性(相关程度如何)、分类变量在数值结果上是否表现出有意义的组间差异,以及是否发现任何子群体交互作用或悖论。这些洞见应指导特征选择决策:高度相关的特征对可能需要删除其中一个,而对目标变量具有较强预测能力的分类变量则应标记为建模时的高优先级输入。

快速检查

测试您对本课双变量分析和相关性分析的理解。

课程回顾

在本课中,您学习了:散点图和 Pearson r 用于分析数值变量之间的关系,箱线图、提琴图和 groupby 用于比较不同类别中的数值变量,交叉表和卡方检验 用于衡量分类变量之间的关联。接下来,我们将学习如何把 EDA 结果整理成结构化摘要报告。

免费开始

用 AI 导师学习 Python — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
30
课程
120

常见问题解答

「双变量与相关性分析」课时是免费的吗?

是的 — 「双变量与相关性分析」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Pandas & NumPy Academy 课程的其余内容,请升级到 CoddyKit PRO。 Pandas & NumPy Academy 课程共包含 4 节课。

「双变量与相关性分析」这节课中我会学到什么?

使用散点图、箱线图和相关性热力图,探索成对列之间的关系。 你通过在浏览器中直接运行的动手代码来练习 Pandas & NumPy Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Pandas & NumPy Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Pandas & NumPy Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「双变量与相关性分析」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Pandas & NumPy Academy 课中编写并运行代码吗?

能。每节 Pandas & NumPy Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 数据集分析清单
  2. 单变量分析
  3. 双变量与相关性分析
  4. 在报告中总结发现
← 返回 Pandas & NumPy Academy