拟合概率模型

最大似然法

from functools import reduce
coin_1 = float(input())     #硬币1正面朝上概率
coin_2 = float(input())     #硬币2正面朝上概率
coin_3 = float(input())     #硬币3正面朝上概率
h = int(input())     #正面朝上次数
t = int(input())     #反面朝上次数
# 实现概率计算
# 输入:w:正面朝上的概率  H:正面朝上的次数  T:反面朝上的次数
# 输出:H+T次抛硬币,H次正面朝上,T次反面朝上的概率值。
def calcu_prob(w,H,T):
    ########## Begin ##########
    # 计算正反面组合数
    f1 = Factorial(H + T) / (Factorial(H) * Factorial(T))
    f2 = (w ** H) * ((1.0 - w) ** T)
    return f1 * f2
    ########## End ##########
# 求正整数x的阶乘
# 输入:正整数x
# 输出:x的阶乘
def Factorial(x):
    return reduce(lambda x, y: x * y, range(1, x + 1))
# 最大似然函数求解
# 输入: 硬币1,2,3正面朝上的概率coin_1,coin_2,coin_3, 正面朝上的次数h, 反面朝上的次数t
# 输出: 打印最大硬币的概率r与最大硬币的编号
def mle(coin_1,coin_2,coin_3,h,t):
    ########## Begin ##########
    # 参考步骤
    # 1. 计算三枚硬币各自的概率,保留三位小数
    # 2. 建立硬币与概率的字典,方便索引
    # 3. 选出最大值
    # 4. 打印最大值
    # 5. 通过字典索引打印硬币编号    
    # 1. 计算三枚硬币各自的概率,保留三位小数
    a = round(calcu_prob(coin_1,h,t),3)
    b = round(calcu_prob(coin_2,h,t),3)
    c = round(calcu_prob(coin_3,h,t),3)
    # 2. 建立a,b,c与字典方便索引
    dict = {a:'coin_1',b:'coin_2',c:'coin_3'}
    # 选出最大值
    r = max(a,b,c)
    print(r)
    print(dict[r])
    ########## End ##########
if __name__ == "__main__":
    # 主函数执行
    mle(coin_1,coin_2,coin_3,h,t)

贝叶斯方法

import numpy as np
# 创建语料库。
# postingList的每一行,代表一个样本数据
# classVec是每个样本数据所对应的标签,0是非恶意留言,1是恶意留言
def loadDataSet():
    postingList = [['I', 'pig', 'has', 'flea', 'problems', 'help', 'please'],
                   ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                   ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                   ['stop', 'posting', 'stupid', 'shit', 'garbage'],
                   ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                   ['quit', 'buying', 'worthless', 'fuck', 'food', 'dick']]
    classVec = [0, 1, 0, 1, 0, 1]
    return postingList, classVec
# 根据vocabList词汇表,将inputSet向量化,向量的每个元素为1或0。
# 输入:
# vocabList就是createVocabList方法最后返回的元素不重复的数组(词汇表)
# inputSet是取的原始数据集里的某一行,比如:['my', 'dog', 'has', 'flea', 'problems', 'help', 'please']
# 输出:词向量returnVec
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0] * len(vocabList)  # 创建一个所有元素都是0的数组,长度和vocabList一样
    for word in inputSet:  # 将词库里的每个元素遍历
        if word in vocabList:  # 如果某个元素在词汇表里
            returnVec[vocabList.index(word)] = 1  # 那就找到该元素在词汇表中的对应索引,并在returnVec里的同样索引位置赋值,值为1
    return returnVec
# 将切分的实验样本词条整理成不重复的此条例列表,也就是词汇表
# 输入: dataSet语料库,即loadDataSet方法里的postingList数据集
# 输出:词汇表
def createVocabList(dataSet):
    vocabSet = set([])  # 先创建一个空的字典(set创建字典,注意字典是不能有重复元素的)
    for document in dataSet:  # 将dataSet的每一行都进行遍历
        vocabSet = vocabSet | set(document)  # set(document)表示取每行的不重复数据,每次迭代后vocabSet返回值类似于:['my','dog','flea',.....]
    #  最终的词汇表应该是
    #{'is', 'mr', 'ate', 'has', 'problems', 'flea', 'cute', 'stop', 
    # 'park', 'pig', 'love', 'fuck', 'I', 'licks', 'maybe', 
    # 'help', 'shit', 'so', 'to', 'worthless', 'stupid', 'steak', 
    # 'buying', 'quit', 'dalmation', 'dick', 'him', 'please', 'take', 
    # 'posting', 'how', 'my', 'food', 'garbage', 'not', 'dog'}
    # 将所有行的不重复数据都进行合并之后,最后得到整个dataSet的不重复的数据集,也就是词汇表并返回。
    return list(vocabSet)
# 贝叶斯分类器训练函数
# 输入: 训练词向量trainMatrix与类别trainCategory
# 输出:
# p1Vect:表示恶意留言出现的概率
# p0Vect:表示非恶意留言出现的概率
# pAbusive:恶意留言文档占总文档的概率(比例)
def trainNB1(trainMatrix, trainCategory):
    numTrainDocs = len(trainMatrix)  # 计算训练的文档数目
    numWords = len(trainMatrix[0])  # 计算每篇文档的词条数
    # 计算恶意留言文档占总文档的概率(比例),请用pAbusive表示
    ########## Begin ##########
    pAbusive = sum(trainCategory) / float(numTrainDocs)
    ########## End ##########
    p0Num = np.ones(numWords);
    p1Num = np.ones(numWords)  # 创建numpy.ones数组,词条出现数初始化为1。
    p0Denom = 2.0
    p1Denom = 2.0  # 分母初始化为2。
    # 对类别标签进行遍历,也就是对[0,1,0,1,0,1]的每个元素进行遍历,0代表非恶意,1代表恶意
    for i in range(numTrainDocs):
        # 如果是恶意的
        if trainCategory[i] == 1:
            # 那就把trainMatrix矩阵中对应的那一行的标签累加到p1Num上,得到频次p1Num。
            # p1Num数组的意思:在整个词条中,第一个词出现的频次为2,第二个词频次为0,以此类推。
            p1Num += trainMatrix[i]
            # 然后,将所有词出现的次数累加到p1Denom上。
            p1Denom += sum(trainMatrix[i])
        # 如果是非恶意的,同样操作,将得到非恶意留言文档的结果。
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    # 最后需要分别计算在恶意留言和非恶意留言中,每个词出现的概率。
    # 请用变量p1Vect表示恶意留言出现的概率,用变量p0Vect表示非恶意留言出现的概率。
    # 注意结果取对数,防止下溢出。
    ########## Begin ##########
    p1Vect = np.log(p1Num / p1Denom)
    p0Vect = np.log(p0Num / p0Denom)
    ########## End ##########
    return p0Vect, p1Vect, pAbusive
# 朴素贝叶斯分类器分类函数
# 输入:
# vec2Classify是待测试的词条
# p0Vec是非恶意留言的条件概率数组
# p1Vec是恶意留言的条件概率数组
# pClass1是文档属于恶意留言的概率
# 输出:0或1。(1代表恶意留言,0代表非恶意留言)
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    # 计算概率。注意计算公式可以省略贝叶斯公式里的分母,因为不管是计算p0还是p1,分母都是一样的,而我们要比较概率的大小,只需要比较分子即可。
    # 计算该文档属于恶意留言的概率,用变量p1表示。
    # 计算该文档属于非恶意留言的概率,用变量p0表示。
    ########## Bengin ##########
    p1 = sum(vec2Classify * p1Vec) + np.log(pClass1)
    p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1)
    ########## End ##########
    if p1 > p0:
        # 如果p1大于p0,说明属于恶意留言的可能性更大,返回1,(1代表恶意留言)。反之,则返回0(代表非恶意留言)。
        return 1
    else:
        return 0
# 测试函数
def testingNB():
    listOPosts, listClasses = loadDataSet()  # 加载语料库
    myVocabList = createVocabList(listOPosts)  # 创建词汇表
    trainMat = []
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))  # 样本向量化
    p0V, p1V, pAb = trainNB1(np.array(trainMat), np.array(listClasses))  # 训练朴素贝叶斯分类器
    # 处理输入。请输入词汇表中的词,多个分词请用英文逗号隔开,否则会不通过。
    testEntry = input()
    testEntry = testEntry.split(',')
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))
    # 执行分类并打印分类结果
    if classifyNB(thisDoc, p0V, p1V, pAb):
        print('1')
    else:
        print('0')
if __name__ == '__main__':
    testingNB()
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值