Bert에서 EC 사이트의 상품 유사도 계산

개요



제품 설명과 제목을 Bert를 사용하여 벡터화하여 제품 간의 유사성을 표현할 수 있는지 테스트합니다.

준비



다음 colab 환경에서 구현합니다.

계정 인증


from google.colab import auth
auth.authenticate_user()

tensorflow 버전 변경



이번에 사용할 소스 코드에 따라 colab에 설치된 tensorflow 버전을 변경합니다.
#tensorflowを1x系に戻します
!pip uninstall -y tensorflow
!pip install tensorflow==1.15.0

입력 데이터와 Bert 소스 코드 준비


#必要なファイルを用意する
#こちらの記事を元にjumanppを使用できるようにコードを修正 https://dev.classmethod.jp/articles/bert-text-embedding/
!gsutil cp -r gs://${your_gcs_path}/bert ./
#日本語wikiで学習したモデルを取得 http://nlp.ist.i.kyoto-u.ac.jp/index.php?BERT%E6%97%A5%E6%9C%AC%E8%AA%9EPretrained%E3%83%A2%E3%83%87%E3%83%AB#k1aa6ee3
!gsutil cp -r gs://${your_gcs_path}/Japanese_L-12_H-768_A-12_E-30_BPE ./
#入力データを用意 (今回はamazonの電子書籍のタイトル+商品説明文)
!gsutil cp -r gs://${your_gcs_path}/inputdata ./

JUMAN++ 설치



# 以下を参照してjumanppをインストールする
#https://github.com/ku-nlp/jumanpp
!wget https://github.com/ku-nlp/jumanpp/releases/download/v2.0.0-rc3/jumanpp-2.0.0-rc3.tar.xz
!sudo apt install cmake
!tar xJvf jumanpp-2.0.0-rc3.tar.xz
%cd jumanpp-2.0.0-rc3/
!mkdir bld
%cd bld
!cmake ..
!sudo make install

환경 변수 설정


%env MODEL=Japanese_L-12_H-768_A-12_E-30_BPE
%env OUTPUT=output
%env INPUT=inputdata

출력 디렉토리 만들기


%cd ../
!mkdir output

Bert로 상품 벡터화


# item.txt : 商品タイトル + 商品説明
!python ./bert/extract_features.py  --input_file=${INPUT}/item.txt  --output_file=${OUTPUT}/output.jsonl  --vocab_file=${MODEL}/vocab.txt  --bert_config_file=${MODEL}/bert_config.json  --init_checkpoint=${MODEL}/bert_model.ckpt  --do_lower_case False  --layers -2

상품 간 거리 행렬 만들기



Bert의 출력 결과에서 벡터 정보 얻기


import json
import numpy as np
import pandas as pd

# 参照するレイヤーを指定する
TARGET_LAYER = -2

# 参照するトークンを指定する
SENTENCE_EMBEDDING_TOKEN = '[CLS]'

file ="./output/output.jsonl"

with open(file, 'r') as f:
    output_jsons = f.readlines()

embedding_list = []
for output_json in output_jsons:
    output = json.loads(output_json)
    for feature in output['features']:
        if feature['token'] != SENTENCE_EMBEDDING_TOKEN: continue
        for layer in feature['layers']:
            if layer['index'] != TARGET_LAYER: continue
            embedding_list.append(layer['values'])

np.savetxt('output.tsv', embedding_list, delimiter='\t')

상품 제목 + 상품 벡터 행렬 만들기


#商品のベクトル
output = pd.read_csv("output.tsv", sep='\t',header=None)
#商品のタイトル
title = pd.read_csv("inputdata/title.txt", sep='\t',header=None, names=["title"])
#商品タイトルとベクトルを結合
res = pd.concat([title, output], axis=1)
# データを確認
res.head(3)



상품 간의 거리 계산


from scipy.spatial import distance
# ベクトルの作成
M = [a for a in res.iloc[:,2:769].values] 
# 総当たりに類似度を計算(こちらを参照https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html#scipy.spatial.distance.cdist)
dist_M = distance.cdist(M, M, metric='cosine')

상품 간 거리 행렬 만들기


dist_matrix = pd.DataFrame(dist_M,columns=res['title'],index=res['title'])

히트맵으로 시각화



파이썬으로 일본어를 그리는 것이 어려울 것 같았기 때문에 스프레드 시트로 만들었습니다.
전문서나 만화인지 등 거친 장르에는 헤어져 있는 것 같습니다.
일본어 위키에서 학습된 모델을 사용하고 있어 상품 데이터로 모델 학습을 하고 있지 않기 때문에, 충분히 데이터를 모아 학습을 실시하는 것으로 보다 정밀도는 올라갈 것 같습니다.

좋은 웹페이지 즐겨찾기