用Python進(jìn)行一些簡(jiǎn)單的自然語(yǔ)言處理的教程
本月的每月挑戰(zhàn)會(huì)主題是NLP,我們會(huì)在本文幫你開(kāi)啟一種可能:使用pandas和python的自然語(yǔ)言工具包分析你Gmail郵箱中的內(nèi)容。
NLP-風(fēng)格的項(xiàng)目充滿無(wú)限可能:
- 情感分析是對(duì)諸如在線評(píng)論、社交媒體等情感內(nèi)容的測(cè)度。舉例來(lái)說(shuō),關(guān)于某個(gè)話題的tweets趨向于正面還是負(fù)面的意見(jiàn)?一個(gè)新聞網(wǎng)站涵蓋的主題,是使用了更正面/負(fù)面的詞語(yǔ),還是經(jīng)常與某些情緒相關(guān)的詞語(yǔ)?這個(gè)“正面”的Yelp點(diǎn)評(píng)不是很諷刺么?(祝最后去的那位好運(yùn)?。?/li>
- 分析語(yǔ)言在文學(xué)中的使用,進(jìn)而衡量詞匯或者寫(xiě)作風(fēng)格隨時(shí)間/地區(qū)/作者的變化趨勢(shì).
- 通過(guò)識(shí)別所使用的語(yǔ)言的關(guān)鍵特征,標(biāo)記是否為垃圾內(nèi)容。
- 基于評(píng)論所覆蓋的主題,使用主題抽取進(jìn)行相似類(lèi)別的劃分。
- 通過(guò)NLTK's的語(yǔ)料庫(kù),應(yīng)用Elastisearch和WordNet的組合來(lái)衡量Twitter流API上的詞語(yǔ)相似度,進(jìn)而創(chuàng)建一個(gè)更好的實(shí)時(shí)Twitter搜索。
- 加入NaNoGenMo項(xiàng)目,用代碼生成自己的小說(shuō),你可以從這里大量的創(chuàng)意和資源入手。
將Gmail收件箱加載到pandas
讓我們從項(xiàng)目實(shí)例開(kāi)始!首先我們需要一些數(shù)據(jù)。準(zhǔn)備你的Gmail的數(shù)據(jù)存檔(包括你最近的垃圾郵件和垃圾文件夾)。
https://www.google.com/settings/takeout
現(xiàn)在去散步吧,對(duì)于5.1G大小的信箱,我2.8G的存檔需要發(fā)送一個(gè)多小時(shí)。
當(dāng)你得到數(shù)據(jù)并為工程配置好本地環(huán)境之后好,使用下面的腳本將數(shù)據(jù)讀入到pandas(強(qiáng)烈建議使用IPython進(jìn)行數(shù)據(jù)分析)
from mailbox import mbox import pandas as pd def store_content(message, body=None): if not body: body = message.get_payload(decode=True) if len(message): contents = { "subject": message['subject'] or "", "body": body, "from": message['from'], "to": message['to'], "date": message['date'], "labels": message['X-Gmail-Labels'], "epilogue": message.epilogue, } return df.append(contents, ignore_index=True) # Create an empty DataFrame with the relevant columns df = pd.DataFrame( columns=("subject", "body", "from", "to", "date", "labels", "epilogue")) # Import your downloaded mbox file box = mbox('All mail Including Spam and Trash.mbox') fails = [] for message in box: try: if message.get_content_type() == 'text/plain': df = store_content(message) elif message.is_multipart(): # Grab any plaintext from multipart messages for part in message.get_payload(): if part.get_content_type() == 'text/plain': df = store_content(message, part.get_payload(decode=True)) break except: fails.append(message)
上面使用Python的mailbox模塊讀取并解析mbox格式的郵件。當(dāng)然還可以使用更加優(yōu)雅的方法來(lái)完成(比如,郵件中包含大量冗余、重復(fù)的數(shù)據(jù),像回復(fù)中嵌入的“>>>”符號(hào))。另外一個(gè)問(wèn)題是無(wú)法處理一些特殊的字符,簡(jiǎn)單起見(jiàn),我們進(jìn)行丟棄處理;確認(rèn)你在這一步?jīng)]有忽略信箱中重要的部分。
需要注意的是,除了主題行,我們實(shí)際上并不打算利用其它內(nèi)容。但是你可以對(duì)時(shí)間戳、郵件正文進(jìn)行各種各樣有趣的分析,通過(guò)標(biāo)簽進(jìn)行分類(lèi)等等。鑒于這只是幫助你入門(mén)的文章(碰巧會(huì)顯示來(lái)自我自己信箱中的結(jié)果),我不想去考慮太多細(xì)節(jié)。
查找常用詞語(yǔ)
現(xiàn)在我們已經(jīng)得到了一些數(shù)據(jù),那么來(lái)找出所有標(biāo)題行中最常用的10個(gè)詞語(yǔ):
# Top 10 most common subject words from collections import Counter subject_word_bag = df.subject.apply(lambda t: t.lower() + " ").sum() Counter(subject_word_bag.split()).most_common()[:10] [('re:', 8508), ('-', 1188), ('the', 819), ('fwd:', 666), ('to', 572), ('new', 530), ('your', 528), ('for', 498), ('a', 463), ('course', 452)]
嗯,那些太常見(jiàn)了,下面嘗試對(duì)常用詞語(yǔ)做些限制:
from nltk.corpus import stopwords stops = [unicode(word) for word in stopwords.words('english')] + ['re:', 'fwd:', '-'] subject_words = [word for word in subject_word_bag.split() if word.lower() not in stops] Counter(subject_words).most_common()[:10] [('new', 530), ('course', 452), ('trackmaven', 334), ('question', 334), ('post', 286), ('content', 245), ('payment', 244), ('blog', 241), ('forum', 236), ('update', 220)]
除了人工移除幾個(gè)最沒(méi)價(jià)值的詞語(yǔ),我們也使用了NLTK的停用詞語(yǔ)料庫(kù),使用前需要進(jìn)行傻瓜式安裝。現(xiàn)在可以看到我收件箱中的一些典型詞語(yǔ),但通常來(lái)講在英文文本中并不一定同樣是典型的。
二元詞組和搭配詞
NLTK可以進(jìn)行另外一個(gè)有趣的測(cè)量是搭配原則。首先,我們來(lái)看下常用的“二元詞組”,即經(jīng)常一起成對(duì)出現(xiàn)的兩個(gè)單詞的集合:
from nltk import collocations bigram_measures = collocations.BigramAssocMeasures() bigram_finder = collocations.BigramCollocationFinder.from_words(subject_words) # Filter to top 20 results; otherwise this will take a LONG time to analyze bigram_finder.apply_freq_filter(20) for bigram in bigram_finder.score_ngrams(bigram_measures.raw_freq)[:10]: print bigram (('forum', 'content'), 0.005839453284373725) (('new', 'forum'), 0.005839453284373725) (('blog', 'post'), 0.00538045695634435) (('domain', 'names'), 0.004870461036311709) (('alpha', 'release'), 0.0028304773561811506) (('default', 'widget.'), 0.0026519787841697267) (('purechat:', 'question'), 0.0026519787841697267) (('using', 'default'), 0.0026519787841697267) (('release', 'third'), 0.002575479396164831) (('trackmaven', 'application'), 0.002524479804161567)
我們可以對(duì)三元詞組(或n元詞組)重復(fù)相同的步驟來(lái)查找更長(zhǎng)的短語(yǔ)。這個(gè)例子中,“new forum content”是出現(xiàn)次數(shù)最多的三元詞組,但是在上面例子的列表中,它卻被分割成兩部分并位居二元詞組列表的前列。
另外一個(gè)稍微不同類(lèi)型的搭配詞的度量是基于點(diǎn)間互信息(pointwise mutual information)的。本質(zhì)上,它所度量的是給定一個(gè)我們?cè)谥付ㄎ谋局锌吹降膯卧~,相對(duì)于他們通常在全部文檔中單獨(dú)出現(xiàn)的頻率,另外一個(gè)單詞出現(xiàn)的可能性。舉例來(lái)說(shuō),通常,如果我的郵件主題使用單詞“blog”與/或“post”很多,那么二元組“blog post”并不是一個(gè)有趣的信號(hào),因?yàn)橐粋€(gè)單詞仍然可能不和另一個(gè)單詞同時(shí)出現(xiàn)。根據(jù)這條準(zhǔn)則,我們得到一個(gè)不同的二元組的集合。
for bigram in bigram_finder.nbest(bigram_measures.pmi, 5): print bigram ('4:30pm', '5pm') ('motley', 'fool') ('60,', '900,') ('population', 'cap') ('simple', 'goods')
因此,我沒(méi)有收到很多提到單詞“motley”或者“fool”的郵件主題,但是當(dāng)我看到其中任意一個(gè),那么“Motley Fool”可能是相關(guān)聯(lián)的。
情感分析
最后,讓我們嘗試一些情感分析。為了快速入門(mén),我們可以使用以NLTK為基礎(chǔ)的TextBlob庫(kù),它提供了對(duì)于大量的常用NLP任務(wù)的簡(jiǎn)單訪問(wèn)。我們可以使用它內(nèi)建的情感分析(基于模式)來(lái)計(jì)算主題的“極性(polarity)”。從,表示高度負(fù)面情緒的-1到表示正面情緒的1,其中0為中性(缺乏一個(gè)明確的信號(hào))
接下來(lái):分析一段時(shí)間內(nèi)的你的收件箱;看看是否能夠通過(guò)郵件分類(lèi),確定正文的發(fā)送者/標(biāo)簽/垃圾這些基本屬性。使用潛在語(yǔ)義索引去揭示所涵蓋的最常用的常規(guī)主題。將你的發(fā)件文件夾輸入到馬爾科夫模型(Markov model)中,結(jié)合詞性標(biāo)注生成看起來(lái)連貫的自動(dòng)回復(fù)
請(qǐng)讓我們知道你是否使用NLP嘗試了有趣的項(xiàng)目分支,包含一份開(kāi)源庫(kù)將作為加分點(diǎn)。你可以在challenge.hackpad.com看下前面的展示,以找到更多的靈感!
相關(guān)文章
python3+telnetlib實(shí)現(xiàn)簡(jiǎn)單自動(dòng)測(cè)試示例詳解
telnetlib 模塊提供一個(gè)實(shí)現(xiàn)Telnet協(xié)議的類(lèi) Telnet,本文重點(diǎn)給大家介紹python3+telnetlib實(shí)現(xiàn)簡(jiǎn)單自動(dòng)測(cè)試示例詳解,需要的朋友可以參考下2021-08-08使用jupyter?notebook保存python代碼為.py格式問(wèn)題
這篇文章主要介紹了使用jupyter?notebook保存python代碼為.py格式問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07Python實(shí)現(xiàn)微信好友的數(shù)據(jù)分析
這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)微信好友的數(shù)據(jù)分析,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12Python自定義主從分布式架構(gòu)實(shí)例分析
這篇文章主要介紹了Python自定義主從分布式架構(gòu),結(jié)合實(shí)例形式分析了主從分布式架構(gòu)的結(jié)構(gòu)、原理與具體的代碼實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-09-09Python decorator攔截器代碼實(shí)例解析
這篇文章主要介紹了Python decorator攔截器代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04python查找目錄下指定擴(kuò)展名的文件實(shí)例
這篇文章主要介紹了python查找目錄下指定擴(kuò)展名的文件,實(shí)例分析了Python文件查詢的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04在python中實(shí)現(xiàn)調(diào)用可執(zhí)行文件.exe的3種方法
今天小編就為大家分享一篇在python中實(shí)現(xiàn)調(diào)用可執(zhí)行文件.exe的3種方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07