ゼロベース入門NLP-深さ学習に基づくテキスト分類1


学習目標
  • FastTextの使用と基礎パラメータ
  • を学ぶ
  • クロス検証による精度向上
  • テキスト表示方法Part 2
    従来のテキスト表現方法の欠陥
    前節では,いくつかのテキスト表現方法を紹介した.
  • One-hot
  • Bag of words(BoW)
  • N-gram
  • TF-IDF

  • 以上の方法はある程度テキストをよく表すことができるが、テキスト種の限られた情報しか掘り起こすことができず、ドキュメント種の単語の統計的特徴に注目し、単語間の相互関係を無視し、多かれ少なかれ次元が高すぎるという問題がある.
    また、以上のように訓練するモデルは、他のタスクにほとんど移行できない.異なるタスクには異なる辞書があるため、訓練したモデルの辞書をほとんど修正することはできない.
    この節では、深い学習に基づくFastTextの1つを紹介します.それはより効率的で、表現能力もより強いです.
    FastText紹介
    FastTextは効率的な語表現と文分類のためのライブラリであり、fasttextは2つのモデルを提供して語表現を計算し、それぞれcbowとskip-gramである.この2つのモデルについて簡単に説明します.
    紹介する前に、Word Embeddingという概念を理解する必要があります.cbowとskip-gramはword embeddingの具体的な実現方式であるからである.
    word embeddingは実はもっと前の節の中の語の表現方法に似ていて、それは実は語の量子化の表現形式で、私たちがRGB 3の値で1つの画素を表すのと同じです.
    では、なぜembeddingが必要なのか、例えば人間の言語では、語catdogが動物であり、両者が近いのに、どのように2つの語が似ているかを表すのか.例えばintelligentcleverはいずれも聡明で、同じ意味を持っていることを表すことができる.このような単語の意味関係もたくさんあります.
    word embeddingはこのような意味関係を量子化してこの問題を解決することができ、word embeddingでは、同じカテゴリの語ベクトルが埋め込み空間の中で比較的近い、すなわち相互間の距離が比較的小さいことを期待している.関係のない言葉は遠く離れているはずだなど.
    では、単語間の意味情報を考慮して単語を量子化するにはどうすればいいのでしょうか.
    CBOW(continuous bag of words)
    CBOWは連続語袋モデルとも呼ばれ、3層の全接続ニューラルネットワークからなり、下図に示すように各単語のコンテキストを入力としてコンテキストに対応する単語を予測する.例えば次の例:Have a great daygreatをネットワーク入力として、単一コンテキスト入力greatを用いて目標単語dayを予測することを試みる.具体的には、入力単語のone-hotベクトル入力を用いる、ターゲット単語(day)のone-hotベクトルとネットワーク出力の損失を評価する.ターゲット単語のone-hotベクトルを予測する過程で、ネットワークはターゲット単語のベクトル表現(暗黙層の出力)を学習する.
    上図に戻ると、コンテキスト入力は$V$のone-hotベクトルであり、隠層は$N$個のニューロンを含み、ネットワークの出力は$V$のsoftmax活性化関数出力である.
    ネットワーク全体で最後のアクティブ化関数(softmax)しかない、入力層と暗黙層の間にアクティブ化関数はない.
    上のネットワークは1つのコンテキスト単語だけでネットワークを訓練し、下のネットワークは$C$のコンテキスト単語、$W_を使用しています.{Vtimes N}$暗黙層の入力を計算するために使用
    文中の各単語をtargetとし、残りの単語をコンテキストとして入力、ネットワークを訓練し、最終的にすべての語ベクトルを得ることができる.
    Skip-gram
    現在、1つの文に固定サイズのスライドウィンドウがある、ウィンドウの真ん中にある単語をtarget、ウィンドウ内の残りの単語(target左とtarget右の単語)をコンテキスト単語とすると仮定する.
    skip-gramモデル訓練は、所与のtargetにおけるコンテキスト単語の確率分布(softmaxの出力)を予測するために用いる.skip-gramモデルの構造を下図に示します.
    例えば次のようにskip-gramモデルを用いて各語のベクトル表現を得る.
    “The man who passes the sentence should swing the sword.” – Ned Stark
    ウィンドウサイズを5に設定すると、ウィンドウが移動するたびに対応するtargetcontextが次の表のようになります
    Sliding window (size = 5)
    Target word
    Context
    [The man who]
    the
    man, who
    [The man who passes]
    man
    the, who, passes
    [The man who passes the]
    who
    the, man, passes, the
    [man who passes the sentence]
    passes
    man, who, the, sentence



    [sentence should swing the sword]
    swing
    sentence, should, the, sword
    [should swing the sword]
    the
    should, swing, sword
    [swing the sword]
    sword
    swing, the
    skip-gramモデルの構造はcbowモデルが水平に反転するようにcbowモデルの構造とは正反対であることがわかる.
    FastTextのインストールと使用
    FastTextはlinuxまたはMacOsシステムへのインストールを推奨、C++11のサポートが必要であり、以下のインストール手順はlinuxシステムで行う.
    #   FastText   
    !wget  https://github.com/facebookresearch/fastText/archive/v0.9.2.zip
    
    #   
    !unzip v0.9.2.zip
    
    # 
    %cd fastText-0.9.2
    
    #        
    !make
    
    #   python,   
    !pip install .
    %cd ..

    インストールに成功したかどうかをテスト
    #      
    !./fastText-0.9.2/fasttext
    
    # python    
    import fasttext  
    help(fasttext.FastText)
    

    正常な関連コマンド情報を出力できる場合は、インストールに成功しました.
    準備が整い次第、FastTextを使ってテキストを分類することができます.
    #    
    import pandas as pd
    import os
    from collections import Counter
    import matplotlib.pyplot as plt
    from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
    from sklearn.metrics import  f1_score
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import RidgeClassifier
    
    %matplotlib inline
    
    import fasttext
    # help(fasttext.FastText)
    
    #     
    root_dir = '/content/drive/My Drive/competitions/NLPNews'
    df = pd.read_csv(root_dir+'/train.csv', sep='\t', nrows=30000)
    
    
    #              fasttext      , label   `__label__`  
    df['label'] = df['label'].apply(lambda x: '__label__' + str(x))
    train_df = df.loc[:27000, ['text', 'label']]
    train_df.to_csv('train.csv', header=False, index=False, sep='\t')
    
    
    # loss = 'hs'    hierarchical softmax,   softmax   ,      
    """
    epoch:     [5, 50]
    lr:     [0.0, 1.0]
    wordNgrams:     [1, 5]
    """
    model = fasttext.train_supervised('train.csv', lr=0.1, wordNgrams=2, verbose=2, minCount=1, epoch=25, loss="hs")
    
    val_pred = [model.predict(x)[0][0].split('__')[-1] for x in df.iloc[-3000:]['text']]
    
    # val_df = train_df.iloc[-3000:]
    
    print('F1_score', f1_score(df.iloc[-3000:]['label'].apply(lambda x: x.split('__')[-1]), val_pred, average='macro'))

    F1_score: 0.8008228595916222
    クロス検証パラメータ
    ここでは10折のクロス検証を用いる、データを訓練セット:検証セット=9:1によって区分するが、ここではデータ量が大きいため、この割合は問題ない.訓練セットと検証セットが同分布であることを保証する必要があることに注意しなければならない.
    wordNgrams:[2,3,4]などのパラメータ探索範囲を予め設定し、探索範囲内の各値をクロス検証し、最後に最も高いf 1-scoreに対応するパラメータをとることができる.
    まとめ
    ここでは,深さ学習に基づくテキスト表示方法CBOWとSkip-gramの2種類を主に学習し,同時にFastTextライブラリを用いてテキストを分類した.ハードウェアの制約のため、モデルのクロス検証はしばらく行われず、簡単な説明にすぎない.
    Reference
    [1] FastText install tutorial
    [2] Text classification
    [3] Introduction to Word Embedding and Word2Vec
    [4] Learning Word Embedding
    [5] NLP 101: Word2Vec — Skip-gram and CBOW
    [6] Datawhaleゼロ基礎入門NLP試合-Task 4深さ学習に基づくテキスト分類1-fastText