scikit-learnを使ってテキスト文書をクラスタリングしてみた

Clustering text documents using k-means (K平均法を使ってテキスト文書をクラスタリングする)というそのまんまのサンプルがあったので写経して最低限だけ削りだしてみた。

K平均法とかTF-IDFとか潜在意味解析の説明は割愛。

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.decomposition import TruncatedSVD
from sklearn.preprocessing import Normalizer


def main():

    _items = [
        'わたし まけ まし た わ',
        'わたし まけ まし た わ',
        'わたし まけ まし た わ',
        'わたし まけ まし た わ',
        'となり の きゃく は よく かき くう きゃく だ',
        'にわ には にわ なかにわ には にわ にわとり が いる',
        'バカ と テスト と 召喚獣',
        '俺 の 妹 が こんな に 可愛い わけ が ない'
    ]

    vectorizer = TfidfVectorizer(
        use_idf=True
    )
    X = vectorizer.fit_transform(_items)

    lsa = TruncatedSVD(10)
    X = lsa.fit_transform(X)
    X = Normalizer(copy=False).fit_transform(X)

    km = KMeans(
        init='k-means++',
    )
    km.fit(X)

    print(km.labels_)


if __name__ == '__main__':
    main()

テキストは分かち書きされてる状態(空白区切りになってます)でドキュメント単位でリストにいれておく。これを元データとしてTfidfVectorizerに突っ込みます。ここでドキュメントがベクトル化されます。

で、潜在意味解析を通した上でK平均法でクラスタリング。至って単純。
km.labels_を出力すると

[1 1 1 1 0 2 4 3]

こんな感じで出力されるのですが、これは「データセットのインデックス0,1,2,3は1番クラスタ、インデックス4は0番クラスタ、、、」ということです。これを使って元データをグルーピングしておきます。

すっごい簡単。使い方はこれであってる、と思う。たぶん。あ、ドキュメント数は少なくても1,000以上ないときれいにクラスタリングされなそうだし、テキストももっと長くないと納得のいく結果は出力されにくいんじゃないかと。

自分のツイートを使ったり青空文庫を使ったりで気軽に試せそうです。

Python 3.4.2、scikit-learn==0.15.2 で動かしました。

昨日Mahoutの記事書いたばっかりなのにね。