"BOKU"のITな日常

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

入力文章の誤字脱字や文法間違いをAIが指摘するデモを作る。「Proofreading API」を使う/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で実装します。

 

apido.py

 

ソース全文です。

import requests
import json
import re

class Apido:
    def __init__(self):
        self.key = 'XXXXXXXX'
        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.http.response import HttpResponse
from django.shortcuts import render, render_to_response
from django.contrib.staticfiles.templatetags.staticfiles import static
from . import forms
from django.template.context_processors import csrf
from . import apido

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

 

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

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

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

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

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

 

forms.py

 

from django import forms

class UserForm(forms.Form):
     textone = forms.CharField(label='元文章',max_length=500,min_length=1,widget=forms.Textarea(attrs={'id': 'commu','placeholder':'ここにチェックしたい文章を入力してください(500文字迄)。'}))

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

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

 

urls.py

 

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('demo/',views.demo,name='demo02'),
]

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

最後にHTMLです。

 

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

{% block header %}
<link rel="stylesheet" href="{% static "css/dj_talk.css" %}"></link>
{% 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.textone.label}}</h4></label>
    		<div class="col-lg-6">       
	            {{form.textone|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.png" %}" /></div> 
     			<div class="col-lg-6 card-text">       
	           		 {{ rets|safe }}
	        	</div> 
        	</div>
        	<div class="col-lg-2">       
	            <a href = "http://localhost:8000/demo/">クリア</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/demo

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

デモとしては上等ですね。

ではでは。