Fタームで課題-解決手段マップを作成してみる

# はじめに
前回は仮データでマップを作成しましたが、今回は実際の特許データを使用して、課題-解決手段マトリクスを作成したいと思います。

なお、Fタームに関する特許データは、Jplatpatからはダウンロードできませんので、今回は特許データの入手に有料の特許データベースを使用しています。

今回は、吸収性物品（おむつなど）に関する特許データ（2553件）を使用します。該当するFタームは、3B200となります。

前回まで使用していたドローンの特許データは新しい技術のため、適切なFタームがありませんでした。このように、Fタームで課題-解決手段マップを作成してみる試みは、適切なFタームがない場合には使えない手法となります。

# データフレームの確認
まず、特許データ2553件のFターム列のみデータフレーム化します。
```Python
! pip install japanize-matplotlib
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
import japanize_matplotlib
# googleドライブの利用
from google.colab import drive
drive.mount('/content/drive')
# データの前処理
# データの読み込み(google ドライブから)
df_fterm = pd.read_csv("/content/drive/MyDrive/吸収性物品_2553.csv", encoding = "shift-jis")
#必要な列のみ抽出
df_fterm = df_fterm[['Ｆターム(最新)']]
# 欠落データを削除
df_fterm = df_fterm.dropna()
# データフレームの確認
print(df_fterm)
```
データフレームを確認すると以下のようになります。1つの列に3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...と多数のFタームが存在するのがわかります。
```
                                               Ｆターム(最新)
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...
1     3B200 AA03;3B200 BA04;3B200 BA16;3B200 BB03;3B...
2     3B200 AA01;3B200 AA03;3B200 BA01;3B200 BA02;3B...
3     3B200 AA03;3B200 BA08;3B200 BB03;3B200 BB11;3B...
4     3B200 BA11;3B200 BA12;3B200 BB02;3B200 BB03;3B...
...                                                 ...
2548  3B200 BA06;3B200 BA05;3B200 BA02;3B200 BA01;3B...
2549  3B200 EA05;3B200 DB02;3B200 BB22;3B200 BB17;4J...
2550  3B200 BB20;3B200 BB17;3B200 BB03;3B200 BA01;3B...
2551  3B200 AA01;3B200 AA03;3B200 BA01;3B200 BA02;3B...
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...

[2553 rows x 1 columns]
```
# 課題列と解決手段列の追加
次に Fターム列をコピーして課題列と解決手段列を追加します。
```Python
# Fターム列をコピーして追加
df_fterm['課題'] = df_fterm['Ｆターム(最新)']
df_fterm['解決手段']= df_fterm['Ｆターム(最新)']
# データフレーム確認
print(df_fterm)
```
確認するほどのものでもないですが、一応課題列と解決手段列を確認します。同じ内容の列が追加されていることがわかります。
```
                                               Ｆターム(最新)  \
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...   
1     3B200 AA03;3B200 BA04;3B200 BA16;3B200 BB03;3B...   
2     3B200 AA01;3B200 AA03;3B200 BA01;3B200 BA02;3B...   
3     3B200 AA03;3B200 BA08;3B200 BB03;3B200 BB11;3B...   
4     3B200 BA11;3B200 BA12;3B200 BB02;3B200 BB03;3B...   
...                                                 ...   
2548  3B200 BA06;3B200 BA05;3B200 BA02;3B200 BA01;3B...   
2549  3B200 EA05;3B200 DB02;3B200 BB22;3B200 BB17;4J...   
2550  3B200 BB20;3B200 BB17;3B200 BB03;3B200 BA01;3B...   
2551  3B200 AA01;3B200 AA03;3B200 BA01;3B200 BA02;3B...   
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...   

                                                     課題  \
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...   
1     3B200 AA03;3B200 BA04;3B200 BA16;3B200 BB03;3B...   
2     3B200 AA01;3B200 AA03;3B200 BA01;3B200 BA02;3B...   
3     3B200 AA03;3B200 BA08;3B200 BB03;3B200 BB11;3B...   
4     3B200 BA11;3B200 BA12;3B200 BB02;3B200 BB03;3B...   
...                                                 ...   
2548  3B200 BA06;3B200 BA05;3B200 BA02;3B200 BA01;3B...   
2549  3B200 EA05;3B200 DB02;3B200 BB22;3B200 BB17;4J...   
2550  3B200 BB20;3B200 BB17;3B200 BB03;3B200 BA01;3B...   
2551  3B200 AA01;3B200 AA03;3B200 BA01;3B200 BA02;3B...   
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...   

                                                   解決手段  
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...  
1     3B200 AA03;3B200 BA04;3B200 BA16;3B200 BB03;3B...  
2     3B200 AA01;3B200 AA03;3B200 BA01;3B200 BA02;3B...  
3     3B200 AA03;3B200 BA08;3B200 BB03;3B200 BB11;3B...  
4     3B200 BA11;3B200 BA12;3B200 BB02;3B200 BB03;3B...  
...                                                 ...  
2548  3B200 BA06;3B200 BA05;3B200 BA02;3B200 BA01;3B...  
2549  3B200 EA05;3B200 DB02;3B200 BB22;3B200 BB17;4J...  
2550  3B200 BB20;3B200 BB17;3B200 BB03;3B200 BA01;3B...  
2551  3B200 AA01;3B200 AA03;3B200 BA01;3B200 BA02;3B...  
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...  

[2553 rows x 3 columns]
```
# エクスプロード処理
次に、課題列と解決手段列をエクスプロードします。
```Python
# ;で課題を分割
df_fterm['課題'] = df_fterm['課題'].str.split(';')
# ;で解決手段を分割
df_fterm['解決手段'] = df_fterm['解決手段'].str.split(';')
# 課題と解決手段をエクスプロード
df_fterm = df_fterm.explode('課題').explode('解決手段')
# データフレーム確認
print(df_fterm)
```
2553行がなんと754269行になってしまいました。google colaboratoryを使用しておりますので、計算時間は一瞬ですが、これでよいのかと不安になる行数です。

```
                                               Ｆターム(最新)          課題  \
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...  3B200 AA03   
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...  3B200 AA03   
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...  3B200 AA03   
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...  3B200 AA03   
0     3B200 AA03;3B200 BA01;3B200 BA03;3B200 BA16;3B...  3B200 AA03   
...                                                 ...         ...   
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...  4J100 DA37   
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...  4J100 DA37   
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...  4J100 DA37   
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...  4J100 DA37   
2552  3B200 AA03;3B200 AA01;3B200 DB02;3B200 DB01;3B...  4J100 DA37   

            解決手段  
0     3B200 AA03  
0     3B200 BA01  
0     3B200 BA03  
0     3B200 BA16  
0     3B200 BB02  
...          ...  
2552  4J100 HA11  
2552  4J100 HA08  
2552  4J100 FA03  
2552  4J100 EA03  
2552  4J100 DA37  

[754269 rows x 3 columns]
```
# グループ化と限定
次にグループ化し、課題列を課題Fタームに限定し、解決手段列を解決手段Fタームに検定します。

課題Fタームは、"3B200 BA01","3B200 BA02","3B200 BA03","3B200 BA04","3B200 BA05","3B200 BA06","3B200 BA07","3B200 BA08","3B200 BA09","3B200 BA10","3B200 BA11","3B200 BA12","3B200 BA13","3B200 BA14","3B200 BA15","3B200 BA16","3B200 BA17","3B200 BA18","3B200 BA19","3B200 BA20"となります（物性）。

解決手段Fタームは、"3B200 BB01","3B200 BB02","3B200 BB03","3B200 BB04","3B200 BB05","3B200 BB06","3B200 BB08","3B200 BB09","3B200 BB10","3B200 BB11","3B200 BB13","3B200 BB14","3B200 BB16","3B200 BB17","3B200 BB18","3B200 BB20","3B200 BB21","3B200 BB22","3B200 BB23","3B200 BB24","3B200 BB25","3B200 BB26","3B200 BB27","3B200 BB30"としました（材料）。

Fタームの詳細につきましては、前回記事にある3B200のFタームリストを参照ください。

コードが一列ずらりと長くなって、かっこ悪くなってしまいました。

```Python
# 「'課題'」と「'解決手段'」の列でグループ化し、グループ内の要素数を数える
result = df_fterm.groupby(['課題', '解決手段']).size().reset_index(name='Counts')
# 課題と解決手段に限定
result = result.query('課題 in ["3B200 BA01","3B200 BA02","3B200 BA03","3B200 BA04","3B200 BA05","3B200 BA06","3B200 BA07","3B200 BA08","3B200 BA09","3B200 BA10","3B200 BA11","3B200 BA12","3B200 BA13","3B200 BA14","3B200 BA15","3B200 BA16","3B200 BA17","3B200 BA18","3B200 BA19","3B200 BA20"] and 解決手段 in ["3B200 BB01","3B200 BB02","3B200 BB03","3B200 BB04","3B200 BB05","3B200 BB06","3B200 BB08","3B200 BB09","3B200 BB10","3B200 BB11","3B200 BB13","3B200 BB14","3B200 BB16","3B200 BB17","3B200 BB18","3B200 BB20","3B200 BB21","3B200 BB22","3B200 BB23","3B200 BB24","3B200 BB25","3B200 BB26","3B200 BB27","3B200 BB30"]')
# 結果を出力して確認
print(result)
```
出力は以下となりました。課題と解決手段のグループとカウント数が無事に抽出できていますので、バブルチャートにできる形式となりました。
```
               課題        解決手段  Counts
28369  3B200 BA01  3B200 BB01      12
28370  3B200 BA01  3B200 BB02       6
28371  3B200 BA01  3B200 BB03     165
28372  3B200 BA01  3B200 BB04      62
28373  3B200 BA01  3B200 BB05     129
...           ...         ...     ...
37151  3B200 BA20  3B200 BB22       1
37152  3B200 BA20  3B200 BB24       4
37153  3B200 BA20  3B200 BB25       1
37154  3B200 BA20  3B200 BB26       1
37155  3B200 BA20  3B200 BB30       9

[344 rows x 3 columns]
```
# バブルチャート化
バブルチャートに描画します。コードは以前のものと基本的には同じです。
```Python
# 「'出願人'」と「'分類'」の列からなる値をリスト形式に変換
y = result['課題'].tolist()
x = result['解決手段'].tolist()
# 「Counts」列からなる値を元に、散布図のすべての点の大きさを示すリストを作成
sizes = [size * 2 for size in result['Counts'].tolist()]
# 「Counts」列からなる値を元に、散布図のすべての点のカウント数を示すリストを作成
nums = [num for num in result['Counts'].tolist()]
# 「出願人」列からなる値を元に、カテゴリーのリストを作成
categories = list(set(y))
# 色マップを作成
colors = cm.rainbow(np.linspace(0, 1, len(categories)))
colors = {categories[i]: colors[i] for i in range(len(categories))}
colors = [colors[item] for item in y]
# 散布図を作成
fig, ax = plt.subplots(figsize=[10,10])
ax.scatter(x, y, s=sizes, c=colors)
# 散布図にカウント数を表示
for i, txt in enumerate(nums):
    ax.annotate(txt, (x[i], y[i]), textcoords="offset points", xytext=(0,0), ha='left', va='bottom')
# x 軸のラベルを設定する。
ax.set_xlabel("解決手段")
# y 軸のラベルを設定する。
ax.set_ylabel("課題")
# タイトルを設定する。
ax.set_title("課題-解決手段マップ")
# X軸項目を90°傾ける
plt.xticks(rotation=90)
# 図を表示
plt.show()
```
# 完成した課題-解決手段マップ
出力は以下のようになりました。無事、課題-解決手段マップをつくることができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/734f1cec-4a8b-214f-cdd9-5206d44b87ea.png)
# 感想
かなり洗練されていない手順ではありましたが、力任せにマップを作ることができました。

20×24のマトリクスとなりますと、作った方は満足感がありますが、見る方は見にくいと思いますので、人に見せる場合には軸項目数は減らした方がよいかもしれません。

また、特許分類を軸項目に使用しますと、とてもわかりにくいマップとなりますので、これは次回以降の課題としたいと思います。