peiprog’s blog

情報科学を学ぶ大学4年生。主にプログラミング(機械学習寄り)の話題を書いていきます。

Pythonでワードクラウド作ってみた

今回はPythonでワードクラウドを作ってみました。ワードクラウドとは
追記:英語のみ対応です。ライブラリ(pytagcloud)が日本語に対応していないので...。日本語に対応させたいなら描画のところは自前で書く必要がありますね(^^;


全体の流れは

1.ドキュメント読み込み
2.ベクトル生成
3.ベクトルからワードクラウド描画
という感じです。こんな感じの画像を生成できます。
f:id:peiprog:20170614221243p:plain:w250



使うライブラリは以下の通りです。

sklearn 機械学習ライブラリ
pytagcloud ワードクラウド描画ライブラリ
numpy 数値計算ライブラリ
urllib インターネットからページを取得する用
 
 ライブラリのインストール方法についての説明は省略します。pip installなどで必要なライブラリは用意してください。
pipのインストールについて
sklearnのインストールについて
pytagcloudのインストールについて(英語サイト)
urllibのインストールについて


 ちなみにpytagcloudはこの参考書に載っていました。レコメンドや感情分析など機械学習の基本的な方法が多く記述されています→実践 機械学習システム


ドキュメント読み込み

これは単純にファイルパスを指定して読み込むだけです。

doc = open("file_path", "r").read()

ベクトル生成

ドキュメントを単語ごとに分けて、出現頻度のベクトルを生成します。

はじめにストップワードを取り除く必要があります(ストップワードとは、私、です、ます、などの出現頻度が高く不要な語)。
日本語のストップワードはインターネットなどから入手する必要があります。今回はSlothLibのページからストップワードを取得します。
SlothLibのページ

from urllib import request

page = request.urlopen('http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt')  # インターネットからページを取得
stopwords = [line.decode('utf-8').strip() for line in page]  # デコード
stopwords = [w for w in stopwords if not w==u'']  # 空文字を取り除く

 次に、取得したストップワードを用いてsklearnのCountVectorizerを使ってベクトル化します。先ほど生成したストップワードとmin_dfを指定します。min_dfを指定すると、指定した値より出現回数の低い単語を無視します。
 最終的には、ワードクラウドを生成するのに必要な、単語と出現頻度ベクトルの数値を合わせたタプルを生成します。
 最後に昇順ソートをしておきます。キー関数を使用しています。キー関数についてはこちらを参考にしてください。

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(min_df=1, stop_words=stopwords)  # ベクトル生成器を生成
vector = vectorizer.fit_transform(doc)  # docからベクトルを生成
words = vectorizer.get_feature_names()  # ベクトルに対応する単語のリストを取得

words_vector = []  # 単語と出現頻度ベクトルの数値のタプルが要素となるリスト
for i in range(len(words)):
    if not words[i].isdigit():  # 数字の文字列でなければリストに追加
        words_vector.append((words[i], vector[0, i]))  # 単語とベクトルの数値をタプルとしてリストに追加
words_vector.sort(key=lambda i:i[1], reverse=True)  # 昇順ソート、キーはベクトルの値


ワードクラウド描画

生成した単語と出現頻度ベクトルを合わせたタプルのリストを用いてワードクラウドを作成します。この例では上位30個の単語をピックアップします。
また、2行目の引数のminsize, maxsizeはワードクラウドの画像中の単語の大きさの最大値、最小値を表します。

from pytagcloud import create_tag_image, make_tags
tag = make_tags(words_vector[:30], minsize=20, maxsize=40)  # 上位30この単語を用いてワードクラウドを生成
create_tag_image(tag, savefile_path, size=(300, 300))  # 実際に描画したものを保存


まとめ

PDFやワードファイルに対応できると色んなドキュメントのワードクラウドが見れて面白いかもしれませんね。

最後にまとめたコードを示します。

from urllib import request
from sklearn.feature_extraction.text import CountVectorizer
from pytagcloud import create_tag_image, make_tags


doc = open("好きなファイルパスを指定", "r").read()

page = request.urlopen(
       'http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt')  # インターネットからページを取得
stopwords = [line.decode('utf-8').strip() for line in page]  # デコード
stopwords = [w for w in stopwords if not w == u'']  # 空文字を取り除く


vectorizer = CountVectorizer(min_df=1, stop_words=stopwords)  # ベクトル生成器を生成
vector = vectorizer.fit_transform([doc])  # docからベクトルを生成
words = vectorizer.get_feature_names() # ベクトルに対応する単語のリストを取得

words_vector = []  # 単語と出現頻度ベクトルの数値のタプルが要素となるリスト
for i in range(len(words)):
    if not words[i].isdigit():  # 数字の文字列でなければ
        words_vector.append((words[i], vector[0, i]))  # 単語とベクトルの数値をタプルとしてリストに追加
words_vector.sort(key=lambda i: i[1], reverse=True)  # 昇順ソート、キーはベクトルの値


tag = make_tags(words_vector[:30], minsize=20, maxsize=40)  # ワードクラウドを生成 上位30語を描画
create_tag_image(tag, "好きなファイルパスを指定", size=(300,300))  # 実際に描画したものを保存