Word2Vec 학습된 모델을 이용한 문서 벡터의 2차원 시각화

15157 단어 word2vec파이썬

개요


  • Word2Vec에서 특허 문장판 분산 표현 모델 을 작성한 분이 있었으므로, 이 학습이 끝난 모델을 사용해 (로드해) 텍스트 정보의 벡터화를 실시해, 단어 벡터화→문서 벡터의 생성→2차원 시각화를 할 수있는 코드를 만들었습니다.
  • 방대한 데이터량을 입력으로 하는 학습 모델의 생성은, 개인의 PC 스펙에서는 어렵습니다만, 이렇게 학습 끝난 모델을 공개해 주실 수 있으면 여러가지 시험할 수 있기 때문에 고맙습니다.

  • 환경



    OS: macOS Catalina
    언어: python3.6.6

    코드



    여기가 만든 코드입니다. 일본어 형태소 해석에서는 MeCab을 이용하고 있습니다. Word2Vec 모델은 300차원으로 2차원으로 줄이기 위해 scikit-learn의 TSNE를 사용합니다.

    patent_w2v_JP.py
    from sklearn.manifold import TSNE
    from gensim.models import word2vec
    from statistics import mean
    import string
    import re
    import MeCab
    import pandas as pd
    import numpy as np
    
    #インプットデータの読み込み
    df = pd.read_csv('input.csv', encoding="utf-8")
    #タイトルと要約を結合
    df['text'] = df['title'].str.cat(df['abstract'], sep=' ')
    
    #ストップワードのリスト(もしあればこのリストに追記する)
    stop_words = []
    
    #MeCabトークナイザー
    def mecab_token_list(text):
        token_list = []
        tagger = MeCab.Tagger()
        tagger.parse('') 
        node = tagger.parseToNode(text)
        while node:
            pos = node.feature.split(",")
            if not node.surface in stop_words: #ストップワードは除外
                if pos[6] != '*': #見出語があればそれを追加
                    token_list.append(pos[6])
                else: #なければ表層語を追加
                    token_list.append(node.surface)
            node = node.next
        return list(token_list)
    
    #数字を除去
    df['text_clean'] = df.text.map(lambda x: re.sub(r'\d+', '', x))
    #英文字は全て小文字に統一
    df['text_clean'] = df.text_clean.map(lambda x: x.lower())
    #MeCab Tokenize
    df['text_tokens'] = df.text_clean.map(lambda x: mecab_token_list(x))
    
    #Word2Vecモデルの読み込み
    model = word2vec.Word2Vec.load("patent_w2v_d300_20191125.model")
    
    #データフレームを300次元の配列に初期化
    doc_vec = np.zeros((df.shape[0], 300))
    #各文書における出現単語のモデルカバー率を格納するリストを用意
    coverage = []
    #各文書の平均ベクトルを配列に格納
    for i,doc in enumerate(df['text_tokens']): #形態素解析後のテキスト情報を文書順に処理
        feature_vec = np.zeros(300) #300次元分を0に初期化
        num_words = 0
        no_count = 0
        for word in doc: #各文書の単語ごとに処理
            try: #単語ベクトルを加算していく処理
                feature_vec += model.wv[word]
                num_words += 1
            except: #分析モデルの対象外の単語はパスする
                no_count += 1
        #得られた単語ベクトルの和を単語数で割って平均値を計算し、文書ベクトルとして格納
        feature_vec = feature_vec / num_words
        doc_vec[i] = feature_vec
        #文書ごとの単語カバー率を計算し格納
        cover_rate = num_words / (num_words + no_count)
        coverage.append(cover_rate)
    
    #単語の平均カバー率を表示
    mean_coverage = round(mean(coverage)*100, 2)
    print("Word cover-rate: " + str(mean_coverage) + "%")
    
    #t-SNEによる次元削減
    tsne= TSNE(n_components=2, init='pca', verbose=1, random_state=2000, perplexity=50, learning_rate=200, method='exact', n_iter=1000)
    embedding = tsne.fit_transform(doc_vec)
    #DataFrameに格納
    embedding = pd.DataFrame(embedding, columns=['x', 'y'])
    embedding["id"]= df.id
    embedding["year"]= df.year
    embedding["title"]= df.title
    embedding["abstract"]= df.abstract
    
    #CSVファイルとして出力
    embedding.to_csv("output.csv", encoding="utf_8")
    
    

    입력 데이터 구성


  • 인풋 데이터는 특허 문서를 상정해, 아래와 같은 CSV 형식으로 id, year(출원년 등), title(발명의 명칭), description(본문) 등의 데이터가 포함되어 있는 것을 전제로 한다. 합니다. 이 근처는 적절히 어레인지 해 주시면 좋겠습니다.



  • id
    title
    year
    description


    1
    (발명의 명칭)
    (출원년 등)
    (본문)

    2
    ···
    ···
    ···


  • 입력 데이터 (input.csv)와 Word2Vec 모델과이 파이썬 스크립트는 모두 동일한 디렉토리에 있다고 가정합니다. 이 근처는 구성에 따라 적절히 어레인지해 주십시오.

  • 유의점


  • Word2Vec 의 단어 벡터로부터 문서 벡터를 생성하는 방법으로서는, 각 문서에 포함되는 단어 벡터의 평균치를 문서 벡터로 하는 방법을 채용하고 있습니다.
  • 일단, 출현 단어의 해당 모델에 있어서의 커버율을 콘솔에서 표시하도록(듯이) 설정하고 있습니다. 이것은 각 문서의 단어 커버리지를 평균값으로 계산합니다.
  • 다른 목적으로 작성한 코드를 베이스로 하고 있기 때문에, 샘플 데이터로 동작 확인은 하고 있습니다만, 실제의 특허문헌의 데이터 세트에서는 시도할 수 없습니다. J-PlatPat 라든지로 취득하면 좋을까.

  • 2차원 시각화 이미지



    matplotlib등을 사용하면 python만으로 가시화까지 할 수 있는 것 같습니다만, 참고까지 GIS(지리 정보 시스템)를 전용해 가시화하면 이러한 표현이 됩니다.
    각 플롯은 문서 데이터이며 2차원 평면에서의 집중도에 따라 히트맵화됩니다. 이러한 표현은 분류나 분석의 베이스로서 유용할까 생각합니다.

    좋은 웹페이지 즐겨찾기