原來的 title 是「文字處理」,但是那會和 Word processing 混淆,故此用了如此的奇怪的 term 。
分析中文文本,對比英文是有非常大的分別。英文的分析我認為是相對較易,而且理論也基本上是以英文分析最為完備。
參考以下英文及中文句子:
Our introduction to the R environment did not mention statistics, yet many people use R as a statistics system. We prefer to think of it of an environment within which many classical and modern statistical techniques have been implemented. A few of these are built into the base R environment, but many are supplied as packages.
我們對 R 環境的介紹中沒有提到統計,但是大多數人用 R 就是因為它的統計功能。不過,我們寧可把 R 當作一個內部實現了許多經典的時髦的統計技術的環境。部分的統計功能是整合在 R 環境的底層,但是大多數功能則以「包」的形式提供。
英文用空格或標點符號等等 delimiter 將詞1 隔開。故此要計算每個關鍵詞的頻率,電腦處理會較易。但是中文的情況,詞並不是用 delimiter 隔開,我們用人腦會知道「我們對 R 環境的介紹中沒有提到統計」是可以分成「我們、對、R、環境、的、介紹、中、沒有、提到、統計」,但是電腦處理會有困難。
電腦分詞是自然語言處理2 的第一步。就這個問題,曾經詢問過朋友。友人 Clement T 先生想出了類似英語 N-gram 的方法。例如第一句:「我們對 R 環境的介紹中沒有提到統計」頭幾個字是可以分成:
我
我們
我們對
我們對 R
我們對 R 環
我們對 R 環境 ….
「我」這個詞,在文中出現兩次。「我們」這個詞,在文中也出現兩次。但是「我們對」之後的,只出現過一次。故此,我們有理由相信「我」或「我們」是常用的詞,而「我們」較「我」長,貪婪地是應選「我們」,故此「我們對 R 環境的介紹中沒有提到統計」中的頭兩個字應該可以獨立成詞。
這個方法經過查書之後,知道名為 forward greedy matching 。事實上,市面有不同的方法進行中文分詞處理,這個 stackoverflow 問題列出不少相關的方案。
基於歷史原因,最近我在工作上使用的是據聞由雅虎研製的 nlpbamboo 。但是長遠來說,我想轉用 Stanford Word Segmenter 。3 據聞中科院研製的 ICTCLAS 也不錯,但可惜並非完全 opensource 。
下集再講講實際操作時所面對的問題,以及 R 整合方法。
A task that come up regularly during data munging is like this: you have a list of user ID (uid). Then, you have another table that has the user ID(lookup.uid) and the value of interest(lookup.value). You would like to fetch the list of value (lookup.value) with the uid = lookup.uid and retaining the order of uid.
I don’t know the terminology for this task. I usually call it “lookup”.
Programmatically, lookup can be done with a simple for-loop to loop through the uid and match the uid with the lookup.uid one by one. In R, the following is the usual pattern for this for-loop.
#< -
forlooplookup <- function(uid, lookup) {
uid.value <- rep(NA, length(uid))
for (i in 1:length(uid)) {
uid.value[uid == lookup[i,1]] <- lookup[i,2]
}
return(uid.value)
}
However, for loop is slow. The whole point of R programming is vectorization1 . The above for-loop can be rewritten using the vectorized match() function.
For-loop version took 29.4s to complete but only 0.007s for vectorized version. The performance was increased by 4200 folds.
We can also assert two functions are doing the same thing to check for correctness.