40. 課題3:クチコミデータへ自然言語処理を適用してみよう。#

Japanese Realistic Textual Entailment Corpusを題材に、クチコミを感情推定するモデルを構築してみよう。また失敗要因分析を通して改善案を検討しよう。

Note

上記リンク先の「References」には、このデータセットを用いた研究論文へのリンクがある。少なくとも1節には目を通し、データセットの背景を確認しておこう。

  • 全体の流れ

    • Level 0: データセット構築。(報告不要、20分)

    • Level 1: 単語出現回数を特徴とする特徴ベクトルの構築。(30分想定)

    • Level 2: 識別学習。(30分想定)

    • Level 3: 失敗要因分析。(1.5〜3時間想定)

    • Level 4: 仮説に対する軽い検証。(30分〜1時間想定)

    • オプション例

    • 提出物


40.1. Level 0: データセット構築。(報告不要、20分)#

  • Level 0 の目的

    • 本課題では spacy を用いることを想定している。データ数は約1万件とさほど多くないが、それでも解析器による処理には時間を要する。具体的にはnlpによる処理だけで数分かかる。この間はただ単に待つことしかできない。待っても良いがその間に集中が途切れ、やる気が薄れてしまうこともあるだろう。

    • このような状況を避けるため、nlpによる処理結果をテキストファイルとして保存しておく。それ以降はテキストファイルを読み込むだけでそれ以降の課題に取り組むことができるようになる。

  • ファイル説明

    • pn.tsv: 実データ。(ノートブック内でダウンロードして用意)

    • build_dataset.ipynb: nlp処理した結果をテキストファイルとして保存するプログラム。

    • (pn_add.pkl: 上記プログラムで生成されるバイナリファイル。便宜上pickleファイルと呼ぶことにする) このプログラム自体をダウンロードして利用してもよいが、そこそこ時間かかる点に注意。

    • example_pickle_load.ipynb: pickleファイルを読み込んで、docオブジェクトを利用できることを確認しているコード例。

  • 実行手順

    • step 1: 自身のGoogleドライブ直下に「2024dm-rep3」というフォルダを作成する。

    • step 2: 共有ドライブ/2024-rep3-tips を参照する。

      • (1) build_dataset.ipynb, (2) example_pickle_load.ipynb の2点をダウンロードする。

      • これらを step 1で用意した自身の「2024-rep3」フォルダにアップロードする。

    • step 3: build_dataset.ipynbを実行(数分)。

      • Googleドライブへのアクセス設定のため、アクセスを許可する必要あり。(ポップアップウィンドウで許可)

      • 実行が終わると、(3) pn_add.pkl という約128MBのファイルが生成される。

    • step 4: example_pikcle_load.ipynb を実行し、pickleファイルを読み込んで実行できることを確認。

  • 補足説明

    • example_pikcle_load.ipynbのように変数dfに読み込むと、5553 rows × 6 columnsの表になっているはずだ。列は以下の通り。

      • id: ユニークID。

      • sentiment: ラベル。1 (Positive), 0 (Neutral), -1 (Negative)

        • -1 が扱いにくい場合には別のラベルに置き換えても構いません。置き換えた場合にはレポート内に記載すること。

      • text: テキスト。

      • judges-json: 3人分のアノテーション結果。これの多数決をしたものが sentiment 列。

      • usage: データ種別。train, dev, test。

        • 学習時にはtrainのみ、もしくは train, dev までを用いること。テスト時には test のみを用いること。

      • doc: nlp(text)により用意したdocオブジェクト(解析結果)。


40.2. Level 1: 単語出現回数を特徴とする特徴ベクトルの構築。(30分想定)#

  • 前提

    • pn_add.pklを変数dfに読み込んでおくこと。

  • やること

    • df[“text”]の全テキストに対し、CountVectorizerを用いて単語出現回数を特徴とする特徴ベクトルを構築せよ。なお、Level 1〜4 の範囲では CountVectorizer をカスタマイズをしてはならない。CountVectorizerをオプション指定なしに利用すること。

    • CountVectorizer.fit_transform() で構築したベクトル集合を、変数 X に保存するものとする。

    • CountVectorizer.get_feature_names_out() の実行結果(ベクトル構築時に生成された特徴)を、変数 features に保存するものとする。

  • 報告事項

    • (1) features[:5] の出力結果。

      • 参考: array(['00', '020', '10', '100', '1000'], dtype=object)) となっていることを確認しよう。

    • (2) len(features) の結果。

      • 参考: 3616 となっていることを確認しよう。

    • (3) X[0] の出力結果。

    • (4) X[0]の出力結果の1行目は (0, 1604) 1 となっているはずだ。これは「サンプル0は、特徴1604が1回出現した」ことを意味する。特徴1604の中身を報告せよ。

    • (5) X[0] に相当する元のテキスト文。


40.3. Level 2: 識別学習。(30分想定)#

  • 前提

    • usage列を参照し、学習用データ(X_train, y_train)、開発用データ(X_dev, y_dev)、テスト用データ(X_test, y_test)を用意すること。

    • ヒント

      • train_indices = df[df["usage"] == "train"].index とすることで、train に該当するインデックスを取得できます。

      • y_train = df[df["usage"] == "train"]["sentiment"].tolist() とすることで、trainに該当する教師ラベルを取得できます。

  • やること

    • 任意の分類器を用いて識別学習を実行せよ。この時点では学習用データのみを用いること。

    • 学習用データ、テスト用データに対する分類精度を求めよ。

  • 報告事項

    • (1) X_test[0] の出力結果。Level 1 (3) と同一になっていることを確認しよう。

    • (2) y_train, y_dev, y_test それぞれの要素数。len(y_train)=3888, len(y_dev)=1112, len(y_test)=553 となることを確認しよう。

    • (3) 学習用データ、テスト用データに対する分類精度。


40.4. Level 3: 失敗要因分析。(1.5〜3時間想定)#

好きな方法で失敗要因分析を行い、以下の事柄について報告せよ。

  • 報告事項

    • (1) 分析方法の説明。

      • 本来なら train, dev のみで分析する必要があります。しかし今回は分析する練習なので、testを含めた全データを対象としても良いものとします。

    • (2) 分析結果。結果に基づいた精度改善案(仮説)の立案。

      • 改善案をエビデンスに基づいて立案する練習です。必ず改善する案を求めているわけではありません。結果的に改善しなくても構いません。

      • 改善案は必ず結果に基づいてください。根拠を示さず別アプローチを提案する場合には大幅減点になります。

  • ヒント

    • 分析方法思いつかない人は以下の方法で取り組んでみよう。

    • step 1: 失敗事例をN件選ぶ。N=10件〜数十件。

      • 全失敗例を観察するのはコストが高いので、失敗事例を抽出し、そこからランダムにN件選ぶとよいでしょう。ランダムにしているのはreporting biasになることを避けるためです。

    • step 2: 仮説立案。

      • 選んだ失敗事例の元テキストを参照し、「恐らく失敗した要因はこういうことではないか(=仮説立案)」と思いついたことを列挙する。思いついただけ列挙すること。

      • 仮説をラベルとして設定しておくとベター。

    • step 3: これを数回繰り返す。

      • step 2 を失敗事例N件について一度通して行うだけでなく、N件について2〜3回繰り返す。複数回繰り返す理由は、他の例文を見ることで新たな気づきを得られることがあるためです。

    • step 4: 仮説の整理。

      • ラベルとして付与したならば、失敗事例N件それぞれに対して1つ以上のラベルが付与されていることになります。この中でラベルの出現回数をカウントすることで、「カウントが多いラベル」を抽出することができます。そのラベル(=その仮説)は多くの失敗事例に共通している可能性が高そうだと目星をつけることができるでしょう。このようにして出現回数をエビデンスとした仮説を提示することができます。

      • カウントは優先順位をつける一つの例として示しています。最多出現回数一つの仮説に絞る必要はありません。


40.5. Level 4: 仮説に対する軽い検証。(30分〜1時間想定)#

仮説の妥当性を簡易的にチェックするため、新たな文とラベルをN件ずつ用意しよう。N=2以上とする。

  • 前提

    • 新たな文を new_texts = ['文1', '文2'] としてリストで用意し、変数new_textsに保存すること。

    • 教師ラベルを new_labels = [label1, label2] としてリストで用意し、変数new_labelsに保存すること。

  • ヒント

    • 例えば「失敗事例の多くに共通していたのは比較が含まれていることだった」ならば、改善案として「比較は含まれている文を正しく理解すること」になるかもしれない。この場合には「比較が含まれていて positive となる新しい文。比較が含まれていて negative となる新しい文」の2文を用意し、それらの予測が失敗することを確認することになるだろう。想定通り失敗するようなら、この改善案を組み込んだ実装を検討する価値が高いという根拠の一つになるだろう。

  • やること

    • new_textsをspacyで処理し、分かち書きした文字列を用意する。

    • Level 1で用意した CountVectorizer をそのまま用いて、ベクトル化する。これを new_X として保存する。

      • 「Level 1で用意したCountVectorizerをそのまま用いる」点に注意すること。ここで改めて CountVectorizer.fit_transform() を実行してしまうと、特徴(次元設計)が変わり、元のベクトル空間とは違うベクトルを生成してしまう。Level 1 で X = vectorizer.fit_transform(corpus) のように実行したのだとすると、この vectorizer を用いて次のように実行すると良い。 new_X = vectorizer.transform(new_texts)。こうすることで同じ特徴(同じベクトル空間)における新しいテキストに対するベクトルを生成することができる。

    • Level 2で構築したモデルを用いて new_X に対する予測を出力する。

    • 予測結果とnew_labelsと比較し、仮説の妥当性について考察する。

  • 報告事項

    • (1) 作成した new_texts, new_labels を表として掲載すること。

    • (2) 仮説の妥当性に対する考察。

      • 仮説が誤りだったという結論でも問題ありません(減点しません)。結果に基づいて論理的に考察してください。


40.6. オプション例#

  • Level 3 で立案した仮説を検証するコードの実装、実験、評価。

  • Level 3 で取り組んだこととは別アプローチによる要因分析、仮説立案。

    • (3) (2)に基づいた実験設計(実装解説)。

    • (4) 修正実装による学習用データ、テスト用データに対する分類精度。


40.7. 提出物#

  • レポート

  • コード(ノートブック)