본문 바로가기

7. ML | DL | NLP

6/22(목) IT K-DT(76일차) / 1. 자연어 처리 개요

 

1. 자연어 처리 개요

 

교육 간 Google Colab과 PyTorch를 이용할 예정

 

1-1. 자연어 처리(Natural Language Processing)

자연어를 컴퓨터 언어로 처리하는 분야.

자연어는 일상적으로 우리가 말하고 쓰는 언어로, 한국어, 영어, 중국어 등이 여기에 해당함.

자연어 처리는 컴퓨터가 자연어를 이해하고 분석하는 작업을 포함하며

이를 통해 텍스트 문서의 의미를 파악하거나, 문장을 이해하여 질문에 답변하는 등의 작업을 수행할 수 있음.

또한, 자연어 처리는 기계 번역, 텍스트 분류, 감성 분석, 정보 추출, 질의 응답 시스템, 챗봇 등의

다양한 응용 분야에 적용됨.

 

1-2. 자연어 처리의 활용

자연어 처리의 주요 작업:
1) 토큰화(Tokenization): 문장을 단어나 구절 등의 작은 단위로 분할하는 작업.
2) 형태소 분석(Morphological Analysis): 단어를 형태소로 분리하고, 각 형태소의 품사를 판별하는 작업.
3) 구문 분석(Syntactic Parsing): 문장의 구조를 분석하여 구문 규칙에 따라 구성된 구조를 생성하는 작업.
4) 의미 분석(Semantic Analysis): 문장의 의미를 이해하고 해석하는 작업.
5) 기계 번역(Machine Translation): 한 언어의 문장을 다른 언어의 문장으로 번역하는 작업.
6) 정보 추출(Information Extraction): 텍스트에서 중요한 정보를 추출하는 작업.
7) 감성 분석(Sentiment Analysis): 텍스트의 감성이나 의견을 파악하는 작업.
8) 질의 응답(Question Answering): 질문에 대해 정확한 답변을 추출하거나 생성하는 작업.
9) 챗봇(Chatbot): 대화를 통해 사용자와 상호작용하며 자연어로 이해하고 응답하는 시스템.

 

 

1-3. 용어 정리

1) 자연어 이해(Natural Language Understanding; NLU):

입력된 자연어를 이해하고 분석하는 과정.

이를 통해 컴퓨터는 문장의 의미, 구조, 의도 등을 파악할 수 있음.

 

주요 자연어 이해 작업:
토큰화(Tokenization): 문장을 단어, 구절 또는 문자 등의 작은 단위로 분할.
형태소 분석(Morphological Analysis): 단어를 형태소로 분리하고, 각 형태소의 품사를 판별.
구문 분석(Syntactic Parsing): 문장의 구조를 분석하여 구문 규칙에 따라 구성된 구조를 생성.
의미 분석(Semantic Analysis): 단어의 의미, 문맥, 추론 등을 고려하여 문장의 의미를 이해하고 해석.

 
자연어 이해는 질의 응답 시스템, 텍스트 분류, 감성 분석, 정보 추출 등 다양한 응용 분야에 활용됨.

 

2) 자연어 생성(Natural Language Generation; NLG)
자연어로 텍스트를 생성하는 과정.

이를 통해 컴퓨터는 응답이나 설명을 자연어로 생성할 수 있음.

 

주요 자연어 생성 작업:
텍스트 생성(Text Generation): 입력된 정보나 지식을 바탕으로 자동으로 텍스트를 생성함.

예를 들어, 기사 요약, 문서 요약, 이메일 작성 등에 사용됨.
기계 번역(Machine Translation): 한 언어의 문장을 다른 언어의 문장으로 번역함.
질문 응답 시스템(Question Answering): 질문에 대한 적절한 답변을 생성함.
챗봇(Chatbot): 대화형 인터페이스를 구현하여 자연어로 대화하는 챗봇을 개발함.


자연어 생성은 효과적인 커뮤니케이션을 위해 컴퓨터가 사람과 자연스럽게 대화할 수 있도록 함.

2. 자연어 처리 기능

 

 

자연어 처리 기능 관련설명 웹사이트:
https://medium.com/nlplanet/two-minutes-nlp-33-important-nlp-tasks-explained-31e2caad2b1b

 

Two minutes NLP — 33 important NLP tasks explained

Information Retrieval, Knowledge Bases, Chatbots, Text Generation, Text-to-Data, Text Reasoning, etc.

medium.com

 

2-1. 텍스트 분류(Text Classification)

텍스트 분류(Text Classification):

주어진 텍스트를 사전 정의된 카테고리로 분류하는 작업.

예를 들어, 스팸 메일 분류, 감성 분석, 뉴스 기사 분류 등이 있음.

 

1) 감성 분석 (Sentiment Analysis):

주어진 문장이나 텍스트의 감정을 분류하는 작업.

일반적으로 긍정/부정/중립과 같은 카테고리로 감정을 분류하거나, 감정의 강도를 수치적으로 표현가능.

감성 분석은 소셜 미디어 감정 분석, 제품 리뷰 분석, 고객 의견 분석 등 다양한 분야에서 활용됨.

예를 들어, "이 영화는 정말 멋있어요!"라는 문장이 주어졌을 때,

감성 분석은 이 문장을 긍정적인 감정으로 분류할 수 있음.

2) 어뷰징 감지 (Abusing Detection):

주어진 문장이나 텍스트가 어뷰징(학대, 혐오, 욕설 등)에 해당하는 내용을 포함하고 있는지 여부를 판별.

어뷰징은 온라인 플랫폼에서의 악성 행위로 인식되며, 이를 탐지하고 예방하기 위해 사용됨.

예를 들어, "너는 멍청해!"라는 문장이 주어졌을 때, 어뷰징 감지는 이 문장이 욕설을 포함하는 것으로 판단함.

이를 통해 온라인 커뮤니티에서의 적절한 사용자 행동을 유도하고, 악성 행위를 차단할 수 있음.

 

2-2. 정보 검색 및 문서 순위 지정(Information Retrieval and Document Ranking)

1) 정보 검색 (Information Retrieval):

대량의 데이터나 문서 집합에서 사용자의 정보 요구에 부합하는 문서를 검색하는 과정.

이를 위해 사용자의 검색어나 질의를 이해하고, 그에 맞는 문서를 찾아내는 것이 목표.
정보 검색은 다양한 응용 분야에서 활용되며, 주로 웹 검색 엔진이 가장 잘 알려진 예시임.

사용자가 검색어를 입력하면, 엔진은 수많은 웹 페이지에서 관련된 문서를 찾아내어 사용자에게 제공함.

2) 문서 순위 지정 (Document Ranking):

여러 문서 중에서 가장 관련성이 높은 문서를 상위에 배치하여 사용자에게 더 나은 검색 결과를 제공함.

문서 순위는 검색어와 문서 간의 일치도, 문서의 중요도, 인기도, 사용자 피드백 등을 고려하여 결정됨.


위의 두 가지 모두 문서 유사도 측정(Text Similarity Task)으로 범위가 확장될 수 있음.

문서 유사도 측정은 문서가 주어졌을 때, 검색어(query text)와 가장 유사한 문서를 검색하거나 순위를 매김.

이를 통해 사용자가 주어진 검색어와 관련성이 높은 문서를 빠르게 찾을 수 있음.

이 작업은 정보 검색, 문서 분류, 질의 응답 시스템 등 다양한 응용 분야에서 활용됨.

 

2-3. 텍스트 생성(Text to Text Generation)

입력 텍스트에 대해 자동으로 출력 텍스트를 생성하는 자연어 처리 작업.

이 작업은 기계 번역, 요약, 질의 응답, 챗봇 대화, 기사 생성 등 다양한 응용 분야에서 사용됨.

기계 번역: 문장 입력 시 모델은 해당 문장의 의미를 파악하고 대상 언어로 번역된 문장을 생성함.
요약 작업: 긴 문서를 요약 모델에 입력하면 짧은 요약 문장을 생성함.
질의 응답 시스템: 사용자의 질문을 입력으로 주면, 질의 응답 모델은 문맥을 이해하고 응답 문장을 생성함.

 

2-4. 지식, 기초, 개체, 관계 추출 (Knowledge, bases, Entities and  relations)

자연어 처리는 텍스트 데이터의 이해와 해석에 관련된 다양한 작업을 수행하며,

이 작업에는 지식, 기초, 개체, 관계 등의 요소가 필요함.

이를 통해 텍스트 데이터의 구조화, 정보 검색, 질의 응답, 문서 분류, 기계 번역, 자동 요약 등

다양한 응용 분야에서 지능적인 자연어 처리를 실현할 수 있음.

 

지식 기반 자연어 처리:

지식은 자연어 처리의 핵심 요소 중 하나임.

단어, 개념, 사건, 관계 등 지식을 기반으로 자연어 처리 모델이 의미를 이해하고 처리하며,

지식 그래프, DB 등의 지식 기초에서 지식을 추출하거나 활용하는 것으로 이해 및 생성 작업을 수행함.

개체 및 관계 추출: 

개체와 관계 추출은 정보 검색, 질의 응답, 정보 추출 등 다양한 자연어 처리 Task에서 사용됨.

문장이나 문서에서 중요한 개체와 관계를 인식하고 추출하며,

이를 통해 텍스트에서 정보를 구조화하고, 지식 그래프나 DB에 저장할 수 있음.

 

2-5. 주제와 키워드 (Topics and Keywords)

자연어 처리는 주제와 키워드를 추출하고 분석하여 의미 있는 정보를 도출하는 작업을 수행함.

이를 통해 텍스트 데이터를 구조화하고, 정보 검색, 문서 분류, 토픽 모델링, 문서 요약 등에 활용할 수 있음.

또한, 키워드를 활용하여 텍스트를 탐색하고 분석하는 것은 효율적인 정보 처리와 검색을 가능하게 함.

 

Topics(주제): 주제는 텍스트에서 다루는 내용이나 주된 이야기의 주제를 나타냄.

텍스트 문서나 문장은 주제와 관련된 정보를 담고 있으며, 이를 추출하고 분류하는 작업은 자연어 처리의

일환으로 수행됨.

Keywords(키워드): 키워드는 텍스트에서 중요한 단어나 구를 나타내는 것으로,

문서의 내용/주제 파악 및 강조, 핵심 단어를 식별.

 

2-6. 챗봇 (Chatbots)

음성/문자를 통한 인간과의 데화를 통해 특정한 작업을 수행하도록 제작된 컴퓨터 프로그램.
정해진 규칙에 맞춰서 메시지를 입력하면 발화를 출력하는 규칙기반 챗봇부터

문맥을 입력으로 받아 적절한 답변을 생성/검색하는 인공지능기반 챗봇이 있음.

 

2-7. 텍스트 추론 (Text Reasoning)

텍스트 문장이나 문서에서 내포된 정보를 추론하고 이해하는 과정.

주어진 텍스트를 해석하고, 논리적인 추론을 수행하여 새로운 정보/결론의 도출을 목표로 함.
간단한 수학 문제들을 푼다고 생각해보면 일련의 계산 과정에 의해 답을 도출하게 되는데

그러한 일련의 계산 과정을 추론과정이라 함.

 

2-8. 가짜뉴스 및 혐오발언 필터링 (Fake News and Hate Speech Detection)

허위 혹은 오해의 소지가 있는 정보가 포함된 텍스트를 감지하고 필터링하는 작업.
소셜 미디어 혹은 배포 중인 제품에서 발생하는 어뷰징 콘텐츠를 필터링하기 위해 사용.

 

2-9. 자연어-데이터 처리 간의 변환 작업(Text to Data and vice-versa)

자연어처리 작업 단일 모달인 텍스트 관련 작업 뿐만 아니라, 입출력의 모달을 다양하게 활용할 수 있음.
음성을 텍스트로(STT) 혹은 텍스트를 음성으로(TTS) 변환하는 작업이나,

텍스트를 이미지로(Text to Image) 변환하는 작업 등이 실무 또는 학계에서 많이 논의되는 중.

 

3. 자연어 처리 순서

 

3-1. 문제 정의

문제에 대한 솔루션이 있어야 하고, 명확하고 구체적일수록 알맞는 자연어처리 기술을 찾을 수 있음.

 

3-2. 데이터 수집 및 분석

다양한 학습 데이터를 수집하기 위해 공개된 데이터셋, 유료데이터셋 또는 웹크롤링을 사용하여 수집.
웹크롤링을 통해 데이터를 수집 후 EDA(탐색적데이터분석) 및 분석작업을 통해 데이터의 검증 필요.
정답 레이블이 필요하다면 수집한 데이터에 레이블을 붙여야 함.(M-Turk, SELECTSTART)

 

Kaggle 外 공개 데이터셋 웹사이트 (Papers with Code)

https://paperswithcode.com/datasets?mod=texts&task=question-answering 

 

Papers with Code - Machine Learning Datasets

266 datasets • 99336 papers with code.

paperswithcode.com

 

3-3. 데이터 전처리

학습에 용이하게 데이터를 수정/보완하는 작업.
데이터가 차지하는 비중이 매우 높음 → 데이터를 수집하고 전처리하는 과정이 중요.
전처리작업의 예시:
    1) 토큰화(Tokenization): 주어진 데이터셋에서 문장이나 문서를 토큰이라 불리는 단위로 나누는 작업.
    2) 정제(Cleaning): 갖고있는 데이터셋으로부터 노이즈데이터(이상치, 편향)를 제거하는 작업.

        (대표적인 정제: 영어에서 the, a를 걸러내는 작업)

    3) 정규화(Normalization): 표현 방법이 다른 데이터들을 통합시켜서 같은 항목으로 합치는 작업.

3-4. 모델링

자연어처리 작업은 대부분 단어 토큰들을 결과로 표현하는 작업을 많이 진행.
언어 모델을 사용하며 문장 혹은 단어에 확률을 할당하여 컴퓨터가 처리할 수 있도록 함.
자연어처리 분야에는 많은 언어모델들이 있음.
어떤 언어모델이 내가 풀고자하는 문제에 가장 적합한지 확인.


자연어 작업 처리에 특화된 세부적인 테크닉들이 다 다르므로 SOTA 모델들을 확인해야 함.
    (예: 기차를 타기 위해 기차역을 가는 중에 차가 막혀서 결국 기차를 ???
    내렸다
    놓쳤다
    멈췄다
    달려갔다
    ... 에서 높은 확률의 단어를 선택하여 진행.)

 

NLP와 관련된 모델: https://paperswithcode.com/area/natural-language-processing 

 

Papers with Code - Natural Language Processing

Browse 606 tasks • 1808 datasets • 2092

paperswithcode.com

 

3-5. 모델학습 및 평가

데이터가 준비되어있고, 모델 구조와 학습 방법을 결정했다면 언어 모델을 학습.
GPU환경에서 학습함.
가용할 수 있는 인프라에 맞춰서 학습 파라미터를 설정하고 학습을 시작.
학습 도중, 학습 종료 후 평가:
정량평가, 정성평가:

 

3-6. 실무에서의 평가 진행 과정

1. 준비된 데이터셋을 Train/Valid/Test 데이터셋으로 분할.
2. Train 데이터셋으로 모델을 학습하고, 중간 중간 valid 데이터셋으로 학습 진행 상황 체크.
3. 문제 없이 학습이 종료되었다면 Test 데이터셋과 추가 정량 평가 데이터셋들로 최종 모델에 대한 

    정량 성능 지표를 측정.
4. 정성 평가를 수행하기 위해 정성 평가 데이터셋을 만들고 평가자를 모집하여 블라인드 테스트를 진행.
5. 정량 평가 및 정성 평가 결과에 따라 모델 사용 여부를 결정.

 

4. Huggingface

기계 학습을 사용하여 애플리케이션을 구축하기 위한 도구를 개발하는 회사.
자연어처리 애플리케이션 용도로 구축된 Transformers 라이브러리와 사용자가 기계 학습 모델 및

데이터셋을 공유할 수 있는 플랫폼으로 유명함.
HuggingFace에 업로드된 모델들은 기본적으로 PretrainedModel 클래스를 상속받고 있음.
공식 홈페이지: https://huggingface.co 

 

Hugging Face – The AI community building the future.

The AI community building the future. Build, train and deploy state of the art models powered by the reference open source in machine learning.

huggingface.co

Token의 위치

 

!pip install transformers
!pip install huggingface_hub

# AutoModel: 모델에 관한 정도를 처음부터 명시하지 않아도 됨.
# 예) BERT모델을 사용하는 경우 모델의 상세정보를 확인할 필요 없이 Model ID만으로 손쉽게 모델 구성
from transformers import AutoModel, AutoTokenizer, BertTokenizer
from getpass import getpass
from huggingface_hub import HfApi

access_token = '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'
bert_model = AutoModel.from_pretrained("bert-base-cased", use_auth_token=access_token)

# tokenizer: 단어를 분절해주는 역할
bert_tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")

# 현재 bert_tokenizer가 알아들을 수 있는 단어가 몇개인지 확인
print(bert_tokenizer.vocab_size) # 28996개

 

 

# vocab에 포함되어있는 단어들을 10개만 뽑아서 확인
for i, key in enumerate(bert_tokenizer.get_vocab()):
  print(key)
  if i>10:
    break

 

 

# tokenizer의 type
print(type(bert_tokenizer))

 

 

# sample message 생성
sample_1 = 'welcome to the natural language class'
sample_2 = 'welcometothenaturallanguageclass'

# sample1을 넣었을 때의 경우
# return_tensors: Token을 어떤 type으로 반환할지를 설정(tf, pt, np 등이 존재)
tokenized_input_text = bert_tokenizer(sample_1, return_tensors='pt') 

# 옵션: return_tensors='pt'는 tensor가 pytorch용으로 retrun이 된다는 의미.
for key, value in tokenized_input_text.items():
  print('{}\n\t{}'.format(key, value))
# input_ids의 시작과 끝인 101과 102는 특수한 키

# welcome to the natural language class이 각각 7236, 1106, 1103, 2379, 1846, 1705인 것으로 보면 됨.
# token_type_ids: 각 토큰이 첫 번째 문장인지 두 번째 문장인지를 나타내는 역할
# attention_mask: 어텐션 연산에서 실제로 어텐션을 수행할 위치를 나타냄. 
# (이 값이 1인 위치는 어텐션 연산에 참여하고, 0인 위치는 어텐션 연산에서 제외)

 

 

# sample2을 넣었을 때의 경우
tokenized_input_text = bert_tokenizer(sample_2, return_tensors='pt')
for key, value in tokenized_input_text.items():
  print('{}\n\t{}'.format(key, value))
# sample1과 input_ids가 다르므로 단어의 분절이 중요하다는 것을 알 수 있음.

 

 

print(tokenized_input_text['input_ids'])
# print(tokenized_input_text.input_ids) # 동일한 코드

 

 

print(tokenized_input_text['token_type_ids'])
# print(tokenized_input_text.token_type_ids) # 동일한 코드

 

 

print(tokenized_input_text['attention_mask'])
# print(tokenized_input_text.attention_mask) # 동일한 코드

 

 

# sample1의 분절된 단어 확인
tokenized_text = bert_tokenizer.tokenize(sample_1) 

# sample_1의 뒤에 ',add_special_tokens=False'를 입력하면 101,102가 사라짐
print(tokenized_text)

# encoding
input_ids = bert_tokenizer.encode(sample_1)
print(input_ids) # encode 시 번호로 출력

# decoding
decoded_ids = bert_tokenizer.decode(input_ids)
print(decoded_ids) # 앞의 CLS와 SEP는 encoding 시의 숫자 101과 102를 의미하는 것을 알 수 있음.

 

 

# sample2의 분절된 단어 확인
tokenized_text = bert_tokenizer.tokenize(sample_2)
print(tokenized_text)
# #이 나오는 이유?

# encoding
input_ids = bert_tokenizer.encode(sample_2)
print(input_ids) # encode 시 번호로 출력

# decoding
decoded_ids = bert_tokenizer.decode(input_ids)
print(decoded_ids) # 앞의 CLS와 SEP는 encoding 시의 숫자 101과 102를 의미하는 것을 알 수 있음.

 

 

# max_length=5: sample1에서 문장의 분절 5개를 읽어들임
tokenized_text = bert_tokenizer.tokenize(
    sample_1,
    add_special_tokens=False,
    max_length=5,
    truncation=True # 입력 텍스트가 최대 길이보다 길다면 잘라내는(truncating) 설정
)
print(tokenized_text)

 

 

# sample1에서 문장의 분절을 encoding한 숫자 5개를 읽어들임
input_ids = bert_tokenizer.encode(
    sample_1,
    add_special_tokens=False,
    max_length=5,
    truncation=True
)
print(input_ids)
# decoding한 내역 출력
decoded_ids = bert_tokenizer.decode(input_ids)
print(decoded_ids)

 

 

# 만약 문장의 분절 20개를 읽어들이기로 한 경우, 비어있는 공간을 PAD(특수token)로 채우는 경우
tokenized_text = bert_tokenizer.tokenize(
    sample_1,
    add_special_tokens=False,
    max_length=20,
    padding='max_length'
)
print(tokenized_text)

input_ids = bert_tokenizer.encode( # index값은 0으로 채워짐
    sample_1,
    add_special_tokens=False,
    max_length=20,
    padding='max_length'
)
print(input_ids)

# decoding한 내역 출력
decoded_ids = bert_tokenizer.decode(input_ids)
print(decoded_ids)

 

 

# [PAD]에 대해서
print(bert_tokenizer.pad_token) # token = [PAD]
print(bert_tokenizer.pad_token_id) # token_id = 0

 

 

# bert 모델은 영어만 인식이 됨

kor_text = '아직도 목요일이네'
tokenized_text = bert_tokenizer.tokenize(
    kor_text,
    max_length=10,
    padding='max_length'
)
print(tokenized_text) # 한글은 인식이 안되기 때문에 [UNK]로 인식이 됨.

tokenized_input_text = bert_tokenizer(kor_text, return_tensors='pt')
for key, value in tokenized_input_text.items():
  print('{}\n\t{}'.format(key, value))  # [UNK]의 encoding값은 100이다.

 

 

# 한글이 인식이 되는 모델을 활용할 예정
# 한국어 텍스트를 지원하는 bert 모델의 다운로드

multi_bert_model = AutoModel.from_pretrained('bert-base-multilingual-cased') # 모델 id
multi_bert_tokenizer =AutoTokenizer.from_pretrained('bert-base-multilingual-cased')

 

 

# 지원하는 한국어 단어의 갯수
print(multi_bert_tokenizer.vocab_size) # 119547개

 

 

# 등록된 글자들에 대한 출력
text = '한국인이 알아볼 수 있는 한국어를 사용함'
tokenized_text = multi_bert_tokenizer.tokenize(text)
print(tokenized_text)

# encoding
input_ids = multi_bert_tokenizer.encode(text)
print(input_ids) # encode 시 번호로 출력

# decoding
decoded_ids = multi_bert_tokenizer.decode(input_ids)
print(decoded_ids) # 앞의 CLS와 SEP는 encoding 시의 숫자 101과 102를 의미하는 것을 알 수 있음.

 

 

# 등록되어있지 않은 글자들에 대한 출력
unk_text = '한꾺인이 알아뽈 쑤 있뉸 한꾺어를 싸용합뉘따'
tokenized_text = multi_bert_tokenizer.tokenize(unk_text)
print(tokenized_text)

# encoding
input_ids = multi_bert_tokenizer.encode(unk_text)
print(input_ids) # encode 시 번호로 출력

# decoding
decoded_ids = multi_bert_tokenizer.decode(input_ids)
print(decoded_ids)

# UNK가 출력되는 것들을 확인할 수 있음.