我正在对来自分类器的实际数据和预测数据进行多标签分类。实际数据由三个类别(c1,c2和c3)组成,以相同的方式,预测数据也由三个类别(c1,c2和c3)组成。数据如下
Actual_data Predicted_data
c1 c2 c3 c1 c2 c3
1 1 0 1 1 1
1 1 0 1 0 1
1 0 1 0 1 1
0 1 1 1 0 0
1 0 0 1 1 0
1 1 1 1 0 1
在多标签分类中,文档可能属于多个类别。在上述数据中,1表示文档属于特定类别,0表示文档不属于特定类别。
Actual_data的第一行表示文档属于类c1和c2,不属于类c3。同样,predicted_data的第一行表示文档属于类c1,c2和c3。
最初,我使用R编程来查找实际数据和预测数据之间的混淆矩阵。我将这些数据帧保存在y_actual和y_predict中。
y_actual<-as.matrix(Actual_data)
y_predict<-as.matrix(Predicted_data)
xtab<-table(y_actual,y_predict)
输出xtab为
y_predict
y_actual 0 1
0 1 5
1 5 7
然后我使用R的脱字符号包创建了混淆矩阵,
library(caret)
confusionMatrix(xtab)
Confusion Matrix and Statistics
y_predict
y_actual 0 1
0 1 5
1 5 7
Accuracy : 0.4444
95% CI : (0.2153, 0.6924)
No Information Rate : 0.6667
P-Value [Acc > NIR] : 0.9856
Kappa : -0.25
Mcnemar's Test P-Value : 1.0000
Sensitivity : 0.16667
Specificity : 0.58333
Pos Pred Value : 0.16667
Neg Pred Value : 0.58333
Prevalence : 0.33333
Detection Rate : 0.05556
Detection Prevalence : 0.33333
Balanced Accuracy : 0.37500
'Positive' Class : 0
在这种情况下,我没有多标签混淆矩阵,而有二进制标签混淆矩阵。我想要一个在y-actual中具有c1,c2,c3以及y--predict的混淆矩阵,而不是在y-actual和y-predict中的0,1。
然后我在Internet上搜索了utiml包,该包用于R中的多标签分类,但是没有提供所需的输出。然后,我尝试使用python的scikit包进行多标签分类,代码如下。
import numpy as np
from sklearn.metrics import multilabel_confusion_matrix
y_actual = np.array([[1, 1, 0],
[1, 1, 0],
[1, 0, 1],
[0, 1, 1],
[1, 0, 0],
[1, 1, 1]])
y_predict = np.array([[1, 1, 1],
[1, 0, 1],
[0, 1, 1],
[1, 0, 0],
[1, 1, 0],
[1, 0, 1]])
matrix = multilabel_confusion_matrix(y_actual, y_predict)
print(matrix)
print(classification_report(y_actual,y_predict))
程序的输出是
[[[0 1]
[1 4]]
[[0 2]
[3 1]]
[[1 2]
[1 2]]]
precision recall f1-score support
0 0.80 0.80 0.80 5
1 0.33 0.25 0.29 4
2 0.50 0.67 0.57 3
micro avg 0.58 0.58 0.58 12
macro avg 0.54 0.57 0.55 12
weighted avg 0.57 0.58 0.57 12
samples avg 0.53 0.61 0.54 12
在这种情况下,我也没有正确地获得输出标签。任何人都可以帮助我在任何平台(R-programming,python或weka)中使用哪种程序包来获取上述实际和预测数据的多标签混淆矩阵。在输出中,对于y_actual和y_predict的c1,c2和c3,混淆矩阵必须是3 * 3矩阵。
y_predict
y_actual c1 c2 c3
c1 4
c2 1
c3 2
在这里,对角元素表明它实际上属于c1,而分类器则预测它属于c1。对于c2和c3同样。我的问题是如何获得混淆矩阵的其他值,因为它是多标签分类。这个问题不是多分类问题,而是多标签分类问题。
答案 0 :(得分:1)
您可以按以下方式使用multilabel_confusion_matrix
中的sklearn
函数:
import numpy as np
from sklearn.metrics import multilabel_confusion_matrix, classification_report
y_true = np.array([[1, 0, 1],
[0, 1, 0]])
y_pred = np.array([[1, 0, 0],
[0, 1, 1]])
matrix = multilabel_confusion_matrix(y_true, y_pred)
print(matrix)
print(classification_report(y_true,y_pred))
答案 1 :(得分:0)
一种解决方案是更改数据的表示方式,以使其与caret
或sklearn
所期望的混淆矩阵一致。如果您认为混淆矩阵中的每个单元格代表一个离散的类预测(即“对于此类,我们进行了预测,但是我们实际上看到了”),那么您会发现没有任何方法可以实际构造这样的矩阵在您的示例中,类可以具有相同的值。
请记住,在您的示例中,您实际上没有三个离散的类别-您拥有8个类别。
这意味着对于观察的每一行,给定存在的三个分类值,您的数据点就可以承担:
none of the categories
only c1
c1&c2
c1&c3
only c2
c2&c3
only c3
all categories
所有您需要做的就是在数据框中添加一个新列,以对您现有的三个目标列进行重新编码,以便新列采用1或8个表示每种组合的值。
以下是解决方案的一个示例:
#Recreating your data
Actual_data <- cbind(c(1, 1, 1, 0, 1, 1),
c(1, 1, 0, 1, 0, 1),
c(0, 0, 1, 1, 0, 1)
)
colnames(Actual_data) <- c("c1", "c2", "c3")
Predicted_data <- cbind(c(1, 1, 0, 1, 1, 1),
c(1, 0, 1, 0, 1, 0),
c(1, 1, 1, 0, 0, 1)
)
colnames(Predicted_data) <- c("c1", "c2", "c3")
#To make it easy to recode everything, we can convert these two objects into dataframes:
Predicted_data <-as.data.frame(Predicted_data)
Actual_data <- as.data.frame(Actual_data)
#Next, we make a simple function that goes through each row and recodes the class
#combinations to a distinct category
set_class_combinations <- function(df){
df$target <- 0
for (i in nrow(df)){
df$target[df$c1 == 0 & df$c2 == 0 & df$c3 == 0] <- 1
df$target[df$c1 == 1 & df$c2 == 0 & df$c3 == 0] <- 2
df$target[df$c1 == 1 & df$c2 == 1 & df$c3 == 0] <- 3
df$target[df$c1 == 1 & df$c2 == 0 & df$c3 == 1] <- 4
df$target[df$c1 == 0 & df$c2 == 1 & df$c3 == 0] <- 5
df$target[df$c1 == 0 & df$c2 == 1 & df$c3 == 1] <- 6
df$target[df$c1 == 0 & df$c2 == 0 & df$c3 == 1] <- 7
df$target[df$c1 == 1 & df$c2 == 1 & df$c3 == 1] <- 8
}
return(df)
}
#With the function, we can add a new "target" column to our respective dataframes
Predicted_data <- set_class_combinations(Predicted_data)
Actual_data <- set_class_combinations(Actual_data)
#As your example does not include all available combinations, we just need to ensure that we
#account for this when we set the factor levels (1 through 8) and call the `confusionMatrix` function
cm <- confusionMatrix(factor(Predicted_data$target, levels = 1:8), factor(Actual_data$target, levels = 1:8))
print(cm)