Joeyos's Blog Software Engineer

Python实现朴素贝叶斯分类

2018-08-08
Quan Zhang

朴素贝叶斯的一般过程

  1. 收集数据:可以使用任何方法

  2. 准备数据:需要数值型或者布尔型

  3. 分析数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好

  4. 训练算法:计算不同的独立特征的条件概率

  5. 测试算法:计算错误率

  6. 使用算法

从文本中构建词向量

  1. def loadDataSet():文档数据来源于斑点狗爱好者论坛,类别有侮辱性和非侮辱性词汇,由人工标注,1代表侮辱性,0代表正常言论,这些标注信息用于训练程序,以便自动检测侮辱性留言。

  2. def createVocabList(dataSet):创建一个空集,存储不重复词汇列表

  3. def setOfWords2Vec(vocabList, inputSet):输入一个文档,创建一个词汇表长的向量,输出向量1,0表示该词汇在文档中是否出现。

检查词表,发现词表无重复单词,目前词表未排序,需要的话可以排序。

下载bayes.py

import bayes
listOPosts,listClasses = bayes.loadDataSet()
myVocabList = bayes.createVocabList(listOPosts)
print(myVocabList)
['worthless', 'take', 'licks', 'has', 'please', 'not', 'so', 'love', 'posting', 'is', 'stupid', 'problems', 'how', 'dalmation', 'maybe', 'garbage', 'I', 'flea', 'stop', 'him', 'mr', 'cute', 'steak', 'dog', 'help', 'ate', 'food', 'my', 'park', 'quit', 'buying', 'to']
bayes.setOfWords2Vec(myVocabList,listOPosts[0])#索引为0,cute
[0,
 0,
 0,
 1,
 1,
 0,
 0,
 0,
 0,
 0,
 0,
 1,
 0,
 0,
 0,
 0,
 0,
 1,
 0,
 0,
 0,
 0,
 0,
 1,
 1,
 0,
 0,
 1,
 0,
 0,
 0,
 0]

测试分类函数

bayes.testingNB()
['love', 'my', 'dalmation'] classified as:  0
['stupid', 'garbage'] classified as:  1

切分文本

mySent='This book is the best book on Python or M.L. I have ever laid'
mySent.split()
['This',
 'book',
 'is',
 'the',
 'best',
 'book',
 'on',
 'Python',
 'or',
 'M.L.',
 'I',
 'have',
 'ever',
 'laid']

可以看到,切分的还不错,但标点符号也切进去了。可以使用正则化,其中分隔符是除单词、数字外的任意字符串。

import re
regEx = re.compile('\\W*')
listOfTokens = regEx.split(mySent)
listOfTokens
F:\Anaconda3.5.2\lib\site-packages\ipykernel_launcher.py:3: FutureWarning: split() requires a non-empty pattern match.
  This is separate from the ipykernel package so we can avoid doing imports until





['This',
 'book',
 'is',
 'the',
 'best',
 'book',
 'on',
 'Python',
 'or',
 'M',
 'L',
 'I',
 'have',
 'ever',
 'laid']

去掉里面的空字符串,可以计算字符串的长度,只返回长度大于0的字符串:

[tok for tok in listOfTokens if len(tok) > 0]
['This',
 'book',
 'is',
 'the',
 'best',
 'book',
 'on',
 'Python',
 'or',
 'M',
 'L',
 'I',
 'have',
 'ever',
 'laid']

可以将字符串全部转换为小写(.lower)或者大写(.upper):

[tok.lower() for tok in listOfTokens if len(tok) > 0]
['this',
 'book',
 'is',
 'the',
 'best',
 'book',
 'on',
 'python',
 'or',
 'm',
 'l',
 'i',
 'have',
 'ever',
 'laid']

下载email.zip

emailText = open('email/ham/6.txt').read()
listOfTokens = regEx.split(emailText)
#listOfTokens
#很多单词
F:\Anaconda3.5.2\lib\site-packages\ipykernel_launcher.py:2: FutureWarning: split() requires a non-empty pattern match.

测试算法(交叉验证)

函数textParse()接受一个大字符串并将其解析为字符串列表,该函数去掉少于两个字符的字符串,并将所有字符串转换为小写。

函数spamTest()对贝叶斯垃圾邮件分类器进行自动化处理,导入spam与ham下的文本文件,并将它们解析为词列表。

接下来构建一个测试集与一个训练集,两个集合中的邮件都是随机选出的。此处有50份邮件,随机选10份作为测试集。

bayes.spamTest()

文件中有非法字符,不知道是哪个文件…….

F:\Anaconda3.5.2\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
  return _compile(pattern, flags).split(string, maxsplit)



---------------------------------------------------------------------------

UnicodeDecodeError                        Traceback (most recent call last)

<ipython-input-68-823d79549753> in <module>()
----> 1 bayes.spamTest()


C:\Users\Administrator\Desktop\bayes.py in spamTest()
     95     for i in range(1,26):
     96         wordList = textParse(open('email/spam/%d.txt' % i).read())
---> 97         docList.append(wordList)
     98         fullText.extend(wordList)
     99         classList.append(1)


UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 199: illegal multibyte sequence

Similar Posts

Comments