朴素贝叶斯 恶意言论识别

朴素贝叶斯 恶意言论识别

文章名字起得有点大:happy:,所谓的识别只是简单的对言论进行分类 ->好言论/坏言论

代码

详细代码地址:https://github.com/kai123wen/MachineLearningAlg/tree/master/NaiveBayes

代码有详细注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from numpy import *


# 过滤网站的恶意留言 侮辱性:1 非侮辱性:0
# 创建一个实验样本
def loadDataSet():
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 = [0, 1, 0, 1, 0, 1]
return postingList, classVec


# 创建一个包含在所有文档中出现的不重复词的列表
def createVocabList(dataSet):
vocabSet = set([]) # 创建一个空集
for document in dataSet:
vocabSet = vocabSet | set(document) # 创建两个集合的并集
return list(vocabSet)


# 将文档词条转换成词向量
def setOfWords2Vec(vocabList, inputSet):
returnVec = [0] * len(vocabList) # 创建一个其中所含元素都为0的向量
for word in inputSet:
if word in vocabList:
# returnVec[vocabList.index(word)] = 1 # index函数在字符串里找到字符第一次出现的位置 词集模型
returnVec[vocabList.index(word)] += 1 # 文档的词袋模型 每个单词可以出现多次
else:
print("the word: %s is not in my Vocabulary!" % word)
return returnVec


# 朴素贝叶斯分类器训练函数 从词向量计算概率
def trainNB0(trainMatrix, trainCategory):
numTrainDocs = len(trainMatrix) # 训练的句子的数目
numWords = len(trainMatrix[0]) # 所有词的数目
pAbusive = sum(trainCategory) / float(numTrainDocs) # 正例的数目
p0Num = ones(numWords); # 避免一个概率值为0,最后的乘积也为0
p1Num = ones(numWords); # 用来统计两类数据中,各词的词频
p0Denom = 2.0; # 用于统计0类中的总数
p1Denom = 2.0 # 用于统计1类中的总数
for i in range(numTrainDocs): # 对于每一个句子
if trainCategory[i] == 1:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
# p1Vect = p1Num / p1Denom
# p0Vect = p0Num / p0Denom
p1Vect = log(p1Num / p1Denom) # 在类1中,每个次的发生概率
p0Vect = log(p0Num / p0Denom) # 避免下溢出或者浮点数舍入导致的错误 下溢出是由太多很小的数相乘得到的
return p0Vect, p1Vect, pAbusive


# 朴素贝叶斯分类器
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec) + log(pClass1)
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
if p1 > p0:
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 = trainNB0(array(trainMat), array(listClasses))
testEntry = ['love', 'my', 'dalmation']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))

testEntry = ['stupid', 'garbage']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))


# 调用测试方法----------------------------------------------------------------------
testingNB()

代码中的一些注意事项

词袋模型与词集模型

代码中:

将一个句子(注意不是单词)转化为一个向量,这里有两种选择,词集模型、词袋模型

词袋模型

词袋模型能够把一个句子转化为向量表示,是比较简单直白的一种方法,它不考虑句子中单词的顺序,只考虑词表(vocabulary)中单词在这个句子中的出现次数。下面直接来看一个例子吧(例子直接用wiki上的例子):

“John likes to watch movies, Mary likes movies too”

“John also likes to watch football games”

对于这两个句子,我们要用词袋模型把它转化为向量表示,这两个句子形成的词表(不去停用词)为:

[‘also’, ‘football’, ‘games’, ‘john’, ‘likes’, ‘mary’, ‘movies’, ‘to’, ‘too’, ‘watch’]

因此,它们的向量表示为:
BOW词向量

词集模型

看懂了词袋模型,接下来词集模型就很容易了。词集模型就是只要词集中单词在句子中出现,就标为1

关于这里两个模型的选取,如果侧重于单词出现频次,最好使用词袋模型;如果不考虑,那就简单使用词集模型。

朴素贝叶斯算法与贝叶斯公式之间关系

之前一提及朴素贝叶斯,就想到贝叶斯公式,但是实际中贝叶斯公式和朴素贝叶斯还是点距离的。

贝叶斯公式:

朴素贝叶斯之所以称这为朴素,是因为假设了各个特征是相互独立的,因此假定下公式成立: