Fタームを使った課題-解決手段マップを考える。

# 課題-解決手段マップとは
課題-解決手段マップは、特許データから抽出した「課題用語」と「解決手段用語」を縦軸，横軸としたマップです。

課題-解決手段マップを使いますと、課題と解決手段の関連性の強弱を判断できますので、製品開発の方向性を考える場合に、とても役に立つ特許マップといえます。
# Fタームとは
Fタームとは、日本国特許庁が編纂している、日本の特許文献の、それぞれの文献に記載された発明の技術的特徴による分類体系、またその分類体系において用いられる分類記号です。

Fターム分類体系を利用すると、複数の技術的観点によって特許文献を分類することができます。

下記はテーマコード3B200（吸収性物品とその支持具）のFタームリストです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/0cb00308-0eb8-7fba-6307-7b2f50a07f57.png)

リストをみますと、BA（物性）のように課題を示すFタームと、BB～EAのように解決手段を示すＦタームがあることがわかります。

したがって、これらをうまく使えば、課題-解決手段マップを作れそうです。
# やりたいこと
Fタームを使って課題-解決手段マップを作成したい。
# 問題点
特許データのFタームのセルには、課題Fタームと解決手段Fタームが混在しているため、分離する方法を考える必要がありますので、これが今回の検討課題です。
# 作り方の検討
##### STEP1 : Fターム列をコピーして、課題列を解決手段列をつくる。
Fターム列はそのままとして、データ加工用の課題列と解決手段列をデッドコピーで作成します。

##### STEP2 : 課題列と解決手段列でデータフレームをエクスプロード
エクスプロード処理するのですが、データ列がとんでもない数となることが予想されるのが不安点です。

##### STEP3 : 課題列を課題分類に限定し、解決手段を解決手段分類に限定する
上記でFターム全体のグループ化がされてしまいますので、ここで課題Fタームと解決手段Fタームに限定します。

##### STEP4 : バブルチャート作成
クロス集計でもよいのですが、せっかく作り方を覚えたバブルチャートを作成します。
# 仮データを使ったマップ作成
いきなり特許データを使用するのも難しいので、まず、簡単な4列の仮データを使用して動作を確認したいと思います。

仮データでは１つのセルに、複数の仮のFターム（A,B,C,D）のいくつかが記入されています。また、AとBを課題Fターム、CとDを解決手段Fタームと仮定します。

|Fターム|
|:-:|
|A,D|
|A,B,C|
|A,B,C|
|A,C|
# データフレーム作成
上記表をデータフレーム化します。

```Python
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
data = {'Fターム': ['A,D', 'A,B,C', 'A,B,C', 'A,C']}
df = pd.DataFrame(data)
```
次に、Fターム列を単純にコピーして、課題列と解決手段列を作成します。
```Python
# Fターム列をコピーして追加
df['課題'] = df['Fターム']
df['解決手段']= df['Fターム']
# データフレーム確認
print(df)
```
出力は以下の通りです。同じ内容の列が3つ出来ております。
```
    Fターム     課題   解決手段
0    A,D    A,D    A,D
1  A,B,C  A,B,C  A,B,C
2  A,B,C  A,B,C  A,B,C
3    A,C    A,C    A,C
```
次に、課題列と解決手段列をエクスプロード処理します。
```Python
# ,で課題を分割
df['課題'] = df['課題'].str.split(',')
# ,で解決手段を分割
df['解決手段'] = df['解決手段'].str.split(',')
# 課題と解決手段をエクスプロード
df = df.explode('課題').explode('解決手段')
# データフレーム確認
print(df)
```
そうすると4行のデータが26行のデータになりました。
```
    Fターム 課題 解決手段
0    A,D  A    A
0    A,D  A    D
0    A,D  D    A
0    A,D  D    D
1  A,B,C  A    A
1  A,B,C  A    B
1  A,B,C  A    C
1  A,B,C  B    A
1  A,B,C  B    B
1  A,B,C  B    C
1  A,B,C  C    A
1  A,B,C  C    B
1  A,B,C  C    C
2  A,B,C  A    A
2  A,B,C  A    B
2  A,B,C  A    C
2  A,B,C  B    A
2  A,B,C  B    B
2  A,B,C  B    C
2  A,B,C  C    A
2  A,B,C  C    B
2  A,B,C  C    C
3    A,C  A    A
3    A,C  A    C
3    A,C  C    A
3    A,C  C    C
```
次に、グループ化してカウントします。そして、課題列を課題FタームA,Bに限定し、解決手段列を解決手段FタームC,Dに限定します。
```Python
# 「'課題'」と「'解決手段'」の列でグループ化し、グループ内の要素数を数える
result = df.groupby(['課題', '解決手段']).size().reset_index(name='Counts')
# 課題をAとBに、解決手段をCとDに限定
result = result.query('課題 in ["A", "B"] and 解決手段 in ["C", "D"]')
# 結果を出力して確認
print(result)
```
出力は以下のようになります。散布図化できるデータとなったことがわかります。
```
  課題 解決手段  Counts
2  A    C       3
3  A    D       1
6  B    C       2
```
最後に散布図化します。
```Python
# 「'出願人'」と「'分類'」の列からなる値をリスト形式に変換
y = result['課題'].tolist()
x = result['解決手段'].tolist()
# 「Counts」列からなる値を元に、散布図のすべての点の大きさを示すリストを作成
sizes = [size * 400 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()
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=(10,10), ha='left', va='bottom')
# X軸とY軸のレンジを設定
plt.xlim(-0.4,1.4)
plt.ylim(-0.4,1.4)
# 図を表示
plt.show()
```
完成したバブルチャートは以下のようになります。縦軸は課題Fタームとなり、横軸は解決手段Fタームとなっており、うまく課題-解決手段マップができていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/5f2fbda8-4b6c-3048-a4ad-88e7ae7b1548.png)
# 感想
なんといいますか、上記手順は正解というわけでもなさそうで、もっとよい手順もあるとは思いますが、一応、課題-解決手段マップを作成できるような気もします。次回は実際の特許データを使用して、課題-解決手段マップの作成を作成したいと思います。