ML基础-朴素贝叶斯-2-进行文本分类

本文介绍了如何使用朴素贝叶斯进行文本分类,讲解了计算概率的方法,包括训练时的类别概率和词在类别中出现的概率。通过条件独立性假设简化了计算过程。同时,提到了在测试阶段如何根据实际情况调整分类器,并概述了词袋模型在处理词频中的作用。文中还提及了一个python的`sum()`函数应用。
摘要由CSDN通过智能技术生成

准备数据:

#
# 创建实实验样本,
# 返回值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.csdn.net/rifengxxc/article/details/75008427

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值