朴素贝叶斯法的参数估计——极大似然估计及其Python实现

统计学习方法——朴素贝叶斯法原理

1. 朴素贝叶斯法的极大似然估计

朴素贝叶斯法的参数估计——极大似然估计及其Python实现_第1张图片

2. 朴素贝叶斯极大似然学习及分类算法

算法过程:
朴素贝叶斯法的参数估计——极大似然估计及其Python实现_第2张图片

2. Python实现

def priorProbability(labelList): # 计算先验概率
    labelSet = set(labelList)  # 得到类别的值
    labelCountDict = {}   # 利用一个字典来存储训练集中各个类别的实例数
    for label in labelList:
        if label not in labelCountDict:
            labelCountDict[label] = 0
        labelCountDict[label] += 1
    priorProbabilityDict = {}
    for label in labelSet:  # 计算不同的类别对应的先验概率
        priorProbabilityDict[label] = labelCountDict[label]/len(labelList)
    return priorProbabilityDict
def conditionProbability(dataSet,labelList):  # 计算条件概率
    dimNum = len(dataSet[0]) # 得到特征数
    characterVal = [] 
    # 利用一个数组来存储训练数据集中不同特征的不同特征值。
    # 每一个不同特征的特征值都要需要另一个数组来存储,这样 characterVal实际上是一个二维数组
    for i in range(dimNum):
        temp = []
        for j in range(len(dataSet)):
            if dataSet[j][i] not in temp:
                temp.append(dataSet[j][i])
        characterVal.append(temp)
    probability = [] # 数组来存储最后的所有的条件概率
    labelSet = list(set(labelList))
    for dim in range(dimNum): # 学习条件概率,需要计算K*S1*...*Sj个概率
        tempMemories = {} # 对于每一个特征,利用一个字点来存储这个特征所有的取值对应的条件概率
        for val in characterVal[dim]:
            for label in labelSet:
                labelCount = 0 # 记录每一类的个数
                mixCount = 0 # 记录当前特征值为这个数,且类别为这个类别的实例个数
                for i in range(len(labelList)):
                    if labelList[i] == label:
                        labelCount += 1
                        if dataSet[i][dim] == val:
                            mixCount += 1
                tempMemories[str(val) + "|" + str(label)] = mixCount/labelCount
                # key表示哪一个特征值和类别,键表示对应的条件概率
        probability.append(tempMemories) # 计算完一个特征,填充一个
    return probability  # 返回条件概率
def naiveBayes(x,dataSet,labelList):  # 贝叶斯分类
    priorProbabilityDict = priorProbability(labelList)
    probability = conditionProbability(dataSet,labelList)
    bayesProbability = {}  # 计算所有类所对应的后验概率
    labelSet = list(set(labelList))
    for label in labelSet:
        tempProb = priorProbabilityDict[label]
        for dim in range(len(x)):
            tempProb *= probability[dim][str(x[dim])+"|"+str(label)]
        bayesProbability[label] = tempProb
    result = sorted(bayesProbability.items(),key= lambda x:x[1],reverse=True)# 排序
    return result[0][0]# 返回后验概率最大的类
dataSet = ([[1,"s"],[1,"m"],[1,"m"],[1,"s"],[1,"s"],[2,"s"],[2,"m"],[2,"m"],
            [2,"l"],[2,"l"],[3,"l"],[3,"m"],[3,"m"],[3,"l"],[3,"l"]])
labelList = [-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1]
print(naiveBayes([2,"s"],dataSet,labelList))
## 返回结果为-1,即归为-1类。
这个实现过程和书上的不太一样,这里每一个特征的取值范围和类的取值范围是根据数据集中的数来进行确定,即每一个特征的取值范围不考虑那些没有出现在训练数据集中的特征值。而书上的算法,每一个特征的取值范围是事先给出的,在这个取值范围中的特征值,可能会出现在训练数据集中,可能不出现。但在估计先验概率和条件概率的时候,过程是一样的。这是这个实现过程的一个不足。

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