豪鬼メモ

一瞬千撃

英和辞書に田中コーパスの対訳例文を付与

統合英和辞書に対訳例文を付与した話。対訳コーパスを元にしたので、英語の例文だけではなく、その訳も読める。実際の用例とそこでの意味が把握できるようになったので、英作文やスピーキングの際により便利な辞書になった。


まずは実際に使ってみてほしい。「get carried away」の検索結果を見てみよう。訳語のリストから、「調子に乗る」という意味であることは理解できるが、実際にどんな文脈で、どんなニュアンスで使われ得るのかはそれだけでは分からない。そこで例文の方に目を移すと、「However if you get carried away you'll risk failure so take care!」(ただし、調子に乗ると失敗を招くので注意)と書いてある。この場合、日本語の「調子に乗る」とまさに同じで、「羽目を外す」とか「気持ちが高ぶって分別のないことをする」とかいう意味であろうことが把握できる。この見出し語は語義説明がないが、それでも大体の語義がわかる。むしろ、長ったらしい語義説明を読むより、例文を読む方がわかりやすいこともある。さらに次の例文に目を移すと、「She tends to get carried away when arguing about that matter.」(彼女はその問題を論じ始めると我を忘れてしまうことがある)と書いてある。この場合、調子こいてふざけているという悪い意味ではなく、真面目すぎて没頭してしまうという、中立的な意味で使うということがわかる。

「bottom」の例も見てみよう。訳語リストには「下部, 底部, 底, 底面, ボトム, 最下位, 根底, 船底, 底の, 基礎, 最下部, 基づく」とあるが、その中でも基本的な意味である「下部」「底部」「最下位」といった意味が例文で取り上げられ、さらに「尻」という意味もあることがわかる。そして、定冠詞「the」を伴って使うことが多いこともわかる。

止めに、「happy」と「fortunate」の例文を比較する。双方とも「幸せ」や「幸福」という意味を持ち、和英モードや類語モードで検索すると二つは並んで出てくる。語義説明を読んでも「幸せ」という意味のことが書いてある。しかし、使い方が微妙に違うのだ。「happy」は幸せになっている人に係り、「fortunate」は人を幸せにする物事に係る。例文を見るとそのことがよくわかる。単に訳語や語義だけを見てしまうと「I'm fortunate」みたいな使い方をするリスクがある。カジュアルな会話だったらそれでも伝わるからいいけど、正式な文書でやってしまうとちょっと恥ずかしい。

英語のリーディングやリスニングの補助として英和辞書を使う場合、そこで読んだり聞いたりした文が既に用例になっているので、辞書に例文が載っている必要はない。一方で、英語のライティングやスピーキングの補助として英和辞書を使う場合、これからその言葉を使った文を自分で作るので、模倣すべき例文があるのは重要だ。統合英和辞書は英文読解の役に立つことを最優先にしているが、英作文にも役立てたいとは思っていた。よって、例文を収録することにした。また、単に英語の例文があるよりも、日本語の対訳がついている例文の方が、ESL学習者にとっては圧倒的に理解しやすい。前回の記事で述べた類似検索によって未知の語句が探しやすくなったのはいいが、未知の語句を自分の言葉として使いこなすのは簡単ではなく、単に読解する以上の努力が必要になる。まずは例文をいくつか読んで、文法上の役割や、そこでの意味論を把握する必要がある。文法の理解は英文を読めばいいのだが、意味を理解するには対訳が便利だ。迂闊に未知の語を使うと、意味不明な表現になったり、ネガティブな印象を与えるリスクもあるので、訳文で意味が確認できることは安心につながる。

細かいUIの改良もした。語義が長い見出し語の場合には下の方に書いてある例文や関連フレーズを見るのにスクロールが必要で面倒だ。なので、見出し語の右上にフィルタ機能をつけた。「WN」「WE」「WJ」等のラベルは、それぞれWordNetの語義、Wiktionary-Englishの語義、Wiktionary-Japaneseの語義などを絞り込んで表示する。「例」は例文のみを表示し、「 句」は関連フレーズのみを表示する。もう一度押すとそれらは解除される。それぞれのラベルの有無で、その見出しに例文等が記載されているかどうかも一目でわかるようになっている。ちなみに、Shift+Backspaceボタンで検索フォームにフォーカスを戻すことができる。あと、これはブラウザの機能だが、Homeボタンでページ冒頭に飛び、Endボタンでページ末尾に飛べる。MacだとHomeボタンやEndボタンがないのだが、Fn+右やFn+左で代用できる。さらに言うと、VoiceOver等のスクリーンリーダー用に、Fn+左右で主要ラベル間を移動したり、Fn+上下で全ラベル間を移動したりするショートカットもある。詳しくはヘルプをご覧いただきたい。

以下、実装のうんちく。データソースとしては、田中コーパスを用いる。以前の記事で述べた対訳コーパスの索引を用いて、英和辞書と統合する。以下の手順だ。

  • 個々の見出し語において、原形とその屈折形(複数形、過去形など)をキーにして索引を調べる
  • 該当した文書IDの各々に対し、対訳文を取得する
  • 対訳文の各々にスコアをつけて昇順で並べる
    • 原形を含むものを優遇する。屈折形では、複数形と三単元形は高めに、比較級や最上級は低めにする。
    • 読みやすさを考えて、英文の長さが60文字に近く、訳文の長さが30文字に近いものを優遇する
    • 見出し語につけられた訳語を訳文に含むものを優遇する。同じ訳語はできるだけ使わない。
  • 類似した文を削除しつつ、スコアが高い対訳文の上位8件を採用する

田中コーパスは、規模が小さい割には日常語をよく網羅していてなかなか素晴らしいものだと個人的には思うのだが、たまに誤訳や重複がある。というか、どんな対訳コーパスでも重複や誤訳の問題は避けて通れないし、最近は機械翻訳の結果が混じって厄介だったりもするのだが、田中コーパスは人力で作られているのでかなりマシな方だ。とはいえ、それでも誤訳や重複には対処しなければならない。

対訳の中に辞書の訳語が含まれているものを優先することで、誤訳には対処できる。見出し語の訳語以外の部分に誤訳があると対処できないのだが、少なくとも見出し語がちゃんと訳されていれば問題ないだろう。統合英和辞書は訳語のリストが充実しているし、今回は日本語の活用のゆれなども加味して存在確認をしたので、そこそこの再現率で適切な対訳を拾えている。訳文を複数個拾う際に、同じ訳語を含むもののスコアを少し下げる処理も重要だ。そうすることで、多義語の各々の意味に対するカバレッジが向上する。

既に採用した英文と類似したものを採用しないことで重複には対処できる。類似性の判定には、語の単位の編集距離を使う。ある例文を採用するか判定するとして、その文と既に採用した例文との編集距離が、自身の語数と比較対象の語数の大きい方の半分より下回るものがある場合、その例文は採用しない。ほとんど一致しているものを捨てるのはもちろん、ちょっと似ている程度のものも躊躇せず捨てる。似た例文を何個も読んでも仕方ないからだ。

ところで、語の単位で編集距離を判定する作業を、文字単位の編集距離の関数を再利用することで簡略化して行うテクニックがある。文から単語のリストを取り出して、個々の語のハッシュ値から適当な文字に変換して、フィンガープリント的な文字列を生成する。あとはそのフィンガープリント同士を文字列の編集距離算出関数に渡して比較すればよい。TkrzwにはUtility.EditDistanceLevという、文字列のレーベンシュタイン編集距離を算出する関数があるので、それを使えば簡単だ。以下のような感じ。ちなみに、0xD800はサロゲートペアの最初の文字だが、サロゲート区間の文字があるとPythonが例外を出すので、変域をそれ未満に絞っている。

import re
import tkrzw

def MakeSentenceKey(text):
  text = re.sub(r"[^ A-Za-z0-9]", "", text)
  tokens = [x for x in text.split(" ") if x]
  chars = []
  for token in tokens:
    chars.append(chr(hash(token) % 0xD800))
  return "".join(chars)

def GetEditDistanceRatio(a, b):
  dist = tkrzw.Utility.EditDistanceLev(a, b)
  return dist / max(len(a), len(b))

def GetSentenceEditDistanceRatio(a, b):
  a_key = MakeSentenceKey(a)
  b_key = MakeSentenceKey(b)
  return GetEditDistanceRatio(a_key, b_key)

GetSentenceEditDistanceRatio(
  "I am John Doe from Tokyo.", "Hi, I am John Doe from Saitama.")
# -> 0.2857142857142857

GetSentenceEditDistanceRatio(
  "I am John Doe from Tokyo.", "Hi, You are Mic Smith from Saitama.")
# -> 0.8571428571428571

例文の有用性に慣れると、逆に例文のない語にあたるとがっかりするようになってしまった。田中コーパスだけだとカバレッジがいまいちな気もするので、パブリックドメインの対訳コーパスを他にも探してきてマージすることも考えている。誤訳回避と重複回避の実装が既にできているので、適当に混ぜてぶっこんでも大丈夫だろう。まあ、それでも面倒なので追々だ。おすすめがあったら教えていただきたい。

今の所、Kindle用の辞書には例文は載せない方針だ。例文は読解の際にもあって損はないので、本当は載せたいのだけれども、これ以上容量が増えるとKindle Previewerが落ちてしまうので仕方ない。そのバグが直ったら考える。

まとめ。統合英和辞書に例文を追加した。我ながらかなり便利になったと思う。やはり英作文の際には例文があると便利だ。適当な見出し語を検索して例文を読んでいくだけでも普通に楽しいので、試しに使ってみてほしい。