2013年5月16日 星期四

perl使用regular expression來match中文數字的寫法

中文的一,從emacs上按C-u C-x =可查得以下資料

file code: #xE4 #xB8 #x80 (encoded by coding system utf-8-dos)

character: 一 (displayed as 一) (codepoint 19968, #o47000, #x4e00)

以下假設資料檔abc為utf8格式儲存。最基本的寫法是

perl -ne 'print if m/^一、/'  abc

使用utf8碼亦可

perl -ne 'print if m/^\xe4\xb8\x80、/'  abc

以下寫法則錯誤,因為[]這個寫法會取第一個byte,所以會match到其它字

perl -ne 'print if m/^[一]、/'  abc

由於中文字的大寫數字當初制定unicode時沒有連號,事實上也不能用[0-9]這種寫法…

以下是目前看來可以work的寫法

perl -ne 'print if m/^(一|二|三|四|五|六|七|八|九|十)+、/'  abc

要match任意中文字,必需要使用 '-Mopen qw/:std :utf8/' 選項,它最大的功用在於將所讀入的utf8編碼字串自動轉為unicode,不需要手動呼叫decode('utf8',$string),例如

perl '-Mopen qw/:std :utf8/' -ne 'print if /\p{Han}/'  abc
perl '-Mopen qw/:std :utf8/' -ne 'print if /[\x{4e00}-\x{9fcc}]/' abc

這兩種寫法的效果是一樣的,而//當中放中文字時顯然固定會被當作utf8去match,因此以下寫法錯誤

perl -ne 'print if m/^一、/'  abc

perl '-Mopen qw/:std :utf8/' '-MEncode' -ne '$test=decode("utf8","一");print if m/$test/'  abc

理想上我也希望能混用中文及萬用字元於常規表示法,不過目前看來是無解了…


2013年5月14日 星期二

嘸蝦米的日文輸入

https://sites.google.com/site/freelearnwang/jp/jp-in-met-1/wuxiami-riwenshurufa

這其中長音  比較特別,是 ee, 或 ee.

2013年5月9日 星期四

Emacs中特殊字元的顯示及輸入

http://ergoemacs.org/emacs/keystroke_rep.html

像是由word的doc檔轉來的,裏面會出現很多^K,這是當使用者使用了自動編號功能,在換行時按了C-enter所致。還有word中換行是\r\n,在emacs中只使用\n,因此多出來的\r會以^M這樣的形式出現在每一行末;有時Emacs左下角若為U(DOS)模式時可認出文件由windows所生成,自然會轉換為正確的顯示方式,但有時認不出來,或換行符號有多種組合存在同一文件中,那麼也會認不出來。

至於這些特殊字元的輸入,則以像C-q C-J這樣的按鍵組合來輸入\n(即^J)這個0xA字元於buffer當中

2013年5月6日 星期一

perl one liner開utf8檔的寫法

一開始是因為要試regular expression在match 單一中文字時,竟然無法成功。眼看 http://stackoverflow.com/questions/12312310/how-to-match-chinese-characters-in-perl?lq=1 上寫得斬釘截鐵,我開始懷疑起自己來了…

結果寫了個.pl檔試試,一開始也失敗,但是開始發現,問題似乎是因為沒有以utf8格式開檔,後來找到 http://zenoga.tumblr.com/post/40094864918/unicode-aware-perl-one-liners 才解決了這個問題。看起來沒什麼,不過可花了我半個早上啊…

以下這行就是結果,可以拿來斷中文句子

perl '-Mopen qw/:std :utf8/' -ne 'while(m/(\p{Han}+)/g){print "$1\n";}'   test.simp.utf8

據說詞頻的統計要用到 pat-tree / suffix tree / trie,估狗了一下覺得只有 http://search.cpan.org/~avif/Tree-Trie-1.9/Trie.pm 適合中文詞頻統計之用。有個現成的斷詞模組叫mmseg, 用法如下

perl '-Mopen qw/:utf8/' '-MLingua::ZH::MMSEG' -Mutf8 -ne 'print join "\n", mmseg'  jian.txt

下一步就是要把結果丟給AI::Categorizer或AI::Classifier來看看結果如何…

20170208更新:
windows 平台上指令請改為
perl "-Mopen qw/:utf8/" -MLingua::ZH::MMSEG -Mutf8 -ne "print join \"\n\", mmseg"  XXX

ubuntu上以規則式(stanford-segmenter)及統計式方法進行斷詞

規則式(stanford-segmenter)

先到 http://nlp.stanford.edu/software/segmenter.shtml 抓個新版的 ,目前是stanford-segmenter-2013-04-04

解壓後進入 stanford-segmenter-2013-04-04 目錄,執行個範例程式

./segment.sh ctb test.simp.utf8 UTF-8 0

若是要對正體中文文檔斷字,需用類似iconv的程式作轉換,例如以utf-8格式儲存的繁體文檔fan.txt要斷字的話,執行以下指令:

 iconv -c -f utf-8 -t big5 fan.txt | iconv -c -f big5 -t gb2312 | iconv -f gb2312 -t utf8

試用結果感覺,對於科學詞彙較多的文檔,似乎斷得有點不好,而且有類似的句子斷出來的結果卻明顯不同的情況。

統計式


http://ckipsvr.iis.sinica.edu.tw/ 中有對中文的類統計方式斷詞步驟的說明,可分為:

  1. 初步斷詞
  2. 未知詞偵測
  3. 中國人名擷取
  4. 歐美譯名擷取
  5. 複合詞擷取
  6. bottom-up merging algorithm
  7. 重新斷詞
我覺得可以歸納這些步驟為一個迭代的迴圈,斷詞後把結果依詞庫分為已知和未知,已知的部分當然就不需要處理,但是需要微調,該小組是分為中外人名及複合詞;未知的部分則嘗試依前後順序結合為新詞(是否就是pat-tree呢? 參 http://newweb.management.ntu.edu.tw/chinese/im/theses/r93/R91725013.pdf‎ )

改寫的步驟為:

while (未知詞比重<閥值 && 迭代次數<閥值) {
    標示已知詞(可能有多個解)
    產生候選詞,加入詞庫,調整權重
}




2013年5月5日 星期日

emacs中undo後再redo

http://stackoverflow.com/questions/3527142/how-do-you-redo-changes-after-undo-with-emacs

在windows系統中,undo/redo通常是C-z/C-y,但在emacs中,裝了CUA只還給你undo,redo還是要記下這個按鍵組合:C-g C-u ,還滿拗口(手?)的,原文是 undo the undo

可以用elpa來裝undo-tree來試試另一種操作法,用undo-tree-visulize可以看到編輯的歷史

2013年5月4日 星期六

emacs遇到desktop file appears to be in use by PID XXX的解決方式

http://stackoverflow.com/questions/14005526/emacs-startup-warning

上面說的是治標的方式

回過頭來說,會遇這個問題表示你使用了類似 http://www.emacswiki.org/DeskTop 中所說的設定

在此同時,一般人不會去設定 desktop-path 變數。但是按一下 C-h v desktop-path 好好檢查吧…

如果它出現了不想要的路徑,或是經常發生當掉的情況,最好根據 http://www.emacswiki.org/DeskTop 中 Minimal Setup 所展示的設定 desktop-path 及相關變數

而有多個桌面或機器共同設定的情況,這個 desktop-path 當然是不能共用的,不然互相lock會很麻煩的

2013年5月3日 星期五

Ubuntu 13.04上主要prolog compiler

  1. swi-prolog - ISO/Edinburgh-style Prolog interpreter
  2. yap - High-performance Prolog System
  3. gprolog - GNU Prolog compiler
按照風行度似乎是這樣排的

perl中相當於sql的衍生欄位用法

http://www.perlhowto.com/sort_ordering_by_multiple_columns

有時查詢需要利用衍生欄位進行排序,使用map這個指令的確非常好用

不過這是很有名的黑魔法,請見 http://docstore.mik.ua/orelly/perl/cookbook/ch04_16.htm

還有個很有迫力的稱號,叫做"史瓦茲變換"…(害我想到柯西不等式TT)

2013年5月2日 星期四

Siri技術解析(II)

http://wesnerm.blogs.com/net_undocumented/2011/10/siri-technology.html

此文指出了幾篇參考文獻,感覺滿可信的。據他所言,後台所用的語法解析模型比較是基於統計而非精確文法。顯然由google translate之類的現存技術,的確是這樣沒錯。

http://search.cpan.org/~dougw/AI-Prolog-0.741/lib/AI/Prolog.pm

以perl來實作的prolog

http://search.cpan.org/~salva/Language-Prolog-Yaswi-0.21/Yaswi.pm

perl當作介面來呼叫swi prolog,真想看看能產生什麼樣的火花