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