机器学习---朴素贝叶斯分类器的实现(对文本进行侮辱性言论和非侮辱性言论的分类)

1. loadDataSet函数

import numpy as np

# 构造loadDataSet函数用于生成实验样本
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] #1表示侮辱性言论,0表示正常言论
    return postingList,classVec

简单的数据加载函数,用于生成一个实验样本。函数 loadDataSet 返回两个列表,postingList 包含

了一些文本数据,classVec 包含了这些文本数据对应的类别标签。postingList 包含了6个子列表,

每个子列表代表一条文本数据,而 classVec 包含了这些文本数据对应的类别标签,其中1表示侮辱

性言论,0表示正常言论。

2. 词汇表生成函数creatVocabList

#构建词汇表生成函数creatVocabList
def createVocabList(dataSet):
    vocabSet=set([]) # 1 1 1 1 和1 1
    for document in dataSet:
        vocabSet=vocabSet|set(document) #取两个集合的并集
    return list(vocabSet)

函数首先创建了一个空集合 vocabSet,然后遍历输入的文本数据集 dataSet 中的每个文档

document。对于每个文档,它将文档中的单词转换为集合,并将这个集合与 vocabSet 取并集,这

样就能逐步地将所有文档中出现的单词整合到 vocabSet 中。最后,函数将 vocabSet 转换为列表

并返回,这样就得到了整个文本数据集中出现的所有单词构成的词汇表。

3. 词集模型setOfWords2Vec

#词集模型
def setOfWords2Vec(vocabList,inputSet):
    returnVec=np.zeros(len(vocabList)) #生成零向量的array
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)]=1 #有单词,则该位置填充0
        else: print('the word:%s is not in my Vocabulary!'% word)
    return returnVec #返回全为0和1的向量

函数接受两个参数,vocabList 是词汇表,inputSet 是待转换的文本数据。首先,函数创建了一个

长度为词汇表长度的全零数组 returnVec,用于存储文本数据的词向量。然后,函数遍历输入的文

本数据 inputSet 中的每个单词 word,如果这个单词在词汇表 vocabList 中,就将 returnVec 中对

应位置的值设为1,表示该单词在文本数据中出现了。如果单词不在词汇表中,就打印一条警告信

息。最后,函数返回生成的词向量 returnVec,它是一个由0和1组成的向量,表示了文本数据中每

个单词在词汇表中的出现情况。这种词集模型的词向量表示方法只记录了每个词是否出现,不考虑

词出现的次数。

4. 词袋模型

#词袋模型
def bagOfWords2VecMN(vocabList,inputSet):
    returnVec=[0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)]+=1
    return returnVec #返回非负整数的词向量

函数接受两个参数,vocabList 是词汇表,inputSet 是待转换的文本数据。首先,函数创建了一个

长度为词汇表长度的全零列表 returnVec,用于存储文本数据的词向量。然后,函数遍历输入的文

本数据 inputSet 中的每个单词 word,如果这个单词在词汇表 vocabList 中,就将 returnVec 中对

应位置的值加1,表示该单词在文本数据中出现了一次。如果单词不在词汇表中,则忽略。最后,

函数返回生成的词袋模型的词向量 returnVec,它是一个由非负整数组成的向量,表示了文本数据

中每个单词在词汇表中的出现次数。

listPosts,listClasses=loadDataSet()
myVocabList=createVocabList(listPosts)
print(myVocabList) # 输出词表
returnVec = setOfWords2Vec(myVocabList, listPosts[0])
print(returnVec) # 对输入的词汇表构建词向量,使用词集模型
returnVec = bagOfWords2VecMN(myVocabList, listPosts[0])
print(returnVec) # 对输入的词汇表构建词向量,使用词袋模型

5. 运用词向量计算概率trainNB1

# 运用词向量计算概率
def trainNB1(trainMatrix,trainCategory):
    numTrainDocs=len(trainMatrix)
    numWord=len(trainMatrix[0])
    pAbusive=sum(trainCategory)/len(trainCategory) # 3/6
    p0Num=np.ones(numWord);p1Num=np.ones(numWord)# 初始化为1
    p0Demon=2;p1Demon=2 #初始化为2
    for i in range(numTrainDocs):
        if trainCategory[i]==0:
            p0Num+=trainMatrix[i]
            p0Demon+=sum(trainMatrix[i])
        else:
            p1Num+=trainMatrix[i]
            p1Demon+=sum(trainMatrix[i])
    p0Vec=np.log(p0Num/p0Demon) #对结果求自然对数
    p1Vec=np.log(p1Num/p1Demon) #对结果求自然对数
    return p0Vec,p1Vec,pAbusive

首先,我们统计了训练集中的文档数目 numTrainDocs 和词汇表的长度 numWord。然后,我们计

算了侮辱性言论的概率 pAbusive,即侮辱性言论所占的比例。接下来,我们初始化了两个向量

p0Num 和 p1Num,它们的长度都是词汇表的长度,并且将所有元素初始化为1。同时,我们初始

化了两个变量 p0Demon 和 p1Demon,它们的初始值都是2。然后,我们遍历训练集中的每个文

档,统计了属于侮辱性言论和非侮辱性言论的词向量分别出现的次数,并分别累加到 p0Num 和

p1Num 中,同时也统计了属于侮辱性言论和非侮辱性言论的词向量总数,并分别累加到 p0Demon

和 p1Demon 中。最后,我们计算了属于非侮辱性言论和侮辱性言论的条件概率向量 p0Vec 和

p1Vec,并对结果取了自然对数。最终,函数返回了 p0Vec、p1Vec 和 pAbusive,它们分别表示

了属于非侮辱性言论的条件概率向量、属于侮辱性言论的条件概率向量和侮辱性言论的先验概率。

6. 构建分类函数classifyNB 

# 计算文档在各类中的概率,取较大者作为该文档的分类,所以构建分类函数classifyNB
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
    # 说明: p1=sum(vec2Classify*p1Vec)+log(pClass1) 的数学原理是ln(a*b)=ln(a) +ln(b)
    p1=sum(vec2Classify*p1Vec)+np.log(pClass1) 
    p0=sum(vec2Classify*p0Vec)+np.log(1-pClass1)
    if p1>p0:
        return 1
    else:
        return 0

首先,代码计算了给定文档向量属于侮辱性言论的概率 p1,这里使用了朴素贝叶斯分类器的数学

原理,通过求取对数的方式将连乘转换为累加,避免了浮点数下溢问题。接着,代码计算了给定文

档向量属于非侮辱性言论的概率 p0,同样使用了对数的方式进行计算。最后,代码比较了 p1 和

p0 的大小,如果 p1 大于 p0,则返回1,表示文档属于侮辱性言论;否则返回0,表示文档属于非

侮辱性言论。

贝叶斯定理:

7. 测试分类函数testingNB 

# 构造几个样本,来测试分类函数
def testingNB():
    listPosts,listClasses=loadDataSet() # listPosts:feature, listClasses:label
    myVocabList=createVocabList(listPosts) # 转换 I am a Chinese  构造词典
    trainMat=[]
    for postinDoc in listPosts:
        trainMat.append(setOfWords2Vec(myVocabList,postinDoc)) # 转换后的词表
    p0V,p1V,pAb=trainNB1(trainMat,listClasses) # 训练
    testEntry=['love','my','dalmation']
    thisDoc=setOfWords2Vec(myVocabList,testEntry)# 转换测试语句词表
    print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb)) # 预测
    testEntry=['stupid','garbage']
    thisDoc=np.array(setOfWords2Vec(myVocabList,testEntry))
    print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))

testingNB()

首先,代码调用了 loadDataSet 函数加载数据集,得到了文本数据列表 listPosts 和类别标签列表

listClasses。接着,代码调用了 createVocabList 函数,将文本数据列表转换为词汇表

myVocabList。然后,代码初始化了一个空列表 trainMat,用于存储训练集的词向量表示。接着,

代码遍历文本数据列表 listPosts,将每条文本数据转换为词向量,并添加到 trainMat 中。接下

来,代码调用了 trainNB1 函数,对训练集进行训练,得到了分类器的参数 p0V、p1V 和 pAb。然

后,代码构造了两个测试样本 testEntry,分别是 ['love','my','dalmation'] 和 ['stupid','garbage'],并

将它们转换为词向量表示 thisDoc。最后,代码调用了 classifyNB 函数,对测试样本进行分类,并

打印出分类结果。

  • 28
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三月七꧁ ꧂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值