"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

A3RTの「Proofreading API」で入力文の疑わしい部分をAIが指摘するデモを作る。/python+django2.0+bootstrap4

今回は、入力した文章の疑わしい部分を指摘するデモ画面を作ってみます。

疑わしい部分とは、「誤字の可能性が高い部分、誤字では無いが珍しい使い方、他により良い表現がありそうな部分等」です。

f:id:arakan_no_boku:20190320212948j:plain

 

この記事の前提

 

djangoのインストール・設定や、bootstrapを使うための設定などは、以下で説明している内容を前提にしています。

不明点があれば、以下も参照ください。

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

 

疑わしい部分のチェックは 「Proofreading API」を使う

 

リクルートのA3RTで提供されている「Proofreading API」を使います。

a3rt.recruit-tech.co.jp

概要を引用します。

Proofreading APIはLSTMを利用して文章として怪しい箇所を検知するAPIです。
例えば、"経験や資格や活かせる職場です"という文章に対して"経験や資格<<<や>>活かせる職場です"という形で不自然な箇所を指摘し、その怪しさ度を返します。また、文章として書き換えた方が良さそうな単語も検知をします。
今回提供するモデルでは求人系の文章を学習データとしているため、是非近いドメインの文章をインプットにして試してみてください。

まず。

API KEYを取得して使う準備をします。

f:id:arakan_no_boku:20190325221935j:plain

説明ページの最下部にある、このボタンを押して、メールアドレスを登録して指示に従うだけなので、簡単に取得はできます。

 

まずはデモ画面のイメージ

 

初期画面は テキストエリアに文章を入力して「送信する」ボタンを押すだけの画面です。

f:id:arakan_no_boku:20190325223749j:plain

そして、文章を入力して「送信する」を押した結果画面のイメージはこんな感じ。

f:id:arakan_no_boku:20190325231403j:plain


本来なら「幹事長」のところで、「漢字」という誤字が検出されて、ハイライト+赤字になっています。

これを見ながら、文章を修正して、最終的にこうなればOKです。

f:id:arakan_no_boku:20190325225126j:plain

 

ソースコードです

 

最初にAPIを利用して、チェック結果を返すクラスをPythonで実装します。

 

typo_v2.py

 

ソース全文です。

import requests
import json
import re


class TypoV2:
    def __init__(self):
        self.key = 'DZZgwYoI0GN6R4CaLqOJagTNdAzXb01r'
        self.api = 'https://api.a3rt.recruit-tech.co.jp/proofreading/v2/typo'

    def get(self, inputtext):
        url = self.api
        quoted_text = inputtext
        r = requests.post(url,
                          {'apikey': self.key,
                           'sentence': quoted_text,
                           'sensitivity': 'medium'})
        data = json.loads(r.text)
        rets = []
        if data['status'] == 1:
            rets = '疑わしい部分と判定した箇所あります。</br>ハイライトされた箇所を確認してください。</br><hr>'
            text = data['checkedSentence']
            rets = rets + self.__trans_word(text)
        elif data['status'] == 0:
            rets = "この文章に誤字脱字はありません。</br>指摘すべき修正を見つけられませんでした。"
        else:
            rets = "エラーがありました。</br>応答コードは" + data['status'] + "です。"
        return rets

    def __trans_word(self, inputtext):
        replacements = {
            '<<': '<span class="mark font-weight-bold text-danger">',
            '>>': '</span>'}
        return re.sub('({})'.format('|'.join(map(
            re.escape, replacements.keys()))), lambda m: replacements[m.group()], inputtext)

補足します。

self.key = 'XXXXXXXX' 

この「XXXXXXXX」の部分には、取得したAPIキーを入力します。

r = requests.post(url,{'apikey':self.key,'sentence':quoted_text,'sensitivity':'medium'})

 ここで、オプションを指定して指定URLにリクエストを投げて、結果を「r」に受け取ります。

文章に指摘事項があれば「data['status'] == 1」になるので、その場合のみ以下で指摘点を<<文字>>でマーキングされた文章を「checkedSentence」をキーにして取得し、<<>>の部分を、ハイライト表示のHTMLタグとクラスに置き換えます。

text = data['checkedSentence']

rets = rets + self.__trans_word(text)

置換を行う 「__trans_word()」関数の構文は少々特殊です。

以下の記事で詳しく説明しているので、わからない場合は参照ください。

arakan-pgm-ai.hatenablog.com

 

views.py

 

from django.shortcuts import render
from . import forms
from django.template.context_processors import csrf
from .tf20 import vgg16_imagenet as cl
from . import typo_v2 as t2


def proofread(request):
    api = t2.TypoV2()
    if request.method == 'POST':
        # テキストボックスに入力されたメッセージ
        input_text = request.POST['areatwo']
        # APIリクエストを投げてからの応答を取得
        rets = api.get(input_text)
        form = forms.UserForm(initial={'areatwo': input_text})
        c = {
            'form': form,
            'areatwo': input_text,
            'rets': rets
        }
    else:
        # 初期表示の時にセッションもクリアする
        request.session.clear()
        # フォームの初期化
        form = forms.UserForm(label_suffix=':')
        rets = '''入力されたテキストで文法的に疑わしい部分を指摘します。
                疑わしい部分とは以下のような部分です。
                ・誤字の可能性が高い部分。
                ・誤字では無いが珍しい使い方。
                ・他により良い表現がありそうな部分。'''
        c = {'form': form,
             'rets': rets
             }
    c.update(csrf(request))
    return render(request, 'typo.html', c)

 

ソースのポイントは初期表示時と、再表示(入力して送信するボタンを押した後)で、formの生成パラメータが異なるところです。

再表示時はこうなってます。

 form = forms.UserForm(initial={'areatwo': input_text})

initialを使って、forms.pyで「areatwo」で定義するフィールドに、レスポンスで受け取った入力内容を初期値として渡してます。

こうしないと、再表示した時に入力内容は引き継がれません。

 

forms.py

 

   areatwo = forms.CharField(
        label='元文章',
        max_length=500,
        min_length=1,
        widget=forms.Textarea(
            attrs={
                'id': 'typov2',
                'placeholder': 'ここにチェックしたい文章を入力してください(500文字迄)。',
                'rows': 10,
                'cols': 5,
            }))

APIの制限が500文字までなので、ここでチェックをかけてます。

一応、ガイドとしてplaceholderも設定してます。 

 

urls.py

 

from django.contrib import admin
from django.urls import path
from . import views, hello

urlpatterns = [
    path('admin/', admin.site.urls),
    path('demo03/', views.proofread, name='typo'),
]

/demo03で初期画面を表示します。  

最後にHTMLです。

 

typo.html
{% extends 'base.html' %}
{% load static %}
{% load bootstrap4 %}
{% load widget_tweaks %}

{% block header %}

{% endblock %}

{% block title %}
  文章チェック
{% endblock %}

{% block content %}
<div class="container">

    <form action="" method="post">{% csrf_token %}
        <h1>文章チェック</h1>
        <div class="form-group row my-4">         
            <label class="col-lg-2 col-form-label"><h4>{{form.areatwo.label}}</h4></label>
    		<div class="col-lg-6">       
	            {{form.areatwo|add_class:"form-control"}}
    		</div>
    		<div class="col-lg-2">       
	            <button type="submit" class="btn btn-primary">送信する</button>
    		</div>
        </div>
     </form>
     <div id="resultarea">
        <div class="row my-4">         
	       	<div class="col-lg-2"><img src="{% static "images/k_boy.png" %}" /></div> 
     			<div class="col-lg-6 card-text">       
	           		 {{ rets|safe }}
	        	</div> 
        	</div>
        	<div class="col-lg-2">       
	            <a href = "{% url 'typo' %}>クリア</a>
    		</div>
     </div>
 </div>  
{% endblock %}

HTMLのCSSは、Bootstrap4を使ってます。

base.htmlでテンプレートを定義して、それを使ってます。

base.htmlについてはこちらに書いてますので、確認が必要な場合は参照ください。 

arakan-pgm-ai.hatenablog.com

python側でハイライト表示のために、HTMLタグ付きで編集しているため、エスケープさせないように「 {{ rets|safe }}」のように「safe」付きで参照しています。

こんな感じですかね。

 

実行

 

例によって、このプロジェクトのmanage.pyのあるフォルダをカレントにして、コマンドプロンプト等で以下のように実行します。

python manage.py runserver

あとは、 urls.pyの設定にそってURLをたたきます。

デフォルトだと、こんな感じになるはずです。

http://localhost:8000/demo03

自分で試してみた感じだと、わりと良い感じで誤字や文法違いを拾ってくれます。

デモとしては上等です。

ではでは。