我正在尝试根据这个示例调整一些正类未标记学习的代码,我的代码能够运行,但我想计算ROC AUC分数时遇到了困难。
我的数据分为正类样本(data_P
)和未标记样本(data_U
),每个样本只有两个特征/列,例如:
#3个示例行:data_P[[-1.471, 5.766], [-1.672, 5.121], [-1.371, 4.619]]
#3个示例行:data_U[[1.23, 6.26], [-5.72, 4.1213], [-3.1, 7.129]]
我按照链接中的示例运行了正类未标记学习:
known_labels_ratio = 0.5NP = data_P.shape[0]NU = data_U.shape[0]T = 1000K = NPtrain_label = np.zeros(shape=(NP+K,))train_label[:NP] = 1.0n_oob = np.zeros(shape=(NU,))f_oob = np.zeros(shape=(NU, 2))for i in range(T): # 自助重抽样 bootstrap_sample = np.random.choice(np.arange(NU), replace=True, size=K) # 正类集合 + 自助重抽样的未标记集合 data_bootstrap = np.concatenate((data_P, data_U[bootstrap_sample, :]), axis=0) # 训练模型 model = DecisionTreeClassifier(max_depth=None, max_features=None, criterion='gini', class_weight='balanced') model.fit(data_bootstrap, train_label) # 标记不在袋外(out of the bag, oob)样本的索引 idx_oob = sorted(set(range(NU)) - set(np.unique(bootstrap_sample))) # oob样本的传导学习 f_oob[idx_oob] += model.predict_proba(data_U[idx_oob]) n_oob[idx_oob] += 1 predict_proba = f_oob[:, 1]/n_oob
这一切都运行得很好,但我想运行roc_auc_score()
,但我不知道如何避免错误地计算它。
目前我尝试的是:
y_pred = model.predict_proba(data_bootstrap)roc_auc_score(train_label, y_pred)ValueError: bad input shape (3, 2)
问题似乎在于y_pred
的输出有两列,看起来像这样:
y_predarray([[0.00554287, 0.9944571 ], [0.0732314 , 0.9267686 ], [0.16861796, 0.83138204]])
我不确定为什么y_pred
会变成这样,它是根据样本是否落入两个组别(正类或其他)来给出概率吗?我是否可以筛选这些数据,选择每行中得分最高的概率?或者我是否可以更改这个,或者有其他方法来计算AUCROC分数?
回答:
y_pred
必须是一个单一的数字,表示正类的概率p1
;目前你的y_pred
包含了两个概率[p0, p1]
(根据定义,p0+p1=1.0
)。
假设你的正类是类1
(即y_pred
中每个数组的第二个元素),你应该做的操作是:
y_pred_pos = [y_pred[i, 1] for i in range(len(y_pred))]y_pred_pos # 检查# [0.9944571, 0.9267686, 0.83138204]roc_auc_score(train_label, y_pred_pos)
如果你的y_pred
是一个Numpy数组(而不是Python列表),你可以用以下命令替换第一个命令中的列表解析:
y_pred_pos = y_pred[:,1]