利用基于概率論的貝葉斯分類器酪惭,對收取的郵件【英文】進(jìn)行分類氯哮。【簡易版】
文本分類待續(xù)
1. 收集數(shù)據(jù)
收集的數(shù)據(jù)包含兩類:垃圾郵件和正常郵件躏敢。每類中有25個(gè)樣本闷愤。
2. 數(shù)據(jù)處理
1)要從文本中獲取特征,需要拆分文本件余,分成詞條讥脐。
2)獲取數(shù)據(jù)字典
3)向量化處理,方便進(jìn)行特征提取啼器。
2.1 分詞
def textParse(bigString):
? ? import re
? ? listOfTokens = re.split(r'\W*',bigString)
? ? return [tok.lower() for tok in listOfTokens if len(tok)>2]#取出掉長度過短的單詞
\W: 非單詞字符
2.2 獲取數(shù)據(jù)字典
def createVocabList(dataSet):
? ? vocabSet = set()
? ? for doc in dataSet:
? ? ? ? vocabSet = vocabSet | set(doc)
? ? return list(vocabSet)
vocabSet | set(doc):相當(dāng)于概率論中集合之間的并運(yùn)算旬渠。
集合特點(diǎn):無序;唯一镀首。
2.3 向量化處理
向量化處理又分為兩種情況:
1)詞集模型:詞集坟漱,顧名思義,就是一個(gè)集合更哄。只關(guān)注token是否出現(xiàn)芋齿,并不關(guān)注出現(xiàn)的次數(shù)。
2)詞袋模型:關(guān)注token的出現(xiàn)次數(shù)成翩,有較好的處理結(jié)果觅捆。
詞集模型:
def setOfWords2Vec(vocabList, inputSet):
? ? returnVec = [0]*len(vocabList)
? ? for word in inputSet:
? ? ? ? if word in vocabList:
? ? ? ? ? ? returnVec[vocabList.index(word)] = 1
? ? return returnVec
詞袋模型:
def bagOfWords2VecMN(vocabList, inputList):
? ? returnVec = [0]*len(vocabList)
? ? for word in inputList:
? ? ? ? if word in vocabList:
? ? ? ? ? ? returnVec[vocabList.index(word)] += 1
? ? return returnVec
3. 訓(xùn)練模型
樸素貝葉斯是基于概率的分類器,其訓(xùn)練過程就是計(jì)算各個(gè)概率的過程麻敌。
def trainNB0(trainMatrix, trainCategory):
? ? numTrainDocs = len(trainMatrix)
? ? numWords = len(trainMatrix[0])
? ? pAbusive = sum(trainCategory)/float(len(trainCategory))
? ? p0Sum = ones(numWords); p1Sum = ones(numWords)#0概率處理
? ? p0Denom = 2.0; p1Denom = 2.0
? ? for i in range(numTrainDocs):
? ? ? ? if trainCategory[i] == 1:
? ? ? ? ? ? p1Sum += trainMatrix[i]
? ? ? ? ? ? p1Denom += sum(trainMatrix[i])#sum(trainMatrix[i]):文章i的詞匯數(shù)
? ? ? ? else:
? ? ? ? ? ? p0Sum += trainMatrix[i]
? ? ? ? ? ? p0Denom += sum(trainMatrix[i])
? ? p1Vec = log(p1Sum/float(p1Denom))#下溢出處理
? ??p0Vec = log(p0Sum/float(p0Denom))? ?
????return p1Vec, p0Vec, pAbusive
使用numpy.array來計(jì)算栅炒,方便、快捷术羔。
4.測試分類器
基本分類器:
def classifyNB(vec2Classify, p1Vec, p0Vec, pAbusive):
? ? p1 = sum(vec2Classify * p1Vec) + log(pAbusive)
? ? p0 = sum(vec2Classify * p0Vec) + log(1-pAbusive)
? ? if p1 > p0:
? ? ? ? return 1
? ? else:
? ? ? ? return 0
垃圾郵件測試程序:
def spamTest():
? ? docList = []; classList = []
? ? for i in range(1,26):
? ? ? ? bigString = open('email/spam/%d.txt' % i).read()#讀取郵件內(nèi)容
? ? ? ? wordList = textParse(bigString)
? ? ? ? docList.append(wordList)
? ? ? ? classList.append(1)
? ? ? ? bigString = open('email/ham/%d.txt' %i).read()
? ? ? ? wordList = textParse(bigString)
? ? ? ? docList.append(wordList)
? ? ? ? classList.append(0)
? ? vocabList = createVocabList(docList)
? ? #劃分訓(xùn)練集和測試集
? ? trainSet = range(50); testSet = []#存儲下標(biāo)
? ? for i in range(10):
? ? ? ? randIndex = int(random.uniform(0,len(trainSet)))#產(chǎn)生一個(gè)隨機(jī)數(shù)
? ? ? ? testSet.append(trainSet[randIndex])
? ? ? ? del trainSet[randIndex]
? ? trainMat = []; trainClasses = []
? ? for docIndex in trainSet:
? ? ? ? trainMat.append(setOfWords2Vec(vocabList,docList[docIndex]))
? ? ? ? trainClasses.append(classList[docIndex])
? ? p1Vec, p0Vec, pSpam = trainNB0(trainMat,trainClasses)
? ? errorCount = 0
? ? for docIndex in testSet:
? ? ? ? wordVec = setOfWords2Vec(vocabList,docList[docIndex])
? ? ? ? predict = classifyNB(wordVec,p1Vec,p0Vec,pSpam)
? ? ? ? if predict != classList[docIndex]:
? ? ? ? ? ? errorCount += 1
? ? errorRate = float(errorCount)/len(testSet)
? ? print ("the error rate is %f" % errorRate)
? ? return errorRate
使用誤分率作為衡量分類器的數(shù)據(jù)指標(biāo)赢赊。
由于測試集的生成是隨機(jī)的,所以分類器誤分率每次運(yùn)行結(jié)果不一致级历。通過運(yùn)行10次的平均值作為分類器的分類效果释移。
5. 小結(jié)
1)貝葉斯概率及貝葉斯 準(zhǔn)則提供了一種利用已知值來估計(jì)位置概率的有效方法;
2)樸素貝葉斯假設(shè):數(shù)據(jù)特征之間相互獨(dú)立寥殖。雖然該假設(shè)一般情況下玩讳,并不滿足涩蜘。但是!盡管不滿足熏纯,使用樸素貝葉斯進(jìn)行分類同诫,仍然取得了很好的效果!U晾健(很氣......)
3)優(yōu)點(diǎn):在數(shù)據(jù)較少的情況下仍然有效误窖,可以處理多類別問題;
4)缺點(diǎn):對輸入數(shù)據(jù)的準(zhǔn)備方式較為敏感往扔;
5)使用數(shù)據(jù)類型:標(biāo)稱型數(shù)據(jù)(就是名詞性數(shù)據(jù))
6)中文文本分類:之前做過一個(gè)大作業(yè)贩猎,就是關(guān)于中文文本分類,100萬新聞?wù)Z料萍膛,10個(gè)類別吭服。
To Be Continued!!!
下午玩去:看看聞名已久的回音壁。