Python 数据分析实战:5种数据类型相关性检验与可视化代码全解
·
Python 数据分析实战:5种数据类型相关性检验与可视化代码全解
在数据科学项目中,理解变量间的相关性是探索性分析的核心环节。本文将深入解析Python中处理五种常见数据类型组合的相关性分析方法,提供可直接复用的代码模板,涵盖统计检验、可视化技巧和实际应用场景。
1. 连续变量 vs 连续变量
当分析两个连续变量的关系时,散点图和Pearson相关系数是标准工具。但实际应用中需要注意数据分布和异常值的影响。
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
from scipy import stats
# 生成示例数据
np.random.seed(42)
data = pd.DataFrame({
'销售额': np.random.normal(100, 15, 200),
'广告投入': np.random.normal(50, 8, 200) * 1.2 + np.random.normal(0, 5, 200)
})
# 增强型散点图
plt.figure(figsize=(10,6))
sns.scatterplot(data=data, x='广告投入', y='销售额',
alpha=0.6, edgecolor='w', s=80)
plt.title('销售额与广告投入关系', pad=20, fontsize=14)
sns.regplot(data=data, x='广告投入', y='销售额',
scatter=False, color='red', ci=95)
plt.grid(True, alpha=0.3)
# 计算相关系数及p值
corr, p_value = stats.pearsonr(data['广告投入'], data['销售额'])
print(f"Pearson r = {corr:.3f}, p-value = {p_value:.4f}")
提示:当数据量较大时,考虑使用hexbin图或密度图替代散点图以避免过度绘制问题
对于非正态分布数据,Spearman相关系数是更好的选择:
# 非参数检验
spearman_corr = data.corr(method='spearman').iloc[0,1]
print(f"Spearman ρ = {spearman_corr:.3f}")
2. 连续变量 vs 分类变量
分析分类变量如何影响连续变量时,箱线图配合统计检验能直观展示组间差异。
2.1 二分类情况
# 模拟电商用户数据
user_data = pd.DataFrame({
'消费金额': np.concatenate([
np.random.normal(800, 150, 100),
np.random.normal(1200, 200, 100)
]),
'会员等级': ['普通']*100 + ['VIP']*100
})
# 增强箱线图
plt.figure(figsize=(8,6))
sns.boxplot(data=user_data, x='会员等级', y='消费金额',
width=0.4, palette='pastel')
sns.stripplot(data=user_data, x='会员等级', y='消费金额',
color='black', alpha=0.3, size=4)
plt.title('不同会员等级的消费金额分布', pad=15)
# 独立样本t检验
normal = user_data[user_data['会员等级']=='普通']['消费金额']
vip = user_data[user_data['会员等级']=='VIP']['消费金额']
t_stat, p_val = stats.ttest_ind(normal, vip, equal_var=False)
print(f"Welch's t-test: t = {t_stat:.2f}, p = {p_val:.4f}")
2.2 多分类情况
对于三个及以上分类,使用ANOVA分析:
# 添加第三组数据
user_data = pd.concat([
user_data,
pd.DataFrame({
'消费金额': np.random.normal(1500, 250, 100),
'会员等级': ['SVIP']*100
})
])
# 可视化
plt.figure(figsize=(10,6))
sns.violinplot(data=user_data, x='会员等级', y='消费金额',
palette='Set2', inner='quartile')
plt.title('多等级用户消费金额分布', pad=15)
# 单因素方差分析
groups = [group['消费金额'] for name, group in user_data.groupby('会员等级')]
f_stat, p_val = stats.f_oneway(*groups)
print(f"ANOVA: F = {f_stat:.2f}, p = {p_val:.4f}")
# 事后检验(Tukey HSD)
from statsmodels.stats.multicomp import pairwise_tukeyhsd
tukey = pairwise_tukeyhsd(user_data['消费金额'], user_data['会员等级'])
print(tukey.summary())
3. 分类变量 vs 分类变量
分析两个分类变量的关联性时,堆叠条形图和卡方检验是标准方法。
# 创建医疗数据示例
medical_data = pd.DataFrame({
'治疗方案': np.random.choice(['A','B','C'], 500, p=[0.4,0.3,0.3]),
'疗效': np.random.choice(['无效','改善','显著改善'], 500,
p=[0.2,0.5,0.3])
})
# 交叉表
cross_tab = pd.crosstab(medical_data['治疗方案'], medical_data['疗效'],
margins=True, margins_name="总计")
cross_tab_pct = cross_tab.div(cross_tab['总计'], axis=0) * 100
# 堆叠条形图
cross_tab_pct.iloc[:-1,:-1].plot(kind='bar', stacked=True,
colormap='RdYlGn', figsize=(10,6))
plt.title('不同治疗方案疗效对比(%)', pad=15)
plt.ylabel('百分比')
plt.legend(bbox_to_anchor=(1.05,1))
# 卡方检验
chi2, p, dof, expected = stats.chi2_contingency(cross_tab.iloc[:-1,:-1])
print(f"卡方检验: χ² = {chi2:.2f}, p = {p:.4f}")
# 计算Cramer's V
n = cross_tab.iloc[-1,-1]
phi_corr = np.sqrt(chi2/(n*(min(cross_tab.shape)-1)))
print(f"Cramer's V = {phi_corr:.3f}")
4. 有序分类变量分析
当处理有序分类变量时,需要特殊的相关性度量方法。
# 创建客户满意度数据
survey_data = pd.DataFrame({
'服务评分': np.random.choice(['差','中','良','优'], 300,
p=[0.1,0.3,0.4,0.2]),
'回购意愿': np.random.choice(['低','中','高'], 300,
p=[0.2,0.5,0.3])
})
# 有序变量编码
rating_order = ['差','中','良','优']
buy_order = ['低','中','高']
survey_data['服务评分'] = pd.Categorical(survey_data['服务评分'],
categories=rating_order, ordered=True)
survey_data['回购意愿'] = pd.Categorical(survey_data['回购意愿'],
categories=buy_order, ordered=True)
# 热力图展示频率
pivot_table = survey_data.groupby(['服务评分','回购意愿']).size().unstack()
plt.figure(figsize=(8,6))
sns.heatmap(pivot_table, annot=True, fmt='d', cmap='YlGnBu',
cbar_kws={'label': '频数'})
plt.title('服务评分与回购意愿关联', pad=15)
# Kendall's tau-b检验
tau_b, p_value = stats.kendalltau(survey_data['服务评分'].cat.codes,
survey_data['回购意愿'].cat.codes)
print(f"Kendall's tau-b = {tau_b:.3f}, p = {p_value:.4f}")
5. 混合类型变量分析
实际项目中常需要分析混合类型变量的关系,如连续变量与有序分类变量的关联。
# 员工绩效数据
employee_data = pd.DataFrame({
'培训时长': np.random.normal(20, 5, 200),
'绩效评级': pd.Categorical(
np.random.choice(['C','B','A'], 200, p=[0.3,0.5,0.2]),
categories=['C','B','A'], ordered=True)
})
# 分组箱线图
plt.figure(figsize=(10,6))
sns.boxplot(data=employee_data, x='绩效评级', y='培训时长',
palette='coolwarm', width=0.5)
sns.swarmplot(data=employee_data, x='绩效评级', y='培训时长',
color='black', alpha=0.4, size=3)
plt.title('不同绩效员工的培训时长分布', pad=15)
# Jonckheere-Terpstra趋势检验
from scipy.stats import kruskal
groups = [group['培训时长'].values
for _, group in employee_data.groupby('绩效评级')]
jt_stat, p_value = stats.kruskal(*groups)
print(f"Jonckheere-Terpstra近似检验: p = {p_value:.4f}")
高级可视化技巧
提升相关性分析呈现效果的专业可视化方法:
# 组合图表示例
fig, axes = plt.subplots(2, 2, figsize=(12,10))
# 1. 带边际分布的散点图
sns.scatterplot(data=data, x='广告投入', y='销售额', ax=axes[0,0])
sns.histplot(data=data, x='广告投入', kde=True, ax=axes[0,1], color='skyblue')
sns.histplot(data=data, y='销售额', kde=True, ax=axes[1,0], color='salmon')
axes[1,1].axis('off')
# 2. 分面网格图
grid = sns.FacetGrid(user_data, col='会员等级', height=4, aspect=1.2)
grid.map(sns.histplot, '消费金额', kde=True, bins=15)
# 3. 相关系数矩阵热力图
corr_matrix = data.corr()
mask = np.triu(np.ones_like(corr_matrix, dtype=bool))
sns.heatmap(corr_matrix, mask=mask, annot=True, cmap='coolwarm',
center=0, fmt='.2f', ax=axes[1,1])
axes[1,1].set_title('变量间相关系数矩阵', pad=10)
实战应用建议
-
数据预处理 :分析前确保处理缺失值(如插补或删除)和异常值(如Winsorize处理)
# Winsorize处理示例 from scipy.stats.mstats import winsorize data['销售额'] = winsorize(data['销售额'], limits=[0.05, 0.05]) -
多重检验校正 :当进行多次相关性检验时,应用Benjamini-Hochberg等方法控制错误发现率
from statsmodels.stats.multitest import multipletests pvals = [0.01, 0.03, 0.05, 0.2] _, adj_p, _, _ = multipletests(pvals, method='fdr_bh') print(f"校正后p值: {adj_p}") -
效应量解读 :除了统计显著性,还应报告相关系数大小等效应量指标
相关系数范围 解释力度 0.00-0.10 可忽略 0.10-0.30 弱相关 0.30-0.50 中等相关 >0.50 强相关
更多推荐
所有评论(0)