学会のアブストラクトの検索

#はじめに
みんな～！　学会行ってる～？
学会のアブストラクト(概要集)ってめちゃくちゃ量があって大変だよね。

そんなわけで、学会のアブストラクトを機械学習(Doc2Vec)を用いて分類して、
自分の興味ある発表を引っ張り出してくるプログラムをPythonで作ります。

すごい汚いコードだけどゆるしてね！


参考にした記事はこちら
[[gensim]Doc2Vecの使い方](https://qiita.com/asian373asian/items/1be1bec7f2297b8326cf)
[doc2vecをしてみた（機械学習名古屋第１３回勉強会）](https://qiita.com/n_kats_/items/e0f4a7c71f32357ef730)
[Doc2Vecの仕組みとgensimを使った文書類似度算出チュートリアル](https://deepage.net/machine_learning/2017/01/08/doc2vec.html)

ドキュメントはこちら
[models.doc2vec – Deep learning with paragraph2vec](https://radimrehurek.com/gensim/models/doc2vec.html)

# もくじ
- [ECS Abstractをダウンロードする](#ECS Abstractをダウンロードする)
- [使うモジュール](#使うモジュール)
- [カテゴリーとセッションのリストを作る](#カテゴリーとセッションのリストを作る)
- [ストップワードのリストを作成](#ストップワードのリストを作成)
- [文章をリストにまとめる](#文章をリストにまとめる)
- [Doc2Vecで学習](#Doc2Vecで学習)
- [類似文書を検索する](#類似文書を検索する)
- [検索結果！](#検索結果！)

#ECS Abstractをダウンロードする
ECS(Electrochemical Society)は電気化学系で一番大きな学会で、国際学会を年2回開催しています。

その中でも2017年秋季ECS meeting(232nd)の概要集をダウンロードします。
https://www.electrochem.org/232/download-abstracts

すばらしいことに、ECSは概要集をzip形式で誰でもダウンロードできるようにしています。
さすがだぜECS！　[Free the science!!](https://www.electrochem.org/free-the-science)

ちなみに、概要本文のhtmlファイルは
ECS MA2017-02/Abstracts/Html
の中に入ってます。

分析に使うのは、Abstractsフォルダに入っているtos.htmlと
Htmlフォルダに入っている1.html~2371.Htmlです。

#使うモジュール

以下のプログラムでは、次のモジュールを使います。

* os
* beautifulsoup4
* re
* time
* numpy
* pandas
* tqdm
* ipywidgets
* gensim.models.doc2vec

```python
import bs4
import re
import os
import time
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import pandas as pd

from tqdm import tqdm_notebook as tqdm
from ipywidgets import IntProgress

from gensim.models.doc2vec import Doc2Vec
from gensim.models.doc2vec import TaggedDocument
```

jupyter-notebookでプログレスバーを表示するためには、コマンドプロンプトで

```
jupyter nbextension enable --py --sys-prefix widgetsnbextension
```

と入力してipywidgetsを有効にしておいてください。

#カテゴリーとセッションのリストを作る
以下のコードでtos.htmlからカテゴリー一覧とセッション名一覧を取得します。
tosはたぶんtable of sessionsかなんかの略じゃないっすかね。

```python
#記号除去用の関数
px = re.compile(r"<[^>]*?>")

#学会のTable of sessionsを読み込み
soup = bs4.BeautifulSoup(open('tos.html', encoding='utf-8'), "html5lib")

#カテゴリーを読み込み、表示
p_len = len(soup('h2'))
categorys = []
for i in range(p_len):
    c = px.sub("", str(soup('h2')[i]))
    categorys.append(c)
print("categoly_num ="+str(p_len))
print(categorys)

#セッションを読み込み、表示
p_len = len(soup('h3'))
sessions = []
for i in range(p_len):
    c = px.sub("", str(soup('h3')[i]))
    sessions.append(c)
print("session_num ="+str(p_len))
print(sessions)
```

カテゴリー名とセッション名はh2,h3タグで書かれているので、その部分を指定します。
出力はこんな感じ。

```
categoly_num =14
['A—', 'B—', 'C—', 'D—', 'E—', 'F—', 'G—', 'H—', 'I—', 'J—', 'L—', 'M—', 'O—', 'Z—']
session_num =56
['A01-Battery and Energy Technology Joint General Session', 'A02-Battery Characterization: Symposium in Honor of Frank McLarnon', 'A03-Battery Student Slam 2', 'A04-Li-ion Batteries', 'A05-Battery Materials: Beyond Li-Ion', 'A06-Advanced Manufacturing Methods for Energy Storage Devices', 'A07-Fast Electrochemical Processes and Devices', 'B01-Carbon Nanostructures: From Fundamental Studies to Applications and Devices', 'C01-Corrosion General Session', 'C02-Light Alloys 5', 'C03-State-of-the-Art Surface Analytical Techniques in Corrosion 3: In Honor of Hugh Isaacs', 'C04-Coatings and Inhibitors', 'C05-Corrosion in Concrete Structures', 'D01-Semiconductors, Dielectrics, and Metals for Nanoelectronics 15: In Memory of Samares Kar', 'D02-Photovoltaics for the 21st Century 13', 'E01-Fundamentals of Electrochemical Growth from UPD to Microstructures 4', 'E02-Current Trends in Electrodeposition - An Invited Symposium', 'E03-Electrochemical Science and Engineering on the Path from Discovery to Product', 'E04-Electrochemical Processing from Non-aqueous Solvents', 'E05-Mechanics and Metallurgy of Electrodeposited Thin Films', 'F01-Electrochemical Engineering General Session', 'F02-Electrochemical Separations', 'F03-Electrochemical Conversion of Biomass', 'G01-15th International Symposium on Semiconductor Cleaning Science and Technology (SCST 15)', 'G02-Atomic Layer Deposition Applications 13', 'G03-Semiconductor Process Integration 10', 'G04-Thermoelectric and Thermal Interface Materials 3', 'G05-Oxide Memristors', 'H01-State-of-the-Art Program on Compound Semiconductors 60 (SOTAPOCS 60)', 'H02-Low-Dimensional Nanoscale Electronic and Photonic Devices 10', 'H03-Gallium Nitride and Silicon Carbide Power Technologies 7', 'I01A-Polymer Electrolyte Fuel Cells 17 (PEFC 17) - Diagnostics/Characterization Methods, MEA Design/Model', 'I01B-Polymer Electrolyte Fuel Cells 17 (PEFC 17) - Fuel Cell Systems, Stack/BOP Design, Gas Processing', 'I01C-Polymer Electrolyte Fuel Cells 17 (PEFC 17) - Cation-Exchange Membrane Performance and Durability', 'I01D-Polymer Electrolyte Fuel Cells 17 (PEFC 17) - Catalyst Activity/Durability for Hydrogen(-Reformate) Acidic Fuel Cells', 'I01E-Polymer Electrolyte Fuel Cells 17 (PEFC 17) - Materials for Alkaline Fuel Cells and Direct-Fuel Fuel Cells', 'I01F-Polymer Electrolyte Fuel Cells 17 (PEFC 17) - Polymer-Electrolyte Electrolysis', 'I01Z-Polymer Electrolyte Fuel Cells 17 (PEFC 17) - Invited Talks', 'I02-Ionic and Mixed Conducting Ceramics 11 (IMCC 11)', 'J01-Luminescence and Display Materials: Fundamentals and Applications', 'L01-Physical and Analytical Electrochemistry General Session', 'L02-Photocatalysts, Photoelectrochemical Cells and Solar Fuels 8', 'L03-Physical and Analytical Electrochemistry of Ionic Liquids 6', 'L05-Bioelectroanalysis', 'L06-Fundamental Aspects of Electrochemical Conversion of Carbon Dioxide', 'L07-Computational Electrochemistry', 'L08-Advanced Techniques for In Situ Electrochemical Systems', 'L09-Multi-electron Redox Systems for Next Generation Batteries', 'M01-Sensors, Actuators and Microsystems General Session', 'M02-Practical Implementation and Commercialization of Sensors 2', 'OC-ECS OpenCon 2017: Exploring Ideas for Next Generation Research', 'Z01-General Student Poster Session', 'Z02-Nanotechnology General Session', 'Z03-Energy-Water Nexus', 'Z04-The Brain and Electrochemistry', 'Z05-Sensors for Food Safety, Quality, and Security']
```

今回の発表は計14の大きなカテゴリー(A~Z)と、56のセッションに分類されることがわかります。

#ストップワードのリストを作成

ストップワードとは、文章の中であまり意味を持たない単語(be動詞や前置詞など)のことです。

英語のストップワードはこの辺りから参照できます。
https://www.ranks.nl/stopwords
コピペしてstopwords.txtを作成し、以下のコードでリストを作成します。

```python
#ストップワードを読み込み、リストを作成
with open('stopwords.txt', 'r', encoding='utf-8') as f:
    stops = f.readlines()
stopwords = []
for s in stops:
    s = s.replace("\n", "")
    stopwords.append(s)
print(stopwords)
```

#文章をリストにまとめる
次に、Htmlフォルダ内の概要から以下の内容を抽出して、それぞれリスト化します。

* タイトル
* セッションNo.
* 作者
* 所属
* 本文

とりあえず以下のコードでやりました。

```python

#リストを定義
tags = []
contents = []
titles = []
auth = []
aff = []
session_num = []

#アブストラクトのpath一覧を取得
path = os.listdir("./Html")

#doc2vec解析用の行列を作成
for i in tqdm(path):
    soup = bs4.BeautifulSoup(open("./Html/"+i, encoding='utf-8'), "html5lib")
    
    #タイトル, 著者リスト, 所属を取得
    title =px.sub("", soup.title.string)
    author = px.sub("", str(soup('p')[1]))
    affiliation = px.sub("", str(soup('p')[2]))
    affiliation = affiliation.replace("a", "", 1)
    
    #発表番号, セッション名をタイトルから取得
    number = re.search('-[0-9]{4}', str(title))
    number = number.group().replace("-", "")
    session = re.match('.*[0-9]{2}', str(title))
    
    #タイトルからセッション名を削除
    title = re.sub('\w[0-9]{2}-[0-9]{4}', "", title)
    title = title.replace("\xa0","")
    
    #アブストラクト本文を取得, 整形。
    content = px.sub("", str(soup.find(class_=re.compile('contaner_content'))))
    stoplist = [",", ".", ":", ";", "(", ")", "{", "}", "[", "]", "\'", "\""]
    for i in stoplist:
        content = content.replace(i, "")
    content = content.replace("\t", "")
    c_list = content.split(" ")
    c_list = [i.lower() for i in c_list]
    for s in stopwords:
        c_list = [i for i in c_list if i != s]
    c_list = [c for c in c_list if c != ""]

    #リストへの追加
    tag = [title]
    tags.append(tag)
    contents.append(c_list)
        
    session_num.append(session.group())
    titles.append(title)
    auth.append(author)
    aff.append(affiliation)

```

汚いけど動くからよし！（思考停止）

#Doc2Vecで学習
まず、Doc2Vecに渡すためのリストを作成してから学習を行います。
それぞれの文章にはタグが必要なんですが、とりあえずそれは概要のタイトルにしてあります。

```python
#Doc2Vecで解析するための行列を作成
docs = []
for i in range(len(contents)):
    trainings = TaggedDocument(contents[i], tags[i])
    docs.append(trainings)

#doc2vecで学習
m = Doc2Vec(docs, dm=1, vector_size=300, window=5, min_count=5, workers=4, sample=1e-5, negative=5, epochs=600)

#学習データを保存
m.save("doc2vec_ECS232(600epoch).model")
```

うまく実行できると、同一ディレクトリに学習済みモデル(doc2vec_ECS232(600epoch).model)が保存されます。
サイズは40MBぐらいです。

#類似文書を検索する
次のコードで、概要集の中から指定したタイトルのアブストラクトと似た内容の発表を100個検索してみます。
抽出した発表の一覧はtest.csvに保存します。

```python
#保存したデータをロード
m = Doc2Vec.load('doc2vec_ECS232(600epoch)_ver.5.model')
#検出するアブストラクトの最大数
total_num = 100
#類似文書を検索したい文章のタイトルを入れる
text = m.docvecs.most_similar(['Understanding Electrolyte Remixing As a Capacity Fade Mitigation Technique for Vanadium Redox Flow Batteries'], topn=total_num)

t = []
s = []
n = []
authors = []
affiliations = []
for i in tqdm(text):
    t.append(i[0])
    s.append(i[1])
    for j in titles:
        C = titles.index(i[0])
        if(j == i[0]):
            n.append(session_num[C])
            authors.append(auth[C])
            affiliations.append(aff[C])
            

df = pd.DataFrame({'Number': n,
                   'Title' :  t,
                   'Authors' :  authors,
                   'Affiliation' :  affiliations,
                   'Similarity': s})
df.to_csv("test.csv")
```

#検索結果！

発表番号A01-0005を基準にして、これに似た内容の発表を検索してみます。

>Understanding Electrolyte Remixing As a Capacity Fade Mitigation Technique for Vanadium Redox Flow Batteries

アブストラクト本文は[こちら](http://ma.ecsdl.org/content/MA2017-02/1/5.abstract)。
発表の内容は、バナジウム系[レドックスフロー電池](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%89%E3%83%83%E3%82%AF%E3%82%B9%E3%83%BB%E3%83%95%E3%83%AD%E3%83%BC%E9%9B%BB%E6%B1%A0)に関する研究です。

出力したtest.csvの内容はこちら！

![table.png](https://qiita-image-store.s3.amazonaws.com/0/203101/daec6722-6043-e622-fc7f-cfbb2ccb7496.png)


赤字はざっと見て確認したレドックスフロー電池に関する発表です。
一番右端のSimilarityが発表番号A01-0005との類似度を示しています。

6位, 9位の発表はHydrogen-Vanadium Fuel Cellという、レドックスフロー電池と類似の構造を持つ燃料電池に関する発表です。
第7位の発表は電気化学反応における物質輸送の問題を論じたもので、レドックスフロー電池をトピックに含んでいます。
15位以内までは、かなりいい感じに抽出できている感じです！

が、16~18位の発表は全く関係がなさそうな内容ですね～。
まだまだ改良の余地はありそうです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/203101/7ffe96a8-01dd-56da-199c-605b260ccc44.png)

神経科学の発表がなぜ16,17位なのか……？

#まとめ
ECSのアブストラクト集から、Doc2Vecを使って類似文書の検索を行いました。
おおむねうまく動いたんじゃないかと思います。
(一部記号に文字化け等は残ってますが)

せっかくベクトル化したので、次は[t-sne](http://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html)とかを使って可視化も試してみたいですね。

学会はこれからも行くつもりなんで、ガンガン使っていこうと思います。
~~電池討論会はなぜ概要集をデータで配布しないのか。~~

ではでは～。