Flask, Sumy 및 Trafilatura를 사용한 텍스트 요약 API

17745 단어 pythonflaskwebdevnlp
텍스트 요약 API는 비용이 많이 들고 일관성이 없으며 부정확할 수 있습니다. 이 python 라이브러리를 사용하여 사용 사례에 맞게 사용자 정의하십시오.

API 작성



여러 요약 라이브러리를 실험한 후 sumy가 가장 정확하다는 것을 알았습니다. 새로운 텍스트가 생성되지 않습니다. sumy는 단순히 각 문장의 중요도에 점수를 매기고 상위 x개의 결과를 반환합니다. 기사의 첫 번째 단락은 일반적으로 페이지를 요약하려고 시도하기 때문에 모든 응답에 포함하고 싶었습니다.

sumy의 채점 시스템은 잘 작동하지만 기사 추출 메커니즘은 좋지 않습니다. 종종 댓글, 광고 및 관련 없는 하위 섹션을 이야기의 일부로 해석합니다. 관련 없는 문장은 점수가 매우 낮고 결과에서 제외되기 때문에 괜찮습니다. 일관되게 첫 번째 단락을 추출하고 이야기의 길이를 결정하려면 trafilatura가 훨씬 더 효과적입니다.

/url/끝점은 2개의 매개변수를 사용합니다. 즉, 0에서 1까지의 척도에서 요약의 URL과 상대 길이입니다./text/끝점은 긴 주석을 요약하는 데 유용한 URL 대신 일반 텍스트를 사용합니다. 이 가이드의 코드는 기본 템플릿일 뿐입니다. 보다 공식적인 API에는 인증, 오류 처리, 데이터베이스 연결 및 기타 기능이 포함됩니다.

import trafilatura
from sumy.parsers.html import HtmlParser
from sumy.parsers.plaintext import PlaintextParser
from sumy.nlp.tokenizers import Tokenizer
from sumy.summarizers.lsa import LsaSummarizer as Summarizer
from sumy.nlp.stemmers import Stemmer
from sumy.utils import get_stop_words
from flask import Flask, request, jsonify, Response
from ratelimit import limits
import nltk

nltk.download('punkt')

app = Flask(__name__)

@app.route('/url/', methods=['POST'])
@limits(calls=1, period=1)
def respond():    

    url = request.form.get("url", None)
    length = request.form.get("length", None)
    LANGUAGE = "english"
    parser = HtmlParser.from_url(url, Tokenizer(LANGUAGE))
    stemmer = Stemmer(LANGUAGE)
    summarizer = Summarizer(stemmer)
    summarizer.stop_words = get_stop_words(LANGUAGE)

    downloaded = trafilatura.fetch_url(url)
    y = trafilatura.process_record(downloaded, include_comments=False, include_tables=False, deduplicate=True, target_language="en", include_formatting=False)

    response = []

    if(y == None):        
        firstParagraph = ""
        l = len(parser.document.sentences)
        SENTENCES_COUNT = int(l*float(length))
    else:        
        firstParagraph = ""
        l = len(y.split("\n"))
        SENTENCES_COUNT = int(l*float(length))
        for p in y.split("\n"):
            if len(p) > 150:
                firstParagraph = p
                break

    if firstParagraph!="":
        response.append(firstParagraph+"\n\n")
    for sentence in summarizer(parser.document, SENTENCES_COUNT):
        if str(sentence) not in firstParagraph:
            response.append(str(sentence) + "  ")

    res = ""  

    for s in response:  
        res += s   

    return Response(res, mimetype="text/plain")


@app.route('/text/', methods=['POST'])
@limits(calls=1, period=1)
def respond_text():

    y = request.form.get("text", None)
    length = request.form.get("length", None)

    LANGUAGE = "english"
    parser = PlaintextParser.from_string(y,Tokenizer("english"))
    stemmer = Stemmer(LANGUAGE)
    summarizer = Summarizer(stemmer)
    summarizer.stop_words = get_stop_words(LANGUAGE)

    response = []
    l = len(y.split(". "))
    SENTENCES_COUNT = int(l*float(length))*2

    for sentence in summarizer(parser.document, SENTENCES_COUNT):
        response.append(str(sentence) + "  ")

    res = ""  

    for s in response:  
        res += s   

    return Response(res, mimetype="text/plain")



if __name__ == '__main__':

    app.run(threaded=True, port=5000)



전개



아래에 표시된 Procfile 및 requirements.txt와 함께 Heroku CLI를 사용하여 앱을 배포했습니다. Heroku 로그를 지침으로 사용하여 API를 로컬에서 실행하기 위해 파일을 여러 번 수정해야 했습니다. 이전에 Heroku에 배포한 적이 없다면 여기에서 방법을 읽을 수 있습니다.

trafilatura
flask
gunicorn
sumy
nltk
numpy
ratelimit



web: gunicorn app:app


API 호출 - https://text-summarize-api.herokuapp.com/url/?url=https://www.nature.com/articles/d41586-020-02706-6&length=0.3

결론



특히 유료 서비스에 통합하는 경우 기존의 많은 요약 API 중 하나를 구독하는 것이 더 나을 수 있습니다. 그러나 사용자 지정 API는 유사하거나 더 나은 성능을 제공할 수 있고 프로젝트에 맞게 사용자 지정할 수 있으며 소규모 규모에서는 완전히 무료라는 점을 명심하는 것이 중요합니다.

좋은 웹페이지 즐겨찾기