计算python中的分类变量和连续变量的条件概率? P(类别|连续)

时间:2018-08-29 11:30:23

标签: python machine-learning statistics classification probability

我有一个数据集,该数据集具有一个类别和多个连续变量,如下所示:

A     B     C
2.0  1.0   foo
2.2  1.2   bar
1.0  1.5   foo

我想计算:

Pr(C='foo'| A=2.0) # column A
Pr(C='foo'| A=1.0) # column A
Pr(C='bar'| A=2.2) # column A
Pr(C='foo'| B=1.0) # column B
Pr(C='bar'| B=1.2) # column B

解决这个问题的正确方法是什么?将A和B中的值放在方括号中或对A和B中的每个随机变量进行计算是否有效?谢谢!

2 个答案:

答案 0 :(得分:2)

  1. A,B是数字变量,仅从表中计算条件概率(将其视为总体)

让我们假设A,B只能具有所提供表中的值,并以下面的示例概率表为例,该表具有更多行(以便更好地理解):

import pandas as pd
df = pd.read_csv('prob.txt', sep=' ') # let the dataframe df store the probability table 
df

# the probability table 
     A   B   C
0   2.0 1.0 foo
1   2.2 1.2 bar
2   1.0 1.5 foo
3   2.0 3.0 bar
4   2.0 2.0 foo
5   3.2 1.2 foo

现在,回顾两个事件X,Y的条件概率的定义,其中P(Y)!= 0:

enter image description here

因此,我们有

# Pr(C='foo'| A=2.0) = Pr(C='foo' & A=2.0) / Pr(A=2.0)

df[(df.C=='foo') & (df.A==2.0)] # Pr(C='foo' & A=2.0), we have 2 such rows
#    A   B   C
# 0 2.0 1.0 foo
# 4 2.0 2.0 foo

df[(df.A==2.0)]    # Pr(A=2.0), we have 3 such rows 
#    A   B   C
# 0 2.0 1.0 foo
# 3 2.0 3.0 bar
# 4 2.0 2.0 foo

# the required probability Pr(C='foo'| A=2.0)
df[(df.C=='foo') & (df.A==2.0)].shape[0] / df[(df.A==2.0)].shape[0]  # 2 / 3
# 0.6666666666666666   

同样,我们也可以计算其他条件概率。

  1. 将表视为具有A,B(连续)预测变量的样本训练数据集进行分类,以预测Pr(C | A,B)

现在让我们假设该表从总体中提供了一些(随机)连续变量A,B的采样值,并且您想拟合一个分类器来预测C类的概率(“ foo”或“ bar” '),根据给定的数据(变量A,B的可见/不可见值),在这种情况下,您可以适合库scikit-learn中的任何分类器,而不必自己实现。例如,在这种情况下,最简单的一个可能是Naive Bayesian,尽管它假定给定类别(P(A,B | C)= P(A | C)P(B | C) )。

假设您拥有的数据集df如下所示(我在其中综合生成了数据集,则可以在此处使用自己的数据集)

import pandas as pd
# load your data in dataframe df here
df.head()
#        A         B      C
# 0.161729  0.814335    foo
# 0.862661  0.517964    foo
# 0.814303  0.337391    foo
# 1.898132  1.530963    bar
# 2.124829  0.289176    bar

from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
X, y = df[['A','B']], df['C']

# fit the classifier on the training dataset
clf.fit(X, y)

# predict the Pr(C = 'bar' | A, B) with predict_proba() 
print(clf.predict_proba([[1,1]])[:,0])   # Pr(C='bar'|A=1.0, B=1.0)
# [ 0.86871233]

import matplotlib.pylab as plt
X1, X2 = np.meshgrid(np.linspace(X[['A']].min(), X[['A']].max(),10), np.linspace(X[['B']].min(), X[['B']].max(),10))
plt.figure(figsize=(10,6))
# plot the probability surface
plt.contourf(X1, X2, clf.predict_proba(np.c_[X1.ravel(), X2.ravel()])[:,0].reshape(X1.shape), cmap='jet', alpha=.8)
plt.colorbar()
cols = {'foo':'green', 'bar':'red'}
plt.scatter(X[['A']], X[['B']], c=[cols[c] for c in y.tolist()], s=50)
plt.show()

颜色条显示了给定A和B值(图中的x,y轴)时C ='bar'的概率如何变化。原始数据点还用绿色和红色色点绘制(分别具有“ foo”类和“ bar”类)。

enter image description here

如果条件独立性对于您来说太过强大,那么您可以尝试适应

  • 贝叶斯分类器:线性/二次判别分析分类器(假设两个高斯,一个用于Pr(A,B | C ='foo'),另一个用于Pr(A,B | C ='bar'),具有相同/不同的协方差矩阵并使用MLE / MAP从数据中获取类条件概率的高斯参数,然后使用贝叶斯定理计算后验概率P(C | A,B),对于一维高斯参数MLE计算this有用)。下图显示了使用MLE拟合类条件分布以及使用LDA分类器拟合决策面的高斯模型。

enter image description here

enter image description here

clf.predict_proba([[1,1]])[:,0]  # Pr(C='bar'|A=1.0, B=1.0)
# [ 0.67028318]
  • SVM,RandomForest,NeuralNet用于更复杂的分类器,并使用拟合的分类器预测概率。下图显示了带有RandomForest classifier的决策面。

enter image description here

clf.predict_proba([[1,1]])[:,0]  # Pr(C='bar'|A=1.0, B=1.0)
# [ 1.0]

希望这现在可以正确回答您的问题。

答案 1 :(得分:0)

我认为,如果应用基本概率概念,则更容易解决此问题:

import numpy as np
import pandas as pd

a=np.random.choice([1.1,1.2,1.3,1.4],10)
b=np.random.choice([1.1,1.2,1.3,1.4],10)
c=np.random.choice(['bar','foo'],10)

df=pd.DataFrame({'A':a,'B':b,'C':c})

probs={}
for col in ['A','B']:
    for num in df[col].unique():
        for cat in df['C'].unique():
            tdf=df[df[col]==num]
            N=len(tdf) #total 
            n=len(tdf[tdf['C']==cat]) #occurences
            probs['C:{2}//{0}:{1}'.format(col,num,cat)]=(n/N)

返回

{'C:bar//A:1.4': 0.6666666666666666,
 'C:foo//A:1.4': 0.3333333333333333,
 'C:bar//A:1.3': 0.6666666666666666,
 'C:foo//A:1.3': 0.3333333333333333,
 'C:bar//A:1.1': 0.0,
 'C:foo//A:1.1': 1.0,
 'C:bar//A:1.2': 0.6666666666666666,
 'C:foo//A:1.2': 0.3333333333333333,
 'C:bar//B:1.3': 0.6666666666666666,
 'C:foo//B:1.3': 0.3333333333333333,
 'C:bar//B:1.4': 0.5,
 'C:foo//B:1.4': 0.5,
 'C:bar//B:1.2': 0.6666666666666666,
 'C:foo//B:1.2': 0.3333333333333333}

使用此生成的数据框

     A   B   C
0   1.4 1.3 bar
1   1.3 1.4 bar
2   1.1 1.2 foo
3   1.4 1.4 foo
4   1.2 1.3 bar
5   1.2 1.4 foo
6   1.3 1.3 foo
7   1.4 1.2 bar
8   1.3 1.4 bar
9   1.2 1.2 bar