2

私は、C++ バックエンド ( http://www.statmt.org/moses/?n=Development.GetStarted ) と Pythonを使用するハイチ (code.google.com/p/ccmts) の統計翻訳システムに取り組んできました。 C++ エンジン/バックエンドを駆動します。

UTF-8 Python 文字列を C++ に渡し、std::stringいくつかの処理を行い、結果を Python に戻しました。これが文字列です (C++ から Linux ターミナルに出力した場合):

mwen bezwen ã ¨ d medikal

  1. それは何のエンコーディングですか?二重にエンコードされた文字列ですか?
  2. レンダリング可能になるように「修正」するにはどうすればよいですか?
  3. フォントか何かが足りないので、そのように印刷されていますか?

Python chardetライブラリには次のように書かれています。

{'confidence': 0.93812499999999999, 'encoding': 'utf-8'}

しかし、Python では、文字列/ユニコード/コーデックのデコードを実行すると、古いものが表示されます:

UnicodeDecodeError: 'ascii' コーデックは位置 30 のバイト 0xc3 をデコードできません: 序数が範囲外です (128)

ああ、Python はまったく同じ文字列を標準出力に出力します。

呼び出しはrepr()次を出力します: ' mwen bezwen \xc3\xa3 \xc2\xa8 d medikal '

4

3 に答える 3

3

ガベージイン、ガベージアウトの場合のようです。ここでは、データの内容を確認する方法についていくつかの手がかりを示します。repr()そしてunicodedata.name()あなたの友達です。

>>> s = ' mwen bezwen \xc3\xa3 \xc2\xa8 d medikal '
>>> print repr(s.decode('utf8'))
u' mwen bezwen \xe3 \xa8 d medikal '
>>> import unicodedata
>>> unicodedata.name(u'\xe3')
'LATIN SMALL LETTER A WITH TILDE'
>>> unicodedata.name(u'\xa8')
'DIAERESIS'
>>>

アップデート:

(AN Other が示唆するように) パッケージに出力言語を無作為に選択させており、その選択が韓国語であると思われる場合 (a) 教えてください (b) その言語に関連するコーデックを使用して出力をデコードしてみてください.. .. ここには韓国語だけでなく、中国語、日本語、ロシア語がそれぞれ 2 つずつあります。

>>> s = ' mwen bezwen \xc3\xa3 \xc2\xa8 d medikal '
>>> for enc in 'euc-kr big5 gb2312 shift-jis euc-jp cp1251 koi8-r'.split():
    print enc, s.decode(enc)


euc-kr  mwen bezwen 찾 짢 d medikal 
big5  mwen bezwen 瓊 穡 d medikal 
gb2312  mwen bezwen 茫 篓 d medikal 
shift-jis  mwen bezwen テ」 ツィ d medikal 
euc-jp  mwen bezwen 達 即 d medikal 
cp1251  mwen bezwen ГЈ ВЁ d medikal 
koi8-r  mwen bezwen цё б╗ d medikal 
>>> 

特にkoi8-rはそうです。さらなる提案: 接続しているパッケージのドキュメントを調べてください (URL をお願いします!) ... エンコーディングについて何と書かれていますか? どの 2 つの言語間で試していますか? 「mwen bezwen」は、予想される出力言語で意味がありますか? より大きなテキスト サンプルを試してみてください。chardet はまだ UTF-8 を示していますか? より大きな出力のいずれかが、予想される出力言語で意味をなすか? ASCII のみを使用する別の言語に英語を翻訳してみてください。意味のある ASCII 出力が得られますか? あなたの Python コードと swig インターフェイス コードを公開してもよろしいですか?

更新 2情報の流れが興味深い: 「文字列処理アプリ」 -> 「統計言語翻訳システム」 -> 「ハイチを支援するための機械翻訳システム (オープンソース/フリーソフトウェア) (crisiscommons.org)」

次の「不明」を事実に置き換えてみてください。

Input language: English (guess)
Output language: Haitian Creole
Operating system: linux
Python version: unknown
C++ package name: unknown
C++ package URL: unknown
C++ package output encoding: unknown

Test 1 input: unknown
Test 1 expected output: unknown
Test 1 actual output (utf8): ' mwen bezwen \xc3\xa3 \xc2\xa8 d medikal '
[Are all of those internal spaces really in the string?]

Test 2 input: 'I need medical aid.'
Test 2 expected output (utf8): 'Mwen bezwen \xc3\xa8d medikal.'
Test 2 actual output (utf8): unknown

Google 翻訳 (アルファ版)Microsoft 翻訳 (ベータ版)の両方から取得したテスト 2 :
Mwen bezwen èd medikal.
3 番目の単語は、ラテン語小文字 E で、GRAVE (U+00E8) の後に 'd' が続きます。

アップデート 3

入力: utf8 (おそらく、私のファイルのいくつかに不適切にコード化されたテキストがあると思います) """

すべてのファイルを UTF-8 でエンコードする必要があると仮定します (これを明示的に述べたことはありません)。

整列された en-fr-ht コーパスの zip ファイルには、UTF-8 としてデコードしようとするとクラッシュするファイルがいくつか含まれています。

これが発生する理由の診断:

シャルデは役に立たない(この場合); それは長い間気まぐれで、80から90パーセントの信頼レベルでISO-8859-2(東ヨーロッパ別名Latin2)の推測で戻ってきます。

次のステップ: ht-en ディレクトリを選択します (ht は fr よりもアクセント付き文字を使用しないため、何が起こっているかを簡単に確認できます)。

予想: e-grave は、想定される適切な ht テキスト (Web サイト、CMU ファイル) で最も頻繁に使用される非 ASCII 文字であり、次の o-grave の約 3 倍です。3 番目に頻度の高いものは、ノイズの中で失われます。

ファイル hten.txt 内の非 ASCII バイト数を取得しました。トップ5:

8a 99164
95 27682
c3 8210
a8 6004
b2 2159

最後の 3 行は、

e-grave is c3 a8 in UTF-8
o-grave is c3 b2 in UTF-8
2159 + 6004 approx == 8210
6004 approx == 3 * 2159

最初の 2 行は、

e-grave is 8a in old Western Europe DOS encodings like cp850!!
o-grave is 95 in old Western Europe DOS encodings like cp850!!
99164 approx == 3 * 27682

latin1 または cp1252 を含む説明は水を保持しません (8a は latin1 の制御文字であり、8a は cp1252 の S キャロンです)。

内容を調べると、ファイルが複数の元のファイル、いくつかの UTF-8、少なくとも 1 つの cp850 (または同様のもの) の集合体であることがわかります。犯人は聖書のようです!!!

エンコーディングの混合は、chardet が苦労した理由を説明しています。

提案:

(1) すべての入力ファイルにエンコードのチェックを実装します。国境管理のように、それらが UTF-8 に変換されていることを確認してください。

(2) リリース前に UTF-8 のデコード可能性をチェックするスクリプトを実装します。

(3) 聖書本文の正書法は (一見) ウェブサイトのものとは異なっているように見える (アポストロフィが多い)。あなたのコーパスが別の正書法によってゆがめられているかどうか、クレオールの専門家と話し合うことをお勧めします...単語の問題もあります。種入れぬパンと粗布と灰を大いに活用できると思いますか。cp850 のものは集塊の約 90% に表示されることに注意してください。一部の聖書は問題ないかもしれませんが、90% はやり過ぎのようです。

(4) Moses が非 UTF-8 入力について文句を言わないのはなぜですか? 可能性: (1) raw バイトで動作している、つまり Unicode に変換しない (2) Unicode に変換しようとしますが、失敗を静かに無視します :-(

于 2010-02-23T21:37:44.260 に答える
1

編集:私が以前に投稿したがらくたを気にしないでください。それは間違っていました。

他の人が示唆しているように、これは、utf-8であると仮定して、Pythonで正しいUnicodeオブジェクトを取得します。

>>> ' mwen bezwen \xc3\xa3 \xc2\xa8 d medikal '.decode('utf-8')
u' mwen bezwen \xe3 \xa8 d medikal '
>>> print _
 mwen bezwen ã ¨ d medikal

それは本当にあなたの図書館があなたにゴミを与える場合のようです、それにゴミが入っているかどうかは関係ありません。

于 2010-02-23T21:27:18.667 に答える
1

デフォルトのエンコーディングは ASCIIのようです。

Unicode 文字列を明示的に変換できます。

print u"Hellö, Wörld".encode("utf-8")

または、スクリプトでこれをグローバルに変更する場合は、sys.stdout を utf-8 としてエンコードするラッパーに置き換えます。

import sys, codecs
sys.stdout = codecs.EncodedFile(sys.stdout, "utf-8")
print u"Hellö, Wörld!"

さらに、 sys.setdefaultencodingを介してデフォルトのエンコーディングを (サイト全体で) 一度だけ変更できますが、これはsitecustomize.pyでのみ行うことができます。ただし、私はこれを行いません-便利に見えるかもしれませんが、システム上のすべての python スクリプトに影響を与え、意図しない副作用が生じる可能性があります。

于 2010-02-23T18:03:13.897 に答える