使用R,我可以使用以下代码和for循环手动计算[并绘制] AUC:
self.new_button = Button(self)
我正在尝试用Python编写相同的代码,但是遇到错误“ TypeError:'Series'对象是可变的,因此不能被散列”
我对Python还是很陌生,正试图与R和Python成为双语。在解决这个问题上,有人可以指出我正确的方向吗?
test = data.frame(cbind(dt$DV, predicted_prob))
colnames(test)[1] = 'DV'
colnames(test)[2] = 'DV_pred_prob'
TP = rep(NA,101)
FN = rep(NA,101)
FP = rep(NA,101)
TN = rep(NA,101)
Sensitivity = rep(NA,101)
Specificity = rep(NA,101)
AUROC = 0
for(i in 0:100){
test$temp = 0
test[test$DV_pred_prob > (i/100),"temp"] = 1
TP[i+1] = nrow(test[test$DV==1 & test$temp==1,])
FN[i+1] = nrow(test[test$DV==1 & test$temp==0,])
FP[i+1] = nrow(test[test$DV==0 & test$temp==1,])
TN[i+1] = nrow(test[test$DV==0 & test$temp==0,])
Sensitivity[i+1] = TP[i+1] / (TP[i+1] + FN[i+1] )
Specificity[i+1] = TN[i+1] / (TN[i+1] + FP[i+1] )
if(i>0){
AUROC = AUROC+0.5*(Specificity[i+1] - Specificity[i])*(Sensitivity[i+1] +
Sensitivity[i])
}
}
data = data.frame(cbind(Sensitivity,Specificity,id=(0:100)/100))
该错误似乎发生在包含(i / 100)的代码部分附近。
答案 0 :(得分:1)
熊猫索引无法按您期望的方式工作。您不能使用df[rows, cols]
而是使用.loc
(https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.loc.html)
是的-您是对的,因为错误是由您的行引起的:
test[test['predictions'] > (i/100), "temp"] = 1
。
要解决此问题,您可以使用:
test.loc[test['predictions'] > (i/100), "temp"] = 1
。
...,那么您将在遵循以下格式的以下4行上遇到问题:
TP[i+1] = test[test["actual"]==1 and test["temp"]==1,].shape[0]
您需要将每个评估语句括在括号中,并将and
更改为&
。关于为什么出现在这里有很好的讨论:Truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()。因此您的代码应如下所示:
TP[i+1] = len(test[(test["actual"]==1) & (test["temp"]==1)])
注意;我们可以使用len
函数而不是数据帧shape
属性的第一个元素来计算行数。不过那只是我的偏爱。
最后;您不能在python中以这种方式设置'NA'值;您将使用np.NAN
。最终的if语句将失败,因为您已将字符串数组用作占位符。我认为np.zeros(101)
将为您服务。
您的完整代码以及我的修改:
predictions = pd.DataFrame(predictions[1])
actual = pd.DataFrame(y_test)
test = pd.concat([actual.reset_index(drop=True), predictions], axis=1)
# Rename column Renew to 'actual' and '1' to 'predictions'
test.columns = ['actual', 'predictions'] #<- You can assign column names using a list
TP = np.zeros(101)
FN = np.zeros(101)
FP = np.zeros(101)
TN = np.zeros(101)
Sensitivity = np.zeros(101)
Specificity = np.zeros(101)
AUROC = 0
for i in range(10):
test['temp'] = 0
test.loc[test['predictions'] > (i / 100), 'temp'] = 1
TP[i+1] = len(test[(test["actual"]==1) & (test["temp"]==1)])
FN[i+1] = len(test[(test["actual"]==1) & (test["temp"]==0)])
FP[i+1] = len(test[(test["actual"]==0) & (test["temp"]==1)])
TN[i+1] = len(test[(test["actual"]==0) & (test["temp"]==0)])
Sensitivity[i+1] = TP[i+1] / (TP[i+1] + FN[i+1])
Specificity[i+1] = TN[i+1] / (TN[i+1] + FP[i+1])
if i > 0:
AUROC += 0.5 * (Specificity[i+1] - Specificity[i]) * (Sensitivity[i+1] + Sensitivity[i])