使用 C# 中的 MongoDB 聚合框架计算基于贝叶斯定理的相关事件的概率






2.71/5 (4投票s)
使用 C# 中的 MongoDB 聚合框架计算基于贝叶斯定理的相关事件的概率
引言
MongoDb 聚合框架有助于分析调查数据。对调查数据进行的最常见的分析之一是计算事件的依赖概率。本文通过一个例子,演示了如何使用贝叶斯定理计算依赖事件的概率。
背景
贝叶斯定理在数学上表示为以下方程
P(A|X) = [P(X|A) P(A)]/P(X) = [P(X|A) P(A)] / [P(X|A) P(A) + P(X | ~A) P(~A)]
其中 A
和 X
是 事件。
P
(A
) 和P
(X
) 是 概率,它们彼此不相关。P
(A
|X
),一个 条件概率,是指在X
为true
的情况下观察到事件A
的概率。P
(X
|A
) 是在A
为true
的情况下观察到事件X
的概率。
假设我们想知道在检测结果呈阳性时患乳腺癌的概率。
即, A
= 患乳腺癌的事件
X
= 检测呈阳性的事件
Using the Code
假设我们已经对 200 名志愿者进行了检测,其中一些人患有已有的疾病。我们将记录保存在 MongoDB 数据库中,如下所示:
{ "_id" : ObjectId("56a92adab2326d187c099531"), "patientName" : "cxb yyy", _
"mammogramResult" : 0, "diagnosedBefore" : 0 }
{ "_id" : ObjectId("56a92adab2326d187c09953d"), "patientName" : "pxx yyy", _
"mammogramResult" : 0, "diagnosedBefore" : 1 }
{ "_id" : ObjectId("56a92adab2326d187c099540"), "patientName" : "sxx yyy", _
"mammogramResult" : 1, "diagnosedBefore" : 0 }
{ "_id" : ObjectId("56a92adab2326d187c09953d"), "patientName" : "pxx yyy", _
"mammogramResult" : 0, "diagnosedBefore" : 1 }
{ "_id" : ObjectId("56aa4cda358f09b19d447bab"), "patientName" : "fxx rrr", _
"mammogramResult" : 1, "diagnosedBefore" : 1 }
根据设备制造商的规格,假设乳腺 X 光检查具有以下属性:
- 80% 的乳腺 X 光检查能够检测出患有乳腺癌的患者(因此 20% 的会漏诊)。
- 9.6% 的乳腺 X 光检查在没有患乳腺癌的情况下会检测出阳性(因此 90.4% 会正确返回阴性结果)。
我们想知道在 乳腺 X 光检查结果呈阳性
的情况下患乳腺癌的概率。
设
A
:患乳腺癌的事件X
:乳腺 X 光检查结果呈阳性的事件P(X)
是乳腺 X 光检查呈阳性结果的概率P(A)
是患乳腺癌的概率P(A | X)
是检测结果呈阳性时患乳腺癌的概率P(X | A)
是你患有乳腺癌时检测结果呈阳性的概率
根据给定的乳腺 X 光检查规格,我们可以得到以下数字:
- 乳腺 X 光检查真阳性结果 = 80%
- 乳腺 X 光检查假阳性结果 = 20%
- 乳腺 X 光检查真阴性结果 = 94%
- 乳腺 X 光检查假阴性结果 = 9.6%
让我们聚合 survey 集合中的示例数据(数据库名为 bayesdb
)。
var connectionString = "mongodb://:27017";
var client = new MongoClient(connectionString);
var db = client.GetDatabase("bayesdb");
var col = db.GetCollection<BsonDocument>("survey");
var surveyList = await col.Find(new BsonDocument()).ToListAsync();
Console.Write("Count of collected survey: {0}", surveyList.Count());
var totalSurveyCount = surveyList.Count();
确定接受检测的人中有多少人患有乳腺癌。为了找出调查数据中检测呈阳性和阴性的人数,我们使用对 mammogramResult
进行聚合。
var previousDiagnosis = col.Aggregate()
.Group(new BsonDocument { { "_id", "$diagnosedBefore" }
, { "count", new BsonDocument("$sum", 1) } });
var results = await previousDiagnosis.ToListAsync();
var mammogramTestResults = await col.Aggregate()
.Group(new BsonDocument { { "_id", "$mammogramResult" }
, { "count", new BsonDocument("$sum", 1) } }).ToListAsync();
根据调查数据,我们计算以下参数:
P(A)
:患乳腺癌的概率
//Pr(A) is the probability of having cancer => cancerExistingConditionsCount/totalCount = ~ 1%
var PreviousDiagnosisPositive = previousDiagnosis.First();
int PositiveCount = (int)PreviousDiagnosisPositive["count"];
double PrA = (double)PositiveCount / totalSurveyCount;
P(~A)
:不患乳腺癌的概率 = 1-P(A)
//Pr(A) is the probability of having cancer => cancerExistingConditionsCount/totalCount = ~ 1%
var PreviousDiagnosisPositive = previousDiagnosis.First();
int PositiveCount = (int)PreviousDiagnosisPositive["count"];
double PrA = (double)PositiveCount / totalSurveyCount;
P(X|A)
:从患有乳腺癌的患者中获得阳性结果的概率
var PrXA = mammogramConstants.mammogramTP * PrA;
struct mammogramConstants
包含所有必需的常量。
public struct mammogramConstants
{
public const double mammogramTP = 0.800;
public const double mammogramFN = 0.200;
public const double mammogramFP = 0.096;
public const double mammogramTN = 0.904;
}
P(X | ~A)
:从没有患乳腺癌的患者中获得阳性结果的概率(假阳性概率)
var PrXnA = mammogramConstants.mammogramFP * PrnA;
P(X)
:获得任何阳性结果的概率(真阳性 + 假阳性)
即,P(X) = P(X | A) + P(X | ~A)
var PrX = PrXA + PrXnA;
最后
P(A|X)
:检测结果呈阳性时患乳腺癌的概率
var PrAX = (double)(mammogramConstants.mammogramTP * PrA) / PrX;
显示结果
Console.WriteLine("Based on the given survey data, we can see that having a positive result means:");
Console.WriteLine("you are {0: 0.00}% likely of having a cancer.", PrAX * 100);
关注点
尽管我们的乳腺 X 光检查规格表明,在检测结果呈阳性的情况下患乳腺癌的几率为 80%,但根据贝叶斯定理和 survey 集合中的数据,我们可以看到,阳性结果意味着患乳腺癌的几率仅为 ~7.76%。
历史
- 版本 2.0