相关性与回归分析
问题
如何衡量两个变量之间的关系?线性回归的原理和假设是什么?如何在数据分析中应用回归?
答案
相关性分析
相关性衡量两个变量之间线性关系的强弱和方向。
常用相关系数对比
| 系数 | 适用场景 | 数据要求 | 范围 |
|---|---|---|---|
| Pearson r | 连续变量、线性关系 | 正态分布、等距/比率 | [-1, 1] |
| Spearman ρ | 有序关系、非线性单调 | 顺序即可 | [-1, 1] |
| Kendall τ | 小样本、有并列 | 顺序即可 | [-1, 1] |
相关不等于因果
- 冰淇淋销量和溺水事件正相关 → 共同受"夏季气温"影响(混淆变量)
- A/B 相关可能是:A→B、B→A、C→A+B(混淆)、纯巧合
- 仅靠观测数据无法确定因果,需要随机对照实验/因果推断
相关性分析
import pandas as pd
import numpy as np
from scipy import stats
df = pd.DataFrame({
'ad_spend': [10, 20, 30, 40, 50, 60, 70, 80],
'revenue': [15, 25, 40, 45, 55, 70, 80, 90],
'satisfaction': [3, 4, 3, 5, 4, 5, 4, 5]
})
# Pearson 相关系数
r, p_value = stats.pearsonr(df['ad_spend'], df['revenue'])
print(f"Pearson r = {r:.4f}, p = {p_value:.4f}")
# 相关系数矩阵
print(df.corr(method='pearson'))
# Spearman(适用于非线性单调关系 或 有序数据)
rho, p = stats.spearmanr(df['ad_spend'], df['satisfaction'])
print(f"Spearman ρ = {rho:.4f}")
相关系数强弱判断
| |r| 范围 | 强度 | |-----------|------| | 0.0 ~ 0.3 | 弱相关 | | 0.3 ~ 0.7 | 中等相关 | | 0.7 ~ 1.0 | 强相关 |
线性回归
简单线性回归
- :截距
- :斜率(x 每增加 1 单位,y 的平均变化)
- :误差项
线性回归建模
import statsmodels.api as sm
X = df['ad_spend']
y = df['revenue']
# statsmodels 需要手动添加常数项(截距)
X_const = sm.add_constant(X)
model = sm.OLS(y, X_const).fit()
print(model.summary())
# 关注:
# - R-squared: 模型解释了多少变异(越接近1越好)
# - coef: 回归系数(广告花费每增加1万,收入增加多少)
# - P>|t|: 系数的 p 值(< 0.05 则显著)
# - Adj. R²: 调整 R²(惩罚变量数量,多元回归时更合理)
多元线性回归
多元回归示例
import pandas as pd
import statsmodels.api as sm
df = pd.DataFrame({
'price': [100, 120, 80, 150, 90, 130, 110, 140],
'ad_spend': [50, 60, 40, 80, 45, 70, 55, 75],
'competitor': [3, 2, 4, 1, 3, 2, 3, 1],
'sales': [200, 180, 250, 150, 230, 170, 190, 160]
})
X = df[['price', 'ad_spend', 'competitor']]
y = df['sales']
X_const = sm.add_constant(X)
model = sm.OLS(y, X_const).fit()
print(model.summary())
# 多重共线性检查:VIF
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif_data = pd.DataFrame()
vif_data['feature'] = X.columns
vif_data['VIF'] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
print(vif_data)
# VIF > 10 → 严重共线性,考虑移除变量
回归的核心假设
| 假设 | 检验方法 | 违反后果 |
|---|---|---|
| 线性关系 | 残差图 | 模型拟合差 |
| 独立性 | Durbin-Watson 检验 | 系数标准误偏小 |
| 等方差性 | 残差 vs 预测值散点图 | 区间估计不准 |
| 正态性 | 残差 Q-Q 图 / Shapiro-Wilk | 小样本推断不可靠 |
| 无多重共线性 | VIF | 系数不稳定 |
逻辑回归(分类问题)
当因变量是二分类时(如是否购买),使用逻辑回归:
逻辑回归示例
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
# 预测用户是否流失
X = df[['usage_days', 'complaint_count', 'contract_months']]
y = df['churned']
model = LogisticRegression()
model.fit(X, y)
# 系数解读:exp(coef) = 优势比 (Odds Ratio)
import numpy as np
for name, coef in zip(X.columns, model.coef_[0]):
print(f"{name}: coef={coef:.3f}, OR={np.exp(coef):.3f}")
# OR > 1: 增加该变量 → 流失概率上升
# OR < 1: 增加该变量 → 流失概率下降
常见面试问题
Q1: R² 和调整 R² 的区别?
答案:
- R²:模型解释的方差比例,添加任何变量都会增大(即使无用变量)
- 调整 R²:惩罚了变量数量,只有变量真正有用时才增大
- 多元回归中应看调整 R²,防止过拟合
Q2: 什么是多重共线性?如何处理?
答案:
- 自变量之间高度相关(如身高 cm 和身高 inch 同时放入模型)
- 后果:系数不稳定、符号反转、置信区间变宽
- 处理:删除冗余变量、PCA 降维、正则化(Ridge/Lasso)
Q3: 回归系数不显著(p > 0.05)怎么办?
答案:
- 检查样本量是否足够(小样本 power 不足)
- 检查多重共线性(VIF 过大导致标准误膨胀)
- 该变量可能确实对因变量没有显著影响
- 可能是非线性关系,尝试变量变换或多项式回归
Q4: 如何选择用 Pearson 还是 Spearman?
答案:
- Pearson:数据近似正态、关系是线性的
- Spearman:数据有异常值、关系是单调但非线性的、数据是有序的
- 不确定时两个都算,如果差异大 → 说明关系可能非线性
Q5: 逻辑回归的 Odds Ratio 怎么解读?
答案:
- OR = 1 → 无影响
- OR = 1.5 → 该变量增加 1 单位,事件发生的优势增加 50%
- OR = 0.7 → 该变量增加 1 单位,事件发生的优势降低 30%
- 用于量化各因素对转化/流失等事件的影响大小