雑記: transformers の examples/token-classification を実行するだけ

以下の transformers リポジトリの固有表現抽出タスクの例(WNUT’17 データの方)を実行するだけです。
https://github.com/huggingface/transformers/tree/master/examples/token-classification
但し、使用する学習済みモデルを bert-large-cased にすると手元のマシンでは DefaultCPUAllocator: can't allocate memory になったので、さしあたり以下では bert-base-cased に変更しています。

手順
transformers リポジトリを clone して examples/token-classification ディレクトリに移動する

git clone https://github.com/huggingface/transformers.git
cd transformers/examples/token-classification/

WNUT’17 データを取得する

mkdir -p data_wnut_17
curl -L 'https://github.com/leondz/emerging_entities_17/raw/master/wnut17train.conll'  | tr '\t' ' ' > data_wnut_17/train.txt.tmp
curl -L 'https://github.com/leondz/emerging_entities_17/raw/master/emerging.dev.conll' | tr '\t' ' ' > data_wnut_17/dev.txt.tmp
curl -L 'https://raw.githubusercontent.com/leondz/emerging_entities_17/master/emerging.test.annotated' | tr '\t' ' ' > data_wnut_17/test.txt.tmp

ls data_wnut_17/  # (train|dev|test).txt.tmp が取得できていることを確認

プレ処理として128トークンを超える文章は分割する

export MAX_LENGTH=128
export BERT_MODEL=bert-base-cased  # トークン数を数えるのでトークナイザの指定が必要
python scripts/preprocess.py data_wnut_17/train.txt.tmp $BERT_MODEL $MAX_LENGTH > data_wnut_17/train.txt
python scripts/preprocess.py data_wnut_17/dev.txt.tmp $BERT_MODEL $MAX_LENGTH > data_wnut_17/dev.txt
python scripts/preprocess.py data_wnut_17/test.txt.tmp $BERT_MODEL $MAX_LENGTH > data_wnut_17/test.txt

ls data_wnut_17/  # プレ処理済みの (train|dev|test).txt が生成されていることを確認

ラベルを収集する

cat data_wnut_17/train.txt data_wnut_17/dev.txt data_wnut_17/test.txt | cut -d " " -f 2 | grep -v "^$"| sort | uniq > data_wnut_17/labels.txt

vi data_wnut_17/labels.txt  # 6固有表現×(B+I)+O=13ラベルのリストが生成されていることを確認

設定ファイルを用意する

vi wnut_17.json  # 以下をコピペするだけ
{
    "data_dir": "./data_wnut_17",
    "labels": "./data_wnut_17/labels.txt",
    "model_name_or_path": "bert-base-cased",
    "output_dir": "wnut-17-model-1",
    "max_seq_length": 128,
    "num_train_epochs": 3,
    "per_device_train_batch_size": 32,
    "save_steps": 425,
    "seed": 1,
    "do_train": true,
    "do_eval": true,
    "do_predict": true,
    "fp16": false
}

モデルを学習する

python run_ner.py wnut_17.json
# 学習が走る

vi wnut-17-model-1/test_predictions.txt  # テストデータへの予測結果が出力されていることを確認

補足
WNUT’17 について
固有表現抽出タスクでも、レアなエンティティを含むタスクとのことです。
WNUT’17 Emerging and Rare Entities task | noisy-text.github.io
ラベリングされている固有表現は6種類あります。
Person人名(架空の人名でも可)。
Location地名(架空の地名でも可)。
Corporation会社名(場所や商品を指している場合は Location, Product へ)。
Product商品名(架空の商品名でも可)。
Creative work創作物(映画、本、歌など)の名前。
Groupグループ名(スポーツチーム、バンドなど)。会社名は Corporation へ。
train.txt.tmp の一番最初の文章をみると、以下のように地名がラベリングされています。
@paulwalk It's the view from where I'm living for two weeks. Empire State Building = ESB. Pretty bad storm here last evening.
設定ファイルについて
以下のファイルの引数が指定できます。
transformers/training_args.py at master · huggingface/transformers · GitHub
モデルについて
学習済みの bert-base-cased を利用した BertForTokenClassification モデルで各トークンを分類しています。
https://github.com/huggingface/transformers/blob/master/src/transformers/modeling_bert.py#L1447-L1530
  入力文章(トークンIDの列)
  →[BERT]
  → 768 次元の特徴ベクトルの列(※ bert-large-cased なら 1024 次元)
  →[ドロップアウト
  →[全結合]
  → 13次元の出力ベクトルの列(※ 活性化前)
損失は正解ラベルとの torch.nn.CrossEntropyLoss によります。
学習について
AdamW で学習します。
https://github.com/huggingface/transformers/blob/master/src/transformers/trainer.py#L583
https://github.com/huggingface/transformers/blob/master/src/transformers/trainer.py#L412
https://github.com/huggingface/transformers/blob/master/src/transformers/optimization.py#L219

統計的因果推論: ノート2

以下の本を読みます。

前回: ノート1 / 次回: まだ
※ キャラクターは架空のものです。私の誤りは私に帰属します。お気付きの点がありましたらコメント等でご指摘いただけますと幸いです。
f:id:cookie-box:20200531131544p:plain:w60

飲酒の習慣と病気Xの関係に興味があるとします。「飲酒の習慣があるか」「病気Xを発症したか」という2×2分割表が1つだけあるときは、「真実は以下のどちらなんだろう」という問題を考えることになるでしょう。これは通常のカイ2乗検定です。

  1. 飲酒の習慣と病気Xは無関係である。
  2. 飲酒の習慣と病気Xは無関係ではない。

ただ、その分割表が実は男女別の2つの分割表に分けることができて、それを活かそうとするとき、考える問題は自明ではありません。例えば、「以下のどちらなんだろう」と考えるのは一つの案です。

  1. 男性であっても女性であっても飲酒の習慣と病気Xは無関係である。
  2. 男性か女性の少なくとも一方で飲酒の習慣と病気Xは無関係ではない。
これも通常のカイ2乗検定です。このときは、「飲酒の習慣があって病気Xを発症した男性」と「飲酒の習慣があって病気Xを発症した女性」を足した値には興味はありません。あくまで、飲酒の習慣と病気Xが無関係ならばそれぞれの値がどれだけ珍しいのかに興味があります。むしろ足したら情報が失われます。…ですが、この検定で有意になっても「飲酒の習慣は病気Xのリスクを上げる」という結論にはなりません。極端な話、「男性の場合は飲酒の習慣は病気Xのリスクを上げるが、女性の場合はリスクを下げる」なんていう場合にも検定は有意になります。だから、「飲酒の習慣は病気Xのリスクを上げる」という結論に向かいたいなら、この検定をやるのは違う気がします。

まあそれで、このような病気の因子の例であてはまるかはわかりませんが、もし「飲酒の習慣は病気Xのリスクを上げることこそあれ、下げることはない」「飲酒の習慣の病気Xへの効果の大きさは、男性でも女性でも同じであるはずである」と信じられるなら、以下のどちらかだろうと考えることができます。

  • 飲酒の習慣の病気Xへの効果の大きさ(0かもしれない)は男性でも女性でも同じと仮定した下で、
    1. 男性であっても女性であっても飲酒の習慣と病気Xは無関係である。
    2. 男性であっても女性であっても飲酒の習慣と病気Xは無関係ではない。
この場合はさっきと違って、「飲酒の習慣があって病気Xを発症した男性」と「飲酒の習慣があって病気Xを発症した女性」を足した値を調べてもいいはずです。男女で効果の大きさを同じだと仮定しているから、「足した値が想定する値より大きくなっているかどうか」に意味があります。「想定する値」もまた男女別の分割表で出した上で足さなければなりませんが。男女を足した分割表でそれを出してしまったら、男女別にしていない分割表へのカイ2乗検定と変わらないし、ユール・シンプソンのパラドクスが生じるかもしれませんので。

…みたいな感じだと思っているんですが、テキストの14ページに「マンテル・ヘンツェル検定統計量は、すべての層で処理の効果があるときに検出力の高い指向性検定と位置付けることができる」とあるのが、MH検定は仮定が違うので何かこうもっと趣が違うのではという気がしました。いやしかし、私はカイ2乗検定の原理があやふやなので…。

f:id:cookie-box:20200531131606p:plain:w60

とりあえず 1.4 節に進もう…埒が明かないし…。

f:id:cookie-box:20200531131544p:plain:w60

それもそうですね。この教科書では、「因果ダイアグラムを作成し、バックドア基準に基づく説明変数の選択を行う」というところに向かうようです。統計的因果探索の本では「因果グラフ」といっていた気がしますが、causal diagram と causal graph を調べると前者はフレームワークやモデルで後者はグラフ自体を指していたりするんでしょうか? まあいいですが。…2章では、まず用語が導入されていますね。上でいう「飲酒の習慣があるか」と「病気Xを発症したか」を処理変数と反応変数といいます。処理というと如何にも「薬を投与された」「手術された」のような、誰かに割り付けられたものといった印象がありますが、飲酒や喫煙の習慣など、個体が自ら選択したり自然にそうなったりしたような変数も処理変数とよぶんですね。必要な場合は「治療」と「曝露」といって区別するようですが。そして、処理変数は、counterfactual(そうでなかったかもしれない)なものでなければならないと。

(次回があれば)つづく