잘 태깅된 노래 데이터를 가져왔고, 

총 대략 3552개의 곡이 있었다. 

 

가수 유사도를 포함 시키면 같은 가수로 편향되어 뺐다. 

 

장르 유사도를 구하기 위해 CountVectorizer를 사용했다. 

가사 유사도를 구하기 위해 TF-IDF Vectorizer를 사용했따. 

 

한 곡이지만 여러 장르가 섞여서 표현되는 경우가 많았다. 

예를 들어서, 성인가요/트로트, 랩/힙합, R&B/Soul, 발라드 게임 등으로 

 

그래서 이를 토대로 장르간 유사도를 구하기 위해 각 장르의 Counting을 계산하는 CountVectorizer를 사용했다. 

https://m.blog.naver.com/myincizor/221643794025

 

문서를 벡터 표현으로 바꾸기 — CountVectorizer

이전 글에서 코사인 유사도 개념을 설명하면서 사이킷런의 CountVectorizer를 사용했습니다. 말 그대로 ...

blog.naver.com

 

가사 간 유사도를 구하기 위해서는 TF-IDF를 사용했다. 

TF-IDF Vectorizer를 사용해 벡터를 구한 뒤 tf 벡터 두개의 유사도를 구하고 

두 가사간의 유사도를 구했다. 

 

곡 유사도를 구하기 위해 공식을 만들었는데,

가사 유사도는 장르 유사도에는 0.3, 가사 유사도에는 1의 가중치를 줘 진행했습니다.

 

사용자가 선택한 노래와 유사한 노래를 찾기 위한 데이터로 활용했습니다.

 

예를 들어서, 

노래의 유사도 테이블을 불러와서, 일단 사용자가 선택한 노래를 seed song이라고 설정한다.

그 노래와 유사한 노래를 가져오고, 리턴한다.

 

사용자가 입력한 글을 토대로 사용자의 감정을 분류한다. 

분류된 감정과 유사한 노래를 리스트업하고, 

사용자의 선택에 의해서 선택된 노래와 상위 5개 노래를 가져온다. 

 

 

사용자가 선택한 노래 를 제외하고 5곡씩 유사한 곡을 추출한다. 

예를 들어 3곡을 선택하면 유사한 5곡 총, 15곡을 추출한다. 

 

사용자가 입력한 text에 대한 4가지 감정의 확률값이 나오면

15곡 중에서 그 감정 확률값과 가장 유사한 5곡을 추천해주게 된다. 

 

사용자가 아무것도 선택하지 않을 시 랜덤으로 5곡을 추천하게 된다. 

<<< 이 추천 부분이 이해가 안가네. >>

 

멜론 노래 가사 

장르 별 TOP 400개의 곡을 스크래핑 했다. 

스크래핑 한 노래 가사의 특수문자를 제거해주고, 50% 이상이 영어일 경우에는 Kobert 모델로 구분을 못할 가능성이 크기 때문에 제거를 진행했다. 

가사도 마찬가지로, 버트 토크나이저를 활용하여  토큰화 진행했다. 가사 내 문장별 확률 값을 추출하고 

가사의 감정 확률 값 추출, 문장별 감성 확률의 정규화 평균을 구했다. 가장 높은 확률 값을 가지는 감정으로 분류했다. 

 

노래 감성 분류 태깅하는데 한 곡당 20~30초 정도 걸리면서 대략 26시간 정도 걸렸다. 

https://huggingface.co/docs/transformers/ko/index

 

🤗 Transformers

(번역중) 효율적인 학습 기술들

huggingface.co

허깅페이스라는 오픈소스 커뮤니티에서 transformers를 제공하고 있다. tensorflow나 pytorch에서 사용 가능하다.

transformer는 사전학습된 최첨단 모델들을 쉽게 다운로드하고 훈련시킬 수 있는 API와 도구를 제공합니다.

transformer에서는 TFBertModel을 사용했다. 

 

6가지 감정으로 분류된 데이터셋을 활용

총 5만 7천개의 데이터를 활용했다. 

 

NLP는 비정형 데이터를 다루기 때문에, 컴퓨터가 이해를 못한다. 따라서 컴퓨터가 이해할 수 있도록 텍스트를 벡터화 (임베딩) 해주었다. 

- 임베딩 단계에서는 세가지 과정을 거쳤는데, 우선 토큰화를 진행해 최소 의미 단위인 토큰으로 나눠주고. (토크나이저는 KoBertTokenizer를 사용했다) 토큰별로 시퀀스를 부여해주고, 하나의 행렬로 나타내기 위해서 병렬 연산을 위해서 여러 문장의 길이를 임의로 동일하게 맞춰주는 작업이 필요한데 이는 패딩으로 진행하였다. 패딩은 최대 토큰 수인 299개를 참고하여 300개로 설정해 진행해주었다. 

 

임베딩된 결과는 세가지로 나뉘는데, input id / attention mask / token type id 로 나뉜다. 이 세개는 Bert 에 들어갈 input 값이다. 

https://rfriend.tistory.com/807

 

transformer 를 이용한 토큰화 (Tokenization), 단어 임베딩 (Word Embedding), 텍스트 임베팅 (Text Embedding)

토큰화, 단어 임베딩, 텍스트 임베딩은 자연어 처리(NLP) 및 기계 학습에서 텍스트 데이터를 표현하고 처리하는 데 사용되는 개념입니다. 이러한 개념들은 감정 분석, 기계 번역, 텍스트 분류와

rfriend.tistory.com

https://soundprovider.tistory.com/entry/transformers-tokenizer-%EA%B2%B0%EA%B3%BC

 

[transformers] tokenizer 결과

huggingface 라이브러리에서 제공하는 tokenizer 결과를 정리해본다. kakaobrain의 KOGPT모델을 사용하였다. 0. Tokenizer import torch from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrain

soundprovider.tistory.com

 

모델링을 시작한다.

모델링에는 TFBertModel에서 pretrained된 kobert 를 사용했다. 

token tensor , mask tensor, segment tensor 레이어를 만들었다. 

세개의 값을 bert 모델 input으로 넣는다. 

output 중에서 두번째에 있는 pooler output 을 bert_outputs으로 설정하고 dropout 0.2로 설정해서 과적합을 막는다. 

https://wikidocs.net/61374

 

07-06 과적합(Overfitting)을 막는 방법들

학습 데이터에 모델이 과적합되는 현상은 모델의 성능을 떨어트리는 주요 이슈입니다. 모델이 과적합되면 훈련 데이터에 대한 정확도는 높을지라도, 새로운 데이터. 즉, 검증 데이터나 …

wikidocs.net

마지막 layer에는 6개로 분류하니깐 unit을 6으로 설정하고 다중 분류의 활성화 함수로 사용하는 soft max를 사용했다.  

https://velog.io/@ym980118/%EB%94%A5%EB%9F%AC%EB%8B%9D-%ED%99%9C%EC%84%B1%ED%99%94-%ED%95%A8%EC%88%98-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC-%EC%8B%9C%EA%B7%B8%EB%AA%A8%EC%9D%B4%EB%93%9C-%EC%86%8C%ED%94%84%ED%8A%B8%EB%A7%A5%EC%8A%A4-ReLU

 

[딥러닝] 활성화 함수 간단 정리 ! (시그모이드, 소프트맥스, ReLU)

활성화 함수 간단 정리 !!

velog.io

 

텐서플로우에 세가지 input을 넣고, final model로는 6개의 유닛을 가진 활성화함수 softmax 인 output layer를 사용해 모델을 만들었다. 옵티마이저로는 RectifiedAdam를 사용했다. RectifiedAdam 은 Adam 모델에서 rectification을 곱해줌으로써 학습 초기에 일어날 수 있는 bad local optima problem을 해결하고, 학습 안정성을 높인 옵티마이저이다. 

 

https://choice-life.tistory.com/34

 

Optimizer : RAdam - Rectified Adam

pdf : https://arxiv.org/abs/1908.03265 About RAdam : https://github.com/LiyuanLucasLiu/RAdam 위의 사이트는 RAdam을 다운로드 할 수 있고, 추가 내용 설명이 있습니다. Adam 가중치 옵티마이저 Adam은 adaptive learning rate를

choice-life.tistory.com

 

loss 함수로는 SparseCategoricalCrossentropy를 사용했다. 훈련 데이터의 label(target)이 one-hot vector 이면 CategoricalCrossentropy, 훈련 데이터의 label(target)이 정수이면 SparseCategoricalCrossentropy 이기 때문에 0~5까지의 정수로 라벨링된 데이터를 활용하였기 때문에 SparseCategoricalCrossentropy를 사용했다. 

https://jins-sw.tistory.com/entry/CategoricalCrossentropy-vs-SparseCategoricalCrossentropy

 

CategoricalCrossentropy vs SparseCategoricalCrossentropy

Tensorflow는 classification task에서 간편하게 사용할 수 있는 cross entropy loss 함수를 제공하고 있습니다. Binary classification이라면 BinaryCrossentropy를 사용하면 되고, Multi-class classification이면 CategoricalCrossent

jins-sw.tistory.com

 

TPU를 세팅하게 되는데. 

TPU는 구글에서 개발한 Tensor Processing Unit의 약자로. AI 시스템이 인공지능 작업을 빠르고 효율적으로 수행하도록 고안된 프로세서입니다. 

 

https://velog.io/@pnuaid1020/CPU-GPU-NPU-TPU

 

CPU GPU NPU TPU 훑어보기

CPU vs GPU, NPU, TPU

velog.io

 

이제 Train을 시작한다.

EarlyStopping 을 사용하여 overfitting을 막았다. 

모델을 더 이상 학습을 못할 경우(loss, metric등의 개선이 없을 경우), 학습 도중 미리 학습을 종료시키는 콜백함수입니다.
출처: https://deep-deep-deep.tistory.com/55 [딥딥딥:티스토리]

 

평가를 한다. 

Train 데이터와 동일하게 특수문자를 제거하고, 토크나이징으로 토큰화를 진행하고, 토큰화된 단어를 벡터화(임베딩)을 진행하고, 동일한 행렬 크기 형태로 만들기 위해 패딩까지 진행한다.

 

그 결과 나온 결과값인 input id, attention smak, segment tensor를 trained 된 bert 모델에 넣어 예측해준다.

예측 결과 예측 정확도 accuracy는 0.62가 나왔다.

f1-score 결과 혐오를 가장 0.4대로  잘 분리못했고 행복을 0.8로 가장 쉽게 분리했다. 

 

이렇게 학습된 모델을 저장했다. dill 함수 안에 있는 dumps 를 이용해 피클로 만들었다. 

저장된 모델을 load 하고 수집한 노래 가사에 6가지 감정으로 분류하는 과정을 진행했다. 

 

 

 

KoBertTokenizer를 사용했다. 

https://github.com/monologg/KoBERT-Transformers

 

GitHub - monologg/KoBERT-Transformers: KoBERT on 🤗 Huggingface Transformers 🤗 (with Bug Fixed)

KoBERT on 🤗 Huggingface Transformers 🤗 (with Bug Fixed) - monologg/KoBERT-Transformers

github.com

KoBERT 장점.

output layer만을 추가로 달아주면 원하는 결과를 출력해낼 수 있다. 많은 BERT 모델 중에서도 KoBERT를 사용한 이유는 "한국어"에 대해 많은 사전 학습이 이루어져 있고, 감정을 분석할 때, 긍정과 부정만으로 분류하는 것이 아닌 다중 분류가 가능한 것이 강점이기 때문이다.

 

이 포스팅에서 하는 작업은 바로  파인 튜닝(Fine-tuning)에 해당한다. 다른 작업에 대해서 파라미터 재조정을 위한 추가 훈련 과정을 거치는 것을 말한다. 예시를 들어보면, 우리가 하고 싶은 작업이 우울증 경향 문헌 분류라고 하였을 때, 이미 위키피디아 등으로 사전 학습된 BERT 위에 분류를 위한 신경망을 한 층 추가하는 것이다. 이미 BERT가 언어 모델 사전 학습 과정에서 얻은 지식을 활용할 수 있으므로 우울증 경향 문헌 분류에서 보다 더 좋은 성능을 얻을 수 있다.

 

 

BERT는 이미 누군가가 학습해둔 모델을 사용한다(pre-trained model)는 것을 뜻한다. 따라서 사용하는 model과 tokenizer는 항상 mapping 관계여야 한다. 예를 들어서 U 팀이 개발한 BERT를 사용하는데, V팀이 개발한 BERT의 tokenizer를 사용하면 model은 텍스트를 이해할 수 없다. U팀의 BERT의 토크나이저는 '우리'라는 단어를 23번으로 int encoding하는 반면에, V라는 BERT의 tokenizer는 '우리'라는 단어를 103번으로 int encoding해 단어와 mapping 되는 정보 자체가 달라지기 때문이다. 이 부분은 뒤에서 간단히 진행해본 실습에서 더 자세히 다뤄볼 것이다.

 

 

 

?? 왜 KoBERT를 사용했는지?

 

KoBERT 모델링

- 전이 학습 모델

- max_length = 300으로 설정 (나머지는 padding 처리)

- tokenizer: 문장을 Token으로 분리

?? 전이 학습 모델링이라 따로 학습은 안하는건가? 

 

Pre-trained된 KoBERT는 그대로 사용할 수도 있지만,
본 포스팅처럼 목적에 맞게 Fine-tuning하여 원하는 방향으로 조정할 수도 있습니다.

 

KoBERT 모델을 가져와서, 감정 데이터셋으로 분류 모델 학습을 시켰다.. 

분류 성능이 좋게 하기 위해서 중립의 감정은 제거하였고, 6종의 감정과 4 종의 감정만을 학습한 모델링을 진행.

 

KoBert 로 학습시키기 전에 전처리 과정 필요.

KoBertTokenizer 토크나이저 생성.

문장을 토큰으로 분리 

토큰으로 분리한 결과 가장 긴 토큰을 가진 게 299개였고, 그래서 bert의 max_length를 300으로 설정.

 

토큰화 과정

- 특수문자 제거

- 토큰화 + 토큰별 시퀀스 번호 부여 + 패딩(나머지 값은 0으로 입력)

- input_ids, attention_mask, token_type_ids  세 개가 나옴. 

 

모델링

- max_length = 300인 모델을 만들고

- TFBertModel 을 사용

- layers를 쌓기 시작하는데 (tokens_tensor, masks_tensor, segments_tensor)

- bert_outputs 

- layers.Dropout(0.2)

- final_output = activation = softmax

- optimizer 는 RectifiedAdam을 사용

- loss는 SparseCategoricalCrossentropy

- metrics 는 SparseCategoricalAccuracy

 

TPU 세팅

- model 함수 불러옴.

 

Train

- EarlyStopping 설정

- model을 epochs=10, batch_size=200, callbacks=[callback_checkpoint, callback_earlystop] 으로 설정

 

Evaluate

- test data set 전처리 (특수문자 제거, tokernizer, tokenizing 된 것 중에서 input_ids/attention_mask/token_type_ids 세개로 분리)

- checkpoint 파일에서 .load_weights  ( Load the best model's weights from checkpoint file)

 

Save model

- create model 함수를 pickle 파일 형태로 저장. tokenizer 저장.

 

=== > 감정 분류에 활용할 수 있는 KoBert 를 활용한 모델링 끝.

 

가사 감정 분류 시작. 

감정 분류 모델로 학습시킨 KoBERT를 가사 감정 분류에 사용하였습니다.

문장별 감성 분류 확률을 추출하고, 다 더한 후 정규화를 진행해 전체 가사의 감성 확률을 구했다.

총 3821곡, 총 24시간 + 2시간 소요.. (곡 당 20~40초 소요)

 

가사 감성 분류

KoBERT 모델 적용 노래 추천용 DB 제작

- 문장별 감성 분류 확률 추출

- 다 더한 후 정규화 

 

https://bbarry-lee.github.io/ai-tech/KoBERT%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EA%B0%90%EC%A0%95%EB%B6%84%EB%A5%98-%EB%AA%A8%EB%8D%B8-%EA%B5%AC%ED%98%84.html

 

KoBERT를 활용한 감정분류 모델 구현 with Colab

안녕하세요, Daisy 입니다 ☺️ SKT Brain에서 개발한 KoBERT 오픈소스 코드를 활용해 Google Colab에서 감정분류 모델을 구현해보았으며 그 과정을 소개하고자 합니다.

bbarry-lee.github.io

 

 

TPU 사용, KoBERT

 

사용자가 문장을 입력하면, 그 문장의 감정을 6가지 중 하나로 분류한다.

음악을 추천하기에 앞서, 음악별로 감정 확률이 라벨링 되어 있어야 한다. 즉, 이 음악이 어떤 감정을 표현하는지 확률 벡터가 필요하다.

 

KoBert 모델 학습이 필요하다

이미 학습된 전이학습 모델이지만, ??? 

 

노래의 가사에 대한 감정이 태깅되어 있어야 한다. (스크래핑 단계에서 진행)

감정 확률을 구하기 앞서, 토크나이저를 활용해 토큰화를 진행해야한다. 

 

- NLP는 비정형 데이터를 다루기 때문에 컴퓨터가 이해를 못한다.

따라서 컴퓨터가 이해할 수 있도록 텍스트를 벡터화(임베딩) 해준다.([0.56, 0, 0.76, 0.23, 0.54, ….] 이런 식으로)

벡터화가 되면 정형 데이터가 되기 때문에 이걸 이용해서 기분 라벨링을 정답으로 하는 지도학습으로 딥러닝 모델을 학습 및 예측을 한다.

가사 내 문장별로 어떤 감정과 유사한지 확률 값 추출

한 노래 내의 여러 문장별 감정별 확률 값을 합산해 평균을 내주는 정규화 평균 값을 구해, 노래 단위의 어떤 감정과 가장 유사한지 클래스를 분류한다. 

https://wikidocs.net/166796

 

3. 토크나이저 (Tokenizer)

토크나이저는 NLP 파이프라인의 핵심 구성 요소 중 하나입니다. 토크나이저는 단지 1가지 목적을 가지고 있습니다. 즉, 입력된 텍스트를 모델에서 처리할 수 있는 데이터로 변환하는…

wikidocs.net

https://sophieeunajang.wordpress.com/2021/01/15/%ED%95%9C%EA%B5%AD%EC%96%B4-bert-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95/

 

한국어 BERT 사용 방법

BERT의 아키텍쳐를 조금 알고 계신다고 생각 하고 설명 하겠습니다! BERT는 GPU가 필요 하니까 ~ 저처럼 GPU가 없으신 분들은 Colab으로 접속해 주시구요! Colab은 Jupyter과 많이 비슷해요 :) 들어오셔서

sophieeunajang.wordpress.com

 

 

토큰화 할 때 패딩을? 

출력값들을 보면 3개의 array가 출력되는데, 첫 번째는 패딩된 시퀀스, 두 번째는 길이와 타입에 대한 내용, 세 번재는 어텐션 마스크 시퀀스이다. 어텐션 마스크는 지난 BERT 프로젝트 글에서도 설명했었는데, BERT에 데이터가 입력되었을 때 어텐션 함수가 적용되어 연산이 된다. 이때 1로 패딩된 값들은 연산할 필요가 없기 때문에 연산을 하지 않아도 된다고 알려주는 데이터가 있어야 하는데 그게 바로 어텐션 마스크 시퀀스인 것이다. 이렇게 BERT나 KoBERT에는 어텐션 마스크 데이터도 함께 입력되어야 한다⭐

 

https://velog.io/@seolini43/KOBERT%EB%A1%9C-%EB%8B%A4%EC%A4%91-%EB%B6%84%EB%A5%98-%EB%AA%A8%EB%8D%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0-%ED%8C%8C%EC%9D%B4%EC%8D%ACColab

 

[파이썬]KoBERT로 다중 분류 모델 만들기 - 코드

KoBERT를 이용한 프로젝트 입니다!

velog.io

https://wikidocs.net/31379

 

16-01 트랜스포머(Transformer)

* 이번 챕터는 앞서 설명한 어텐션 메커니즘 챕터에 대한 사전 이해가 필요합니다. 트랜스포머(Transformer)는 2017년 구글이 발표한 논문인 Attention i…

wikidocs.net

 

프로젝트 주제 : 사용자 감성 분석을 통한 음악 추천 서비스 개발

(영어로) Music Recommendation Service through User Sentiment Analysis

 

프로젝트 주제와 목적

주제 : 사용자의 입력 기반으로 감정분석을 활용한 음악 추천 서비스

  1. 사용자의 글을 기반으로 감정을 분류
  2. 감정을 분류한 것과 유사한 음악 추천

목적 : 사용자의 감성을 분석하여 음악 추천 

 

서비스 Flow 

Input : 300자 이내의 한글, 감정 플레이리스트별 2곡씩 랜덤 추출된 총 12곡 중 3곡 선택 

Model : KoBERT (61,698개의 문장으로 훈련, max_length = 300)

--> Output : 4 emotion's probabilities

Song Similarity :

  • CounterVectorizer : Genre Similarity
  • TF-IDF Vectorizer : Lyric Similarity

--> Output  : 4 emotion's probabilities

 

Output 

Recommend 5 songs (by Cosine Similarity)

 

[분노혐오, 놀람공포, 슬픔, 행복] 확률값, 학습된 KoBERT 모델

감정별 곡 리스트 큐레이션 : 3곡씩 총 12곡

사용자가 3곡 선택 : 사용자 seed 반영

옵션 : 곡 리스트 새로고침 & 선택 초기화

 

사용자 감정 (KoBERT 분석 확률값)

+ 사용자 곡 선택

+ 감정 유사도

활용한 추천 알고리즘으로 5개곡 추천

 

KoBERT 61,698개의 문장으로 훈련되고, max_length=300인 모델로 4개의 감정 확률을 나오게 하고,

Recommendation Algorithm에 4개의 감정 확률을 보내고, 

CounterVectorizer를 통해 Genre similarity와 Artist Similarity를 구하고,

TF-IDF Vectorizer를 통해 Lyric Similarity를 구한다.

결과적으로 5개 노래를 추천

 

사용자의 감성 분류 모델링

한국어 감정 정보가 포함된 단발성 대화 데이터셋

한국어 감정 정보가 포함된 연속적 대화 데이터셋

감정 분류를 위한 대화 음성 데이터셋

 

노래 추천, 가사 감성 분류

멜론 데이터 스크래핑

장르별 최신 500곡 총 4000곡

 

데이터 전처리

기분라벨링 된 지도학습으로 딥러닝 모델을 활용해 예측 분류한다.

최종 사용 데이터셋 : 7종 감정

분노, 놀람, 행복, 슬픔, 혐오, 공포, 중립

 

데이터 전처리 - 감정 분류 모델링용

Ver1. 6종 감정 : '중립' 제거

분노/놀람/행복/슬픔/혐오/공포

 

Ver2. 4종 감정 : 중립 제거 및 병합

분노 놀람/ 슬픔/행복/혐오 공포

분노 놀람 0 행복 1 슬픔 2 혐오공포3

 

멜론 가사 스크래핑 

성인인증 필요 가사 제외.

html 태그들 삭제, 텍스트만 남기기

문장별로 element, 리스트에 저장

==> 문장별로 감성 분류 확률을 추출, 전체 가사의 감정 확률을 도출해 내기 위함!

 

모델링

KoBERT 모델링

ㄴ 전이학습(Pre-tranined model) 모델링 

ㄴ SKT Korean Bidirectional Encoder Representations from Transformers

ㄴ 구글의 BERT 모델이 한국어에서는 성능 한계가 있어 SKT에서 만든 한국어 BERT 모델

KoBERT는 위키피디아나 뉴스 등에서 수집한 수백만 개 한국어 문장의 대규모 말뭉치 (Corpus)(자연언어 연구를 위해 특정한 목적을 가지고 언어의 표본을 추출한 집합)를 학습

한국어의 불규칙한 언어 변화의 특성을 반영하기 위해 데이터 기반 토큰화 (Tokenization) 기법을 적용하여 기존 대비 27%의 토큰만으로 2.6% 이상의 성능 향상을 이끌어 낸 모델

텍스트 데이터를 토큰화 했을 때, 최대값 292

https://github.com/SKTBrain/KoBERT

 

GitHub - SKTBrain/KoBERT: Korean BERT pre-trained cased (KoBERT)

Korean BERT pre-trained cased (KoBERT). Contribute to SKTBrain/KoBERT development by creating an account on GitHub.

github.com

 

토큰화(tokenization)란?

https://wikidocs.net/21698

 

02-01 토큰화(Tokenization)

자연어 처리에서 크롤링 등으로 얻어낸 코퍼스 데이터가 필요에 맞게 전처리되지 않은 상태라면, 해당 데이터를 사용하고자하는 용도에 맞게 토큰화(tokenization) & 정제(c…

wikidocs.net

자연어 처리에서 크롤링 등으로 얻어낸 코퍼스 데이터가 필요에 맞게 전처리되지 않은 상태라면, 해당 데이터를 사용하고자하는 용도에 맞게 토큰화(tokenization) & 정제(cleaning) & 정규화(normalization)하는 일을 하게 됩니다.

주어진 코퍼스(corpus)에서 토큰(token)이라 불리는 단위로 나누는 작업을 토큰화(tokenization)라고 합니다. 토큰의 단위가 상황에 따라 다르지만, 보통 의미있는 단위로 토큰을 정의합니다. 

 

토큰의 기준을 단어(word)로 하는 경우, 단어 토큰화(word tokenization)라고 합니다. 다만, 여기서 단어(word)는 단어 단위 외에도 단어구, 의미를 갖는 문자열로도 간주되기도 합니다.

 

문장 토큰화(Sentence Tokenization)

 

5. 한국어에서의 토큰화의 어려움.

영어는 New York과 같은 합성어나 he's 와 같이 줄임말에 대한 예외처리만 한다면, 띄어쓰기(whitespace)를 기준으로 하는 띄어쓰기 토큰화를 수행해도 단어 토큰화가 잘 작동합니다. 거의 대부분의 경우에서 단어 단위로 띄어쓰기가 이루어지기 때문에 띄어쓰기 토큰화와 단어 토큰화가 거의 같기 때문입니다.

하지만 한국어는 영어와는 달리 띄어쓰기만으로는 토큰화를 하기에 부족합니다. 한국어의 경우에는 띄어쓰기 단위가 되는 단위를 '어절'이라고 하는데 어절 토큰화는 한국어 NLP에서 지양되고 있습니다. 어절 토큰화와 단어 토큰화는 같지 않기 때문입니다. 그 근본적인 이유는 한국어가 영어와는 다른 형태를 가지는 언어인 교착어라는 점에서 기인합니다. 교착어란 조사, 어미 등을 붙여서 말을 만드는 언어를 말합니다.

 

한국어 토큰화에서는 형태소(morpheme) 란 개념을 반드시 이해해야 합니다. 형태소(morpheme)란 뜻을 가진 가장 작은 말의 단위를 말합니다. 이 형태소에는 두 가지 형태소가 있는데 자립 형태소와 의존 형태소입니다.

 

  • 자립 형태소 : 접사, 어미, 조사와 상관없이 자립하여 사용할 수 있는 형태소. 그 자체로 단어가 된다. 체언(명사, 대명사, 수사), 수식언(관형사, 부사), 감탄사 등이 있다.
  • 의존 형태소 : 다른 형태소와 결합하여 사용되는 형태소. 접사, 어미, 조사, 어간을 말한다.
  • 문장 : 에디가 책을 읽었다

이 문장을 띄어쓰기 단위 토큰화를 수행한다면 다음과 같은 결과를 얻습니다.

  • ['에디가', '책을', '읽었다']

하지만 이를 형태소 단위로 분해하면 다음과 같습니다.

자립 형태소 : 에디, 책
의존 형태소 : -가, -을, 읽-, -었, -다

 

'에디'라는 사람 이름과 '책'이라는 명사를 얻어낼 수 있습니다. 이를 통해 유추할 수 있는 것은 한국어에서 영어에서의 단어 토큰화와 유사한 형태를 얻으려면 어절 토큰화가 아니라 형태소 토큰화를 수행해야한다는 겁니다.

 

결론적으로 한국어는 수많은 코퍼스에서 띄어쓰기가 무시되는 경우가 많아 자연어 처리가 어려워졌다는 것입니다.

 

6. 품사 태깅(Part-of-speech tagging)

단어는 표기는 같지만 품사에 따라서 단어의 의미가 달라지기도 합니다.

한국어도 마찬가지입니다. '못'이라는 단어는 명사로서는 망치를 사용해서 목재 따위를 고정하는 물건을 의미합니다. 하지만 부사로서의 '못'은 '먹는다', '달린다'와 같은 동작 동사를 할 수 없다는 의미로 쓰입니다.  결국 단어의 의미를 제대로 파악하기 위해서는 해당 단어가 어떤 품사로 쓰였는지 보는 것이 주요 지표가 될 수도 있습니다. 그에 따라 단어 토큰화 과정에서 각 단어가 어떤 품사로 쓰였는지를 구분해놓기도 하는데, 이 작업을 품사 태깅(part-of-speech tagging)이라고 합니다. NLTK와 KoNLPy를 통해 품사 태깅 실습을 진행합니다.

 

형태소 분석기로 Okt(Open Korea Text), 메캅(Mecab), 코모란(Komoran), 한나눔(Hannanum), 꼬꼬마(Kkma)가 있습니다.

 

프로젝트를 할 때 어려웠던 점, 어떤 형태소 분석기를 사용하느냐????

예를 들어서 속도를 중시한다면 메캅을 사용할 수 있습니다.

 

https://wikidocs.net/86657

 

13-02 센텐스피스(SentencePiece)

앞서 서브워드 토큰화를 위한 BPE(Byte Pair Encoding) 알고리즘과 그 외 BPE의 변형 알고리즘에 대해서 간단히 언급했습니다. BPE를 포함하여 기타 서브워드 토…

wikidocs.net

https://wikidocs.net/31379

 

16-01 트랜스포머(Transformer)

* 이번 챕터는 앞서 설명한 어텐션 메커니즘 챕터에 대한 사전 이해가 필요합니다. 트랜스포머(Transformer)는 2017년 구글이 발표한 논문인 Attention i…

wikidocs.net

https://namu.wiki/w/TPU

 

TPU

Tensor Processing Unit 구글 에서 2016년 5월에 발표한 머신러닝을 위해 설계된 ASIC 이

namu.wiki

 

https://youtu.be/GVPTGq53H5I?feature=shared

 

pizza가 ramen 보다 hamburger랑 유사하다는걸 어떻게 알까? 

  • pizza
  • pizza hamburger cookie
  • hamburger
  • ramen
  • sushi
  • ramen sushi

Bag of words를 이용한다면 단어의 의미를 파악하지 못하고 단어 빈도수 기반이기에 서로 의미가 비슷하다는 걸 모른다.

Similarity(pizza, hamburger) = 0

Similarity(pizza, ramen) = 0

  pizza hamburger cookie ramen sushi
pizza 1 0 0 0 0
pizza hamburger cookie 1 1 1 0 0
hamburger 0 1 0 0 0
ramen 0 0 0 1 0
sushi 0 0 0 0 1
ramen sushi 0 0 0 1 1

 

TF-IDF 또한 마찬가지. pizza와 hamburger가 같은 단어를 가지고 있지 않기 때문에 유사도 = 0으로 나오게 된다.

TF-IDF와 Bag of words는 words 기반이지만, LSA 는 토픽 기반의 유사도를 측정한다.

 

LSA로 유사도 구하는 과정

word-document matrix = "A"

  pizza pizza hamburger cookie hamburger ramen sushi ramen sushi
(word) d1 d2 d3 d4 d5 d6
pizza 1 1 0 0 0 0
hamburger 0 1 1 0 0 0
cookie 0 1 0 0 0 0
ramen 0 0 0 1 0 0
sushi 0 0 0 0 1 0

 

A 를 특이값 분해를 통해 세개의 곱으로 나눠줄 수 있다. 

  • word matrix for topic 
  • Topic Strength (시그마 매트릭스)
  • Document matrix for topic (Vt)

세 개 중 Topic Strength와 Document matrix for topic 행렬에서 토픽 분류를 할 수 있는데,

Topic Strength 행렬은 토픽 중요도에 따라 내림차순으로 정렬이 되는데,,, t1, t2가 주요 토픽이다.

Ignore less than 1.7 토픽 2개만 남기고 나머지는 없앤다. 

https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-20-%ED%8A%B9%EC%9D%B4%EA%B0%92-%EB%B6%84%ED%95%B4Singular-Value-Decomposition

 

머신러닝 - 20. 특이값 분해(SVD)

이번 장에서는 특이값 분해(SVD)에 대해 알아보겠습니다. 고유값 분해에 대해 알고 있어야 특이값 분해를 이해할 수 있습니다. 고유값 분해를 잘 모르시는 분은 이전 장을 참고해주시기 바랍니다

bkshin.tistory.com

주요 토픽 2개를 가지고 (시그마, VT)를 곱해 계산하면 

  pizza pizza hamburger cookie hamburger      
  d1 d2 d3 d4 d5 d6
t1 0.57 1.57 0.57 0 0 0
t2 0 0 0 0.68 0.68 1.36

 

https://youtu.be/Rd3OnBPDRbM?feature=shared

 

문서간 유사도를 어떻게 측정할까?

  • Bag of words 기반 유사도를 측정한다.
  • TF-IDF 기반 유사도를 측정한다.

Bag of words 로 유사도를 측정할 경우

  • d1: the best italian restaurant enjoy the best pizza
  • d2: american restaurant enjoy the best hamburger
  • d3: korean restaurant enjoy the best bibimbap
  • d4: the best the best american restaurant
  italian restaurant enjoy the best pasta american hamburger korean bibimbap
d1 1 1 1 2 2 1 0 0 0 0
d2 0 1 1 1 1 0 1 1 0 0
d3 0 1 1 1 1 0 0 0 1 1
d4 0 1 0 2 2 0 1 0 0 0

 

d4 와 각 문서간의 코싸인 유사도를 구하면, d1이 가장 유사도가 높다. 그러나, 미국 레스토랑의 최고와 이탈리안 레스토랑의 최고는 유사도가 없는 것. the best 라는 말이 반복되었기 때문에 유사도가 높게 측정이 되었다. 

document ID Document cosine similarity with d4
d1  the best italian restaurant enjoy the best pizza 0.82
d2 american restaurant enjoy the best hamburger 0.77
d3 korean restaurant enjoy the best bibimbap 0.65
d4 the best the best american restaurant 1

 

그래서 문서 간 중복되는 단어들은 문서를 대표하지 않기 때문에 패널티를 주기 위해서 TF-IDF 를 활용하게 된다.

TF = how frequently a term occurs in a document

IDF = Log(Total # of Docs / # of Docs with the term in it)

 

TF-IDF 기반으로 구한 코싸인 유사도는 

Document TF-IDF Bag of words Cosine Similarity with d4
 the best italian restaurant enjoy the best pizza   0
American restaurant enjoy the hamburger   0.5
korean restaurant enjoy the best bibimbap   0
the best the best america restaurant    1

 

TF-IDF bag of words의 이점

  • 문서 유사도를 쉽게 구할 수 있다. 
  • 중요한 단어의 점수를 그대로 유지하고
  • 중요하지는 않지만 자주 출현하는 단어는 여러문서에 존재할 경우에 더 낮춰주는 역할

TF-IDF bag of words의 단점

  • 단어만 보지, 그 단어의 속 의미(의미간 유사도)를 알지 못한다. 
  • 문서의 주요 토픽을 이끌어내는대는 약하다
  • 동의어를 핸들링하는데는 약하다 (다른 단어이지만 같은 뜻을 갖는 경우)

예시 : 

U.S President speech in public

Donald Trump presentation to people

두 문장은 같은 의미이지만 같은 의미의 다른 단어를 사용했기 때문에 문자 그 자체로만 파악하는 TF-IDF로는 해결할 수 없다. 

 

TF-IDF 단점을 극복하는 방법은? 

  • LSA (Latent Segmatic Analysis)
  • Word Embedding (Word2vec, Glove)
  • ConceptNet

 

 

https://youtu.be/if6tjHAT6iM?feature=shared

 

자연어처리의 유사도 측정 방법

  • 유클라디안 유사도
  • 코사인 유사도

유클라디안 유사도

  • 두 점 사이의 최단 거리
  • 거리 계산 공식은 피타고라스 정리를 사용
  • princess 와 man 거리 = d2, price와 man 간의 거리 d1이라고 한다면 d1이 더 짧아, price는 man과 가까운 의미라고 해석

 

  • 한계점 : 벡터의 크기에 영향을 받는다. (magnitude of vector matter)
  • money라는 단어가 반복되었기 때문에 벡터의 크기가 늘어났다. 유클라디안 유사도 기반으로 보면 money를 6번 반복한 것 보다도 laundering이라는 벡터와 더 가까운 의미를 가진다고 나온다. 하지만 사실상 money money laundering은 money가 두번 반복되기 때문에 money*6번 반복하는 벡터와 더 의미가 유사하다고 할 수 있다. 

 

Cosine Similarity

  • 이를 극복하기 위해 사용하는 것이 코싸인 유사도. 
  • 코싸인 유사도는 두 벡터 사이의 각도를 기반으로 유사도를 결정한다. 
  • 벡터 자체의 크기는 무시하고 두 벡터 사이의 각도 기반이기 때문에 money money laundering을 money*6와 더 유사하다고 말할 수 있다.
  • 문장이 유사하다면 같은 방향, 문장이 유사하지 않다면 90도의 방향을 (직교하는 방향)을 가질 것이다.
  • 아래는 공식

  • 각도가 90도 이상 커질 수 있을까? 
    • 보통은 불가능하다. 
    • 두 문장 벡터 사이의 각도는 90도 이상일 수 없다. 
    • 이유는, 문장 벡터는 문장 내의 Frequency 빈도수를 기반으로 벡터를 만들기 때문에 빈도수가 -1이 될 수 없으므로 90도가 최대라고 할 수 있다. 
    • 코싸인 함수에 의해서 90도일때는 0의 값을 갖는다. 0도 일때는 1의 유사도를 갖고

+ Recent posts