Colaboratoryで自然言語処理の基本みたいなワードクラウドを生成することができるので使ってみた。
1.そのまま使う(英語のみ)
ワードクライドを作成するライブラリのWordCloudを使うだけならこう。
結果はこんな感じになる。
"the"や"over"が入っていないのは、組み込みのstopwordsに指定されており、画像生成時に削除されているから。
#Colabで使ってDriveに出力する場合
from wordcloud import WordCloud
txt = "The quick brown fox jumps over the lazy dog"
a = WordCloud()
a.generate(text=txt)
#to_fileメソッドで書き出し
a.to_file("/content/drive/MyDrive/tmp/new.png")
生成例1 |
stopwordsに"quick"を追加したこのコードでやるとこうなる。
#Colabで実行する場合
#ビルドインのSTOPWORDSをインポートする
from wordcloud import WordCloud, STOPWORDS
txt = "The quick brown fox jumps over the lazy dog"
#brownをstopwordsに加える
stop = set(STOPWORDS)
stop.add("brown")
a = WordCloud(stopwords=stop)
a.generate(text=txt)
a.to_file("/content/drive/MyDrive/tmp/newst.png")
生成例2 |
ワードクラウドでの文字の大きさはword-ranksと出現頻度で決定される。出現頻度への文字の大きさの影響を変更するときはインスタンス作成時にrelative_scalingへ値を与える。
遥かなティペラリー(It's a Long Way to Tipperary)のサビ部分を例にやるとこう。
relative_scaling=0.5 |
relative_scaling=1.0 |
relative_scaling以外で気になったパラメータを公式ドキュメントから抜粋する。
- height: int (default=200)
- 画像の縦幅の設定
- width: int (default=400)
- 画像の横幅の設定
- scale: float (default=1)
- 描写のスケールを設定
- min_word_length: int, default=0
- ワードクラウドに含まれるための最低の単語の長さ
- collocation_threshold: int, default=30
- コロケーション(単語と単語のつながり)の判定地
それ以外は公式ドキュメント参照。
2.日本語で使う
wordcloudに日本語辞書は入っていない上に、日本語からワードクラウドを作成するために必要な分かち書きや瀕死の分類などができない。
そこで日本語の形態素解析ツールであるJanomeを使う。
Janomeで簡単に形態素解析を行うには、Tokenizerを使う。日本国憲法前文について、解析を行うとこうなる。
from janome.tokenizer import Tokenizer
txt = """
日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。
日本国民は、恒久の平和を念願し、人間相互の関係を支配する崇高な理想を深く自覚するのであって、平和を愛する諸国民の公正と信義を信頼して、われらの安全と生存を保持しようと決意した。われらは平和を維持し、専制と隷従、圧迫と偏狭を地上から永遠に除去しようと努めている国際社会において、名誉ある地位を占めたいと思う。われらは全世界の国民が、ひとしく恐怖と欠乏から免れ、平和の内に生存する権利を有することを確認する。
われらは、いずれの国家も、自国のことのみに専念して他国を無視してはならないのであって、政治道徳の法則は、普遍的なものであり、この法則に従うことは、自国の主権を維持し、他国と対等関係に立とうとする各国の責務であると信ずる。
日本国民は、国家の名誉にかけて、全力をあげて崇高な理想と目的を達成することを誓う。
"""
txt = txt.replace('\n', '')
t = Tokenizer()
for token in t.tokenize(txt):
print(token)
###出力###
"""
日本 名詞,固有名詞,地域,国,*,*,日本,ニッポン,ニッポン
国民 名詞,一般,*,*,*,*,国民,コクミン,コクミン
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
正当 名詞,形容動詞語幹,*,*,*,*,正当,セイトウ,セイトー
に 助詞,副詞化,*,*,*,*,に,ニ,ニ
選挙 名詞,サ変接続,*,*,*,*,選挙,センキョ,センキョ
さ 動詞,自立,*,*,サ変・スル,未然レル接続,する,サ,サ
れ 動詞,接尾,*,*,一段,連用形,れる,レ,レ
た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
国会 名詞,一般,*,*,*,*,国会,コッカイ,コッカイ
における 助詞,格助詞,連語,*,*,*,における,ニオケル,ニオケル
代表 名詞,サ変接続,*,*,*,*,代表,ダイヒョウ,ダイヒョー
者 名詞,接尾,一般,*,*,*,者,シャ,シャ
を通じて 助詞,格助詞,連語,*,*,*,を通じて,ヲツウジテ,ヲツージテ
行動 名詞,サ変接続,*,*,*,*,行動,コウドウ,コードー
し 動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
、 記号,読点,*,*,*,*,、,、,、
われ 名詞,代名詞,一般,*,*,*,われ,ワレ,ワレ
ら 名詞,接尾,一般,*,*,*,ら,ラ,ラ
と 助詞,並立助詞,*,*,*,*,と,ト,ト
われ 名詞,代名詞,一般,*,*,*,われ,ワレ,ワレ
ら 名詞,接尾,一般,*,*,*,ら,ラ,ラ
"""
単語自体はtoken.surfaceで取り出せるが、これでは、様々な品詞が混じっているうえ、「日本国民」が「日本」と「国民」に分割されていたりしており、このままワードクラウドに用いることはできない。
そこで、Analizerとtokenfilterを用いる。
from janome.tokenizer import Tokenizer
from janome.analyzer import Analyzer
from janome.tokenfilter import *
txt = """
日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。
日本国民は、恒久の平和を念願し、人間相互の関係を支配する崇高な理想を深く自覚するのであって、平和を愛する諸国民の公正と信義を信頼して、われらの安全と生存を保持しようと決意した。われらは平和を維持し、専制と隷従、圧迫と偏狭を地上から永遠に除去しようと努めている国際社会において、名誉ある地位を占めたいと思う。われらは全世界の国民が、ひとしく恐怖と欠乏から免れ、平和の内に生存する権利を有することを確認する。
われらは、いずれの国家も、自国のことのみに専念して他国を無視してはならないのであって、政治道徳の法則は、普遍的なものであり、この法則に従うことは、自国の主権を維持し、他国と対等関係に立とうとする各国の責務であると信ずる。
日本国民は、国家の名誉にかけて、全力をあげて崇高な理想と目的を達成することを誓う。
"""
txt = txt.replace('\n', '')
t = Tokenizer()
filters = [CompoundNounFilter(), POSKeepFilter('名詞'), POSStopFilter(['非自立','代名詞'])]
NG = ['非自立', '代名詞']
analyzer = Analyzer(tokenizer=t, token_filters=filters)
for token in analyzer.analyze(txt):
#POSStopFilterがうまく機能しない部分があるので二重にフィルタリングする
ex = token.extra[0].split(',')
if all(x not in ex for x in NG):
print(token)
###出力###
'''
日本国民 名詞,複合,*,*,*,*,日本国民,ニッポンコクミン,ニッポンコクミン
正当 名詞,形容動詞語幹,*,*,*,*,正当,セイトウ,セイトー
選挙 名詞,サ変接続,*,*,*,*,選挙,センキョ,センキョ
国会 名詞,一般,*,*,*,*,国会,コッカイ,コッカイ
代表者 名詞,複合,*,*,*,*,代表者,ダイヒョウシャ,ダイヒョーシャ
行動 名詞,サ変接続,*,*,*,*,行動,コウドウ,コードー
子孫 名詞,一般,*,*,*,*,子孫,シソン,シソン
国民 名詞,一般,*,*,*,*,国民,コクミン,コクミン
協和 名詞,サ変接続,*,*,*,*,協和,キョウワ,キョーワ
成果 名詞,一般,*,*,*,*,成果,セイカ,セイカ
わが国全土 名詞,複合,*,*,*,*,わが国全土,ワガクニゼンド,ワガクニゼンド
自由 名詞,形容動詞語幹,*,*,*,*,自由,ジユウ,ジユー
恵沢 名詞,一般,*,*,*,*,恵沢,ケイタク,ケイタク
確保 名詞,サ変接続,*,*,*,*,確保,カクホ,カクホ
政府 名詞,一般,*,*,*,*,政府,セイフ,セイフ
行為 名詞,サ変接続,*,*,*,*,行為,コウイ,コーイ
戦争 名詞,サ変接続,*,*,*,*,戦争,センソウ,センソー
惨禍 名詞,一般,*,*,*,*,惨禍,サンカ,サンカ
決意 名詞,サ変接続,*,*,*,*,決意,ケツイ,ケツイ
'''
これでワードクラウドに入力する準備は整ったので、あとはjanomeの出力をスペース連結したものをWordCloudに放り込めば完了となる。
ただし、WordCloudには日本語フォントが含まれていないので、フォント指定をすることになる。今回はIPAフォントを利用する。
from pyparsing.helpers import Word
from wordcloud import WordCloud
from janome.tokenizer import Tokenizer
from janome.analyzer import Analyzer
from janome.tokenfilter import *
txt = """
日本国民は正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民と協和による成果と、わが国全土にわたって自由のもたらす恵沢を確保し、政府の行為によって再び戦争の惨禍が起こることのないようにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。そもそも国政は国民の厳粛な信託によるものであって、その権威は国民に由来し、その権力は国民の代表者がこれを行使し、その福利は国民がこれを享受する。これは人類普遍の原理であり、この憲法は、かかる原理に基づくものである。われらはこれに反する一切の憲法、法令及び詔勅を排除する。
日本国民は、恒久の平和を念願し、人間相互の関係を支配する崇高な理想を深く自覚するのであって、平和を愛する諸国民の公正と信義を信頼して、われらの安全と生存を保持しようと決意した。われらは平和を維持し、専制と隷従、圧迫と偏狭を地上から永遠に除去しようと努めている国際社会において、名誉ある地位を占めたいと思う。われらは全世界の国民が、ひとしく恐怖と欠乏から免れ、平和の内に生存する権利を有することを確認する。
われらは、いずれの国家も、自国のことのみに専念して他国を無視してはならないのであって、政治道徳の法則は、普遍的なものであり、この法則に従うことは、自国の主権を維持し、他国と対等関係に立とうとする各国の責務であると信ずる。
日本国民は、国家の名誉にかけて、全力をあげて崇高な理想と目的を達成することを誓う。
"""
cloud_text = '' #出力用
font_path = '/content/drive/MyDrive/tmp/ipaexm.ttf'
output_path = '/content/drive/MyDrive/tmp/constitution.png'
txt = txt.replace('\n', '')
t = Tokenizer()
filters = [CompoundNounFilter(), POSKeepFilter('名詞'), POSStopFilter(['非自立','代名詞'])]
NG = ['非自立', '代名詞']
analyzer = Analyzer(tokenizer=t, token_filters=filters)
for token in analyzer.analyze(txt):
#POSStopFilterがうまく機能しない部分があるので二重にフィルタリングする
ex = token.extra[0].split(',')
if all(x not in ex for x in NG):
#スペース区切りで単語を連結
cloud_text += ' '+ token.surface
wc = WordCloud(font_path = font_path, width=1980, height=1080)
wc.generate(text=cloud_text)
wc.to_file(output_path)
ひとまずこれで日本語のワードクラウドが作成できるようになったが、専門用語や流行語など、janomeのビルドイン辞書に記載されていない単語では上手くいかない。従って、辞書を生成していく必要があるが、それはまた書くことににする。