65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.71/5 (4投票s)

2016年1月29日

CPOL

3分钟阅读

viewsIcon

14669

downloadIcon

134

使用 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
© . All rights reserved.