こんにちは。たかぱい(@takapy0210)です。
本日は自然言語の可視化を手軽にできるようにしたパッケージnlplotをPyPIに公開したので、これのご紹介です。
nlplotとは?
自然言語の基本的な可視化を手軽にできるようにしたパッケージです。
現在は日本語と英語で動作確認済みです。
基本的な描画はplotlyを用いているため、notebook上からインタラクティブにグラフを操作することができます。
github.com (スター★お待ちしております🙇♂️)
nlplotで何ができるか
現時点(ver 1.6.0)では下記のグラフをプロットできます。(リンク先で動的なグラフを表示できます)
- N-gram bar chart
- N-gram tree Map
- Histogram of the word count
- wordcloud
- co-occurrence networks
- sunburst chart
自然言語入れたらよしなに可視化してくれるやつの大枠はできたので、PyPIへ登録やっていき pic.twitter.com/waPhLC0ugA
— takapy | たかぱい (@takapy0210) 2020年5月6日
以降で簡単に使い方をご紹介します。
使い方
詳しい使用方法のコード・今回使用したデータはGithubにあげてあります。
また、Tweet Sentiment Extractionコンペのカーネルも公開しておきました。
使用データ
今回は、Twitterからハッシュタグ「#kaggle」と「#データサイエンティスト」がついているツイートをスクレイピングし、そのタグを分析してみました。
データの形式は下記のようなデータフレームを想定しています。
textのカラムはスペース区切りの文字列 or リスト型のカラムを想定しています。
日本語の場合はお好きな形態素解析器で事前にtokenizeをお願いします。
(このパッケージにtokenizerも含めるか迷いましたが、あくまで可視化
のみを責務としているので、含めていません)
searched_for | hashtags | |
---|---|---|
0 | #データサイエンティスト | データマイニング データサイエンス データサイエンティスト |
1 | #データサイエンティスト | 統計学 人工知能 ダイヤモンド データサイエンティスト プログラミング |
2 | #データサイエンティスト | 筋トレ 今日の積み上げ 駆け出しエンジニアと繋がりたい データサイエンティスト |
... | ... | ... |
N | #kaggle | python kaggle タイタニック |
事前準備
インストールはpipで可能です。
pip install nlplot
事前にデータを読み込み、nlplotのインスタンスを生成しておきます。
import nlplot import pandas as pd import plotly from plotly.subplots import make_subplots from plotly.offline import iplot import matplotlib.pyplot as plt %matplotlib inline df = pd.read_csv('sample_twitter.csv') # 全データ・#データサイエンティスト・#kaggleをそれぞれインスタンス化 npt = nlplot.NLPlot(df, target_col='hashtags') npt_ds = nlplot.NLPlot(df.query('searched_for == "#データサイエンティスト"'), target_col='hashtags') npt_kaggle = nlplot.NLPlot(df.query('searched_for == "#kaggle"'), target_col='hashtags')
ストップワードの計算
下記のようにストップワードの計算ができます。
# top_nで頻出上位単語, min_freqで頻出下位単語を指定できる # 今回は上位2単語(データサイエンティスト・kaggle)をストップワードに指定 stopwords = npt.get_stopword(top_n=2, min_freq=0)
N-gram bar chart
よく見聞きするアレです。
ngram
の引数に与える数値により、いくつ隣り合わせの単語までを考慮するかを指定できます。
fig_unigram = npt.bar_ngram( title='uni-gram', xaxis_label='word_count', yaxis_label='word', ngram=1, top_n=50, width=800, height=1100, color=None, horizon=True, stopwords=stopwords, verbose=False, save=False, ) fig_unigram.show()
下記のようにすることで、データをラベルごとに比較することもできます。
# #データサイエンティストのfigを取得 fig_unigram_ds = npt_ds.bar_ngram( title='uni-gram', xaxis_label='word_count', yaxis_label='word', ngram=1, top_n=50, stopwords=stopwords, ) # #kaggleのfigを取得 fig_unigram_kaggle = npt_kaggle.bar_ngram( title='uni-gram', xaxis_label='word_count', yaxis_label='word', ngram=1, top_n=50, stopwords=stopwords, ) # subplot trace1 = fig_unigram_ds['data'][0] trace2 = fig_unigram_kaggle['data'][0] fig = make_subplots(rows=1, cols=2, subplot_titles=('#データサイエンティスト', '#kaggle'), shared_xaxes=False) fig.update_xaxes(title_text='word count', row=1, col=1) fig.update_xaxes(title_text='word count', row=1, col=2) fig.update_layout(height=1100, width=1900, title_text='unigram #データサイエンティスト vs. #kaggle') fig.add_trace(trace1, row=1, col=1) fig.add_trace(trace2, row=1, col=2) plotly.offline.plot(fig, filename='unigram #データサイエンティストvs#kaggle.html', auto_open=False) fig.show()
以降のグラフも上記のようにコーディングすることで、特定のラベルごとに比較することができます。
N-gram tree Map
こちらも同様、ngram
の引数に与える数値により、いくつ隣り合わせの単語までを考慮するかを指定できます。
fig_treemap = npt.treemap( title='Tree map', ngram=1, top_n=50, width=1300, height=600, stopwords=stopwords, verbose=False, save=False ) fig_treemap.show()
Histogram of the word count
単語の出現頻度のヒストグラムです。
# 単語数の分布 fig_histgram = npt.word_distribution( title='word distribution', xaxis_label='count', yaxis_label='', width=1000, height=500, color=None, template='plotly', bins=None, save=False, ) fig_histgram.show()
wordcloud
みんな大好きwordcloudです。日本語でもそのままプロットできます。
fig_wc = npt.wordcloud( width=1000, height=600, max_words=100, max_font_size=100, colormap='tab20_r', stopwords=stopwords, mask_file=None, save=False ) plt.figure(figsize=(15, 25)) plt.imshow(fig_wc, interpolation="bilinear") plt.axis("off") plt.show()
co-occurrence networks
共起ネットワークです。
このネットワークとサンバーストチャートを描画する場合は、事前にビルド処理が必要です。
このビルド処理のmin_edge_frequency
引数でプロットするノードの数を制限します。
(指定数以下のエッジ(辺)しか存在しないノードはプロット対象から除外することができます)
# ビルド(データ件数によっては処理に時間を要します) npt.build_graph(stopwords=stopwords, min_edge_frequency=25) # ビルド後にノードとエッジの数が表示される。ノードの数が100前後になるようにするとネットワークが綺麗に描画できる >> node_size:63, edge_size:63 fig_co_network = npt.co_network( title='Co-occurrence network', sizing=100, node_size='adjacency_frequency', color_palette='hls', width=1100, height=700, save=False ) iplot(fig_co_network)
ノードの色は、networkxのcommunitiesで計算したコミュニティを表しています。
networkx.github.io
ノードの大きさは、networkxのGraph.adjacencyで算出した値の大きさに比例しています。(隣接エッジが多ければ多いほど大きくなります) networkx.github.io
ちなみにビルド処理で生成されたデータフレーム にもアクセスできます。
display( npt.node_df.head(), npt.node_df.shape, npt.edge_df.head(), npt.edge_df.shape )
sunburst chart
上記共起ネットワークのコミュニティと、それに属する単語をサンバーストチャートで表示しています。
fig_sunburst = npt.sunburst( title='sunburst chart', colorscale=True, color_continuous_scale='Oryel', width=1000, height=800, save=False ) fig_sunburst.show()
色の濃さはnetworkxのbetweenness_centralityで算出した値が大きいほど濃い色で表示されています。(ネットワークの媒介中心性が高ければ高いほど濃い色になります)
幅は、前述したnetworkxのGraph.adjacencyで算出した値に比例しています。(隣接エッジが多ければ多いほど大きくなります)
まとめ
不便な部分はどんどん更新していこうと思っていますので、気になる部分や要望などあれば、PR/ISSUEお待ちしております!
業務でもKaggleなどのコンペでも短時間でデータの全体像を把握したい時に使っていただければと思います。