towardsdatascience.com/coverage-vs-accuracy-striking-a-balance-in-data-science-d555415eebe4?source=collection_archive---------7-----------------------#2024-04-16
敏捷模型生产:快速实现成果的艺术
作者:Nadav Har-Tuv 与 Yuval Cohen
发表于 Towards Data Science | 阅读时间:7 分钟 | 发布日期:2024 年 4 月 16 日

封面图像由 ChatGPT 提供
引言
在数据科学领域,许多项目因预测精度不足而被中止。这种情况令人惋惜,因为这些模型往往对数据中的某些子集表现良好,只是未能在整个数据集上保持一致的高性能。
通常,数据科学家会尝试通过引入更复杂的算法或增加训练数据量来提升整体性能。然而,一种更为高效的方法常常被忽视:先从数据中最容易处理的部分入手,建立高精度的预测能力,再逐步攻克更具挑战性的部分。
这种策略不仅能够迅速产出可用成果,还能让团队将资源集中在真正困难的问题上,从而显著提升解决实际问题的效率。
敏捷思维在建模中的应用
所谓“敏捷生产”,指的是优先处理简单、清晰的数据片段,在确保这部分建模成功后,再转向复杂情形。这种方法支持迭代式开发、价值导向决策以及高效的团队协作。
其核心优势包括:
- 迭代与增量推进: 在短周期内完成小目标,先在易处理的数据上实现高准确率,随后逐步扩展到更难的样本。
- 聚焦价值创造: 优先解决那些能带来最高边际效益的问题,最大化时间利用率。
- 灵活应对变化: 当外部需求变动(如客户关注特定数据子集)时,可快速调整方向。将任务拆解有助于适应动态环境。
- 持续反馈与优化: 拆分问题使得改进过程更加连续,无需等待大规模突破即可验证进展。
- 促进团队协作: 小模块化任务便于并行处理和跨成员协作,避免工作过度集中于单一个人。
面对现实世界的复杂性
真实场景下的数据通常充满噪声和细微差异。例如,在医疗诊断中,症状的微小变化可能意味着健康与危重疾病之间的区别。在这种背景下,追求全量数据上的高精度往往是不现实的。
此时,“覆盖率”成为一个关键指标——它衡量的是模型能够在多大比例的数据上做出高置信度且准确的预测。
与其试图覆盖全部数据并牺牲整体精度,不如选择专注于模型擅长的子集。通过这种方式,可以在该子集上实现极高准确率,同时明确承认其余部分尚未被有效建模。
举例来说,假设一个模型在测试集上的总体准确率为 50%。如果我们能识别出其中模型高度确信的预测样本(需明确定义“高度确信”的标准),那么即使只覆盖 60% 的数据,也可能将准确率提升至 85%。
对于大多数产品负责人而言,这样的结果极具吸引力——尤其是在尚无任何上线模型的情况下,这已是实质性的第一步进展。
两阶段建模范式
我们可以将整个建模流程划分为两个阶段,分别对应“已覆盖”和“未覆盖”两类数据:
- 已覆盖数据: 指初步模型可以高精度、高置信度预测的部分。
- 未覆盖数据: 模型无法给出可靠判断、准确率较低的数据区域。
第一阶段: 训练初始模型,并识别其表现优异的数据子集。一旦确认该子集上的预测质量达标,即可部署模型处理这些数据,形成早期可用成果。
第二阶段: 转向未覆盖部分。通过补充数据、改进特征工程、采用更先进算法或融合领域知识,深入挖掘复杂模式。
在此过程中,首要步骤是直观分析错误案例。很多时候,仅通过可视化观察就能发现明显的模式,无需立即动用复杂的建模技术。
实例演示:二维分类问题
以下示例旨在形象说明敏捷工作流如何释放巨大价值。虽然情境经过简化,但其所体现的理念完全适用于现实场景。
考虑一组模拟的二维数据,包含三个类别,每个类别有 500 个样本:
num_samples_A = 500
num_samples_B = 500
num_samples_C = 500
# Class A
mean_A = [3, 2]
通过对这些数据进行建模,我们可以首先识别出最容易区分的类别组合(例如 A 与 B),构建一个在该子集上表现优异的轻量级模型并投入使用。之后,再集中精力研究剩余难以分离的样本(如 C 类与其他类的边界区域),进行精细化建模。
这种方法允许我们快速交付第一版模型,同时保留后续优化的空间,体现了真正的敏捷精神。
# 定义类别 A 的参数 mean_A = [0, 0] cov_A = [[0.1, 0], [0, 0.1]] # 方差较小,数据分布集中 class_A = np.random.multivariate_normal(mean_A, cov_A, num_samples_A) # 设置类别 B 的均值与协方差矩阵 mean_B = [0, 0] cov_B = [[1, 0.5], [0.5, 1]] # 方差较大,且与类别 C 存在部分重叠 class_B = np.random.multivariate_normal(mean_B, cov_B, num_samples_B) # 配置类别 C 的统计特性 mean_C = [0, 1] cov_C = [[2, 0.5], [0.5, 2]] # 更大的方差,与类别 B 有交集 class_C = np.random.multivariate_normal(mean_C, cov_C, num_samples_C)来自三个类别的二维数据towardsdatascience.com/coverage-vs-accuracy-striking-a-balance-in-data-science-d555415eebe4?source=collection_archive---------7-----------------------#2024-04-16
接下来,我们尝试使用支持向量机(SVM)分类器对上述生成的数据进行建模。考虑到数据中存在一定的非线性可分性,选择带有高斯核函数(即径向基函数,RBF)的SVM可能更为合适。
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
# 合并三类样本及其标签
data = np.concatenate([class_A, class_B, class_C])
labels = np.concatenate([
np.zeros(num_samples_A),
np.ones(num_samples_B),
np.ones(num_samples_C) * 2
])
# 构造DataFrame便于处理
df = pd.DataFrame(data, columns=['x', 'y'])
df['label'] = labels.astype(int)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
df[['x', 'y']], df['label'], test_size=0.2, random_state=42
)
# 使用RBF核训练SVM模型,并启用概率输出
svm_rbf = SVC(kernel='rbf', probability=True)
svm_rbf.fit(X_train, y_train)
# 预测每个测试样本属于各个类别的概率
svm_rbf_probs = svm_rbf.predict_proba(X_test)
# 提取预测结果:坐标、真实标签、预测标签及置信度
svm_rbf_predictions = [
(X_test.iloc[i]['x'], X_test.iloc[i]['y'], true_class, np.argmax(probs), np.max(probs))
for i, (true_class, probs) in enumerate(zip(y_test, svm_rbf_probs))
]
# 将结果转换为DataFrame以便分析
svm_predictions_df = pd.DataFrame(svm_rbf_predictions).rename(
columns={0: 'x', 1: 'y', 2: 'true_class', 3: 'predicted_class', 4: 'confidence'}
)
评估该分类器在当前数据上的表现:
accuracy = (svm_predictions_df['true_class'] == svm_predictions_df['predicted_class']).mean() * 100
print(f'Accuracy = {round(accuracy, 2)}%')
输出结果为:
Accuracy = 75.33%
尽管准确率达到75.33%,看似并不理想,但这是否说明模型毫无价值?实际上,在类别之间存在显著重叠的情况下,这样的性能可能已经反映了模型具备一定的判别能力。进一步优化超参数或采用集成方法或许能提升效果,但当前结果仍提供了有意义的分类参考。
为了评估模型在高置信预测下的表现,我们首先需要明确“最有信心的预测”如何定义。一种可行的方法是设定不同的置信度阈值(
),并分析每个阈值下模型的覆盖率与精度,从而根据实际业务需求选择最优阈值。predict_proba
以下代码展示了如何遍历多个置信度阈值,并计算对应的覆盖率和准确率:
thresholds = [.5, .55, .6, .65, .7, .75, .8, .85, .9]
results = []
for threshold in thresholds:
svm_df_covered = svm_predictions_df.loc[svm_predictions_df['confidence'] > threshold]
coverage = len(svm_df_covered) / len(svm_predictions_df) * 100
accuracy_covered = (svm_df_covered['true_class'] == svm_df_covered['predicted_class']).mean() * 100
results.append({'Threshold': threshold, 'Coverage (%)': round(coverage,2), 'Accuracy on covered data (%)': round(accuracy_covered,2)})
results_df = pd.DataFrame(results)
print(results_df)
执行后得到如下结果:

若希望更直观地观察趋势,可以绘制精度与覆盖率随阈值变化的曲线图:

通过图表或表格,我们可以依据业务要求进行权衡决策。例如,若公司规定预测精度不得低于90%,则可选择0.75作为阈值,在此条件下模型覆盖了约62%的数据且达到了预期精度水平。相比完全弃用模型,这种策略显著提升了可用性,尤其在尚未部署任何生产模型的情况下更具优势。
当模型已在约60%的数据上稳定运行时,后续工作可聚焦于剩余未被覆盖的数据部分。可能的改进方向包括:收集更多样本、优化特征工程、尝试更复杂的算法结构,或引入领域专家的知识支持。
方法权衡分析
采用分阶段的两步建模策略,允许我们在整体精度尚未达标的情况下,优先确保部分数据上的高质量预测。这种方法避免了在初期就强求全量数据高精度所带来的资源浪费和开发瓶颈,反而更加务实高效。
效率优化视角
本文提出的敏捷式建模流程旨在提升资源利用效率。与其投入大量算力追求全域高精度,不如识别出模型表现最佳的数据子集,集中资源发挥其最大价值。这种“先局部上线,再逐步扩展”的思路,有助于实现快速迭代与持续优化。
总结
尽管高准确性是数据科学项目的核心目标之一,但在面对真实场景中噪声多、分布复杂的数据时,盲目追求全面高精度并不现实。敏捷模型部署倡导优先服务于模型最擅长的子集,在此基础上稳步推进对困难样本的建模能力。这一策略不仅能加快落地进程,还能更合理地分配有限资源。
思考模型的生产价值,拥抱敏捷思维,才能在现实挑战中实现真正的数据驱动。


雷达卡


京公网安备 11010802022788号







