机器学习之bayes算法

在几位志同道合的小伙伴的带领下,开始了机器学习的路程,然而一切并不是想象的那么简单,因此本文记录了自己的学习路程,希望还能坚持做好这件事。

一个简单的例子,用Python语言实现朴素贝叶斯算法,这里不再介绍算法的理论思想,我会将自己看到的理解的东西写出来做记录,这些可能 是初学者比较困惑的地方。

1.关于连续属性的概率估计

我们针对离散属性的概率估计很好理解,比如说对训练数据中的House统计,很容易得到P(House=Yes|No)=3/7。
但对于Income这一个连续的属性,我们需要使用一点点处理方式来估计他们的概率。

(1)设置区间,比如说划分[120K,>120K),[70K,120K),(<70K,70K)这样子的区间,就可以将连续的属性离散化,但这样做有个很麻烦的问题就是如何才能选取适当的区间,这个问题的解决需要根据个人经验去判断。

(2)另一个估计连续属性的条件概率的方法是通过高斯分布计算。需要计算的有两个参数,均值μ和方差δ²。参数μ可以用标签Y下所有训练记录X样本的均值来估计,δ²可以用这些训练记录的样本方差来估计。

2.训练数据中某个属性的类条件概率等于0

从下面的实例中,我们可以计算得到P(Marriage=Married|Yes)=0,这就导致一个问题,比如我要统计X=(House=No,Marriage=Married,Income=120K)的类标号,我们计算得到的类Yes下的后验概率等于0。即如果某个属性的类条件概率等于0,将会导致整个类的后验概率等于0 。解决方法:

(1)条件概率的m估计(参考数据挖掘导论 Pang-Ning Tang等著)

P(xi|yi)=nc+mpn+m

其中,n是类 yi 中的实例总数, nc 是类 yi 训练集中取值 xi 的样例个数,m为等价样本大小的参数,而p为用户指定的参数
(2)贝叶斯估计
条件概率的贝叶斯估计为:

Pλ(X(j)=ajl|Y=ck)=i=1NI(x(j)i=ajl,yi=ck)+λi=1NI(yi=ck)+Sjλ

λ≥0. 当λ=0的时候,就是极大似然估计,λ=1为拉普拉斯平滑(Laplace smoothing)。

先验概率的贝叶斯估计为:

Pλ(Y=ck)=i=1NI(yi=ck)+λN+Kλ

λ≥0,N为条件( Y=ck )下的样本总数,K为Y的种类数。通常按照拉普拉斯平滑(Laplace smoothing)估计概率,即取 λ=1


训练数据

Tid House   Marriage    Income  Borrower
1   Yes Single  125K    No
2   No  Married 100K    No
3   No  Single  70K No
4   Yes Married 120K    No
5   No  Divorced    95K Yes
6   No  Married 60K No
7   Yes Divorced    220K    No
8   No  Single  85K Yes
9   No  Married 75K No
10  No  Single  90K Yes

测试数据

Tid House   Marriage    Income
Test    No  Married 120K

准备数据

def loadDataSet_train(path_read):
    df = pd.read_csv(path_read, sep='\t', header=0, dtype=str, na_filter=False)
    group = df[['House','Marriage','Income','Borrower']]
    label = df["Borrower"]
    return group

def loadDataSet_test(path_read):
    df = pd.read_csv(path_read, sep='\t', header=0, dtype=str, na_filter=False)
    group = df[['House','Marriage','Income']]
    return group
#calculate mean and variance of the sample,and then return the probability of this Inx
def calculateProbability(Inx,dataSet):
    mean = np.sum(dataSet)/len(dataSet)
    dataSetSize = len(dataSet)
    diffMat = np.tile(mean, (dataSetSize,1)) - dataSet
    variance = np.sum(diffMat ** 2)/(dataSetSize-1)
    probobility = np.exp(-((Inx-mean) ** 2/(2*variance))) * (1/(((2*np.pi)**0.5)*variance**0.5))
    return probobility

训练集分类

#Through the tag classification, generate numpy two-dimensional array
def separateByClassYes(dataset):
    separatedYes = []
    for i in range(len(dataset)):
        vector = dataset[i]
        if (vector[-1] == 'Yes'):
            separatedYes = np.append(separatedYes,np.array(vector),axis=0)
    return separatedYes.reshape(-1,4)

def separateByClassNo(dataset):
    separatedNo = []
    for i in range(len(dataset)):
        vector = dataset[i]
        if (vector[-1] == 'No'):
            separatedNo = np.append(separatedNo,np.array(vector),axis=0)
    return separatedNo.reshape(-1,4)
def trainNB(trainMatrix,testMatrix):
    newtrainMatrix = np.array(trainMatrix[0:,:3])
    numTrain = len(newtrainMatrix)
    calculateArr = np.zeros(newtrainMatrix.shape)
    calculateArr[newtrainMatrix==testMatrix[0][0]]=1
    calculateArr[newtrainMatrix==testMatrix[0][1]]=1
    for i in trainMatrix[:,2]:
        calculateArr[newtrainMatrix==i]=i[0:-1]

    numFirstRank = sum(calculateArr[:,0])
    numSecondRank = sum(calculateArr[:,1])

    firstPrabobility = (numFirstRank+1)/(numTrain+2)
    secondPrabobility = (numSecondRank+1)/(numTrain+2) #Laplace smoothing

    trirdRank = calculateArr[:,2].reshape(-1,1)
    trirdProbobility = calculateProbability(int(testMatrix[0][2]),trirdRank)

    probobility = firstPrabobility*secondPrabobility*trirdProbobility
    # print(probobility)
    return probobility

初学者代码写得很low,在文章中有什么错误的地方还希望大家指正出来,一起交流。

你可能感兴趣的:(机器学习)