こんにちは。
コーポレートエンジニアリンググループの 下村 です。 コーポレートエンジニアリングって?という方は こちら をご参照下さい。 誤解を恐れず言えば、社内ITをハックする人 といった職種です。
本日はマネーフォワードグループ全体で利用中の情報共有ツール(Kibela)の記事をDeepLによる自動翻訳ができるようにしてみた記事を書いてみます。
この記事の要約
- Kibelaの記事の件名に特定キーワードをつけるだけで、DeepL APIによる翻訳記事が作成/更新されるようにした。
- DeepL APIを利用するにあたって工夫した点を書いた。
- 課金額の節約方法
- 翻訳をかける前の下処理について
DeepLとは
DeepLとは 「世界一高精度な翻訳ツール」 (公式ページから引用) です。 その謳い文句通り、翻訳精度はとても高いと思います。 例えば、こちらの記事 で解説していますが、Google翻訳と比べても自然な翻訳結果となります。
( Google検索するとDeepLについて語っている例が多くヒットするので詳細説明は こちら の中からご覧ください )
なぜやったか
マネーフォワードCTOが考えていること(2021年9月) にもあるとおり、マネーフォワードの開発サイドは英語化へ舵を切っていくことになりました。 一方で、下記のような課題があるのでDeepLを使ってKibelaの記事をお手軽に翻訳できないかなと考えて作成することとしました。
- 既存の日本語記事を英語に手動翻訳するのは手間である。
- そして現時点で英語が喋れない日本人開発者がいる。
どうなるか
下記のように変換されます。
どうやったか
KibelaにはOutgoing Webhookの機能があるので、それを利用して記事の作成・更新がされたときにDeepL翻訳をするようにしてみます。
全記事に対して翻訳をかけるとDeepLの課金額が高くなってしまうので、マネーフォワードでは件名に #ja といった文字列が入ってた場合にDeepL翻訳処理がされるようにしています。
工夫したポイント
社内へのリリースにあたり、何点か工夫したポイントはあるのですが特に注意した点としては下記になります。
1. 課金額の節約方法(過去に翻訳した記事は課金しないようにする)
翻訳元の記事が更新されたら翻訳後の記事も更新されるようにしています。 ただ、そうなった場合に困るのが、 毎回、全文翻訳してしまうとDeepL課金額が膨れる というところです。 これを避けるため、下記のようにすることでDeepL APIを実行する回数を減らしました。
- 記事本文を改行で分割。
- 分割した単位でDeepL翻訳した後に、翻訳後の結果をDBに格納。
こうすることで前回翻訳した文章は「DBから取得」(※DeepLへの課金は発生しない)、新規文章は「DeepL翻訳」といった形で課金額をおさえました。
2. DeepL翻訳前の下処理について
翻訳元の文章をそのまま、DeepL翻訳すると下記のようなケースで文章が崩れることがあります。 DeepL翻訳をかける際に翻訳元言語が"日本語"、翻訳先言語が"英語"で翻訳処理をかけたりするのですが、日本語読みできる英単語が入ったときに空白が入ったり、別の文字列に変わったりしてて意味合いが変わったりすることがあります。 そのため、下記に該当するものはDeepL翻訳にかけないようにしました。
- URL
- 絵文字(
:+1:
みたいな文字列 ) - 英語だけの文章
上記に該当する処理の抜粋としては下記です。 問題となりそうな文字列をダミー文字列に置き換えてからDeepL翻訳をかけて、DeepL翻訳後の文章をダミー文字列から元の文字列に戻してます。 (もう少し良いやり方がありそうな気がしますが...)
if re.search("[ぁ-んァ-ヶア-ン゙゚一-龠]", sentence): #日本語を含む場合の処理 regex_pattern_1 = "https?://[\w!\?/\+\-_~=;\.,\*&@#\$%'\(\)\[\]]+" #単純なURLのパターン regex_pattern_2 = "\(https?://[\w!\?/\+\-_~=;\.,\*&@#\$%'\(\)\[\]]+\)" #markdownで指定されているURLのパターン regex_pattern_3 = "\:[0-9a-zA-Z,\-\_\+]{1,32}\:" #1〜32文字以内のEmoji sentence_list = re.findall("{}|{}|{}".format(regex_pattern_1, regex_pattern_2,regex_pattern_3), sentence) #対象文字列があればlist化する ###実際の置き換え処理 num = int(0) #初期値 split_dict = {} #初期値 for url_value in sentence_list: #置き換え処理 dummy_value = "xxx{}xxx".format(str(num)) #置き換え文字列 sentence = re.sub(re.escape(url_value), dummy_value, sentence) #置き換え処理 split_dict[dummy_value] = url_value #後で戻す時用のdictに代入 num += 1 #翻訳処理を実施 #<<割愛>> #翻訳後のテキストを事前に置き換えていた文字列から再置換え for dummy_value in split_dict: url_value = split_dict[dummy_value] translated_sentence = re.sub(re.escape(dummy_value), url_value, translated_sentence)
結果どうなったか
下記のように反応は上々そうです。
終わりに
DeepLといえでも機械翻訳なので、本来は人間による翻訳が一番精度が良いと思われます。 ただ、完全英語化までの過渡期としては十分なものが提供できたかなと思います。
なお、マネーフォワードでは、「すべての人のお金の悩みや課題を解決したい」という想いをともにするエンジニアを募集しています。
私が所属するCIO室でも募集をしているのでぜひご応募ください!
コーポレートエンジニアの募集 ←私の現在の所属はこちら コーポレートインフラの募集 ITサポートの募集
マネーフォワードでは、エンジニアを募集しています。 ご応募お待ちしています。
【サイトのご案内】 ■マネーフォワード採用サイト ■Wantedly ■京都開発拠点
【プロダクトのご紹介】 ■お金の見える化サービス 『マネーフォワード ME』 iPhone,iPad Android
■ビジネス向けバックオフィス向け業務効率化ソリューション 『マネーフォワード クラウド』
■だれでも貯まって増える お金の体質改善サービス 『マネーフォワード おかねせんせい』