Skip to main content

マルコフ行列の中の著者達 Part 2 (11): 付録


付録 A: Unicode and Python 2.7.x


今回 Python 2 にて Unicode の処理をする必要が生じた.これは日本語の Web page やドイツ語の Web page の処理のためである.実際には英語の Web pageにも accent のある文字が出現することがあるので,Unicode は避けて通れなかった.プログラムの開発中に,UnicodeDecodeError と UnicodeEncodeError というexception に悩まされたので,これを解説しておく.

How the Unicode encodes characters?


Unicode は私の理解するところ,2つの map を使う coding system である.これはどのようにこの体系を理解するかにもよる.私はこの調査をするまではこのことを知らなかったので UTF-8 などという coding system があると誤解していた.UTF-8 というのは Unicode をどのように codeするのかという mapping の手法の一つであって,Unicode そのものではない.

  • Unicode: a map from characters to code (numbers)
  • UTF-X:   a map from Unicode encoded data to a specific data

Unicode そのものは code point と呼ばれる番号と文字の Description の単一のmapである.たとえば. 0x0061 'a'; LATIN SMALL LETTER A である.ここで0x0061 という数字が code point である.これが font に map されると,図形としての文字が表示される.図形としての文字は glyph と呼ばれる.Unicodeのmap は bijection であるので,文字 a は code point 0x0061 へmap されるとも言える.

この code point が Unicode,つまりある数を特定の文字への code している.しかし通常この Unicode の code point は使われない.通常使われないという意味は,テキストファイルにこの番号が save されることはまずないということである.通常もう一つの map,Unicode Transformation Format (UTF)が使われる.UTF-8, UTF-16 と endian information などが存在する.実際にはこのtransformation format に encode されたバイト列がファイルに save される.私はこのような用法が一般なので Unicode は Uni の code ではないと考えていた.Unicode の coding そのものは唯一であるが,それを実際に使う時のmapping が複数あるという意味では Uni ではない.したがって,Unicode はUni な code であるが,UTF-8, UTF-16 などは複数ある mapping の一つである.これは Unicode をそのまま使った場合に英語の Text などのサイズが増大する問題を避けるために生じた問題である.

これらの知識は [2] によった.

Python 2.7.x's Unicode representation


Python 2.x において文字列を表現するデータ型としては str 型と unicode 型がある.str 型は 8-bit の任意のデータ保持できるが,より ASCII の処理に適している.それぞれのデータ型は異なる encode への変換が可能である [2].

では,結局ほとんど同じであるのならば,文字列という一つのコンセプトを表現するために,なぜ違うデータ型が存在するのであろうか.これはおそらく歴史的な理由で,初期の python は Unicode のサポートをしていなかったため,2つのデータ型ができてしまったようである.実際,Python 3 では str 型が Unicodeを直接内部で利用可能なために,この違いはなくなっているようである.

Python 2.7 ではしかし,これが print (stream) に渡る時に問題を引き起こすことがある.Python 2.7.xにおける encode とdecode, そして文字型間の関係を図 8に示す.

Figure 8: Relationship between Unicode type and 8-bit str type in Python 2.7.x.
Python 2.7.x の unicode 型には encode method があり,str 型には decodemethod がある.これによって相互の変換が可能であるが,encode 手法によっては exception が発生する.encode 時に起きる exception がUnicodeEncodeError であり,decode 時に起きる exception がUnicodeDecodeError である.なかなかややこしい.例によって説明しよう.

まずは unicode 型の文字列を定義する.

uc = u'Wächter'
print type(uc)
-> <type 'unicode'>

これを utf-8 で str 型に encode する.

s = uc.encode('utf-8', 'ignore')
print type(s)
-> <type 'str'>

print statement は str をとるので,unicode 型が与えられると encode が呼ばれる.

print uc
-> UnicodeEncodeError: 'ascii'
codec can't encode character
u'\xe4' in position 1: ordinal
not in range(128)
uc には ascii に encode できない文字が含まれているので,error が発生した.ここで発生した error は encode の error であることに注意すること.

しかし,error を無視するように指定して encode を行えばこれは機能する.

print uc.encode('utf-8', 'ignore')
-> 'Wächter'

複雑な case としては,encode された str 型がまた decode される場合がある.

print u'{0}'.format(uc.encode('utf-8', 'ignore'))
-> UnicodeDecodeError: 'ascii'
codec can't decode byte 0xc3 in
position 1: ordinal not in
range(128)

ここでは format が str 型をとったが,それが unicode 型に対するものであったので,decode が呼ばれた.しかし,そこには decode の 'ascii' が扱えない文字が入っていたため exception が発生した.ここでは encode exceptionではないことに注意されたい.したがって,次のように最後に encode する場合にはこれは機能する.

print u'\{0\}'.format(uc).
encode('utf-8', 'ignore')
-> Wächter

付録 B: Contribution to Wikipedia


今回の実験の副作用として Wikipedia にある List の間違いが判明したので,これを修正し,Wikipedia への貢献を行なった.

今回の実験では隣接行列を生成し,eigenanalysis を用いてその行列を解析した.eigenanalysis では matrix の basis が独立していることが望ましい.しかし,今回のような matrix では一般には full rank のmatrix は望めない.たとえば,著者へのリンクのない著者の Page やリンクが張られていない page, root nodeからの同じpage への linkなどの間違いが避けられないからである.PageRank アルゴリズムはこれに対処する方法が組込まれているが,root node のリンクの間違いは簡単に修正できるので,ここではduplicated link の check を行い,それを除いた.

Duplicated link は間違いもあるが,Pseudonym が link されている場合もあるので目視でそのチェックを行なった.

Wikipedia への貢献が行えたことは個人的に嬉しい.


参考文献

[2] Python documentation 2.7.3, Unicode HOWTO http://docs.python.org/2/howto/unicode.html

Comments

Popular posts from this blog

共有メモリによるプロセス間通信

Unix の共有メモリを使ったプロセス間通信について調べて実験をしてみた.対象は1つのホスト上での複数のプロセスである.ネット上でいくつか例題はないかと探したが,どうも良い例となるコードが見当たらなかった.結局はある解説記事と,Stack Overflow の議論と,man page を見て作ってみたものになったので,例をここに置くのも有用かと考え,この記事を書く.(もしかしたら探し方が悪くて良いコード例をみつけられなかっただけかもしれない.) mmap を使うかどうかという話がいくつもでていたが,POSIX の方向としては,shmem_open と mmap を使うという方向があるということだったので,それを信じてその形での実装を試してみた. 基本的なコードの流れは次のようになる. 共有メモリ領域を1つのプロセスが shm_open() を使って作成する.その際に,プロセス間で共通の文字列を識別子(``identifier'')とする.(Linux ではこれが /dev/shm/identifier のように見える.) 共有メモリ領域を mmap() でメモリにマップする.共有メモリポインター (shared_ptr)が得られる. shared_ptr を使って複数のプロセスで通信をする. 利用終了後は munmap() をつかってマップを消す. 共有メモリオブジェクトを shm_unlink() によって消す. 以下に示すプログラムは,server と client の2つのプロセスが共有メモリを使って通信をするものである.ここで,server プロセス数と client プロセス数は共に 1 を仮定する.server と client は自分の領域にしか値を書き込まないことで,ロックを避けている.互いに相手の値を読み,それよりも1大きい数を一定の期間ごとに自分の領域に書くという例題である.シンプルではあるが,共有メモリで通信をする基本としては十分なものだと思う.ソースコード(shmem_test.cpp)を以下に付加する.ソースコードのコメントにコンパイル方法とどのように利用するかを書いておく. /*   Shared memory inter process communication minimal exa

複数の線を持つ線グラフを Jenkins の plot plugin で描く方法

私は毎夜のソフトウェアテストを自動化するために Jenkins というツールを使っています.今回は, valgrind  を使ってメモリーリークのテストを自動化することにし ました.その際,エラーの数の結果をグラフとして表そうと思って, Plot plugin  を使うことにしました. Plot plugin の例図からは,複数のデータラインを描くことができるのは明らかなのですが,どうやったらいいのかは参照のページや,例としてあった Perl script,plugin 中の help からは私にはよくわからなかったのです. ここで重要な考えは,それぞれのデータラインにはそれぞれの出力ファイルが必要ということでした.私はこれを誤解していました. 例として,ビルドの時に次の property データファイルを出力します.それぞれのファイルが1つのデータラインを表します. valgrind_trunk_result.definitely.property valgrind_trunk_result.indirectly.property valgrind_trunk_result.possibly.property それぞれのデータの中身は1行のデータ点です.たとえば, valgrind_trunk_result.definitely.property ファイルの中身は次のような1行 です. YVALUE=0 このファイルを ${WORKSPACE} ディレクトリ以下に出力します.ここで," WORKSPACE " は jenkins が提供する環境変数です. 図1が私の plot plugin の設定を示しています.これは jenkins の config 画面です.3つの data series があって,それぞれにデータファイルがあります. Figure 1: Plot plugin configuration in Jenkins 図2が結果です.複数の線が描かれているのがわかります.(実際には 3 本の線がありますが,最初の線と2番目の線が同じデータなので,重ねって見えません.) Fugure 2: Plot data with multiple data lines

ソニーのカメラ (α 5000) の 30 分のビデオ録画時間の制限を外す方法

私は Sony の Alpha 5000 を気にいって使っています。しかし一つだけ問題がありました。それはビデオの録画時間の制限が 30 分というものです。 今日,ちょっと気になって探したらこの制限を解除できることがわかりました。以下のビデオがその紹介です。 https://youtu.be/7cstA_PuRIg このビデオの作者によれば,ほとんどのソニーのカメラのビデオの制限はなくせるそうです。ただし私が試したのは,Alpha 5000 のみです。 手順 カメラ側 スイッチ On Menu -- Setup --- USB connection を MTP にする スイッチ Off and On USB ケーブルでカメラをコンピュータに接続する (以下接続したままにする) コンピュータ側でソフトのダウンロードとインストール (私は Windows 10 で試しました) 次の URL に行く https://sony-pmca.appspot.com/apps ただし,Internet Explorer か Safari のみサポートということでした。Chrome では上手くいきませんでした。私が試したのは Windows 10,Internet Explore 11 です。 注意事項: このサイトは Sony のサイトですが,ここにあるソフトウェアは Sony のものとは限らないので保証はありません。御自分でリスクを判断してご利用下さい。当方も何も責任を負えません。 上記の URL から,OpenMemories のページに移動する。 このページにある PMCADownloader plugin (PMCADownloader.msi) をダウンロードする PMCADownloader をインストールする 私はいちどここでページを閉じてもう一度 https://sony-pmca.appspot.com/apps を開き,OpenMemories のページに移動しました ここで log に Loading plugin Plugin loaded と表示されます。PMCADownloader の Install がされていない時には,``Plugin loaded'&#