sotetsuk's tech blog

技術系専門書(機械学習)の翻訳体験から学んだこと

技術書(訳書)を出版社から初めて刊行したのですが、その過程で経験したことなどを共有することで誰かの役に立てて貰えれば、と言うのがこの記事の趣旨になります。最近では他にも、"CSの定番教科書「Open Data Structures」を日本にも届けたい!"というプロジェクトもあり、こうした草の根の技術書の翻訳活動がもう少し日本にあってもいいのではと個人的に思っています。理系専門書に邦訳が必要なのかどうか(英語で読めばいいでしょ論)は立場が別れるところだとは思いますが、私は基本的に上記プロジェクト内の次の一文と同じ立場です。

そして、母国語でこのような入門書が読める、少なくともその選択肢があるのは望ましいことだと考えています。

なお、この記事も前の記事に引き続き、2017年に書きかけだった記事の供養です(投稿は2018年の年始)。 年末にやりたかったのですが、年始になってしまいました。。。

どんな本を出版したの?

f:id:sotetsuk:20180102223653p:plain

これは主題とズレるので別記事に譲ります。こちらの記事をご参照ください。 2017年9月に「速習 強化学習 ―基礎理論とアルゴリズム―」という本を刊行しました。Csaba Szepesvari著、"Algorithms for Reinforcement Learning"の訳書になります。 原著はLaTeXで書かれていて数式と擬似コードが多い一方、サンプルコードのようなものはないです。

どういう手順で翻訳したの?

まずは、実際に私達が翻訳する際に踏んだ手順をほぼ時系列順で記述していきます。

1. 企画する

もともとこの翻訳は強化学習の勉強会での輪読からスタートしています。 せっかく洋書を読むなら翻訳しようということで気軽な気持ちで10人くらいでスタートしました。 この時点で著者のC. Szepesvari先生にメールでコンタクトを取って、原著の翻訳とそのフリーでのWeb公開について許可をいただきました。 ただ、後で説明するように、最終的には出版社から出版するということで落ち着きます。

2. 翻訳を開始する

最初は担当を一人5ページずつくらいで分担し、毎週の輪講までにOverleaf上に納品してもらっていました。 この時点ではまだ担当者の理解度の都合もあり、クオリティも非常に低かったです。 一通り埋まるまで2015年10月から2016年3月まで半年近くかかっています。 一通り埋まってからはGitHub上に原稿を移して編集していきました。

3. 監訳をお願いする

翻訳のクオリティの質を上げるためのモチベーションとして、ただ公開するだけでなく出版物にしようかという案が上がりました。 この時点で訳者陣に博士学位持ちがいなかったので、内容・体裁の両方の面で問題があろうということで、監訳を出身研究室のツテで前田新一先生と小山雅典先生にお願いしました。 前田先生は"これからの強化学習"や"深層学習本"にも寄稿されており関連分野に非常に詳しく、小山先生は数学博士で英語がほぼネイティブなので数式の多い洋書の翻訳にあたって心強かったです。

4. 出版社に営業する

前田先生に出版社の営業の方を紹介して頂いて、メールで企画の営業をしました。 幸い、最初に営業をした共立出版さんの方で企画が通り、刊行されることが決まりました(少しすったもんだはありましたが)。 このあとで一度出版社に出向き、印税などの取り決めも口頭でおおよそ合意して、後日書類で契約しました。 出版は決まりましたが、代わりにWeb上でのオープンでの公開は取りやめとなりました。 洋書ではドラフトがpdfダウンロードできる専門書が多いですが、国内ではマーケットサイズの問題もあり、そうした試みは難しいそうです。

5. 版権を取る

これは私達がした作業ではないのですが、出版社の方で版権を取って頂きました。 この作業を踏まないといくら翻訳しても日本で出版できません。

またこのときになって初めて原著者・出版社の方から原著のLaTeXファイルをもらいました。 実はこれまでは数式部分も訳者が手入力していて非常に効率が悪く、ミスも多かったです。 これは完全に最初にやっておくべきでした。

6. 原稿を納品する

いろいろすっ飛ばしますが、原稿を納品します。実は(ありがちですが)締め切りを丸1年近く伸ばしてしましました(2016年夏に納品予定が2017年夏に納品)。

この過程では、

  1. もう一度輪講をして、最初とは別の担当者が確認・修正をする。
  2. 上の原稿を小山先生に(主に英語を中心に)確認・修正してもらう。
  3. 監訳のお二人と私の3人で原稿の読み合わせ・修正をする。(x 3回)
  4. 輪講メンバーを新規で増やしてもう一度読み直して確認する。
  5. 訳書オリジナルの付録を執筆し、前田先生含め他の訳者に確認してもらう。

といった工程があり、その途中で専門用語のチェックや送り仮名を揃えるなどの細かい作業も膨大にありました。 こうした専門用語チェックや日本語の言葉遣いの問題はGitHub上でIssue管理して、RedPenを使っての自動チェックのCIを回したりしていました。例えば、専門用語についてはGoogleスプレッドシートに辞書を用意して対応が取れているか雑にスクリプトを書いてCIでチェックしていました。

f:id:sotetsuk:20180103000046p:plain

ただ後に書くようにこのチェックを自動でCI回すのはfalse-positiveの問題があり、なかなか一筋縄ではありませんでした。 例えば辞書は最初のうちは(専門)用語の種類を少し多めに登録してしまいましたが、箇所によって柔軟に訳したくなるような用語もアラートがなってしまい面倒でした。

7. 出版社の編集の方に校正をしてもらう

納品したら出版者の編集の方に校正をしてもらいました。 さすがプロということで、凄まじい速さで(ある程度)専門的な記述・一般的な記述含めて大量に直されました。 CIを回していたりある程度細かくやっていたつもりだったのですが、やはりプロに校正をお願いしないと品質として最低ラインを満たさないように思います。 "CSの定番教科書「Open Data Structures」を日本にも届けたい!"というプロジェクトでも、校正費用をクラウドファンディングしていたようです。(少額でも支援したかった。。。気付かず or 失念で叶わず)

編集の方で判断がつかない点はやり取りをしながらになりますが、基本的にこちらはそんなに大変ではなく、待っていたら完成・刊行になります。

教訓・反省(失敗・成功したなと思うこと、次にやるならどうするか)

上記のような方法・手順で無事刊行に至りましたが、その過程での反省は多かったです。 ここではその過程で得た教訓と反省、また逆にやってよかったことなどを記述していきます。

締切は厳守すべきだった

これは翻訳に限らないですし当たり前の話なのでアレなのですが、普通に生きていると、(ときに無意識に) 「質が最低ラインを超えるまで、必要なだけ時間をかける」 という方針で作業をしがちです。 これをやると何時までたっても納品できないので、 「締切をきちんと決めた上で、それまでに質を最大化する」 といった方針で作業すべきです。 結局、時間をかけたからといってさして良くなるわけでもないので、締切については動かない"決め"が必要で、それまでに最大限努力するようにした方がいいです。 後述の、「自動チェックを最初に初めて、いつでも最悪納品できるようにする」というのもこれと関連します。

ただこれはすごい普遍的な問題で、実行するのが非常に難しいというか、私は頭ではわかっていても正直すごく苦手ですし現に出来ていません(このブログ記事の投稿は2017年10月中を目指していましたが、結局2018年1月に投稿されました)。 そして、これは私だけでなく、苦手な人が世の中にはとても多いのではないかと思っています(皆さんは夏休みの宿題、ちゃんと終わっていましたか...?)。

正直どうしたらいいのか良くわかりません。ノウハウある方に教えて欲しいです。成功報酬として給料3ヶ月分くらい払っても知りたいです。

f:id:sotetsuk:20180103013957j:plainf:id:sotetsuk:20180103014006j:plain
締切を守るのはYoshikiにも難しい...
引用: https://twitter.com/jun_666_jun/status/947776153174994945

人数がいたのに並列で作業できなかったのは良くなかった

結局締め切り1年伸びてしまったのはこれも一つの要因かと思います。 輪講していた都合もありますが、どうしても直列で作業しがちでした。 ここはもっと並列にやることで効率的にできたかなと思っています。 また、直列で依存関係を作ってしまって作業することの弊害として、 上記のような「締切守るの難しい問題」からドミノ倒しのように作業が遅延していくという問題もあったような気がします。

結局一番進んだのは、少人数でその場で読み合わせ&修正

分担を振って締め切りまでにやってもらったり色々したのですが、皆さん忙しいので結局いつまで経っても終わらなかったりします。 結局少人数(3人くらい)でその場で読みながら気になった点を逐一修正していく、というミーティングを定期的に持つのが一番進みました。 今回は例えば、前田先生・小山先生と3人でスカイプをしつつ読み合わせ・修正するミーティングを何回もしていました。 年末年始など時間が取れるときに毎日スカイプでミーティングしながら進めたりしていました。 また、監訳を除く訳者陣で輪講している際にも、気になる訳についてはその場で対訳を考えたりしていました(ただこれは人数が多いとすごい疲労しました。。。)

色んな人に何となく修正させても訳(の質)が単調に改善して収束していくとは限らない(振動する)

やはり訳者の好みもあるので、違う担当者が確認・修正するのを繰り返すと訳(の質)が振動したり(あるいはデグレしたり)といったことがありました。 ただこれは担当者が悪いのではなく仕組みの問題で、翻訳が進むにつれて担当者の役割を細かく限定的にしたり、 masterマージ前に最終的に責任持つ人のレビューをきちんとやるといった工程が本来は必要だったかなと思います。

GitHubで管理したのは良かった

人数が多かったので、GitHubで原稿を管理したのは非常に良かったです。これは一定以上の人数で作業するならマストだと思います。 Overleaf等でもいいのですが、やはり修正者と修正意図はコミットログから確認したいところです。 科学技術書の出版社の方でもGitHubがデフォルトになるといいんではないかと思ったりはします(例えば技評さんはGitHubがデフォルトと聞いています)。 ただ一方、Gitに不慣れなメンバーがいると、Git自体の学習コストがそれなりに掛かるので、なかなか難しいところではあります。

masterマージ前に責任者がキチンとレビューすべきだった

当たり前なのですが、ここが少し疎かだったので、前述のようにデグレしたりといったことがあってしんどかったです。 時間がなくてもmasterへのマージはきちんとレビューしてからにした方が良いです。また、PRの粒度を適当な小ささで抑えるのも重要です(当たり前の一般論ですが)。

出版社への営業・版権を取るのは最初にやるべきだった

結果論ですがこれは翻訳を始める前にしてもよかったかなと思います。 まず大丈夫だと思いますが、版権ないと翻訳頑張っても結局出版できないので。。。

まず最初に原著のLaTeXファイルをもらうべきだった

前の項目とも関連しますが、これも大事です。 すごい当たり前な気もしますが、最初は頭が回ってませんでした。

原著を一文ぐらいずつコメントアウトして、その下に訳を書くのは良かった

原著との対応が見やすくよかったです。また専門用語訳などをスクリプトで自動でチェックする際にも役立ちました。

まず最初に専門用語辞書や簡単な規約をある程度固めて、スクリプトで自動でチェック出来るようにすべきだった

専門用語の辞書や簡単な規約は途中から導入したのですが、最初にすごく小さくでも仕組みを作ってCIの仕組みを作って、いつでも最悪納品できるようにしておいた方が良いと思いました。 辞書を作るのと自動でスクリプトである程度チェックするのは必須で、さもないと専門用語の訳を途中で変えたときに一々抜け漏れを逐一チェックしないといけません。

今回チェックしていた項目は色々ありましたが、例えば次のようなものをチェックしていました。 RedPenの機能を使ったものもあれば、自分で雑にスクリプトを書いたものもあります。

  • 不適切な記号の確認(、。など)
  • 正しい専門用語が使われているか(value function => 価値関数)
  • 間違った専門用語が文中で使われていないか(価値 数など)
  • 原著と(インライン)数式が一致しているか(意外と修正時にミスで意図しない数式になってることがあります)
  • 送り仮名
  • 一文中のカンマの数を一定以下に
  • 一文の長さを一定以下に

またこれに関しては、出版社の中の規約のようなものも事前に編集の方に聞くべきだったなと思いました。 (同じ社内でも詳しい人と詳しくない人がいると思うので、事前に詳しい人(例えば営業畑ではなく編集畑の方とか)を紹介してもらったりすべきでした)

自動チェックはfalse-positiveのトレードオフを考える必要がある

例えば今回、"system"の訳として、"システム"と訳す人と、"系"と訳す人が混在していました。 今回は基本的にシステムと訳すことにし、"system" => "システム"という対応を辞書に登録してチェックしていました。 ただ、"system"という単語は他の文脈で柔軟に訳したりしたくなるので、"system"に対し絶対"システム"と訳さなくてはいけない、というルールでチェックをすると、 スクリプトが誤検知を頻繁に起こします。 なのでここで取れる選択肢としては、

  1. "system" => "システム"の対応を辞書から外す
  2. 文章中のいくつかの"system"は例外として登録する

といったものが考えられます。"system"くらい訳が簡単そうなものなら1.を選択して辞書から外してもいい気はしますが、高い精度でのチェックを目指すなら、例外の登録を簡単にできるよう仕組みを作っておくことが大事です。 実際、こうした用途のツールであるRedPenには例外登録ができる機能があります: アノテーションによるエラーの抑制

また、どの程度のレベルのものなら辞書に登録するのか、自動でチェックをするのかといったしきい値を自分の中で設定しておく必要があるのではないかと思います。

LaTeX自動コンパイルは良かった

Overleafで編集しているときは勝手にコンパイルされますが、GitHubではCIでコンパイル => PDFアップロードを自動でするようにしていました。 色々やり方はある気はしますが、リリースにpdfを上げるようにしていました。

例えば、werckerでCIするなら wercker.yml は大体こんな感じです。ブランチ毎に最新のpdfがリリースにアップロードされます。

box: sotetsuk/platex
build:
  steps:
    - script:
        name: compile
        code: |-
          platex -interaction=nonstopmode -halt-on-error -shell-escape -kanji=utf8 main
          bibtex main
          platex -interaction=nonstopmode -halt-on-error -shell-escape -kanji=utf8 main
          platex -interaction=nonstopmode -halt-on-error -shell-escape -kanji=utf8 main
          dvipdfmx main
deploy:
  steps:
    - script:
        name: remove_old_assets
        code: |-
          export OLD_ASSET=`curl -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/<user>/<repo>/releases | jq ".[] | .assets | map(select(.name==\"${WERCKER_GIT_BRANCH}.pdf\") | .id) | .[]"`
          curl -H "Authorization: token ${GITHUB_TOKEN}" -X DELETE https://api.github.com/repos/<user>/<repo>releases/assets/$OLD_ASSET
    - github-upload-asset:
        token: $GITHUB_TOKEN
        file: main.pdf
        filename: ${WERCKER_GIT_BRANCH}.pdf
        release_id: <release_id>

boxとして次のdocker imageを利用してます。一応pdflatex版もあります。

大まかには次のような手順を踏みます。

  1. GitHubトークンを生成
  2. リリースを作る(リリースのIDも調べる)
  3. werckerでアプリケーション・パイプラインを作る。トークンを登録する。

総括

理系専門書を初めて翻訳して得た体験をもとにその教訓・反省などをまとめました。 見直してみると、当たり前というか、マヌケに聞こえる話が多いような気もしますが、意外と当たり前のことをきちんとやるのが難しいものだったりします。 今回の翻訳は薄い本だったので気軽な気持ちで始めましたが、思いの外大変だったので、 皆さんも技術書の翻訳などを始める前に上記のようなポイントを踏まえて始めてみてはいかがでしょうか。 誰かの参考になると嬉しいです。