zoukankan      html  css  js  c++  java
  • 机器学习实战-朴素贝叶斯垃圾邮件分类

    朴素贝叶斯

    概念

        对朴素贝叶斯的概念存在疑惑的,可以依此理解条件概率,全概率公式和贝叶斯公式。

    附链接帮助理解:

    链接1https://blog.csdn.net/Hearthougan/article/details/75174210

    链接2https://www.cnblogs.com/hellcat/p/7195843.html

    朴素贝叶斯分类是一种十分简单的分类算法,叫它朴素贝叶斯分类是因为这种方法的思想真的很朴素,朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。

    实战

        此实例为"朴素贝叶斯实现垃圾邮件分类"。

    数据集样例:

    Data->normal文件夹下数据样例:

    200.txt:

    Return-Path: <cai@tsinghua.edu.cn>

    Received: from mail.tsinghua.edu.cn (mail.tsinghua.edu.cn [166.111.8.18])

        by home.ccert.edu.cn (8.13.1/8.13.1) with SMTP id i9S1aCPt007420

        for <jiang@ccert.edu.cn>; Thu, 28 Oct 2004 09:36:12 +0800

    Received: (eyou send program); Thu, 28 Oct 2004 09:33:01 +0800

    Message-ID: <298927181.07940@mail.tsinghua.edu.cn>

    Received: from unknown (HELO mail.tsinghua.edu.cn) (unknown@127.0.0.1)

    by 127.0.0.1 with SMTP; Thu, 28 Oct 2004 09:33:01 +0800

    X-scanvirus: By Symantec Scan Engine

    X-scanresult: CLEAN

    Received: (eqmail ); 28 Oct 2004 01:32:52 -0000

    Received: from unknown (HELO sony) (duanhx@202.112.50.6)

    by localhost with SMTP; 28 Oct 2004 01:32:52 -0000

    Message-ID: <009f01c4bc90$12b41200$c63270ca@sony>

    From: "cai" <cai@tsinghua.edu.cn>

    To: jiang@ccert.edu.cn

    Subject: =?gb2312?B?ofEgW7T6t6Jd1dDGuMTayN2x4Lyt0rvD+6Osu7bTrc3GvPY=?=

    Date: Thu, 28 Oct 2004 09:47:18 +0800

    MIME-Version: 1.0

    Content-Type: text/plain;

        charset="gb2312"

    X-Priority: 3

    X-MSMail-Priority: Normal

    X-Mailer: Microsoft Outlook Express 6.00.2900.2180

    X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180

    Content-Transfer-Encoding: 8bit

    X-MIME-Autoconverted: from base64 to 8bit by home.ccert.edu.cn id i9S1aCPt007420

    X-UIDL: 0~p"!(4g!!K0I!!][`!!

    项目管理者联盟招聘内容编辑一名,欢迎大家帮忙推荐。

    工作地点:北京市德胜门外

    学 历:大专以上

    工作年限:一年以上

    内容编辑的工作内容如下:

    1. 负责项目管理者联盟网站[http://www.mypm.net]内容的收集、整理、编辑。

    2. 配合内容总编,进行网站栏目的规划和更新、活动组织等工作。

    职位的基本要求如下:

    1. 具有较强的文字功底、良好的语言表达和沟通能力

    2. 熟悉网络操作和office软件操作

    3. 为人踏实肯干,男女不限

    4. 有网站内容编辑工作经验者优先

    5. 对项目管理知识有一定了解者优先

    欢迎大家推荐人员应聘。

    应聘者请将简历发送邮件至:yhua@mypm.net

    并请在简历中注明待遇要求。

    Data->spam文件夹样例:

    1.txt:

    Return-Path: <qing@163.com>

    Received: from 163.com ([219.133.253.235])

        by spam-gw.ccert.edu.cn (MIMEDefang) with ESMTP id j68BPGTT015150

        for <cheng@ccert.edu.cn>; Fri, 08 Jul 2005 19:25:25 +0800 (CST)

    Message-ID: <200507081925.j68BPGTT015150@spam-gw.ccert.edu.cn>

    From: qing@163.com" <jsj@163.com>

    Subject: =?gb2312?B?u6W73bulwPuhormyzay3otW5?=

    To: cheng@ccert.edu.cn

    Content-Type: text/plain;charset="GB2312"

    Reply-To: qing@163.com

    Date: Fri, 8 Jul 2005 19:35:35 +0800

    X-Priority: 2

    X-Mailer: Foxmail 4.1 [cn]

    1.txt:

    您好!

    尊敬的客户:本公司长期代理进出口报关业务.有些发票可以为广大客户优惠代开(税率1.5%左右)

    以解广大客户财务票据得不足. 具体有(增值税专用发票、国税商品销售专用发票、地税运输专用

    发票、建筑安装专用发票;广告专用发票;还有其他服务发票)等,希望有意者来电详谈,愿合作

    愉快,成功! 可验证后付款!!

    联系人:王政

    手 机:13670068682。

    电 话:0755-21151603。

    邮 箱:haihongsz@126.com

    地 址:深圳市罗湖区深南路京鹏大厦。

    深圳市海宏实业有限公司

    Data->test文件夹数据由正常邮件和垃圾邮件混合组成:

    附代码:

    main.py

    #encoding=utf-8
    '''
    Created on 2018年3月11日
    
    @author: icmll
    '''
    
    from spam.spamEmail import spamEmailBayes
    import re
    #spam类对象
    spam=spamEmailBayes()
    #保存词频的词典
    spamDict={}
    normDict={}
    testDict={}
    #保存每封邮件中出现的词
    wordsList=[]
    wordsDict={}
    #保存预测结果,key为文件名,值为预测类别
    testResult={}
    #分别获得正常邮件、垃圾邮件及测试文件名称列表
    normFileList=spam.get_File_List("./../data/normal")
    spamFileList=spam.get_File_List("./../data/spam")
    testFileList=spam.get_File_List("./../data/test")
    #获取训练集中正常邮件与垃圾邮件的数量
    normFilelen=len(normFileList)
    spamFilelen=len(spamFileList)
    #获得停用词表,用于对停用词过滤
    stopList=spam.getStopWords()
    #获得正常邮件中的词频
    for fileName in normFileList:
        wordsList.clear()
        for line in open("./../data/normal/"+fileName):
            #过滤掉非中文字符
            rule=re.compile(r"[^u4e00-u9fa5]")
            line=rule.sub("",line)
            #将每封邮件出现的词保存在wordsList中
            spam.get_word_list(line,wordsList,stopList)
        #统计每个词在所有邮件中出现的次数
        spam.addToDict(wordsList, wordsDict)
    normDict=wordsDict.copy()  
    
    #获得垃圾邮件中的词频
    wordsDict.clear()
    for fileName in spamFileList:
        wordsList.clear()
        for line in open("./../data/spam/"+fileName):
            rule=re.compile(r"[^u4e00-u9fa5]")
            line=rule.sub("",line)
            spam.get_word_list(line,wordsList,stopList)
        spam.addToDict(wordsList, wordsDict)
    spamDict=wordsDict.copy()
    
    # 测试邮件
    for fileName in testFileList:
        testDict.clear( )
        wordsDict.clear()
        wordsList.clear()
        for line in open("./../data/test/"+fileName):
            rule=re.compile(r"[^u4e00-u9fa5]")
            line=rule.sub("",line)
            spam.get_word_list(line,wordsList,stopList)
        spam.addToDict(wordsList, wordsDict)
        testDict=wordsDict.copy()
        #通过计算每个文件中p(s|w)来得到对分类影响最大的15个词
        wordProbList=spam.getTestWords(testDict, spamDict,normDict,normFilelen,spamFilelen)
        #对每封邮件得到的15个词计算贝叶斯概率  
        p=spam.calBayes(wordProbList, spamDict, normDict)
        if(p>0.9):
            testResult.setdefault(fileName,1)
        else:
            testResult.setdefault(fileName,0)
    #计算分类准确率(测试集中文件名低于1000的为正常邮件)
    testAccuracy=spam.calAccuracy(testResult)
    for i,ic in testResult.items():
        print(i+"/"+str(ic))
    print(testAccuracy)  

    spamEmail.py

    #encoding=utf-8
    '''
    Created on 2018年3月11日
    
    @author: ICMLL
    '''
    import jieba;
    import os;
    class spamEmailBayes:
        #获得停用词表
        def getStopWords(self):
            stopList=[]
            for line in open("../data/中文停用词表.txt"):
                stopList.append(line[:len(line)-1])
            return stopList;
        #获得词典
        def get_word_list(self,content,wordsList,stopList):
            #分词结果放入res_list
            res_list = list(jieba.cut(content))
            for i in res_list:
                if i not in stopList and i.strip()!='' and i!=None:
                    if i not in wordsList:
                        wordsList.append(i)
                        
        #若列表中的词已在词典中,则加1,否则添加进去
        def addToDict(self,wordsList,wordsDict):
            for item in wordsList:
                if item in wordsDict.keys():
                    wordsDict[item]+=1
                else:
                    wordsDict.setdefault(item,1)
                                
        def get_File_List(self,filePath):
            filenames=os.listdir(filePath)
            return filenames
        
        #通过计算每个文件中p(s|w)来得到对分类影响最大的15个词
        def getTestWords(self,testDict,spamDict,normDict,normFilelen,spamFilelen):
            wordProbList={}
            for word,num  in testDict.items():
                if word in spamDict.keys() and word in normDict.keys():
                    #该文件中包含词个数
                    pw_s=spamDict[word]/spamFilelen
                    pw_n=normDict[word]/normFilelen
                    ps_w=pw_s/(pw_s+pw_n) 
                    wordProbList.setdefault(word,ps_w)
                if word in spamDict.keys() and word not in normDict.keys():
                    pw_s=spamDict[word]/spamFilelen
                    pw_n=0.01
                    ps_w=pw_s/(pw_s+pw_n) 
                    wordProbList.setdefault(word,ps_w)
                if word not in spamDict.keys() and word in normDict.keys():
                    pw_s=0.01
                    pw_n=normDict[word]/normFilelen
                    ps_w=pw_s/(pw_s+pw_n) 
                    wordProbList.setdefault(word,ps_w)
                if word not in spamDict.keys() and word not in normDict.keys():
                    #若该词不在脏词词典中,概率设为0.4
                    wordProbList.setdefault(word,0.47)
            sorted(wordProbList.items(),key=lambda d:d[1],reverse=True)[0:15]
            return (wordProbList)
        
        #计算贝叶斯概率
        def calBayes(self,wordList,spamdict,normdict):
            ps_w=1
            ps_n=1
             
            for word,prob in wordList.items() :
                print(word+"/"+str(prob))
                ps_w*=(prob)
                ps_n*=(1-prob)
            p=ps_w/(ps_w+ps_n)
    #         print(str(ps_w)+"////"+str(ps_n))
            return p        
    
        #计算预测结果正确率
        def calAccuracy(self,testResult):
            rightCount=0
            errorCount=0
            for name ,catagory in testResult.items():
                if (int(name)<1000 and catagory==0) or(int(name)>1000 and catagory==1):
                    rightCount+=1
                else:
                    errorCount+=1
            return rightCount/(rightCount+errorCount)
    代码说明:
    1. python参数的作用域:对于不可变类型的参数,在函数中不会被修改,例如字符串、数字和数组;对于可变类型的参数,在函数中其指向不会被修改,但其内容会被修改,例如列表、字典。
    2. line = re.sub(r"[u4e00-u9fa5]","-",string),参数1表示替换规则,即替换前匹配到的数据;参数2表示替换后的数据;参数3表示待扫描的数据。

      等价于:

      rule = re.compile(r"[u4e00-u9fa5]")

      line = rule.sub("-",string)

    3. 垃圾邮件中的事件相互独立,所以在词语1,词语2出现的情况下,此邮件为垃圾邮件的概率如下:

      P(垃圾邮件|词语1,词语2)=

  • 相关阅读:
    类型-String:二进制安全
    影视-纪录片:《魅力柬埔寨》
    植物:探矿植物
    植物-探矿植物:铜草
    扩展名:cs
    扩展名:snk
    Code-Helper:OracleHelper.cs
    Code-Helper:SqlHelper.cs
    Linux: FTP服务原理及vsfptd的安装、配置
    Linux下/etc/fstab文件详解
  • 原文地址:https://www.cnblogs.com/smuxiaolei/p/10847346.html
Copyright © 2011-2022 走看看