|
|
|||||||||||||||||||||||||||||||||||||||||||||||||
アラビア語形態素解析デキターー!!!! Xが単語境界です。
setenv LANG ar_AE.utf8 で行けました。
嬉しい。
教師データなんてものは一切使っていません(Arabic gigawordの生テキストのみ)
ので注意。完全ベイズです。
語彙を見ると, それなりに高頻度なものが出ている感じです。
問題はこれを読めないことです。(T_T)
ICUはUnicodeを扱うフリーソフトで, 基本的にUTF-16を扱うもののようなので,
内部表現がUTF-16になるglibcでは, そのまま wchar_t や wstring の要素を渡すこと
ができるようです。
ICUには正規表現やcharacter iteratorなど様々な機能があるようですが,
C/C++で文字がひらがな/カタカナ/漢字かどうかを判別したいということは
自然言語処理でよくあるかも知れないのと, あまり検索しても方法を紹介している
ページはないようなので, 自分用のメモも兼ねて。
文字がひらがな/カタカナ/漢字(中国語もここ)のどれなのかは, それぞれUnicodeの ブロックが 異なるので, uchar.h に含まれる ublock_getCode() を使って, 基本的には以下の ようにすればよいようです。(実際の僕のコードではもう少し色々やっています)
#include "unicode/uchar.h"
#include "unicode/utypes.h"
#include "unicode/uscript.h"
wtype_t
wtype (wchar_t w)
{
UChar32 c = (UChar32) w;
UBlockCode bc = ublock_getCode(c);
UErrorCode err;
if (bc == UBLOCK_HIRAGANA)
return U_HIRAGANA;
else if (bc == UBLOCK_KATAKANA)
return U_KATAKANA;
else if (bc == UBLOCK_CJK_UNIFIED_IDEOGRAPHS)
return U_HANJI;
else if (bc == UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS)
{
UScriptCode uc = uscript_getScript(c, &err);
if (uc == USCRIPT_KATAKANA)
return U_KATAKANA;
else
{
if (u_getIntPropertyValue(c, UCHAR_WORD_BREAK)
== U_WB_KATAKANA) /* "-" in hankaku */
return U_KATAKANA;
}
}
}
注意すべきなのは最後の半角カナの場合で, これはブロック
Halfwidth_And_Fullwidth_Forms
(FF00-FFEF)に入っていますが,
ここにはハングルの半角カナ(というのがあるらしい)も同時に入っているので,
カタカナかどうかを判別するには, さらにScript属性を見て, USCRIPT_KATAKANA
であれば(半角)カタカナ, という判別をしています。
さらに, 実はよく見ると半角カナの"ー"はScript属性がカタカナでないようで(!)
このままではカタカナに分類されません。
このためには,
"ー"のProperty
をよく見ると, Word_Break 属性がKatakanaになっているので, さらにここを見て
判別してやります。(Word_Break属性を直接取る関数はないようなので,
u_getIntPropertyValue で UCHAR_WORD_BREAK を取り出します。)
これでめでたくwchar_tの文字が例えばひらがな/カタカナ/漢字かどうかを判別
できて, 上のコードでOKのようです。
これで
2008/9/17の日記
のように, 自分で文字コードを直書きする必要がなくなり
ました。
メモ: 各ブロックやプロパティにどんな文字が含まれているかは, http://unicode.org/cldr/utility/properties.jsp を見ると全部わかるようです。