基于paired t-test的新旧路由算法成功率A/B测试及置信区间问询
新旧算法成功率统计分析与代码优化
背景
我正在对现有模型的改进版本(称为新算法)进行模拟测试,该模型用于预测特定交易在两条可选路由中的选择,成功率定义为总成功数/总交易数。现有包含14天新旧算法每日成功率的DataFrame数据。
问题
- 希望通过统计方法判断新算法是否优于旧算法,已编写配对t检验代码,但交换新旧列后p值不变,当前检验仅能判断两者存在显著差异,需指导如何得出新算法更优的结论。
- 能否给出新旧算法成功率差值的置信区间?
原代码
import pandas as pd from scipy import stats data = pd.DataFrame({ 'old': [74.9254,73.7721,73.6018,68.6855,63.4666,63.9204,70.6977,62.6488,67.8088,70.2274,71.1197,64.8925,73.1113,70.7065], # Replace with your old algorithm results 'new': [74.8419,73.7548,73.6677,68.9352,63.8387,64.1143,70.9533,62.6026,67.9586,70.7,71.1263,65.1053,72.9996,70.5899], }) # Perform a paired t-test t_statistic, p_value = stats.ttest_rel(data['new'], data['old']) # Define your significance level (alpha) alpha = 0.05 # Print the t-statistic and p-value print(f"Paired t-statistic: {t_statistic}") print(f"P-value: {p_value}") # Compare p-value to the significance level if p_value < alpha: print("Reject the null hypothesis. The new algorithm is performing significantly better.") else: print("Fail to reject the null hypothesis. There is no significant difference between the algorithms.")
解答
问题1:验证新算法更优的统计方法
scipy.stats.ttest_rel默认执行双侧t检验,原假设是“新旧算法成功率无差异”,备择假设仅判定“两者存在差异”,因此交换新旧列只会让t统计量符号反转,p值保持不变。要证明新算法更优,需改用单侧配对t检验:
- 原假设H₀:新算法成功率 ≤ 旧算法成功率(即
new - old的总体均值 ≤ 0) - 备择假设H₁:新算法成功率 > 旧算法成功率(即
new - old的总体均值 > 0)
实现逻辑:
- 计算
new - old的差值,明确检验方向 - 将双侧检验的p值转换为单侧:若t统计量为正(新算法平均成功率更高),单侧p值为双侧p值的一半;若t统计量为负,单侧p值为
1 - 双侧p值/2 - 只有当单侧p值 < 显著性水平α(如0.05),且t统计量为正时,才能得出“新算法显著更优”的结论
问题2:计算成功率差值的置信区间
基于t分布性质,可通过样本均值、样本标准差和样本量计算差值的置信区间(默认95%置信水平),公式为:差值均值 ± t临界值 * (样本标准差 / √样本量)
其中t临界值通过scipy.stats.t.ppf获取,自由度为样本量-1
优化后完整代码
import pandas as pd from scipy import stats data = pd.DataFrame({ 'old': [74.9254,73.7721,73.6018,68.6855,63.4666,63.9204,70.6977,62.6488,67.8088,70.2274,71.1197,64.8925,73.1113,70.7065], 'new': [74.8419,73.7548,73.6677,68.9352,63.8387,64.1143,70.9533,62.6026,67.9586,70.7,71.1263,65.1053,72.9996,70.5899], }) # 计算新旧算法成功率差值 data['diff'] = data['new'] - data['old'] # 执行双侧配对t检验 t_stat, p_val_two_sided = stats.ttest_rel(data['new'], data['old']) # 转换为单侧p值(检验new > old) if t_stat > 0: p_val_one_sided = p_val_two_sided / 2 else: p_val_one_sided = 1 - (p_val_two_sided / 2) alpha = 0.05 # 输出检验结果 print(f"配对t统计量: {t_stat:.4f}") print(f"双侧p值: {p_val_two_sided:.4f}") print(f"单侧p值(new > old): {p_val_one_sided:.4f}") # 判断新算法是否显著更优 if p_val_one_sided < alpha and t_stat > 0: print("拒绝原假设:新算法的成功率显著优于旧算法。") elif p_val_two_sided < alpha: print("拒绝原假设:新旧算法成功率存在显著差异,但无法证明新算法更优。") else: print("无法拒绝原假设:新旧算法成功率无显著差异。") # 计算差值的95%置信区间 confidence_level = 0.95 n = len(data['diff']) mean_diff = data['diff'].mean() std_diff = data['diff'].std(ddof=1) # 样本标准差,自由度n-1 t_critical = stats.t.ppf((1 + confidence_level) / 2, df=n-1) margin_of_error = t_critical * (std_diff / (n ** 0.5)) confidence_interval = (mean_diff - margin_of_error, mean_diff + margin_of_error) print(f"\n新旧算法成功率差值的95%置信区间: ({confidence_interval[0]:.4f}, {confidence_interval[1]:.4f})")
内容的提问来源于stack exchange,提问作者Aayush Gupta
相关产品推荐
相关产品推荐

