机器学习task3 朴素贝尔斯

朴素贝尔斯

kNN 和 kD-Tree 都只能明确地判断一个数据是否属于一个类,这里给出的是 guess, 也就是说结果可能会像这样: “ xx 最有可能在 yy 分组中,可能性为 zz%”,但是之前计算可能性我们是直接按照 targetNum / totalNum,太过粗暴

Bayesian 决策: 选择可能性最高的决策
Conditional probablity:

naive Bayes 的假设: 1. 词和其他词搭配概率一样 2. 每个 feature 的权重一样

基本的东西

把文字转化为数组:

def createVocabList(dataSet):
    '''
    1. Being an unordered collection, sets do not record element position or order of insertion. Accordingly, sets do not support indexing, slicing, or other sequence-like behavior.
    :param dataSet:
    :return: vocabset(list)
    '''
    vocabset = set([])
    for document in dataSet:
        # print(document)
        # print(set(document))          位置不是确定的
        vocabset = vocabset | set(document)
        # print(vocabset)
    return list(vocabset)

def setofWords2Vec(vocabList, inputSet):
    '''
    1. 由于python中的列表对其中的元素采用的是引用的方法 删除其中一个元素在迭代时会导致列表的引用的改变,因此最好的处理办法创建一个与之一一对应的列表
    2. 遍历整个vocabList集 遇到与查找词汇相同时更改下标对应的flag值,确定词汇集中的查找词汇
    3. 返回returnVec
    :param vocabList: 所有的词汇集
    :param inputSet:  敏感词汇列表
    :return: 向量化的文本对应列表
    '''
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else:
            print("the word %s is not in my Vocabulary") % word
    return returnVec

计算 0 和 1 的分布

ok

w 是和 Vocabulary 一样长的 vector,值是是否含有 Vocabulary 中的第 index 个单词,一一对应

p(ci) && p(w) 是用传统概型计算出来的

def trainNBO(trainMatrix,trainCategory):
    '''

    :param trainMatrix: 文档矩阵 二维矩阵
    :param trainCategory: 文档类型标签向量 通过向量和可以除以文件总数来获得侮辱性文档概率
    :return: pAbusive 侮辱性文档概率
    :return: p1Vect 正常性文档中存在所有词的概率
    :return: p0Vect 侮辱性文档中存在所有词的概率 最大概率的词可以表征这个类别
    '''
    # print(trainMatrix,trainCategory)
    #获取文档总数
    trainDistance = len(trainMatrix)
    # 获取到每行myVocabList(文档)是多少元素 也就是去重后的listOPosts元素数
    trainNumbers = len(trainMatrix[0])
    # 侮辱词类别文章的出现的总概率
    pAbusive = sum(trainCategory)/float(trainNumbers)
    #计算侮辱和正常对应词在文章出现的次数
    #词对应个数      为了避免在多个概率乘积以获得某个文档类别时,某个概率值为0,最后的乘积为0,可以初始化时初始化为全1矩阵
    p0Num = ones(trainNumbers)
    p1Num = ones(trainNumbers)
    #该文档总词数     将分母初始化为2.0? 个人理解:首先,若为0.0的话若trainCategory为全0向量会导致分母为0致使抛出异常, 若为1.0时以上情况出现时概率为全1
    p0Denom = 2.0
    p1Denom = 2.0
    for i in range(trainDistance):
        if trainCategory[i] == 1:
            # 在侮辱性文章中所有的词的向量和   在侮辱性文章中词的总数
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:
            #在正常文章中所有词的向量和  在正常文章中所有词的总数
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    # 每个在正常文章中的词在正常文章中的概率 由于每个乘数较小在python中会得到四舍五入的结果 因此需要取对数
    p0Vect = log(p0Num / p0Denom)
    # 每个在侮辱文章中的词在侮辱文章中的概率
    p1Vect = log(p1Num / p1Denom)
    return p0Vect, p1Vect, pAbusive

比较大小做出分类

def classifyNB(vec2Classify, p0Vect, p1Vect,pAbusive):
    p1 = sum(vec2Classify * p1Vect) + log(pAbusive)
    p0 = sum(vec2Classify * p0Vect) + log(pAbusive)
    if p1> p0:
        return 1
    else:
        return 0

测试数据

def bagOfWords2VecMN(vocabList, inputSet):
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    return returnVec


def testingNB():
    # 获取词汇表和标签表
    listOPosts, listclasses = loadDataSet()
    # 获取去重词汇表
    myVocablist = createVocabList(listOPosts)
    trainMat = []
    for lineinDoc in listOPosts:
        trainMat.append(setofWords2Vec(myVocablist, lineinDoc))
    # 传入文档矩阵和标签集
    p0Vect, p1Vect, pAbusive = trainNBO(array(trainMat), array(listclasses))
    # 测试正常词组
    testEntry1 = ['love', 'my', 'dalmation']
    thisDoc = array(setofWords2Vec(myVocablist, testEntry1))
    print(testEntry1, "class is:", classifyNB(thisDoc, p0Vect, p1Vect, pAbusive))
    testEntry2 = ['stupid', 'garbage']
    thisDoc = array(setofWords2Vec(myVocablist,testEntry2))
    print(testEntry2, "class is :", classifyNB(thisDoc, p0Vect, p1Vect, pAbusive))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值