深い学習を利用した自然言語処理入門4.Vector Similarity(1)


0. Vector Similarity


機械的に計算した文書類似度の性能は,各文書の単語をどのような方法で数値化したか(DTM,Word d 2 Vecなど),文書間の単語差(ユークリッド距離,コサイン類似度など)をどのように計算したかに依存する.前者が単語(数値化)を表す方法/後者がvector類似性を表す

1. Cosine similarity

  • コサイン類似度:2つのベクトル間のコサイン角度を用いて求めることができる2つのベクトルの類似度
  • .

    cosine similarity


    深さ学習においても機械学習においても,ベクトル表現(行列)は重要な基礎概念であるようだ.
    復習しながら振り返りましょう
    内敵の意味は以下の通り.


    (証明)
  • の基本的な意味は、各成分の積の和である.
    @2つの基板(base)が垂直である場合、ex(0,1)/(1,0)=>成分積の和は0である.
    =>各成分の類似性が低下
    @2つの基板(base)が平行である場合、直感的に同じである.正規化の場合、ex)(1/2)^(1/2),(1/2)^(1/2))の成分積は1となる.=>各成分の類似性が高い
  • ジオメトリ上の2つのベクトル間の挟み角のコサイン値とベクトルサイズの積.
    2つの基底が垂直である場合、1つのベクトル(A)が別のベクトル(B)に投影されるとき、Aの長さは0である.類似性は0と考えられる.
    2つの基板が平行である場合=>投影時の長さは一定(空間的に類似)
  • である.
    =>vector最終cosine角は類似性判断基準とすることができる.(サイズは標準)

    類似=コサイン角=(A・B)/(|A|||||B|)=成分乗算/ベクトルサイズ乗算

    cosine類似性応用例


    3つのドキュメント、
         문서1 : 저는 사과 좋아요
         문서2 : 저는 바나나 좋아요
         문서3 : 저는 바나나 좋아요 저는 바나나 좋아요
    について
    from numpy import dot
    from numpy.linalg import norm
    import numpy as np
    
    def cos_sim(A, B):
           return dot(A, B)/(norm(A)*norm(B))
           
    doc1=np.array([0,1,1,1])
    doc2=np.array([1,0,1,1])
    doc3=np.array([2,0,2,2])
    
    print(cos_sim(doc1, doc2)) #문서1과 문서2의 코사인 유사도
    print(cos_sim(doc1, doc3)) #문서1과 문서3의 코사인 유사도
    print(cos_sim(doc2, doc3)) #문서2과 문서3의 코사인 유사도
    
    #---------------------------------#output
    0.67
    0.67
    1.00
    
    =>doc 2,3は大きさが異なるだけで方向が同じなので類似度は1である.

    3.コサイン類似度推奨システム例)


    tf−idf指数のcosine類似性により、映画タイトル−シナリオ概要間の類似性の例を理解する.
    (1)データのロード
    data ) https://www.kaggle.com/rounakbanik/the-movies-dataset
    import pandas as pd
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.metrics.pairwise import linear_kernel
    import os
    
    from google.colab import drive
    drive.mount('/content/drive') #googledrive mount
    
    data = pd.read_csv('./drive/MyDrive/movies_metadata.csv', low_memory=False) #data load 
    data.head(2)
    
    i...original_titleoverview...titlevideo0...Toy StoryLed by Woody, Andy's toys live happily in his ... 中略Toy StoryFalse1...JumanjiWhen siblings Judy and Peter discover an encha ... 中略JumanjiFalse
    データセットはKaggleのTheMovies Data Setです.
    cosine類似オブジェクトフィーチャーはtitle列とoverview列です.
    =>goalは、ムービー入力時にムービーストーリーに似たムービーを検索して推奨するシステムです.
    (2)データサンプルと測定値の削除
    data = data.head(20000)
    data['overview'].isnull().sum() #135
    # overview에서 Null 값을 가진 경우에는 Null 값을 제거
    data['overview'] = data['overview'].fillna('')
    
    20,000個のサンプルデータを抽出し、欠落したデータを削除します(空).
    (3) tf-idf
    tfidf = TfidfVectorizer(stop_words='english')
    # overview에 대해서 tf-idf 수행
    tfidf_matrix = tfidf.fit_transform(data['overview'])
    #print(tfidf_matrix.shape) # (20000, 47487)
    tf-idfを求めます.=>このとき、overviewdocsでtfidfVectorizerを使用してtoken split->tokenとドキュメント間の周波数マトリクスtfマトリクス->idf計算->tfidfマトリクスを生成します.
    以下はtfmatrixの概略外観(0番ドキュメントと809番token tf-idf=0.1506886.)
    (0, 809)	0.15068863901965732
    (0, 210)	0.15068863901965732
    (0, 1657)	0.11703946979728948
    (0, 998)	0.1211799516296032
    (0, 904)	0.13979786049282722
    (0, 2042)	0.13207073015643328
    (0, 2557)	0.15068863901965732
    (0, 524)	0.13979786049282722
    (0, 2145)	0.15068863901965732
    (0, 1332)	0.13207073015643328
    (0, 2122)	0.11703946979728948
    (0, 1725)	0.13979786049282722
    (0, 106)	0.15068863901965732
    (0, 2510)	0.13979786049282722
    ..
    .. 
    (4) cosine similarity & index
    cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)
    
    indices = pd.Series(data.index, index=data['title']).drop_duplicates() #타이틀 입력시 인덱스 리턴 용도
    print(indices.head()) #5개만 출력
    --------------------------------------------
    title
    Toy Story                      0
    Jumanji                        1
    Grumpier Old Men               2
    Waiting to Exhale              3
    Father of the Bride Part II    4
    dtype: int64
    sklearningからsckitを勉強します.metrics.ペアimport linear kernelの使用
    コサイン類似度計算.
    #cosine_sim
    
    (20000, 20000)
    [[1.         0.01575748 0.         ... 0.         0.         0.        ]
     [0.01575748 1.         0.04907345 ... 0.         0.         0.        ]
     [0.         0.04907345 1.         ... 0.         0.         0.        ]
     ...
     [0.         0.         0.         ... 1.         0.         0.08375766]
     [0.         0.         0.         ... 0.         1.         0.        ]
     [0.         0.         0.         ... 0.08375766 0.         1.        ]]
    20000個のサンプルセットについて、各データ間のコサイン類似度を求めることによって格納されるマトリクス.cosines sim[n][m]は、n番目のデータセットとm番目のデータセットの概要の類似性である.
    (5)cosine類似性overview類似を利用した10個の映画return関数
    def get_recommendations(title, cosine_sim=cosine_sim):
        # 선택한 영화의 타이틀의 인덱스 저장
        idx = indices[title]
    
        # 모든 영화에 대해서 해당 영화와의 유사도 구함
        sim_scores = list(enumerate(cosine_sim[idx]))
    
        # 유사도에 따라 영화 정렬
        sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
    
        # 가장 유사한 10개의 영화
        sim_scores = sim_scores[1:11]
    
        # 가장 유사한 10개의 영화의 인덱스
        movie_indices = [i[0] for i in sim_scores]
    
        # 가장 유사한 10개의 영화의 제목을 리턴
        return data['title'].iloc[movie_indices]
    (6)似たような映画を探す
    get_recommendations('The Dark Knight Rises')
    ------------------------------------------------
    12481                            The Dark Knight
    150                               Batman Forever
    1328                              Batman Returns
    15511                 Batman: Under the Red Hood
    585                                       Batman
    9230          Batman Beyond: Return of the Joker
    18035                           Batman: Year One
    19792    Batman: The Dark Knight Returns, Part 1
    3095                Batman: Mask of the Phantasm
    10122                              Batman Begins
    Name: title, dtype: object