准备数据:
#
# 创建实实验样本,
# 返回值1:词条切割后的文档集合
# 返回值2:一个类别标签的集合
#
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']]
# 1 is abusive(侮辱性文字), 0 not
classVec = [0, 1, 0, 1, 0, 1]
return postingList, classVec
#
# 创建一个包含在所有文档中不重复词的列表,使用set数据类型
#
#
def createVocabList(dataSet):
# 创建一个空的集合
vocabSet = set([])
for document in dataSet:
# 创建2个集合的合并
vocabSet = vocabSet | set(document)
return list(vocabSet)
#
# 参数1:词汇表,参数2:输入的文档
# return:文档向量(向量的每一个元素为1或者0,分别表示词汇表中的单词是否在文档中出现)
#
def setOfWords2Vec(vocabList, inputSet):
# 创建一个所含元素都是0 的向量
returnVec = [0] * len(vocabList)
for word in inputSet:
# 如果输入的文档中的词汇在vocablist中存在就设置为1
if word in vocabList:
returnVec[vocabList.index(word)] = 1
else:
print("the word: %s is not in my Vocabulary!" % word)
return returnVec
训练算法:从词向量计算概率
我们将使用上述公式,对每个类计算该值,然后比较这两个概率值的大小。
首先可以通过类别i (侮辱性留言或非侮辱性留言)中文档数除以总的文档数来计算概率p(ci ) 。接下来计 算p(w |ci ) ,这里就要用到朴素贝叶斯假设。
如果将w展开为一个个独立特征,那么就可以将上述概率写作p(w0 ,w1 ,w2 ..wN |ci ) 。这里假设所有词都互相独立,该假设也称作条件独立性假设, 它意味着可以使用p(w0 |ci )p(w1 |ci )p(w2 |ci )…p(wN |ci ) 来计算上述概率,这就极大地简化了计算的过程。
#
# trainMatrix:文档矩阵(postingList中的每个元素在my Vocabulary中是否出现的情况)
# trainCategory:每篇文章类别标签构成的向量
#
#
def trainNB0(trainMatrix, trainCategory):
# 计算每个类别中的文档个数
numTrainDocs = len(trainMatrix)
# 计算my Vocabulary的个数
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory) / float(numTrainDocs)
# 分母变量是一个元素个数等于词汇表大小的NumPy数组。
# sum(trainCategory)是向量为1的与文档个数总作比较得出pbAusive
# 初始化概率(p0 代表0(正常)词条,p1代表1(侮辱)词条,出现文档中的词条# )
p0Num = zeros(numWords);
p1Num = zeros(numWords) # change to ones()
p0Denom = 0.0;
p1Denom = 0.0 # change to 2.0
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) # change to log()
p0Vect = (p0Num / p0Denom) # change to log()
return p0Vect, p1Vect, pAbusive
看一下使用算法的代码:
# 切割后的文本与标签
listOPosts, listClasses = bayes.loadDataSet()
#创建不重复词表
myVocabList=bayes.createVocabList(listOPosts)
print(myVocabList)
trainMat = []
# postinDoc是每一个词汇的数组
for postinDoc in listOPosts:
#append 中的内容是:输入的文档在词汇表中是否在文档中出现
#同时将向量添加到trainMat中,trainMat的数组中包含了
trainMat.append(bayes.setOfWords2Vec(myVocabList, postinDoc))
print(trainMat)
p0V,p1V,pAb=bayes.trainNB0(trainMat,listClasses)
print("p0V代表了这个词汇出现在正常语句中的频率")
print(p0V)
print("p1V代表了这个词汇出现在侮辱性语句中的频率")
print(p1V)
print(pAb)
-8的位置上是出现频率比较高的侮辱性词汇,就算把例子上内容补充完整了。
测试算法:根据现实情况修改分类器
修改如下内容:
# 修改为ones 和2。0
p0Num = ones(numWords);
p1Num = ones(numWords)
p0Denom = 2.0;
p1Denom = 2.0
# 采用对数
p1Vect = log(p1Num / p1Denom) # change to log()
p0Vect = log(p0Num / p0Denom) # change to log()
#
朴素贝叶斯函数
# vec2Classify:分类向量
# p0Vec:0的概率
# p1Vec 1的概率
# pClass1: 在分类中1的概率
#
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec) + log(pClass1) # element-wise mult
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
if p1 > p0:
return 1
else:
return 0
准备数据:文档词袋模型
如果一个词在文档中出现不止一次,这可能意味着包含该词是否出现在文档中所不能表达的某种信息,这种方法被称为词袋模型 词袋模型 (bag-of-words model)
#
# 词袋模型
# 和原有的模型的差别在于+=1 这一块
# 如果输入的文档中的词汇在vocablist中存在就设置为1,现在是出现就累加,
# 在词集中,每个单词只能出现一次,而在词袋中,可以出现多次
#
def bagOfWords2VecMN(vocabList, inputSet):
returnVec = [0] * len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] += 1
return returnVec
python函数:
sum()
import numpy as np
a = np.array([[[1,2,3,2],[1,2,3,1],[2,3,4,1]],[[1,0,2,0],[2,1,2,0],[2,1,1,1]]])
print(a)
# 可以理解为数组是3维的,得到的结果是2.axis的取值就是这个精确定位某个元素需要经过多少数组的长度
print(a[1][1][2])
# 结果是38
print(a.sum())
#结果是2个矩阵相加
print(sum(a))
参考文章:https://blog.youkuaiyun.com/rifengxxc/article/details/75008427