日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

朴素贝叶斯算法实现 豆瓣Top250电影评价的情感分析与预测。​

發布時間:2024/5/14 编程问答 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 朴素贝叶斯算法实现 豆瓣Top250电影评价的情感分析与预测。​ 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本文使用樸素貝葉斯算法實現 豆瓣Top250電影評價的情感分析與預測。

最近在學習自然語言正負面情感的處理問題,但是絕大部分能搜索到的實踐都是Kggle上IMDB影評的情感分析。

所以在這里我就用最基礎的樸素貝葉斯算法來對豆瓣的影評進行情感分析與預測。

在這里我參考了?https://github.com/aeternae/IMDb_Review,萬分感謝。

樸素貝葉斯分類器

貝葉斯分類是一類分類算法的總稱,這類算法均以貝葉斯定理為基礎,故統稱為貝葉斯分類。

這種算法常用來做文章分類,垃圾郵、件垃圾評論分類,樸素貝葉斯的效果不錯并且成本很低。

已知某條件概率,如何得到兩個事件交換后的概率,也就是在已知P(A|B)的情況下如何求得P(B|A)。

P(B|A)表示事件A已經發生的前提下,事件B發生的概率,叫做事件A發生下事件B的條件概率。

樸素貝葉斯的公式
P ( B ∣ A ) = P ( A ∣ B ) P ( B ) P ( A ) P(B|A) = \frac{P(A|B)P(B)}{P(A)}P(B∣A)=P(A)P(A∣B)P(B)?

一個通俗易懂的視頻教程

Youtube?https://www.youtube.com/watch?v=AqonCeZUcC4

舉個不太恰當的例子

我們想知道做程序員與禿頭之間的關系,我們就可以用樸素貝葉斯公式來進行計算。

我們現在想求?P(禿頭|做程序員)?的概率, 也就是做程序員就會禿頭的概率

我這輩子都不會禿頭 (((o(゚▽゚)o))) !!!

代入樸素貝葉斯公式

P ( 禿 頭 ∣ 做 程 序 員 ) = P ( 做 程 序 員 ∣ 禿 頭 ) P ( 禿 頭 ) P ( 做 程 序 員 ) P(禿頭|做程序員) = \frac{P(做程序員|禿頭)P(禿頭)}{P(做程序員)}P(禿頭∣做程序員)=P(做程序員)P(做程序員∣禿頭)P(禿頭)?

已知數據如下表

姓名職業是否禿頭
奎托斯戰神
殺手47號殺手
埼玉超人
滅霸計生辦主任
杰森 斯坦森硬漢
某某996程序員程序員
程序員

基于樸素貝葉斯公式,由以上這張表我們可以求出:
P ( 禿 頭 ∣ 做 程 序 員 ) = 1 6 ? 6 7 2 7 = 21 42 = 1 2 P(禿頭|做程序員) = \frac{\frac16 * \frac67}{\frac27} = \frac{21}{42} = \frac{1}{2}P(禿頭∣做程序員)=72?61??76??=4221?=21?
上面這個例子就簡單的描述了樸素貝葉斯公式的基本用法。

接下來我就使用豆瓣Top250排行榜的影評來使用樸素貝葉斯進行好評與差評的訓練與預測。

豆瓣Top250影評情感分析

首先需要豆瓣Top250影評的語料,我用Scrapy抓取了5w份語料,用于訓練與驗證。

豆瓣影評爬蟲?GitHub - 3inchtime/douban_movie_review: 豆瓣Top250影評爬蟲(用于情感分析語料)

有了語料之后我們就可以開始實際開發了。

這里建議使用jupyter來開發操作。

以下代碼全部在我的Github上可以看到,歡迎大家提出建議。

GitHub - 3inchtime/douban_sentiment_analysis: 基于樸素貝葉斯實現的豆瓣影評情感分析

首先加載語料

# -*- coding: utf-8 -*- import random import numpy as np import csv import jiebafile_path = './data/review.csv' jieba.load_userdict('./data/userdict.txt')# 讀取保存為csv格式的語料 def load_corpus(corpus_path):with open(corpus_path, 'r') as f:reader = csv.reader(f)rows = [row for row in reader]review_data = np.array(rows).tolist()random.shuffle(review_data)review_list = []sentiment_list = []for words in review_data:review_list.append(words[1])sentiment_list.append(words[0])return review_list, sentiment_list

在訓練之前,一般均會對數據集做shuffle,打亂數據之間的順序,讓數據隨機化,這樣可以避免過擬合。所以使用random.shuffle()方法打亂數據。

jieba.load_userdict('./data/userdict.txt')這里我自己做了一個詞典,防止部分結巴分詞的不準確,可以提高約1%左右的準確率。

比如不是很喜歡這句,jieba會分成’不是‘,’很喜歡‘兩個詞,這樣導致這句話很大概率會被預測為好評。

所以這里我在自定義的詞典中分好了很多類似這樣的詞,提高了一點點準確率。

然后將全部的語料按1:4分為測試集與訓練集

n = len(review_list) // 5train_review_list, train_sentiment_list = review_list[n:], sentiment_list[n:] test_review_list, test_sentiment_list = review_list[:n], sentiment_list[:n]

分詞

使用jieba分詞,將語料進行分詞,并且去除stopwords。

import re import jiebastopword_path = './data/stopwords.txt'def load_stopwords(file_path):stop_words = []with open(file_path, encoding='UTF-8') as words:stop_words.extend([i.strip() for i in words.readlines()])return stop_wordsdef review_to_text(review):stop_words = load_stopwords(stopword_path)# 去除英文review = re.sub("[^\u4e00-\u9fa5^a-z^A-Z]", '', review)review = jieba.cut(review)# 去掉停用詞if stop_words:all_stop_words = set(stop_words)words = [w for w in review if w not in all_stop_words]return words# 用于訓練的評論 review_train = [' '.join(review_to_text(review)) for review in train_review_list] # 對于訓練評論對應的好評/差評 sentiment_train = train_sentiment_list# 用于測試的評論 review_test = [' '.join(review_to_text(review)) for review in test_review_list] # 對于測試評論對應的好評/差評 sentiment_test = test_sentiment_list

TF*IDF與詞頻向量化

TF-IDF(是一種常用于信息處理和數據挖掘的加權技術。根據詞語的在文本中出現的次數和在整個語料中出現的文檔頻率來計算一個詞語在整個語料中的重要程度。

它的優點是能過濾掉一些常見的卻無關緊要本的詞語,同時保留影響整個文本的重要字詞。

使用Countvectorizer()將一個文檔轉換為向量,計算詞匯在文本中出現的頻率。

CountVectorizer類會將文本中的詞語轉換為詞頻矩陣,例如矩陣中包含一個元素a[i] [j],它表示j詞在i類文本下的詞頻。它通過fit_transform函數計算各個詞語出現的次數。

TfidfTransformer用于統計vectorizer中每個詞語的TF-IDF值。

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer from sklearn.pipeline import Pipeline from sklearn.naive_bayes import MultinomialNBcount_vec = CountVectorizer(max_df=0.8, min_df=3)tfidf_vec = TfidfVectorizer()# 定義Pipeline對全部步驟的流式化封裝和管理,可以很方便地使參數集在新數據集(比如測試集)上被重復使用。 def MNB_Classifier():return Pipeline([('count_vec', CountVectorizer()),('mnb', MultinomialNB())])

max_df?這個參數的作用是作為一個閾值,當構造語料庫的關鍵詞集的時候,如果某個詞的詞頻大于max_df,這個詞不會被當作關鍵詞。

如果這個參數是float,則表示詞出現的次數與語料庫文檔數的百分比,如果是int,則表示詞出現的次數。

min_df類似于max_df,不同之處在于如果某個詞的詞頻小于min_df,則這個詞不會被當作關鍵詞

這樣我們就成功的構造出了用于訓練以及測試的Pipeline

然后用?Pipeline.fit()對訓練集進行訓練

再直接用?Pipeline.score()?對測試集進行預測并評分

mnbc_clf = MNB_Classifier()# 進行訓練 mnbc_clf.fit(review_train, sentiment_train)# 測試集準確率 print('測試集準確率: {}'.format(mnbc_clf.score(review_test, sentiment_test)))

這樣我們就完成了整個從訓練到測試的全部流程。

基本上測試集的正確率在79%-80%左右。

因為電影評論中有很大一部分好評中會有負面情感的詞語,例如在紀錄片《海豚灣》中

我覺得大部分看本片會有感的人,都不知道,中國的白暨豚已經滅絕8年了,也不會知道,長江里的江豚也僅剩1000左右了。與其感慨,咒罵日本人如何捕殺海豚,不如做些實際的事情,保護一下長江里的江豚吧,沒幾年,也將絕跡了。中國人做出來的事情,也不會比小日本好到哪兒去。

所以說如果將這種類似的好評去除,則可以提高準確率。

保存訓練好的模型

# 先轉換成詞頻矩陣,再計算TFIDF值 tfidf = tfidftransformer.fit_transform(vectorizer.fit_transform(review_train)) # 樸素貝葉斯中的多項式分類器 clf = MultinomialNB().fit(tfidf, sentiment_train)with open(model_export_path, 'wb') as file:d = {"clf": clf,"vectorizer": vectorizer,"tfidftransformer": tfidftransformer,}pickle.dump(d, file)

使用訓練好的模型進行影評情感預測

這里我直接貼上全部的源代碼,代碼非常簡單,我將整個處理邏輯封裝為一個類,這樣就非常方便使用了。

有需要直接可以在我的Github上clone

# -*- coding: utf-8 -*- import re import pickleimport numpy as np import jiebaclass SentimentAnalyzer(object):def __init__(self, model_path, userdict_path, stopword_path):self.clf = Noneself.vectorizer = Noneself.tfidftransformer = Noneself.model_path = model_pathself.stopword_path = stopword_pathself.userdict_path = userdict_pathself.stop_words = []self.tokenizer = jieba.Tokenizer()self.initialize()# 加載模型def initialize(self):with open(self.stopword_path, encoding='UTF-8') as words:self.stop_words = [i.strip() for i in words.readlines()]with open(self.model_path, 'rb') as file:model = pickle.load(file)self.clf = model['clf']self.vectorizer = model['vectorizer']self.tfidftransformer = model['tfidftransformer']if self.userdict_path:self.tokenizer.load_userdict(self.userdict_path)# 過濾文字中的英文與無關文字def replace_text(self, text):text = re.sub('((https?|ftp|file)://)?[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|].(com|cn)', '', text)text = text.replace('\u3000', '').replace('\xa0', '').replace('”', '').replace('"', '')text = text.replace(' ', '').replace('?', '').replace('\n', '').replace('\r', '').replace('\t', '').replace(')', '')text_corpus = re.split('[!。?;……;]', text)return text_corpus# 情感分析計算def predict_score(self, text_corpus):# 分詞docs = [self.__cut_word(sentence) for sentence in text_corpus]new_tfidf = self.tfidftransformer.transform(self.vectorizer.transform(docs))predicted = self.clf.predict_proba(new_tfidf)# 四舍五入,保留三位result = np.around(predicted, decimals=3)return result# jieba分詞def __cut_word(self, sentence):words = [i for i in self.tokenizer.cut(sentence) if i not in self.stop_words]result = ' '.join(words)return resultdef analyze(self, text):text_corpus = self.replace_text(text)result = self.predict_score(text_corpus)neg = result[0][0]pos = result[0][1]print('差評: {} 好評: {}'.format(neg, pos))

使用時只要實例化這個分析器,并使用analyze()方法就可以了。

# -*- coding: utf-8 -*- from native_bayes_sentiment_analyzer import SentimentAnalyzermodel_path = './data/bayes.pkl' userdict_path = './data/userdict.txt' stopword_path = './data/stopwords.txt' corpus_path = './data/review.csv'analyzer = SentimentAnalyzer(model_path=model_path, stopword_path=stopword_path, userdict_path=userdict_path) text = '倍感失望的一部諾蘭的電影,感覺更像是盜夢幫的一場大雜燴。雖然看之前就知道肯定是一部無法超越前傳2的蝙蝠狹,但真心沒想到能差到這個地步。節奏的把控的失誤和角色的定位模糊絕對是整部影片的硬傷。' analyzer.analyze(text=text)

總結

以上是生活随笔為你收集整理的朴素贝叶斯算法实现 豆瓣Top250电影评价的情感分析与预测。​的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。