プログマのプログラマ日記

技術メモや自社サービスに関する記事を書いていく予定です。

ユーザが入力した過去形の動詞から、動詞の語幹と活用形を推定する方法について

概要

ゲーム「いつどこ語り」の開発過程で、以下の課題を解決する必要に迫られた。

ユーザが入力した「何をした」の動詞から、動詞の語幹と活用形(※)を推定したい。

※例えば、「走った」のような言葉から、語幹は「走」で、活用は「ラ行五段活用」であると推定する。

現実的に実装可能な範囲で、かつ、ユーザにもそれほど負担をかけない方法を検討した結果、ユーザが

「野球した」

のような言葉を入力したときに、ユーザに対して

以下の文章で違和感がないのはどちらですか?
□僕は「野球」した
□僕は「野球」さなかった

のような補足の問いかけをすることで、動詞の語幹および活用形を(だいたい)推定できることが分かった。 (上記の問いかけで、入力した動詞がサ行五段活用か不規則動詞「した」かを切り分けることが可能)

以下詳細。

問題の背景

ゲーム「いつどこ語り」には、ユーザが入力した言葉で短文を作るモードと、長文を作るモードがある。
ユーザには、言葉を「いつ」「どこで」「誰」「何をした」の形式で入力してもらう。
短文を作るモードでは、入力された言葉をそのまま

「いつ」「どこで」「誰」が「何をした」

の形で出力するため、出来上がった文章に違和感が生じるケースは少ない。

例)

「今日」「空き地で」「ジャイアン」が「歌った」  

一方、長文を作るモードでは、これらのことばを文章用のテンプレートに埋め込んでいくことで文章を作っていく。
例えば、以下のようなテンプレートに「いつ」「どこで」「誰」「何をした」を埋めていくイメージ。

[(誰)]くんの日課は、毎週日曜日に[(どこで)][(何をした)]ことなんですよ。
...

ここでちょっと問題が生じる。
ユーザがいれたことばを、このままテンプレートに埋め込んでいくと、

「ジャイアン」くんの日課は、毎週日曜日に「空地で」「歌った」ことなんですよ。

のように、文章に違和感が生じてしまう。
これを

「ジャイアン」くんの日課は、毎週日曜日に「空地で」「歌う」ことなんですよ。

のように、違和感がない形で埋め込みたい。
そのためには、「歌った」のことばを「歌う」の形に活用してあげる必要がある。
つまり、文章の中に適切な形に「何をした」を埋め込むためには、ことばの登録時に動詞の語幹・活用形も判別し、一緒に保持しておく必要がある。
これが今回の課題。

方針の検討

検討の過程を時系列で説明する。

ユーザには負担をかけたくない

言葉の入力時にユーザーに

「この動詞の語幹と活用形も一緒に入力してください」  

のように問いかけることができれば確実だが、それは避けたい
(そんなめんどくさいアプリ誰も遊んでくれないので)

辞書はつまない

アプリ内部に動詞の辞書を組み込むという手も考えられるが、それは手間なのでやりたくなかった。
※辞書を使わないで実装したほうが面白そうというのが本音

ほどほどをめざす

「完璧なものはできないだろうな」という予感があるので、入力された動詞すべてに対応しようとは考えないことにする。
(多少違和感が生じるケースがあっても許容。そもそもデタラメな文章を楽しむ趣旨のアプリなので、それくらいは許してね、というスタンスで行く)

ユーザが入力した動詞は過去形であると仮定する

ユーザには「何をした」の部分を入力してもらうことになるので、ほとんどの場合、動詞は過去形で入ってくるはず。
(そうじゃないケースもあるだろうが、過去形以外は今回は切り捨てることにした。)

過去形から活用形を1:1で特定するのは無理

例えば、過去形が「った」で終わる動詞は

  • 勝った -> 勝つ(カ行五段)
  • 走った -> 走る(ラ行五段)
  • 買った -> 買う(ア行五段) のように3パターンがある。
    つまり、動詞の語尾が「った」で終わった時点で活用形が一つに絞るこむことができない。
    動詞の語尾からある程度推定するにしても、全くヒントがない状態で語幹と活用形を推定するのは厳しそう。

逆に言えば、ここでヒントをもらえたら?...

例えばユーザが「勝った」と入力したときに

以下の文章で、最も違和感がないものを選んでください
□僕は「勝たない」 → これがYesなら「カ行五段」と判定
□僕は「勝らない」 → これがYesなら「ラ行五段」と判定
□僕は「勝わない」 → これがYesなら「ア行五段」と判定

のような問いかけをすれば、それほどユーザにも負担をかけずに活用形を推定できるのではないか?

というわけで、動詞の語尾をもとに、語幹と活用を特定できるチャートを作ることは可能か?を、以下で検討していくことにした。

用語の整理

ここでいったん、用語の整理。

語幹

ざっくり理解:活用しても変化しない部分。
だけど、言語学と学校文法で定義が異なっているらしい。
学校文法の場合は、仮名単位で考える一方で、言語学ではローマ字単位で考える。 例えば、動詞「歩く(あるく)」の場合、以下の太字部分が語幹になる。

  • カナ単位 ... あるかない/あるきます/あるく/あるけば/あるこう (「ある」が語幹)
  • ローマ単位 ... arukanai/arukimasu/aruku/arukeba/arukou (「aruk」が語幹)

詳細は以下参照: 語幹 - Wikipedia
語幹 - ウィクショナリー日本語版

活用語尾

活用したときに変化する部分。

活用の種類別の動詞の分類

自分は学校で「五段活用」「上一段活用」「下一段活用」のような言葉で習ったが、言語学とか外国人向けの日本語教育の場では別な言い方をすることが多いようだ。

母音語幹動詞( = 上一段活用動詞, 下一段活用動詞, u-verbs, Group I verbs)

  • 語幹(ローマ字のほう?)が母音で終わる
  • 上一段活用・下一段活用する。
  • 「ru-verbs」とも呼ばれる(基本形が「ru」で終わることから)
  • Group I verbsとも呼ばれる
  • このグループに属する動詞の例:起きる(カ行上一段)、見せる(サ行下一段), 耐える(ア行下一段),

子音語幹動詞(五段活用動詞, u-verbs)

  • 語幹(ローマ字のほう?)が子音で終わる。
  • これらの動詞は五段活用する。
  • 「u-verbs」とも呼ばれる(基本形が「u」で終わることから)
  • Group I verbsとも呼ばれる
  • このグループに属する動詞の例:話す, 飛ぶ, 暴れる, 思い出す

不規則動詞

  • 「する」(サ行変格活用)「来る」(カ行変格活用)だけ。

※「勉強した」とか「野球した」とか、全部不規則動詞「する」に属するので「する」は最重要動詞かも。

敬体

いわゆる、ですます調。
過去形の入力で「~ました。」で終わるケースを想定する必要がある。

活用形

例えば、「書く」を活用させると以下の通り。

  • 未然形(書か ナイ、書こ ウ)
  • 連用形(書き マス)
  • 終止形(書く
  • 連体形(書く トキ)
  • 仮定形(書けバ)
  • 命令形(書け

参考:
動詞の五段活用と音便をマスターしよう - 国語の文法(口語文法)

過去形はどうやって作られる?

連用形 + 「タ」(ただし、五段活用時は「音便」を考慮する必要がある)

「タ形」という言い方もあるらしい。
「タ」は、過去の助動詞(完了とか存続の意味もある)。
ただし単純につなげると、赤字のところに違和感が。。

  • 貸す(サ行五段):貸し + タ →貸した
  • 起きる(カ行上一段段):起き + タ →起きた
  • 耐える(ア行下一段段):耐え + タ →耐えた
  • 書く(カ行五段):書き + タ → 書
  • 走る(ラ行五段):走り + タ → 走

五段活用動詞の場合、「連用形 + タ」だと発音しにくいので活用語尾が変化するケースがある。これを「音便」という。
音便の種類は以下の3種類。

  • イ音便(書きた→書いた)
  • 撥音便(死にだ→死んだ)
  • 促音便(勝ちた→勝った)

「った」「んだ」「いた」「いだ」で終わる動詞が来たときは音便を考慮する必要がありそう。

五段活用と音便の解説:
動詞の五段活用と音便をマスターしよう - 国語の文法(口語文法)

助動詞「た(だ)」の解説
助動詞「た(だ)」をマスターしよう - 国語の文法(口語文法)

連用形 + 「まし」 + 「タ」

「まし」というのは、丁寧の助動詞「ます」の連用形。
(音便は考慮しなくてよい)

  • 貸す(サ行五段):貸し + まし + タ →貸しました
  • 起きる(カ行上一段段):起き + まし + タ →起きました
  • 耐える(ア行下一段段):耐え + まし + タ →耐えました
  • 書く(カ行五段):書き + まし + タ → 書きました
  • 走る(ラ行五段):走り + まし + タ → 走りました

助動詞「ます」の解説

助動詞「ます」をマスターしよう - 国語の文法(口語文法)

過去形からの活用形推定チャート(詳細設計)

上記のまとめとして、ユーザが入力したことば(過去形)から、活用形を推定する流れを整理した。
ユーザとシステムのやり取りは以下の2パターン:

入出力

追加の質問が必要ないケース

  1. input ... ユーザが入力した言葉
  2. output ... 語幹と活用系

追加の質問が必要ないケース

  1. input1 ... ユーザが入力した言葉
  2. output1 ... 活用形を特定するための追加の質問(n個の文章から最も適切なものを一つを選んでもらう形式)
  3. input2 ... ユーザの2への回答
  4. output2 ... 語幹と活用系

チェックリスト(1から順番に判定)

1. 語尾が「xxxった」で終わる

以下のケースを切り分ける必要がある。

  • 「タ行五段」(勝つ)
  • 「ラ行五段」(走る)
  • 「ア行五段」(買う)

質問に以下の文章を追加してユーザに提示する。

  • 「xxx」たなかった。 → 選ばれたら語幹は「xxx」で活用は「タ行五段」
  • 「xxx」らなかった。 → 選ばれたら語幹は「xxx」で活用は「ラ行五段」
  • 「xxx」わなかった。 → 選ばれたら語幹は「xxx」で活用は「ア行五段」

※ユーザに答えてもらったら処理終了

2. 語尾が「んだ」で終わる

以下のケースを切り分ける必要がある。

  • 「ナ行五段」(死ぬ)
  • 「マ行五段」(読む)
  • 「バ行五段」(学ぶ)

質問に以下の文章を追加してユーザに提示する。

  • 「xxx」ななかった。 → 選ばれたら語幹は「xxx」で活用は「ナ行五段」
  • 「xxx」まなかった。 → 選ばれたら語幹は「xxx」で活用は「マ行五段」
  • 「xxx」ばなかった。 → 選ばれたら語幹は「xxx」で活用は「バ行五段」

※ユーザに答えてもらったら処理終了

3. 語尾が「xxxいた」で終わる

以下のケースを切り分ける必要がある。

  • 「カ行五段」(書く)
  • 「ア行上一段」(老いた)

質問に以下の文章を追加してユーザに提示する。

  • 「xxx」かなかった。 → 選ばれたら語幹は「xxx」で活用は「カ行五段」
  • 「xxx」いなかった。 → 選ばれたら語幹は「xxx」で活用は「ア行上一段」

※ユーザに答えてもらったら処理終了

4. 語尾が「xxxいだ」で終わる

以下のケースをのみ?

  • 「グ行五段」(泳いだ)

※ユーザに質問は提示せずに処理終了(語幹は「xxx」で活用は「グ行五段」とする。)

5. 語尾が「xxx来た」「xxxきた」で終わる

「xxx来た」の場合はその時点で「カ行変格」と判定する。
「xxxきた」の場合は以下のケースを切り分ける必要がある。

  • 「カ行変格」(来たのひらがな)
  • 「カ行上一段」(起きた)

質問に以下の文章を追加する。

  • 「xxx」こない。 → 選ばれたら語幹は「xxx」で活用は 「カ行変格」
  • 「xxx」きない。 → 選ばれたら語幹は「xxxき」で活用は「カ行上一段」

※ユーザに答えてもらったら処理終了

6. 語尾が「xxxました」で終わる

以下のケースを切り分ける必要がある。

  • 「xxxま」 +「した」(おいとました, けんだました, のように「サ行変格」の連用形がたまたま「まし」で終わっているケース)
  • 「xxx」 + 「ました」(食べました, のように「何かの動詞の連用形」+「まし」+「タ」のケース)

質問に以下の文章を追加する。

  • 僕は「xxxま」しませんでした。 → 選ばれたら語幹は「xxxま」で活用は「サ行変格」

※まだユーザに質問は提示せずに、後ろの処理を続行。
このとき、入力を「xxxました」から「xxxた」に変更する。

7. 語尾が「xxxした」で終わる

以下のケースを切り分ける必要がある。

  • 「サ行変格」(女子会した,将棋した)
  • 「サ行五段」(正体を現した)

質問に以下の文章を追加してユーザに提示する。

  • 「xxx」しなかった。 → 選ばれたら語幹は「xxxま」で活用は「サ行変格」
  • 「xxx」さなかった。 → 選ばれたら語幹は「xxxま」で活用は「サ行変格」

※ユーザに答えてもらったら処理終了

8. 語尾が「xxxた」で終わる

以下のケースを切り分ける必要がある。

  • 「?行五段活用」
  • 「?行上一段活用」(老いる, 起きる, 閉じる)
  • 「?行下一段活用」(見える, 混ぜる, 寝る, 食べる)

質問に以下の文章を追加してユーザに提示する。

  • 「xx」[xa(*)]なかった。 → 選ばれたら語幹は「xxx」で活用は「[xa]行五段」
  • 「xx」[xi(*)]なかった。 → 選ばれたら語幹は「xxx」で活用は「[xa]行上一段」
  • 「xx」[xe(*)]なかった。 → 選ばれたら語幹は「xxx」で活用は「[xa]行下一段」

*) 「xxx」部分の最後の1文字の母音をa, i, eに変えた文字。
例) 老いたの場合[xa]は「あ」になる。

※ユーザに答えてもらったら処理終了

8. 上記どれにも当てはまらない場合

推定をあきらめる。

実装

実装中にいくつか、設計漏れが判明した。例えば

  • 語幹と活用語尾が一致している動詞の扱い(見る、着る、似る、など)
  • 「~した」だけじゃなく「~をした」も判定する必要があった

など。

宣伝

最後に宣伝。「いつどこ語り」は、以下のサイトからダウンロードできます。

AppStore:

いつどこ語り

いつどこ語り

  • PUROGUMA, K.K.
  • ゲーム
  • 無料
apps.apple.com

サポートURL:
prgm.co.jp