ビジネスパーソン・ガジェット置場 empty lot for business

営業や仕事、それに伴う生活を便利に楽にするツール、ガジェットを作ります。既にあるツールも自分用にカスタマイズ。

文章要約アプリ【python + spacy】

今回のガジェットはこういう声に対応します。

「長い文章は読んでて意味が分からなくなる。すぐに頭に入ってくるようにシュッと短く簡単にまとめてくれないかな。」

f:id:kslabo51:20220321152631j:plain

streamlitで文章要約アプリを作成

長い文章をシュッとまとめ分かりやすく要約するガジェットです。要約の方法は抽出型で、与えられた文章を短くまとめてくれます。UIとしてstreamlitを利用しファイルのアップロードから要約までを画面で表記し操作しやすくしています。

 

f:id:kslabo51:20220321152729p:plain

このガジェットでできることはこちら

  • 要約したいテキストファイルを簡単アップロード
  • 何行に要約したいか選択(3~10行)
  • アルゴリズム選択(6種類)
  • 元の文章、要約結果の表示

注意点はこちら

  • spaCy上で日本語ドキュメントを処理するライブラリ 要約結果については何行に要約するかによってブレ等あります

評価(自己)

役立ち度   ★★★★(良し)
効率化    ★★★★(良し)
ミス防止   ★★★(平均)
楽しさ    ★★★★(良し)
操作性    ★★★★(良し)

 

実行環境

使用環境    streamlit
使用言語     python
使用ライブラリ  spacy、sumy.parsers.plaintext、sumy.nlp.tokenizers、sumy.summarizers.lex_rank、sumy.summarizers.lsa、sumy.summarizers.reduction、sumy.summarizers.luhn、summarizers.sum_basic

 

今回はstreamlit以外は下記の方の記事を超参考にしています(ほぼいただいて。。)

長文テキストを自動要約しよう(その1)~sumy~ - Qiita

sumy で要約(spaCy、GiNZA) を試してみた: Pythonで自然言語処理にフリーライド - はてだBlog(仮称)

import spacy
import streamlit as st
from sumy.parsers.plaintext import PlaintextParser
from sumy.nlp.tokenizers import Tokenizer
from sumy.summarizers.lex_rank import LexRankSummarizer
from sumy.summarizers.lsa import LsaSummarizer
from sumy.summarizers.reduction import ReductionSummarizer
from sumy.summarizers.luhn import LuhnSummarizer
from sumy.summarizers.sum_basic import SumBasicSummarizer
from sumy.summarizers.kl import KLSummarizer

# 変数定義
nlp = spacy.load('ja_ginza_electra')
parser = None
input_data = None

# 要約の準備をする関数
def exe_summary(input_data):
    document = ''.join(input_data).replace(' ', '').replace(' ', '').replace('\n', '')

    
    corpus = []
    originals = []
    doc = nlp(document)

    # spaCyは、「sents」で文のジェネレータを戻す
    for s in doc.sents:
        originals.append(s)
        tokens = []
        # レンマ化したトークンを追加
        for t in s:
            tokens.append(t.lemma_)
        corpus.append(' '.join(tokens))

    parser = PlaintextParser.from_string(''.join(corpus), Tokenizer('japanese'))
    
    return parser, originals, corpus

# 要約用のアルゴリズムを実行する
def summarize(summarizer, parser, originals, corpus):
    result = summarizer(document=parser.document, sentences_count=sentences)
    for sentence in result:
        st.write(originals[corpus.index(sentence.__str__())])

# インターフェイスの表示        
st.title('文章要約アプリ')

# ファイル選択
st.write('### 要約ファイル選択')
uploaded_file = st.file_uploader('テキストファイルをアップロードしてください。', ['txt'])

if uploaded_file is not None:
    content = uploaded_file.read()
    input_data = content.decode()
    
if input_data is not None:
    st.write(input_data)

# 要約結果の行数を表示
st.write('### 要約結果行数選択')
sentences = st.slider('何行に要約しますか', 3, 10, 5)

# 要約実行関数を呼び出し
st.write('### 要約実行')
algori = st.selectbox(
        '要約アルゴリズムを選択してください',
        ("LexRank", "Lsa", "Reduction", "Luhn", "SumBasic")
    )
st.write('要約を開始しますか?')
if st.button('開始'):  
    parser, originals, corpus = exe_summary(input_data)

# 要約を実行し結果の表示
if parser is not None:
    st.write('### 結果の表示')
    if algori == "LexRank":
        summarize(LexRankSummarizer(), parser, originals, corpus)
    elif algori == "Lsa":
        summarize(LsaSummarizer(), parser, originals, corpus)
    elif algori == "Reduction":
        summarize(ReductionSummarizer(), parser, originals, corpus)
    elif algori == "Luhn":
        summarize(LuhnSummarizer(), parser, originals, corpus)
    else:
        summarize(SumBasicSummarizer(), parser, originals, corpus)