개발자로 후회없는 삶 살기
NLP PART.텍스트 전처리 이론 본문
서론
※ 이 포스트는 다음 강의의 학습이 목표임을 밝힙니다.
https://www.youtube.com/playlist?list=PL7SDcmtbDTTzQ69rNQ85LyA2WAx438pxz
본론
- 텍스트 전처리
자연어를 숫자로 바꾸는 과정
-> 크게 3가지 단계로 나뉩니다.
1. 토큰화, > 2. 정제 및 추출, > 3. 인코딩
1. 토큰화 : 문장을 자르는 것 > i love you를 i/love/you로 나눕니다.
2. 정제 및 추출 : 중요한 단어만 놔두고 다 자르는 것이 입니다. > can you help me on this problem에서 중요한 단어 > (problem,you, can, help) 말고는 다 지워도 됩니다. 이 4개 단어만 안다면 굳지 다 필요 없습니다. 메모리 차원, 시간, 해석하는 차원에서도 불필요한 단어는 없애는 게 낫습니다. 남겨진 단어를 ↓
3. encoding : 숫자로 바꿉니다. > 1, 2, 3으로 바꾸면 정수 encoding이라고 하고 [0, 1]로 된 거로 바꾸면 one-hot encoding이라고 합니다.
=> 언어의 형태소
토큰화에서 형태소가 매우 중요한 역할을 합니다. > "화분에 예쁜 꽃이 피었다"를 토큰화 해보겠습니다. 단어 띄어쓰기 기준으로 나누면 "화분에"/ "예쁜"/ "꽃이"/ "피었다" > 근데 "화분에"는 뭔가 이상합니다. "화분은"도 되고 "화분이"도 되네 명사와 조사 사이에도 띄어줘야 합니다. > 예쁜은 "예쁘" 어간에 "ㅁ"어미가 붙은 것입니다. 또 바꿀 수 있으니 "예쁘"와 "ㅁ"으로 토큰화해야 합니다. > 한국어가 굉장히 토큰화하기 어렵습니다 = 띄어쓰기가 되어있지 않은데 나눠야 하기 때문입니다.
"모른다"의 파생어가 40가지가 있습니다 인간은 40가지를 다 모른다로 볼 수 있는데 컴퓨터는 다 다른 단어로 본다 이게 모든 언어의 토큰화에서 가장 도전적인 문제라고 볼 수 있습니다.
-> 언어 전처리 : 컴퓨터 언어에서 자연어를 효과적(시간, 메모리, 해석적)으로 처리할 수 있도록 전처리 과정을 거칩니다.(토큰화, 정제 및 추출, 인코딩)
=> 전처리 과정 6개로 세분화
원래는 3개였는데 6개 세분화해보겠습니다. 문장 > 토큰화 > 정체 및 추출 > encoding > 분류 > padding+유사도 분석
1. 토큰화부터 보자!
문장을 형태소 단위로 자르는 것 > 주어진 문장에서 의미 부여가 가능한 단위를 찾습니다. i/ love/ you 영어는 띄어쓰기가 있으면 자르면 됩니다. + 문장부호 '.' 마침표가 나오면 끊으면 되니 굉장히 쉽습니다.
그런데 어려운 예시가 한국어입니다. > 형태소 단위로 나누는 게 어렵고 축구가 5:3이다는 따로 처리를 해줘야 합니다. "5:3"이라는 하나의 단어로 할 것인가, "5", ":" ,"3"으로 따로 볼 것인가를 예외 처리로 수동으로 해줘야 합니다. > 제거하면 안 됩니다. (= 사람의 직관이 필요합니다.)
> 그래서 표준화된 토큰화 방법이 있습니다. > treebank tokenization 방법으로 파이썬 패키지가 있습니다.
-는 하나의 단어로 했습니다., 'dont'를 'do', 'nt'으로 했습니다. > 이건 이 토큰화 방법의 규칙이고 -을 따로 보는 토큰화 방법도 있고 dont를 하나로 보는 방법도 있습니다. > 패키지의 특성을 잘 확인하고 토큰화를 진행해야 합니다.
> 문장 토큰화 : 문장 단위로 의미를 나누기 문장 단위로 끊는 것을 문장 토큰화라고 하고 글이 매우 길 때 사용한다 단어 잘 사용은 안 합니다.
> 한국어 토큰화의 어려움
형태소 단위로 토큰화를 해야 해서 그렇습니다. 필요하다면 형태소 분석하면 필요, 하, 다면으로 쪼개야 합니다 . 어렵고 패키지도 별로 없습니다.
-> 결론 : 토큰화는 간단합니다. 그냥 패키지를 쓰면 되는데 주의할 점은 단어를 처리하는 방식이 패키지마다 다르고 사람의 직관이 필요할 수 있습니다.
2. 정제 및 추출
=> 정제(cleaning)
1) 대, 소문자
데이터 사용 목적에 맞게 노이즈 제거하는 것입니다. > Lang, lang에서 L 하나의 차이로 컴퓨터는 다른 단어로 본다 그래서 대문자를 소문자로 바꿔줘야 합니다. 그런데 바꾸면 문제가 되는 경우가 있습니다. 'US'는 '미국'인데 'us'는 '우리'입니다. 그래서 주의할 단어는 정제하지 말라고 예외 처리를 걸어줘야 합니다.
2) 단어 출현 횟수가 적을 수도 있습니다.
> 굳이 이런 것까지 encoding을 해줘야 하나 싶습니다. (정제 및 루출 다음이 encoding이므로) 필요 없습니다. 이 단어가 영향을 미치지 않을 때! 근데 딱 한 번 나오는데 그게 killing word일 수 있습니다! 그런 애들은 정제를 하면 안 됩니다. 근데 한번 나오는데 별로면 지워도 됩니다. (예외 처리!) = 사람이 정해줄 필요가 있습니다.
3) 노이즈 제거 :
관사 , i ,a, an 같은 건 다 지워도 됩니다.
=> 추출(stemming)
lectures, playing 복수, 진행형은 중요하지 않습니다. 무엇이 중요하냐면 '강의', '논다'의 표현이 중요합니다. 따라서 지워도 됩니다. > 물론 중요할 때는 놔둬야 합니다. = 지워도 될 때만 지워도 됩니다.
1) 어간 추출(stemming)
electical, organization 등 파생어들은 al, ation 지워도 됩니다. > 의미보다는 역할을 나타내는 것을 지우는 것을 어간추출이라고 합니다.
2) 표제어 추출(Lemmatization)
having은 have로 is, are는 be로 같은 것으로 볼 수 있습니다. 그러면 어간추출과 표제어 추출이 뭐가 다를까요?
-> 어간 추출 vs 표제어 추출
표제어 추출은 단어의 품사 정보를 포함하고, 어간은 포함하지 않습니다. > 왜 포함하고 있어야 할까요? 어간 추출로 하면 안 될까요? 해도 됩니다. 언제나면. 단어의 뜻이 분명한 단어들만 모여있을 때는 어간 추출을 해도 됩니다.
> 근데 'bear'는 명사도 되고 동사도 되는데 단어의 뜻이 완전히 달라지므로 품사 정보를 포함하고 있는 게 중요합니다. = 품사 정보가 달리 쓰일 수 있는 단어들이 존재하여 정확하게 분류해야 하면 표제어 추출을 써야 합니다.
3) 불용어(stopword)
대세로 작용하지 않은 중요도가 낮은 단어 제거 아까 i, 출현 횟수 이런 거 다 지웠는데 그래도 남아있는 단어가 있을 수 있습니다 > 남아있는 것을 지우는 게 불용어 처리입니다.
-> 패키지 : 이 단어가 불용어 목록에 있으면 지워주는 패키지입니다.
+ 불용어 제거 방법
불용어 목록을 불러오고 > 정제할 문장을 토큰화하고 > 단어마다 불용어 목록에 있는지 체크합니다. > "있어요? 있으면 지워주세요~" > "없으면 가져가서 사용할게요."라고 생각하면 된다.
> 파이썬 코드
불용어 패키지를 가져와서 > 토큰화한 것에서 불용어 목록에 없으면 그것만 append 합니다.
★ 여기까지 하면 중요한 단어 리스트만 남았습니다. 이제 이걸 어떻게 컴퓨터가 이해할 수 있게 할까요? 알아봅시다.
3. 인코딩
정수 인코딩 : 예제로 문장 4개가 있습니다. 불용어를 다 제거했습니다. 토큰화도 했습니다, 이제 인코딩을 하겠습니다. 어떻게 하냐면? 처음 보는 단어들의 번호를 붙입니다. > 1 2 3 4 5 6 아까 본 python은 이전의 번호 5를 붙입니다. > 이러면 4문장이 4개의 숫자 벡터로 바뀝니다.
-> 근데 무작정 번호를 붙이면 되나요?
그래도 됩니다. 하지만 효율적인 방법이 있습니다. > 단어 등장 횟수를 세자 많이 등장하는 단어가 있고 조금인 단어가 있는데 "많은 단어들을 조금 앞에 번호를 부여하면 되지 않을까?" 하는 방법입니다.
> 3번 나온 'exam'은 1로 2번 나온 'score'는 2로 붙이면 굉장히 좋은 방법입니다. = 숫자가 작을수록 사용하는 메모리가 작아질뿐더러 앞에 숫자를 많이 검색할 텐데 앞에 뒀으니 서칭하는 속도도 빨라질 것입니다.(딥러닝 수업 7장 노트북 파일 참고!)
-> 등장하는 빈도수를 다 체크하고 다시 번호 부여하는 방법
순서 :
1) dic vocab dir 자료형{}를 만듭니다.
2) 단어가 vocab에 속하지 않는 경우 vocab[단어] = 1(처음 봤으니 1)
3) vocab[단어] += 1 (다시 보는 건 횟수를 세는 거니 증가)
4. sorting
sorting으로 value 값을 정렬하고 키값만 불러와서 다시 처음부터 1 2 3 4 5로 encoding 합니다. (처음에 배운 encoding처럼 하면 됩니다.)
※ encoding에 이어지는 거였습니다. 질문 : 횟수를 세는 게 단어를 빈도수로 나타내는 것이니 encoding으로 보나??
-> 코드
빈도수를 세고 sorted 하면 리스트로 반환합니다. > 정렬이 됐습니다. 그리고 키값만 불러와서 1,2,3,4,5를 다시 붙이면 됩니다. word가 튜플이라서 word[0]이 단어입니다. 단어에 인덱스를 1부터 다시 2,3,4,5 붙입니다.
★결론 : 빈도수 세고 정렬해서 빈도수가 많은 단어부터 번호를 붙어서 효율적으로 encoding하자는 것입니다.
5. 패딩
대표적으로 zero padding이 있습니다. encoding된 결과가 들어와서 길이가 전부 다 다릅니다. 그러면 컴퓨터가 처리하기 어려울 수 있습니다. 근데 rnn 쓰면 인자가 임베딩 크기지 뉴런 수가 아니라서 괜찮을 수 있습니다. 근데 웬만하면 padding 하는 게 좋습니다. 전부 길이를 맞춰줍니다.
> 하는 법 : 문장을 다 보고 가장 길이가 긴 문장을 기준으로 다른 짧은 애들은 0으로 채워줍니다.
+ 원핫인코딩
단어가 012345로 되는 게 정수 encoding입니다. 근데 컴퓨터는 0, 1만 인식한다고 했습니다. 하지만 분류를 하기 위해서는 one-hot encoding을 하는 게 유리합니다. > 근데 문제가 있습니다. 메모리를 많이 차지합니다. 그러니 평소에는 정수 encoding으로 놔뒀다가 필요할 때만 one-hot encoding으로 합니다.
※ 사실 이런 거 다 패키지 있는 데 사용 방법을 알아야 합니다.
=> 추가 언어 전처리 과정
1. word2vec encoding
2. tf-idf
단어들의 중요한 정도를 가중치로 매기는 것입니다. 빈도가 많은 단어가 중요한 단어이니 가중치를 매기자 tf와 idf의 곱으로 나타내집니다.
용어 :
1) tf : 특정 문서 d에서 특정 단어 t의 등장 횟수(tf는 많아야 하고)
2) idf : 역수 값으로 총 문서 수 / 특정 단어 t가 등장한 문서수에 로그 취한 것(idf는 역수이니 낮아야 합니다.)
> 둘이 곱하면 tf - idf입니다. > 그러면 단어들의 중요한 정도가 매겨질 수 있습니다. > 단어의 중요도를 가중치로 매겨주는 것입니다.
=> 요약
전처리 과정 : 토큰화 > 정제 및 추출 > encoding(+사실 인코딩 + 정렬이 하나!) > padding
'[AI] > [네이버 BoostCamp | 학습기록]' 카테고리의 다른 글
NLP PART.BERT, GPT (0) | 2022.12.09 |
---|---|
NLP PART.Attention 메커니즘 (0) | 2022.12.06 |
NLP PART.RNN, Seq2Seq 구조 (0) | 2022.12.03 |
NLP PART.텍스트 마이닝 이론 (0) | 2022.12.01 |
[22.05.01]딥러닝 PART.순환 신경망 (0) | 2022.11.08 |