跳到主要内容

相关性与回归分析

问题

如何衡量两个变量之间的关系?线性回归的原理和假设是什么?如何在数据分析中应用回归?

答案

相关性分析

相关性衡量两个变量之间线性关系的强弱和方向

常用相关系数对比

系数适用场景数据要求范围
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 | 强相关 |

线性回归

简单线性回归

y=β0+β1x+ϵy = \beta_0 + \beta_1 x + \epsilon
  • β0\beta_0:截距
  • β1\beta_1:斜率(x 每增加 1 单位,y 的平均变化)
  • ϵ\epsilon:误差项
线性回归建模
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²(惩罚变量数量,多元回归时更合理)

多元线性回归

y=β0+β1x1+β2x2++βpxp+ϵy = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \cdots + \beta_p x_p + \epsilon
多元回归示例
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系数不稳定

逻辑回归(分类问题)

当因变量是二分类时(如是否购买),使用逻辑回归:

P(y=1x)=11+e(β0+β1x)P(y=1|x) = \frac{1}{1 + e^{-(\beta_0 + \beta_1 x)}}
逻辑回归示例
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²,防止过拟合

Q2: 什么是多重共线性?如何处理?

答案

  • 自变量之间高度相关(如身高 cm 和身高 inch 同时放入模型)
  • 后果:系数不稳定、符号反转、置信区间变宽
  • 处理:删除冗余变量、PCA 降维、正则化(Ridge/Lasso)

Q3: 回归系数不显著(p > 0.05)怎么办?

答案

  1. 检查样本量是否足够(小样本 power 不足)
  2. 检查多重共线性(VIF 过大导致标准误膨胀)
  3. 该变量可能确实对因变量没有显著影响
  4. 可能是非线性关系,尝试变量变换或多项式回归

Q4: 如何选择用 Pearson 还是 Spearman?

答案

  • Pearson:数据近似正态、关系是线性的
  • Spearman:数据有异常值、关系是单调但非线性的、数据是有序的
  • 不确定时两个都算,如果差异大 → 说明关系可能非线性

Q5: 逻辑回归的 Odds Ratio 怎么解读?

答案

  • OR = 1 → 无影响
  • OR = 1.5 → 该变量增加 1 单位,事件发生的优势增加 50%
  • OR = 0.7 → 该变量增加 1 单位,事件发生的优势降低 30%
  • 用于量化各因素对转化/流失等事件的影响大小

相关链接