본문 바로가기

머신러닝

텍스트 전처리

전처리 파이프라인

가장 재미없고(?) 반복적인 끝이 없는 작업

 

하지만 가장 중요 - 어쩌면 모델링만큼 

데이터가 중요한 시대 - 중요한 데이터를 어떻게 처리해야 할까?

SOTA* 알고리즘은 공개되어 있다.

 

NLP Project Workflow -e.g. Task : 고객 상품 리뷰, 평점 데이터를 수집해서 감성 분석 모델을 만들어 볼까

1. 문제정의 -단계를 나누고 simplify, x와 y의 정의

2. 데이터수집 - 문제 정의에 따른 수집, 필요에 따라 레이블링

3. 데이터 전처리 및 분석 - 형태를 가공, 필요에 따라 EDA 수행

4. 알고리즘 적용 - 가설을 세우고 구현 / 적용

5. 평가 - 실험 설계, 테스트셋 구성

6. 배포 - RESTful API를 통한 배포, 상황에 따라 유지/보수

 

Text Preprocessing workflow -노이즈 제거, 레이블링, 분절 등 처리 후 사전 생성, Word2index 맵핑을 통해 미니배치 작업을 해준다.

 

1. 데이터(코퍼스) 수집 - 구입, 외주, 크롤링을 통한 수집

2. 정제 - task에 따른 노이즈 제거, 인코딩 변환

3. 레이블링 - 문장마다 또는 단어마다 labeling 수행

4. Tokenization - 형태소 분석기를 활용해서 분절 수행

5. Subword Segmentaion - 단어보다 더 작은 의미 단위 추가 분절 수행

6. Batchify - 사전 생성 및 word2index 맵핑 수행, 효율화를 위한 전/후 처리

 

말뭉치(corpus)란?

• 자연어처리를 위한 문장들로 구성된 데이터셋 (복수표현:Corpora)

• 포함된 언어 숫자에 따라,

- Monolingual Corpus

- Bi-lingual Corpus

- Multilingual Corpus

• Parallel Corpus : 대응되는 문장 쌍이 labeling 되어 있는 말뭉치

 

Preprocessing Pipeline for Service

• 사용자 입력 데이터가 들어오면 학습과 동일한 전처리 수행 후 학습 데이터로 얻은 모델을 적용한다. 최종적으로는 사용자가 인식 가능한 형태로 변환 후 deploy 한다.

 

1. 정제 : 학습 데이터와 같은 방식의 정제 수행

2. 토크니제이션 - 학습 데이터와 같은 방식의 분절 수행

3. Subword Segmentation - 학습 데이터로부터 얻은 '모델'을 활용해서 똑같은 분절 수행

4. Batchify -학습 데이터로부터 얻은 사전에 따른 word2index 맵핑 수행

5. Prediction - 모델에 넣고 추론 수행, 필요에 따라 search 수행(자연어 생성)

6. Detokenization(Optional) - 사람이 읽을 수 있는 형태로 변환, 분절복원

 

 

코퍼스 데이터 수집

Preprocessing Workflow

데이터(코퍼스)수집 - 구입, 외즈, 크롤링을 통한 수집

정제 - Task에 따른 노이즈 제거, 인코딩 변환

레이블링(Optional) -문장마다 또는 단어마다 라벨링 수행

Tokenization - 형태소 분석기를 활용해서 분절 수행

Subword Segmentation(Optional) - 단어보다 더 작은 의미 단위 추가 분절 수행

Batchify - 사전 생성 및 word2index 맵핑 수행, 효율화를 통한 전/후 처리

 

 

데이터 구입 및 외주

구입

- 장점 : 정제 및 레이블링이 완료된 양질의 데이터를 얻을 수 있음

- 단점 : 양이 매우 제한적

- 구입처 : 대학교, 한국전자통신연구원(ETRI), 플리토 등

 

외주 - 수집, 정제 및 레이블링을 외주줄 수 있음

- 단점 : 돈이 든다 -> 양이 매우 제한적

품질 관리를 위한 인력이 추가로 필요

 

 

무료 공개 데이터

• 공개 사이트

- AI-HUB (정부 운영)

- WMT competition

- Kaggle

- OPUS (http://opus.nlpl.eu/)

- 네이버 영화 리뷰

 

• 마찬가지로 양이 매우 제한적

• 한국어 코퍼스는 흔치 않음

 

Crawling

• 장점 : 무한한 양의 코퍼스 수집 가능

- 원하는 도메인 별로 수집 가능

 

• 단점 : 품질이 천차만별이며, 정제 과정에 많은 노력 필요

- e.g. 특수문자, 이모티콘, 노이즈, 띄어 쓰기, 오타

 

•아직은 회색지대(합법과 적법 사이 그 어딘가)

- 적법한 절차에 따른 크롤링이 필요

 

• url/robots.txt : 크롤링 허용/불허 check http://www.robotstxt.org

 

크롤링 수집처 별 특징

•다양한 크롤링 수집처의 특징으로 고려해서 데이터를 수집한다.

데이터 크롤링 시 고려할 내용

- 저작권

- 욕설, 비속어, 신조어 등

 

코퍼스 정제 (data cleaning)

Preprocessing Workflow

데이터(코퍼스)수집 - 구입, 외주, 크롤링을 통한 수집

정제 - Task에 따른 노이즈 제거, 인코딩 변환

레이블링 - 문장마다 또는 단어마다 labeling 수행

토큰이즘 - 형태소 분석기를 활용하여 분절 수행

Subword Segmentaion - 단어보다 더 작은 의미 단위 추가 분절 수행

Batchify - 사전 생성 및 word2index 맵핑 수행, 효율화를 위한 전/후 처리

 

 

Two Steps

• 기계적인 노이즈 제거

- 전각문자 변환

- Task에 따른 노이즈 제거

 

• Interactive 노이즈 제거

- 코퍼스의 특성에 따른 노이즈 제거

- 작업자가 상황을 확인하며 작업 수행

 

 

텍스트 정제 시 주의할 점

• Task에 따른 특성 - 풀고자 하는 문제의 특성에 따라 전처리 전략이 다름

- 신중한 접근이 필요

✓ 이모티콘은 필요없는 정보일까?

✓ 점(.)이 여러 개 있으면 기분이 나쁜 걸까? 좋은 걸까?

 

• 언어, 도메인, 코퍼스에 따른 특성

- 각 언어, 도메인, 코퍼스 별 특성이 다르므로 다른 형태의 전처리 전략이 필요

 

 

전각 문자는 반각 문자로 치환

-현재 우리는 반각문자를 사용한다

 

전각 문자 vs 반각 문자

- 전각문자 : 문자의 폭이 영문자 폭의 두 배 정도의 폭을 가지는 문자

- 반각문자 : 영문자 폭을 가지는 문자

 

• 과거(*유니코드 이전)의 한글, 한자, 일본어는 전각 문자로 취급 되었음

• 반각 문자로 표기 가능한 전각 문자의 경우, 반각 문자로 치환한다.

- 중국어, 일본어 문서는 많은 경우, 반각 문자로 치환 필요

- 오래된 한국어 문서의 경우, 종종 전각 문자로 되어있어서 반각 문자로 치환 필요

 

대소문자 통일(Optional)

• 하나의 단어를 다양하게 표현하면 희소성이 높아짐

• 전통적인 텍스트 분석에서는 필수였으나, 딥러닝 시대에 워드 임베딩을 잘 하게 되면서 Optional

 

정규식을 이용한 정제

• 정규식(regular expression)을 활용하면 복잡한 규칙의 노이즈도 제거/치환 가능

• 코딩 없이 Text Editor(Sublime Text, VSCode 등)로도 정규식 적용 가능

 

 

Interactive 노이즈 제거 과정

 

• 규칙에 의해 노이즈를 제거하기 때문에, 한 번 만에 노이즈 전부를 제거하는 것은 어려움

- 반복적인 규칙 생성 및 적용 과정이 필요

 

• 끝이 없는 과정

- 노력과 품질 사이의 trade-off

- Sweet spot을 찾아야함

✓ 작은 노이즈 정도는 딥러닝을 믿고 가야 한다.

 

 

Summary

• 전처리 과정은 task, 언어, 도메인, 코퍼스 특성에 따라 다르다.

• 시간과 품질 사이의 trade-off

• 전처리 중에서도 특히 텍스트 데이터 노이즈 제거의 경우, 많은 노하우가 필요함.

- 실무 경험상 알고리즘 담당과 별도로 전처리 담당자가 있는게 좋다

 

정규식(regular expression)

실무 팁: 정규식(regex) 적용 방법

1. Text Editor 활용

- 파일을 열어 적용 과정을 보면서 정제

- 장점 : 바로 결과를 확인할 수 있음

- 단점 : 적용 과정이 log로 남지 않음 / 재활용 불가

 

2. 전용 모듈 활용

- Python 등을 활용하여 모듈을 만들고 regex 리스트를 파일로 받아서 처리

- 한번에 모든 regex를 적용

- 장점 : regex 재활용 가능

- 단점 : 중간 결과 확인 불가

 

Text Editors with regex

• Sublime Text 3, VSCode

- 무료

- 단점: 대용량 코퍼스 데이터는 힘들 수 있음

 

• EmEditor

- 유료

- 다양한 인코딩 지원(다국어 처리 가능)

- 대용량 corpus (GB 단위) 로딩 가능

 

정규식 실습

[ ] : 하나의 character라도 매칭되는지 check

• [2345cde] : 2, 3, 4, 5, c, d, e 중 하나라도 매칭되는지 check

• 조건 (2|3|4|5|c|d|e) 과 같다

 

ㅡ : 범위

• [2-5c-e] : 2, 3, 4, 5, c, d, e 중 하나라도 매칭되는지 check

 [2-5c-e] : 2, 3, 4, 5, c, d, e 중 하나라도 매칭되는지 check

 

[^] : not character

• [^2-5c-e] : 2, 3, 4, 5, c, d, e가 아닌 character인지 check

• [^2-5c-e] : 2, 3, 4, 5, c, d, e가 아닌 character인지 check

 

() : 그룹화 및 변수로 지정

• (x)(yz) : x를 ₩1에, yz를 ₩2에 지정

전체값은 \0 에 지정

 

그룹화 응용 : regex의 꿀기능

 

| : or

• (x|y) : x 또는 y가 나타남. 그리고 ₩1에 지정

 

 

X?, X+, X* : X가 출현

• x? : x가 0번 또는 1번 출현

• x+ : X가 무조건 출현. 한 번 이상 출현

• x* : x가 나타나지 않을수도, 반복될 수도 있음

- 강력한 표현. 유의해서 사용해야 함

 

X{n}, X{n,}, X{n,m} : X가 반복

• x{n} : n번 반복 ∗ X{2}

• x{n,} : n번 이상 반복

• x{n,m} : n번 ~ m번까지 반복

 

X{n}, X{n,}, X{n,m} : X가 반복

• 카드번호 인식 : [0-9]{4}\ㅡ[0-9]{4}\ㅡ[0-9]{4}\ㅡ[0-9]{4}

• 알파벳 소문자, 대문자, 숫자로 이루어진 10자 이하의 문자열을 찾는 경우 :

[a-zA-Z0-9]{0,10}

 

. any character

-매우 강력한 표현. 유의해서 사용해야 함

.{9} : 아무 캐릭터가 9번 출현

.+ : 아무 캐릭터가 한 번 이상 출현

 

^ : 문장의 시작, $ : 문장의 끝

• 문자열 전체에 대해 파악할 때 사용

• 카드번호 16자리 인식 : ^[0-9]{4}\ㅡ[0-9]{4}\ㅡ[0-9]{4}\ㅡ[0-9]{4}$

 

그 밖의 Meta Charaters

\s (space, tab, blank) - 공백문자 (space, tab, blank)

\S - 공백문자를 제외한 모든 문자

\w - 알파벳, 숫자, '-' - 동일한 표현은 [A-Za-z0-9_]

\W - 알파벳,숫자 및 '-' 제외, 동일한 표현은 [^A-Za-z0-9]

\d - 숫자, 동일한 표현은 [0-9]

\D - 숫자를 제외한 모든 문자, 동일한 표현은 [^0-9]

 

실습 정규식

1. 전용 모듈(refine.py) 활용

전각문자-> 반각문자

여러 개의 공백-> 한 개의 공백

refine.py 모듈로 삭제

 

입력 데이터 : review.sorted.uniq.tsv

평점과 리뷰가 들어있는 tsv 파일 확인(index 0 : rating, index 1 : review)

 

공백 문자(white space)가 2개 이상인 character 찾기

주어진 데이터(review.sorted.uniq.tsv)에는 여러 개의 공백 문자들이 들어있는 상태

 

정규식 규칙을 담은 파일 : refine.regex.txt

반각문자 치환, 정규식 규칙을 담은 파일(TSV : tab으로 구분되어 있음)

 

 

정규식 적용 실행문

refine.py 파일로 정규식을 적용할 건데,

규칙은 refine.regex.txt 파일에 들어있고,

index 1 field(column)에 대해서 적용할 것이고 인풋 데이터 파일은 review.sorted.uniq.tsv 이다.

아웃풋 파일 이름은 review.sorted.uniq.refined.tsv 로 저장한다

 

 

정제된 데이터 중 샘플 한 개(평점, 리뷰) 정규식으로 선택해보기

시작이 positive or negative + tab + tab(\t)과 줄바꿈(\n)이 아닌 문자 한 개 이상

 

정제된 데이터 중 샘플 한 개(평점, 리뷰) 정규식으로 선택해보기

시작이 positive or negative + tab + tab(\t)과 줄바꿈(\n)이 아닌 문자 한 개 이상

 

 

2. Text Editor 활용

불필요한 character Sublime text를 이용해서 정규식 필터링 후 Replace로 삭제

 

불필요한 character 선택하기 -> 선택된 문자들 Replace로 삭제(Find – Replace – Replace All)

 

여러 개의 줄바꿈(\n\n\n\n 등) Replace로 삭제 -> 여러 차례 반복해서 최종적으로 \n 하나만 남도록

 

 

코퍼스 레이블링

Label 종류

 

1. Text Classification

- input : sentence

- output : class

 

2. Token Classification

- input : sentence

- output : tag for each token -> sequence

 

3. Sequence-to-Sequence

- input : sentence

- output : sentence

 

 

feature -> Label 종류

1. Sentence -> Class

- TSV 파일 하나

- 각 row마다 문장과 대응되는 레이블 존재.

- 각 column은 문장, 레이블로 구성.

 

2. Sentence -> Sentence(Sequence)

- TSV 파일 하나

- 각 row마다 문장 쌍이 대응

- 각 열은 문장으로 구성

 

3. Sentence 당 여러 레이블 존재

- 분리된 파일 형태

- 같은 순서의 row가 대응되는 문장 쌍

✓ e.g. 한국어 한 문장이 파일 별로 영어, 중국어 한 문장씩과 대응

 

Q. 레이블링을 사람이 직접 진행하는 것이 맞나? (Prototyping을 위한 Human labeling)

⦁NLP에서 레이블링(지도학습)을 꼭 해야할까? YES!

- 비지도학습 방법은 상용화가 거의 불가능하다 (단지 이미 만들어진 지도학습의 성능을 약간 올려줄 뿐)

- 레이블링을 하는 것이 최고의 성능을 낸다.

 

⦁ 레이블링 외주를 주기 전 Human Labeling으로 모델 prototyping을 해서 성능 검증 후 외주를 주면 된다.

- Human Labeling은 prototyping 시 강력한 도구다. (두려워 하지 말자)

- 가능하면 외주를 주고, 아니면 팀원들과 나눠서 직접 레이블링을 하는 것도 방법이다.

 

⦁ 효율적인 레이블링 도구를 구성하자 (e.g. 엑셀)

 

 

코퍼스 분절(tokenization)

Two steps

1. Sentence Segmentation (문장 세분화) 2. Tokenization (토크나이징) 

 

Sentence Segmentation

• 보통 훈련 시 우리가 원하는 이상적인 입력 데이터는 1 line 당 1 sentence이나,

현실적으로 우리가 수집한 코퍼스는

- 한 라인에 여러 문장이 들어있거나, 여러 라인에 한 문장이 들어있다.

 

• 따라서 Sentence Segmentation을 통해 원하는 형태로 변환해 줄 필요가 있다.

- 단순히 마침표 등을 문장의 끝으로 처리하면 안된다. ✓ (ex) 3.141592 / U.S.

 

• NLTK의 sent_tokenize를 활용하여 Sentence Segmentation 가능

- from nltk.tokenize import sent_tokenize

- 영어 기반. 한글에도 적용 가능

 

MulPple sentence/line

문장 끝에 줄바꿈이 안되어 있는 경우는 별도로 문장을 잘라주어야 한다.

문장 끝도 아닌데 줄바꿈이 되어 있는 경우는 별도로 문장을 이어붙여 주어야 한다.

 

Tokenization을 해야 하는 이유?

두 개 이상의 다른 token들의 결합으로 이루어진 단어를 쪼개어,

vocabulary 숫자를 줄이고, 희소성(sparseness)을 낮추기 위함

 

 

Tokenization

⦁ Tokenization for Korean

1. 한국어는 교착어(어근+접사)이기 때문에 어근에 접사를 떼주는 tokenization이 필요하다.

2. 띄어쓰기 통일의 필요성

 

⦁ Tokenization for Other Languages

- 영어: 띄어쓰기가 이미 잘 되어 있음. NLTK를 사용하여 comma 등 후처리

- 중국어: 기본적인 띄어쓰기가 없음. Character 단위로 사용해도 무방

- 일본어: 기본적인 띄어쓰기가 없음

 

형태소 분석 및 품사 태깅

•형태소 분석 : 형태소 등 언어적 구조 파악(어근, 접두사/접미사 등)

- 형태소 : 의미를 가진 말의 최소 단위

- e.g. “나는 잘 익은 과일을 아이에게 먹였다.” -> (나, 는, 잘, 익-, -은, 과일, 을, 아이, 에게, 먹-, -이-, -었-, -다. ) 와 같이 13개의 형태소로 구분할 수 있다.

 

• 품사 태깅 : 형태소의 뜻과 문맥을 고려하여 그것에 마크업을 하는 일

- 품사(POS, part-of- speech) : 한국어는 명사, 대명사, 수사, 조사, 동사, 형용사, 관형사, 부사, 감탄사의 아홉 가지 품사로 분류 됨

 

⦁ 형태소 분석기(POS Tagger) 종류 : 쉬운 문장은 성능이 다 비슷하다. 

 

분절 예제 (feat. Mecab with wakati)

mecab에서 wakati 옵션을 주면 품사 정보는 버리고 Sentence Segmentation만 한다.

echo : 문자열을 컴퓨터 터미널에 출력하는 명령어

 

 

tokenization Summary

 

• 한글 분절의 역할

1) 접사를 분리하여 희소성을 낮추고,

2) 띄어쓰기 통일

 

• 굉장히 많은 POS Tagger가 존재하는데, 쉬운 문장은 다 성능이 비슷하다.

- 전형적인 쉬운 문장(표준 문법을 따르며, 구조가 명확한 문장)의 경우, 성능이 비슷함

- 하지만 신조어나 고유명사를 처리하는 능력이 다름

- 따라서, 주어진 문제에 맞는 정책을 가진 tagger를 선택하여 사용해야 함

 

 

'머신러닝' 카테고리의 다른 글

정제(Cleaning) / 정규화(Normalization)  (0) 2022.03.16
추천시스템의 이해와 문서 유사도  (0) 2022.02.08
사이킷런  (1) 2022.01.24
파이썬 기반 머신러닝 생태계 이해  (0) 2022.01.21
평가  (0) 2022.01.21