💣 배틀그라운드 리뷰 자연어처리
목차
- Sentence Transformer 설치 및 실행
- Clustering 예제
- 배틀그라운드 리뷰 크롤링
- 전처리
- 배틀그라운드 리뷰 임베딩
- Clustering
- 워드클라우드 만들기
BERT : 문장의 문맥을 양방향으로 이해해서 숫자의 형태로 바꿔주는 딥러닝 모델
Bidirectional : 양방향
Encoder : 입력값을 숫자 형태로 바꾸는
Representations from
Transformers : 인코더 디코더 모델을 지닌 딥러닝 모델
SBERT : BERT의 문장 임베딩의 성능을 개선시킨 모델, BERT의 문장 임베딩을 응용하여 BERT를 fine tuning 한다.
Sentence Transformer 설치 및 실행
!pip install -q -U sentence-transformers
Pretrained Model (ko-sroberta-multitask)사용
https://huggingface.co/jhgan/ko-sroberta-multitask
문장이나 문단을 768차원의 dense vector로 바꿔준다.
clustering이나 semantic search에 쓰일 수 있다.
이제 임베딩 해보자.
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('jhgan/ko-sroberta-multitask')
sentences = ["안녕하세요?", "한국어 문장 임베딩을 위한 버트 모델입니다."]
embeddings = model.encode(sentences)
print(embeddings)
768개의 두개의 벡터가 나오는 것을 확인할 수 있다.
Clustering 예제
from sklearn.cluster import KMeans
# Corpus with example sentences
sentences = ['한 남자가 음식을 먹는다.',
'한 남자가 빵 한 조각을 먹는다.',
'그 여자가 아이를 돌본다.',
'한 남자가 말을 탄다.',
'한 여자가 바이올린을 연주한다.',
'두 남자가 수레를 숲 속으로 밀었다.',
'한 남자가 담으로 싸인 땅에서 백마를 타고 있다.',
'원숭이 한 마리가 드럼을 연주한다.',
'치타 한 마리가 먹이 뒤에서 달리고 있다.',
'한 남자가 파스타를 먹는다.',
'고릴라 의상을 입은 누군가가 드럼을 연주하고 있다.',
'치타가 들판을 가로 질러 먹이를 쫓는다.']
embeddings = model.encode(sentences)
# Then, we perform k-means clustering using sklearn:
num_clusters = 5
clustering_model = KMeans(n_clusters=num_clusters)
clustering_model.fit(embeddings)
cluster_assignment = clustering_model.labels_
clustered_sentences = [[] for i in range(num_clusters)]
for sentence_id, cluster_id in enumerate(cluster_assignment):
clustered_sentences[cluster_id].append(sentences[sentence_id])
for i, cluster in enumerate(clustered_sentences):
print("Cluster ", i+1)
print(cluster)
print("")
열두개의 문장을 분류 해보도록 하자.
Sentence Transformer로 인코딩을 먼저 해주면, 벡터값들이 embeddings라는 변수에 저장이 되고, 이 저장된 결과를 가지고 클러스터링을 진행한다.
kmeans clustering을 이용해서 클러스터링을 진행한다.
5개로 분류하겠다고 설정을 하고, 클러스터링 모델 정의를 해준다.
그리고 벡터값들을 클러스터링 모델에 넣어준다.
그리고 클러스터링 라벨을 assignment에 저장을 해준다.
그 결과를 살펴보면 5개의 군집으로 나눠져있는 것을 볼 수 있다.
약간 주어 목적어 동사 위주로 클러스터링이 되는 것 같다.
배틀그라운드 리뷰 크롤링
- 배틀그라운드 리뷰 : https://steamcommunity.com/app/578080/reviews/?filterLanguage=koreana&p=1&browsefilter=toprated
import requests
import time
def get_reviews(appid, params={'json':1}):
url = 'https://store.steampowered.com/appreviews/'
response = requests.get(url=url+str(appid), params=params, headers={'User-Agent': 'Mozilla/5.0'})
return response.json()
def get_n_reviews(appid, n=100): # 어떤 게임, 몇개
reviews = []
cursor = '*'
params = {
'json' : 1,
'filter' : 'all',
'language' : 'koreana',
'day_range' : 9223372036854775807, # 전체기간 리뷰
'review_type' : 'all',
'purchase_type' : 'all'
}
while n > 0:
time.sleep(2) # 차단 당할 수 있기 때문에 2초간 쉬면서 받는다.
params['cursor'] = cursor.encode()
params['num_per_page'] = min(100, n)
n -= 100
response = get_reviews(appid, params)
cursor = response['cursor']
reviews += response['reviews']
if len(response['reviews']) < 100: break
return reviews
reviews = get_n_reviews(578080, 10000)
reviews[:5]
import pandas as pd
df = pd.DataFrame.from_dict(reviews)
df.head()
전처리
- 한글이 아닌 글자 제거
- 작은따옴표 제거
- 연속된 공백 제거
- 좌우 공백 제거
- 최대 글자 255자
df['review'] = df['review'] \
.replace(r'[^가-힣 ]', ' ', regex=True) \
.replace("'", '') \
.replace(r'\s+', ' ', regex=True) \
.str.strip() \
.str[:255]
df.head()
- 아무것도 안 써져 있는 리뷰 제거
- 좌우 공백 없에준 후 남아있는 리뷰들만 저장해준다.
df = df[df['review'].str.strip().astype(bool)]
len(df)
리스트 형태로 바꾸어준다.
df['review'].values.tolist()[:5]
그리고 csv파일로 저장해준다.
df.to_csv('battleground_steam_reviews_ko.csv', index=False)
배틀그라운드 리뷰 임베딩
review 컬럼을 Sentence Transformer로 임베딩해준다.
corpus = df['review'].values.tolist()
embeddings = model.encode(corpus)
embeddings[:5]
Clustering
num_clusters = 4
clustering_model = KMeans(n_clusters=num_clusters)
clustering_model.fit(embeddings)
cluster_assignment = clustering_model.labels_
clustered_sentences = [[] for i in range(num_clusters)]
for sentence_id, cluster_id in enumerate(cluster_assignment):
clustered_sentences[cluster_id].append(corpus[sentence_id])
for i, cluster in enumerate(clustered_sentences):
print('Cluster %d (%d)' % (i+1, len(cluster)))
print(cluster)
print('')
4개의 클러스터 분류
- 좋다, 갓겜
- 안좋다, 망겜
- 중국 욕, 홍콩과 위구르 독립을 기원, 천안문 사건, 시진핑 주석
- 핵, FPS의 한계
워드 클라우드 만들어보기
!pip install -q konlpy tqdm
from konlpy.tag import Komoran, Okt, Kkma, Hannanum
from tqdm import tqdm
extractor = Hannanum()
nouns = [] # 명사만 추출해라
for review in tqdm(df['review'].values.tolist()):
nouns.extend(extractor.nouns(review))
len(nouns)
from collections import Counter
count = Counter(nouns)
words = dict(count.most_common())
for i, (word, count) in enumerate(words.items()):
if i > 10:
break
print(word, count)
한글 폰트 다운로드
!wget https://github.com/kairess/MBTI-wordcloud/raw/master/NanumSquareRoundR.ttf
from wordcloud import WordCloud
import matplotlib.pyplot as plt
wc = WordCloud(
font_path='NanumSquareRoundR.ttf',
width=2000,
height=1000
).generate_from_frequencies(words)
plt.figure(figsize=(20, 10))
plt.imshow(wc)
plt.axis('off')
plt.show()