自然語(yǔ)言處理簡(jiǎn)介
現(xiàn)在可帽,讓我們先從介紹自然語(yǔ)言處理(NLP)開始吧橘茉。眾所周知除嘹,語(yǔ)言是人們?nèi)粘I?活的核心部分怎憋,任何與語(yǔ)言問題相關(guān)的工作都會(huì)顯得非常有意思又碌。希望這本書能帶你領(lǐng)略 到 NLP 的風(fēng)采,并引起學(xué)習(xí) NLP 的興趣绊袋。首先毕匀,我們需要來(lái)了解一下該領(lǐng)域中的一些令 人驚嘆的概念,并在工作中實(shí)際嘗試一些具有挑戰(zhàn)性的 NLP 應(yīng)用癌别。
在英語(yǔ)環(huán)境中皂岔,語(yǔ)言處理研究這一領(lǐng)域通常被簡(jiǎn)稱為 NLP。對(duì)語(yǔ)言有深入研究的人通 常被叫作語(yǔ)言學(xué)家规个,而“計(jì)算機(jī)語(yǔ)言學(xué)家”這個(gè)專用名詞則指的是將計(jì)算機(jī)科學(xué)應(yīng)用于語(yǔ) 言處理領(lǐng)域的人凤薛。因此從本質(zhì)上來(lái)說姓建,一個(gè)計(jì)算機(jī)語(yǔ)言學(xué)家應(yīng)該既有足夠的語(yǔ)言理解能力, 同時(shí)還可以用其計(jì)算機(jī)技能來(lái)模擬出語(yǔ)言的不同方面缤苫。雖然計(jì)算機(jī)語(yǔ)言學(xué)家主要研究的是 語(yǔ)言處理理論速兔,但 NLP 無(wú)疑是對(duì)計(jì)算機(jī)語(yǔ)言學(xué)的具體應(yīng)用。
NLP 多數(shù)情況下指的是計(jì)算機(jī)上各種大同小異的語(yǔ)言處理應(yīng)用活玲,以及用 NLP 技術(shù)所構(gòu) 建的實(shí)際應(yīng)用程序涣狗。在實(shí)踐中,NLP 與教孩子學(xué)語(yǔ)言的過程非常類似舒憾。其大多數(shù)任務(wù)(如 對(duì)單詞镀钓、語(yǔ)句的理解,形成語(yǔ)法和結(jié)構(gòu)都正確的語(yǔ)句等)對(duì)于人類而言都是非常自然的能 力镀迂。但對(duì)于 NLP 來(lái)說丁溅,其中有一些任務(wù)就必須要轉(zhuǎn)向標(biāo)識(shí)化處理、語(yǔ)塊分解探遵、詞性標(biāo)注窟赏、 語(yǔ)法解析、機(jī)器翻譯及語(yǔ)音識(shí)別等這些領(lǐng)域的一部分箱季,且這些任務(wù)有一大部分還仍是當(dāng)前 計(jì)算機(jī)領(lǐng)域中非常棘手的挑戰(zhàn)涯穷。在本書中,我們將更側(cè)重于討論 NLP 的實(shí)用方面藏雏,因此我 們會(huì)假設(shè)讀者在 NLP 上已經(jīng)有了一些背景知識(shí)拷况。所以,讀者最好在最低限度上對(duì)編程語(yǔ)言 有一點(diǎn)了解掘殴,并對(duì) NLP 和語(yǔ)言學(xué)有一定的興趣赚瘦。
目前,NLP 已被認(rèn)為是業(yè)界最為稀缺的技能之一奏寨。自大數(shù)據(jù) 的概念問世之后蚤告,我們所面對(duì)的主要挑戰(zhàn)是——業(yè)界需要越來(lái)越多不僅能處理結(jié)構(gòu)化數(shù)據(jù), 同時(shí)也能處理半結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)的人才服爷。對(duì)于我們所生產(chǎn)出來(lái)的那些博客、微博获诈、 Facebook 訂閱仍源、聊天信息、E-mail 以及網(wǎng)絡(luò)評(píng)論等舔涎,各公司都在致力于收集所有不同種類 的數(shù)據(jù)笼踩,以便建立更好的客戶針對(duì)性,形成有意義的見解亡嫌。而要想處理所有的這些非結(jié)構(gòu) 化數(shù)據(jù)源嚎于,我們就需要掌握一些 NLP 技能的人員掘而。
身處信息時(shí)代,我們甚至不能想象生活中沒有 Google 會(huì)是什么樣子于购。我們會(huì)因一些最基本的事情而用到 Siri;我們會(huì)需要用垃圾過濾器來(lái)過濾垃圾郵件;我們會(huì)需要在自己的 Word 文檔中用到拼寫檢查器等袍睡。在現(xiàn)實(shí)世界中所要用到的 NLP 應(yīng)用數(shù)不勝數(shù)。
在這里肋僧,我們可以再列舉一些令人驚嘆的 NLP 應(yīng)用實(shí)例斑胜。雖然你很可能已經(jīng)用過它們,
但未必知道這些應(yīng)用是基于 NLP 技術(shù)的嫌吠。
? 拼寫校正(MS Word/其他編輯器)
? 搜索引擎(Google止潘、Bing、Yahoo!辫诅、WolframAlpha)
? 語(yǔ)音引擎(Siri凭戴、Google Voice)
? 垃圾郵件分類(所有電子郵件服務(wù))
? 新聞?dòng)嗛?Google、Yahoo!等)
? 機(jī)器翻譯(Google 翻譯與其他類似服務(wù))
? IBM Watson1
構(gòu)建上述這些應(yīng)用都需要非常具體的技能炕矮,需要優(yōu)秀的語(yǔ)言理解能力和能有效處理這 些語(yǔ)言的工具么夫。因此,這些不僅是各 NLP 最具優(yōu)勢(shì)領(lǐng)域的未來(lái)趨勢(shì)吧享,同時(shí)也是我們用 NLP 這種最獨(dú)特技能所能創(chuàng)建的應(yīng)用種類魏割。
Natural Language Tool Kit (NLTK)
NLTK 庫(kù)是一個(gè)非常易學(xué)的工具包,這得益于 Python 本身 非常平緩的學(xué)習(xí)曲線(畢竟 NLTK 是用它編寫的)钢颂,人們學(xué)習(xí)起來(lái)會(huì)非吵快。NLTK 庫(kù)中收納了 NLP 領(lǐng)域中的絕大部分任務(wù)殊鞭,它們都被實(shí)現(xiàn)得非常優(yōu)雅遭垛,且易于使用。正是出于上述
的這些原因操灿,NLTK 如今已成為了 NLP 社區(qū)最流行的庫(kù)之一锯仪。
正則表達(dá)式
對(duì) NLP 愛好者來(lái)說,正則表達(dá)式是另一個(gè)非常重要的技能趾盐。正則表達(dá)式(regular expression) 是一種能對(duì)字符串進(jìn)行有效匹配的模式庶喜。我們會(huì)大量使用這種模式,以求從大量凌亂的文 本數(shù)據(jù)中提取出有意義的信息救鲤。下面久窟,我們就來(lái)整體瀏覽一下你將會(huì)用到哪些正則表達(dá)式。 其實(shí)本缠,我這一生至今所用過的正則表達(dá)式無(wú)非也就是以下這些斥扛。
? (句點(diǎn)):該表達(dá)式用于匹配除換行符\n 外的任意單字符
? \w:該表達(dá)式用于匹配某一字符或數(shù)字,相當(dāng)于[a-z A-Z 0-9]
? \W(大寫 W):該表達(dá)式用于匹配任意非單詞性字符
? \s(小寫 s):用于匹配任意單個(gè)空白字符丹锹,包括換行稀颁、返回芬失、制表等,相當(dāng)于[\n\r\t\f]
? \S:該表達(dá)式用于匹配單個(gè)任意非空白字符
? \t:該表達(dá)式用于匹配制表符
? \n:該表達(dá)式用于匹配換行符
? \r:該表達(dá)用于匹配返回符
? \d:該表達(dá)式用于匹配十進(jìn)制數(shù)字匾灶,即[0-9]
? ^:該表達(dá)式用于匹配相關(guān)字符串的開始位置
? $:該表達(dá)式用于匹配相關(guān)字符串的結(jié)尾位置
? :該表達(dá)式用來(lái)抵消特殊字符的特殊性棱烂。如要匹配$符號(hào),就在它前面加上\
文本清理
一旦我們將各種數(shù)據(jù)源解析成了文本形式粘昨,接下來(lái)所要面臨的挑戰(zhàn)就是要使這些原生 數(shù)據(jù)體現(xiàn)出它們的意義垢啼。文本清理就泛指針對(duì)文本所做的絕大部分清理、與相關(guān)數(shù)據(jù)源的 依賴關(guān)系张肾、性能的解析和外部噪聲等芭析。
語(yǔ)句分離
- 字
- 詞
- 句
- 段
- 篇
- 章
語(yǔ)句分離是將大段的語(yǔ)句分成句子。
段篇章 -> 句
標(biāo)識(shí)化處理
可以理解為編譯原理里面的詞法分析吞瞪,把語(yǔ)句分成標(biāo)記(token)馁启。
句 -> 詞
標(biāo)識(shí)器(tokenizer)
- 第一種是 word_tokenize(),這是我們的默 認(rèn)選擇芍秆,基本上能應(yīng)付絕大多數(shù)的情況惯疙。
- 另一選擇是 regex_tokenize(),這是一個(gè)為用戶特 定需求設(shè)計(jì)的妖啥、自定義程度更高的標(biāo)識(shí)器霉颠。
詞干提取(詞根化)
所謂詞干提取(stemming)荆虱,顧名思義就是一個(gè)修剪枝葉的過程蒿偎。這是很有效的方法, 通過運(yùn)用一些基本規(guī)則怀读,我們可以在修剪枝葉的過程中得到所有的分詞诉位。詞干提取是一種 較為粗糙的規(guī)則處理過程,我們希望用它來(lái)取得相關(guān)分詞的各種變化菜枷。
例如 eat 這個(gè)單詞 就會(huì)有像 eating苍糠、eaten、eats 等變化啤誊。在某些應(yīng)用中岳瞭,我們是沒有必要區(qū)分 eat 和 eaten 之 間的區(qū)別的,所以通常會(huì)用詞干提取的方式將這種語(yǔ)法上的變化歸結(jié)為相同的詞根蚊锹。
由此 可以看出寝优,我們之所以會(huì)用詞干提取方法,就是因?yàn)樗暮?jiǎn)單枫耳,而對(duì)于更復(fù)雜的語(yǔ)言案 例或更復(fù)雜的 NLP 任務(wù),我們就必須要改用詞形還原(lemmatization)的方法了孟抗。詞形 還原是一種更為健全迁杨、也更有條理的方法钻心,以便用于應(yīng)對(duì)相關(guān)詞根的各種語(yǔ)法上的變化。
一個(gè)擁有基本規(guī)則的詞干提取器铅协,在像移除-s/es捷沸、-ing 或-ed 這類事情上都可以達(dá)到 70%以 上的精確度,而 Porter 詞干提取器使用了更多的規(guī)則狐史,自然在執(zhí)行上會(huì)得到很不錯(cuò)的精確度痒给。
停用詞移除
停用詞移除(Stop word removal)是在不同的 NLP 應(yīng)用中最常會(huì)用到的預(yù)處理步驟之 一。
該步驟的思路就是想要簡(jiǎn)單地移除語(yǔ)料庫(kù)中的在所有文檔中都會(huì)出現(xiàn)的單詞骏全。通常情 況下苍柏,冠詞和代詞都會(huì)被列為停用詞。這些單詞在一些 NPL 任務(wù)(如說關(guān)于信息的檢索和 分類的任務(wù))中是毫無(wú)意義的姜贡,這意味著這些單詞通常不會(huì)產(chǎn)生很大的歧義试吁。
恰恰相反的 是,在某些 NPL 應(yīng)用中楼咳,停用詞被移除之后所產(chǎn)生的影響實(shí)際上是非常小的熄捍。在大多數(shù)時(shí) 候,給定語(yǔ)言的停用詞列表都是一份通過人工制定的母怜、跨語(yǔ)料庫(kù)的余耽、針對(duì)最常見單詞的停 用詞列表。
雖然大多數(shù)語(yǔ)言的停用詞列表都可以在相關(guān)網(wǎng)站上被找到苹熏,但也有一些停用詞 列表是基于給定語(yǔ)料庫(kù)來(lái)自動(dòng)生成的碟贾。
有一種非常簡(jiǎn)單的方式就是基于相關(guān)單詞在文檔中 出現(xiàn)的頻率(即該單詞在文檔中出現(xiàn)的次數(shù))來(lái)構(gòu)建一個(gè)停用詞列表,出現(xiàn)在這些語(yǔ)料庫(kù) 中的單詞都會(huì)被當(dāng)作停用詞柜裸。
經(jīng)過這樣的充分研究缕陕,我們就會(huì)得到針對(duì)某些特定語(yǔ)料庫(kù)的 最佳停用詞列表。
NLTK 庫(kù)中就內(nèi)置了涵蓋 22 種語(yǔ)言的停用詞列表疙挺。
罕見詞移除
這是一個(gè)非常直觀的操作扛邑,因?yàn)樵摬僮麽槍?duì)的單詞都有很強(qiáng)的唯一性,如說名稱铐然、品 牌蔬崩、產(chǎn)品名稱、某些噪音性字符(例如 html 代碼的左縮進(jìn))等搀暑。
這些詞匯也都需要根據(jù)不同的 NLP 任務(wù)來(lái)進(jìn)行清除沥阳。
例如對(duì)于文本分類問題來(lái)說,對(duì)名詞的使用執(zhí)行預(yù)測(cè)是個(gè)很壞 的想法自点,即使這些詞匯在預(yù)測(cè)中有明確的意義桐罕。我們會(huì)在后面的章節(jié)進(jìn)一步討論這個(gè)問題。
總而言之,我們絕對(duì)不希望看到所有噪音性質(zhì)的分詞出現(xiàn)功炮。為此溅潜,我們通常會(huì)為單詞設(shè)置 一個(gè)標(biāo)準(zhǔn)長(zhǎng)度,那些太短或太長(zhǎng)的單詞將會(huì)被移除:
文本分類
對(duì)于文本分類薪伏,最簡(jiǎn)單的定義就是要基于文本內(nèi)容來(lái)對(duì)其進(jìn)行分類滚澜。
通常情況下,目前所有的機(jī)器學(xué)習(xí)方法和算法都是根據(jù)數(shù)字/變量特征來(lái)編寫的嫁怀。所以這里最重要的問題之一设捐,就是如何在語(yǔ)料庫(kù)中用數(shù)字特征的形式來(lái)表示文本。
取樣操作
一旦以列表的形式持有了整個(gè)語(yǔ)料庫(kù)塘淑,接下來(lái)就要對(duì)其進(jìn)行某種形式的取樣操作萝招。 通常來(lái)說,對(duì)語(yǔ)料庫(kù)的整體取樣方式與訓(xùn)練集朴爬、開發(fā)測(cè)試集和測(cè)試集的取樣方式是類似的即寒,整個(gè)練習(xí)背后的思路是要避免訓(xùn)練過度。
如果將所有數(shù)據(jù)點(diǎn)都反饋給該模型召噩, 那么算法就會(huì)基于整個(gè)語(yǔ)料庫(kù)來(lái)進(jìn)行機(jī)器學(xué)習(xí)母赵,但這些算法在真實(shí)測(cè)試中針對(duì)的是不可 數(shù)據(jù)。
在非常簡(jiǎn)單的詞匯環(huán)境中具滴,如果在模型學(xué)習(xí)過程中使用的是全體數(shù)據(jù)凹嘲,那么盡管分 類器在該數(shù)據(jù)上能得到很好的執(zhí)行,但其結(jié)果是不穩(wěn)健的构韵。原因在于一直只在給定數(shù)據(jù)上執(zhí)行出最佳結(jié)果周蹭,但這樣它是學(xué)不會(huì)如何處理未知數(shù)據(jù)的。
詞匯文檔矩陣(term-document matrix) & 詞袋 BOW(bag of word)
整個(gè)文本轉(zhuǎn)換成向量形式疲恢。
文本文檔也可以用所謂的 BOW(bag of word)來(lái)表示凶朗,這也是文本挖掘和其他相 關(guān)應(yīng)用中最常見的表示方法之一∠匀基本上棚愤,不必去考慮這些單詞在相關(guān)語(yǔ)境下的表示方式。
分類器
樸素貝葉斯法
依賴于貝葉斯算法杂数,它本質(zhì)上是一個(gè)根據(jù)給定特征/屬性宛畦,基于某種條件概率為樣本賦予某
個(gè)類別標(biāo)簽的模型。在這里揍移,將用頻率/伯努利數(shù)來(lái)預(yù)估先驗(yàn)概率和后驗(yàn)概率次和。
樸素算法往往會(huì)假設(shè)其中所有的特征都是相互獨(dú)立的,這樣對(duì)于文本環(huán)境來(lái)說看起來(lái)會(huì)直觀一些那伐。
但令人驚訝的是踏施,樸素貝葉斯算法在大多數(shù)實(shí)際用例中的表現(xiàn)也相當(dāng)良好石蔗。
樸素貝葉斯(NB)法的另一個(gè)偉大之處在于它非常簡(jiǎn)單,實(shí)現(xiàn)起來(lái)很容易畅形,評(píng)分也很簡(jiǎn)單抓督。只需要將各頻率值存儲(chǔ)起來(lái),并計(jì)算出概率束亏。無(wú)論在訓(xùn)練時(shí)還是測(cè)試(評(píng)分)時(shí), 它的速度都很快阵具“椋基于以上原因,大多數(shù)的文本分類問題都會(huì)用它來(lái)做基準(zhǔn)阳液。
決策樹
決策樹是最古老的預(yù)測(cè)建模技術(shù)之一怕敬,對(duì)于給定的特征和目標(biāo),基于該技術(shù)的算法會(huì) 嘗試構(gòu)建一個(gè)相應(yīng)的邏輯樹帘皿。使用決策樹的算法有很多種類东跪,這里主要介紹的是其中最著 名和使用最廣泛的算法之一:CART。
CART 算法會(huì)利用特性來(lái)構(gòu)造一些二叉樹結(jié)構(gòu)鹰溜,并構(gòu)造出一個(gè)閾值虽填,用于從每個(gè)節(jié)點(diǎn) 中產(chǎn)生大量的信息。
隨機(jī)梯度下降法
隨機(jī)梯度下降(Stochastic gradient descent曹动,簡(jiǎn)稱 SGD)法是一種既簡(jiǎn)單又非常有效 的斋日、適用于線性模型的方法。
尤其在目標(biāo)樣本數(shù)量(和特征數(shù)量)非常龐大時(shí)墓陈,其作用會(huì)特別突出恶守。如果參照之前的功能列表圖,我們會(huì)發(fā)現(xiàn) SGD 是許多文本分類問題的一站式解 決方案贡必。另外兔港,由于它也能照顧到規(guī)范化問題并可以提供不同的損失函數(shù),所以對(duì)于線性 模型的實(shí)驗(yàn)工作來(lái)說它也是個(gè)很好的選擇仔拟。
SGD 算法有時(shí)候也被稱為最大熵(Maximum entropy衫樊,簡(jiǎn)稱 MaxEnt)算法,它會(huì)用 不同的(坡面)損失函數(shù)(loss function)和懲罰機(jī)制來(lái)適配針對(duì)分類問題與回歸問題的線性模型理逊。
例如當(dāng) loss = log 時(shí)橡伞,它適配的是一個(gè)對(duì)數(shù)回歸模型,而當(dāng) loss = hinge 時(shí)晋被,它適 配的則是一個(gè)線性的支持向量機(jī)(SVM)兑徘。
邏輯回歸
邏輯回歸(logistic regression)是一種針對(duì)分類問題的線性模型。它在某些文獻(xiàn)中也 被稱為対元邏輯(logit regression)羡洛、最大熵(MaxEnt)分類法或?qū)?shù)線性分類器挂脑。在這 個(gè)模型中藕漱,我們會(huì)用一個(gè)対元函數(shù)來(lái)進(jìn)行建模,以概率的方式來(lái)描述單項(xiàng)試驗(yàn)的可能 結(jié)果崭闲。
支持向量機(jī)
支持向量機(jī)(Support vector machine肋联,簡(jiǎn)稱 SVM)是目前在機(jī)器學(xué)習(xí)領(lǐng)域中最為先 進(jìn)的算法。
SVM 屬于非概率分類器刁俭。SVM 會(huì)在無(wú)限維空間中構(gòu)造出一組超平面橄仍,它可被應(yīng)用在 分類、回歸或其他任務(wù)中牍戚。
直觀來(lái)說侮繁,可以通過一個(gè)超平面來(lái)實(shí)現(xiàn)良好的分類劃界,這個(gè) 超平面應(yīng)該距離最接近訓(xùn)練數(shù)據(jù)點(diǎn)的那些類最遠(yuǎn)(這個(gè)距離被稱為功能邊界)如孝,因?yàn)樵谝话?情況下宪哩,這個(gè)邊界越大,分類器的規(guī)模就越小第晰。
隨機(jī)森林算法
隨機(jī)森林是一種以不同決策樹組合為基礎(chǔ)來(lái)進(jìn)行評(píng)估的合成型分類器锁孟。
事實(shí)上,它比較適 合用于在各種數(shù)據(jù)集的子樣本上構(gòu)建多決策樹型的分類器茁瘦。另外品抽,該森林中的每個(gè)樹結(jié)構(gòu)都建立 在一個(gè)隨機(jī)的最佳特征子集上。最后腹躁,啟用這些樹結(jié)構(gòu)的動(dòng)作也找出了所有隨機(jī)特征子集中的最 佳子集桑包。總而言之纺非,隨機(jī)森林是當(dāng)前眾多分類算法中表現(xiàn)最佳的算法之一
示例 飯店評(píng)論
# Data Preprocessing
# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# Importing the dataset
dataset = pd.read_csv('Restaurant_Reviews.tsv',delimiter = '\t', quoting = 3)
dataset.info()
dataset.head()
'^[a-zA-Z]': match all strings that start with a letter
'[^a-zA-Z]': match all strings that contain a non-letter
# Cleaning the texts
import re
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
corpus = []
ps = PorterStemmer()
for i in range(0, 1000):
review = re.sub('[^a-zA-Z]', ' ', dataset['Review'][i])
review = review.lower()
review = review.split()
review = [ps.stem(word) for word in review if not word in set(stopwords.words('english'))]
review = ' '.join(review)
corpus.append(review)
[nltk_data] Downloading package stopwords to
[nltk_data] /Users/iosdevlog/nltk_data...
[nltk_data] Package stopwords is already up-to-date!
corpus[:10]
['wow love place',
'crust good',
'tasti textur nasti',
'stop late may bank holiday rick steve recommend love',
'select menu great price',
'get angri want damn pho',
'honeslti tast fresh',
'potato like rubber could tell made ahead time kept warmer',
'fri great',
'great touch']
# Creating the Bag of Words model
from sklearn.feature_extraction.text import CountVectorizer
#create a feature matrix out of the most 1500 frequent words:
cv = CountVectorizer(max_features = 1500)
X = cv.fit_transform(corpus).toarray()
y = dataset.iloc[:, 1].values
X[:5]
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=int64)
# Splitting the dataset into the Training set and Test set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 0)
X_train[:5]
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=int64)
# Fitting Naive Bayes to the Training set
from sklearn.naive_bayes import GaussianNB
classifier = GaussianNB()
classifier.fit(X_train, y_train)
GaussianNB(priors=None, var_smoothing=1e-09)
# Predicting the Test set results
# Looking at first 5 testing data, we can see we predicted the first 3 incorrectly as positive reviews, and last 2 correctly as negative review
y_pred = classifier.predict(X_test)
print(y_pred[:5])
print(y_test[:5])
print(cv.inverse_transform(X_test[:5]))
[1 1 1 0 0]
[0 0 0 0 0]
[array(['aw', 'food', 'present'], dtype='<U17'), array(['food', 'servic', 'worst'], dtype='<U17'), array(['dine', 'never', 'place'], dtype='<U17'), array(['disgrac', 'guess', 'mayb', 'night', 'went'], dtype='<U17'), array(['avoid', 'lover', 'mean', 'place', 'sushi'], dtype='<U17')]
# Making the Confusion Matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
cm
array([[55, 42],
[12, 91]])
參考資料:《NLTK基礎(chǔ)教程》哑了,《機(jī)器學(xué)習(xí) A-Z》