基于C#的机器学习--我应该接受这份工做吗-使用决策树

 决策树

       要使决策树完整而有效,它必须包含全部的可能性。事件序列也必须提供,而且是互斥的,这意味着若是一个事件发生,另外一个就不能发生。面试

       决策树是监督机器学习的一种形式,由于咱们必须解释输入和输出应该是什么。有决策节点和叶子。叶子是决策,不论是否是最终决策,节点是决策分裂发生的地方。算法

       虽然有不少算法可供咱们使用,但咱们将使用迭代二分法(ID3)算法。数据库

在每一个递归步骤中,根据一个标准(信息增益、增益比等)选择对咱们正在处理的输入集进行最佳分类的属性。数组

这里必须指出的是,不管咱们使用什么算法,都不能保证生成尽量小的树。由于这直接影响到算法的性能。网络

请记住,对于决策树,学习仅仅基于启发式,而不是真正的优化标准。让咱们用一个例子来进一步解释这一点。框架

下面的示例来自http://jmlr.csail.mit.edu/papers/volume8/esmeir07a/esmeir07a.pdf,它演示了XOR学习概念,咱们全部的开发人员都(或应该)熟悉这个概念。稍后的例子中也会出现这种状况,但如今a3和a4与咱们要解决的问题彻底无关。它们对咱们的答案没有影响。也就是说,ID3算法将选择其中一个构建树,事实上,它将使用a4做为根节点!记住,这是算法的启发式学习,而不是优化结果:机器学习

但愿这张图能让你们更容易理解刚刚所说的内容。咱们的目标并非深刻研究决策树机制和理论。而是如何使用它,尽管存在不少问题,但决策树仍然是许多算法的基础,尤为是那些须要对结果进行人工描述的算法。这也是咱们前面试试人脸检测算法的基础。ide

     决策节点

决策树的一个节点。每一个节点可能有关联的子节点,也可能没有关联的子节点工具

     决策的变量

       此对象定义树和节点能够处理的每一个决策变量的性质。值能够是范围,连续的,也能够是离散的。性能

     决策分支节点的集合

       此集合包含将一个或多个决策节点组,以及关于决策变量的附加信息,以便进行比较。

       下面是一个用于肯定金融风险的决策树示例。咱们只须要在节点之间导航,就能够很容易地跟随它,决定要走哪条路,直到获得最终的答案。在这种状况下,当有人正在申请贷款,而咱们须要对他们的信用价值作出决定。这时决策树就是解决这个问题的一个很好的方法:

我应该接受这份工做吗?

       你刚刚获得一份新工做,你须要决定是否接受它。有一些重要的事情须要考虑,因此咱们将它们做为输入变量或特性,用于决策树。

对你来讲最重要的是:薪水、福利、公司文化,固然还有,我能在家工做吗?

咱们将建立一个内存数据库并以这种方式添加特性,而不是从磁盘存储中加载数据。咱们将建立DataTable并建立列,以下图所示:

在这以后,咱们将加载几行数据,每一行都有一组不一样的特性,最后一列应该是Yes或No,做为咱们的最终决定:

一旦全部的数据都建立好并放入表中,咱们就须要将以前的特性转换成计算机可以理解的表示形式。

因为数字更简单,咱们将经过一个称为编码的过程将咱们的特性(类别)转换为一本代码本。该代码本有效地将每一个值转换为整数。

注意,咱们将传递咱们的数据类别做为输入:

 

接下来,咱们须要为决策树建立要使用的决策变量。

这棵树会帮助咱们决定是否接受新的工做邀请。对于这个决策,将有几类输入,咱们将在决策变量数组中指定它们,以及两个可能的决策,是或者否。

DecisionVariable数组将保存每一个类别的名称以及该类别可能的属性的总数。例如,薪水类别有三个可能的值,高、平均或低。咱们指定类别名和数字3。而后,除了最后一个类别(即咱们的决定)以外,咱们对全部其余类别都重复这个步骤:

如今咱们已经建立了决策树,咱们必须教它如何解决咱们要解决的问题。为了作到这一点,咱们必须为这棵树建立一个学习算法。因为咱们只有这个示例的分类值,因此ID3算法是最简单的选择。

 

一旦学习算法被运行,它就会被训练并可供使用。咱们简单地为算法提供一个样本数据集,这样它就能够给咱们一个答案。在这种状况下,薪水不错,公司文化不错,福利也不错,我能够在家工做。若是正确地训练决策树,答案将会是是:

Numl

numl是一个很是著名的开源机器学习工具包。与大多数机器学习框架同样,它的许多示例也使用Iris数据集,包括咱们将用于决策树的那个。

下面是咱们的numl输出的一个例子:

让咱们看一下这个例子背后的代码:

        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            var description = Descriptor.Create<Iris>();
            Console.WriteLine(description);
            var generator = new DecisionTreeGenerator();
            var data = Iris.Load();
            var model = generator.Generate(description, data);
            Console.WriteLine("生成的模型:");
            Console.WriteLine(model);
            Console.ReadKey();
        }

这个方法并不复杂,对吧?这就是在应用程序中使用numl的好处;它很是容易使用和集成。

上述代码建立描述符和DecisionTreeGenerator,加载Iris数据集,而后生成模型。这里只是正在加载的数据的一个示例:

        public static Iris[] Load()
        {
            return new Iris[]
            {
                new Iris { SepalLength = 5.1m, SepalWidth = 3.5m, PetalLength = 1.4m, PetalWidth = 0.2m, Class = "Iris-setosa" },
                new Iris { SepalLength = 4.9m, SepalWidth = 3m, PetalLength = 1.4m, PetalWidth = 0.2m, Class = "Iris-setosa" },
                new Iris { SepalLength = 4.7m, SepalWidth = 3.2m, PetalLength = 1.3m, PetalWidth = 0.2m, Class = "Iris-setosa" },
                new Iris { SepalLength = 4.6m, SepalWidth = 3.1m, PetalLength = 1.5m, PetalWidth = 0.2m, Class = "Iris-setosa" },
                new Iris { SepalLength = 5m, SepalWidth = 3.6m, PetalLength = 1.4m, PetalWidth = 0.2m, Class = "Iris-setosa" },
                new Iris { SepalLength = 5.4m, SepalWidth = 3.9m, PetalLength = 1.7m, PetalWidth = 0.4m, Class = "Iris-setosa" }
            };
        }

Accord.NET 决策树

Accord.NET framework也有本身的决策树例子。它采用了一种不一样的、更图形化的方法来处理决策树,可是您能够经过调用来决定您喜欢哪一个决策树,而且最习惯使用哪一个决策树。

       一旦数据被加载,您就能够建立决策树并为学习作好准备。您将看到与这里相似的数据图,使用了X和Y两个类别:

下一个选项卡将让您看到树节点、叶子和决策。右边还有一个自顶向下的树的图形视图。最有用的信息在左边的树形视图中,你能够看到节点,它们的值,以及作出的决策:

最后,最后一个选项卡将容许您执行模型测试:

 

代码

下面是学习代码

            // 指定输入变量
            DecisionVariable[] variables =
            {
                new DecisionVariable("x", DecisionVariableKind.Continuous),
                new DecisionVariable("y", DecisionVariableKind.Continuous),
            };
            // 建立C4.5学习算法
            var c45 = new C45Learning(variables);

            // 使用C4.5学习决策树
            tree = c45.Learn(inputs, outputs);

            // 在视图中显示学习树
            decisionTreeView1.TreeSource = tree;

            // 获取每一个变量(X和Y)的范围
            DoubleRange[] ranges = table.GetRange(0);

            // 生成一个笛卡尔坐标系
            double[][] map = Matrix.Mesh(ranges[0], 200, ranges[1], 200);

            // 对笛卡尔坐标系中的每一个点进行分类
            double[,] surface = map.ToMatrix().InsertColumn(tree.Decide(map));
CreateScatterplot(zedGraphControl2, surface);
            //测试
            // 从整个源数据表建立一个矩阵
            double[][] table = (dgvLearningSource.DataSource as DataTable).ToJagged(out columnNames);

            //只获取输入向量值(前两列)
            double[][] inputs = table.GetColumns(0, 1);

            // 获取预期的输出标签(最后一列)
            int[] expected = table.GetColumn(2).ToInt32();


            // 计算实际的树输出
            int[] actual = tree.Decide(inputs);


            // 使用混淆矩阵来计算一些统计数据。
            ConfusionMatrix confusionMatrix = new ConfusionMatrix(actual, expected, 1, 0);
            dgvPerformance.DataSource = new[] { confusionMatrix };

            CreateResultScatterplot(zedGraphControl1, inputs, expected.ToDouble(), actual.ToDouble());

而后他的值被输入一个混淆矩阵。对于不熟悉这一点的同窗,让我简单解释一下.

混淆矩阵

混淆矩阵是用来描述分类模型性能的表。它在已知真值的测试数据集上运行。这就是咱们如何得出以下结论的。

 

真-阳性

在这个例子中,咱们预测是,这是事实。

真-阴性

在这种状况下,咱们预测否,这是事实。

假-阳性

在这种状况下,咱们预测是,但事实并不是如此。有时您可能会看到这被称为type 1错误。

假-阴性

在这种状况下,咱们预测“否”,但事实是“是”。有时您可能会看到这被type 2类错误。

如今,说了这么多,咱们须要谈谈另外两个重要的术语,精确度和回忆。

让咱们这样来描述它们。在过去的一个星期里,天天都下雨。这是7天中的7天。很简单。一周后,你被问到上周多久下一次雨?

回忆

它是你正确回忆下雨的天数与正确事件总数的比值。若是你说下了7天雨,那就是100%。若是你说下了四天雨,那么57%的人记得。在这种状况下,它的意思是你的回忆不是那么精确,因此咱们有精确度来识别。

精确度

它是你正确回忆将要下雨的次数与那一周总天数的比值。

对咱们来讲,若是咱们的机器学习算法擅长回忆,并不必定意味着它擅长精确。有道理吗?这就涉及到其余的事情,好比F1的分数,咱们会留到之后再讲。

可视化错误类型

如下是一些可能会有帮助的可视化:

识别真阳性和假阴性:

使用混淆矩阵计算统计量后,建立散点图,识别出全部内容:

总结

在这一章中,咱们花了不少时间来研究决策树;它们是什么,咱们如何使用它们,以及它们如何使咱们在应用程序中受益。在下一章中,咱们将进入深度信念网络(DBNs)的世界,它们是什么,以及咱们如何使用它们。

咱们甚至会谈论一下计算机的梦,当它作梦的时候!

相关文章
相关标签/搜索