Apache Mahout:适合所有人的可扩展机器学习框架
原文鏈接:http://blog.csdn.net/gdp5211314/article/details/7173505
簡介:?Apache Mahout 專家 Grant Ingersoll 引領(lǐng)您快速了解最新版本 Mahout 中的機器學習庫,并通過示例說明如何部署和擴展 Mahout 的某些最常用的算法。
在軟件的世界中,兩年就像是無比漫長的時光。在過去兩年中,我們看到了社交媒體的風生水起、大規(guī)模集群計算的商業(yè)化(歸功于 Amazon 和 RackSpace 這樣的參與者),也看到了數(shù)據(jù)的迅猛增長以及我們詮釋這些數(shù)據(jù)的能力的顯著提升。“Apache Mahout 簡介” 最初在 developerWorks 上發(fā)表也已經(jīng)是兩年之前的事情。這之后,Mahout 社區(qū)(以及項目的代碼庫和功能)取得了長足的發(fā)展。Mahout 也得到了全球各地各種規(guī)模的企業(yè)的積極采用。
在我撰寫的?Apache Mahout 簡介?中,我介紹了許多機器學習的概念以及使用 Mahout 提供的一套算法的基礎(chǔ)知識。我在那篇文章中介紹的概念仍然有效,但這套算法已經(jīng)發(fā)生了顯著的變化。這篇文章不會重述基礎(chǔ)知識,而是重點關(guān)注 Mahout 的當前狀態(tài),以及如何利用 Amazon 的 EC2 服務(wù)和包含 700 萬個電子郵件文檔的數(shù)據(jù)集在一個計算集群上擴展 Mahout。如需回顧基礎(chǔ)知識,請參閱?參考資料?部分,特別是《Mahout 實戰(zhàn)》?一書。此外,我假設(shè)讀者具備 Apache Hadoop 和 Map-Reduce 范式方面的基本知識。(有關(guān) Hadoop 的更多信息,請參閱?參考資料?部分。)
Mahout 現(xiàn)狀
Mahout 在極短的時間內(nèi)取得了長足的發(fā)展。項目的關(guān)注點仍然可以歸納為我所說的 “3 個要點”:協(xié)同過濾(推薦機制)、聚類和分類。除此之外,這個項目還增加了其他一些功能。我將重點強調(diào)兩個領(lǐng)域中的一些關(guān)鍵擴展和改進:機器學習的核心算法(實現(xiàn)),以及包括輸入/輸出工具、與其他庫的集成點和更多參考示例的支持基礎(chǔ)架構(gòu)。然而,務(wù)必注意,本文對于現(xiàn)狀的敘述并不完整。此外,由于篇幅有限,我只能通過寥寥數(shù)語簡單介紹各項改進。建議讀者閱讀 Mahout 網(wǎng)站的“新聞”部分和各 Mahout 發(fā)布版的發(fā)布說明,以了解這方面的更多信息。
算法,算法,還是算法
只要嘗試解決過機器學習問題,您就應(yīng)該認識到,沒有任何一種能夠適合所有情況的萬能算法。為此,Mahout 添加了眾多新實現(xiàn)。表 1 包含我總結(jié)出的 Mahout 中最重要的新算法實現(xiàn),還列舉了一些用例示例。在這篇文章稍后的內(nèi)容中,我將實際運用其中的幾個算法。
表 1. Mahout 中的新算法
| 邏輯回歸,使用隨機梯度下降法 (SGD) 求解 | 速度超快、簡單的順序分類器,能夠在要求嚴格的環(huán)境中實現(xiàn)在線學習 | 為用戶推薦廣告,將文本分類為多種類別 |
| 隱藏式馬可夫模型 (HMM) | 經(jīng)典分類算法的順序和并行實現(xiàn),設(shè)計用于在基本生成過程不可知的情況下建模實際過程。 | 文本詞類標注、語音識別 |
| 奇異值分解 (SVD) | 旨在減少大型矩陣內(nèi)的噪聲,使噪音更小、更容易處理 | 作為聚類、推薦機制和分類的前導,自動執(zhí)行特性選擇 |
| 狄利克雷聚類 | 基于模型的聚類方法,根據(jù)數(shù)據(jù)是否適合基本模型來確定從屬關(guān)系 | 在數(shù)據(jù)存在重疊或?qū)哟螘r非常有用 |
| 譜聚類 | 一系列類似的方法,使用基于圖形的方法來確定聚類從屬關(guān)系 | 與所有聚類算法相似,適用于探索大規(guī)模、不可見的數(shù)據(jù)集 |
| Minhash 聚類 | 利用散列戰(zhàn)略,將類似的項目組織在一起,從而生成聚類 | 與其他聚類方法相同 |
| 大量推薦機制改進 | 分布式共生、SVD、交替最小二乘法 | 交友網(wǎng)站、電子商務(wù)、電影或書籍推薦 |
| 并置 | 支持 “Map-Reduce” 的并置實現(xiàn) | 以統(tǒng)計學的方式在文本中查找關(guān)注的詞組 |
Mahout 還新增了對用戶極為有用的大量低級數(shù)學算法(請參見數(shù)學包),表 1 所述算法使用了其中的許多低級數(shù)學算法,但這些低級數(shù)學算法是為一般用途設(shè)計的,因此有可能也適合您的需要。
改進和擴展 Mahout 的基礎(chǔ)架構(gòu)
Mahout 命令行
不久之前,Mahout 發(fā)布了一個 shell 腳本,處理類路徑、環(huán)境變量和其他設(shè)置項,從而使 Mahout 程序(包含main()?的 Mahout 程序)的運行更加輕松。該腳本 — 名為 mahout — 位于 $MAHOUT_HOME/bin 目錄中。
利用開放源碼項目并竭力使項目的代碼與自己的代碼協(xié)同工作的人越多,基礎(chǔ)架構(gòu)就越充實。對于 Mahout 來說,這種演進方式促成了多項改進。最顯著的一項就是經(jīng)過重大改進、一致的命令行界面,它使得在本地和 Apache Hadoop 上提交和運行任務(wù)更加輕松。這個新腳本位于 Mahout 頂層目錄(下文中將稱之為 $MAHOUT_HOME)下的 bin 目錄中。(請參閱側(cè)欄中的?Mahout 命令行。)
任何機器學習庫都有兩個關(guān)鍵組件,即可靠的數(shù)學庫和一個有效的集合包。數(shù)學庫(位于 $MAHOUT_HOME 下的數(shù)學模塊中)提供了多種功能:范圍從表示向量、矩陣的數(shù)據(jù)結(jié)構(gòu)、操作這些數(shù)據(jù)結(jié)構(gòu)的相關(guān)操作符一直到生成隨機數(shù)的工具和對數(shù)似然值等有用的統(tǒng)計數(shù)據(jù)(請參閱?參考資料)。Mahout 的集合庫包含的數(shù)據(jù)結(jié)構(gòu)與 Java 集合提供的數(shù)據(jù)結(jié)構(gòu)相似(Map、List?等),不同之處在于它們原生地支持 Java 原語,例如?int、float?和?double,而非其?Object?對應(yīng)部分?Integer、Float?和?Double。這一點非常重要,因為在處理擁有數(shù)百萬項特征的數(shù)據(jù)集時,需要精打細算地考慮每個位。此外,在較大的規(guī)模上,原語及其?Object?對應(yīng)部分之間的封包成本將成為嚴重的問題。
Mahout 還引入了一種新的集成模塊,其中包含的代碼旨在補充或擴展 Mahout 的核心功能,但并非所有用戶在所有情況下都需要使用這種模塊。例如,推薦機制(協(xié)同過濾)代碼現(xiàn)在支持將其模型存儲在數(shù)據(jù)庫(通過 JDBC)、MongoDB 或 Apache Cassandra 中(請參閱?參考資料?部分)。集成模塊還包含多種將數(shù)據(jù)轉(zhuǎn)為 Mahout 格式的機制,以及評估所得到的結(jié)果的機制。例如,其中包含可將充存滿文本文件的目錄轉(zhuǎn)為 Mahout 向量格式的工具(請參閱集成模塊內(nèi)的?org.apache.mahout.text?包)。
最后,Mahout 提供了大量新示例,包括通過 Netfix 數(shù)據(jù)集計算推薦內(nèi)容、聚類 Last.fm 音樂以及其他許多示例。此外,我為這篇文章開發(fā)的示例也添加了 Mahout 的代碼庫。建議您抽出一些時間,進一步研究一下示例模塊(位于 $MAHOUT_HOME/examples 中)。
現(xiàn)在,您已經(jīng)了解了 Mahout 的現(xiàn)狀,下面我們將深入探究主要內(nèi)容:如何外擴 Mahout。
回頁首
在云中擴展 Mahout
使 Mahout 有效實現(xiàn)擴展并不容易,無法通過簡單地為 Hadoop 集群添加更多節(jié)點來實現(xiàn)此擴展。在決定 Mahout 能否能夠有效進行擴展時,算法選擇、節(jié)點數(shù)量、特性選擇和數(shù)據(jù)的稀疏性等因素(以及內(nèi)存、帶寬和處理器速度這些常見要素)扮演著至關(guān)重要的角色。為了便于討論,我將演示一個示例,合理地利用 Amazon 的 EC2 計算基礎(chǔ)架構(gòu)和 Hadoop(請參閱?參考資料),對 Apache Software Foundation (ASF) 提供的一個公共郵件存檔數(shù)據(jù)集運行某些 Mahout 算法。
在 “設(shè)置” 小節(jié)之后的每一小節(jié)中都會探討外擴 Mahout 的部分關(guān)鍵問題,并研究在 EC2 上運行示例的語法。
設(shè)置
示例的設(shè)置包括兩個部分:一個本地設(shè)置和一個 EC2(云)設(shè)置。要運行示例,您需要:
為了實現(xiàn)本地設(shè)置,請在命令行中運行以下命令:
這將編譯并恰當?shù)匕惭b您需要的全部代碼。單獨?下載示例數(shù)據(jù),將其保存在 scaling_mahout/data/sample 目錄中,并解壓縮(tar -xf scaling_mahout.tar.gz)。出于測試方面的目的,這里僅包含將在 EC2 上使用的一個較小的數(shù)據(jù)子集。
為完成 Amazon 設(shè)置,您需要提供一個?Amazon Web 服務(wù)?(AWS) 帳戶(請注意安全密鑰、訪問密鑰和帳戶 ID),還需要對 Amazon 的 EC2 和 Elastic Block Store (EBS) 服務(wù)的工作原理有一定的了解。按照 Amazon 網(wǎng)站上的文檔說明,獲得必要的訪問權(quán)限。
滿足了先決條件之后,即可啟動集群。最佳做法或許是從單獨一個節(jié)點開始,然后根據(jù)需要添加更多的節(jié)點。當然需要注意,在 EC2 上運行需要付費。因此請務(wù)必在運行完成后關(guān)閉節(jié)點。
要啟動一個集群,以便使用本文中的示例,請按以下步驟操作:
| <span style="font-family:Times New Roman;font-size:12px;"><property> <name>mapred.child.java.opts></name> <value>-Xmx8096m></value> </property> </span> |
注意:如果希望運行分類,則需要使用更大的實例和更多的內(nèi)存。我使用了兩個 X-Large 實例和 12 GB 的 Java Heap 值。
| <span style="font-family:Times New Roman;font-size:12px;">./hadoop-ec2 launch-cluster mahout-clustering <em>X</em></span> |
X?是您希望啟動的節(jié)點數(shù)量(例如?2?或?10)。建議先使用較小的值,在熟悉之后添加更多節(jié)點。這種做法有助于控制成本。
| <span style="font-family:Times New Roman;font-size:12px;">./hadoop-ec2 push mahout-clustering $PATH/setup-asf-ec2.sh</span> |
| <span style="font-family:Times New Roman;font-size:12px;">./hadoop-ec2 login mahout-clustering</span> |
| <span style="font-family:Times New Roman;font-size:12px;">./setup-asf-ec2.sh</span> |
完成具體設(shè)置之后,下一步我們來看看如何運用一些較為流行的 Mahout 算法,并對其進行上擴。我主要關(guān)注的是上擴的實際任務(wù),但在此過程中也會介紹有關(guān)特性選擇的一些問題,以及做出某些特定選擇的原因。
推薦
協(xié)同過濾是 Mahout 最流行、最易用的功能之一,因此也是討論如何外擴 Mahout 的合理起點。再次提醒,我們使用的是來自 ASF 的郵件存檔。對于推薦任務(wù)來說,一種有趣的可能性就是搭建一個系統(tǒng),根據(jù)其他用戶已經(jīng)閱讀過的郵件線程向一名用戶推薦他可能會感興趣的郵件線程。為將作為協(xié)同過濾問題處理,我將定義一個項,系統(tǒng)會根據(jù)郵件標頭中的消息 ID 和引用,確定是否將其作為郵件線程進行推薦。用戶將由郵件消息中的 “發(fā)件人” 地址定義。換句話說,我關(guān)心的是誰發(fā)出或回復(fù)了一個郵件消息。至于偏好本身的值,我直接將與郵件線程的交互作為一個布爾偏好處理:如果用戶 X 與線程 Y 交互,則偏好值為 on;否則為 off。這種選擇唯一的負面效應(yīng)就是我們必須使用可處理布爾偏好的似然性指標,例如 Tanimoto 似然法或?qū)?shù)似然法 (log-likelihood)。這通常能加快計算速度,并且可能減少系統(tǒng)內(nèi)的噪聲,但您的經(jīng)歷可能有所不同,所以您可能希望嘗試使用不同的權(quán)重。
線程、消息 ID、避免好高騖遠
請注意,我處理消息線程的方法并不完美,存在郵件列表中常見的線程劫持 (thread hijacking)。線程劫持的含義是,某人通過回復(fù)郵件列表中已有消息的方式發(fā)出新消息(即具有新主題/話題的消息),附帶傳遞了原始消息引用內(nèi)容。這篇文章沒有嘗試解決這個問題,而是直接選擇忽略,但實際解決方案可能需要正面解決此問題。因此,我選擇了 “足夠好” 的方法,力求完美。
協(xié)同過濾方面的特性選擇較為簡單(用戶、項、可選偏好),因此我們可以跳過這一步,直接介紹如何從原始郵件存檔中獲取在本地運行的內(nèi)容,然后再在云中運行。請注意,在很多情況下,最后一步通常不是必需的,因為在單獨一臺機器上可足夠快地獲得結(jié)果,沒有必要引入 Hadoop 使問題復(fù)雜化。按照大致估算,Mahout 社區(qū)基準測試表明可在單獨一個節(jié)點上為多達 1 億名用戶提供推薦。電子郵件數(shù)據(jù)達不到如此之多的項數(shù)(約為 700 萬條消息),但無論如何,我仍會繼續(xù)在 Hadoop 上運行它。
為了查看代碼的實際效果,我在 $MAHOUT_HOME/examples/bin/build-asf-email.sh 文件中的 shell 腳本內(nèi)打包了必要的步驟。請執(zhí)行這個 shell 腳本,傳遞您的輸入數(shù)據(jù)位置和所需的結(jié)果輸出位置,例如:
| <span style="font-family:Times New Roman;font-size:12px;">./build-asf-email.sh ./scaling_mahout/data/sample/content ./scaling_mahout/output/</span> |
看到提示時,選擇?recommender(選項 1),靜候 Mahout 和 Hadoop 冗長的日志輸出完成。完成后,您將看到類似清單 1 所示的內(nèi)容:
清單 1. 運行推薦機制代碼的輸出示例?
| <span style="font-family:Times New Roman;font-size:12px;"> 11/09/08 09:57:37 INFO mapred.JobClient: Reduce output records=2072 11/09/08 09:57:37 INFO mapred.JobClient: Spilled Records=48604 11/09/08 09:57:37 INFO mapred.JobClient: Map output bytes=10210854 11/09/08 09:57:37 INFO mapred.JobClient: Combine input records=0 11/09/08 09:57:37 INFO mapred.JobClient: Map output records=24302 11/09/08 09:57:37 INFO mapred.JobClient: SPLIT_RAW_BYTES=165 11/09/08 09:57:37 INFO mapred.JobClient: Reduce input records=24302 11/09/08 09:57:37 INFO driver.MahoutDriver: Program took 74847 ms </span> |
此作業(yè)的結(jié)果是面向輸入數(shù)據(jù)內(nèi)所有用戶的全部推薦。結(jié)果存儲在輸出目錄的子目錄 prefs/recommendations 中,包含名稱以 part-r- 開頭的一個或多個文本文件。(這就是 Hadoop 輸出文件的方式。)查看其中的一個文件即可注意到推薦已格式化為以下形式(同時還有一條警告):
| <span style="font-family:Times New Roman;font-size:12px;"> <em>user_id</em> [<em>item_id</em>:<em>score</em>, <em>item_id</em>:<em>score</em>, ...]</span> |
例如,用戶 ID 25 具有針對電子郵件 ID 26295 和 35548 的推薦。警告指出,user_id?和?item_id?并非原始 ID,而是從原始 ID 映射而來的整數(shù)。為幫助您理解這樣做的原因,我將解釋一下在執(zhí)行 shell 腳本時實際發(fā)生的情況。
在生成推薦結(jié)果的過程中,涉及三個步驟:
本文不會詳細介紹第 1 步,只建議對此感興趣的讀者參閱代碼。
對于第 2 步,需要花一些工夫從文件中提取相關(guān)的信息片段(消息 ID、回復(fù)引用和 From 地址),隨后以三元組(FromID、Message-ID、偏好)的形式存儲它們,以供?RecommenderJob?使用。此過程由?MailToPrefsDriver?驅(qū)動,其中包含三個 “Map-Reduce” 作業(yè):
完成所有這些操作之后,即可開始生成一些推薦。為了創(chuàng)建推薦,RecommenderJob?將執(zhí)行圖 1 所示的步驟:
圖 1. 推薦機制作業(yè)流
?
完成工作流中大部分工作的主要步驟是 “計算共生(calculate co-occurrences)” 步驟。這個步驟負責在整個矩陣內(nèi)執(zhí)行成對比較,尋找共性。除此之外,對于執(zhí)行矩陣內(nèi)任何行之間的成對計算(而不僅僅限于評分/評論),這個步驟(由 Mahout?RowSimilarityJob支持實現(xiàn))通常也非常有用。
shell 腳本中使用以下命令調(diào)用了?RecommenderJob:
| <span style="font-family:Times New Roman;font-size:12px;">bin/mahout recommenditembased --input $PREFS_REC_INPUT --output $RECS_OUT --tempDir$PREFS_TMP --similarityClassname SIMILARITY_LOGLIKELIHOOD> </span> |
第一個參數(shù)告訴 Mahout 要運行哪個命令(RecommenderJob);其他幾個參數(shù)(input/output/tempDir)的含義不言自明。similarityClassname?告訴 Mahout 在計算共生時如何計算各項之間的似然性。我選擇使用對數(shù)似然性是因為它的簡單性、速度和質(zhì)量。
獲得結(jié)果之后,下一步就是評估結(jié)果。Mahout 附帶了一個評估包(org.apache.mahout.cf.taste.eval),提供了一些有用的工具,可幫助您檢查結(jié)果的質(zhì)量。遺憾的是,它們無法與基于 Hadoop 的算法一起使用,但在其他一些情況下可能非常有用。這些工具抽出一定百分比的數(shù)據(jù)作為測試數(shù)據(jù),隨后將這些數(shù)據(jù)與系統(tǒng)生成的數(shù)據(jù)對比,從而判斷質(zhì)量。
這就是生成推薦所需的全部操作,這種做法的優(yōu)點在于可以直接在集群上運行。為此,請登錄您之前設(shè)置的 EC2 集群,并運行與之前相同的 shell 腳本(/mnt/asf-email/mahout-trunk/examples/bin)。在向集群添加節(jié)點時,您應(yīng)看到運行這些步驟所需的總時間縮短了。例如,在本地機器上運行一個完整的數(shù)據(jù)集需要超過三天的時間才能完成。在 EC2 上的一個 10 節(jié)點集群中,運行主要推薦任務(wù)加上將電子郵件轉(zhuǎn)換為可用格式的準備時間只需約 60 分鐘。
最后一部分是將推薦作為應(yīng)用程序的一部分使用,這部分留給讀者作為練習。典型情況下,如果系統(tǒng)中有大量的項和用戶,推薦將定期生成 — 根據(jù)業(yè)務(wù)需求的不同,生成頻率大致為每小時一次至每天一次。無論如何,如果系統(tǒng)中的用戶和推薦達到一定的數(shù)量,那么對所生成的推薦進行的更改將會更加微妙。
接下來,我們來觀察一下電子郵件消息的分類,在某些情況下,可將此視為一種上下文推薦系統(tǒng)。
分類
Mahout 擁有多種分類算法,其中大多數(shù)算法都是為了在 Hadoop 上運行而編寫的(只有一個值得注意的例外,即隨機梯度下降法)。出于本文的目的,我將使用貝氏分類器 (na?ve bayes classifier),許多人最初都選擇這種分類器,在有效擴展的時候,它也能給出合理的結(jié)果。有關(guān)其他分類器的更多細節(jié),請參見《Mahout 實戰(zhàn)》一書中的相關(guān)章節(jié),或者 Mahout wiki 中的 “算法” 部分(請參閱?參考資料?部分)。
電子郵件文檔按照 Apache 項目(Lucene、Mahout、Tomcat 等)細分,通常每個項目有兩個或兩個以上的郵件列表(用戶、開發(fā)等等)。考慮到 ASF 電子郵件數(shù)據(jù)集是按照項目分區(qū)的,因此一個合情合理的分類問題就是:嘗試預(yù)測一條新傳入的消息應(yīng)交付至哪個項目。例如,一條新消息是屬于 Lucene 郵件列表還是屬于 Tomcat 郵件列表?
要使 Mahout 的分類算法發(fā)揮效力,必須實現(xiàn)一個表示要識別的模式的模型,隨后根據(jù)一個數(shù)據(jù)子集進行測試。在大多數(shù)分類問題中,都必須有一名或多名人員身體力行,手動標注將要在訓練中使用的數(shù)據(jù)子集。但在本文所討論的情況下,數(shù)據(jù)集已經(jīng)按項目進行了劃分,因此無需手動標注,但我要依靠人們在發(fā)送電子郵件時通常能夠選取正確的列表這個事實,而我們都知道,事情并非總是能這樣順利。
就像在推薦機制示例中所介紹的一樣,必要的步驟已經(jīng)預(yù)先打包在 build-asf-email.sh 腳本之中,只要從菜單中選擇選項 3(隨后在出現(xiàn)第二條提示時選擇選項 2,即標準貝氏分類器)即可執(zhí)行分類。類似于推薦,外擴代碼的部分工作是準備好要使用的數(shù)據(jù)。對于文本分類,這實際上意味著對特性進行編碼,隨后根據(jù)特性創(chuàng)建向量,但還包括設(shè)置訓練和測試集。需要執(zhí)行的全部步驟如下:
| <span style="font-family:Times New Roman;font-size:12px;">bin/mahout org.apache.mahout.text.SequenceFilesFromMailArchives --charset "UTF-8" --body --subject --input $ASF_ARCHIVES --output $MAIL_OUT </span> |
| <span style="font-family:Times New Roman;font-size:12px;">bin/mahout split --input $SEQ2SPLABEL --trainingOutput $TRAIN --testOutput $TEST--randomSelectionPct 20 --overwrite --sequenceFiles </span> |
值得注意的兩個重要步驟就是第 2 步和第 4 步。第 2a 步是主要的特性選擇和編碼步驟,一系列的輸入?yún)?shù)負責控制如何將輸入文本表示為向量中的權(quán)重。表 2 具體列舉了第 2 步中與特性選擇相關(guān)的選項:
表 2. 創(chuàng)建向量時的特性選擇選項
| --norm | norm 通過一個計算向量長度的函數(shù) (norm) 來修改所有向量 | 1 norm = 曼哈頓距離,2 norm = 歐幾里得距離 |
| --weight | 計算任何給定特性的權(quán)重,并將其作為 TF-IDF(術(shù)語頻率,逆向文檔頻率)或者單純的術(shù)語頻率。 | TF-IDF 是搜索和機器學習中常用的權(quán)重模式,通常用于將文本表示為向量。 |
| --maxDFPercent,?--minSupport | 這些選項均用于刪除文檔集合中出現(xiàn)得過于頻繁(最大值)或過于不頻繁的術(shù)語 | 在自動刪除對于計算價值不高的高頻術(shù)語或低頻術(shù)語時非常有用 |
| --analyzerName | 一個 Apache Lucene 分析器類,可用于對文檔中的詞執(zhí)行分詞、詞干化、刪除或其他更改 | 如需進一步了解 Lucene,請參閱?參考資料?部分 |
第 2a 步中的分析過程值得深究,因為它承擔了特性選擇的大部分工作。Lucene?Analyzer?包括一個?Tokenizer?類以及零個或多個TokenFilter?類。Tokenizer?負責將原始輸入劃分成零個或多個標記(例如,單詞)。TokenFilter?實例彼此連接,隨后修改Tokenizer?生成的標記。例如,示例中所用的?Analyzer:
這項分析的最終結(jié)果將使各文檔的對應(yīng)向量顯著減少,并消除向量中可能會使分類器產(chǎn)生混淆的常見 “噪聲” 詞(the、a、an?等)。這個?Analyzer?以迭代的方法開發(fā),首先在電子郵件中查找示例,隨后通過?Analyzer?對其加以處理并檢查輸出,從而判斷處理效果。遺憾的是,這個流程可以說是科學的,但也僅僅是一種直觀的體驗。流程和結(jié)果并不完美,但足夠好。
第 2b 步對數(shù)據(jù)稍加轉(zhuǎn)化以便處理,還刪除了一些內(nèi)容,使各種不同的標簽平均地出現(xiàn)在訓練數(shù)據(jù)中。這一點非常重要,因為我最初嘗試處理數(shù)據(jù)時產(chǎn)生了機器學習中的常見問題,即相關(guān)訓練示例過多的標簽的過度擬合 (overfitting)。實際上,對完整的數(shù)據(jù)集運行聚類時,將?--maxItemsPerLabel?的設(shè)置降低至 1000 仍然不夠好,無法得到良好的結(jié)果,因為部分郵件列表中發(fā)布的內(nèi)容少于 1000。這很可能是由 Mahout 的一個 bug 導致的,社區(qū)目前仍然在對此進行研究。
第 4 步是執(zhí)行實際工作的部分,包括構(gòu)建模型和隨后測試模型是否有效。在第 4a 步中,--extractLabels?選項告訴 Mahout 根據(jù)輸入判斷訓練標簽。(另外一種做法是直接傳入標簽。)這個步驟的輸出是一個可通過org.apache.mahout.classifier.naivebayes.NaiveBayesModel?類讀取的文件。第 4b 步獲取模型和測試數(shù)據(jù),檢查訓練成效如何。輸出結(jié)果是一個混合矩陣,如 “Apache Mahout 簡介” 一文所述。對于示例數(shù)據(jù),輸出結(jié)果如清單 2 所示:
清單 2. 運行分類器代碼的輸出示例
| <span style="font-family:Times New Roman;font-size:12px;"> Correctly Classified Instances : 41523 61.9219% Incorrectly Classified Instances : 25534 38.0781% Total Classified Instances : 67057 ======================================================= Confusion Matrix ------------------------------------------------------- a b c d e f ><--Classified as 190440 12 1069 0 0 | 20125 a= cocoon_apache_org_dev 2066 0 1 477 0 0 | 2544 b= cocoon_apache_org_docs 165480 2370 704 0 0 | 19622 c= cocoon_apache_org_users 58 0 0 201090 0 | 20167 d= commons_apache_org_dev 147 0 1 4451 0 0 | 4599 e= commons_apache_org_user </span> |
您應(yīng)注意到,這對分類器來說實際上是一種非常糟糕的顯示(盡管好于猜測)。產(chǎn)生這種糟糕的顯示的原因很可能是給定 Apache 項目的用戶和開發(fā)郵件列表的詞匯過于相近,難以區(qū)分。16,548 條 cocoon_user 消息被錯誤地分類為 cocoon_dev 即可說明這一點。實際上,如果直接使用項目名稱重新運行任務(wù),而不區(qū)分示例數(shù)據(jù)中的用戶類表和開發(fā)列表,將得到清單 3 所示的結(jié)果:
清單 3. 僅使用項目名稱重新運行分類器代碼的輸出示例
| <span style="font-family:Times New Roman;font-size:12px;"> Correctly Classified Instances : 38944 96.8949% Incorrectly Classified Instances : 1248 3.1051% Total Classified Instances : 40192======================================================= Confusion Matrix ------------------------------------------------------- a b c ><--Classified as 18733 1241 0 | 19974 a = cocoon_apache_org 7 20211 0 | 20218 b = commons_apache_org </span> |
您一定同意,96% 的準確度比 61% 好太多了!實際上,該結(jié)果過于完美,不可能是真的。這樣的評分可能源于這個特定的小數(shù)據(jù)集的本質(zhì),或者是有待調(diào)查的更深層面的問題。事實上,這樣的評分應(yīng)警示我們進一步開展調(diào)查,添加數(shù)據(jù)并檢查生成這種評分的代碼。就目前而言,我的目的是通過這個示例來展示結(jié)果的效果,因此不再深究。然而,我們應(yīng)該嘗試利用其他技術(shù)或者更好的特性選擇,或許還應(yīng)該采用更多的訓練示例,以便提高準確性。對結(jié)果執(zhí)行交叉驗證?也是一種常見的做法。交叉驗證包括從訓練樣本中反復(fù)獲取部分數(shù)據(jù),并將其納入測試樣本,或者將這部分數(shù)據(jù)留出不用。隨后系統(tǒng)將判斷全部運行過程的質(zhì)量,而不僅考慮一次。
將此納入云就像是使用推薦機制一樣簡單。整個腳本將在您的集群中運行,只需傳入恰當?shù)穆窂郊纯伞H绻?EC2 的 10 節(jié)點集群上運行,除通常的準備工作之外,訓練和測試的整個過程只需短短幾分鐘。遺憾的是,如果您這樣運行,則對云中整個數(shù)據(jù)集的運行質(zhì)量將下降,因為某些郵件列表所包含的數(shù)據(jù)點極少。這些問題很可能未得到充分的考慮。
實現(xiàn)生產(chǎn)的后幾步包括使模型作為運行時系統(tǒng)的一部分,設(shè)置工作流以確保從系統(tǒng)獲得反饋時更新模型。下面,我將介紹聚類。
聚類
與分類相似,Mahout 也有無數(shù)種聚類算法,每種算法都有著與眾不同的特點。例如,K-Means 的伸縮能力出色,但需要您預(yù)先指定需要的聚類數(shù)量;而狄利克雷聚類要求您選擇所需的模型分布和聚類數(shù)量。聚類與分類有很多共同之處,在某些情況下甚至可以共同使用,將聚類作為分類的一部分。除此之外,分類的大部分數(shù)據(jù)準備工作都與聚類相似,例如將原始內(nèi)容轉(zhuǎn)換為順序文件,隨后再轉(zhuǎn)換為稀疏向量,因此您可以參考?分類?部分,了解這些信息。
對于聚類來說,要回答的主要問題是:我們能否根據(jù)內(nèi)容的相似度來合情合理地組織所有消息(而無論項目如何)?例如,或許 Apache Solr 郵件列表中有關(guān)使用 Apache Tomcat 作為一種 Web 容器的消息與針對 Tomcat 項目的消息更為接近,而非原始項目。
就本例而言,前幾個步驟與分類相似,但在轉(zhuǎn)換為稀疏向量之后就發(fā)生了差別。具體步驟如下:
本例中運行 K-Means 來執(zhí)行聚類,但 shell 腳本也支持運行狄利克雷聚類。(執(zhí)行腳本時,您將看到選擇希望運行哪種算法的提示。)在之前的示例中,值得深入研究的參數(shù)如下:
在運行完成之后,您可以使用 Mahout 的?ClusterDump?程序轉(zhuǎn)儲聚類質(zhì)心(和相關(guān)的點)。最終結(jié)果將存儲在 kmeans 目錄下名稱以 clusters- 開頭、以 -final 結(jié)尾的子目錄中。具體的值將取決于運行任務(wù)使用了多少次迭代,例如?clusters-2-final?是第三次迭代的輸出結(jié)果。例如,以下命令將轉(zhuǎn)儲聚類,而不是運行小規(guī)模數(shù)據(jù)樣本:
| <span style="font-family:Times New Roman;font-size:12px;">bin/mahout clusterdump --seqFileDir ../output/ibm/clustering/kmeans/clusters-2-final--pointsDir ../output/ibm/clustering/kmeans/clusteredPoints/ </span> |
--seqFileDir?指向所創(chuàng)建的質(zhì)心,-pointsDir?是聚類點的目錄。清單 4 給出了小部分結(jié)果抽樣:
清單 4. 運行?ClusterDumper?的輸出示例
| <span style="font-family:Times New Roman;font-size:12px;"> :VL-337881{n=4420 c=[Top Terms:user =>0.060885823267350335mailscann => 0.05059369006868677cocoon =>0.048781178576134204virus => 0.04285897589148712derek => 0.04084340722527813legal =>0.040052624979813184scan => 0.03861016730680097danger => 0.03848600584647758csir => 0.03712359352614157transtec => 0.03388019099942435Weight : [props - optional]: Point:1.0 : [distance=0.888270593967813]: /cocoon.apache.org/dev/200004.gz/NBBBIDJGFOCOKIOHGDPBKEPPEEAA.XXXXX = [ag:0.165, briefli:0.250, chang:0.075, close:0.137, cocoon:0.060, cocoon1:0.226, cocoon2:0.218, concept:0.277, develop:0.101, differ:0.144, explain:0.154, greet:0.197, klingenderstrass:0.223, langham:0.223, look:0.105, mailserv:0.293, matthew:0.277, mlangham:0.240, paderborn:0.215, processor:0.231, produc:0.202, put:0.170, scan:0.180, tel:0.163, understand:0.127, virus:0.194] </span> |
在?清單 4?中,請注意輸出包括一個術(shù)語列表,算法已經(jīng)確定這是聚類中最有代表性的術(shù)語列表。在生成用于生產(chǎn)的標簽、在準備步驟中調(diào)優(yōu)特性選擇時,這可能很有幫助,因為停止詞(本例中,user?很可能就是一個停止此)往往出現(xiàn)在前幾次試運行數(shù)據(jù)時的列表中。
正如您期待的那樣,在集群中運行此任務(wù)就像在本地運行一樣簡單 — 就像這兩個示例中一樣簡單。在我的測試中,除了轉(zhuǎn)換內(nèi)容所用的時間之外(約為 150 分鐘),10 個節(jié)點上的實際聚類作業(yè)僅用了大約 40 分鐘。
遺憾的是,對于聚類,盡管 Mahout 確實提供了一些評估工具(請參見輸出頂級術(shù)語的?CDbwEvaluator?和?ClusterDumper?選項),但評估結(jié)果往往會簡化為 “氣味測試(smell test)”。在氣味測試中,可視化聚類往往是最有益的做法,但很多圖形可視化工具包難以處理大型數(shù)據(jù)集,因此您可能需要依靠自己的設(shè)備實現(xiàn)可視化。
就像推薦和分類一樣,實現(xiàn)生產(chǎn)的后續(xù)步驟包括確定獲取數(shù)據(jù)的工作流以及執(zhí)行處理的頻率,當然,還包括在您的業(yè)務(wù)環(huán)境中實際應(yīng)用。您可能需要嘗試不同的算法,確定哪種算法最適合您的數(shù)據(jù)。
回頁首
Mahout 未來展望
Apache Mahout 仍在通過多種方式向前發(fā)展。目前,社區(qū)的關(guān)注重點是通過執(zhí)行性能測試、文檔整理、API 改進和新算法添加來促進 1.0 發(fā)布版的推出。下一個發(fā)布版(即 0.6 版)很有可能在 2011 年的年底或不久之后推出。在較為深入的層面,該社區(qū)也開始著眼于分布式、內(nèi)存中的機器學習問題解決方法。在很多情況下,單憑一臺機器難以處理復(fù)雜的機器學習問題,但 Hadoop 又引入了過多磁盤 I/O 方面的負擔。無論采用哪種方法,關(guān)注可伸縮性的 Mahout 都能很好地幫助您解決當前最艱難的大數(shù)據(jù)問題,使得復(fù)雜機器學習算法的使用更加輕松。
致謝
特別感謝 Timothy Potter 協(xié)助我完成 AMI 打包,感謝 Mahout 專家 Sebastian Schelter、Jake Mannix 和 Sean Owen 的技術(shù)審查。本文的部分內(nèi)容由 Amazon Apache 測試計劃提供支持。
回頁首
下載
| Shell 腳本 | j-mahout-scaling.zip | 2KB | HTTP |
關(guān)于下載方法的信息
參考資料
學習
- "Apache Mahout 簡介”(Grant Ingersoll,developerWorks,2009 年 9 月):Mahout 聯(lián)合創(chuàng)始人 Ingersoll 介紹了機器學習的基本概念,展示了如何使用 Mahout 來聚類文檔、提供推薦以及組織內(nèi)容。
- Apache Mahout:隨時關(guān)注 Apache Mahout 主頁,了解所有最新新聞、獲得文檔和新下載內(nèi)容。?
- Powered By Mahout:Mahout 的 “powered by” 頁面列舉了愿意公開其使用 Mahout 算法的情況的眾多公司。?
- Taming Text(Grant S. Ingersoll、Thomas S. Morton 和 Andrew L. Farris,Manning Publications,2011 年):這本書介紹了 Mahout 和用于構(gòu)建基于文本的應(yīng)用程序的相關(guān)開放源碼技術(shù)。?
- Mahout 實戰(zhàn)?(Sean Owen、Robin Anil、Ted Dunning 和 Ellen Friedman,Manning Publications,2011 年):這本書是理解 Mahout 的終極指南。?
- Apache Hadoop:了解 Hadoop。?
- 算法:在 Mahout Wiki 中閱讀有關(guān) Mahout 實現(xiàn)的算法的更多內(nèi)容,并進一步了解社區(qū)關(guān)注的領(lǐng)域。?
- 驚喜和巧合:在 Mahout 專家 Ted Dunning 的博客中了解有關(guān)對數(shù)似然性測量的有用之處。?
- MongoDB:訪問 MongoDB 網(wǎng)站,發(fā)現(xiàn)有關(guān) MongoDB 的更多內(nèi)容。?
- Apache Cassandra:訪問 Apache Cassandra 網(wǎng)站,獲得有關(guān) Apache Cassandra 的更多信息。在 Sean Owen 的博客文章 “Recommending (from) Cassandra” 中進一步了解如何將其與 Mahout 一起使用。?
- Amazon Web 服務(wù),包括 EC2 在內(nèi):進一步了解 Amazon 的 EC2 基礎(chǔ)架構(gòu)。?
- 使用現(xiàn)有 Hadoop AMI:Mahout wiki 中的這個頁面詳述了在 EC2 中啟動 Hadoop 集群的流程。?
- Amazon EC2 用戶指南:查詢 EC2 用戶指南,了解本文中的?設(shè)置?步驟:
- 使用公共數(shù)據(jù)集:如何使用 Amazon EC2 公共數(shù)據(jù)集。
- Apache Software Foundation 公共郵件存檔:使用 Apache Software Foundation 公共郵件存檔的一個快照來測試 Mahout。
- 使用 Amazon EBS 卷:如何使 Amazon EBS 卷可用于您的操作系統(tǒng)。
- 命令行工具入門:如何設(shè)置您的 Amazon EC2 環(huán)境,以便利用 Amazon EC2 命令行工具(也稱為?API 工具?或?CLI 工具)。
- Message-ID:進一步了解郵件標頭和 Message-ID(消息 ID)。?
- Apache Lucene:訪問 Apache Lucene 網(wǎng)站,了解 Apache Lucene 的更多信息。?
- Martin Porter 博士的雪球式詞干分析器:這些詞干分析器通常適用于處理搜索和機器學習項目中的文本。?
- 瀏覽?技術(shù)書店,閱讀有關(guān)這些主題和其他技術(shù)主題的圖書。?
- developerWorks 中國網(wǎng)站 Java 技術(shù)專區(qū):查看數(shù)百篇關(guān)于 Java 編程各個方面的文章。?
獲得產(chǎn)品和技術(shù)
- Apache Mahout:下載 Grant Ingersoll 的 Mahout 源代碼,其中包括示例。?
- 下載?IBM 產(chǎn)品評估試用版軟件?或者IBM SOA 人員沙箱,親身體驗 DB2?、Lotus?、Rational?、Tivoli? 和 WebSphere? 方面的應(yīng)用程序開發(fā)工具和中間件產(chǎn)品。?
討論
- Mahout 用戶郵件列表:訂閱此郵件列表,以便提出問題、分享知識、討論話題。?
- 加入?developerWorks 社區(qū)。與其他 developerWorks 用戶聯(lián)系,瀏覽開發(fā)人員推動的博客、論壇、小組和 wiki。
關(guān)于作者
Grant Ingersoll 是 Lucid Imagination 的創(chuàng)始人和技術(shù)成員之一。Grant 的編程興趣包括信息檢索、機器學習、文本分類和提取。Grant 是 Apache Mahout 機器學習項目的創(chuàng)始人之一,并且是 Apache Lucene 和 Apache Solr 項目的負責人和發(fā)言人。他還是描述使用開源工具進行自然語言處理的圖書?Taming Text(Manning 出版社,即將上市)的合著者。
總結(jié)
以上是生活随笔為你收集整理的Apache Mahout:适合所有人的可扩展机器学习框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。