在python中,用实际标签和预测标签的计数从已经聚合的表中创建混淆矩阵的最佳方法是什么

在python中,用实际标签和预测标签的计数从已经聚合的表中创建混淆矩阵的最佳方法是什么,python,pandas,machine-learning,scikit-learn,Python,Pandas,Machine Learning,Scikit Learn,如果数据以以下格式提供,用python创建混淆矩阵的最佳/最快方法是什么: +--------------+-----------------+-------------------+ | Actual Label | Predicted Label | Count Occurrences | +--------------+-----------------+-------------------+ | A | A | 200

如果数据以以下格式提供,用python创建混淆矩阵的最佳/最快方法是什么:

+--------------+-----------------+-------------------+
| Actual Label | Predicted Label | Count Occurrences |
+--------------+-----------------+-------------------+
| A            | A               | 200               |
+--------------+-----------------+-------------------+
| B            | B               | 150               |
+--------------+-----------------+-------------------+
| C            | D               | 15                |
+--------------+-----------------+-------------------+
| X            | Y               | 5                 |
+--------------+-----------------+-------------------+
| ...          | ...             | ...               |
+--------------+-----------------+-------------------+

假设您拥有以下形式的数据帧:

import pandas as pd


df = pd.DataFrame({
    'Actual Label': ['A', 'A', 'A', 'A', 'B', 'B', 'C', 'D'],
    'Predicted Label': ['A', 'B', 'C', 'D', 'B', 'C', 'D', 'D'],
    'Count Occurences': [200, 150, 100, 150, 50, 100, 70, 80]
})
看起来是这样的:

  Actual Label Predicted Label  Count Occurences
0            A               A               200
1            A               B               150
2            A               C               100
3            A               D               150
4            B               B                50
5            B               C               100
6            C               D                70
7            D               D                80
[[200. 150. 100.   0.]
 [  0. 150.  50.   0.]
 [  0.   0.   0. 100.]
 [  0.   0.   0.  70.]
 [ 80.   0.   0.   0.]]
然后可以使用
.pivot\u table()
函数创建类似矩阵的表格:

df = df.pivot_table(values='Count Occurences', index='Actual Label', columns='Predicted Label')
这类似于混淆矩阵:

Predicted Label      A      B      C      D
Actual Label                               
A                200.0  150.0  100.0  150.0
B                  NaN   50.0  100.0    NaN
C                  NaN    NaN    NaN   70.0
D                  NaN    NaN    NaN   80.0
missing_cols = [col for col in df.index if col not in df.columns]

for col in missing_cols:
    df[col] = 0

# This will ensure that the index and columns have the same order
df = df[df.index.values]
如果您想去掉列名和索引名,只需使用
values
属性获取仅包含数据帧值的
numpy
数组。您可能还希望使用
.fillna()
删除
NaN
值,并用0替换它们:

df.fillna(0, inplace=True)
print(df.values)

# Output

[[200. 150. 100. 150.]
 [  0.  50. 100.   0.]
 [  0.   0.   0.  70.]
 [  0.   0.   0.  80.]]

编辑

在某些情况下,可能无法预测所有的实际标签,因此可能会丢失一些标签。例如:

  Actual Label Predicted Label  Count Occurences
0            A               A               200
1            A               B               150
2            A               C               100
3            B               B               150
4            B               C                50
5            C               D               100
6            D               D                70
7            E               A                80
注意标签
E
从未被预测到。上述代码将生成如下矩阵:

  Actual Label Predicted Label  Count Occurences
0            A               A               200
1            A               B               150
2            A               C               100
3            A               D               150
4            B               B                50
5            B               C               100
6            C               D                70
7            D               D                80
[[200. 150. 100.   0.]
 [  0. 150.  50.   0.]
 [  0.   0.   0. 100.]
 [  0.   0.   0.  70.]
 [ 80.   0.   0.   0.]]
在这种情况下,您可以手动添加缺少的所有列以创建混淆矩阵:

Predicted Label      A      B      C      D
Actual Label                               
A                200.0  150.0  100.0  150.0
B                  NaN   50.0  100.0    NaN
C                  NaN    NaN    NaN   70.0
D                  NaN    NaN    NaN   80.0
missing_cols = [col for col in df.index if col not in df.columns]

for col in missing_cols:
    df[col] = 0

# This will ensure that the index and columns have the same order
df = df[df.index.values]
得到

[[200. 150. 100.   0.   0.]
 [  0. 150.  50.   0.   0.]
 [  0.   0.   0. 100.   0.]
 [  0.   0.   0.  70.   0.]
 [ 80.   0.   0.   0.   0.]]

假设您拥有以下形式的数据帧:

import pandas as pd


df = pd.DataFrame({
    'Actual Label': ['A', 'A', 'A', 'A', 'B', 'B', 'C', 'D'],
    'Predicted Label': ['A', 'B', 'C', 'D', 'B', 'C', 'D', 'D'],
    'Count Occurences': [200, 150, 100, 150, 50, 100, 70, 80]
})
看起来是这样的:

  Actual Label Predicted Label  Count Occurences
0            A               A               200
1            A               B               150
2            A               C               100
3            A               D               150
4            B               B                50
5            B               C               100
6            C               D                70
7            D               D                80
[[200. 150. 100.   0.]
 [  0. 150.  50.   0.]
 [  0.   0.   0. 100.]
 [  0.   0.   0.  70.]
 [ 80.   0.   0.   0.]]
然后可以使用
.pivot\u table()
函数创建类似矩阵的表格:

df = df.pivot_table(values='Count Occurences', index='Actual Label', columns='Predicted Label')
这类似于混淆矩阵:

Predicted Label      A      B      C      D
Actual Label                               
A                200.0  150.0  100.0  150.0
B                  NaN   50.0  100.0    NaN
C                  NaN    NaN    NaN   70.0
D                  NaN    NaN    NaN   80.0
missing_cols = [col for col in df.index if col not in df.columns]

for col in missing_cols:
    df[col] = 0

# This will ensure that the index and columns have the same order
df = df[df.index.values]
如果您想去掉列名和索引名,只需使用
values
属性获取仅包含数据帧值的
numpy
数组。您可能还希望使用
.fillna()
删除
NaN
值,并用0替换它们:

df.fillna(0, inplace=True)
print(df.values)

# Output

[[200. 150. 100. 150.]
 [  0.  50. 100.   0.]
 [  0.   0.   0.  70.]
 [  0.   0.   0.  80.]]

编辑

在某些情况下,可能无法预测所有的实际标签,因此可能会丢失一些标签。例如:

  Actual Label Predicted Label  Count Occurences
0            A               A               200
1            A               B               150
2            A               C               100
3            B               B               150
4            B               C                50
5            C               D               100
6            D               D                70
7            E               A                80
注意标签
E
从未被预测到。上述代码将生成如下矩阵:

  Actual Label Predicted Label  Count Occurences
0            A               A               200
1            A               B               150
2            A               C               100
3            A               D               150
4            B               B                50
5            B               C               100
6            C               D                70
7            D               D                80
[[200. 150. 100.   0.]
 [  0. 150.  50.   0.]
 [  0.   0.   0. 100.]
 [  0.   0.   0.  70.]
 [ 80.   0.   0.   0.]]
在这种情况下,您可以手动添加缺少的所有列以创建混淆矩阵:

Predicted Label      A      B      C      D
Actual Label                               
A                200.0  150.0  100.0  150.0
B                  NaN   50.0  100.0    NaN
C                  NaN    NaN    NaN   70.0
D                  NaN    NaN    NaN   80.0
missing_cols = [col for col in df.index if col not in df.columns]

for col in missing_cols:
    df[col] = 0

# This will ensure that the index and columns have the same order
df = df[df.index.values]
得到

[[200. 150. 100.   0.   0.]
 [  0. 150.  50.   0.   0.]
 [  0.   0.   0. 100.   0.]
 [  0.   0.   0.  70.   0.]
 [ 80.   0.   0.   0.   0.]]

谢谢你详细的回答。你的解决方案似乎奏效了。然而,“实际标签”(df_initial['Actual Label'].nunique=17)和“预测标签”(df_initial['Predicted Label'].nunique=15)的唯一值数量不平衡。因此,如果我使用你的解决方案,我得到一个17x15矩阵,我确实需要一个17x17矩阵(如果我正确理解混淆矩阵的问题)。你知道如何用你漂亮简单的解决方案来解决这个问题吗?我更新了我的答案,也涵盖了这个案例。我想不出比添加缺少的列更优雅的方法了。但它会解决问题。我还发现了一些可能更优雅的方法来生成矩阵。简单,优雅,快速,我真的很感激你的回答:)保持良好的工作!Best RegardsI意识到,如果只添加列,可能会破坏索引和列之间的顺序。因此,结果不会是一个真正的混淆矩阵。我在
for
循环之后添加了语句,以保证正确的顺序。我想现在一切都应该包括在内。谢谢你详细的回答。你的解决方案似乎奏效了。然而,“实际标签”(df_initial['Actual Label'].nunique=17)和“预测标签”(df_initial['Predicted Label'].nunique=15)的唯一值数量不平衡。因此,如果我使用你的解决方案,我得到一个17x15矩阵,我确实需要一个17x17矩阵(如果我正确理解混淆矩阵的问题)。你知道如何用你漂亮简单的解决方案来解决这个问题吗?我更新了我的答案,也涵盖了这个案例。我想不出比添加缺少的列更优雅的方法了。但它会解决问题。我还发现了一些可能更优雅的方法来生成矩阵。简单,优雅,快速,我真的很感激你的回答:)保持良好的工作!Best RegardsI意识到,如果只添加列,可能会破坏索引和列之间的顺序。因此,结果不会是一个真正的混淆矩阵。我在
for
循环之后添加了语句,以保证正确的顺序。我想现在一切都应该包括在内。