ワードクラウドで特許データを分析してみた

# 自己紹介
まったくのプログラミング初心者です。理系の大学は出ておりますが、プログラミング経験はありません。今までプログラミングから逃げておりましたが、昨今のデータサイエンスが盛り上がる状況を鑑み、重い腰を上げて勉強を始めました・・・。
# やりたいこと
テキストマイニングを使って、各社のドローン技術の特徴を見える化したい。できればワードクラウドを使って見える化したい、ということで、いろいろ調べながらプログラミングしてみます。一部不可解なコードがあるかもしれませんが、初心者ですので、ご容赦願います。
# 特許データ収集
j-platpatを使って、発明の名称に「ドローン」を含む、という検索式で検索しました。ヒット件数は960件となりました。なお、この検索式では、検索漏れが大量に発生しますが、今回はドローン技術の概要がわかればよいので、適当な検索式としております。
# 使用ツール
プログラミングツールには、Google Colaboratoryを使用しました。Google Colaboratoryは難しい環境構築が不要で、この点で初心者向きのツールといえますので、これで進めました。
# ライブラリ
インストールしたライブラリは以下となります。今回はテキストマイニングを行い、ワードクラウドを出力しますので、使用するライブラリが多くなっています。matplotlibの文字化け対処としてjapanize-matplotlibもインストールしております。
```python
! pip install -U ginza ja_ginza
! pip install wordcloud japanize-matplotlib
! pip install japanize-matplotlib
! wget -c https://moji.or.jp/wp-content/ipafont/IPAexfont/IPAexfont00401.zip
! mkdir -p fonts
! unzip -d fonts -o IPAexfont00401.zip
! rm -f IPAexfont00401.zip
from collections import Counter
import spacy
import pandas as pd
import matplotlib.pyplot as plt
import wordcloud
import japanize_matplotlib
import numpy as np
from google.colab import drive
drive.mount('/content/drive')
```
# 解析器
使用する品詞とストップワードを設定し、解析器を初期化します。使用する品詞は、名詞、代名詞、動詞、形容詞です。また、ストップワードは、後のワードクラウドの出力を見て、不要語をどんどん追加しました。形態素解析にはspaCyを使用しております。MeCabが一般的と思いますが、環境構築が容易なspaCyを使用しました。いずれMeCabも使ってみたいと思います。
```python
include_pos = ('NOUN', 'PROPN', 'VERB', 'ADJ')
stopwords = ('する', 'ある', 'ない', 'いう', 'もの', 'こと', 'よう', 'なる', 'ほう', 'いる', 'くる',  'できる', '部', 'ドローン', '前記', '複数', '備える', 'よる', '所定')
nlp = spacy.load("ja_ginza")
```
# 前処理
googleドライブからCSVデータ2件を読み込みます。なお、2件となったのはj-platpatでは1回のダウンロードで取得できる特許件数が500件の制限があるためです。面倒ですが、今回は494件と466件の2つのCSVファイルに分割してダウンロードします。2件のCSVデータを結合して1つのデータフレームにし、分析に必要な列（出願番号、出願日、出願人/権利者、要約）のみ抽出します。
```python
df_drone_data_1 = pd.read_csv("/content/drive/MyDrive/pat_data_drone.20181231.csv", encoding = "shift-jis")
df_drone_data_2 = pd.read_csv("/content/drive/MyDrive/pat_data_drone.20190101.csv", encoding = "shift-jis")
df_drone_data = pd.concat([df_drone_data_1, df_drone_data_2], ignore_index = True)
df_drone_data = df_drone_data[['出願番号', '出願日', '出願人/権利者', '要約']]
```
前処理の結果、データフレームは以下となりました。全部出力しますと長くなりますので、960件中、例として5件のみ出力しております。

|idx|出願番号|出願日|出願人/権利者|要約|
|:-:|:--|:--|:--|:--|
|0|特願2018-115480|2018/6/18|ソニー株式会社|\(57\)【要約】【課題】撮影を行う複数の移動体どうしが互いの撮影を\<BR\>妨害することを抑制する。【解決手段】移動体は、他の移動体により撮影される撮\<BR\>影範囲に関する情報を含む撮影情報を受信する。そして\<BR\>、移動体は、他の移動体の撮影情報に応じて、カメラに\<BR\>よる撮影のための撮影行動を制御する。本技術は、例え\<BR\>ば、複数のドローンにより空撮を行う撮影システム等に\<BR\>適用することができる。【選択図】図２|
|1|特願2017-057245|2017/3/23|日本電気株式会社|\(57\)【要約】      （修正有）【課題】ユーザが望む条件に適合した無人航空機を効果\<BR\>的にユーザに提供することができる情報処理装置、情報\<BR\>処理方法および情報処理プログラムを提供する。【解決手段】情報処理装置は、ドローンを使用する日時\<BR\>、場所および目的に関するジョブ情報を取得するジョブ\<BR\>情報取得手段と、ドローン管理データベースを参照して\<BR\>、ジョブ情報取得手段で取得した前記ジョブ情報に適合\<BR\>するドローンの特定を行なうドローン特定手段と、ドロ\<BR\>ーン特定手段が特定した前記ドローンに対して、前記ジ\<BR\>ョブ情報に対応するデータを送信する送信手段と、を備\<BR\>える。【選択図】図１|
|2|特願2018-237992|2018/12/20|ソフトバンク株式会社|\(57\)【要約】      （修正有）【課題】飛行装置の飛行制御部に通信モジュールを追加\<BR\>する構成変更を行うことなく、セルラー移動通信方式を\<BR\>含む複数種類の無線通信方式を切り替えて操縦装置から\<BR\>遠隔制御データを受信することができる通信装置を提供\<BR\>する。【解決手段】無線通信を介して飛行装置の飛行制御情報\<BR\>を受信する通信装置（ドローンコントローラ）１２は、\<BR\>飛行装置の飛行制御部を有する飛行装置本体とは別体の\<BR\>装置として設けられている。通信装置１２は、セルラー\<BR\>移動通信方式を含む複数種類の無線通信方式それぞれを\<BR\>介して飛行装置の操縦装置から送信された遠隔制御デー\<BR\>タの送信信号を受信する複数の遠隔制御データ受信部１\<BR\>２１と、複数の遠隔制御データ受信部１２１のいずれか\<BR\>によって受信された遠隔制御データを所定形式の遠隔制\<BR\>御信号に変換する遠隔制御データ処理部１２２と、遠隔\<BR\>制御信号を飛行装置本体に送信する送信部１２８とを備\<BR\>える。【選択図】図３|
|3|特願2018-237722|2018/12/19|一般財団法人電力中央研究所|\(57\)【要約】【課題】送電線から給電を行い、バッテリを大型化する\<BR\>ことなく、飛行のための電力を確保する。【解決手段】バッテリ６の電力により駆動力を得て無人\<BR\>で飛行するドローン５と、ドローン５に取り付けられ、\<BR\>送電線２に装着される環状の本体部４と、本体部４に設\<BR\>けられ、活線状態の送電線２からの電力によりバッテリ\<BR\>の充電を行う給電手段７とを備えた。【選択図】  図２|
|4|特願2019-572242|2018/12/21|楽天株式会社|\(57\)【要約】  本発明は、飛行体への保護部材の装着が確実な飛行装\<BR\>置を提供する。  本発明の一実施形態の飛行装置１は、本体部１１及び\<BR\>前記本体部に保持される１以上のプロペラを有する飛行\<BR\>体（ドローン）２と、前記飛行体に装着され、前記本体\<BR\>部の外側を囲うように張り渡される保護部材３を支持す\<BR\>る複数の支持具４と、前記保護部材の支持状態を示す支\<BR\>持情報を検出する支持情報検出部４１，４２と、前記支\<BR\>持情報検出部の検出値に基づいて前記保護部材の支持状\<BR\>態の適否を判定する装着判定部４３を有する。|
# 不要語の削除
データフレームの要約の列を見てわかるように、意味不明な用語や分析に不要な用語が多数見受けられます。これら不要な用語を要約から予め削除しました。
```python
df_drone_data['要約'] = df_drone_data['要約'].str.replace('(57)', '')
df_drone_data['要約'] = df_drone_data['要約'].str.replace('\r\n', '')
df_drone_data['要約'] = df_drone_data['要約'].str.replace('（修正有）', '')
df_drone_data['要約'] = df_drone_data['要約'].str.replace('<BR>', '')
df_drone_data['要約'] = df_drone_data['要約'].str.replace('\n+', '\n', regex=True)
df_drone_data['要約'] = df_drone_data['要約'].str.strip('()')
df_drone_data['要約'] = df_drone_data['要約'].str.replace(' ', '')
df_drone_data['要約'] = df_drone_data['要約'].str.replace('【要約】', '')
df_drone_data['要約'] = df_drone_data['要約'].str.replace('【課題】', '')
df_drone_data['要約'] = df_drone_data['要約'].str.replace('【解決手段】', '')
df_drone_data['要約'] = df_drone_data['要約'].str.replace('【選択図】', '')
```
# 出願日の処理
後で出願年の分析をするために、出願日の列を日付型に置き換えておきます。
```python
df_drone_data['出願日'] = pd.to_datetime(df_drone_data['出願日'])
```
# 出願件数 : top10の図示
分析対象の企業を絞り込むため、出願件数のtop10企業を図示します。企業ごとの出願件数のカウントにはCounterを使用しました。図表化にはmatplotlibを使用しました。
```python
df_drone_data['app'] = df_drone_data['出願人/権利者'].str.split(',')
app = sum(df_drone_data['app'], [])
counter = Counter(app)
df = pd.DataFrame(counter.most_common(10))
df = df.sort_values(by=1, ascending=True)
x = df[0]
y = df[1]
fig = plt.figure(figsize=(10.0,6.0))
fig = plt.rcParams["font.size"]=13
plt.title("出願人top10")
plt.barh(x,y)
```
下が出力された図です。top3は、ナイルワークス、ＮＴＴドコモ、トヨタ自動車であることがわかります。これら３社について、テキストマイニングによる分析をすることにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/5cbc2631-5bcc-c3e2-4069-8ee2a3d16587.png)
# top3社のデータフレームの作成
各社の技術の特徴を分析をするために、上記データフレームから、「出願人：ナイルワークス」を含むデータフレーム、「出願人：ＮＴＴドコモ」を含むデータフレーム、「出願人：トヨタ自動車」を含むデータフレームの３つのデータフレームを作成しました。
```python
df_nile = df_drone_data.copy()
df_nile['出願人/権利者'] = df_nile['出願人/権利者'].str.contains('株式会社ナイルワークス')
df_nile = df_nile[~(df_nile['出願人/権利者'] == False)]

df_ntt = df_drone_data.copy()
df_ntt['出願人/権利者'] = df_ntt['出願人/権利者'].str.contains('株式会社ＮＴＴドコモ')
df_ntt = df_ntt[~(df_ntt['出願人/権利者'] == False)]

df_toy = df_drone_data.copy()
df_toy['出願人/権利者'] = df_toy['出願人/権利者'].str.contains('トヨタ自動車株式会社')
df_toy = df_toy[~(df_toy['出願人/権利者'] == False)]
```
# top3社の出願件数推移の確認
次にtop3社の出願件数推移を確認します。図表化にはmatplotlibを使用しました。
```python
df_y_nile = df_nile['出願日'].dt.year.value_counts().sort_index().reset_index()
df_y_nile.columns = ["出願年", "件数"]
x_nile = df_y_nile["出願年"]
y_nile = df_y_nile["件数"]

df_y_ntt = df_ntt['出願日'].dt.year.value_counts().sort_index().reset_index()
df_y_ntt.columns = ["出願年", "件数"]
x_ntt = df_y_ntt["出願年"]
y_ntt = df_y_ntt["件数"]

df_y_toy = df_toy['出願日'].dt.year.value_counts().sort_index().reset_index()
df_y_toy.columns = ["出願年", "件数"]
x_toy = df_y_toy["出願年"]
y_toy = df_y_toy["件数"]

fig = plt.figure(figsize=(10.0,6.0))
fig = plt.rcParams["font.size"]=13
plt.title("出願件数推移（2013～2022）")
plt.xticks(np.arange(2013, 2023, 1))
plt.xlim(2013, 2022)
plt.ylim(0,60)
plt.plot(x_toy,y_toy, label='トヨタ')
plt.plot(x_ntt,y_ntt, label='NTTドコモ')
plt.plot(x_nile,y_nile, label='ナイルワークス')
plt.xlabel('出願年')
plt.ylabel('出願件数')
plt.legend()
```
下が出力された図です。ナイルワークスは2019年に多くの出願をしていることがわかります。NTTドコモとトヨタ自動車は2015年から年10件弱の出願をしていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/96038692-36b1-b886-2edf-2545882e3302.png)
# ワードクラウドの作成
次に、ナイルワークス、NTTドコモ、トヨタ自動車の要約の記載からワードクラウドを作成します。形態素解析にはspaCyを使用し、ワードクラウドの作成には、WordCloudを使用します。
## ナイルワークス
コードは以下となります。
```python
words_nile = []
for doc_nile in nlp.pipe(df_nile['要約']):
  words_nile.extend([token.lemma_ for token in doc_nile
    if token.pos_ in include_pos and token.lemma_ not in stopwords])
wc_nile = wordcloud.WordCloud(background_color='white', font_path='fonts/IPAexfont00401/ipaexg.ttf', max_font_size=100).generate(' '.join(words_nile))
plt.figure(figsize=(8, 4))
plt.imshow(wc_nile, interpolation='bilinear')
plt.axis("off")
plt.tight_layout(pad=0)
plt.title("ナイルワークス" )
```
以下が、ナイルワークスのワードクラウドとなります。ワードクラウドを見ますと、ナイルワークスの特許技術は移動体の飛行制御関係であることがわかるような気もします。また圃場という用語も見られますので、ドローンを活用した農業関係の技術が多いのかな、とも思われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/eea7aac2-7f33-c0a8-ba52-2d729cdc54cc.png)
## NTTドコモ
コードは以下となります。
```python
words_ntt = []
for doc_ntt in nlp.pipe(df_ntt['要約']):
  words_ntt.extend([token.lemma_ for token in doc_ntt
    if token.pos_ in include_pos and token.lemma_ not in stopwords])
wc_ntt = wordcloud.WordCloud(background_color='white', font_path='fonts/IPAexfont00401/ipaexg.ttf', max_font_size=100).generate(' '.join(words_ntt))
plt.figure(figsize=(8, 4))
plt.imshow(wc_ntt, interpolation='bilinear')
plt.axis("off")
plt.tight_layout(pad=0)
plt.title("NTTドコモ" )
```
以下が、NTTドコモのワードクラウドとなります。ワードクラウドを見ますと、NTTドコモの特許技術はドローンの飛行による情報取得関係であることがわかるような気もします。また、飛行計画、飛行空域という用語も見られますので、計画に基づく情報取得関係の技術が多いのかな、とも思われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/f03edbcf-158c-b1d5-e646-a312e5a7ea63.png)
## トヨタ自動車
コードは以下となります。
```python
words_toy = []
for doc_toy in nlp.pipe(df_toy['要約']):
  words_toy.extend([token.lemma_ for token in doc_toy
    if token.pos_ in include_pos and token.lemma_ not in stopwords])
wc_toy = wordcloud.WordCloud(background_color='white', font_path='fonts/IPAexfont00401/ipaexg.ttf', max_font_size=100).generate(' '.join(words_toy))
plt.figure(figsize=(8, 4))
plt.imshow(wc_toy, interpolation='bilinear')
plt.axis("off")
plt.tight_layout(pad=0)
plt.title("トヨタ自動車" )
```
以下が、トヨタ自動車のワードクラウドとなります。ワードクラウドを見ますと、トヨタ自動車の特許技術はドローンを使った荷物の配送関係であることがわかるような気もします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/ad30d458-4103-258e-7c04-82170abac63d.png)
# まとめ
ワードクラウドからは、各社特許技術の概要がわかるような気もします。しかし、あくまでも概要がわかるだけであり、厳密には特許明細書を読みませんとわからないともいえます。そういう意味では、ワードクラウドは、まず簡単に各社の技術を比べる用途には使えると思います。
# 感想と今後の目標
今回のプログラムは、まず、やりたい処理を考え、その処理について本やネットで調べて、使えるコードを参考にする、という順序で作りました。そんな進め方でも、とりあえず動くプログラムが作れましたので、今後もこんな感じで特許分析に使えるプログラムを作ってゆきたいと思います。 

また、この分析（特許データ収集、ツールやライブラリの使用）にかかった費用は0円ということで、プログラミングの知識があれば、誰でも気軽にデータ分析ができる良い時代になったと感じました。また、このようなことからPythonの勉強を始めてよかったとも感じました。