文章原創(chuàng),最近更新:2018-08-21
前言:
本文介紹機器學習分類算法中的樸素貝葉斯分類算法并給出偽代碼,Python代碼實現(xiàn)。
學習參考鏈接:
1.第4章 基于概率論的分類方法:樸素貝葉斯
本章節(jié)的主要內容是:
重點介紹項目案例2:使用樸素貝葉斯過濾垃圾郵件項目匯總代碼。
1.樸素貝葉斯項目案例介紹:
項目案例2:
使用樸素貝葉斯過濾垃圾郵件
項目概述:
完成樸素貝葉斯的一個最著名的應用: 電子郵件垃圾過濾。
樸素貝葉斯 工作原理:
提取所有文檔中的詞條并進行去重
獲取文檔的所有類別
計算每個類別中的文檔數(shù)目
對每篇訓練文檔:
對每個類別:
如果詞條出現(xiàn)在文檔中-->增加該詞條的計數(shù)值(for循環(huán)或者矩陣相加)
增加所有詞條的計數(shù)值(此類別下詞條總數(shù))
對每個類別:
對每個詞條:
將該詞條的數(shù)目除以總詞條數(shù)目得到的條件概率(P(詞條|類別))
返回該文檔屬于每個類別的條件概率(P(類別|文檔的所有詞條))
開發(fā)流程:
使用樸素貝葉斯對電子郵件進行分類
- 收集數(shù)據(jù): 提供文本文件
- 準備數(shù)據(jù): 將文本文件解析成詞條向量
- 分析數(shù)據(jù): 檢查詞條確保解析的正確性
- 訓練算法: 使用我們之前建立的 trainNB() 函數(shù)
- 測試算法: 使用樸素貝葉斯進行交叉驗證
- 使用算法: 構建一個完整的程序對一組文檔進行分類,將錯分的文檔輸出到屏幕上
數(shù)據(jù)集介紹
數(shù)據(jù)集包含兩部分,spam(垃圾郵件)文件夾,以及ham(正常郵件)文件夾.spam/ham文件夾分別有25個郵件.代碼塊的內容是ham郵件其中的一個1.txt郵件數(shù)據(jù)集,圖1是ham(正常郵件)文件夾所有的數(shù)據(jù)集.
Hi Peter,
With Jose out of town, do you want to
meet once in a while to keep things
going and do some interesting stuff?
Let me know
Eugene

2.文檔詞袋模型的介紹
目前為止,我們將每個詞的出現(xiàn)與否作為一個特征,這可以被描述為詞集模型(set-of-wordsmodl).如果一個詞在文檔中出現(xiàn)不止一次,這可能意味著包含該詞是否出現(xiàn)在文檔中所不能表達的某種信息,這種方法被稱為詞袋模型(bag-of-words model)。在詞袋中,每個單詞可以出現(xiàn)多次,而在詞集中,每個詞只能出現(xiàn)一次。為適應詞袋模型,需要對函數(shù) setofWords2vec()稍加修改,修改后的函數(shù)稱為 bagofwords2vec().
下面的程序清單給出了基于詞袋模型的樸素貝葉斯代碼。它與函數(shù) setofwords2vec()幾乎完全相同,唯一不同的是每當遇到一個單詞時,它會增加詞向量中的對應值,而不只是將對應的數(shù)值設為1.
def bagOfWords2Vec(vocabList, inputSet):
"""
遍歷查看該單詞是否出現(xiàn),出現(xiàn)該單詞則將該單詞置1,否則該單詞置0
:param vocabList: 所有單詞集合列表
:param inputSet: 輸入數(shù)據(jù)集
:return: 匹配列表[0,1,0,1...],其中 1與0 表示詞匯表中的單詞是否出現(xiàn)在輸入的數(shù)據(jù)集中
"""
# 創(chuàng)建一個和詞匯表vocabList等長的向量returnVec,向量中每一元素都為0
returnVec = [0]*len(vocabList)# [0,0......]
#用變量word遍歷輸入文檔inputSet中的所有單詞
for word in inputSet:
# 如果單詞在詞匯表vocabList中
if word in vocabList:
# 則將輸出文檔向量中的值設為1
returnVec[vocabList.index(word)] +=1
return returnVec
3.相關代碼:
3.1準備數(shù)據(jù): 將文本文件解析成詞條向量
之前介紹了如何創(chuàng)建詞向量,并基于這些詞向量進行樸素貝葉斯分類的過程。前一節(jié)中的詞向量是預先給定的,下面介紹如何從文本文檔中構建自己的詞列表。
對于一個文本字符串,可以使用 Python的 string.split()方法將其切分。下面看看實際的運行結果
mySent = 'This book is the best book on Python or M.L. I have ever laid eyes upon.'
mySent.split()
Out[244]:
['This', 'book', 'is', 'the','best', 'book','on', 'Python', 'or', 'M.L.', 'I', 'have', 'ever','laid', 'eyes', 'upon.']
可以看到,切分的結果不錯,但是標點符號也被當成了詞的一部分??梢允褂谜齽t表示式來切分句子,其中分隔符是除單詞、數(shù)字外的任意字符串.
使用正則表達式來切分文本
import re
regEx = re.compile("\\W*")
listOfTokens=regEx.split(mySent)
listOfTokens
Out[248]:
['This', 'book', 'is', 'the', 'best', 'book', 'on', 'Python', 'or', 'M', 'L', 'I','have', 'ever', 'laid', 'eyes', 'upon', '']
現(xiàn)在得到了一系列詞組成的詞表,但是里面的空字符串需要去掉??梢杂嬎忝總€字符串的長度只返回長度大于0的字符串。
[tok for tok in listOfTokens if len(tok)>0]
Out[250]:
['This', 'book', 'is', 'the', 'best', 'book', 'on', 'Python', 'or', 'M', 'L', 'I', 'have', 'ever', 'laid', 'eyes', 'upon']
最后,我們發(fā)現(xiàn)句子中的第一個單詞是大寫的。如果目的是句子查找,那么這個特點會很有用。
但這里的文本只看成詞袋,所以我們希望所有詞的形式都是統(tǒng)一的,不論它們出現(xiàn)在句子中間、結尾還是開頭。
Python中有一些內嵌的方法,可以將字符串全部轉換成小寫(.1ower())或者大寫(.upper(),借助這些方法可以達到目的。于是,可以進行如下處理:
[tok.lower() for tok in listOfTokens if len(tok)>0]
Out[255]:
['this', 'book', 'is', 'the', 'best', 'book', 'on', 'python', 'or', 'm', 'l', 'i', 'have', 'ever', 'laid', 'eyes', 'upon']
現(xiàn)在來看數(shù)據(jù)集中一封完整的電子郵件的實際處理結果。
emailText=open("6.txt").read()
emailText
Out[259]: 'Hello,\n\nSince you are an owner of at least one Google Groups group that uses the customized welcome message, pages or files, we are writing to inform you that we will no longer be supporting these features starting February 2011. We made this decision so that we can focus on improving the core functionalities of Google Groups -- mailing lists and forum discussions. Instead of these features, we encourage you to use products that are designed specifically for file storage and page creation, such as Google Docs and Google Sites.\n\nFor example, you can easily create your pages on Google Sites and share the site (http://www.google.com/support/sites/bin/answer.py?hl=en&answer=174623) with the members of your group. You can also store your files on the site by attaching files to pages (http://www.google.com/support/sites/bin/answer.py?hl=en&answer=90563) on the site. If you抮e just looking for a place to upload your files so that your group members can download them, we suggest you try Google Docs. You can upload files (http://docs.google.com/support/bin/answer.py?hl=en&answer=50092) and share access with either a group (http://docs.google.com/support/bin/answer.py?hl=en&answer=66343) or an individual (http://docs.google.com/support/bin/answer.py?hl=en&answer=86152), assigning either edit or download only access to the files.\n\nyou have received this mandatory email service announcement to update you about important changes to Google Groups.'
listOfTokens=regEx.split(emailText)
listOfTokens
Out[261]:
['Hello', 'Since', 'you', 'are', 'an', 'owner', 'of', 'at', 'least', 'one', 'Google', 'Groups', 'group', 'that', 'uses', 'the', 'customized', 'welcome', 'message', 'pages', 'or', 'files', 'we', 'are', 'writing', 'to', 'inform', 'you', 'that', 'we', 'will', 'no', 'longer', 'be', 'supporting', 'these', 'features', 'starting', 'February', '2011', 'We', 'made', 'this', 'decision', 'so', 'that', 'we', 'can', 'focus', 'on', 'improving', 'the', 'core', 'functionalities', 'of', 'Google', 'Groups', 'mailing', 'lists', 'and', 'forum', 'discussions', 'Instead', 'of', 'these', 'features', 'we', 'encourage', 'you', 'to', 'use', 'products', 'that', 'are', 'designed', 'specifically', 'for', 'file', 'storage', 'and', 'page', 'creation', 'such', 'as', 'Google', 'Docs', 'and', 'Google', 'Sites', 'For', 'example', 'you', 'can', 'easily', 'create', 'your', 'pages', 'on', 'Google', 'Sites', 'and', 'share', 'the', 'site', 'http', 'www', 'google', 'com', 'support', 'sites', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '174623', 'with', 'the', 'members', 'of', 'your', 'group', 'You', 'can', 'also', 'store', 'your', 'files', 'on', 'the', 'site', 'by', 'attaching', 'files', 'to', 'pages', 'http', 'www', 'google', 'com', 'support', 'sites', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '90563', 'on', 'the', 'site', 'If', 'you抮e', 'just', 'looking', 'for', 'a', 'place', 'to', 'upload', 'your', 'files', 'so', 'that', 'your', 'group', 'members', 'can','download', 'them', 'we', 'suggest', 'you', 'try', 'Google', 'Docs', 'You', 'can', 'upload', 'files', 'http', 'docs', 'google', 'com', 'support', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '50092', 'and', 'share', 'access', 'with', 'either', 'a', 'group', 'http', 'docs', 'google','com', 'support', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '66343', 'or', 'an', 'individual', 'http', 'docs', 'google', 'com', 'support', 'bin', 'answer', 'py', 'hl', 'en', 'answer', '86152', 'assigning', 'either', 'edit', 'or', 'download', 'only', 'access', 'to', 'the', 'files', 'you', 'have','received', 'this', 'mandatory', 'email', 'service', 'announcement', 'to', 'update', 'you', 'about', 'important', 'changes', 'to', 'Google', 'Groups', '']
通過結果可以知道,這里對url進行了切分,得到了很多詞,如果我們想去掉這些單詞,因此在實現(xiàn)時會過濾掉長度小于3的字符串.
3.2訓練算法: 使用我們之前建立的 trainNB0() 函數(shù)
def trainNB0(trainMatrix, trainCategory):
"""
訓練數(shù)據(jù)原版
:param trainMatrix: 文件單詞矩陣 [[1,0,1,1,1....],[],[]...]
:param trainCategory: 文件對應的標簽類別[0,1,1,0....],列表長度等于單詞矩陣數(shù),其中的1代表對應的文件是侮辱性文件,0代表不是侮辱性矩陣
:return:
p0Vect: 各單詞在分類0的條件下出現(xiàn)的概率
p1Vect: 各單詞在分類1的條件下出現(xiàn)的概率
pAbusive: 文檔屬于分類1的概率
"""
# 總文件數(shù)
numTrainDocs = len(trainMatrix)
# 每個文件中的單詞數(shù)
numWords = len(trainMatrix[0])
# 侮辱性文件的出現(xiàn)概率,即trainCategory中所有的1的個數(shù)
# 代表的就是多少個侮辱性文件,與文件的總數(shù)相除就得到了侮辱性文件的出現(xiàn)概率
pAbusive = sum(trainCategory) / float(numTrainDocs)
# p0Num 正常的統(tǒng)計,p1Num 侮辱的統(tǒng)計
p0Num = np.ones(numWords); p1Num =np.ones(numWords)
# 整個數(shù)據(jù)集單詞出現(xiàn)總數(shù),2.0根據(jù)樣本/實際調查結果調整分母的值(2主要是避免分母為0,當然值可以調整)
# p0Num 正常的統(tǒng)計
# p1Num 侮辱的統(tǒng)計
p0Denom = 2.0
p1Denom = 2.0
for i in range(numTrainDocs):
if trainCategory[i]==1:
# 累加辱罵詞的頻次
p1Num += trainMatrix[i]
# 對每篇文章的辱罵的頻次 進行統(tǒng)計匯總
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
# 類別1,即侮辱性文檔的[log(P(F1|C1)),log(P(F2|C1)),log(P(F3|C1)),log(P(F4|C1)),log(P(F5|C1))....]列表
# log下什么都不寫默認是自然對數(shù)
p1Vect = np.log(p1Num/p1Denom)
# 類別0,即正常文檔的[log(P(F1|C0)),log(P(F2|C0)),log(P(F3|C0)),log(P(F4|C0)),log(P(F5|C0))....]列表
p0Vect = np.log(p0Num/p0Denom)
return p0Vect, p1Vect, pAbusive
3.3測試算法: 使用樸素貝葉斯進行交叉驗證
文件解析及完整的垃圾郵件測試函數(shù)
打開文本編輯器,將下面程序清單中的代碼添加到bayes.py文件中.
# 切分文本
def textParse(bigString):
'''
Desc:
接收一個大字符串并將其解析為字符串列表
Args:
bigString -- 大字符串
Returns:
去掉少于 2 個字符的字符串,并將所有字符串轉換為小寫,返回字符串列表
'''
import re
# 使用正則表達式來切分句子,其中分隔符是除單詞、數(shù)字外的任意字符串
listOfTokens =re.split(r'\W*',bigString)
return [tok.lower() for tok in listOfTokens if len(tok)>2]
def spamTest():
'''
Desc:
對貝葉斯垃圾郵件分類器進行自動化處理。
Args:
none
Returns:
對測試集中的每封郵件進行分類,若郵件分類錯誤,則錯誤數(shù)加 1,最后返回總的錯誤百分比。
'''
import random
# 定義docList文檔列表,classList類別列表,fullText所有文檔詞匯
docList=[];classList=[];fullText=[]
#spam和ham文件夾里的郵件都是25封,所以用for循環(huán)25次
for i in range(1,26):
# 打開并讀取第i封垃圾郵件到列表worldList里
wordList = textParse(open('email/spam/%d.txt' % i, "rb").read().decode('GBK','ignore') )
# append()向列表尾部追加一個新元素,列表只占一個索引位
docList.append(wordList)
# extend()向列表尾部追加一個列表,將列表中的每個元素都追加進來
fullText.extend(wordList)
# classList里面追加加個1(1代表是類標簽,垃圾郵件)
classList.append(1)
# 打開并讀取第i封正常郵件到列表worldList里
wordList = textParse(open('email/ham/%d.txt' % i, "rb").read().decode('GBK','ignore') )
# append()向列表尾部追加一個新元素,列表只占一個索引位
docList.append(wordList)
# extend()向列表尾部追加一個列表,將列表中的每個元素都追加進來
fullText.extend(wordList)
# classList里面追加加個0(0代表是類標簽,正常郵件)
classList.append(0)
# 創(chuàng)建詞列表,調用自定義函數(shù)createVocabList()剔除列表docList中重復的詞,返回含有docList中所有不重復詞的列表
vocabList=createVocabList(docList)
# 創(chuàng)建測試集與訓練集
trainingSet = list(range(50))
testSet=[]
# 用for循環(huán)隨機選擇10個文檔作為測試集,其余作為訓練集
for i in range(10):
# 生成隨機整數(shù)randIndex,random.uniform(a,b)用于生成指定范圍內的隨機浮點數(shù)
randIndex=int(random.uniform(0,len(trainingSet)))
# 將trainingSet列表中的第randIndex個元素添加到testSet里
testSet.append(trainingSet[randIndex])
# 刪除trainingSet列表中的第randIndex個元素,其余作為訓練集
del(trainingSet[randIndex])
# 創(chuàng)建空訓練集列表以及空的訓練集標簽列表
trainMat =[];trainClasses=[]
# 遍歷訓練集,求得先驗概率和條件概率
for docIndex in trainingSet:
# 將詞匯列表變?yōu)橄蛄糠诺絫rainMat
trainMat.append(bagOfWords2Vec(vocabList, docList[docIndex]))
# 訓練集的類別標簽
trainClasses.append(classList[docIndex])
# 計算先驗概率,條件概率
p0V,p1V,pSpam=trainNB0(np.array(trainMat), np.array(trainClasses))
# 定義錯誤計數(shù)
errorCount = 0
# 對測試集進行分類
for docIndex in testSet:
# 將測試集詞匯向量化
wordVector =bagOfWords2Vec(vocabList, docList[docIndex])
# 對測試數(shù)據(jù)進行分類
if classifyNB(np.array(wordVector),p0V,p1V,pSpam)!=classList[docIndex]:
#分類不正確,錯誤計數(shù)+1
errorCount += 1
# 輸出分類錯誤的文檔
print("classification error",docList[docIndex])
#輸出分類錯誤率
print('the error rate is: ',float(errorCount)/len(testSet))
測試代碼及其結果如下:
import bayes
bayes.spamTest()
the error rate is: 0.0
D:\360Downloads\Software\Anaconda\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
return _compile(pattern, flags).split(string, maxsplit)
import bayes
bayes.spamTest()
classification error ['benoit', 'mandelbrot', '1924', '2010', 'benoit', 'mandelbrot', '1924', '2010', 'wilmott', 'team', 'benoit', 'mandelbrot', 'the', 'mathematician', 'the', 'father', 'fractal', 'mathematics', 'and', 'advocate', 'more', 'sophisticated', 'modelling', 'quantitative', 'finance', 'died', '14th', 'october', '2010', 'aged', 'wilmott', 'magazine', 'has', 'often', 'featured', 'mandelbrot', 'his', 'ideas', 'and', 'the', 'work', 'others', 'inspired', 'his', 'fundamental', 'insights', 'you', 'must', 'logged', 'view', 'these', 'articles', 'from', 'past', 'issues', 'wilmott', 'magazine']
the error rate is: 0.1
D:\360Downloads\Software\Anaconda\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
return _compile(pattern, flags).split(string, maxsplit)
3.4與之關聯(lián)相關的代碼
def createVocabList(dataSet):
"""
獲取所有單詞的集合
:param dataSet: 數(shù)據(jù)集
:return: 所有單詞的集合(即不含重復元素的單詞列表)
"""
vocabSet = set()
for document in dataSet:
# 操作符 | 用于求兩個集合的并集
vocabSet=set(document)|vocabSet
return list(vocabSet)
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
"""
使用算法:
# 將乘法轉換為加法
乘法:P(C|F1F2...Fn) = P(F1F2...Fn|C)P(C)/P(F1F2...Fn)
加法:P(F1|C)*P(F2|C)....P(Fn|C)P(C) -> log(P(F1|C))+log(P(F2|C))+....+log(P(Fn|C))+log(P(C))
:param vec2Classify: 待測數(shù)據(jù)[0,1,1,1,1...],即要分類的向量
:param p0Vec: 類別0,即正常文檔的[log(P(F1|C0)),log(P(F2|C0)),log(P(F3|C0)),log(P(F4|C0)),log(P(F5|C0))....]列表
:param p1Vec: 類別1,即侮辱性文檔的[log(P(F1|C1)),log(P(F2|C1)),log(P(F3|C1)),log(P(F4|C1)),log(P(F5|C1))....]列表
:param pClass1: 類別1,侮辱性文件的出現(xiàn)概率
:return: 類別1 or 0
"""
# 計算公式 log(P(F1|C))+log(P(F2|C))+....+log(P(Fn|C))+log(P(C))
# 大家可能會發(fā)現(xiàn),上面的計算公式,沒有除以貝葉斯準則的公式的分母,也就是 P(w) (P(w) 指的是此文檔在所有的文檔中出現(xiàn)的概率)就進行概率大小的比較了,
# 因為 P(w) 針對的是包含侮辱和非侮辱的全部文檔,所以 P(w) 是相同的。
# 使用 NumPy 數(shù)組來計算兩個向量相乘的結果,這里的相乘是指對應元素相乘,即先將兩個向量中的第一個元素相乘,然后將第2個元素相乘,以此類推。
# 我的理解是:這里的 vec2Classify * p1Vec 的意思就是將每個詞與其對應的概率相關聯(lián)起來
# P(w|c1) * P(c1) ,即貝葉斯準則的分子
p1=sum(vec2Classify*p1Vec)+np.log(pClass1)
# P(w|c0) * P(c0) ,即貝葉斯準則的分子·
p0=sum(vec2Classify*p0Vec)+np.log(1.0-pClass1)
if p1>p0:
return 1
else:
return 0
def trainNB0(trainMatrix, trainCategory):
"""
訓練數(shù)據(jù)原版
:param trainMatrix: 文件單詞矩陣 [[1,0,1,1,1....],[],[]...]
:param trainCategory: 文件對應的標簽類別[0,1,1,0....],列表長度等于單詞矩陣數(shù),其中的1代表對應的文件是侮辱性文件,0代表不是侮辱性矩陣
:return:
p0Vect: 各單詞在分類0的條件下出現(xiàn)的概率
p1Vect: 各單詞在分類1的條件下出現(xiàn)的概率
pAbusive: 文檔屬于分類1的概率
"""
# 總文件數(shù)
numTrainDocs = len(trainMatrix)
# 每個文件中的單詞數(shù)
numWords = len(trainMatrix[0])
# 侮辱性文件的出現(xiàn)概率,即trainCategory中所有的1的個數(shù)
# 代表的就是多少個侮辱性文件,與文件的總數(shù)相除就得到了侮辱性文件的出現(xiàn)概率
pAbusive = sum(trainCategory) / float(numTrainDocs)
# p0Num 正常的統(tǒng)計,p1Num 侮辱的統(tǒng)計
p0Num = np.ones(numWords); p1Num =np.ones(numWords)
# 整個數(shù)據(jù)集單詞出現(xiàn)總數(shù),2.0根據(jù)樣本/實際調查結果調整分母的值(2主要是避免分母為0,當然值可以調整)
# p0Num 正常的統(tǒng)計
# p1Num 侮辱的統(tǒng)計
p0Denom = 2.0
p1Denom = 2.0
for i in range(numTrainDocs):
if trainCategory[i]==1:
# 累加辱罵詞的頻次
p1Num += trainMatrix[i]
# 對每篇文章的辱罵的頻次 進行統(tǒng)計匯總
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
# 類別1,即侮辱性文檔的[log(P(F1|C1)),log(P(F2|C1)),log(P(F3|C1)),log(P(F4|C1)),log(P(F5|C1))....]列表
# log下什么都不寫默認是自然對數(shù)
p1Vect = np.log(p1Num/p1Denom)
# 類別0,即正常文檔的[log(P(F1|C0)),log(P(F2|C0)),log(P(F3|C0)),log(P(F4|C0)),log(P(F5|C0))....]列表
p0Vect = np.log(p0Num/p0Denom)
return p0Vect, p1Vect, pAbusive
4.相關知識點
知識點1:re正則表達式
學習參考鏈接:(三)正則表達式入門學習筆記|Python網(wǎng)絡爬蟲與信息提取



知識點2:Python uniform() 函數(shù)
uniform() 方法將隨機生成下一個實數(shù),它在 [x, y) 范圍內。
具體語法如下:
import random
random.uniform(x, y)
注意:uniform()是不能直接訪問的,需要導入 random 模塊,然后通過 random 靜態(tài)對象調用該方法。
- 參數(shù)
- x -- 隨機數(shù)的最小值,包含該值。
- y -- 隨機數(shù)的最大值,不包含該值。
- 返回值:返回一個浮點數(shù)。
具體小案例如下:
import random
random.uniform(5, 10)
Out[279]: 9.171064277882996
random.uniform(7, 14)
Out[280]: 10.991165154571751
知識點3:刪除列表元素
可以使用 del 語句來刪除列表的元素,如下實例:
list1 = ['physics', 'chemistry', 1997, 2000]
del list1[2]
list1
Out[283]: ['physics', 'chemistry', 2000]
知識點4:代碼運行報錯匯總
學習參考鏈接:機器學習實戰(zhàn)Py3.x填坑記—樸素貝葉斯
代碼運行報錯1
問題點:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 199: illegal multibyte sequence原因:
因為有可能文件中存在類似“?”非法字符,按以下方法更改后,代碼能有效運行.更改前:
wordList = textParse(open('email/spam/%d.txt' % i).read()
wordList = textParse(open('email/ham/%d.txt' % i).read()
- 更改后:
wordList = textParse(open('email/spam/%d.txt' % i, "rb").read().decode('GBK','ignore') )
wordList = textParse(open('email/ham/%d.txt' % i, "rb").read().decode('GBK','ignore') )
代碼運行報錯2
- 問題點:
del(trainingSet[randIndex])
TypeError: 'range' object doesn't support item deletion - 原因:
因為是python3中range不返回數(shù)組對象,而是返回range對象.方法是將代碼del(trainingSet[randIndex])上面第4行代碼進行修改.按以下方法更改后,代碼能有效運行. - 更改前:
trainingSet = range(50)
- 更改后:
trainingSet = list(range(50))