2020년 3월 6일 금요일

python: 구글의 sentencepiece 적용하기 ( Word Piece Model )

Untitled2

Word Piece Model

언어와 상관없이 문장을 토큰으로 나눌수 있는 모델입니다. 학습 데이터의 단어 빈도수를 기반으로 subword를 나눠주기 때문에
NLP에서 미등록단어의 문제를 비켜갈 수 있다. 또, 언어와 상관없이 사용할 수 있다는 장점이 있다.
구글에서 공개한 Word Piece Model(WPM) sentencepiece를 사용해 보려고 한다.

1. 패키지 설치

In [1]:
!pip install sentencepiece

2. 필요한 패키지 load

In [2]:
import pandas as pd
import numpy as np
import sentencepiece as spm

3. 데이터 읽어 들이기

사용한 데이터셋은 Naver sentiment movie corpus v1.0의 ratings_test.txt를 사용했습니다.

In [3]:
df = pd.read_csv('~/data/ratings_test.txt', delimiter='\t')
In [4]:
df.head()
Out[4]:
id document label
0 6270596 굳 ㅋ 1
1 9274899 GDNTOPCLASSINTHECLUB 0
2 8544678 뭐야 이 평점들은.... 나쁘진 않지만 10점 짜리는 더더욱 아니잖아 0
3 6825595 지루하지는 않은데 완전 막장임... 돈주고 보기에는.... 0
4 6723715 3D만 아니었어도 별 다섯 개 줬을텐데.. 왜 3D로 나와서 제 심기를 불편하게 하죠?? 0

4. 모델 생성을 위한 학습데이터 생성

In [5]:
input_file = 'input_data.txt'
with open(input_file, 'w', encoding='utf-8') as f:
    for x in df['document']:
        f.write('{}\n'.format(x))

5. 모델 생성

[주의] jupyter notebook에서는 에러가 발생하기 때문에 일반 커널에서 실행해야 합니다.

import sentencepiece as spm
templates = '--input={} --model_prefix={} --vocab_size={}'

input_file = 'input_data.txt'
vocab_size = 3000
prefix = 'naver_movie_review'
cmd = templates.format(input_file, prefix, vocab_size)

spm.SentencePieceTrainer.Train(cmd)
...
unigram_model_trainer.cc(486) LOG(INFO) EM sub_iter=1 size=2823 obj=19.0172 num_tokens=635242 num_tokens/piece=225.024
unigram_model_trainer.cc(486) LOG(INFO) EM sub_iter=0 size=2200 obj=20.13 num_tokens=684863 num_tokens/piece=311.301
unigram_model_trainer.cc(486) LOG(INFO) EM sub_iter=1 size=2200 obj=19.8178 num_tokens=685812 num_tokens/piece=311.733
trainer_interface.cc(507) LOG(INFO) Saving model: naver_movie_review.model
trainer_interface.cc(531) LOG(INFO) Saving vocabs: naver_movie_review.vocab

6. 학습된 모델을 load

In [6]:
prefix = 'naver_movie_review'
sp = spm.SentencePieceProcessor()
sp.Load('{}.model'.format(prefix))
Out[6]:
True

7. 결과 테스트

In [7]:
reviewStr = df.document[11]
print('--- 문장 원문 --- ')
print(reviewStr)

### subword로 변환
print('--- subword로 변환 --- ')
print(sp.EncodeAsPieces(reviewStr))

### subword id로 변환
print('--- subword id로 변환 --- ')
print(sp.EncodeAsIds(reviewStr))
--- 문장 원문 --- 
한국독립영화의 한계 그렇게 아버지가 된다와 비교됨
--- subword로 변환 --- 
['▁한국', '독', '립', '영화', '의', '▁한계', '▁그렇게', '▁아버지', '가', '▁된다', '와', '▁비교', '됨']
--- subword id로 변환 --- 
[296, 1040, 961, 29, 9, 3262, 858, 1617, 7, 1380, 56, 1209, 719]

8. 모든 데이터를 id 형태로 변환

In [8]:
total_data = np.array(df['document'].apply(lambda x: sp.EncodeAsIds(str(x))))
In [9]:
total_data
Out[9]:
array([list([1969, 397]),
       list([3, 1902, 924, 2003, 1139, 1172, 2569, 2013, 2874, 1368, 2111, 2111, 2863, 2003, 1139, 3574, 2053, 2013, 2874, 3992, 2335]),
       list([1432, 30, 93, 461, 73, 2466, 79, 3762, 111, 47, 3, 1736, 12, 66, 244, 1855, 4062]),
       ...,
       list([2138, 10, 675, 2249, 10, 3, 4996, 668, 82, 11, 171, 560, 502, 108, 92, 3318]),
       list([827, 1581, 12, 43, 795, 8, 6, 852, 290, 782, 22, 1059, 992, 6, 81, 574, 127, 117, 55, 71, 407, 4999, 46]),
       list([2029, 12, 247, 3855])], dtype=object)

댓글 없음:

댓글 쓰기

추천 게시물

python: SVD(Singular Value Decomposition)로 간단한 추천시스템 만들기( feat. surprise )

svd_example In [15]: # !pip install surprise In [21]: from...