基於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)的世界,它們是什麼,以及咱們如何使用它們。

咱們甚至會談論一下計算機的夢,當它作夢的時候!

相關文章
相關標籤/搜索