700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > python(NLP)-朴素贝叶斯(监督型学习)

python(NLP)-朴素贝叶斯(监督型学习)

时间:2022-05-22 09:43:50

相关推荐

python(NLP)-朴素贝叶斯(监督型学习)

分类算法-朴素贝叶斯(监督学习)

贝叶斯方法是一个历史悠久,有着坚实的理论基础的方法,同时处理很多问题时直接而又高效,很多高级自然语言处理模型也可以从它演化而来。因此,学习贝叶斯方法,是研究自然语言处理问题的一个非常好的切入口。

贝叶斯公式

P(X|Y)P(Y)P(Y|X)= ——————————P(X)

而它其实是由以下的联合概率公式推导出来:

P(Y,X)=P(Y|X)P(X)=P(X|Y)P(Y)

其中 P(Y) 叫做先验概率, P(Y|X) 叫做后验概率, P(Y,X) 叫做联合概率。

处理重复词语的三种方式

多项式模型

如果我们考虑重复词语的情况,也就是说,重复的词语我们视为其出现多次,直接按条件独立假设的方式推导

伯努利模型

另一种更加简化的方法是将重复的词语都视为其只出现1次(抛硬币模型)

混合模型

第三种方式是在计算句子概率时,不考虑重复词语出现的次数,但是在统计计算词语的概率P(“词语”|S)时,却考虑重复词语的出现次数,这样的模型可以叫作混合模型。

贝叶斯常见应用场景

褒贬分析

一个比较常见的应用场景是情感褒贬分析。比如你要统计微博上人们对一个新上映电影的褒贬程度评价:好片还是烂片。但是一条一条地看微博是根本看不过来,只能用自动化的方法。我们可以有一个很粗略的思路:首先是用爬虫将微博上提到这个电影名字的微博全都抓取下来,比如有10万条。然后用训练好的朴素贝叶斯分类器分别判断这些微博对电影是好评还是差评。最后统计出这些好评的影评占所有样本中的比例,就能形成微博网友对这个电影综合评价的大致估计。接下来的核心问题就是训练出一个靠谱的分类器。首先需要有打好标签的文本。这个好找,豆瓣影评上就有大量网友对之前电影的评价,并且对电影进行1星到5星的评价。我们可以认为3星以上的评论都是好评,3星以下的评论都是差评。这样就分别得到了好评差评两类的语料样本。剩下就可以用朴素贝叶斯方法进行训练了。基本思路如下:训练与测试样本:豆瓣影评的网友评论,用爬虫抓取下100万条。标签:3星以上的是好评,3星以下的是差评。特征:豆瓣评论分词后的词语。一个简单的方法是只选择其中的形容词,网上有大量的情绪词库可以为我们所用。然后再用常规的朴素贝叶斯方法进行训练。但是由于自然语言的特点,在提取特征的过程当中,有一些tricks需要注意:对否定句进行特别的处理。比如这句话“我不是很喜欢部电影,因为它让我开心不起来。”其中两个形容词“喜欢”、“开心”都是褒义词,但是因为句子的否定句,所以整体是贬义的。有一种比较简单粗暴的处理方式,就是“对否定词(“不”、“非”、“没”等)与句尾标点之间的所有形容词都采用其否定形式” 。则这句话中提取出来的形容词就应该是“不喜欢”和“不开心”。一般说来,最相关的情感词在一些文本片段中仅仅出现一次,词频模型起得作用有限,甚至是负作用,则使用伯努利模型代替多项式模型。这种情况在微博这样的小篇幅文本中似乎不太明显,但是在博客、空间、论坛之类允许长篇幅文本出现的平台中需要注意。其实,副词对情感的评价有一定影响。“不很喜欢”与“很不喜欢”的程度就有很大差异。但如果是朴素贝叶斯方法的话比较难处理这样的情况。我们可以考虑用语言模型或者加入词性标注的信息进行综合判断。这些内容我们将在之后的文章进行探讨。当然经过以上的处理,情感分析还是会有一部分误判。这里涉及到许多问题,都是情感分析的难点:情绪表达的含蓄微妙:“导演你出来,我保证不打死你。”你让机器怎么判断是褒还是贬?转折性表达:“我非常喜欢这些大牌演员,非常崇拜这个导演,非常赞赏这个剧本,非常欣赏他们的预告片,我甚至为了这部影片整整期待了一年,最后进了电影院发现这是个噩梦。” 五个褒义的形容词、副词对一个不那么贬义的词。机器自然判断成褒义,但这句话是妥妥的贬义。

拼写纠错

拼写纠错本质上也是一个分类问题。但按照错误类型不同,又分为两种情况:

非词错误(Non-word Errors):指那些拼写错误后的词本身就不合法,如将“wifi”写成“wify”;

真词错误(Real-word Errors):指那些拼写错误后的词仍然是合法的情况,如将“wifi”写成“wife”。

真词错误复杂一些,我们将在接下来的文章中进行探讨。而对于非词错误,就可以直接采用贝叶斯方法,其基本思路如下:

标签:通过计算错误词语的最小编辑距离(之前咱们提到过的),获取最相似的候选词,每个候选词作为一个分类。

特征:拼写错误的词本身。因为它就一个特征,所以没有什么条件独立性假设、朴素贝叶斯啥的。它就是纯而又纯的贝叶斯方法。

判别公式:

P(候选词i|错误词)∝P(错误词|候选词i)P(候选词i);i=1,2,3,…

训练样本1:该场景下的正常用词语料库,用于计算 P(候选词i) 。

P(候选词i)=候选词出现的次数所有词出现的次数

训练样本2:该场景下错误词与正确词对应关系的语料库,用于计算 P(错误词|候选词i)

P(错误词|候选词i)=候选词被拼写成该“错误词”的次数候选词出现的次数

由于自然语言的特点,有一些tricks需要注意:

据统计,80%的拼写错误编辑距离为1,几乎所有的拼写错误编辑距离小于等于2。我们只选择编辑距离为1或2的词作为候选词,这样就可以减少大量不必要的计算。

由于我们只选择编辑距离为1或2的词,其差别只是一两个字母级别差别。因此计算似然函数的时候,可以只统计字母层面的编辑错误,这样搜集的样本更多,更满足大数定律,也更简单。对于编辑距离为1的似然函数计算公式可以进化为:

P(错误词|候选词i)=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪字母“xy”被拼写成“y”的次数字母“xy”出现的次数,字母“x”被拼写成“xy”的次数字母“x”出现的次数,字母“x”被拼写成“y”的次数字母“x”出现的次数,字母“xy”被拼写成“yx的次数字母“xy”出现的次数,

键盘上临近的按键更容易拼写错误,据此可以对上面这个条件概率进行加权。

python使用贝叶斯算法

语种检测

使用py2.7环境代码中有注释,两种方法都可以实现最终测试~

# coding: utf-8in_f = open('data/data.csv')lines = in_f.readlines()in_f.close()dataset = [(line.strip()[:-3], line.strip()[-2:]) for line in lines]print dataset[:1]# 为了一会儿检测一下咱们的分类器效果怎么样,我们需要一份测试集。# 所以把原数据集分成训练集的测试集,咱们用sklearn自带的分割函数。from sklearn.model_selection import train_test_split# 解包元组x, y = zip(*dataset)x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1)print len(x_train)import re# 模型要有好效果,数据质量要保证# 我们用正则表达式,去掉噪声数据def remove_noise(document):noise_pattern = pile("|".join(["http\S+", "\@\w+", "\#\w+"]))clean_text = re.sub(noise_pattern, "", document)return clean_text.strip()print remove_noise("Trump images are now more popular than cat gifs. @trump #trends http://www.trumptrends.html")# 下一步要做的就是在降噪数据上抽取出来有用的特征啦,我们抽取1-gram和2-gram的统计特征from sklearn.feature_extraction.text import CountVectorizervec = CountVectorizer(lowercase=True, # lowercase the textanalyzer='char_wb', # tokenise by character ngramsngram_range=(1, 2), # use ngrams of size 1 and 2max_features=1000, # keep the most common 1000 ngramspreprocessor=remove_noise)vec.fit(x_train)def get_features(x):res = vec.transform(x)# print resreturn res# 把分类器import进来并且训练from sklearn.naive_bayes import MultinomialNBclassifier = MultinomialNB()classifier.fit(vec.transform(x_train), y_train)# classifier.MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)# 0.9770621967357741print classifier.score(vec.transform(x_test), y_test)print classifier.predict(get_features(['Yo también estoy muy bien.', 'hello' ]))# 能在1500句话上,训练得到准确率97.7%的分类器,效果还是不错的。# 如果大家加大语料,准确率会非常高。# 规范化,写成一个classimport refrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn.model_selection import train_test_splitfrom sklearn.naive_bayes import MultinomialNBclass LanguageDetector():def __init__(self, classifier=MultinomialNB()):self.classifier = classifierself.vectorizer = CountVectorizer(ngram_range=(1, 2), max_features=1000, preprocessor=self._remove_noise)def _remove_noise(self, document):noise_pattern = pile("|".join(["http\S+", "\@\w+", "\#\w+"]))clean_text = re.sub(noise_pattern, "", document)return clean_textdef features(self, X):return self.vectorizer.transform(X)def fit(self, X, y):self.vectorizer.fit(X)self.classifier.fit(self.features(X), y)def predict(self, x):return self.classifier.predict(self.features([x]))def score(self, X, y):return self.classifier.score(self.features(X), y)in_f = open('data/data.csv')lines = in_f.readlines()in_f.close()dataset = [(line.strip()[:-3], line.strip()[-2:]) for line in lines]print datasetx, y = zip(*dataset)# 分类,分出训练集,测试集x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1)print x_trainprint x_testprint y_trainprint y_testlanguage_detector = LanguageDetector()language_detector.fit(x_train, y_train)print(language_detector.predict('Yo también estoy muy bien.'))# 测试出成功率print(language_detector.score(x_test, y_test))

输入语种后分析为西班牙语

可检测 英语en,法语fr,德语de,西班牙语es,意大利语it,荷兰语nl

没怎么发过csdn,data.csv数据无法上传训练集数据可私我发给你最近在学习nlp,机器学习,有兴趣的伙伴可以一起交流!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。