목차

  1. Sentence Transformer 설치 및 실행
  2. Clustering 예제
  3. 배틀그라운드 리뷰 크롤링
  4. 전처리
  5. 배틀그라운드 리뷰 임베딩
  6. Clustering
  7. 워드클라우드 만들기

BERT : 문장의 문맥을 양방향으로 이해해서 숫자의 형태로 바꿔주는 딥러닝 모델

Bidirectional : 양방향

Encoder : 입력값을 숫자 형태로 바꾸는

Representations from

Transformers : 인코더 디코더 모델을 지닌 딥러닝 모델

 

SBERTBERT 문장 임베딩의 성능을 개선시킨 모델, BERT 문장 임베딩을 응용하여 BERT fine tuning 한다.


Sentence Transformer 설치 및 실행

!pip install -q -U sentence-transformers

 

Pretrained Model (ko-sroberta-multitask)사용

https://huggingface.co/jhgan/ko-sroberta-multitask

 

jhgan/ko-sroberta-multitask · Hugging Face

ko-sroberta-multitask This is a sentence-transformers model: It maps sentences & paragraphs to a 768 dimensional dense vector space and can be used for tasks like clustering or semantic search. Usage (Sentence-Transformers) Using this model becomes easy wh

huggingface.co

 

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개의 군집으로 나눠져있는 것을 볼 수 있다.

약간 주어 목적어 동사 위주로 클러스터링이 되는 같다.


배틀그라운드 리뷰 크롤링

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개의 클러스터 분류

  1. 좋다, 갓겜
  2. 안좋다, 망겜
  3. 중국 욕, 홍콩과 위구르 독립을 기원, 천안문 사건, 시진핑 주석 
  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()

복사했습니다!