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

下面将使用来自不同城市的广告训练一个分类器,然后观察分类器的效果。我们的目的并不是使用该分类器进行分类,而是通过观察单词和条件概率值来发现与特定城市相关的内容。
收集数据:导入RSS源

Python count() 方法用于统计字符串里某个字符出现的次数。可选参数为在字符串搜索的开始与结束位置。
使用iteritems()这个函数得到我们字典中的所有元素,就是键-值对{‘yes’:2,’maybe’:1}
之后定义一个叫做key的函数,这个名字可以任意取,key只是习惯性定义的
之后通过itemgetter函数对字典中的元素进行排序,operator.itemgetter(1)表示按照元素的第二个进行排序,指按键-值对的值来排,也就是分类出现的多少。
reverse=True 表示按照递减的顺序来排序,即降序。

def calcMostFreq(vocabList,fullText):#该函数遍历词汇表中的每个词并统计它在文本中出现的次数,
    # 然后根据出现的次数从高到低对词典进行排序,最后返回排序最高的30个单词。
    import operator
    freqDict = {}#出现频率,建立字典
    for token in vocabList:
        freqDict[token]=fullText.count(token)#字典的键对应这个词在fullText中出现的次数
        sortedFreq = sorted(freqDict.items(), key=operator.itemgetter(1),reverse=True)
    return sortedFreq[0:30]

def localWords(feed1,feed0):#使用两个RSS源作为参数
    import feedparser
    docList=[];classList = []; fullText = []
    minLen = min(len(feed1['entries']),len(feed0['entries']))
    for i in range(minLen):  
        wordList = textParse(feed1['entries'][i]['summary'])  # 进行文本分切,每次访问一条RSS源
        docList.append(wordList)  # docList最后是一个放满了n个被切分后的RSS源
        fullText.extend(wordList)  # fullText是一个有n个元素的列表
        classList.append(1)  # n个1,0交叉的列表
        wordList = textParse(feed0['entries'][i]['summary'])
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
    vocabList = createVocabList(docList)  # 找出n个RSS源中不重复的词组成列表
    top30Words = calcMostFreq(vocabList,fullText)#得到出现次数最多的前30个单词
    for pairW in top30Words:
        if pairW[0] in vocabList:vocabList.remove(pairW[0])#移去vocabList中那些出现频率高的词
    trainingSet = list(range(2*minLen));
    testSet = []  # trainingSet是一个整数列表,其中的值从0-2len
    for i in range(20):
        randIndex = int(random.uniform(0, len(trainingSet)))  # 从0-49随机选择10个文件
        testSet.append(trainingSet[randIndex])  # testSet是一个放了10个文件序列号的列表
        del (trainingSet[randIndex])  # 删去trainingSet中已被随机挑选出的元素
    trainMat = [];
    trainClasses = []  # trainMat构建一个文档矩阵,trainClasses每片文档类别标签构成的向量
    for docIndex in trainingSet:  # 循环遍历训练集的所有文档  trainingSet40
        trainMat.append(setOfWords2Vec(vocabList, docList[docIndex]))  # 对每封邮件基于词汇表使用setOfWords2Vec构建词向量
        trainClasses.append(classList[docIndex])  # 由1和0组成的列表,1代表邮件来自spam,0代表邮件来自ham
    p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))
    errorCount = 0
    for docIndex in testSet:  # 遍历测试集
        wordVector = setOfWords2Vec(vocabList, docList[docIndex])
        if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:  # 判断分类器的结果与事实是否相同
            errorCount += 1
    print('the error rate is: ', float(errorCount) / len(testSet))
    return vocabList,p0V,p1V

一个现象,留言中出现次数最多的前30个词涵盖了所有用词的30%,在进行测试的时候,vocabList的大小约为3000个词,也就是说,词汇表中的一小部分单词却占据了所有文本用词的一大部分。
在移除高频词的同时,从某个预定词表中移除结构上的辅助词,该词表称为停用词表。

分析数据:显示地域相关的用词
(Python将不能修改的值称为是不可变的,而不可变的列表称为元组,用())
lambda函数是一种快速定义单行的最小函数

>>> def f(x,y):  
...   return x*y  
...    
>>> f(2,3)  

>>> g = lambda x,y: x*y  
>>> g(2,3) 
def getTopWords(ny,sf):#使用两个RSS源作为输入,返回大于某个阈值的所有词
    import operator
    vocabList,p0V,p1V=localWords(ny,sf)
    topNY=[];topSF=[]#创建两个列表用于元组的存储
    for i in range(len(p0V)):#p0V是一个数组,元素是RSS源中每条信息对应的vocabList中的每个词出现的概率
        if p0V[i] > -6.0 : topSF.append((vocabList[i],p0V[i]))储存这个词和这个词出现的概率
        if p1V[i] > -6.0 : topSF.append((vocabList[i], p1V[i]))
    sortedSF = sorted(topSF, key=lambda pair: pair[1],reverse=True)
    print ("SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**")
    for item in sortedSF:
        print item[0]
    sortedNY = sorted(topNY, key=lambda pair: pair[1], reverse=True)
    print ("NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**")
    for item in sortedNY:
        print item[0]

key=lambda pair: pair[1]这里其实每看懂

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

在之前,注释掉用于移除高频词的三行代码后,也就是说不移除高频词,错误率为54%,而保留得到的错误率为70%,移除固定的停用词,分类错误率也将会降低。

贝叶斯 通过特征之间的条件独立性假设,降低对数据量的需求。改进,词袋模型在解决文档分类问题上比词集模型有所提高,移除停用词。

停用词:文本中出现频率很高,但实际意义又不大的词。这一类主要包括了语气助词、副词、介词、连词等,通常自身并无明确意义,只有将其放入一个完整的句子中才有一定作用的词语。如常见的“的”、“在”、“和”、“接着”之类,比如“SEO研究院是原创的SEO博客”这句话中的“是”、“的”就是两个停用词。

猜你喜欢

转载自blog.csdn.net/qq_42799920/article/details/81348136