映画等の字幕の対訳を集めてコーパスにしたJESC(Japanese-English Subtitle Corpus)から抽出した対訳文を、英和辞書の例文として付与した。クリーンアップやフィルタの面倒だった話をメモ。
JESCの公式ページに書いてあるが、スタンフォード大学やらが279万個の字幕文とその対訳を収集してコーパスとして公開している。データはTSVファイルなので、扱うのも簡単だ。ただ、字幕なので、意訳、省略、追加が激しいのと、アラインメントがずれがちなので、そのまま辞書の例文として使うには厳しい。適切なものをだけを選択するフィルタを書かなければならない。また、なぜか英文が全て小文字に正規化されているので、文頭や固有名詞等は適宜大文字に復元しなければならない。
まず、大文字の復元について考える。文頭を大文字にするのは簡単だが、固有名詞の判断はアルゴリズミックにはできない。なので、辞書から固有名詞っぽいフレーズを抽出しておいて、4-gramまでの最左最長一致で照合をかけることにした。個々の語句について出現率を数えるとともに、Wikipediaコーパス内にどの形式(キャピタライズ、全部大文字、全部小文字など)で現れるかの確率も計算した。まあ数えただけなんだけども。このTSVファイルにまとめてある。以下に例を示す。
I 0.820 0.0542228 Wikipedia 1.000 0.0093315 American 1.000 0.0071635 I'd 1.000 0.0054223 I'll 1.000 0.0054223 I'm 1.000 0.0054223 I've 1.000 0.0054223 UK 1.000 0.0047939 British 1.000 0.0043572 I think 1.000 0.0042197 European 1.000 0.0038757 June 1.000 0.0038128 January 1.000 0.0037441 September 1.000 0.0037051 Japanese 1.000 0.0036846
第1列はその語の文字列、第2列はそのスペルのその形式での出現率、第3列はそのスペルの形式を問わない文中での出現率である。順序は第2列*第3列でソートしてある。例えば、「I」や「i」は最も出現しやすい大文字を含む後であり、任意の文に5.4%の確率で出現し、そのうち82%は「I」という形になっているということがわかる。大文字を含む形式の確率が0.6を超えたものは、固有名詞もしくは英文においてキャピタライズで表現すべきユニーク性を持った言葉だとみなせる。「May」(5月)と「may」(かもしれない)とか、「March」(3月)と「march」(行進)とか、「Polish」(ポーランドの)と「polish」(磨く)とかいった同級語は出現確率だけではうまく扱えないけれど、多くの語はこれでうまくいく。「Americans」「Koreans」などの複数形にも対応している。
上記のTSVファイルを読み込んだ上で、該当する語を大文字に変換する関数を実装した。文頭にあたる語の最初の文字も大文字にする。
import re def ReadCapitalWords(path): capital_words = {} with open(path) as input_file: for line in input_file: fields = line.strip().split("\t") if len(fields) != 3: continue word, share, score = fields capital_words[word.lower()] = word return capital_words def RestoreSource(text): tokens = re.split('([ "!?,.]+)', text) result = [] start_index = 0 head = True while start_index < len(tokens): end_index = min(start_index + 7, len(tokens)) hit = False while end_index >= 0: phrase = "".join(tokens[start_index:end_index]) capital = capital_words.get(phrase) if capital: result.append(capital) start_index = end_index hit = True break end_index -= 1 if hit: head = False else: token = tokens[start_index] match = re.search(r"^([A-Za-z]+)'(s|d|ve|ll)$", token) if match: capital = capital_words.get(match.group(1)) if capital: token = capital + "'" + match.group(2) if head and re.search(r"^[A-Za-z]", token): token = token[0].upper() + token[1:] head = False elif re.search(r"[.?!] ", token): head = True result.append(token) start_index += 1 text = "".join(result) text = re.sub(r"\s+", " ", text).strip() text = re.sub(r"([a-zA-Z]) ([.!?])", r"\1\2", text) return text capital_words = ReadCapitalWords("capital_words.tsv") RestoreSource("i work for bank of japan from july.") # -> "I work for Bank of Japan from July." RestoreSource("does he live in the united states of america?") # -> "Does he live in the United States of America?"
マイナーな人名とか地名とかはそもそも辞書に載っていないので、どうしようか迷うところだ。辞書に載っていない語は1-gramでコーパスを調べて、大文字で始まる確率が一定以上であればそれを採用するようにした。それでも検出できないものは、小文字のまま何もしないことにした。辞書の小文字の語を全て書き出して未知語を全て大文字にする作戦もあるが、たぶんそれはやりすぎだ。
これでJESCの英文を人間が読みやすい形式に直せた。次に、字幕ならではの意訳・追加・省略の問題に対処する。実際の例を見ればわかるが、字幕の翻訳は、普通の翻訳とは程遠い。
And we are paying a cost. | その結果犠牲を払うことになります |
I was given an education | 教育を受け |
I'm starting to feel stupid for agonizing over it. | 何か悩むんがアホらしゅうなって来たわ。 |
With furcifer gone, I can put a cloaking spell on her. | 俺が隠している魔法をかけることもできる |
This way, please! | 帰れ!やだね。 |
And to the gymnosophist. | 裸行者に戻ります |
Get out! | 退散しろ! |
Yeah, he wrote one. | 初回にプロフィルn書かされませんでした? |
You did the right thing. | 良くやってくれた |
He's on the run. | 逃走中です |
No way! Seriously?! | まさかの赤ペン先生! |
No, you can't! | う...うん |
辞書の例文に収録するのは、訳文はできるだけ逐語訳っぽい方がいい。しかし、字幕では映像や文脈でわかる部分は原文にあっても省略されてしまうし、そうでないものは原文になくても追加されてしまう。もはや意訳どころか創作になっているものも多い。上述の例にある「赤ペン先生」てのは銀魂のセリフっぽいのだが、そのまま訳しても外国の人には意味不明なので、「Seriously」に変えられてしまっている。
さて、文化的差異への対処はさておき、それ以外の省略や追加に関しては字幕ならではの事情がある。字幕は表示時間によって字数に制限がかかるので、その制限内で必要十分な情報を伝えるには単なる翻訳では間に合わないからだ。ということは、文字列が長いほど、表示時間に余裕があることになり、内容変更の必要性が薄れると推測できる。つまり、短いものを捨てて、長いものを残せば、より逐語訳的なものの割合が増えることになる。また、一文の途中で分割された字幕は意訳的になりがちなので、分割されていないものを選びたい。JESCのデータだと文末を表すピリオド、疑問符、感嘆符は残されているので、それらで終わっているもののみを残す。そうすれば、少なくとも後ろが切られていないことは保証できる。前が切られている可能性はあるが、小文字に正規化されているから文頭の推測はできないので、それは諦めるしかない。
てことで、英文が40文字以下のものは捨て、また英文の文字数と和文の文字数を比べて0.4以下や1.0以上のものは捨て、さらにピリオド疑問符か感嘆符で終わっていないものは捨てることにした。そうすると、元々279万文だったものが40万文に減ってしまうのだが、だいぶまともな翻訳っぽい匂いが濃くなる。それでもまだノイズが多いけれども。
You are back, aren't you, Harold? | あなたは戻ったのねハロルド? |
I know the visual's incongruous, but... | 犯人像とは違和感のある見た目だが |
Let me show you more detailed ones. | もっと詳しいの見せますから。 |
Um...please go ahead and eat without me. | あの...皆さんで先済ませてください。 |
There is no such thing as a curse in this world! | 持っているだけで人を不幸にする呪われた本などというものは存在しないのです |
Any good things to you about this. | お前たちを英雄にしたりはしない |
Now! Throw out all the seal tickets! | 今だ!ありったけの封印札を投げつけろ! |
That's the expectation from demographers, going forward. | 今後もこの状況は続くと人口統計学者は予想しています |
Must have been a really great man. | ほんまの豪傑じゃったんじゃろうねぇ。 |
Warehouse? Ah, it's alright. Really. | 倉庫って。あっ。大丈夫。うん。 |
What if that was a message from erica? | エリカからだったら?なぜ受け取らなかった? |
They look after the engineers working on the darn. | 彼らは送水口で働いているの技術者を守ってる |
It is this zeele Schneider that embodied it most strongly. | それを最も強く具現化したのがこのゼーレシュナイダーだ。 |
あとは、前回の記事で述べたように、辞書に収録する際に、少なくとも見出し語が英文に含まれ、その訳語が和文に含まれるものを選択すれば、それっぽくなる。以下が収録例だ。結構まともな対訳文が取得できていることがわかるだろう。
見出し語 | 英文 | 和文 |
at that time | At that time, I will recommend Dr. Senju. | その時は千住先生を推薦しますよ僕は。 |
prospect | But they had no hope, no Jobs, no prospects. | それなのに希望も仕事もなく見通しも立たなかった |
supplying | There's no way they can undertake supplying the part. | 冗談じゃない部品供給など請け負えるわけがない |
car park | You know, we drove off together, and then he dropped me back at the car park and er... | 彼の車に一緒に乗ってドライブしてからあの駐車場で降ろしてもらって家に帰った |
slope | Who calculates slopes at a job? | 誰が仕事で斜面の計算なんかする? |
collecting | See, collecting cars helps me keep my sanity. | 車を収集すると、私を助け、参照してください。私の正気を保つ。 |
enlarge | When we enlarge the writing on his jersey... | こいつの着てるジャージー文字の部分を拡大すると...。 |
be full of | If such were the truth, I'd still be full of tears, not surprisingly. | 本当だったらまだ自分のことでいっぱいでもおかしくないのに。 |
outer | Outer sections moving up? It's completely static. | 外側部分が上へ動いているように見えますか?完全に静止しています |
moderate | Traffic ahead reporting moderate turbulence. | 先行機より中程度の乱気流の報告があった |
intercept | He knows the klingons will intercept us if we follow him. | もし追えば、クリンゴンが我々を迎撃することを彼は知っている |
classical | It's classical stuff. She'll love it. | それは古典的なものだ彼女は好きになるだろう |
garage | Is that propeller thing on your head on of those garage Kits too? | お前の頭についてるそのプロペラもガレージキットかなんかなのか? |
New Mexico | A family that owned 2,000 hives of Bees in New Mexico. | ニューメキシコ州の一家で 2,000個のハチの巣を所有していました |
pedestrian | It's the law to stop for a pedestrian who's waiting to cross. | 渡ろうとしている歩行者がいたら止まるのがルールです |
go into | He used the money he made to go into legitimate business. | 彼は表の実業界に入るためにそれで作った金を使ってきた |
secretly | Hes secretly pleased to see you, underneath all that. | あなたに会えて心の底では密かに喜んでいるのよ |
arc | The arc cradle will soon collide into neo domino city. | まもなくアーククレイドルはネオ童実野シティに衝突し |
malicious | It's embezzlement. This is a malicious compliance violation. | 備品の横領。これは悪質なコンプライアンス違反です。 |
commissioner | But the commissioner decided not to accept the judge's recommendation to terminate me. | だが警視総監は僕との契約を解除すべきだという判事の勧告を蹴ることに決めた |
lesion | We can find lesions that were missed before. | 以前は見逃していたかもしれない病変を発見できます |
a while | After his mom died, I kind of lost him for a while. | 母親が死んで、しばらくはオレに距離をおいた |
forth | But when a champion steps forth to slay the jabberwocky, the people will rise against her. | でも戦士がジャバウォッキーを殺すために前へ進むとき人々が彼女を倒すために立ち上がるわ |
jack | Where are you going, jack? Jack? | どこ行くんだ,ジャック,ジャック? |
Jack | You can be, uh, dahmer, Jack the Ripper, the bay harbor butcher. | ジェフリーダーマーや切り裂きジャックやベイハーバーブッチャーだ |
今回の目的ではこのフィルタで十分だが、もっと精度重視で絞り込むことも考えらえれる。英文中で最も頻度の低い複数の語句に着目して、それらの訳語が和文中に出現しているかどうかを確認するとか、和文を英文に逆翻訳して比較するとか。ただ、あんまり絞り込むと不自然な逐語訳だけが残ることにもなりかねないので、バランスを考えるのが重要だろう。
まとめ。JESCの対訳文を英和辞書にあたり、小文字の単語を大文字に復元するのとか、フィルタを掛けて有益そうなもののみを残すとかいった対策をした。それでも人力で作られた田中コーパスよりも精度は低い気がするけども、田中コーパスではカバーできなかった専門用語とかスラングっぽいものにも例文がつけられるようになったのは大きい。