基于豆瓣影评数据的完整文本分析
?
作者:沂水寒城,CSDN博客專家,個人研究方向:機器學習、深度學習、NLP、CV
Blog:?http://yishuihancheng.blog.csdn.net
文本分析中很多的工作都是基于評論數據來進行的,比如:滴滴出行的評價數據、租房的評價數據、電影的評論數據等等,從這些預料數據中能夠挖掘出來客戶群體對于某種事物或者事情的看法,較為常見的工作有:輿情分析、熱點挖掘和情感分析。
在之前的工作經歷中,我對微博數據和電影評論數據進行文本分析工作較多,今天的文章主要就是想以影評數據為切入點介紹一些自己文本分析的流程和方法,本文簡單的實現流程如下圖所示:
主要分為:數據采集、數據清洗存儲、主題挖掘、分詞與詞頻統計、詞云展示幾個部分。
一、影評數據采集
影評數據有很多網站可以去獲取,比如最常用的貓眼電影、豆瓣電影等等,本文是基于豆瓣電影完成的數據采集工作,這個具體的采集項目網上都有很多詳細的講解與實現,這里我就不再對采集過程進行過多的介紹,直接看代碼實現。
首選需要實現對于給定電影名稱獲取到其對應的id功能,因為在數據中電影數據項都是以id作為標識的,這里的代碼實現很簡單,主要是就是需要找到具體請求的API即可:
1.def?getIMDBIdByName(name='勇敢的心',save_path='id_title.txt'):?? 2.????'''''? 3.????基于劇名查詢獲取?id? 4.????'''?? 5.????url="https://movie.douban.com/j/subject_suggest?q="+urllib.quote(name)?? 6.????data=getJsonData(url)?? 7.????if?data:?? 8.????????id_list=[one['id']?for?one?in?data]?? 9.????????title_list=[one['title']?for?one?in?data]?? 10.????????with?open(save_path,'a')?as?f:?? 11.????????????for?i?in?range(len(id_list)):?? 12.????????????????f.write(','.join([id_list[i],title_list[i]]).strip()+'\n')??獲取到的電影id會存儲在我們默認的文件id_title.txt中,之后影評數據的獲取會從這里讀取數據來構建映射字典。
完成上述功能后我們就可以對給定名稱的電影獲取其對應的影評數據了,這里給出來樣例爬蟲代碼的具體實現:
1.def?demoSpider(movie_id='12345689',offset=0):?? 2.????'''''? 3.????爬蟲數據展示? 4.????'''?? 5.????res_list=[]?? 6.????url="https://movie.douban.com/subject/{0}/comments?start={1}&limit=20&sort=new_score&status=P".format(movie_id,str(offset))?? 7.????header,proxy=buildProxy()?? 8.????res=getPageHtml(url,header,proxy,flag=True,num_retries=3)?? 9.????soup=BeautifulSoup(res.content,'html5lib')?? 10.????div_comment=soup.find_all('div',class_='comment-item')??? 11.????for?one?in?div_comment:?? 12.????????username=one.find('div',class_='avatar').a['title']?? 13.????????comment_time=one.find('span',class_='comment-time')['title']?? 14.????????votes=one.find('span',class_='votes').get_text()?? 15.????????comment=one.p.get_text()?? 16.????????one_list=[username.strip(),comment_time.strip(),votes.strip(),comment.strip()]?? 17.????????print?one_list?? 18.????????res_list.append(one_list)?? 19.????????offset+=20?? 20.????????time.sleep(random.randint(3,8))?? 21.????????url="https://movie.douban.com/subject/{0}/comments?start={1}&limit=20&sort=new_score&status=P".format(movie_id,str(offset))?? 22.????????header,proxy=buildProxy()?? 23.????????res=getPageHtml(url,header,proxy,flag=True,num_retries=3)?? 24.????????soup=BeautifulSoup(res.content,'html5lib')?? 25.????????div_comment=soup.find_all('div',class_='comment-item')??? 26.????????for?one?in?div_comment:?? 27.????????????username=one.find('div',class_='avatar').a['title']?? 28.????????????comment_time=one.find('span',class_='comment-time')['title']?? 29.????????????votes=one.find('span',class_='votes').get_text()?? 30.????????????comment=one.p.get_text()?? 31.????????????one_list=[username.strip(),comment_time.strip(),votes.strip(),comment.strip()]?? 32.????????????res_list.append(one_list)?? 33.????return?res_list??仔細看上述代碼會發現,這里的實現是非常簡單的,我們的翻頁操作是基于網頁的offset偏移量來間接完成的。上述代碼實現了指定電影評論數據的采集工作。
如果在實際應用中出現大量數據采集工作的話需要考慮一些網站的反爬蟲機制,這里我較為常用的三種反反爬蟲機制主要包括:隨機休眠機制、隨機User-Agent偽裝機制和動態IP代理池構建機制,如果對這方面感興趣的話可以閱讀我的頭條號系列文章,搜索《反反爬蟲機制三重奏》即可,這里我基于代碼實現了隨機UA和代理池的功能,具體不多解釋了,直接看代碼實現即可:
1.def?buildProxy():?? 2.????'''''? 3.????構建代理信息? 4.????'''?? 5.????header_list=generateRandomUA(num=500)?? 6.????header={'User-Agent':random.choice(header_list)}?? 7.????ip_proxy=random.choice(ip_list)?? 8.????one_type,one_ip,one_port=ip_proxy[0],ip_proxy[1],ip_proxy[2]?? 9.????proxy={one_type:one_type+'://'+one_ip+':'+one_port}?? 10.????return?header,proxy??二、影評數據清洗存儲
完成第一部分的工作后,我們就采集到了所需的評論數據,但是這里的評論數據難以直接用于分析工作,我們需要對其進行解析處理后,對所需的評論文本數據進行清洗后才能夠使用,這里簡單對相關的工作進行說明。
我們隨便打開一部電影《紅海行動》的影評數據文件,找出前3條評論數據樣例如下所示:
1.評論人:夢夢夢夢?? 2.評論時間:2018-02-16?00:05:42?? 3.支持人數:14673 ? 4.評論內容:本來對這類電影不感興趣,陪著男朋友去看的,很意外,還不錯,一部很燃的片子,倆個多小時的電影,至少一個半小時的高潮,全程無尿點,據說是根據真實事件改編的,海陸空作戰,超級帥。算是春節檔電影的一股清流,大家真的要感受一下中國軍人的風采,只想說威武!!佟莉炸飛機還有狙擊手對戰那段太帥了?? 5.評論人:烏鴉火堂?? 6.評論時間:2018-02-13?15:35:16?? 7.支持人數:10557 ? 8.評論內容:春節檔最好!最好不是戰狼而是戰爭,有點類似黑鷹墜落,主旋律色彩下,真實又殘酷的戰爭渲染。故事性不強,文戲不超20分鐘,從頭打到尾,林超賢場面調度極佳,巷戰、偷襲、突擊有條不紊,軍械武器展示效果不錯。尺度超大,鋼鋸嶺式血肉橫飛,還給你看特寫!敵人如喪尸一般打不完,雙方的狙擊手都是亮點?? 9.評論人:sylvia曉霄小小?? 10.評論時間:2018-02-11?00:11:02?? 11.支持人數:7839 ? 12.評論內容:超前點映場。場面真實,劇情緊湊。中間其實很想上廁所,但是愣是沒有找到任何尿點…作為戰爭片,已超額完成任務,在真實度還原上,達到了國產影片從未有過的高度。細節處理也很妙,剝糖紙的那一段看的揪心。被海清和蔣璐霞的演技圈粉…看到最后,感覺自己整個人都在燃燒。準備春節的時候帶著爸媽二刷。?? 13.評論人:華盛頓櫻桃樹?? 14.評論時間:2018-02-06?00:06:34?? 15.支持人數:10171 ? 16.評論內容:國產類型片的里程碑,2個多小時節奏全程緊繃清晰,真熱血真刺激。敘事,人物,情感,動作,制作都幾乎無可挑剔。該有的都有,演員群像都比想象中出色,但最出色的還是導演。這個格局,超越某狼N倍。??分析發現:對于單條影評數據主要包含:評論人、評論時間、支持人數和評論內容四部分,我們需要的是評論內容,這里需要對原始獲取到數據進行解析,具體實現如下:
1.def?singeCommentParse(data='comments/1291546.txt',save_path='handle/1291546.json'):?? 2.????'''''? 3.????單個影評數據的解析處理? 4. ???數據樣式:? 5. ???評論人:phoebe 6. ???評論時間:2007-11-21 20:38:33 7. ???支持人數:22660? 8. ???評論內容:陳凱歌可以靠它吃兩輩子飯了,現在看來江郎才盡也情有可原? 9.????'''?? 10.????with?open(data)?as?f:?? 11.????????data_list=[one.strip()?for?one?in?f.readlines()?if?one]?? 12.????comment_list=cutList(data_list,c=4)?? 13.????res_list=[]?? 14.????for?i?in?range(len(comment_list)):?? 15.????????one_list=comment_list[i]?? 16.????????try:?? 17.????????????one_dict={}?? 18.????????????one_dict['person'],one_dict['timestamp'],one_dict['number'],one_dict['content']='N','N','N','N'?? 19.????????????for?one?in?one_list:?? 20.????????????????if?one.startswith('評論人'):?? 21.????????????????????one_dict['person']=one.split(':')[-1].strip()?? 22.????????????????elif?one.startswith('評論時間'):?? 23.????????????????????one_dict['timestamp']=one.split(':')[-1].strip()?? 24.????????????????elif?one.startswith('支持人數'):?? 25.????????????????????one_dict['number']=one.split(':')[-1].strip()?? 26.????????????????elif?one.startswith('評論內容'):?? 27.????????????????????one_dict['content']=one.split(':')[-1].strip()?? 28.????????????res_list.append(one_dict)?? 29.????????except:?? 30.????????????pass?? 31.????with?open(save_path,'wb')?as?f:?? 32.????????f.write(json.dumps(res_list))?? 33.?? 34.?? 35.def?allCommentsHandle(dataDir='comments/',saveDir='handle/'):?? 36.????'''''? 37.????對整個目錄下的影評數據全部處理? 38.????'''?? 39.????if?not?os.path.exists(saveDir):?? 40.????????os.makedirs(saveDir)?? 41.????txt_list=os.listdir(dataDir)?? 42.????for?one_txt?in?txt_list:?? 43.????????one_name=one_txt.split('.')[0].strip()?? 44.????????one_txt_path=dataDir+one_txt?? 45.????????one_json_path=saveDir+one_name+'.json'?? 46.????????singeCommentParse(data=one_txt_path,save_path=one_json_path)??上述代碼實現了對所有電源原始評論數據的解析處理,執行后就得到了所需的評論內容數據。
完成解析處理后需要對影評內容數據進行清洗,這里的清洗我主要是去除評論數據中的特殊字符等信息,具體實現如下:
1.def?dataClean(one_line):?? 2.????'''''? 3.????去臟、去無效數據? 4.????'''?? 5.????with?open('stopwords.txt')?as?f:?? 6.????????stopwords_list=[one.strip()?for?one?in?f.readlines()?if?one]?? 7.????sigmod_list=[',','。','(',')','-','——','\n','“','”','*','#','《','》','、','[',']','(',')','-',?? 8.???????????????????'.','/','】','【','……','!','!',':',':','…','@','~@','~','「一」','「','」',?? 9.????????????????'?','"','?','~','_','?',';','◆','①','②','③','④','⑤','⑥','⑦','⑧','⑨','⑩',?? 10.????????????????'⑾','⑿','⒀','⒁','⒂','"','?','/','·','…','!!!','】','!',',',?? 11.????????????????'。','[',']','【','、','?','/^/^','/^','”',')','(','~','》','《','。。。',?? 12.????????????????'=','⑻','⑴','⑵','⑶','⑷','⑸','⑹','⑺','…','']?? 13.????for?one_sigmod?in?sigmod_list:?? 14.????????one_line=one_line.replace(one_sigmod,'')?? 15.????return?one_line??到這里文本數據的預處理工作就結束了,之后需要對數據進行存儲,這里我是直接將數據存儲到了MySQL數據庫中。
首先需要創建對應的表,具體實現如下:
1.def?createTableMySQL(tablename='mytable'):?? 2.????'''''? 3.????創建表? 4.????'''?? 5.????conn=pymysql.connect(**mysql)?? 6.????cur=conn.cursor()???? 7.????try:?? 8.????????drop_sql="drop?table?if?exists?%s"?%?tablename?? 9.????????cur.execute()?? 10.????except?Exception,e:?? 11.????????print?'Drop?Exception:?',e?? 12.????try:?? 13.????????create_sql="""CREATE?TABLE?%s?(? 14.?????????????????????movieId?VARCHAR(50)?NOT?NULL,? 15.?????????????????????movieName?VARCHAR(50)?NOT?NULL,? 16.?????????????????????personName?VARCHAR(50)?NOT?NULL,? 17.?????????????????????supportNum?VARCHAR(50),? 18.?????????????????????content?VARCHAR(255),? 19.?????????????????????timePoint?VARCHAR(50)?NOT?NULL,? 20.?????????????????????"""?%(table)?? 21.????????cur.execute(create_sql)?? 22.????????conn.commit()?? 23.????????cur.close()?? 24.????????conn.close()?? 25.????except?Exception,e:?? 26.????????print?'createTableMySQL?Exception:?',e??數據入庫操作實現如下:
到此就完成了影評數據的清洗與存儲工作!
三、LDA主題挖掘分析
這一部分主要是基于LDA主題挖掘模型來對處理好的影評數據進行主題傾向性的分析挖掘工作。具體實現如下所示:
結果輸出如下:
1.{"蝶衣":?1,?"記得":?1,?"故事":?1,?"哥哥":?6,?"背景":?1,?"作品":?2,?"時代":?1,?"真的":?1,?"瘋魔":?1,?"女嬌":?1,?"霸王":?1,?"說好":?1,?"生活":?1,?"角色":?1,?"陳凱歌":?3,?"電影":?6,?"人生":?2,?"風華絕代":?1,?"成活":?1,?"中國":?4,?"喜歡":?1,?"一年":?1,?"人物":?1,?"這部":?3,?"一輩子":?2,?"歷史":?2,?"時辰":?1,?"經典":?3,?"看過":?1,?"感情":?1,?"導演":?1,?"程蝶衣":?6,?"真虞姬":?1,?"一部":?2,?"霸王別姬":?2,?"不算":?1,?"關注":?1,?"虞姬":?3,?"一個月":?1,?"永遠":?1,?"張國榮":?5,?"一出":?1,?"巔峰":?1,?"之作":?1}??上述代碼中我們數據的數據是《霸王別姬》的評論數據,輸出的是對應的10個主題中主題詞的詞頻數據。基于詞云對其可視化結果如下所示:
接下來我們借助于主題可視化分析工具對其各個主題進行展示如下所示:
Topic0:
Topic1:
Topic2:
Topic3:
這里僅展示出前4個主題的分布情況,借助于可視化工具來呈現主題還是一種不錯的方式。
四、分詞與詞頻統計
這部分的工作主要是對原始的影評數據進行分詞和詞頻統計,相對來說較為簡單,就不多說明了,直接看代碼實現即可:
1.def?singleCommentCut(data='1291546.json',word_path='1291546.txt',fre_path='1291546.json'):?? 2.????'''?? 3.????對單個影評數據清洗、分詞處理?? 4.????'''?? 5.????with?open(data)?as?f:?? 6.????????data_list=json.load(f)?? 7.????content=[]?? 8.????fre_dict={}?? 9.????for?one_dict?in?data_list:?? 10.????????one_clean=dataClean(one_dict['content'])?? 11.????????one_cut=seg(one_clean)?? 12.????????one_line='/'.join(one_cut)?? 13.????????content.append(one_line)?? 14.????????for?one?in?one_cut:?? 15.????????????if?one?in?fre_dict:?? 16.????????????????fre_dict[one]+=1?? 17.????????????else:?? 18.????????????????fre_dict[one]=1?? 19.????with?open(word_path,'w')?as?f:?? 20.????????for?one_line?in?content:?? 21.????????????f.write(one_line.strip()+'\n')?? 22.????with?open(fre_path,'w')?as?f:?? 23.????????f.write(json.dumps(fre_dict))??上述代碼實現了對輸入影評數據的分詞與詞頻統計,并存儲到本地文件中。
五、詞云可視化分析
這里是本文的最后一個部分,主要是對前面幾章中計算處理得到的文本數據進行可視化展示分析,對于文本數據的可視化我用的最多的也就是詞云了,簡單看下具體的效果吧。
原始影評數據詞云可視化結果如下:
《我不是藥神》
《流浪地球》
《肖申克的救贖》
《紅海行動》
主題挖掘詞云可視化分析結果如下:
《我不是藥神》
《流浪地球》
《肖申克的救贖》
《紅海行動》
對于完整影評數據的可視化來說更全面地展現出來了評論數據的信息,對于主題挖掘的可視化來說,突出了在廣大評論數據中的主題傾向性。
到這里本文的工作就結束了,很高興在自己溫習回顧知識的同時能寫下點分享的東西出來,如果說您覺得我的內容還可以或者是對您有所啟發、幫助,還希望得到您的鼓勵支持,謝謝!
贊 賞 作 者
Python中文社區作為一個去中心化的全球技術社區,以成為全球20萬Python中文開發者的精神部落為愿景,目前覆蓋各大主流媒體和協作平臺,與阿里、騰訊、百度、微軟、亞馬遜、開源中國、CSDN等業界知名公司和技術社區建立了廣泛的聯系,擁有來自十多個國家和地區數萬名登記會員,會員來自以工信部、清華大學、北京大學、北京郵電大學、中國人民銀行、中科院、中金、華為、BAT、谷歌、微軟等為代表的政府機關、科研單位、金融機構以及海內外知名公司,全平臺近20萬開發者關注。
▼ 點擊成為社區注冊會員? ? ? ? ??「在看」一下,一起PY!
總結
以上是生活随笔為你收集整理的基于豆瓣影评数据的完整文本分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cortex、ARMv8、arm架构、A
- 下一篇: FCPX:快速时尚视频转场Stupid