Help:Extension:Translate/Translation memories/ja

翻訳拡張機能翻訳メモリは複数のバックエンドをサポートします. 利用できるバックエンドとは、データベース、Solr と ElasticSearch です. このページではそれぞれの仕様をより詳細に説明し、利用者に最適のものをインストールする手助けをしていきます.

例えば外部機械翻訳サービスなど他の翻訳支援ソフトとは異なり、この翻訳メモリは利用者のウィキの新しい訳文によって絶えず更新されます. Solr または ElasticSearch を選択した場合、全訳文を対象にした高度な検索 Special:SearchTranslations も利用できます.

比較
既定でデータベースバックエンドを使用. 依存関係はなく設定も不要です. ただし複数のウィキ間でデータベースバックエンドの共有はできず、あるいは大量の翻訳コンテンツの処理はできません. そのため Solr と ElasticSearch のバックエンドもサポートします. 他のウィキの翻訳メモリも、先方の Web API を開いた状態なら使用可能です. 他種のものと異なる点は、利用中のウィキの翻訳を使った、リモートバックエンドの更新はできないことです.

ElasticSearch バックエンド
ElasticSearch の設定歯比較的簡単です. 配布パッケージに同梱されていない場合は、先方能佐糸からダウンロードします. 合わせて拡張機能のElastica extension も入手してください. そして翻訳拡張機能に固有の環境設定は、で確認をお願いします.

ブートストラップ スクリプトが必要なスキーマを作成します. 複数のウィキで ElasticSearch バックエンドを利用する場合は、既定で翻訳メモリが共有されます. 利用者が環境設定でインデックス引数を設定すると、共有されません.

Elasticsearch のメジャーアップグレード（2.x から 5.x へなど）を実行する前に、リリースノートおよび説明文書に書いてある、アップグレード手順を熟読するよう、強く推奨します. Elastic にはmigration plugin があり、新しいバージョンをインストールする準備をサポートできる場合があります. これら注意点を慎重に実行しないとElasticsearch のアップグレードを拒否され、意禅野バージョンにもロールバックできないといった微妙な状況にはまることがあります.

後続のメジャーなバージョンをインストールした直後には、 を実行しようとすると失敗する事例が見られます. Once the next major version is installed it's probable that the next time you run it fails. 原因は Elasticsearch が内部で移行プロセスを実行して作成するデータマッピングと、 が探すマッピングが不整合を起こす場合があります. インデックス全体を強制的に再構築するには、 フラッグを使用します.

経験的な知恵として、メジャーのアップグレード直後には フラッグを使って を実行することをお勧めします. インデックスは常に Elasticsearch の現状バージョンで作成されること、それがメジャーアップグレードの要件であることを、利用者の責任で十分に認識する必要があります.

Solr バックエンド
以下は、Solr for TTMServer のインストールおよび構成の、一般的な手順のまとめです. 手順は、利用者各自の状況に適応させる必要があります.

Solr バックエンドの使用に当たり、Solarium ライブラリを入手します. もっとも簡便な方法は、拡張機能 Solarium extensionのインストールです. このページの「設定」節に Solr バックエンドの設定サンプルがありますので、参照してください. キーを使うと、Solarium に関する煩雑な環境設定を省略でき、手順はたとえば を参照してください.

インストール
必要条件が整ったら、インストール前に設定を微調整し、ブートストラップを実行する必要があります.

設定
翻訳メモリを含め、翻訳支援ソフトはどれも 環境変数を使って設定されます.

プライマリの翻訳メモリ バックエンドは キーを必ず使います. プライマリのバックエンドは翻訳更新情報を受け取り、Special:SearchTranslations に渡します.

TTMServers の設定サンプルは以下のとおり.

利用できるキーと値は以下の通りです:

現在、対応しているデータベース バックエンドは MySQL のみです.

Bootstrap
Solr もしくは ElasticSearch を選び、要件と設定が整ったら、 を実行し翻訳メモリをブートします. 翻訳メモリのバックエンドを変更したときも必ずブートしてください. 断片化翻訳メモリを複数のウィキに使用している場合は、個別にひとつずつブートストラップする必要があります.

大量の翻訳を要するサイトの場合は、 引数を用いるスレッドを複数使い、プロセスの処理速度を上げるよう検討してください. 時間は、メッセージグループ完了統計の完全度に大きく依存します（不完全なものはブートストラップ中に計算）. 新しい翻訳は自動的にフックによって追加されます. 初めて訳文が作成されると、新しい翻訳原文（メッセージ定義）を追加します.

ブートストラップが行う以下のことは、その他の処理では実行されません.
 * 翻訳メモリスキーマの追加と更新.
 * 既存の翻訳を翻訳メモリに追加する.
 * 翻訳メモリを空にしたあと再設定し、未使用の翻訳エントリを開放.

特定のメッセージの翻訳が更新されると、それまでの訳文は翻訳メモリから除外されます. ただし新しい定義に対して翻訳が更新され新しいエントリが追加されても、古い定義とそれに対する古い翻訳はパージするまでデータベースに残されます. 特定のメッセージの定義変更や、すべてのメッセージグループからの削除が発生しても、直後には何も起こりません. 翻訳をファジーとして保存しても、新しい翻訳が追加されたり、古い翻訳が翻訳メモリから削除されることはありません.

TTMServer API
If you would you like to implement your own TTMServer service, here are the specifications.

クエリのパラメーター:

Your service must accept the following parameters:

Your service must provide a JSON object that must have the key  with an array of objects. Those objects must contain the following data:

例:


 * URL: http://translatewiki.net/w/api.php?action=ttmserver&sourcelanguage=en&targetlanguage=ja&text=january&format=jsonfm
 * 応答:

データベース バックエンド
The backend contains three tables:,   and. Those correspond to sources, targets and fulltext. You can find the table definitions in. The sources contain all the message definitions. Even though usually they are always in the same language, say, English, the language of the text is also stored for the rare cases this is not true.

Each entry has a unique id and two extra fields, length and context. Length is used as the first pass filter, so that when querying we don't need to compare the text we're searching with every entry in the database. The context stores the title of the page where the text comes from, for example "MediaWiki:Jan/en". From this information we can link the suggestions back to "MediaWiki:Jan/de", which makes it possible for translators to quickly fix things, or just to determine where that kind of translation was used.

The second pass of filtering comes from the fulltext search. The definitions are mingled with an ad hoc algorithm. First the text is segmented into segments (words) with MediaWiki's. If there are enough segments, we strip basically everything that is not word letters and normalize the case. Then we take the first ten unique words, which are at least 5 bytes long (5 letters in English, but even shorter words for languages with multibyte code points). Those words are then stored in the fulltext index for further filtering for longer strings.

When we have filtered the list of candidates, we fetch the matching targets from the targets table. Then we apply the levenshtein edit distance algorithm to do the final filtering and ranking. Let's define:


 * E :編集距離
 * S :提案を探す元となっている文字列
 * Tc :提案の文章
 * To :Tc が翻訳結果となるような元の文章

The quality of suggestion Tc is calculated as E/min(length(Tc),length(To)). Depending on the length of the strings, we use: either PHP's native levenshtein function; or, if either of the strings is longer than 255 bytes, the PHP implementation of levenshtein algorithm. It has not been tested whether the native implementation of levenshtein handles multibyte characters correctly. This might be another weak point when source language is not English (the others being the fulltext search and segmentation).

Solr バックエンド
Solr Solr search platform backend works similar to the database backend, except that it uses a dedicated search engine for increased speed. The results are by default ranked with the levenshtein algorithm on the Solr side, but other available string matching algorithms can also be used, like ngram matching for example.

In Solr there are no tables. Instead we have documents with fields. Here is an example document:

Each translation has its own document and message documentation has one too. To actually get suggestions we first perform the search sorted by string similarity algorithm for all documents in the source language. Then we do another query to fetch translations if any for those messages.

We are using lots of hooks to keep the translation memory database updated in almost real time. If user translates similar messages one after another, the previous translation can (in the best case) be displayed as suggestion for the next message.

New translation (if not fuzzy)
 * 1) Create document

Updated translation (if not fuzzy)
 * 1) Delete wiki:X language:Y message:Z
 * 2) Create document

Updated message definition All existing documents for the message stay around because globalid is different.
 * 1) Create new document

Translation is fuzzied
 * 1) Delete wiki:X language:Y message:Z

Messages changes group membership
 * 1) Delete wiki:Z message:Z
 * 2) Create document (for all languages)

Message goes out of use Any further changes to definitions or translations are not updated to TM.
 * 1) Delete wiki:Z message:Z
 * 2) Create document (for all languages)

Translation memory query
 * 1) Collect similar messages with strdist("message definition",content)
 * 2) Collect translation with globalid:[A,B,C]

Search query Can be narrowed further by facets on language or group field.
 * 1) Find all matches with text:"search query"

Identifier fields Field  uniquely identifies the translation or message definition by combining the following fields: The used format is.
 * wiki identifier (MediaWiki database id)
 * message identifier (Title of the base page)
 * message version identifier (Revision id of the message definition page)
 * message language

さらに上記の削除クエリを実行するため、wiki id、message id と言語にそれぞれ別個のフィールドを当てています.