1. 程式人生 > >基於C#的機器學習--貝葉斯定理-執行資料分析解決肇事逃逸之謎

基於C#的機器學習--貝葉斯定理-執行資料分析解決肇事逃逸之謎

貝葉斯定理-執行資料分析解決肇事逃逸之謎

在這一章中,我們將:

  1. 應用著名的貝葉斯定理來解決電腦科學中的一個非常著名的問題。
  2. 向您展示如何使用貝葉斯定理和樸素貝葉斯來繪製資料,從真值表中發現異常值等等

貝葉斯定理概況

       當我們使用貝葉斯定理的時候,我們是在測量一件事發生的概論程度:

   上式表示在給定事件B的情況下事件A發生的概率。

       概率通常被量化為0和1之間的一個數,包括這兩者;0表示不可能,1表示絕對肯定。概率越大,確定性越大。擲骰子得到6的概率和擲硬幣得到正面的概率這兩個例子你們肯定很熟悉。還有另一個你們每天都熟悉和遇到的例子:垃圾郵件。

       我們所有人通常一整天都在開啟電子郵件(有些人甚至整夜都在開啟!)伴隨著我們所期待的資訊,我們也將迎來那些我們不願意、也不願意接收的資訊。我們都討厭處理垃圾郵件。我每天收到的郵件中有一封是垃圾郵件的概率是多少?我關心它的內容的概率是多少?我們是怎麼知道的?

       讓我們來談談垃圾郵件過濾器是如何工作的,因為,這可能是我們可以使用的關於概率的最好的例子!

       大多數垃圾郵件過濾器的工作方式(至少在最基本的層次上)是定義一個單詞列表,用於指示我們不想要或不要求接收的電子郵件。如果郵件中包含這些詞,就會被認為是垃圾郵件.

從公式化的角度來看是這樣的:

根據給定的一組單詞,判斷電子郵件是垃圾郵件的概率:維基百科中的使用者Qniemiec有一個令人難以置信的視覺化圖表,該圖表充分解釋了概率檢視的每個組合,該檢視由兩個事件樹的疊加表示。這是一個完整的貝葉斯定理的視覺化,它由兩個事件樹圖的疊加表示:

現在,我們來看一個非常著名的問題。它有很多名字,但最基本的問題是所謂的計程車問題。這是我們的場景,我們將嘗試用概率和貝葉斯定理來解決。

一名Uber司機捲入了一起肇事逃逸事故。著名的黃色計程車和Uber司機是在這個城市運營的兩家公司,隨處可見。我們得到以下資料:

  1. 該市85%的計程車是黃色的,15%是Uber。
  2. 一名目擊者指認了肇事逃逸車輛的身份,並表示車上貼著Uber的貼紙。話雖如此,我們不知道證人的證詞有多可靠,因此法院決定對使用者進行測試並確定其可靠性。最終,法院得出結論,證人在80%的情況下正確識別了兩輛車中的每一輛,但在20%的情況下未能識別。

這是很重要的,所以請注意接下來的內容:

我們的兩難境地是:事故中涉及的車輛是Uber司機還是黃色計程車的概率是多少。

從數學上來說,以下就是我們如何得到我們需要的答案的過程:

  1. 正確識別的Uber司機總數為:

    15*0.8=12

  1. 目擊者有20%的時間是錯誤的,所以錯誤識別的車輛總數是:

    85*0.2=17

  1. 因此,證人確認的車輛總數為12 + 17 = 29。因此,他正確識別Uber司機的概率是

    12/29=41.3%

       現在,讓我們看看是否可以開發一個簡單的程式來幫助我們得出這個數字,以證明我們的解決方案是可行的。為此,我們將深入研究我們的第一個開源工具包:Encog。Encog被設計用來處理這樣的問題。

       Encog框架是一個成熟的機器學習框架,由Jeff Heaton先生開發。希頓先生還出版了幾本關於Encog框架以及其他主題的書籍,如果您打算廣泛使用這個框架,我鼓勵您去尋找它們。

       讓我們看看解決這個問題所需要的程式碼。你會注意到,數學,統計學,概率…這些都是從你那裡抽象出來的。Encog可以讓您專注於您試圖解決的業務問題。             

static void Main(string[] args)

        {

            //建立一個貝葉斯網路

            BayesianNetwork network = new BayesianNetwork();

            //建立肇事逃逸事件

            BayesianEvent UberDriver = network.CreateEvent("肇事逃逸");

            //建立目擊者事件

            BayesianEvent WitnessSawUberDriver =network.CreateEvent("目擊肇事逃逸");

            //把兩個事件關聯起來

            network.CreateDependency(UberDriver, WitnessSawUberDriver);

            //確定結構

            network.FinalizeStructure();

            //建立真值表

            UberDriver?.Table?.AddLine(0.85, true);

            WitnessSawUberDriver?.Table?.AddLine(0.80, true, true);

            WitnessSawUberDriver?.Table?.AddLine(0.20, true, false);

            //初始化貝葉斯網路

            network.Validate();

            Console.WriteLine(network.ToString());

            Console.WriteLine($"引數數量:{ network.CalculateParameterCount()}");

            //列舉查詢

            EnumerationQuery query = new EnumerationQuery(network);

            //證據是有人看見Uber司機撞了車

            query.DefineEventType(WitnessSawUberDriver,EventType.Evidence);

            //結果是Uber司機真這麼做了

            query.DefineEventType(UberDriver, EventType.Outcome);

            query.SetEventValue(WitnessSawUberDriver, false);

            query.SetEventValue(UberDriver, false);

            query.Execute();

            Console.WriteLine(query.ToString());

            Console.ReadKey();

        }

       好,讓我們把它分解成更容易消化的部分。我們要做的第一件事是建立一個貝葉斯網路。這個物體將是解開我們這個謎的核心。貝葉斯網路物件是概率和分類引擎的包裝器。

       貝葉斯網路由一個或多個貝葉斯事件組成。事件將是證據、結果或隱藏的三種不同型別之一,通常對應於訓練資料中的一個數字。事件總是離散的,但是連續值(如果存在並且需要)可以對映到離散值的範圍。

       在建立初始網路物件之後,我們為Uber司機以及聲稱看到肇事逃逸司機的目擊者建立一個事件。我們將在Uber司機和目擊者之間建立一個依賴關係,然後確定我們網路的結構。      

   //建立一個貝葉斯網路

     BayesianNetwork network = new BayesianNetwork();

     //建立肇事逃逸事件

     BayesianEvent UberDriver = network.CreateEvent("肇事逃逸");

     //建立目擊者事件

     BayesianEvent WitnessSawUberDriver =network.CreateEvent("目擊肇事逃逸");

     //把兩個事件關聯起來

     network.CreateDependency(UberDriver, WitnessSawUberDriver);

     //確定結構

     network.FinalizeStructure();

       接下來,我們需要構建實際的真值表。真值表是一個函式可能具有的所有值的列表。有一行或多行復雜度不斷增加,最後一行是最終的函式值。如果你還記得邏輯理論,基本上有三種操作可以使用:NOT, AND和OR。0通常表示false, 1通常表示true。

       如果我們再深入一點,就會發現我們得到了下面的規則

             If A = 0, -A = 1

    If A = 1, -A = 0

    A+B = 1, except when A and B = 0

    A+B = 0 if A and B = 0

    A*B = 0, except when A and B = 1

    A*B = 1 if A and B = 1

         現在,回到我們的程式碼。

         為了構建真值表,我們需要知道概率和結果值。在我們的問題中,Uber司機捲入事故的可能性是85%。至於目擊者,有80%的可能他們說的是真話,有20%的可能他們錯了。我們將使用真值表的AddLine函式新增這些資訊。      

     //建立真值表

     UberDriver?.Table?.AddLine(0.85, true);

     WitnessSawUberDriver?.Table?.AddLine(0.80, true, true);

     WitnessSawUberDriver?.Table?.AddLine(0.20, true, false);

     //初始化貝葉斯網路

     network.Validate();

       這是一個擴充套件真值表,顯示了兩個變數P和Q的所有可能真值函式。

         如果我們要對真值表進行更廣泛的程式設計,下面是一個例子:

    a?.Table?.AddLine(0.5, true); // P(A) = 0.5

    x1?.Table?.AddLine(0.2, true, true); // p(x1|a) = 0.2

    x1?.Table?.AddLine(0.6, true, false);// p(x1|~a) = 0.6

    x2?.Table?.AddLine(0.2, true, true); // p(x2|a) = 0.2

    x2?.Table?.AddLine(0.6, true, false);// p(x2|~a) = 0.6

    x3?.Table?.AddLine(0.2, true, true); // p(x3|a) = 0.2

    x3?.Table?.AddLine(0.6, true, false);// p(x3|~a) = 0.6

         現在我們的網路和真值表已經構建好了,是時候定義一些事件了。

如前所述,事件是證據、隱藏或結果的任何一種。隱藏的事件既不是證據也不是結果,但仍然與貝葉斯圖本身有關。我們不會使用隱藏,但我想讓你知道它確實存在。

要解開我們的謎團,我們必須積累證據。在我們的案例中,我們掌握的證據是,目擊者報告稱看到一名Uber司機參與了這起肇事逃逸事件。我們將定義一種事件型別的證據,並將其分配給證人報告的內容。如果結果,是一個優步司機,所以我們會給它分配一個事件型別的結果。

最後,我們必須承認,至少在某些時候,目擊者看到一名優步司機捲入其中的報告是不正確的。因此,我們必須為目擊者沒有看到優步司機和優步司機沒有參與的兩種可能性建立事件值:

    //列舉查詢

     EnumerationQuery query = new EnumerationQuery(network);

     //證據是有人看見Uber司機撞了車

     query.DefineEventType(WitnessSawUberDriver,EventType.Evidence);

     //結果是Uber司機真這麼做了

     query.DefineEventType(UberDriver, EventType.Outcome);

     query.SetEventValue(WitnessSawUberDriver, false);

     query.SetEventValue(UberDriver, false);

     query.Execute();

         注意,我們將要執行的查詢是EnumerationQuery。該物件允許對貝葉斯網路進行概率查詢。這是通過計算隱藏節點的每個組合並使用總概率找到結果來實現的。如果貝葉斯網路很大,效能可能會很差,但幸運的是,它不是。

         最後,我們對貝葉斯網路定義執行查詢並列印結果,正如我們所希望的,是41.3%。

         作為練習,看看現在是否可以使用Encog來解決另一個非常著名的示例。在這個例子中,我們早上醒來發現草是溼的。是下雨了,還是灑水器開著,還是兩者都開了?這是我們的真值表在紙和筆上的樣子:

下雨的概率:

完整真值表:

繪製資料

如前所述,樸素貝葉斯在解決複雜情況方面的效率驚人。雖然在某些情況下,它的效能肯定會優於其他演算法,但它只是應用於您的問題的一個很好的初試演算法。因為與許多其他模型相比,我們只需要非常少的訓練資料。

         在下一個應用程式中,我們將使用奇妙的Accord.NET機器學習框架,它為我們提供了一種工具,我們可以使用該工具輸入資料、檢視繪製的資料,並瞭解假陽性和假陰性。我們將能夠為存在於資料空間中的物件輸入資料,並將它們分類為綠色或藍色。我們將能夠改變這些資料,看看它們是如何分類的,更重要的是,它們是如何視覺化表示的。我們的目標是瞭解新資料到達時屬於哪組;它們不是綠色就是藍色。此外,我們希望跟蹤假陽性和假陰性。樸素貝葉斯會根據資料空間中的資料為我們做這些事。記住,在我們訓練樸素貝葉斯分類器之後,最終目標是它能夠從以前從未見過的資料中識別出新的物件。如果不能,那麼我們需要回到訓練階段。

         我們簡單地討論了真值表,現在是時候回過頭來,在這個定義後面新增一些正式的東西了。更具體地說,我們用一個混淆矩陣來討論。在機器學習中,混淆矩陣(錯誤矩陣或匹配矩陣)是一種表佈局,可以讓您視覺化演算法的效能。每一行表示預測的類例項,而每一列表示實際的類例項。它被稱為混淆矩陣,因為視覺化可以很容易地看出你是否混淆了兩者。

         真值表的抽象檢視是這樣的:

 

X 現在

(X present)

X 預設

(X absent)

 

檢測結果呈陽性

(Test positive)

真陽性

(True positive)

假陽性

(False positive)

陽性總分

(Total positive)

  • 檢測結果呈陰性
  • (Test negative)

假陰性

(False negative)

真陰性

(False negative)

陰性總分

(Total negative)

 

X發生的總分

(Total negative)

X沒發生的總分

(Total negative)

總和

(Grand total)

       對同一個真值表的更直觀的檢視是這樣的:

最後,對於一個真正的混淆矩陣有一個更正式的觀點:

       在機器學習領域,真值表/混淆矩陣允許您直觀地評估演算法的效能。正如您將在下面的應用程式中看到的,每當新增或更改資料時,您將能夠看到是否出現了這些錯誤或負面條件。

       目前,我們將要開始測試的資料在綠色和藍色物件之間平均分配,所以在沒有任何合理的可能性下,任何新的情況更有可能是其中一種或者另一種,而不是其他種。這種合理的概率,被稱為先驗概率。先驗概率是基於我們對資料所見的先驗經驗,在很多情況下,這些資訊被用來在結果發生之前預測結果。給定一個先驗概率,我們就會得出一個結論,這個結論就成為我們的後驗概率。

       在我們的案例中:

  1. 綠色物件的先驗概率是綠色物件的總數/資料空間中物件的總數
  2. 藍色物件的先驗概率等於藍色物件的總數/資料空間中物件的總數

讓我們進一步看看發生了什麼。

可以在下面的截圖中看到我們的資料。X和Y列表示資料空間中沿著X和Y軸的座標,G列是一個標籤,表示物件是否為綠色。記住,監督學習應該給出我們想要達到的目標,樸素貝葉斯應該讓我們很容易看出這是否正確。

 

       如果我們使用前面的資料並建立它的散點圖,它將看起來像下面的螢幕截圖。如你所見,資料空間中的所有點都被繪製出來了,那些G列值為0的點被繪製成藍色,而那些值為1的點被繪製成綠色。

       每個資料點在資料空間中的X/Y位置上繪製,用X/Y軸表示:

       但是,當我們向資料空間新增新物件時,樸素貝葉斯分類器無法正確分類,會發生什麼情況呢?我們最終得到了假陰性和假陽性,如下所示:

由於我們只有兩類資料(綠色和藍色),因此我們需要確定如何正確分類這些新資料物件。如您所見,我們有14個新的資料點,顏色編碼顯示它們與x軸和y軸的對齊位置。

現在讓我們以完整的形式檢視應用程式。以下是我的主螢幕截圖。在螢幕左側的Data Samples選項卡下,我們可以看到已經載入了資料空間。在螢幕的右邊,我們可以看到我們有一個散點圖,它可以幫助我們視覺化資料空間。如您所見,所有的資料點都被正確地繪製和著色了。

如果我們看看概率是如何分類和繪製的,你會發現資料幾乎以兩個封閉但重疊的簇的形式出現:

當空間中的一個數據點與另一個不同顏色的資料點重疊時,我們就需要樸素貝葉斯來完成它的工作。

如果切換到模型測試選項卡,就可以看到新增的新資料點。

接下來,讓我們修改已經新增的一些資料點,以顯示任何一個數據點如何變為假陰性或假陽性。請注意,我們在開始這個練習時使用了7個假陰性和7個假陽性。

我們之前所做的資料修改結果如下圖所示。如你所見,我們現在有額外的誤報:

我將把資料的實驗留給您,並繼續您的樸素貝葉斯學習!

總結

在這一章中,我們學習了概率論,貝葉斯定理,樸素貝葉斯定理,以及如何將其應用於實際問題。我們還學習瞭如何開發一種工具來幫助我們測試分類器,並檢視我們的資料是否包含任何假陰性或陽性。

在下一章中,我們將深入探討機器學習的世界,並討論強化學習。

轉載請註明出處:https://www.cnblogs.com/wangzhenyao1994/p/10225616.html 

文章發表的另一個地址:https://blog.csdn.net/wyz19940328/article/details/85863533