深い学習を利用した自然言語処理入門3.カウントベースの単語表現(1)


1.言葉の表現方法


文字を数字で表す方法.
=>数学的特性をベクトル化して表現してこそ,数学−統計的手法/深さ学習により,自然言語だけでは把握できない特性,関係などの結果を導くことができる.
(1)ローカル表現(localrepresentation):単語自体の表現のみを見る=離散(discrete)
(2)分布式表現(分布式表現):語値表現=連続(連続)
よく一緒に現れる単語は似ているので、似たような値マッピングには関心がありません=>分散表示/周囲の単語は、単語の出現頻度に応じて値=>局所表示

言葉の言い回し.
ディスクリート
  • one hot vector
  • N-gram
  • count-based (Bag of words)(DTM)
  • 国所
  • prediction based
  • word2Vec
  • count based
  • fullDocoument : LSA
  • windows : Glove ( +prediction based )
  • 2. BoW (bag of words)

  • 単語出現順を考慮しない
  • 周波数に基づく
  • BoWコース


    (1)単語ごとに一意の整数インデックスを提供する
    (2)インデックスごとの位置に単語タグの出現回数を記録するベクトルを生成する.
    example)
    from konlpy.tag import Okt
    import re  
    okt=Okt()  
    
    token=re.sub("(\.)","","정부가 발표하는 물가상승률과 소비자가 느끼는 물가상승률은 다르다.")  #마침표제거(cleaning)
    token=okt.morphs(token)  
    # OKT tokenizing
    
    word2index={}  
    bow=[]  
    for voca in token:  
             if voca not in word2index.keys():  
                 word2index[voca]=len(word2index)   
                 bow.insert(len(word2index)-1,1)
    # BoW 단어 개수 최소 1개 이상=>default 1
             else:
                index=word2index.get(voca)
                bow[index]=bow[index]+1
    
    print(word2index)  
    ------------------------------------
    ('정부': 0, '가': 1, '발표': 2, '하는': 3, '물가상승률': 4, '과': 5, '소비자': 6, '느끼는': 7, '은': 8, '다르다': 9)  
    bow = [1, 2, 1, 1, 2, 1, 1, 1, 1, 1] 
    BoWは主に特定の単語の頻度で文書の性質を判断するために用いられる.(分類/複数のドキュメント間の類似性)

    非用語BoW exampleの削除


    ユーザー定義の非用語
    from sklearn.feature_extraction.text import CountVectorizer
    
    text=["Family is not an important thing. It's everything."]
    vect = CountVectorizer(stop_words=["the", "a", "an", "is", "not"])
    print(vect.fit_transform(text).toarray()) 
    print(vect.vocabulary_)
    --------------------------------
    [[1 1 1 1 1]]
    {'family': 1, 'important': 2, 'thing': 4, 'it': 3, 'everything': 0}
    nltkは用語をサポートしていません
    from sklearn.feature_extraction.text import CountVectorizer
    from nltk.corpus import stopwords
    
    text=["Family is not an important thing. It's everything."]
    sw = stopwords.words("english")
    vect = CountVectorizer(stop_words =sw)
    print(vect.fit_transform(text).toarray()) 
    print(vect.vocabulary_)
    -----------------------------
    [[1 1 1 1]]
    {'family': 1, 'important': 2, 'thing': 3, 'everything': 0}

    3.DTM=文書単語行列(document-term matrix)


    複数のドキュメント内の各単語の頻度をマトリクスで表します.
    DTMは文書間の関係を表し,BoWに複数の文書があることを考慮する.
    各列/行はドキュメント/単語を表します.
    ex)
  • dtm[n][M]n番目の文書にm個の単語が出現した回数.
  • =>dtmの限界は、疎表現(ソース-ホットベクトルは単語セットのサイズがベクトルの次元を表し、大部分の値が0であり、メモリ/計算リソースの成長効率が0である)/単純な周波数に基づく方法で、類似性基準を簡単に回転させることである.(ex->糖価が急騰した文書と糖の履歴文書は、頻度が一致して類似文書に分類されることがある.)
    =>正規化によるフレーズサイズの縮小/TF-IDFによる重要単語の重み付け

    4. TF-IDF(Term Frequency-Inverse Document Frequency)


    マルチドキュメント/ワード周波数ベース
    単語が出現する頻度と、特定の単語が出現する文書の数(これに反比例する数値)を用いて、各単語に重みを付与する.
    =>重み付けによる各単語の重要度の計算

    TD-IDF


    ドキュメント:d,単語:t,ドキュメント総数nの場合,
    (1)tf(d,t):特定文書dにおける特定単語tの出現回数(term frequency)
    (2)df(t):特定の単語tが現れる文書数(docs frequency)
    (3)idf(d,t):df(t)に反比例する数
    df(t)は0に収束すると発散が無限大になるので,分母に1を加え,logを用いて単語周波数の急激な数値変化を調整する.
    ただし,df(t)に反比例するある数値を作るために,上記の式が出現した.(正規化されているような気がします)
    TF-IDFで
  • すべてのドキュメントによく見られる単語は、重要度が低い(tf-idf値が低い)
  • と考えられています.
  • 特定の文書によく見られる単語のみが重要である(tf-idf値が高い)
  • .


    tf値=特定文書dにおける単語tの頻度:上のdtm行列と同じ.
    idf =


    (上の4/1は、dfが4/1ではなく、4つのドキュメントの1つであることを示しています.dfは、それぞれ1、1、1、2、2、1、1)

    以上
    あやまる
    ドキュメント2-
    ドキュメント3は、長/黄/バナナ
    書類4の中で、果物/私/好きではありません.
    このようなキーワードの大まかなフィルタリング結果が見られる.

    python example(sklearn)

    from sklearn.feature_extraction.text import CountVectorizer
    corpus = [
        'you know I want your love',
        'I like you',
        'what should I do ',    
    ]
    vector = CountVectorizer()
    print(vector.fit_transform(corpus).toarray()) # 코퍼스로부터 각 단어의 빈도 수를 기록한다.
    print(vector.vocabulary_) # 각 단어의 인덱스가 어떻게 부여되었는지를 보여준다
    ---------------------------------------
    [[0 1 0 1 0 1 0 1 1]
     [0 0 1 0 0 0 0 1 0]
     [1 0 0 0 1 0 1 0 0]]
    {'you': 7, 'know': 1, 'want': 5, 'your': 8, 'love': 3, 'like': 2, 'what': 6, 'should': 4, 'do': 0}
    
    from sklearn.feature_extraction.text import TfidfVectorizer
    corpus = [
        'you know I want your love',
        'I like you',
        'what should I do ',    
    ]
    tfidfv = TfidfVectorizer().fit(corpus)
    print(tfidfv.transform(corpus).toarray())
    print(tfidfv.vocabulary_)
    ---------------------------------------
    [[0.         0.46735098 0.         0.46735098 0.         0.46735098 0.         0.35543247 0.46735098]
     [0.         0.         0.79596054 0.         0.         0.         0.         0.60534851 0.        ]
     [0.57735027 0.         0.         0.         0.57735027 0.         0.57735027 0.         0.        ]]
    {'you': 7, 'know': 1, 'want': 5, 'your': 8, 'love': 3, 'like': 2, 'what': 6, 'should': 4, 'do': 0}