使用测试数据预测概率分数时y值为空的问题排查
问题排查:模型预测后y值为空的原因及修复
问题背景
测试已构建的回归模型时,重点验证年龄对概率分数(proba score)的影响,以此判断是否需要重新训练模型。使用包含age、sex、cc_list的测试数据和模型参数集合PARAM_COLLECTION编写代码后,运行结果y为空——即便代码中有低于阈值时赋值的逻辑,仍无法定位原因。
错误原因分析
参数引用逻辑错误:
代码中param_coll = PARAM_COLLECTION[coll_name]得到的是PULL对应的模型参数字典(包含auc、coef、features_sltd等键),但后续判断if cc not in param_coll:时,cc的值是"PULL",而param_coll中并没有"PULL"这个键,因此直接触发continue跳过整个循环,后续的概率计算、赋值逻辑完全没执行,导致y始终为空。参数层级混淆:
PARAM_COLLECTION的结构是{"PULL": 模型参数字典},而非{"PULL": {"PULL": 模型参数字典}},因此不需要从param_coll中再通过cc取值,直接使用param_coll作为模型参数即可。
修复后的代码
import numpy as np # 测试数据:用户带有PULL特征 x_test = { "cc_list": ["PULL"], "age": 38, "sex": "M" } # 模型参数集合(来自之前训练的模型) PARAM_COLLECTION = { "PULL": { "auc": 0.8202432743081695, "coef": [-0.01853237366699478, 0.14359336438414397, 3.0070029131017155, 1.4999028794882714, 0.2499927123452168, 0.00869006612608888, -0.17741710091314503], "features_sltd": ["CARM", "GIL", "PULL", "PULM", "SKCVL", "age", "sex"], "intercept": -3.066213895858403, "model_name": "l1-reg", "regularization_param": 100000.0, "threshold": 0.5277152026373001 } } # 预测概率分数 y = {} coll_name = "PULL" param_coll = PARAM_COLLECTION[coll_name] for cc in x_test["cc_list"]: # 直接使用param_coll作为当前cc对应的模型参数,无需再嵌套取值 param = param_coll if param["model_name"] == "none": continue features_sltd = param["features_sltd"] features_efft = [] x_vec = np.zeros(len(features_sltd)) for i, f in enumerate(features_sltd): if f == cc: # 匹配当前cc对应的特征,而非判断是否在cc_list里 x_vec[i] = 1.0 features_efft.append((f, param["coef"][i])) # 按系数降序排序,过滤出系数大于0.1的特征 features_efft = sorted(features_efft, key=lambda x: -x[1]) features_efft = [f[0] for f in features_efft if f[1] > 0.1] # 赋值年龄和性别特征 x_vec[features_sltd.index("age")] = x_test["age"] x_vec[features_sltd.index("sex")] = int(x_test["sex"]=="M") # 计算逻辑回归概率 beta = np.dot(np.array(param["coef"]), x_vec) + param["intercept"] proba = 1.0/(1.0 + np.exp(-beta)) # 根据阈值赋值结果 if proba > param["threshold"]: y[cc] = {"score": np.clip(proba, 0.0, 1.0), "features": features_efft} else: y[cc] = {"score": 0.0, "features": []} # 输出结果 print(y)
关键修改说明
- 修正参数引用:直接将
param_coll赋值给param,不再尝试从param_coll中通过cc取值,解决循环被跳过的核心问题。 - 调整特征匹配逻辑:将
if f in x_test["cc_list"]改为if f == cc,精准匹配当前循环的cc对应的特征,避免误匹配其他可能存在的cc。 - 保留核心逻辑:去掉了
if len(features_efft)==0: continue的判断,确保即使没有高系数特征,也能完成概率计算并赋值y,符合原代码中低于阈值时赋值的需求。
内容的提问来源于stack exchange,提问作者btk666
相关产品推荐
相关产品推荐

