Power BI × Pythonで日本語ワードクラウド ～カスタムビジュアル編～


"Word Cloud"様へ非礼を詫びる回。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/9979680f-d042-2a30-1572-4710ee4448f8.png)


## はじめに
[前回の記事](https://qiita.com/hirondine36/items/4a3bbc3c20a0fff21532)で，カスタムビジュアル"Word Cloud"では日本語テキストデータが上手く扱えないとお伝えしました。
しかし，データ取込の段階で分かち書きすればええじゃないか！ということに気がつきましたので，贖罪の念を込め，早速試してみた次第です。


## 環境構築
前回と同様，Power BIでPythonを使用する準備がまだの方は，
　[Python × PowerBI データ分析事始め【データ準備編】 - Qiita](https://qiita.com/h_kobayashi1125/items/afc55abf7e98581bcab3)
をご参照の上，ご準備ください。

また，カスタムビジュアル"Word Cloud"を[Marketplace](https://appsource.microsoft.com/en-us/marketplace/apps?product=power-bi-visuals)から入手しておきます。
※Marketplaceから入手する際は，組織アカウントが必要になります。


## 処理の流れ
Pythonで記載するコードは，前回の前半部分と大体同じです。
但し，コードの記載先がPower Queryになる点，データ行ごとに処理を行う点が異なります。

1. 分かち書き用カラム用意
1. 形態素解析
1. スペース区切りで再結合
1. Word Cloud作成(カスタムビジュアル)


## 実装
#### 0. データ準備
前回と同じ[自身のツイート履歴](https://help.twitter.com/ja/managing-your-account/how-to-download-your-twitter-archive)(CSV)をデータとして使用します。
データは予めPower BI上に取り込んでおきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/0b5f3490-8185-9b0d-cda0-cebace1b0538.png)
[text]列がツイートの中身です。こちらを分かち書きした列を追加し，ワードクラウドで可視化します。

尚，データ取込は，Pandasのread系メソッドを利用してPythonで行ってしまっても構いません。
その場合，以下で登場する変数`dataset`は，ご自身で指定した名前に読み替えてください。


#### 1. 分かち書き用カラム用意
ここからはPower QueryのPythonスクリプトエディターに記載していきます。
エディターは [変換] > [スクリプト] > [Pythonスクリプトを実行する] で開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/ac8e959d-7273-44ef-0a7a-dfeddacbb048.png)
こちらに記載したスクリプトは，ステップの1つとして適用されます。
データはPandasのDataFrameとして，変数名`dataset`で既にセットされています。

まず`dataset`に，分かち書き用のカラムを追加します。

```Python
dataset['wakachi_text'] = ""
```

説明するほどのものでもないですね。


#### 2. 形態素解析
今回もjanomeを使って形態素解析を行います。~~だって楽チンなんだもん。~~
但し今回は**行ごとに**解析させます。

```Python
from janome.tokenizer import Tokenizer
tok = Tokenizer()

for i, row in dataset.iterrows():
    tokens = tok.tokenize(row.text)
```


#### 3. スペース区切りで再結合
前回と同様，ワードクラウド上へ表示するにあたり**有意義な品詞(名詞/動詞/形容詞/副詞)の原型のみ**を半角スペース区切りで結合し，1で用意した分かち書き用カラムに格納します。
結合・格納も行ごとに行うので，下記は2のループ内に書きます。

```Python    
    for token in tokens:
        if token.part_of_speech.split(',')[0] in ['名詞', '動詞', '形容詞', '副詞']:
            dataset.at[i, 'wakachi_text'] += (token.base_form + " ")
```
3行目左辺を`row.wakachi_text`にしないよう注意！
コピーにアクセスするので，値が更新されません。


ここまでエディターに記載したら，![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/d2d7468f-9b8a-94b1-f6f2-8917c6146fd9.png)を押し，スクリプトを実行します。


#### 4. Word Cloud作成
スクリプトの実行が終わると，こんな状態になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/a0de90f7-0239-883d-10c7-819f78a018cf.png)

慌てず騒がず，`Table`をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/76731361-45c3-6613-803d-e416ba90adce.png)
無事展開されました。
分かち書き用カラムが最右端に追加されています。

ここまでできたら，Power Queryを閉じて適用します。

Word Couldビジュアルを配置し，**[カテゴリ]**に分かち書き用カラムを渡すと・・・

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/60e86c91-db97-d9dd-a642-2aec120ff896.png)|
|:-:|
できた！

ちなみに，ストップワードは**書式**で設定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/2524aa33-6669-6980-6a5f-be2e7d7bfcce.png)
表示したくない単語を，半角スペース区切りで入力します。引用符は不要です。
このとき，スペースを入力する度に更新がかかってしまいますので，予めメモ帳等で準備しておき，コピペで入力することをお薦めします。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/222eaf51-0aac-2b8e-ae54-dea3acdf00da.png)|
|:-:|
いい感じです。

カスタムビジュアルの場合，既定のビジュアルと同様，ツールチップを表示させたりデータを選択したりすることができます。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/01d28bb2-7667-d1bf-a5b7-2124f06e534e.png)|
|:-:|

もちろん，スライサーを利用して絞り込みを行うことも可能です。


## おまけ
#### 表示までの速度比較
Pythonビジュアルで表示した場合とカスタムビジュアルで表示した場合とで，時間を要するタイミングが異なるので，正確に比較できたわけではないですが，あまり変わらないように感じました。


#### 表示変更
カスタムビジュアルでは，マスキングやフォントの指定はできません。(多分)

フォントカラーは [書式] > [データの色] で指定できます。
また， 単語の表示角度も [書式] > [テキストの回転] で変更可能です。


#### その他
カスタムビジュアルでは，データ量が多くなると一部データが表示されなくなる場合があります。
その場合，ビジュアル右上に下図のようなインフォメーションが表示されますので，「おかしいな？」と思ったら注意して見てみてください。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/205972/13225ac2-c6a0-9b27-7e00-410c7d772304.png)|
|:-:|


## まとめ
今回は先に分かち書き列を準備し，カスタムビジュアル"Word Cloud"を使って日本語ワードクラウドを表示してみました。

こちらでも無事表示されたところで，「ではどちらが良いのか？」となるわけですが，表示までの速度もさほど変わらないので，用途や目的に応じて使い分けるのが良いかと思います。

尚，前回と同様，あくまで「Power BI上で日本語ワードクラウドを作成すること」が目的でしたので，テキストマイニングという観点でイマイチな点はご容赦いただければ幸いです。
(PythonやPower BIの方でイマイチな点がある場合は，お気軽にコメントや編集リクエスト頂けますと幸いです。)


以下，スクリプトです。

```Python
from janome.tokenizer import Tokenizer

# 分かち書き用カラム
dataset['wakachi_text'] = ""

tok = Tokenizer()
for i, row in dataset.iterrows():
    # 行ごとに形態素解析
    tokens = tok.tokenize(row.text)

    # 解析結果のうち，名詞/動詞/形容詞/副詞の「原型」のみをスペース区切りで結合し，格納
    for token in tokens:
        if token.part_of_speech.split(',')[0] in ['名詞', '動詞', '形容詞', '副詞']:
            dataset.at[i, 'wakachi_text'] += (token.base_form + " ")
```


## 参考
- [PowerBI × Pythonで形態素解析をしてみよう - Qiita](https://qiita.com/ryoukom1216/items/657abcf0368f8b6da720)