gensimのDoc2Vecを使って質問主意書の類似度を推定してみた

# はじめに
先日、小泉進次郎氏のこの発言に目が留まりました。

「将来的な国会のあり方をイメージすると、何度も同じような質問が繰り返される時は人工知能ではじいてほしいな、と。そういう人工知能の活用とか、未来の国会のあり方、やれることはいっぱいある」（[自民・小泉氏「同じような質問、将来はＡＩではじいて」](https://www.asahi.com/articles/ASL1Q6W20L1QUTFK01N.html)）

ということで、本当にそんなことが出来るのか、Doc2Vecの勉強も兼ねつつ、ある程度データが入手しやすい「質問主意書」を使って実行してみました。BERT（Bidirectional Encoder Representations from Transformers）やELMo（Embeddings from Language Models）等が出てきている昨今にDoc2Vec？という方もいるかと思いますが、gensimでパッケージ化されていて、手軽に使えるなど、ちょっとした分析をやるにはまだまだ現役なのではと思っています。

# 質問主意書
国会で質問というと、議員が大臣などに口頭で行っている姿を思い浮かべると思います。法案や政策についての疑問点を内閣に問いただすのは、議員の重要な仕事ですが、こうした質問は文書でも行うことができます。それが質問主意書です。

少数政党を中心に、国会での質問を行う時間は限られています。そんな時によく活用されるのがこの質問主意書です。過去には薬害エイズ事件などが明るみになったこともある国会議員にとっては大事な追求方法のひとつになっています。

ただし、質問主意書を受け取った内閣は、原則として7日以内に文書で回答しなければなりませんが、このときの回答は、閣議を通さなければならないことになっています。閣議を経るということもあって、質問主意書に対する回答は、政府の公式見解として残ることになるため、現場にとっては重たい作業になっているようです。

[霞が関の嫌われ者 “質問主意書”って何？](https://www3.nhk.or.jp/news/html/20190708/k10011986031000.html)
[時事用語のABC](https://www.weblio.jp/content/%E8%B3%AA%E5%95%8F%E4%B8%BB%E6%84%8F%E6%9B%B8)
<img width="400" height="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/1004444c-4627-6850-a39d-3c6d3cdfaf49.png">
今回対象とした期間での質問主意書の提出者をワードクラウドにしてみました。鈴木宗男の圧倒的存在感…。

# Doc2Vec
Docment-to-Vectorのことで、ドキュメント＝文書の特徴量をベクトルで表すものです。Doc2VecはWord2Vecを開発したTomas Mikilov氏によって提案されたもので、学習方法には下記の2手法が提案されています。

- Distributed Memory Model of Paragraph Vector (PV-DM)
- Distributed Bag of Words version of Paragraph Vector (PV-DBOW)

PV-DMでは、文書ベクトルと連続する単語ベクトルから、直後の単語を予測するように文書ベクトルを学習します。
<img width="400" height="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/5bb9e575-cd0a-6181-2d62-7309f7680bc1.png">

PV-DBOWでは、語順を無視した上で、文章に含まれる単語を当てるように文章ベクトルを学習します。この手法での文の分散表現化は、PV-DMよりも簡単ですが、精度は劣ると紹介されています。
<img width="400" height="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/f26bca3c-8631-035c-7793-bc58fd643417.png">
[自然言語処理技術の活用法　ーDoc2VecとDANを使って論文の質を予測してみた！ー](http://blog.brainpad.co.jp/entry/2019/02/20/103508)より

# データ
今回用いるのはクローリング＆スクレイピングをして入手した衆議院と参議院の質問主意書です。本当は第1回国会からの全データを抽出する気でしたが、心が途中で折れたこともあり、平成と令和に絞って質問主意書のデータを抽出しました。対象となる国会は第114回から第200回になります。
なお、今回はDoc2Vecがメインなので、クローリング＆スクレイピングのコードは省略し、結果だけを掲載します。
また、今回の記事では第114回国会から第199回国会までを使ってモデリングし、第200回国会での質問主意書の類似度を推定します。

データの中身を見る前にまずはライブラリのインポートから。今回は日本語を用いた作図をしているので、それ用のフォントである`NotoSansMonoCJKjp-Regular.otf`を使用してます。豆腐よおさらば。

```{python}
import numpy as np
import pandas as pd

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.pylab import rcParams
from matplotlib.font_manager import FontProperties
font_path = "/mnt/c/u_home/font/NotoSansMonoCJKjp-Regular.otf"
font_prop = FontProperties(fname=font_path)
```
さて、今回のデータはこのようになっています。上から、第114回～第199回国会までの衆参両院の質問主意書、第200回国会の衆参両院の質問主意書、そして、国会が開会している期間の一覧です（[ここのページ](http://www.shugiin.go.jp/internet/itdb_annai.nsf/html/statics/shiryo/kaiki.htm)から入手）。

```{python}
data = pd.read_excel("data.xlsx")
data_200 = pd.read_excel("data_200.xlsx")
data_diet_open = pd.read_excel("data_diet_open.xlsx")
```
それぞれ日付ごとにソートし、上位2つと、下位2つを表示。。

```{python}
data.sort_values(by=['date']).iloc[np.r_[0:2, -2:0]]
```
![s3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/cba0bb4d-e43e-79ee-c9fb-1d7dfbf7c5e6.png)
補足すると、
`time`　質問主意書が提出された国会の会期
`diet`　衆議院か参議院
`title`　質問主意書のタイトル
`name`　質問主意書の提出者
`date`　質問主意書が提出された日
`question`　質問主意書の本文
`q_numb`　質問主意書の質問数（詳細は後述）
`year`　質問主意書が提出された年
`month`　質問主意書が提出された月
`day`　質問主意書が提出された日

今回使用するデータの中で最も古いものは猪熊重二議員が1989-01-20に提出した「貸金業者の金利取締りに関する質問主意書」で、最も新しいのは古賀之士議員が2019-08-05に提出した「「日本郵政グループにおけるご契約調査及び改善に向けた取組について」に関する質問主意書」になります。なお、データ数は15,515です。このデータ数については、少なすぎないという感じでしょうか。

```{python}
data.shape
(15515, 10)
```
また、第200回国会のデータも同様です。データ数は167です。

```{python}
data_200.sort_values(by=['date']).iloc[np.r_[0:2, -2:0]]
```
![s4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/a603d4d8-d395-8a57-39ed-d287f14fb678.png)
最後に国会会期一覧

```{python}

```
<img width="300" height="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/3ec0a268-70ff-c075-8f47-c33c44706f22.png">

# EDA
Doc2Vecに行く前に、色々とデータを探索

## 年・月・日ごとの主意書数
まずは年ごとのグラフ。2006年あたりから急激に増えています。

```{python}
rcParams['figure.figsize'] = 8,4
data.groupby('year').size().plot.bar()
```
<img width="500" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/d4123991-bb88-f71e-9d99-67f59f9d1dd3.png">
次に月ごと。6月多し。7月～9月は少なし。

```{python}
rcParams['figure.figsize'] = 8,4
data.groupby('year').size().plot.bar()
```
<img width="500" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/fe113e09-5279-74bf-3973-88382e4bdcd0.png">

最後に日ごと。31日はそもそも少ないので、主意書数も少ないのは分かるが、それ以外は傾向なし。

```{python}
rcParams['figure.figsize'] = 8,4
data.groupby('day').size().plot.bar()
```
<img width="500" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/5f3cc78f-5bea-db37-66a7-04fe861c37e8.png">

## 日々データに変換
一日いくつの主意書が提出されたのかを把握するために、日付ごとにソートして件数を数えつつ、提出がない日をゼロにして、第114回国会の初日（1988年12月30日）から第199回国会の最終日（2019年8月5日）までの時系列データを作っていきたいと思います。

```{python}
def convert_to_daily(data):
    time_index = pd.DataFrame(index=pd.date_range('19881230','20190805'))
    # 対象となる期間の初日と最終日をセット

    doc_num_daily = pd.DataFrame(data.groupby('date').size(), columns=['doc_num'])
    # 日付ごとに主意書数をカウントし、コラム名を'doc_num'に

    data_daily = pd.concat([time_index, doc_num_daily], axis=1) #マージ
    data_daily['doc_num'] = data_daily['doc_num'].fillna(0) #欠損値をゼロに
    data_daily = data_daily.iloc[:,0] #pandas seriesに
    
    return data_daily

data_daily = convert_to_daily(data) #実行
```
さらに、国会期間中の場合は、背景色をグレーにする用の関数を作成。

```{python}
def plot_daily_data(data_daily, start_day, end_day):
    subdata = data_diet_open[(data_diet_open['end'] >= start_day) & (data_diet_open['end'] <= end_day)].sort_values(by='diet_time').reset_index(drop=True)
    plt.plot(data_daily.loc[start_day:end_day])
    plt.title("Number of docments between " + start_day + " and " + end_day)
    for i in range(subdata.shape[0]):
        plt.axvspan(subdata.start[i],subdata.end[i], color=sns.xkcd_rgb['grey'], alpha=0.5)
```
ということでプロット。

```{python}
rcParams['figure.figsize'] = 20,5
start_day = "1988-12-30"; end_day = "2019-12-31"
plot_daily_data(data_daily, start_day, end_day)
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/7465b81e-c506-1b48-4b31-025147090568.png">

なんとなく右肩上がりで、2004年から増え続けているっぽいのは分かるが見づらい…ので、3分割してみました。

```{python}
start_day = "1988-12-30"; end_day = "1999-12-31"
plot_daily_data(data_daily, start_day, end_day)
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/d5036cf3-72cb-da33-2469-d0e9ab001032.png">

```{python}
start_day = "2000-01-01"; end_day = "2009-12-31"
plot_daily_data(data_daily, start_day, end_day)
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/521b2aa9-4186-8761-09aa-4907e6e4c57b.png">


```{python}
start_day = "2010-01-01"; end_day = "2019-12-31"
plot_daily_data(data_daily, start_day, end_day)
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/99a0dc41-a67d-7978-70eb-3bc779570464.png">

質問主意書は国会会期中のみ提出可能ということで、毎回、国会の会期末（＝グレーの一番右端）になると提出数が増えるということが良く分かります。それにしても、3分割してグラフを出しましたが、左側のスケールが段々増えているのが、昨今、質問主意書がよく利用されているのを如実に表しています…。

質問主意書の提出数をヒストグラムに。綺麗な右肩下がりのグラフになっています。

```{python}
plt.hist(data_daily[data_daily > 0], bins=50)
```
![s13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/552f1fa4-ed64-e519-60c4-9ec9142ee779.png)

最大値は2015年9月25日の84！この日に何があったかは後述…。

```{python}
data_daily.max()

doc_num    84.0
dtype: float64
```
```{python}
data.groupby('date').size().idxmax()
Timestamp('2015-09-25 00:00:00')
```

## 名前ごと
どの国会議員が質問主意書をよく提出しているのかを見ていきたいと思います。まずはデータに載っている国会議員の数は、789です。このデータでは連名を「赤嶺政賢高橋千鶴子吉井英勝」と雑に扱っている点にはご留意ください。

```{python}
len(data.name.unique())
789
```
さて、気になるトップ30人はこちらです！

```{python}
subdata = data.groupby('name').filter(lambda x: len(x) >= 100)
len(subdata.name.unique())
30 #上位30人までを抽出

plot_value = subdata.groupby('name').size().sort_values(ascending=False)
plot_index = subdata.groupby('name').size().sort_values(ascending=False).index

rcParams['figure.figsize'] = 20,5
plt.bar(plot_index, plot_value)
plt.xticks(plot_index, rotation=90, fontproperties=font_prop)
for i, v in enumerate(plot_value):
    plt.text(i - 0.5, v + 5, str(v), color='blue')
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/98845079-f242-fdb5-2129-f6baf0ea5978.png">

2位以下を大きく引き離してトップになったのは鈴木宗男氏。その数2155…。[Wikipedia](https://ja.wikipedia.org/wiki/%E8%B3%AA%E5%95%8F%E4%B8%BB%E6%84%8F%E6%9B%B8#%E6%8F%90%E5%87%BA%E6%95%B0)にもばっちり記載があります。

”提出の多い例として、「質問主意書のキング」とも呼ばれ野党時代に1900の質問主意書を提出した新党大地の鈴木宗男が挙げられる。宗男は2010年（平成22年）に失職となり国会を去ったが、その後は同じ新党大地で後継者となった浅野貴博に質問主意書の提出を継続させた。さらに2013年（平成25年）6月に宗男の長女の鈴木貴子が繰り上げ当選すると、以降は貴子を通じて質問主意書による攻勢をかけている。”

## 鈴木宗男
質問主意書の役割が大きく変わったのは鈴木宗男氏の存在が大きいとされています。[NHKの記事](https://www3.nhk.or.jp/news/html/20190926/k10012096901000.html)でも触れられています。ということで、鈴木宗男氏の質問主意書の数を見ていきたいと思います。

```{python}
muneo_daily = convert_to_daily(data[data['name']=="鈴木宗男"].reset_index(drop=True))

rcParams['figure.figsize'] = 20,5
plt.plot(data_daily)
plt.plot(muneo_daily)
for i in range(data_diet_open.shape[0]):
    plt.axvspan(data_diet_open.start[i],data_diet_open.end[i], color=sns.xkcd_rgb['grey'], alpha=0.4)
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/d8e999fe-b911-b3a6-6374-10c1678397f8.png">
オレンジ色が鈴木宗男氏の質問主意書の提出数です。鈴木宗男氏が質問主意書を提出していた時期を拡大してみると、

```{python}
start_day = "2005-10-03"; end_day = "2010-08-04"
subdata = data_diet_open[(data_diet_open['end'] >= start_day) & (data_diet_open['end'] <= end_day)].sort_values(by='diet_time').reset_index(drop=True)

plt.plot(data_daily.loc[start_day:end_day])
plt.plot(muneo_daily.loc[start_day:end_day])
plt.title("Number of docments between " + start_day + " and " + end_day)
for i in range(subdata.shape[0]):
    plt.axvspan(subdata.start[i],subdata.end[i], color=sns.xkcd_rgb['grey'], alpha=0.5)
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/54240083-b6c7-c989-b7a1-d20acb4e4268.png">
2006年から2007年にかけては、提出された質問主意書のほとんどが鈴木宗男氏になっているのが分かります。

## 日付と提出者ごと
今度は一日あたりの提出が多い議員を探していきたいと思います。

```{python}
subdata = data.groupby(['name','date']).filter(lambda x: len(x) >= 15)
pd.DataFrame(subdata.groupby(['name','date']).size().sort_values(ascending=False))
```
<img width="150" height="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/12c37f1e-6c93-9932-a498-2f6c25f4e41a.png">

トップは2015年9月25日に55本提出した小西洋之氏でした。さすがは「国会のクイズ王」の異名を持つだけのことはありますね。ちなみに小西洋之氏のこの日提出した質問主意書のタイトルはこちら。

<img width="350" height="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/70f03ce9-9a42-92ab-7d56-39c7ac851b4b.png">

似たようなタイトルが続いていますが、特に39と40は何とかならなかったのでしょうか…。これだけ質問主意書のコストが叫ばれているのに…、間違い探しのよう…。

39．日米同盟に基づく在日米軍の海軍基地の米国における価値に関する質問主意書
40．日米同盟に基づく在日米軍の空軍基地の米国における価値に関する質問主意書

こちらに関しては、[こんな記事](https://seijiyama.jp/article/news/nws20151007-002.html)も書かれていました。

「今回、55件という記録的な数を提出した小西議員の質問を見てみると、同じようなテーマでわずか1行半の質問を複数回に分けて質問しているケースがありました。主意書は同じテーマであれば箇条書きにして複数の質問をすることができます。内容も文言の解釈を問うものが多く、かつて予算委員会で安倍総理大臣から「クイズのような質問は生産的ではない」と言われた場面を思い出す、大局観に欠けた質問が並んでいる印象です。」


## 主意書の質問数
データのコラム名の解説のところで`q_numb`は後述と書きましたが、今回は質問主意書の数だけではなく、質問主意書に記載のある質問数もスクレイピングの際に抽出しています。例えば、[こちらの主意書](https://www.sangiin.go.jp/japanese/joho1/kousei/syuisyo/200/syuh/s200001.htm)では、三つの質問を問うています。

<img width="500" height="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/1e40a4f4-0cb5-314a-91b3-261daba52f03.png">

漢数字部分が個別の質問になっているのです。ただ単に質問主意書の数ではなく、質問主意書の中の質問数を見た方が実際のコストを図れるのではないかというアイディアからです。
まずは質問数の一日の合計から見ていきます。

```{python}
def convert_to_daily_qnum_sum(data):
    time_index = pd.DataFrame(index=pd.date_range('19881230','20190805'))

    doc_num_daily = data.groupby(['date'], as_index=False)['q_numb'].sum()
    doc_num_daily.set_index('date', inplace=True)
    data_daily = pd.concat([time_index, doc_num_daily], axis=1)
    data_daily['q_numb'] = data_daily['q_numb'].fillna(0)
    data_daily = data_daily["q_numb"]
    
    return data_daily

convert_to_daily_qnum_sum(data).plot()
for i in range(data_diet_open.shape[0]):
    plt.axvspan(data_diet_open.start[i],data_diet_open.end[i], color=sns.xkcd_rgb['grey'], alpha=0.4)
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/af28be0b-1d5a-670c-0092-6c3e1500a98b.png">
こちらも2000年以降右肩上がり。特に2007年あたりからは269（2007-07-03）の質問があるなど、大きく伸びており、その後も200を超える日が散見されます。なお、一日の平均質問数も見ていきます。

```{python}
def convert_to_daily_qnum_mean(data):
    time_index = pd.DataFrame(index=pd.date_range('19881230','20190805'))

    doc_num_daily = data.groupby(['date'], as_index=False)['q_numb'].mean()
    doc_num_daily.set_index('date', inplace=True)
    data_daily = pd.concat([time_index, doc_num_daily], axis=1)
    data_daily['q_numb'] = data_daily['q_numb'].fillna(0)
    data_daily = data_daily["q_numb"]
    
    return data_daily

convert_to_daily_qnum_mean(data).plot()
for i in range(data_diet_open.shape[0]):
    plt.axvspan(data_diet_open.start[i],data_diet_open.end[i], color=sns.xkcd_rgb['grey'], alpha=0.4)
```
<img width="1000" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/c868307d-be41-ba43-3b13-6413c8640a2f.png">

こちらはあまり目立った変化はないですね…。なお、一つの質問主意書の質問数が一番多かったのは山井和則氏の「雇用分野の国家戦略特区に関する質問主意書」で質問数は68！なんというか、「解雇ルール明確化の具体例を三つ挙げて下さい」、「そもそも特区では労働契約法十六条は適用外になりますか。」などなど、テストを受けているみたいな感覚になりました…。

# Doc2Vec
## 分かち書き
データ探索が長くなってしまいましたが、ここからが本番です。まずは質問主意書の本文ごとに文章を単語に分割していきます（分かち書き）。例えば、`「私は男である」`であれば`[私 は 男 で ある]`というふうに、単語レベルに分割し、それぞれ半角スペースで区切っていきます。分かち書きで今回使用したのは`MeCab`になります。次の関数が分かち書きに使用したものになります。`POS1`で必要となる品詞のみを抽出できるようにしています。

```{python}
import MeCab
def word_pos(text, POS1=['連体詞','名詞','副詞','動詞','接頭詞','接続詞',
                         '助動詞','助詞','形容詞','記号','感動詞','フィラー','その他']):

    tagger  = MeCab.Tagger('mecab -d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd')
    tagger.parse('')

    node = tagger.parseToNode(text)
    word_class = []
    while node:
        word = node.surface
        wclass = node.feature.split(',')
        if wclass[0] != u'BOS/EOS':
            if wclass[6] == None:
                if wclass[0] in POS1:
                    word_class.append((word,wclass[0],wclass[1],""))
            else:
                if wclass[0] in POS1:
                    word_class.append((word,wclass[0],wclass[1]))
        node = node.next
        
    word_class = pd.DataFrame(word_class, columns=['term', 'pos1', 'pos2'])
    
    return word_class
```
質問主意書の本文の空白を消したのちに、名詞と形容詞のみを抽出し、さらにあまり意味をなさない、'接尾'、'非自立'、'数'を消去していきます。そして、`data`に`word_list`として格納

```{python}
data.question = data.question.str.replace("\u3000", " ")
data_200.question = data_200.question.str.replace("\u3000", " ")

data['word_list'] = ""

for i in range(data.shape[0]):
    each_data = word_pos(data.question[i], ["名詞","形容詞"])
    each_data1 = each_data[each_data['pos2'] != '接尾']
    each_data1 = each_data1[each_data1['pos2'] != '非自立']
    each_data1 = each_data1[each_data1['pos2'] != '数']
    data.loc[i,"word_list"] = " ".join(list(each_data1.term))

data_200['word_list'] = ""

for i in range(data_200.shape[0]):
    each_data = word_pos(data_200.question[i], ["名詞","形容詞"])
    each_data1 = each_data[each_data['pos2'] != '接尾']
    each_data1 = each_data1[each_data1['pos2'] != '非自立']
    each_data1 = each_data1[each_data1['pos2'] != '数']
    data_200.loc[i,"word_list"] = " ".join(list(each_data1.term))
```

イメージを掴むために、一つだけ例示します。`神奈川県鎌倉市では、市内の海水浴場において、津波避難訓練を実施する`を`word_pos`で処理すると、次のようになります。
<img width="200" height="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/ac84a08a-5ac7-551e-d48a-e0f7c008a3e4.png">

## Doc2Vec
ここでは、一つの質問主意書ごとに、本文を単語に分割し、リストに入れていきます。[([単語1,単語2,単語3],文書id),...]というイメージです。以下のコードのうち、wordsは文書に含まれる単語のリスト（単語の重複あり）、tagsは質問主意書の識別子（リストで指定．1つの質問主意書に複数のタグを付与できる）を指します。

```{python}
docments = data.word_list
tagged_data = [TaggedDocument(words = data.split(),tags = [i]) for i,data in enumerate(docments)]
```

## モデルの学習
```{python}
model = Doc2Vec(documents=tagged_data, size=300, window=10, min_count=5, workers=4, seed=1, dm=1)
```
パラメータについては、
`size`：ベクトルの長さ
`window`：windowサイズ
`min_count`：カウントする最小単語数
`workers`：スレッド数
`seed`：乱数の固定
`dm`：dm=1とするとPV-DM、それ以外はDBoWで学習
となります。このほかにも学習率を指定する`alpha`や`min_alpha`などがありますが、いろいろと試し、定性的に評価したところ、先ほどのパラメータに落ち着きました。正直、`gensim`は損失を自動的に算出する関数がないので、この辺りは自分でモデリングできた方がだいぶんやりやすいだろうなと感じました。また、学習させる意味合いでこのようなコードを沢山見かけます。

```{python}
for epoch in range(10):
    print('iteration {0}'.format(epoch+1))
    model.train(tagged_data, total_examples=model.corpus_count, epochs=model.iter)
    model.alpha -= 0.0002 # decrease the learning rate
    model.min_alpha = model.alpha # fix the learning rate, no decay
```
しかし、`gensim`の作成者によれば、これはバージョンの古い`Doc2Vec`用の学習コードであり、現在のバージョンだと、よほどの専門家でない限りはこのようにする必要はないとのことでした。
[What does epochs mean in Doc2Vec and train when I have to manually run the iteration?](https://stackoverflow.com/questions/51245689/what-does-epochs-mean-in-doc2vec-and-train-when-i-have-to-manually-run-the-itera)
"An advanced user who needed to do some mid-training logging or analysis or adjustment might split the training over multiple train() calls, and very consciously manage the effective alpha parameters for each call. An extremely advanced user experimenting with further training on an already-trained model might also try it, aware of all of the murky quality/balance issues that might involve. But essentially, unless you already know specifically why you'd need to do so, and the benefits and risks, it's a bad idea."

また、ベクトルのサイズについても、`gensim`の作成者から興味深いコメントがなされています。今回のデータ量もギリギリという感じでしょうか。
[what is the minimum dataset size needed for good performance with doc2vec?](https://stackoverflow.com/questions/45959618/what-is-the-minimum-dataset-size-needed-for-good-performance-with-doc2vec)
In general, word2vec/paragraph-vector techniques benefit from a lot of data and variety of word-contexts. I wouldn't expect good results without at least tens-of-thousands of documents. Documents longer than a few words each work much better. Results may be harder to interpret if wildly-different-in-size or -kind documents are mixed in the same training – such as mixing tweets and books.

```{python}
model.save("doc2vec.model") #モデルの保存
model = Doc2Vec.load('doc2vec.model') #モデルの呼び出し
```

## 類似の質問主意書
`model.docvecs.most_similar()`で類似の質問主意書が検索できます。

```{python}
model.docvecs.most_similar(10531)

[(12348, 0.8008440732955933),
 (10543, 0.7899609804153442),
 (10534, 0.7879745960235596),
 (12278, 0.7819333076477051),
 (14764, 0.7807815074920654),
 (13340, 0.7798347473144531),
 (11314, 0.7743450403213501),
 (14881, 0.7730422616004944),
 (1828, 0.7719383835792542),
 (14701, 0.7534374594688416)]
```

ということで、元のやつと、上位2つを表示
```{python}
pd.set_option('display.max_colwidth', -1)
data.iloc[10531:10532,:6]
```
![s23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/ca14b899-a72b-1838-cf41-7fcc31fc1f0e.png)

```{python}
idx = model.docvecs.most_similar(10531)[0][0]
pd.set_option('display.max_colwidth', -1)
data.iloc[idx:idx+1,:6]
```
![s24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/5f714d60-c158-0fc4-caea-4e9982c1d4b1.png)

```{python}
idx = model.docvecs.most_similar(10531)[1][0]
pd.set_option('display.max_colwidth', -1)
data.iloc[idx:idx+1,:6]
```
![s25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/52ad3b8d-ef40-e6e2-1b35-0a9853191bd2.png)

どれも残業問題、ワークライフバランスというトピックなので、まあまあの結果かなと思います。

## 新しい質問主意書との類似度
さて、ここからがようやく本題です。

「将来的な国会のあり方をイメージすると、何度も同じような質問が繰り返される時は人工知能ではじいてほしいな、と。そういう人工知能の活用とか、未来の国会のあり方、やれることはいっぱいある」（小泉進次郎氏）

をモデルの中にはない第200回国会の質問主意書を用いて、類似度を推定していきます。新たな文書をベクトルにするには`model.infer_vector()`を用います。`()`には新たな文書と、何回モデルを回すかの`step`を指定します。step数は、`gensim`の作成者の意見を踏まえて、20としました。
さらに、この新たな文書のベクトルは`model.docvecs.most_similar(positive=[new_docvec], topn=1)`で既存のモデルの中の文書との類似度を算出します。`topn`は上位いくつの文書を抽出するかというものになります。

```{python}
list_most_sim_doc   = []
list_most_sim_value = []

for i in range(data_200.shape[0]):
    new_doc = data_200.loc[i,'word_list']
    new_doc = new_doc.split(" ")
    new_docvec = model.infer_vector(new_doc, steps=20)
    most_sim_doc   = model.docvecs.most_similar(positive=[new_docvec], topn=1)[0][0]
    most_sim_value = model.docvecs.most_similar(positive=[new_docvec], topn=1)[0][1]
    
    list_most_sim_doc.append(most_sim_doc)
    list_most_sim_value.append(most_sim_value)
```
類似度の分布はこのとおり。1に近づくほど、近くなります。

```{python}
plt.hist(list_most_sim_value, bins=50)
```
<img width="350" height="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/5c0e2ff5-4e60-6ad4-7fdb-9faabdb6c626.png">
ここで、既存のデータセットに、最も近い文書IDと類似度の値を結合。

```{python}
new_doc_sim = pd.DataFrame({"sim_doc":list_most_sim_doc,"sim_value":list_most_sim_value})
data_200_sim = pd.concat([data_200, new_doc_sim], axis= 1)
```

類似度トップ3はこちら。どれも0.8を超えています。

```{python}
pd.reset_option('^display.', silent=True)
data_200_sim = data_200_sim.sort_values(by='sim_value', ascending=False).reset_index(drop=True)
data_200_sim.head(3)
```
![s27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/9d38d30f-58cf-478c-0fb8-1b5a65c7e089.png)

## 質問主意書の中身
### その１
どんな内容なのか。第200回国会の文書その１。内容はガーダシルという薬がなぜ承認されないのかというもの。

```{python}
idx=data_200_sim.index[1]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]
```
![s30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/c1f387d8-bf57-6598-1575-258b3a26f3d0.png)
次に、第200回国会の文書その１に、モデルの中での一番近い文書。長い…。内容はイレッサという薬の承認に関するもの。まずまずの結果。

```{python}
idx=data_200_sim.index[0]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]
```
![s31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/8cd80698-4811-3be4-959f-1a51aa87d064.png)

### その２
第200回国会の文書その２。長い…。内容はMMT理論に基づく景気刺激策。

```{python}
idx=data_200_sim.index[0]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]
```
![s28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/982b9d5d-4cfd-4843-aab2-1fa054b52e4a.png)
次に、第200回国会の文書その２に、モデルの中での一番近い文書。もっと長い…。とりあえずの経済刺激策の内容。悪くはない結果。

```{python}
idx=data_200_sim.index[0]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]
```
![s29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/57e02983-0dfa-21a2-03ae-ffdd79973871.png)


### その３
第200回国会の文書その３。内容は令和時代の恩赦について。

```{python}
idx=data_200_sim.index[2]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]
```
![s32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/f13dc735-1c98-fc0f-be05-d7f3614ccaff.png)
モデルの中のでの一番近い文書は、これまた令和時代の恩赦について。これもいい結果に。

```{python}
idx=data_200_sim.sim_doc[2]
pd.set_option('display.max_colwidth', -1)
data.iloc[idx:idx+1,:6]
```
![s33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246473/d58b3757-6ce4-a1c9-6235-431902a26276.png)

# おわりに
途中データ探索が楽しくなってしまい、無駄に長く書いてしまいましたが、Doc2Vecをさらっと試してみた結果、第200回国会の質問主意書という新たな文書について、まあまあ上手く類似度を推定できたなのではないでしょうか。といいつつ、小泉進次郎氏が言うような、AIがパシッと質問を切るような世界は近くはない将来の出来事なのかなという印象です。

今回はデータ探索とDoc2Vecを使った類似度判定を試してみましたが、今後は政党のデータを交えつつ、クラスタリングを行ったり、本当に私がやってみたい、質問主意書の”質”の判定をやってみたいと思います。特に質問主意書の”質”については、単に質問主意書を多く出せばそれが成果となるという論調を変えていけれるのではないかと考えています。

私の手元にクローリング＆スクレイピングを行ったデータセットがありますので、このデータを使って色々分析＆解析したいという方がいらっしゃれば、何かしら共同でやっていけるのではないかと期待しています！