読者です 読者をやめる 読者になる 読者になる

さわだのノート

書籍のお仕事に役立つかもしれない思いつきを記録しています。

RSS: 記事の更新情報 Rss Feed

原稿を簡単に校正してくれるモジュールを書いた

Yahoo!デベロッパーネットワークの校正支援APIを使って文章を構成してくれるモジュールを自作してみました。
Yahoo!デベロッパーネットワーク - テキスト解析 - 校正支援

こちらがモジュールのスクリプト。

package Yahoo::Kosei;
use 5.12.3;
use warnings;
use utf8;
use URI;
use LWP::UserAgent;
use XML::XPath;

sub new {
  my $class = shift @_;
  my $uri = URI->new('http://jlp.yahooapis.jp/KouseiService/V1/kousei');
  my $agent = LWP::UserAgent->new;
  my $self = {
    uri     => $uri,
    agent   => $agent,
    last    => '',
    content => undef,
    xml     => undef,
  };
  bless $self => $class;
  return $self;
}

sub kousei {
  my ($self, $sentence) = @_;

  return unless $sentence;
  my $last = length $sentence;

  $self->set_sentence($sentence);
  my $xp = XML::XPath->new(xml => $self->xml);

  my $next = 0;
  my @list = ();
  for my $node ($xp->findnodes('//Result')) {
    my $start  = $node->find('StartPos')->string_value;
    my $length = $node->find('Length')->string_value;
    my $hash_rf = {
      start       => substr($sentence, $next, $start - $next),
      shusei      => substr($sentence, $start, $length),
      ShitekiInfo => '[' . $node->find('ShitekiInfo')->string_value,
      ShitekiWord => $node->find('ShitekiWord')->string_value ?
          ':' . $node->find('ShitekiWord')->string_value . ']' : ']',
    };
    push @list, $hash_rf;
    $next = $start + $length;
  }

  $self->content(\@list);
  $self->last(substr($sentence, $next, $last - $next));
  return [$self->content, $self->last];
}

sub content {
  my ($self, $content) = @_;
  $self->{content} = $content if $content;
  return $self->{content};
}

sub last {
  my ($self, $last_text) = @_;
  $self->{last} = $last_text if $last_text;
  return $self->{last};
}

sub xml {
  my ($self, $xml) = @_;
  $self->{xml} = $xml if $xml;
  return $self->{xml};
}

sub set_sentence {
  my ($self, $sentence) = @_;
  return unless $sentence;
  $self->__set_query($sentence);
  my $res = $self->__agent->get($self->__uri);
  die $res->status_line unless $res->is_success;
  $self->xml($res->decoded_content);
}

sub shiteki {
  my $self = shift @_;
  my $shiteki = '';
  for my $content (@{$self->content}){
    $shiteki .= $content->{$_} for qw/start shusei ShitekiInfo ShitekiWord/;
  }
  return $shiteki . $self->last;
}


sub __uri {
  return shift->{uri};
}

sub __agent {
  return shift->{agent};
}

sub __set_query {
  my ($self, $sentence) = @_;
  $self->__uri->query_form(
    appid    => 'please set your api app id!',
    sentence => $sentence,
  );
}

1;

こちらがモジュールを使った校正の実行スクリプト。

#!/usr/bin/env perl
use 5.12.3;
use warnings;
use utf8;
use open IO => qw/:utf8 :std/;

use Yahoo::Kosei;
my $sentence = '遙か彼方に小形飛行機が見える。'
my $kosei = Yahoo::Kosei->new;
$kosei->kousei($sentence);
print $kosei->shiteki;

実行結果はこちら。

遙か[表外漢字あり:●か]彼方[用字:彼方(かなた)]に小形飛行機[誤変換:小型飛行機]が見える。

[□□□□◆□□□□■]が指摘です。指摘が不要であれば、[]を削除していけばいいわけです。

Yahoo!校正APIは精度が今ひとつ

こんな感じで校正スクリプトは簡単に作れるのですが(実際には苦労しました)、この校正API、統一表記の設定ができないとか、助詞・他動詞の係り受けがうまく判定できないとか、精度が今ひとつなところもあります。

なんとか自分の基準に沿った校正機能を実装してみたいのですが、果たしてどうしたものなのやら。