かんちゃんの備忘録

プログラミングや言語処理、ガジェットなど個人の備忘録です。(メモ書き+α)

系列ラベリングの素性抽出

系列ラベリング問題を取り扱う際の素性抽出が、いつも複雑になりがちなので、テンプレートを書いてサクッと抽出できるよう整理しました。

どんな素性を抽出したいか

固有表現抽出を例にあげます。

以下の表は、「午前8時に東京駅で集合する。」という文を形態素解析し、IOB2(Inside-outside-beggining)タグ形式で固有表現のラベルを付与したものです。

単語 品詞 IOB2タグ
午前 名詞 B-TIME
名詞 I-TIME
名詞 I-TIME
助詞 O
東京 名詞 B-LOCATION
名詞 I-LOCATION
助詞 O
集合 名詞 O
する 動詞 O
記号 O

「午前8時」はTIME属性、「東京駅」はLOCATION属性を持つことになります。

ここで、「東京」という単語を例に素性抽出します。

素性には、対象単語と前後2単語の表層形、対象単語と前後2単語の品詞、推定済みの前2単語のIOB2タグを利用するとします。 あるラベルを学習する際の素性は、Pythonの辞書形式で表すと以下のようになります。

{
    "word-2": "時",
    "word-1": "に",
    "word": "東京",
    "word+1": "駅",
    "word+2": "で",
    "pos-2": "名詞",
    "pos-1": "助詞",
    "pos": "名詞",
    "pos+1": "名詞",
    "pos+2": "助詞",
    "iob-2": "I-TIME",
    "iob-1": "O"
}

これを簡単に抽出できるように、テンプレート作ります。

テンプレートを使って素性抽出

テンプレートは、「ラベル名、素性抽出のための関数、対象単語からの相対的な位置」を持ちます。 素性抽出のための関数は、対象の素性を抽出するための関数で、例えば小文字かどうかを素性に含めたい場合は lambda x: x.surface.islower() のような処理を記述します。 例では、あるトークンのインスタンス変数としてsurfaceを持っているため、x.surfaceでアクセスしていますが、x['surface']のように与えるトークンの形式により異なります。

# 素性抽出のための関数
word_feature = lambda x: x.surface
pos_feature = lambda x: x.pos
iob2_feature = lambda x: x.iob2

# テンプレート
templates = [
    ("word-2", word_feature, -2), ("word-1", word_feature, -1), ("word", word_feature, 0), ("word+1", word_feature, 1), ("word+2", word_feature, 2),
    ("pos-2", pos_feature, -2), ("pos-1", pos_feature, -1),("pos", pos_feature, 0), ("pos+1", pos_feature, 1), ("pos+2", pos_feature, 2),
    ("iob2-2", iob2_feature, -2),  ("iob2-1", iob2_feature, -1),
]

テンプレートを適用し素性抽出を行うメソッドを書きます。

def iter_feature(tokens, templates):
    tokens_len = len(tokens)
    for i in range(tokens_len):
        # バイアス項
        feature = {"bias": 1.0}

        # テンプレートを適用
        for label, f, target in templates:
            current = i + target
            if current < 0 or current >= tokens_len:
                continue
            feature[label] = f(tokens[current])

        # BOSとEOS
        if i == 0:
            feature["BOS"] = True
        elif i == tokens_len - 1:
            feature["EOS"] = True

        yield feature

たとえば、scikit-learnを利用する場合は、辞書形式で抽出された素性を、DictVectorizerでベクトル化することで、利用可能となります。

features = []
for tokens in corpus:
    features.extend(iter_feature(tokens, templates))

# from sklearn.feature_extraction import DictVectorizer
feature_vectorizer = DictVectorizer()
vec = feature_vectorizer.fit_transform(features)

同じテンプレートで推定を行う

実際の推定時には、以下のように先頭から順に推定し、推定したタグを代入していくことで、次のタグの素性抽出時に推定した前のタグが利用可能になります。

# tokensは推定したいトークン列, templatesは学習時と同じものを利用
for token, feature in zip(tokens, iter_feature(tokens, templates)):
    # 素性抽出
    vec = feature_vectorizer.transform(feature)
    # tokenのiob2変数に推定値をセットする
    token.iob2 = label_encoder.inverse_transform(model.predict(vec))[0]

Google Compute EngineでPythonのGPU環境を構築

機械学習環境として、Google Compute Engine(GCE)のGPUインスタンス上にPythonを構築しました。 また、GPU対応版のLightGBMとCatboostをインストールしました。

本記事はその備忘録となります。

続きを読む

ErgoDoxEZを購入した

HHKB Pro 2 type-Sの日本語配列から、左右分離型キーボードであるErgoDoxEZに移行しました。

目的だった猫背の解消は、徐々に軽減されつつあるように思います。

きっかけから購入までを紹介します。

猫背解消がきっかけ

徹底的な猫背解消に取り組むためです。 現在猫背対策として、スタンディングデスクにしてディスプレイの高さに気を配ったり、ラットプルダウンやデッドリフトを始めとした筋トレに取り組んだりしています。

そんな中でHHKBの長所であるスリムなキーボードが、体格に合っていないことに気づきました。 キー入力をしていると、どうしても肩が前に出てしまいます。 左右分離型なら、肩を内転させずに作業できると考えました。

周りにErgoDoxEZユーザがいた

左右分離型キーボードユーザが周りにたまたま居たため、入力させてもらいました。 ErgoDoxEZとBaroccoを体験しました。

直感ですが、徹底的に対策するならErgoDoxEZがパームレストがあり、傾斜も変更可能なためいいと考えました。

購入してから届くまで三週間

ErgoDoxEZの公式サイトから注文しました。

無刻印の黒色で、ティルトキットとパームレストを付けました。 無刻印にした理由は、キー配置を変更した際に入れ換えなくていいことと、入れ換えたとしてもキートップの傾斜が適切なものではなくなるためです。

注文すると、宛先や注文内容が記載されたメールが届きます。 総計325USDでした。

1x Tilt/Tent Kit - Black for $25.00 each
1x The Wing: Custom ErgoDox EZ Wrist Rest - Black for $30.00 each
1x ErgoDox EZ Original Standalone - Blank / Black / Cherry MX Silent Red for $240.00 each
Subtotal : $295.00 USD

Shipping : $30.00 USD

Total : $325.00 USD

メールに記載のあった通り、約三週間後に発送されました。 配送状況などは、メール内のリンクからステータスを確認できます。

発送後にDHLのページから時間指定ができるため、都合のいい時間を希望します。

そこから待つこと約二日、指定時刻に佐川急便さんが来ました。 手数料を払って受けとりました(関税なのか何の手数料かは詳細はわからなかったが、1000円程度だったと思います)。

開封してセットアップすればErgoDoxEZライフが始まる

厚み約4cmくらいのわりと大きな箱を開封し、PCに接続すればErgoDoxEZライフが始まります。

私はキー設定でなんだかんだ数時間溶かしました(Emacsキーバインドで小指が疲れるため、どうやって親指にマッピングさせるか考えていると時間が溶けた)

キー設定やWindowsで利用するときのIME切り替えについては、別記事で書こうと思います。

Xonshを使ってみた

【Xonsh Advent Calendar 2017の13日目の記事です。】

Xonshがいいという話を聞いて、これは使ってみないと!と思い使ってみました。

その備忘録です。

続きを読む

Pythonのrequestsモジュールでの文字コード対策

【Webスクレイピング Advent Calendar 2017 4日目の記事です。】

Pythonrequestsモジュールは、 「Requestsは、人が使いやすいように設計されていて、Pythonで書かれている Apache2 Licensed ベースのHTTPライブラリです。」公式サイト1文目に記述されているほど、扱いやすいHTTPライブラリです。

そんなrequestsモジュールですが、日本語HTMLを対象に取得する際に文字化けを起こすことがしばしばあります。

その対策や原因について備忘録としてまとめます。

続きを読む

hugでAPIやCLIを作る

【Sansan Advent Calendar 2017 1日目の記事です。】

Pythonで、WebAPIやコマンドラインツールを作ったりするときに、ボトルネックになりがちなのが、ルーティングや引数の管理です。 hugは、ここらへんをよしなにやってくれるPythonモジュールです。

hugを使った、WebAPIやコマンドラインツールの作成について備忘録として記します。

続きを読む

ICDAR2017に参加した

f:id:kanjirz50:20171119214450j:plain

最近 会社の技術ブログにうつつを抜かし 、個人ブログに投稿できていなかったので、久しぶりの投稿となります。 (個人ブログ、少しはがんばろう)

会社スポンサーブース対応および聴講を目的に、京都で開催されたICDAR2017に参加しました。

これまで言語処理系の学会にばかり参加しており、画像系は初めてだったためとても新鮮でした。 参加した所感を書き残しておきます。

ICDARとは?

International Conference on Document Analysis and Recognitionの略で、文書の構造解析やOCR関連会議となります。

いくつかセッションをピックアップすると、以下の領域について議論が行われていました。

  • 文字列を利用した画像認識
  • 文字領域認識
  • 文字認識
    • 手書き文字
    • 印字された文字
    • 街中の看板など

特にOCR関係は、アラビア系文字を対象にした研究が多かったです。 アラビア系文字は推定が難しく、文字種も多いため研究対象となっています。

研究対象として、古典文書が一つのジャンルになっているようでした。 文字の欠けや、そもそもの紙の破れ、透けなど、技術的難しさが混在するようです。

全体的には言語処理と同様に、Seq2Seqで解けるタスク設計をしたり、CNNやLSTMを使って分類問題に落とし込んだりする研究が、どっと行われていました。

雰囲気が良かったことが印象に残っている

ICDAR2017に参加して一番に思い浮かぶ感想は、会場の雰囲気が良かったことです。

特に印象に残っているのが、発表者が質問を受け付ける旨を発表ごとに強調していたことです。 これに反応してか、積極的な議論もよく見受けられました。

発表も全体的に、背景と問題意識がわかりやすく述べられており、私としては隣の分野でしたが、わかる部分が多かったです。 ソースコードGithubでの公開や、学会が主となり作成するデータセットなど分野全体での統一感を感じました。

また、チュートリアル講演のサーベイの充実ぶりにはびっくりしました。 文書解析・文字認識界隈の流れを知ることのできる非常に良い機会となりました。

f:id:kanjirz50:20171119214512j:plain

強烈なチュートリアル

"Word Spotting - From Bag-og-Features to Deep Learning"というチュートリアルでは、単語切り出しにおいてこれまでのFeatureを作って分類するというモデルから、特にCNNをはじめとするディープラーニングに置き換わっているということを丁寧に説明されていました。 それぞれの技術の説明もあり、非常に勉強になるスライドでした。 CNNは特徴抽出のフィルタのようなもので、パラメータ調整はヒューリスティックにも頼らざるを得ないなど、貴重な現場での話が頻出していました。

"GMPRDIA: Graph-based Methods in Pattern Recognition and Document Image Analysis"は、文字認識領域におけるグラフ理論についてのチュートリアルでした。 そもそものグラフ理論から始まり、文字認識での応用例が紹介されていました。

ミスタードーナッツが美味しかった学会

f:id:kanjirz50:20171119214537j:plain

ブースでの英語対応に苦戦しつつ、面白い発表を聴講できたいい学会参加でした。

ちょっとつかれた脳みそに補充するティーブレイクのミスタードーナツは、格別に美味しかったです。

ICDARは隔年開催なので、次回は何か原稿を出して発表したいなと思いました。