Upgrade to Pro — share decks privately, control downloads, hide ads and more …

spaCy Pipeline上でのSHAPを日本語で試してみた

Hiromasa Sakata
April 13, 2022
360

spaCy Pipeline上でのSHAPを日本語で試してみた

2022/4/8開催のNLP Hacks vol.3での発表資料です。

Hiromasa Sakata

April 13, 2022
Tweet

Transcript

  1. 自己紹介 ▪ 名前: 坂田 大直 (さかた ひろまさ) ▪ 所属: 株式会社レトリバ

    ▪ 仕事内容:自然言語処理分野の研究受託、製品開発
  2. SHAPとは? ② • SHAPは X1, X2を特徴量とする。 f 𝑋1 , 𝑋2

    = 1.5 × 𝑋1 + 1.0 × 𝑋2 データポイントi と データポイントj があったとき 𝑥𝑖,1 = 2.0, 𝑥𝑖,2 = 1.0, 𝑥𝑗,1 = 4.0, 𝑥𝑗,2 = 2.0 のとき、 f 𝑋1 = 𝑥𝑖,1 , 𝑋2 = 𝑥𝑖,2 = 4.0, f 𝑋1 = 𝑥𝑗,1 , 𝑋2 = 𝑥𝑗,2 = 8.0 ・エンドポイントiの X2を無視 f 𝑋1 = 𝑥𝑖,1 , 𝑋2 = 𝑥𝑖,2 = 4.0, f 𝑋1 = 𝑥𝑖,1 , 𝑋2 = 𝑥𝑗,2 = 5.0 上記の平均をとる f 𝑋1 = 𝑥𝑖,1 = (4.0 + 5.0) / 2 = 4.5
  3. 文書分類実験 ~ データ準備 ~ • 使用データ:Livedoor NEWSコーパス(https://www.rondhuit.com/download.html) • 2012年9月上旬にLivedoor Newsから収集されたニュース記事のデータセット

    • ニュースサイト名がラベルとして付いている。 • 以下の9種類のラベルが付いたマルチクラス分類タスク 'topic-news', 'livedoor-homme', 'sports-watch', 'smax', 'peachy', 'movie-enter', 'dokujo-tsushin', 'it-life-hack', 'kaden-channel’
  4. 文書分類実験 ~ データ準備 ~ • Ginzaを使用 • Ginza(https://megagonlabs.github.io/ginza/)はSpacyで日本語データを扱うため のライブラリ。 •

    形態素解析器にSudachiPy(https://github.com/WorksApplications/SudachiPy)を 採用している。 • データの読み込み • 読み込んだGinzaの解析器を使ってデータをSpacyの学習コマンドで読み込める形式に変換。 • それぞれのニュース記事をDocクラスのインスタンスに格納。 • この際、Doc.catsにラベル情報を格納。 • 学習データ、開発データ、検証データに分割し、それぞれDocBinクラスに格納。
  5. 文書分類実験 ~ データ準備 ~ • 依存モジュールのインストール • データの読み込み(概略) import spacy

    docs = []c-news', 'livedoor-homme', nlp = spacy.load("ja_ginza_electra") with open(“smax-article.txt”, “r”) as f: doc = nlp(f.read()) doc.cats = {“smax”: 1.0, ‘topic-news’: 0.0, ‘livedoor- homme’:0.0(略) } docs.append(doc) $ $ pip install -U spacy ginza ja-ginza ja-ginza-electra ginzatransformers sudachitra
  6. 文書分類実験 ~ データ準備 ~ データを分割してDocBinに概略 import random Import math random.seed(RANDOM_SEED)

    random.shuffle(docs) num_docs = len(docs) train_docs = docs[: math.floor(num_docs * 0.8)] dev_docs = docs[math.floor(num_docs * 0.8): math.floor(num_docs * 0.9)] test_docs = docs[math.floor(num_docs * 0.9): ] train_doc_bin = DocBin(docs=train_docs) train_doc_bin.to_disk("train_livedoor.spacy")
  7. 文書分類実験 ~ Spacy学習Configの準備~ • GinzaのGitリポジトリから設定ファイルの元をダウンロード https://github.com/megagonlabs/ginza/blob/develop/config/ja_ginza_electra .cfg • 以下の部分を書き換える。 textcatは文書分類用コンポーネント。

    [paths] train = "train_livedoor.spacy" dev = "dev_livedoor.spacy" [nlp] ~(略)~ pipeline = ["transformer", "textcat"] ~(略)~ [components.textcat] factory = "textcat" [components.textcat.model] @architectures = "spacy.TextCatEnsemble.v2" [components.textcat.model.tok2vec] @architectures = "spacy-transformers.TransformerListener.v1" grad_factor = 1.0 pooling = {"@layers":"reduce_mean.v1"} upstream = "*"
  8. 文書分類実験 ~ configの更新と学習コマンド実行~ • 未記入に設定を埋め、学習コマンドの実行。 • livedoor_electra_textcat に文書分類モデルが出力される。 $ python

    -m spacy init fill- config ja_ginza_electra.cfg ja_ginza_electra_filled.cfg $ python -m spacy train ja_ginza_electra_filled.cfg --verbose -- output livedoor_electra_textcat --gpu-id 0
  9. 文書分類実験 ~ SHAPのExpalinerの準備~ ・SpacyのTextCategorizerの出力がSHAPに合わない。Transformersの形式に変更する必要性。 import spacy textcat_spacy = spacy.load("livedoor_electra_textcat/model-best") tokenizer_spacy

    = spacy.tokenizer.Tokenizer(textcat_spacy.vocab) classes = list(textcat_spacy.get_pipe("textcat").labels) def predict(texts): texts = [str(text) for text in texts] results = [] for doc in textcat_spacy.pipe(texts): results.append([doc.cats[cat] for cat in classes]) return results
  10. 文書分類実験 ~ Spacyの出力のラッパーの準備~ ・SpacyのTextCategorizerの出力がSHAPに合わない。Transformersの形式に変更する必要性。 import spacy textcat_spacy = spacy.load("livedoor_electra_textcat/model-best") tokenizer_spacy

    = spacy.tokenizer.Tokenizer(textcat_spacy.vocab) classes = list(textcat_spacy.get_pipe("textcat").labels) def predict(texts): texts = [str(text) for text in texts] results = [] for doc in textcat_spacy.pipe(texts): results.append([doc.cats[cat] for cat in classes]) return results
  11. 文書分類実験 ~ SHAPのExplainerに渡す~ ・先ほどのpredict関数とtransformersのtokenizerを渡す。 from sudachitra import ElectraSudachipyTokenizer tokenizer =

    ElectraSudachipyTokenizer.from_pretrained("megagonlabs/tra nsformers-ud-japanese-electra-base-discriminator") explainer = shap.Explainer( predict, masker=shap.maskers.Text(tokenizer=tokenizer), algorithm="permutation", output_names=classes, max_evals=1500, )
  12. 参考文献 • Spacy ドキュメント(https://spacy.io/usage) • Pythonではじめる テキストアナリティクス入門 榊 剛史 (編集,

    著), 石野 亜耶 (著), 小早川 健 (著), 坂地 泰紀 (著), 嶋田 和孝 (著), 吉田 光男 (著), 講談社 • 機械学習を解釈する技術 森下 光之助 (著),