【机器学习实战】03-朴素贝叶斯算法实例

【博客的主要内容主要是自己的学习笔记,并结合个人的理解,供各位在学习过程中参考,若有疑问,欢迎提出;若有侵权,请告知博主删除,原创文章转载还请注明出处。】

[机器学习实战:文本过滤器]

实例一:在线社区留言板过滤器

1 需求描述:

为维护在线社区留言板的正常次序,需屏蔽侮辱性的言论,需构建一个快速过滤器,如果某条留言使用了负面或侮辱性的言语,那么就将该留言标识为内容不当。

2 算法分析:【自问的过程】

1、拥有数据样本情况?

有若干条数据样本,其中每条“言论”均标识所属类别(即侮辱性言语或非侮辱性言语)

2、程序如何判断言语为侮辱性和非侮辱性?

  1. 朴素贝叶斯

将使用朴素贝叶斯公式:

Paste_Image.png

c 表示分类类别即:侮辱性言语和非侮辱性言语

对每个类别分母都一样,即需计算$P(w|c_i)$ 和 $P(c_i)$,在朴素贝叶斯中假设事件是相互独立的,故:
$P(w|c_i)=P(w_0|c_i)P(w_1|c_i)...P(w_n|c_i)$

  1. 需要计算什么?
    $P(w|c_i)=P(w_0|c_i)P(w_1|c_i)...*P(w_n|c_i)$
    以上用文字描述:计算每个类别下各个单词出现的概率。由此,需要统计内容:
    a)每条言论下各个单词出现的次数;
    b)每个类别的单词总数;

  2. 数据分析:现有数据什么样?需要对数据如何处理?

  • a、对每条言语转换成向量数组;

  • b、制定“词典集合”,将每条言语做并集,去除重复单词;并将“词典集合”转换为向量数组;

  1. 特殊情况分析:
  • a、由于$P(w|c_i)=P(w_0|c_i)P(w_1|c_i)...*P(w_n|c_i)$ 是做乘法运算,若其中一个单词概率为0,则该言语概率为0。

    • [解决方法]将所有词出现数初始化为1,分母初始化为2。
  • b、太多很小数相乘,结果将趋近为0.

    • [解决方法]对乘积取自然对数。在代数中有ln(a*b) = ln(a) + ln(b)。

3 算法实现

#1、将文本转换为数字向量
##a、建立不重复的词汇表
def createVocabList(dataSet):
    vocabSet = set([])
    for document in dataSet:
        vocabSet = vocabSet | set(document)
    return list(vocabSet)
    

#test
myVocabLists = createVocabList(postingLists)   
    
##b、将每条言语转换为数字向量:建立与词汇表同等大小的言语向量,若言语中的词汇在词汇表中出现则标记为1,否则为0.
#vocabList:单词字典集合
#inputSet:单条文本
def setOfWords2Vec(vocabList,inputSet):
    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

#test
wordsVec=[]
for postingList in postingLists:
    wordsVec.append(setOfWords2Vec(myVocabLists,postingList))

#trainMainx - 输入文档矩阵
#trainCategory - 由每篇文档类别标签所构成的向量
def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory)/float(numTrainDocs)
    
    #初始化概率
    p0Num = ones(numWords)
    p1Num = ones(numWords)
    
    p0Denom = 2.0
    p1Denom = 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 = log(p1Num / p1Denom)
    p0Vect = log(p0Num / p0Denom)  
    
    return p0Vect,p1Vect,pAbusive
    
##test
p0Vect,p1Vect,pAbusive=trainNB0(wordsVec,classLists)

2 实例二:电子邮件垃圾过滤

如何从文本文档中构建自己的词列表
随机选择数据的一部分作为训练集,剩余部分作为测试集的过程称为“留存交叉验证”(hold-out cross validation)

思路:
1)构建词列表:对文本文档进行按词切分
2)交叉验证:对现有数据划分为训练集和测试集
3)朴素贝叶斯算法计算独立事件概率

  1. 计算算法准确率
    5)多次重复实验,提高正确率

textParse()接受一个大字符串并将其解析为字符串列表;
spamTest()对垃圾邮件分类器进行自动处理。主要:
1)解析文本文件编制成词列表;
2)构建测试集合训练集

######电子邮件垃圾过滤######
def textParse(bigString):
    import re
    listOfTokens = re.split(r'\W*',bigString)
    return [tok.lower() for tok in listOfTokens if len(tok) > 2]

def spamTest():
    docList=[]; classList=[]; fullText=[]
    #创建词汇表
    for i in range(1,26):
        wordList = textParse(open('email/spam/%d.txt'%i).read())
        docList.append(workList)
        fullText.extend(workList) 
        
        classList.append(1)
        wordList = textParse(open('email/ham/%d.txt'%i).read())
        
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
        
    vocabList = createVocabList(docList)
    
    #划分测试集 和 训练集
    trainingSet = range(50);
    testSet=[]
    for i in range(10):
        randIndex = int(random.uniform(0,len(trainingSet)))
        testSet.append(trainingSet[randIndex])
        del(trainingSet[randIndex])
        
    #朴素贝叶斯计算概率
    trainMat = [];trainClasses=[]
    for docIndex in trainingSet:
        trainMat.append(bagOfWord2VecMN(vocabList,docList[docIndex]))
        trainClasses.append(classList[docIndex])
        
        p0V,p1V,pSpam=trainNB(array(trainMat),array(trainClasses))      
        
    #统计错误率
    errorCount = 0 
    for docIndex in testSet:
        wordVector = bagOfWord2VecMN(vocabList,docList[docIndex])
        if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
            errorCount +=1
            print "classification error:",docList[docIndex]
            print "the error rate is:", float(errorCount)/len(testSet)

3 实例三:使用朴素贝叶斯分类器从个人广告中获取区域倾向

对两个城市所发布的征婚广告信息,来比较这两个城市的人们在广告用词上是否不同。
如果结论是不同,那么他们各自常用的词是那些?
从人们的用词中,能否对不同城市的人所关心的内容有所了解?

该实例目的:通过观察单词和条件概率值来发现与特定城市相关的内容

calcMostFreq() 遍历词汇表中每个词并统计它在文本中出现的次数,然后根据出现次数从高到低对词典进行排序,最后返回排序最高的100个单词。

localWords() 主要:1)解析文本词列表;2)构建测试集合训练集
getTopWords() 训练并测试朴素贝叶斯分类器,返回使用的概率值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • 第4章 基于概率论的分类方法:朴素贝叶斯 朴素贝叶斯 概述 贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理...
    Joyyx阅读 2,957评论 1 15
  • 忘光了概率统计的知识还想学朴素贝叶斯算法?这一篇就是为你准备的。虽然如此,作为初学者,别指望 5 分钟就能完全理解...
    kamidox阅读 2,676评论 4 7
  • 【博客的主要内容主要是自己的学习笔记,并结合个人的理解,供各位在学习过程中参考,若有疑问,欢迎提出;若有侵权,请告...
    Paullu阅读 2,244评论 0 11
  • 注:题中所指的『机器学习』不包括『深度学习』。本篇文章以理论推导为主,不涉及代码实现。 前些日子定下了未来三年左右...
    我偏笑_NSNirvana阅读 39,936评论 12 145
  • 音乐课:保持家庭和谐 为了掌握演奏种乐器的技巧,孩子需对他们努力的赞赏,而不是对他们错误的批评。 家长应理...
    尤占芳阅读 195评论 0 0