LoginSignup
9
3

More than 1 year has passed since last update.

Paper2Slack~英語論文のアブストを要約・翻訳してSlackへ~

Last updated at Posted at 2022-12-15

はじめに

今回は論文のAbstractを抽出し、要約・翻訳を施してSlackへ送るアプリをPythonで作成しました。Abstractは論文を要約していますが、チャットで共有するには少し長いですよね。これを使うことで論文共有がスムーズになるかと思います!
result

目次

  • 構成図
  • プログラム全体
  • Pythonによる実装
    1. PDFからAbstractを抽出
    2. Transformersによる要約
    3. DeepL APIによる翻訳
    4. SlackへPOST
  • 終わりに
  • 参考文献

構成図

app_design

プログラム全体

main.py
import os
import requests
from pdfminer.high_level import extract_text
from transformers import pipeline
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

### EXTRACT INFO FROM PDF ###
# Extract Abstract
text = extract_text("test_paper1.pdf") # ローカルPCにある対象の論文
text = text.replace("\n", "")
text = text[text.find("Abstract"):text.find("Introduction")]


### SUMMARIZATION ###
summarizer = pipeline("summarization")
response = summarizer(text, max_length=100, min_length=30, do_sample=False)
summarized_text = response[0]["summary_text"]


### TRANSLATE TEXT ###
# Settings
post_url = "https://api-free.deepl.com/v2/translate" # エンドポイント
api_key = "ご自身のAPI Key"
source_lang = "EN"
target_lang = "JA"

# Content
content = {
    "text":summarized_text,
    "auth_key":api_key,
    "source_lang":source_lang,
    "target_lang":target_lang
}
request = requests.post(post_url, data=content)
translated_text = request.json()["translations"][0]["text"] # レスポンスから翻訳済みテキストを取り出す

# Make return text
result = "【論文紹介】\n・要約\n" + summarized_text + "\n" + "・和訳\n" + translated_text


### POST TO SLACK ###
client = WebClient(token=os.environ['SLACK_BOT_TOKEN']) # 環境変数のTokenを渡す

try:
    filepath="test_paper1.pdf" # 自身のファイル
    response = client.files_upload(channels='#test', file=filepath, initial_comment=result) # 自身のチャンネル
    assert response["file"]  # the uploaded file
except SlackApiError as e:
    # You will get a SlackApiError if "ok" is False
    assert e.response["ok"] is False
    assert e.response["error"]  # str like 'invalid_auth', 'channel_not_found'
    print(f"Got an error: {e.response['error']}")

Pythonによる実装

では早速実装していきます。先に使用するライブラリをinstall/importしておきましょう。

main.py
import os
import requests
from pdfminer.high_level import extract_text
from transformers import pipeline
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

1. PDFからAbstractを抽出

まず、論文PDFからAbstractに該当する箇所を抽出していきましょう。
コードは以下の通りです。

main.py
### EXTRACT INFO FROM PDF ###
# Extract Abstract
text = extract_text("test_paper1.pdf") # ローカルPCにある対象の論文
text = text.replace("\n", "")
text = text[text.find("Abstract"):text.find("Introduction")]

まずpdfminerというライブラリのextract_textメソッドを使用することでPDF全体の文字データを取得します。次に、改行タグを削除しておきます。削除しておかないとその後のタスクで都合が悪いです。最後に、「Abstract」から「Introduction」までの文字列を抽出しています。

2. Transformersによる要約

次は抽出されたAbstractをさらに要約します。Hugging FaceのTransformersのパイプラインを使用して翻訳を行います。

main.py
### SUMMARIZATION ###
summarizer = pipeline("summarization")
response = summarizer(text, max_length=100, min_length=30, do_sample=False)
summarized_text = response[0]["summary_text"]

1~2行程度に要約してほしいので、30~100語の範囲を指定しました。

3. DeepL APIによる翻訳

翻訳にはDeepLのAPIを使用しました。アカウントを作成すれば、無料枠で月500,000文字まで翻訳可能です。Abstractだけを使えばそうそう使い切ることはないと思います。

main.py
### TRANSLATE TEXT ###
# Settings
post_url = "https://api-free.deepl.com/v2/translate" # エンドポイント
api_key = "ご自身のAPI Key"
source_lang = "EN"
target_lang = "JA"

# Content
content = {
    "text":summarized_text,
    "auth_key":api_key,
    "source_lang":source_lang,
    "target_lang":target_lang
}

request = requests.post(post_url, data=content)
translated_text = request.json()["translations"][0]["text"] # レスポンスから翻訳済みテキストを取り出す

# Make return text
result = "【論文紹介】\n・要約\n" + summarized_text + "\n" + "・和訳\n" + translated_text

アカウント登録するとご自身のAPI Keyが発行されますので、そちらを入力してください。

4. SlackへPOST

最後に要約・翻訳済みのAbstractをSlackへ投稿しましょう。まずは公式Documentに従い、投稿したいチャンネルにアプリを作成してください。途中環境変数の設定が必要になります。ファイルのアップロードのコードはGitHubのサンプルコードをそのまま真似しました。

main.py
### POST TO SLACK ###
client = WebClient(token=os.environ['SLACK_BOT_TOKEN']) # 環境変数のTokenを渡す

try:
    filepath="test_paper1.pdf" # 自身のファイル
    response = client.files_upload(channels='#test', file=filepath, initial_comment=result) # 自身のチャンネル
    assert response["file"]  # the uploaded file
except SlackApiError as e:
    # You will get a SlackApiError if "ok" is False
    assert e.response["ok"] is False
    assert e.response["error"]  # str like 'invalid_auth', 'channel_not_found'
    print(f"Got an error: {e.response['error']}")

おわりに

以上で完成です!
今後の課題としては、

  • 「Abstract」と「Introduction」に反応するようにしているため、「Summary」とかには対応できていない件

をどうにかしたいですね。

参考文献

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3