使用 C# 运行符号测试
若有需前后對比的數據,且要確定某種效果是否有統計依據,最常使用的是符號檢驗。通過舉例可以很好地解釋這個原理。
假設你在一家制藥公司工作,想要確定一種新型減肥藥是否有效。你找來八名志愿者服用這種減肥藥長達幾周的時間。觀察八名實驗對象在實驗前后的體重變化。假設八名實驗對象中有六名體重下降。有確鑿的統計依據表明這種減肥藥有效嗎?
減肥藥效是一個典型的符號檢驗示例,但此類檢驗也同樣適用于許多 IT 和軟件方案。假設你有 40 臺 Web 服務器計算機,并應用了一個旨在提升性能的軟件修補程序。測量應用此修補程序前后的響應時間。如果 32 臺服務器的性能提升,2 臺服務器的性能沒有變化,6 臺服務器的性能下降,能得出什么結論?
了解本文所述觀點的最佳方式是查看圖 1?中的演示程序。閱讀完本文后,你將非常了解符號檢驗所能解決的問題類型、究竟該如何使用 C# 實現符號檢驗,以及該如何解讀符號檢驗結果。本文展示了演示程序的所有源代碼。還可以從本文隨附的代碼下載中獲取完整的演示程序。
圖 1:使用 C# 實現符號檢驗
演示程序設置了八對需前后對比的數據,旨在確定某減肥養生計劃是否有效。從數據來看,六名實驗對象的體重確實下降,而兩名實驗對象的體重上升。
演示程序計算的“無效”概率為 0.1445。如何解讀此結果完全由你自己決定,例如,“數據表明減肥計劃有效的跡象不充分 (p = 0.8555)。”
閱讀本文的前提是,至少擁有中級編程技能,無需了解符號檢驗。演示代碼用 C# 編寫,依賴于 .NET System.Numerics 命名空間,因為需要使用 Microsoft .NET Framework 4(2010 年發布)或更高版本。
? 演示程序結構 ?
為了創建演示程序,我啟動了 Visual Studio,并從“新建項目”菜單項中選擇了“C# 控制臺應用程序模板”。我將此項目命名為“SignTestUsingCSharp”。在將模板代碼加載到編輯器窗口之后,我右鍵單擊了解決方案資源管理器窗口中的 Program.cs 文件,并將此文件重命名為“SignTestProgram.cs”,然后允許 Visual Studio 為我重命名 Program 類。
接下來,我右鍵單擊了項目名稱,然后選擇了“添加 | 引用”項。在“組件 | 框架”列表中,我選擇了 System.Numerics 命名空間,然后單擊了“確定”,將其添加到我的項目。在編輯器窗口頂部,我刪除了所有 using 語句(引用頂級 System 命名空間的語句除外),然后添加了 using 語句來引用 System.Numerics 命名空間。
圖 2?展示了程序的整體結構。為簡單起見,程序采用的是嚴格意義上的靜態方法,而不是面向對象編程 (OOP) 方法。DoCounts 和 ShowVector 方法是實用工具幫助程序。計算無效概率的工作是由 BinomRightTail 方法完成。BinomProb 和 Choose 方法是 BinomRightTail 的幫助程序。
圖 2:符號檢驗演示程序結構
在顯示幾條介紹信息之后,Main 方法設置并顯示符號檢驗的演示數據:
在數據對超過約 30 個的非演示方案中,你會將數據存儲在文本文件中,并編寫用于讀取和存儲數據的幫助程序方法。使用平行數組是實現符號檢驗時最常用的方法。
接下來,演示使用 DoCounts 方法計算項目對數。如果體重下降,視為“成功項”,如果體重上升,視為“失敗項”:
返回值是一個數組,其中存儲單元 0 保存失敗項數(體重上升),存儲單元 1 保存無變化項數,存儲單元 2 保存成功項數(體重下降)。
在計算機還沒有普及的年代,計數是手動完成的,即在成功項旁邊添加“+”號,在失敗項旁邊添加“-”號。這就是符號檢驗的命名由來。對于演示數據,手動方法如下所示:
請注意,符號檢驗不會考慮體重上升或下降的幅度。接下來,演示準備調用符號檢驗,如下所示:
變量 k 保存成功項數。變量 n 保存數據對總數。在此示例中,體重前后都有變化。在這種情況下,最常用的方法是不考慮無變化項。然而,在某些情況下,可能需要將無變化項添加為成功項或失敗項。
例如,在減肥程序中,體重無變化很有可能會被視為失敗。
Main 方法生成的結果如下:
符號檢驗實際上是更為普遍的二項分布檢驗的具體示例。程序定義的函數 BinomRightTail 接受成功項數、數據對數以及概率值(在此示例中,為 0.5)。當二項分布檢驗使用 0.5 作為概率參數時,就是符號檢驗,我很快就會對此進行介紹。
? 了解 Choose 函數 ?
符號檢驗采用二項分布,此分布反過來使用 Choose 函數。Choose(n, k) 函數返回從 n 個項中選擇 k 個項的方法數。例如,Choose(5, 3) 返回從五個項中選擇三個項時可以采用的方法數。假設這五個項為 (A, B, C, D, E)。從中選擇三個項的方法有 10 種:
Choose 函數的定義為 Choose(n, k) = n! / [k! * (n-k)!],其中“!”字符表示階乘。那么,
實現 Choose 函數比較棘手,因為即使 n 和 k 值適中,返回值也可能會非常大。例如,
為了能夠返回非常大的值(在符號檢驗中可能會發生),演示程序在 System.Numerics 命名空間中使用 BigInteger 類型。Choose 的演示實現運用了兩個數學技巧來提高效率。首先,事實證明,Choose(n, k) = Choose(n, n-k)。例如,
使用較小的 k 值,可以減少計算量。其次,Choose 還有另一種定義,以下示例最能解釋:
也就是說,分母就是 k!,分子直接使用 n! 公式的前 k 項,很多項抵消掉了。綜上,圖 3?展示了 Choose 的演示實現。
圖 3:Choose 函數
??了解二項分布 ?
了解如何實現和解讀符號檢驗的關鍵是了解二項分布。通過示例最能對此進行解釋。
假設你有一個有偏硬幣設計,投擲硬幣出現正面的概率是 0.6,出現反面的概率是 0.4,并將出現正面定義為成功。如果投擲硬幣 n = 8 次,二項分布為 n 個試驗中恰好有 k 次成功的概率分布,其中每次試驗的成功概率為 p(在此示例中為 0.6)。
在八次投擲中恰好出現八次正面和零次反面的概率就是連續出現八次正面的概率,即:
若要在八次投擲中恰好出現七次正面,可以在任意八次投擲中出現七次正面和一次反面。有八種組合:
下面是在 n 個試驗中恰好有 k 次成功的概率的常規公式,其中 p 是每次試驗的成功概率:
在符號檢驗中,p 始終是 0.5,所以 1-p 也始終是 0.5,公式就簡化為:
因此,對于演示數據,存在 n = 8 個試驗(數據對)和 k = 6 次成功(體重下降),所以恰好六次成功的概率是:
圖 4?展示了在八次試驗中當 p = 0.5 時恰好零到八次成功對應的概率圖。
實現返回二項分布概率的函數很簡單:
圖 4:n = 8 和 p = 0.5 時的二項分布
演示定義了接受 p 作為參數的通用二項函數。另一種做法是,定義一個假設 p = 0.5 的版本并簡化計算,如前所述。演示不含錯誤檢查功能。例如,在生產環境中,可能需要確保 k <= n;k 和 n 都不是負數;p 介于 0.0 到 1.0 之間。
? 實現符號檢驗??
符號檢驗旨在計算無效概率。從概念上講,這意味著前后值之間的任何差異純粹是偶然。從數學上講,這意味著上升或下降的概率為 0.5。
符號檢驗假設無效,然后計算在此假設下本該發生的成功項觀測數的概率。對于八次試驗中有六次成功(體重下降)的演示數據示例,計算的不是你可能會猜到的恰好六次成功的概率,而是六次以上成功的概率。這種思路相當微妙。
計算 k 次以上成功的概率有時被稱為右尾檢驗。因此,若要實現符號檢驗,需要計算 k 次以上成功的概率,方法為計算恰好 k 次成功外加 K+1 次成功、K+2 次成功(依此類推)的概率。演示實現如下所示:
完成符號檢驗只需用于統計成功次數和顯示值的可選函數。演示將計數方法定義為:
幫助程序顯示方法為:
另一種設計是將成功失敗計數與二項計算合并為一個更大的元方法。
? 總結??
應務必謹慎解讀符號檢驗的結果。最好解讀為“符號檢驗表明有效”,而不是“有效”。
示例問題被稱為單側或單尾檢驗。因為此示例涉及的是減肥實驗,所以體重下降(成功項數)大于偶然值視為有效。
還可以執行雙側(亦稱為“雙尾”)符號檢驗。例如,假設要做的是某種止痛藥的實驗。在實驗過程中,稱量檢驗對象的實驗前后體重。沒有理由相信止痛藥會影響體重。換句話說,體重下降或上升都可以視為有效。
符號檢驗最棘手的地方是要確保定義明確。由于每個問題都存在多重對稱性,因此可能會產生混淆。可以將成功定義為后值增加或減少。
例如,在減肥示例中,將后值減少定義為成功。不過,如果數據表示的是學習前后某類考試的成績,很可能會將后值增加定義為成功。
符號檢驗就是所謂的非參數統計檢驗示例。也就是說,在某種程度上,符號檢驗不對研究的數據分布作任何假設。可以使用所謂的配對 t 檢驗來取代符號檢驗。
然而,t 檢驗假設總體數據呈正態分布(高斯分布、鐘形分布),用小數據集進行驗證幾乎是不可能的。正因為如此,我通常會在要調查需前后對比的數據時使用符號檢驗,而不是配對 t 檢驗。
Dr.James McCaffrey?供職于華盛頓地區雷蒙德市沃什灣的 Microsoft Research。他參與過多個 Microsoft 產品的工作,包括 Internet Explorer 和 Bing。Scripto可通過?jammc@microsoft.com?與 McCaffrey 取得聯系。
衷心感謝 Microsoft 技術專家對本文的審閱:?Chris Lee?和?Kirk Olynyk
原文地址:https://msdn.microsoft.com/zh-cn/magazine/mt793273
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的使用 C# 运行符号测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 强势解析 eBay BASE 模式、去哪
- 下一篇: 编写高效率的C#代码