Mahout的TF-IDF 淺度與深度使用筆記

Lucene以及Mahout還有Hadoop都是一家人,處理TFIDF的計算真的不需要再重新寫過,如果在這個EcoSystem的平台上,應該是直接引用就好,然而,這裡面的運作宛如黑箱子,所以這篇簡短的文章試著幫大家窺視一下TFIDF裡面的機制。

TF-IDF的描述請詳見- http://zh.wikipedia.org/wiki/TF-IDF

Lucene早就有處理TF-IDF的方法,不是這篇文章的重點,今天講的是Mahout處理TF-IDF的機制~

要用Mahout的TFIDF機制很容易,你不需要會java也可以~

輸入的序列檔格式是<Text,Text>,Key是文件代號,Value是文件內容,以Mobile01 Canon板上面的文章,輸入的格式就是以下的序列檔

****************************

521c246530041d9129773125:你是用那種後製軟體阿,由其是那個大圓章,是怎麼做的

****************************

接著下mahout命列seq2sparse即可!!

mahout seq2sparse -i tweets-seq -o tweets-vectors

所有的內容都會放在tweets-vectors裡面。

=========給深度使用者==========

如果你覺得下指令不夠過癮,一定要整合到API,那請參考以下的code

 //輸入的序列化檔案路徑
String inputDir = "data/canon";
// HDFS環境設定
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
String outputDir = "reuters";
HadoopUtil.delete(conf, new Path(outputDir));
//所有tf, df, tf-idf存放的資料夾路徑設定
Path tokenizedPath = new Path(outputDir,
DocumentProcessor.TOKENIZED_DOCUMENT_OUTPUT_FOLDER);

//一長串文字一定要有個斷詞分析器
ChineseAnalyzer analyzer=new ChineseAnalyzer();

//進行段詞Tokenized, 這會產生以斷完詞的文件序列,輸出格式為&lt;Text,StringTuple&gt;
DocumentProcessor.tokenizeDocuments(new Path(inputDir), analyzer.getClass()
.asSubclass(Analyzer.class), tokenizedPath, conf);

//進行TF的產生
DictionaryVectorizer.createTermFrequencyVectors(tokenizedPath,
new Path(outputDir), conf, minSupport, maxNGramSize, minLLRValue, 2, true, reduceTasks,
chunkSize, sequentialAccessOutput, false);

//進行IDF的產生
TFIDFConverter.processTfIdf(
new Path(outputDir , DictionaryVectorizer.DOCUMENT_VECTOR_OUTPUT_FOLDER),
new Path(outputDir), conf, chunkSize, minDf,
maxDFPercent, norm, false, sequentialAccessOutput, false, reduceTasks);

===========================

順帶一提,我們團隊已經有寫好的CKIP斷詞分析器的套件,我們願意分享,請留言囉~

一般而言產生的文件有許多個資料夾,分別詳述如下:

  • df-count <IntWritable,LongWritable>

文件內容如下:

3329:1

3330:2

  • tf-vectors <Text,VectorWritable>

文件內容如下:

521c244d30041d9129773111:{2461:0.1042572070285374,944:0.1042572070285374,…}

  • tfidf-vectors <Text,VectorWritable> 與tf-vectors類似。
  • tokenized-documents <Text,StringTuple>

文件內容如下:

      521c246530041d9129773125:[你, 是, 用, 那, 種, 後, 製, 軟, 體, 阿, 由, 其, 是, 那, 個, 大, 圓, 章, 是,           怎, 麼, 做, 的]
  • wordcount <Text,LongWritable>

文件內容如下:

神:15

票:12

  • dictionary.file-0

文件內容如下:

a05:0

a06:1

a061:2

  • frequency.file-0

文件內容如下:

0:1

1:2

2:1

由此看來,最先產生的是 tokenized-documents,接著統計總共的文字集合放在dictionary.file-0裡面,再計算文字在每個文章內出現的向量放在tf-vectors裡面,然後計算文字出現在多少個文件裡面放在df-count,文字出現的次數放在wordcount裡面,frequency.file-0也是存放文字出現的次數,差別在於wordcount是直接存放文字與其次數,而frequency.file-0則是存放文字的索引以及其次數。

基本上放到分群演算法裡面,直接放tfidf-vectors或是tf-vectors即可,由此可知,mahout的群聚演算法的input是每筆的<Text,VectorWritable>資料。

而mahout的分類演算法略為不同,在學習與測試階段,我們必須要給每筆資料一個標記,標記的資訊需要與文件序號透過/隔開,範例如下:

/tech/309514920892964864:{490:5.852030277252197,829:3.6548056602478027,…

這是指文件序號309514920892964864是屬於tech類,其向量為{490:5.852030277252197,829:3.6548056602478027,…

順帶一提,放入NaiveBayes時需要放入類別標記的索引,例如有五個類別:apparel:0、art:1、camera:2、event:3、health:4、home:5與tech:6,我們要把這存成<Text,IntWritable>的資料。

還記得怎麼訓練NaiveBayes嗎~

mahout trainnb -i train-vectors -el -li labelindex -o model -ow -c

其中-li後面跟著的就是索引檔。

最後下一個感想以及給一個功課,功課是將iris的資料去產生一個NaiveBayes的模型吧~感想是,Mahout的文件真的是少的可憐,只能靠大家不斷的分享以及整理囉!

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s