假设检验 和 回归分析

假设检验:判断差异是不是"真的"

核心问题

你观察到 CTR 从 12% 变成 13%,这1%的提升到底是排序策略真的有效,还是纯粹随机波动?
任何指标天天都在波动,哪怕什么都没变,今天12.3%明天11.8%都很正常。假设检验要解决的就是:怎么判断"看到的差异"够不够大,大到不能用随机波动解释。

为什么能做到——背后的逻辑链

第一步:假设"什么都没变"(零假设)

零假设 H0:策略上线前后,CTR 真实值没有变化
观察到的差异只是随机波动
注意这是个反向逻辑:不是直接证明"策略有效",而是先假设"无效",然后看观察到的数据有多不像"无效"的情况。

第二步:如果零假设成立,波动应该有多大

这是关键的统计学事实:如果反复抽样测量同一个本质不变的指标,每次测出来的平均值会围绕真实值上下波动,波动幅度可以被计算出来,叫做标准误(Standard Error)。

python# 你的两组真实数据
before = [0.12, 0.118, 0.121, 0.119, 0.122]   # 均值 0.12, 标准差 0.00158
after  = [0.13, 0.128, 0.131, 0.129, 0.132]   # 均值 0.13, 标准差 0.00158
#  标准误:两组均值差异,预期会波动多大
SE = sqrt(var(before)/n + var(after)/n) = sqrt(0.0000025/5 + 0.0000025/5) = 0.001

这个 0.001 的意思是:如果真实没有差异,纯靠随机波动,两组均值的差大概会在 ±0.001 这个量级晃动。

第三步:算出观察到的差异是标准误的多少倍

观察到的差异 = 0.13 - 0.12 = 0.01
标准误 SE = 0.001
t = 差异 / SE = 0.01 / 0.001 = 10

这个 t = 10 的意思是:你观察到的差异,是"纯随机波动应该有的幅度"的10倍。
第四步:把 t 值翻译成概率(p-value)
t 值服从一个已知形状的分布(t分布),可以查出"如果真的没有差异,随机抽样恰好抽出 t=10 这么极端结果"的概率:
pythonp_value = 0.0000085 # 算出来的实际值
p 值小于 0.05(约定的阈值),说明:如果真的什么都没变,几乎不可能随机抽到这么大的差异。所以拒绝"什么都没变"这个假设,认为差异是真实的。

为什么这套逻辑能成立——数学根基

中心极限定理是整套逻辑的地基: 不管原始数据是什么分布,只要样本量够大,"样本均值"这个东西,会近似服从正态分布
而且这个正态分布的"宽窄"是可以精确计算的:
标准误 = 总体标准差 / √样本量
样本量越大,标准误越小(均值越稳定);标准差越大(数据本身波动大),标准误越大(均值越不稳定)。这就是为什么数据量小、波动大的时候,差异看起来很大也可能不显著。

完整代码

pythonfrom scipy import stats
import numpy as np

before = [0.12, 0.118, 0.121, 0.119, 0.122]
after  = [0.13, 0.128, 0.131, 0.129, 0.132]

t_stat, p_value = stats.ttest_ind(before, after)
print(f"t统计量: {t_stat:.2f}")      # -10.0
print(f"p值: {p_value:.6f}")          # 0.0000085

if p_value < 0.05:
    print("差异显著,不是随机波动")
else:
    print("差异不显著,可能是随机噪音")

回归分析:量化变量之间的关系

核心问题

不只是"有没有关系",而是关系有多强、变化一个单位会带来多大影响。
比如:搜索词越长,CTR 是不是越低?低多少?

为什么能做到——背后的逻辑

回归分析的目标是找一条直线,让这条直线和所有真实点的"误差"加起来最小。

真实数据点:(搜索词长度, CTR)
  (2, 0.15)
  (3, 0.13)
  (4, 0.12)
  (5, 0.10)
  (6, 0.08)

# 要找一条直线: CTR = β0 + β1 × 长度 让所有点到这条直线的距离(误差)平方和最小


# 为什么是平方和最小,不是直接距离最小:
平方有两个好处:
1. 消除正负号问题(点在线上方和下方误差不会抵消)
2. 数学上可以求导,能解出精确解(不需要试错)

怎么求出这条最优直线——数学推导
设直线为 y = β0 + β1·x,误差平方和为:
S = Σ(yi - β0 - β1·xi)²
要让 S 最小,对 β0  β1 求偏导,令导数为 0(高中微积分:极值点导数为0):
S/∂β0 = 0
S/∂β1 = 0
解这两个方程,得到一个直接套用的公式(叫最小二乘法):
β1 = Σ(xi-x̄)(yi-ȳ) / Σ(xi-x̄)²
β0 = ȳ - β1·x̄
不需要试错或迭代,直接套公式就能算出唯一最优解,这是线性回归的优势——有解析解。

用真实数字走一遍
x(搜索词长度):2, 3, 4, 5, 6      x̄ = 4
yCTR):       0.15, 0.13, 0.12, 0.10, 0.08    ȳ = 0.116

第一步:算每个点离均值多远
x偏差-2, -1, 0, 1, 2
y偏差0.034, 0.014, 0.004, -0.016, -0.036

第二步:分子 Σ(xi-x̄)(yi-ȳ)
= (-2)(0.034) + (-1)(0.014) + (0)(0.004) + (1)(-0.016) + (2)(-0.036)
= -0.068 - 0.014 + 0 - 0.016 - 0.072
= -0.17

第三步:分母 Σ(xi-x̄)²
= 4 + 1 + 0 + 1 + 4 = 10

第四步:算系数
β1 = -0.17 / 10 = -0.017
β0 = 0.116 - (-0.017 × 4) = 0.184
最终方程: CTR = 0.184 - 0.017 × 搜索词长度
直接的业务解读:搜索词每增加1个字,CTR平均下降1.7个百分点。

这个系数靠不靠谱——  p-value
光有系数不够,还要知道这条线"靠不靠谱"
pythonfrom scipy import stats

x = [2, 3, 4, 5, 6]
y = [0.15, 0.13, 0.12, 0.10, 0.08]

slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)
print(f"系数: {slope:.4f}")        # -0.017
print(f"截距: {intercept:.4f}")    # 0.184
print(f"R²: {r_value**2:.4f}")     # 0.9897
print(f"p值: {p_value:.6f}")       # 0.00044
 = 0.99
   这条直线解释了99%CTR变化
   长度几乎完全决定了CTR(现实中很少见,这是构造的干净例子)

p值 = 0.00044 < 0.05
   这个关系不是巧合,长度对CTR确实有显著影响
 在说什么: 这条线"贴合"数据的程度,从01,越接近1说明 x  y 的解释力越强。
p-value 在说什么: 这次其实是套用了假设检验的逻辑——零假设是"长度对CTR没有影响(系数应该是0)"p值小说明系数显著不为0,这个影响是真实存在的。

两者的共同底层逻辑

假设检验:
先假设"没有差异"
算出"纯随机情况下差异应该多大"
对比"实际差异"和"随机应该的差异"
差太多 → 拒绝"没有差异"的假设

回归分析的显著性检验:
先假设"系数是0(没有关系)"
算出"纯随机情况下系数应该在0附近晃动多大"
对比"实际算出的系数"和"随机应该的晃动幅度"
差太多 → 拒绝"没有关系"的假设

本质上是同一套思路:用观察到的数据,反推"巧合"能不能解释这个现象,不能就认为是真实效应。
这也是为什么数据分析师岗位常把两者放在一起要求——理解一个,另一个的逻辑也就通了。