Doc2Vecを用いて特許公報の要約部分をベクトル化し可視化する

今回は、Doc2Vecを用いて特許公報の要約部分をベクトル化し可視化しました。「特許公報が似ているかどうかDoc2Vecで判断」という記事<https://qiita.com/opankopan/items/ba2c651b8ead348b9386>がありますが、今回は、AI系の特許公報と化学系の特許公報をベクトル化して、可視化するということをやってみました。
玄人が特許公報を読めば、それがAI系の特許公報なのか化学系の特許公報なのかはすぐに分かるのですが、Doc2Vecを使ってその違いが可視化できれば面白いのではと思い、このようなテーマ設定しました。

# やったこと
１．特許情報プラットフォームhttps://www.j-platpat.inpit.go.jp/ から特許公報のcsvデータをダウンロード
２．既存のDoc2Vecを利用して特許公報の要約部分をベクトル化（300次元）
３．PCA（主成分分析）を用いて2次元ベクトルを生成
４．2次元ベクトルを可視化

言語はPython、環境はGoogle Colaboratoryを使用しました。

# 評価対象のデータ
今回、データとして用いたのは、2022年1月1日～2022年10月6日までに公開された特許公報の要約部分の文章データです。具体的には、要約に「学習済みモデル」という単語が含まれているAI系の特許公報と、要約に「組成物」という単語が含まれている化学系の特許公報を対象としました。そして、この２種類の特許公報の要約をDoc2Vecを用いて可視化しました。

# データの取得と前処理
まず、特許が公開されているサイト特許情報プラットフォームhttps://www.j-platpat.inpit.go.jp/ から特許公報のcsvデータをダウンロードしました。
「学習済みモデル」が含まれている要約281件と「組成物」が含まれている要約359件とをcsvデータとしてダウンロードし、以下のようにデータフレームとして取得しました。なお、以下の「label」は手作業で付加したものです。

```py:
import pandas as pd
df_predict = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/特実_国内文献.csv',encoding="utf_8")
dfx_predict = df_predict[['出願番号','要約','label']]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2899509/0b340438-1351-3492-fe53-e0a57ec85626.png)

次に、「要約」に対して、以下の前処理を実行することにより、余計な記載を除去しました。

```py:
def f_str(x):
    return str(x).replace('【要約】', '').replace('【課題】', '').replace('\r\n', '').replace('(57)', '').replace('【解決手段】', '').replace('<BR>', '').replace('【選択図】', '').replace('図１', '').replace('図２', '').replace('図３', '').replace('（修正有）', '')

s = dfx_predict['要約']
T = s.map(f_str)
dfy_predict = pd.DataFrame(T)
dfx_predict['要約'] = dfy_predict['要約']
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2899509/0fa7047e-9824-900d-adc8-c10443e7138e.png)

上記の処理は、以下のサイトを参考にしました。
https://note.nkmk.me/python-pandas-map-applymap-apply/

# Doc2Vecモデル
次に、Doc2Vecについて説明します。今回使用したDoc2Vecは既存のものであり、「日本語WIKIPEDIAで学習したDOC2VECモデルhttps://yag-ays.github.io/project/pretrained_doc2vec_wikipedia/」で公開されている「dbow300d」を使用させて頂きました。

```py:
from gensim.models.doc2vec import Doc2Vec
model = Doc2Vec.load("/content/drive/MyDrive/Colab Notebooks/jawiki.doc2vec.dbow300d.model")
```
上記の処理は、以下のサイトを参考にしました。
https://analysis-navi.com/?p=2293#%E6%96%87%E7%AB%A0%E3%81%AE%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E5%8C%96

# Doc2Vecによる埋め込みベクトル取得と可視化

次に、要約を分かち書きする処理を実行し、その結果をDoc2Vecへ入力することにより埋め込みベクトルを生成しました。埋め込みベクトルは300次元です。

```py:
from janome.tokenizer import Tokenizer
def sep_by_janome(text):
    t = Tokenizer()
    tokens = t.tokenize(text)
    docs=[]
    for token in tokens:
        docs.append(token.surface)
    return docs
```

```py:
document_vecs=[]
for d in dfx_predict["要約"]:
    document_vecs.append(model.infer_vector(sep_by_janome(d)))
dfx_predict['Vector'] = document_vecs
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2899509/ed4909b5-3ebc-f9ad-0951-24b0d923e958.png)

```py:
df_vec = dfx_predict['Vector'].apply(pd.Series)
```
Doc2Vecによって得られるベクトルは300次元なので、見ることができません。
そのため、得られたベクトルに対してPCA（主成分分析）を実行することにより、300次元のベクトルを2次元のベクトルへと変換しました。
具体的には、上記のVectorを分割して以下のようなデータにしてPCA（主成分分析）を実行しました。

```py:
df_vec = dfx_predict['Vector'].apply(pd.Series)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2899509/e766de3e-ed82-9cd5-245e-74a49b1e31f7.png)

```py:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
df_pca = pd.DataFrame(pca.fit_transform(df_vec))
df_pca['label'] = dfx_predict['label']
```
```py:
import seaborn as sns
sns.scatterplot(data=df_pca, x=0, y=1, hue='label')
```

以下の図が可視化結果です。1つのプロット点が1つの特許公報の要約を表しています。また、青いプロット点はAI系の特許公報に相当し、オレンジ色のプロット点が化学系の特許公報に相当します。かなりきれいに分けることができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2899509/a25c797c-c891-dc62-d017-7c266116eb1e.png)

# 考察
上記のように、AI系の特許公報と化学系の特許公報とでは、Doc2Vecによって生成される埋め込みベクトルがかなり異なることが分かりました。Doc2Vecを利用すれば、特許分類などが比較的容易にできるものと考えられます。