标签:
朴素贝叶斯是贝叶斯决策理论的一部分。
使用决策树方法对数据进行分类不会非常成功,二和简单的概率计算相比,kNN的计算量太大,因此一般问题使用概率比较方法。
定义贝叶斯分类准则:
其中c 为类别,x, y为坐标。
使用贝叶斯准则,可以通过一直的三个概率值来计算未知的概率值。
机器学习的一个重要应用就是文档的自动分类。 在文档分类中,整个文档(如电子邮件)是实例,而电子邮件中的某些元素则构成特征。虽然电子邮件是一种会不断增加的文本,但我们同样也可以对新闻报道,用户留言,政府公文等其他任意类型的文本进行分类。 我们可以观察文档中出现的词, 并把每个词的出现或者不出现作为一个特征,这样得到的特征数目就会跟词汇表中的词目一样多。 朴素贝叶斯是上节介绍的贝叶斯分类器的一个扩展, 适用于文档分类的常用算法。
朴素贝叶斯的一般过程:
1 | 收集数据 | 可以使用任何算法。 |
2 | 准备数据 | 需要数值型或者布尔型数据 |
3 | 分析数据 | 又大量特征时,绘制特征作用不大,此时使用直方图效果更好 |
4 | 训练算法 | 计算不同的独立特征的条件概率 |
5 | 测试算法 | 计算错误率 |
6 | 使用算法 | 一个常见的朴素贝叶斯应用使文档分类。 可以在任意的分类场景中使用朴素贝叶斯分类器,不一定非要使文本 |
要从文本中获取特征, 需要先拆分文本。特征来自文本的词条(token), 一个词条是字符的任意组合。 可以把词条想象为单词, 也可以使用非单词词条,如URL, IP地址或者任意其他字符串。然后将每个文本片段表示为一个单词向量,其中值为1表示词条出现在文档中,0表示词条未出现。
以在线社区的留言板为例。为了不影响社区的发展,我们要屏蔽侮辱性的言论, 所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言, 那么就将该留言标识为内容不当。过滤这类内容是一个很常见的需求。对此问题建立两个类别: 侮辱类和非侮辱类,使用1和0表示
将把文本看成单词向量或者词条向量,即将句子转换为向量。考虑出现在所有文档中的所有单词,再决定将哪些词纳入词汇表或者说所要的词汇集合, 然后必须要将每一篇文档转换为词汇表上的向量。词表到向量的转换函数:
def loadDataSet(): postingList=[[‘my‘, ‘dog‘, ‘has‘, ‘flea‘, ‘problems‘, ‘help‘, ‘please‘], [‘maybe‘, ‘not‘, ‘take‘, ‘him‘, ‘to‘, ‘dog‘, ‘park‘, ‘stupid‘], [‘my‘, ‘dalmation‘, ‘is‘, ‘so‘, ‘cute‘, ‘I‘, ‘love‘, ‘him‘], [‘stop‘, ‘posting‘, ‘stupid‘, ‘worthless‘, ‘garbage‘], [‘mr‘, ‘licks‘, ‘ate‘, ‘my‘, ‘steak‘, ‘how‘, ‘to‘, ‘stop‘, ‘him‘], [‘quit‘, ‘buying‘, ‘worthless‘, ‘dog‘, ‘food‘, ‘stupid‘]] classVec = [0,1,0,1,0,1] #1 is abusive, 0 not return postingList,classVec def createVocabList(dataSet): vocabSet = set([]) #create empty set for document in dataSet: # 创建两个集合的并集 vocabSet = vocabSet | set(document) #union of the two sets return list(vocabSet) def setOfWords2Vec(vocabList, inputSet): # 创建一个其中所含元素都为0的向量 returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] = 1 else: print "the word: %s is not in my Vocabulary!" % word return returnVec
现在已经知道了一个词是否出现在一篇文档中,也知道该文档所属的类别。令w作为一个向量于是有: P(ci|w) = P(w|ci)P(ci)/P(w)
我们将使用上述公式,对每个类计算该值,然后比较这两个概率值的大小。首先通过类别i(侮辱类和非侮辱类) 中文档数除以总的文档数来计算概率P(ci)。接下来计算P(w|ci), 根据朴素贝叶斯假设,如果w展开为一个个独立特征, 那么概率可以写作P(w0, w1,w2..... wn|ci)。假设苏由此都互相独立, 该假设也称作条件独立性假设,意味着可以使用P(w0|ci)P(w1|ci)P(w2|ci)......P(wn|ci)计算上述概率,简化计算过程。
伪代码如下:
计算每个类别的文档数目 对每篇训练文档: 对每个类别: 如果词条出现在文档中-> 增加该词条的计数值 增加所有词条的计数值 对每个类别: 对每个词条: 将该词条的数目除以总词条数目得到条件概率 返回每个类别的条件概率
朴素贝叶斯分类器训练函数:
def trainNB0(trainMatrix,trainCategory): numTrainDocs = len(trainMatrix) numWords = len(trainMatrix[0]) pAbusive = sum(trainCategory)/float(numTrainDocs) p0Num = ones(numWords); p1Num = ones(numWords) #change to ones() p0Denom = 2.0; p1Denom = 2.0 #change to 2.0 for i in range(numTrainDocs): if trainCategory[i] == 1: p1Num += trainMatrix[i] p1Denom += sum(trainMatrix[i]) else: p0Num += trainMatrix[i] p0Denom += sum(trainMatrix[i]) p1Vect = log(p1Num/p1Denom) #change to log() p0Vect = log(p0Num/p0Denom) #change to log() return p0Vect,p1Vect,pAbusive
现在已经准备好构建完整的分类器,朴素贝叶斯分类函数如下:
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise mult p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1) if p1 > p0: return 1 else: return 0 def testingNB(): listOPosts,listClasses = loadDataSet() myVocabList = createVocabList(listOPosts) trainMat=[] for postinDoc in listOPosts: trainMat.append(setOfWords2Vec(myVocabList, postinDoc)) p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses)) testEntry = [‘love‘, ‘my‘, ‘dalmation‘] thisDoc = array(setOfWords2Vec(myVocabList, testEntry)) print testEntry,‘classified as: ‘,classifyNB(thisDoc,p0V,p1V,pAb) testEntry = [‘stupid‘, ‘garbage‘] thisDoc = array(setOfWords2Vec(myVocabList, testEntry)) print testEntry,‘classified as: ‘,classifyNB(thisDoc,p0V,p1V,pAb)
将每个词的出现与否作为一个特征, 这个可以被描述为词集模型。如果一个词在文档中出现不止一次,这可能意味着包含该词是否出现在文档中所不能表达的某种信息。因此使用词袋模型。词袋模型中,每个单词可以出现多次, 而在刺激中, 每个词只能出现一次。
朴素贝叶斯词袋模型代码:
def bagOfWords2VecMN(vocabList, inputSet): returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] += 1 return returnVec
标签:
原文地址:http://www.cnblogs.com/keltoy/p/5396252.html