65.9K
CodeProject 正在变化。 阅读更多。
Home

AI 分类项目的交叉表/混淆矩阵

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2017 年 11 月 13 日

CPOL

3分钟阅读

viewsIcon

18638

downloadIcon

324

在 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.RowLabelsct.ColumnLabels 属性添加行和列值标签。(如果您添加的行或列标签少于不同的状态值,则剩余的标签将被填充为空字符串。如果您添加的标签多于值,则将被忽略。)

然后,您可以通过调用 ct.WritetoConsole() 方法将格式良好的结果表以文本形式写入控制台窗口(可能仅用于测试),如下所示。或者更好的是(在使用表单时),通过将 Form1.datagridview 控件的名称提供给 ct.View() 方法,您可以获得交叉表/混淆矩阵结果的更具吸引力的输出可视化,如上所示。 任何一种输出都易于复制并粘贴到其他文档中。

关注点

这里几乎没有涉及到巧妙的编程,但是这种工具在我的工作中非常有用,用于可视化使用 C# 进行的 AI 训练和验证的结果。 我希望读者可以直接或通过少量修改和/或添加来满足类似的需求。 例如,如果您只需要交叉表(带正方形或矩形网格),则此方法将执行此操作。 如果您需要其他统计测试(卡方检验、F 比率等),添加它们将很简单。

历史

  • 2017 年 11 月 13 日:原文
  • 2017 年 11 月 18 日:更新
    • 重新设计了 crosstabs.cs 以更正当混淆矩阵为矩形时的错误:例如,如果训练好的模型没有对某些标记值进行任何分类。 将行和列值标签的类型从 List<string> 更改为 Dictionary<int><string>
© . All rights reserved.