読者です 読者をやめる 読者になる 読者になる

簡易的な日本語ストップワードの取得メソッド

それほど厳密に調査した訳ではないが、NLTKのコーパスには日本語のストップワードが存在しないようで、多くの人は SlothLib を利用している、という印象をWebから受けた。 SlothLibのように単語ベースでストップワードを定義している一方で、 IBM Content Analytics のように、シンプルに名詞か動詞以外の品詞の単語をストップワードとしているのもあった。 今回は、これら2種類の定義により、入力したテキストのストップワードを出力するメソッドを実装した。

品詞によるストップワードの取得

前回、単語と品詞のセットのリストが取得できるメソッド word_and_class() を作ったので、 そこから名詞と動詞以外の単語を取得する。

word_class = self.word_and_class(doc)
ok_class = [u"名詞", u"動詞"]
stopwords = []
for wc in word_class:
    if not wc[1] in ok_class:
        stopwords.append(wc[0])

サンプルテキストに「日本語の自然言語処理は本当にしんどい、と彼は十回言った。」を渡すと次のようになる。

>>> for sw in stopwords:
>>>    print sw,
の は 本当に しんどい 、 と は た 。

SlothLibによるストップワードの取得

SlothLibのテキストページ を取得してストップワードとする。

slothlib_path = 'http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt'
slothlib_file = urllib2.urlopen(slothlib_path)
slothlib_stopwords = [line.decode("utf-8").strip() for line in slothlib_file]
slothlib_stopwords = [ss for ss in slothlib_stopwords if not ss==u'']

実行結果は次の通り。

>>> for ss in slothlib_stopwords:
>>>    print ss,
あそこ あたり あちら あっち あと あな あなた あれ いくつ いつ いま いや いろいろ うち おおまか おまえ おれ がい かく かたち かやの から がら きた くせ ここ こっち こと ごと こちら ごっちゃ これ これら ごろ さまざま さらい さん しかた しよう すか ずつ すね すべて ぜんぶ そう そこ そちら そっち そで それ それぞれ それなり たくさん たち たび ため だめ ちゃ ちゃん てん とおり とき どこ どこか ところ どちら どっか どっち どれ なか なかば なに など なん はじめ はず はるか ひと ひとつ ふく ぶり べつ へん ぺん ほう ほか まさ まし まとも まま みたい みつ みなさん みんな もと もの もん やつ よう よそ わけ わたし ハイ 上 中 下 字 年 月 日 時 分 秒 週 火 水 木 金 土 国 都 道 府 県 市 区 町 村 各 第 方 何 的 度 文 者 性 体 人 他 今 部 課 係 外 類 達 気 室 口 誰 用 界 会 首 男 女 別 話 私 屋 店 家 場 等 見 際 観 段 略 例 系 論 形 間 地 員 線 点 書 品 力 法 感 作 元 手 数 彼 彼女 子 内 楽 喜 怒 哀 輪 頃 化 境 俺 奴 高 校 婦 伸 紀 誌 レ 行 列 事 士 台 集 様 所 歴 器 名 情 連 毎 式 簿 回 匹 個 席 束 歳 目 通 面 円 玉 枚 前 後 左 右 次 先 春 夏 秋 冬 一 二 三 四 五 六 七 八 九 十 百 千 万 億 兆 下記 上記 時間 今回 前回 場合 一つ 年生 自分 ヶ所 ヵ所 カ所 箇所 ヶ月 ヵ月 カ月 箇月 名前 本当 確か 時点 全部 関係 近く 方法 我々 違い 多く 扱い 新た その後 半ば 結局 様々 以前 以後 以降 未満 以上 以下 幾つ 毎日 自体 向こう 何人 手段 同じ 感じ

ストップワードの統合

上記の2種類のストップワードを取得する手法を統合して、1つのメソッドにすると次のようになる。

def stopwords(self, doc):
    """
    Get stopwords from input document.
    """
    # Judged by class
    word_class = self.word_and_class(doc)        
    ok_class = [u"名詞", u"動詞"]
    stopwords = []
    for wc in word_class:
        if not wc[1] in ok_class:
            stopwords.append(wc[0])

    # Defined by SlpothLib
    slothlib_path = 'http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt'
    slothlib_file = urllib2.urlopen(slothlib_path)
    slothlib_stopwords = [line.decode("utf-8").strip() for line in slothlib_file]
    slothlib_stopwords = [ss for ss in slothlib_stopwords if not ss==u'']

    # Merge and drop duplication
    stopwords += slothlib_stopwords
    stopwords = list(set(stopwords))

    return stopwords

テスト

サンプルテキストの分かち書きとそこからストップワードを除去したものを表示。

text = '日本語の自然言語処理は本当にしんどい、と彼は十回言った。'
sw = nltkjp.stopwords(text)

words = nltkjp.word_tokenize(text)
print '分かち書き:'
for w in words:
    print w,
print
print

print '分かち書き(ストップワードを除去):'
for w in words:
    if not w in sw:
       print w,
print

単語の分割方法や動詞の基本形の必要性など、まだ課題はあるが、 ストップワードを取得するという目的は達成できた。

分かち書き:
日本語 の 自然 言語 処理 は 本当に しんどい 、 と 彼 は 十 回 言っ た 。

分かち書き(ストップワードを除去):
日本語 自然 言語 処理 言っ