AI 分类项目的交叉表/混淆矩阵
在 C# 中为二元或多级分类器的训练或验证数据构建混淆矩阵或交叉表
引言
如果您使用 Python 等语言和/或使用 TensorFlow 或 MatLab 等工具,那么在执行神经网络、svm、逻辑回归或决策树等的二元或多分类训练时,可以使用各种工具或方法来获得“评估指标”。 如果您使用 SPSS 或 SAS 等工具,获取交叉表和相关统计数据也很容易。 但是,当您想使用 C# 时(通常情况下),您需要构建自己的方法。
对于 C# AI 和统计工作,我使用 ALGLIB 的免费(但非线程)版本取得了良好的效果,该版本具有相当不错且相对易于使用的工具,用于构建和训练神经网络和决策树,以及在其他 C# 应用程序中使用这些训练好的网络来分类新数据。 但是,我想能够以普通的交叉表或“混淆矩阵”格式可视化结果。 因此,本文介绍了并描述了我认为有用且希望分享的一种方法。
给定两个列表,一个列表是用于训练的“有监督”或“标记”值列表,另一个列表是通过将训练好的网络应用于相同“特征”数据而产生的分类列表,以及用于提供良好的变量和值标签的选项,此 Crosstabs()
方法将返回一个漂亮的“混淆矩阵”(一个方阵交叉表,外加一列用于行精度和一行用于列召回值,以及一个整体准确度),或者作为文本输出到控制台(如下所示),或者作为填充的 DataGridView
控件,用于在表单中使用(如上所示)。
Using the Code
CrosstabsDemo
运行一个包含 datagridview
控件的 winform。 Form1.cs 代码(部分如下所示)为变量(例如,VOTING
)创建一个列表(名为 LabelledData
),该变量统一随机地假设 NofStates = 4
。 假设这是用于训练或验证网络的有监督或标记的准则数据。
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace CrosstabsDemo
{
public partial class Form1 : Form
{
public static Random Rand = new Random(0); // Note: random seed is set to 0
// for reproducibility
public Form1()
{
InitializeComponent();
int NofCases = 10000;
int NofStates = 4;
List<int> LabelledData = new List<int>();
List<int> ClassifiedData = new List<int>();
// Generate some random data
for (int i = 0; i < NofCases; i++)
{
int avalue = Rand.Next(1, NofStates+1);
int pvalue = avalue + (int)RandomGausian(0, .6); // add a bit of random error
if (pvalue > NofStates) pvalue = NofStates;
if (pvalue < 1) pvalue = 1;
LabelledData.Add(avalue);
ClassifiedData.Add(pvalue);
}
Dictionary<int, string=""> RowValueLabels = new Dictionary<int, string="">()
{
{ 1,"One" }, { 2,"Two" }, { 3,"Three" },{ 4,"Four" },{ 5,"Five" }
};
// For example:
Crosstabs ct =
new Crosstabs(ClassifiedData, LabelledData, tablelabel: "VOTING");
ct.RowLabels = RowValueLabels;
ct.ColumnLabels = RowValueLabels; // In a confusion matrix,
// both vars have the same distinct values
ct.WritetoConsole();
ct.View(dataGridView1);
}
......
}
}
接下来,它创建第二个列表(名为 ClassifiedData
),其中包含一些添加的错误以模拟将训练好的网络应用于特征数据(用于训练)并取回网络的预测分类的结果。(或者,当然,这些列表可以模拟一个验证数据集。)
这两个列表是 Crosstabs
对象的构造函数方法的输入(可能还有像 VOTING
这样的准则变量名)。 初始 Crosstabs
对象(在演示中名为 ct
)是一个简单的数值整数 array [,]
,您可以使用 ct.GetTableArray
属性检索它。
可选地,为了获得更易读的输出,您可以使用 ct.RowLabels
和 ct.ColumnLabels
属性添加行和列值标签。(如果您添加的行或列标签少于不同的状态值,则剩余的标签将被填充为空字符串。如果您添加的标签多于值,则将被忽略。)
然后,您可以通过调用 ct.WritetoConsole()
方法将格式良好的结果表以文本形式写入控制台窗口(可能仅用于测试),如下所示。或者更好的是(在使用表单时),通过将 Form1.datagridview
控件的名称提供给 ct.View()
方法,您可以获得交叉表/混淆矩阵结果的更具吸引力的输出可视化,如上所示。 任何一种输出都易于复制并粘贴到其他文档中。
关注点
这里几乎没有涉及到巧妙的编程,但是这种工具在我的工作中非常有用,用于可视化使用 C# 进行的 AI 训练和验证的结果。 我希望读者可以直接或通过少量修改和/或添加来满足类似的需求。 例如,如果您只需要交叉表(带正方形或矩形网格),则此方法将执行此操作。 如果您需要其他统计测试(卡方检验、F 比率等),添加它们将很简单。
历史
- 2017 年 11 月 13 日:原文
- 2017 年 11 月 18 日:更新
- 重新设计了 crosstabs.cs 以更正当混淆矩阵为矩形时的错误:例如,如果训练好的模型没有对某些标记值进行任何分类。 将行和列值标签的类型从
List<string>
更改为Dictionary<int><string>
。
- 重新设计了 crosstabs.cs 以更正当混淆矩阵为矩形时的错误:例如,如果训练好的模型没有对某些标记值进行任何分类。 将行和列值标签的类型从