糖逗 发表于 2020-11-6 22:38:28

python实现朴素贝叶斯

本帖最后由 糖逗 于 2020-11-7 08:54 编辑

参考书籍:《机器学习实战》

import numpy as np

#获得词典
def createVocabList(dataSet):
    vocabSet = set()
    for document in dataSet:
      #求两个集合的全集
      vocabSet = vocabSet | set(document)#按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
    return list(vocabSet)

#将输入根据已有的词典转换为向量
def setOfWords2Vec(vocabList, inputSet):
    returnVec = * len(vocabList)
    for word in inputSet:
      if word in vocabList:
            returnVec = 1
      else:
            print("the word: %s is not in my Vocabulary!" % word)
    return returnVec

def trainNB0(trainMatrix, trainCategory):
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix)
    pAbusive = sum(trainCategory) / float(numTrainDocs)#训练的样本中属于正样本的占比
    p0Num = np.ones(numWords)#为了避免概率连乘时,其中一个概率为0,导致总体成绩为0
    p1Num = np.ones(numWords)
    p0Denom = 2#为了避免概率连乘时,其中一个概率为0,导致总体成绩为0
    p1Denom = 2
    for i in range(numTrainDocs):
      if trainCategory == 1:
            p1Num += trainMatrix
            p1Denom += sum(trainMatrix)
      else:
            p0Num += trainMatrix
            p0Denom += sum(trainMatrix)
    p1Vect = np.log(p1Num / p1Denom)#正分类样本中,某一个单词数占所有正样本单词数的比值
    p0Vect = np.log(p0Num / p0Denom)#防止下溢
    return p0Vect, p1Vect, pAbusive

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + np.log(pClass1)
    p0 = sum(vec2Classify * p0Vec) + np.log(1 - pClass1)
    if p1 > p0:
      return 1
    else:
      return 0
   
def testingNB(testEntry, listOPosts, listClasses):
    myVocabList = createVocabList(listOPosts)#创建词典
    trainMat = []
    for postinDoc in listOPosts:
      trainMat.append(setOfWords2Vec(myVocabList, postinDoc))#将训练数据变为二维矩阵形式
    p0V, p1V, pAb = trainNB0(np.array(trainMat), np.array(listClasses))
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))
    print(testEntry, "classified as:", classifyNB(thisDoc, p0V, p1V, pAb))
   
   
if __name__ == "__main__":
    postingList = [["my", "dog", "has", "flea","problems", "help", "please"],
                   ["maybe", "not", "take", "him", "to", "dog", "park", "stupid"],
                   ["my", "dalmation", "is", "so", "cute", "I", "love", "him"],
                   ["stop", "posting", "stupid", "worthless", "garbage"],
                   ["mr", "licks", "ate", "my", "steak", "how", "to", "stop", "him"],
                   ["quit", "buying", "worthless", "dog", "food", "stupid"]]
    classVec =
    testEntry = ["love", "my", "dalmation"]
    testingNB(testEntry, postingList, classVec)

糖逗 发表于 2020-11-6 22:38:58

{:10_312:}

永恒的蓝色梦想 发表于 2020-11-6 23:08:03

建议把 set([]) 改为 set() 。

#按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
这个是并集吧……只有 int 才是按位或。

糖逗 发表于 2020-11-7 08:55:26

永恒的蓝色梦想 发表于 2020-11-6 23:08
建议把 set([]) 改为 set() 。

#按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。


set已改{:10_281:}谢谢{:10_254:}
另一个问题:
set(["a", "b"]) | set(["a"])
Out: {'a', 'b'}
所以我怎么觉得还是全集呀{:10_250:}

永恒的蓝色梦想 发表于 2020-11-7 11:32:35

糖逗 发表于 2020-11-7 08:55
set已改谢谢
另一个问题:



set 的创建一般不这么写……{"a", "b"} | {"a"}
Out: {'a', 'b'}

这里全集和并集有区别么……

糖逗 发表于 2020-11-7 14:15:11

永恒的蓝色梦想 发表于 2020-11-7 11:32
set 的创建一般不这么写……

这里全集和并集有区别么……

vocabSet就是想根据所有set()里的每个词条,得到一个没有重复的总词条库。

永恒的蓝色梦想 发表于 2020-11-7 17:36:34

糖逗 发表于 2020-11-7 14:15
vocabSet就是想根据所有set()里的每个词条,得到一个没有重复的总词条库。

我是说 | 是并集运算符

糖逗 发表于 2020-11-7 19:47:35

永恒的蓝色梦想 发表于 2020-11-7 17:36
我是说 | 是并集运算符

{"a", "b"} | {"a"}
Out: {'a', 'b'}

如果并集的话,不就返回了 {'a'}了吗{:10_255:}

永恒的蓝色梦想 发表于 2020-11-8 14:18:44

糖逗 发表于 2020-11-7 19:47
{"a", "b"} | {"a"}
Out: {'a', 'b'}



你说的那叫交集{:10_247:}

>>> {"a", "b"} | {"a"}
{'a', 'b'}
>>> {"a", "b"} & {"a"}
{'a'}

糖逗 发表于 2020-11-8 15:24:38

永恒的蓝色梦想 发表于 2020-11-8 14:18
你说的那叫交集

{:10_252:}
页: [1]
查看完整版本: python实现朴素贝叶斯