# 02-01 토큰화
1. 단어 토큰화(word tokenization)
-토큰(token): 의미있는 단위
-토큰화(tokenization): 코퍼스(corpus)에서 토큰이라 불리는 단위로 나누는 작업
-단어 토큰화: 토큰의 기준을 단어로 하는 경우
2. 영어 토큰화 도구들
- NLTK의 word_tokenize: Don't를 Do와 n't로, Jone's를 Jone과 's로 분류
- NLTK의 wordPunctTokenizer: 구두점을 별도로 분류 (Don't를 Don와 '와 t로, Jone's를 Jone과 '와 s로 분류)
- 케라스의 text_to_word_sequence: 기본적으로 모든 알파벳을 소문자로 바꾸면서 마침표나 컴마, 느낌표 등의 구두점을 제거하지만 don't나 jone's와 같은 경우 아포스트로피는 보존
3. 문장 토큰화
-문장 토큰화(sentence tokenization): 갖고있는 코퍼스 내에서 문장 단위로 구분하는 작업
-NLTK의 sent_tokenize: 단순히 마침표를 구분자로 하여 문장을 구분하지 않음
-한국어는 KSS의 split_sentences 사용 추천
4. 한국어가 토큰화 어려운 이유
-어절토큰화가 아닌 형태소토큰화(자립형태소, 의존형태소로 분류)
-띄어쓰기로 간단히 구분 불가
5. 품사 태깅
-품사 태깅(part-of-speech tagging): 각 단어가 어떤 품사로 쓰였는지를 구분하는 지표
- NLTK에서는 Penn Treebank POS Tags라는 기준을 사용하여 품사를 태깅
- Penn Treebank POS Tags (PRP: 인칭 대명사, VBP: 동사, RB: 부사, VBG: 현재부사, IN: 전치사, NNP: 고유 명사, NNS: 복수형 명사, CC: 접속사, DT: 관사)
-한국어 형태소 분석기: KoNLPy(코엔엘파이)의 Okt(Open Korea Text), 메캅(Mecab), 코모란(Komoran), 한나눔(Hannanum), 꼬꼬마(Kkma)
-각 형태소 분석기는 공통적으로 다음 메소드들을 지원
1) morphs : 형태소 추출
2) pos : 품사 태깅(Part-of-speech tagging)
3) nouns : 명사 추출
# 02-02 정제와 정규화
-정제(cleaning) : 갖고 있는 코퍼스로부터 노이즈 데이터를 제거
-정규화(normalization) : 표현 방법이 다른 단어들을 통합시켜서 같은 단어로 만듦
-대소문자 통합: 결국 예외사항 고려하지 않고 모든 코퍼스를 소문자로 바꾸는 것이 종종 더 실용적인 해결책이 되기도 함
-노이즈데이터: 분석 목적에 맞지 않는 데이터(주로 등장빈도가 적은 단어, 길이가 짧은 단어 등)
# 02-03 어간추출과 표제어추출
1. 표제어추출(Lemmatization)
-표제어(Lemma): 단어들이 다른 형태를 가지더라도, 그 뿌리 단어를 찾아가서 단어의 개수를 줄일 수 있는지 판단 (Ex. am, are, is의 표제어는 be)
-형태학적 파싱: 어간(stem)과 접사(affix)로 분리하는 작업
-NLTK의 WordNetLemmatizer로 표제어추출 작업 수행시, 본래 단어의 품사 정보를 알아야만 정확한 결과를 얻을 수 있음. 다음과 같이 표제어 추출기에 단어의 품사 정보를 알려줄 수 있음
- lemmatizer.lemmatize('dies', 'v')
2. 어간추출(Stemming)
-어간을 추출하는 작업으로, 정해진 규칙만 보고 단어의 어미를 어림짐작해서 자름
-포터 알고리즘(Porter Algorithm): 정밀하게 설계되어 정확도가 높으므로 영어 자연어 처리에서 가장 준수한 선
-랭커스터 스태머(Lancaster Stemmer) 알고리즘
-사용하고자 하는 코퍼스에 스태머를 적용해보고 어떤 스태머가 해당 코퍼스에 적합한지를 판단한 후에 사용
Stemming
am → am
the going → the go
having → hav
Lemmatization
am → be
the going → the going
having → have
3. 한국어에서의 어간추출
-활용: 용언(동사, 형용사)의 어간(stem)이 어미(ending)를 가지는 일
-어간의 모습이 일정하다면 규칙 활용, 어간이나 어미의 모습이 변하면 불규칙 활용
# 02-04 불용어
-불용어(Stopword) : 문장에서는 자주 등장하지만 실제 의미 분석을 하는데는 거의 기여하는 바가 없는 단어
-NLTK 패키지를 이용해 불용어 제거 가능
-보편적인 한국어 불용어 리스트 https://www.ranks.nl/stopwords/korean
Korean Stopwords
www.ranks.nl
# 02-05 정규표현식
1. 정규표현식 문법
특수문자 설명
. | 한 개의 임의의 문자를 나타냅니다. (줄바꿈 문자인 \n는 제외) |
? | 앞의 문자가 존재할 수도 있고, 존재하지 않을 수도 있습니다. (문자가 0개 또는 1개) |
* | 앞의 문자가 무한개로 존재할 수도 있고, 존재하지 않을 수도 있습니다. (문자가 0개 이상) |
+ | 앞의 문자가 최소 한 개 이상 존재합니다. (문자가 1개 이상) |
^ | 뒤의 문자열로 문자열이 시작됩니다. |
$ | 앞의 문자열로 문자열이 끝납니다. |
{숫자} | 숫자만큼 반복합니다. |
{숫자1, 숫자2} | 숫자1 이상 숫자2 이하만큼 반복합니다. ?, *, +를 이것으로 대체할 수 있습니다. |
{숫자,} | 숫자 이상만큼 반복합니다. |
[ ] | 대괄호 안의 문자들 중 한 개의 문자와 매치합니다. [amk]라고 한다면 a 또는 m 또는 k 중 하나라도 존재하면 매치를 의미합니다. [a-z]와 같이 범위를 지정할 수도 있습니다. [a-zA-Z]는 알파벳 전체를 의미하는 범위이며, 문자열에 알파벳이 존재하면 매치를 의미합니다. |
[^문자] | 해당 문자를 제외한 문자를 매치합니다. |
l | AlB와 같이 쓰이며 A 또는 B의 의미를 가집니다. |
문자규칙 설명
\\\ | 역 슬래쉬 문자 자체를 의미합니다 |
\\d | 모든 숫자를 의미합니다. [0-9]와 의미가 동일합니다. |
\\D | 숫자를 제외한 모든 문자를 의미합니다. [^0-9]와 의미가 동일합니다. |
\\s | 공백을 의미합니다. [ \t\n\r\f\v]와 의미가 동일합니다. |
\\S | 공백을 제외한 문자를 의미합니다. [^ \t\n\r\f\v]와 의미가 동일합니다. |
\\w | 문자 또는 숫자를 의미합니다. [a-zA-Z0-9]와 의미가 동일합니다. |
\\W | 문자 또는 숫자가 아닌 문자를 의미합니다. [^a-zA-Z0-9]와 의미가 동일합니다. |
2. 모듈함수
re.compile() | 정규표현식을 컴파일하는 함수입니다. 다시 말해, 파이썬에게 전해주는 역할을 합니다. 찾고자 하는 패턴이 빈번한 경우에는 미리 컴파일해놓고 사용하면 속도와 편의성면에서 유리합니다. |
re.search() | 문자열 전체에 대해서 정규표현식과 매치되는지를 검색합니다. |
re.match() | 문자열의 처음이 정규표현식과 매치되는지를 검색합니다. |
re.split() | 정규 표현식을 기준으로 문자열을 분리하여 리스트로 리턴합니다. |
re.findall() | 문자열에서 정규 표현식과 매치되는 모든 경우의 문자열을 찾아서 리스트로 리턴합니다. 만약, 매치되는 문자열이 없다면 빈 리스트가 리턴됩니다. |
re.finditer() | 문자열에서 정규 표현식과 매치되는 모든 경우의 문자열에 대한 이터레이터 객체를 리턴합니다. |
re.sub() | 문자열에서 정규 표현식과 일치하는 부분에 대해서 다른 문자열로 대체합니다. |
# 02-06 정수 인코딩
* 정수 인코딩(Integer Encoding): 자연어처리에서 텍스트를 숫자로 바꾸는 것
1. dictionary 사용하기
-단어 토큰화를 진행하며 파이썬의 딕셔너리 구조로 단어를 키(key)로, 단어에 대한 빈도수가 값(value)으로 저장
-빈도수가 높은 상위 n개 단어만 저장
- Out-Of-Vocabulary(단어 집합에 없는 단어) 문제: 단어 집합에 존재하지 않는 단어들이 생기는 상황
-OOV 문제 해결법: 'OOV'란 단어를 새롭게 추가하고, 단어 집합에 없는 단어들은 'OOV'의 인덱스로 인코딩
2. Counter 사용하기
-파이썬의 Counter() 입력으로 단어 리스트를 주면 중복을 제거하고 단어의 빈도수를 기록
- 단어를 키(key)로, 단어에 대한 빈도수가 값(value)으로 저장되므로 단어를 입력하면 빈도수를 리턴
- most_common() : 상위 빈도수를 가진 주어진 수의 단어만을 리턴
3. NLTK의 FreqDist 사용하기
- NLTK의 빈도수 계산 도구인 FreqDist() 는 파이썬의 Counter()와 똑같은 기능
- enumerate() : 순서가 있는 자료형(list, set, tuple, dictionary, string)을 입력으로 받아 인덱스를 순차적으로 함께 리턴
4. 케라스의 텍스트 전처리
- tokenizer = Tokenizer()
- tokenizer.fit_on_texts() : 입력한 텍스트로부터 단어 빈도수가 높은 순으로 낮은 정수 인덱스를 부여
- tokenizer.word_index : 각 단어에 인덱스가 어떻게 부여되었는지
- tokenizer.word_counts : 각 단어가 카운트를 수행하였을 때 몇 개였는지
- tokenizer.texts_to_sequences() : 입력으로 들어온 코퍼스에 대해서 각 단어를 이미 정해진 인덱스로 변환
- tokenizer = Tokenizer(num_words=숫자) : 빈도수가 높은 상위 몇 개의 단어만 사용하겠다고 지정, 실제 적용은 texts_to_sequences를 사용할 때만 적용됨
- Tokenizer의 인자 oov_token : 케라스 Tokenizer는 기본적으로 단어 집합에 없는 단어인 OOV에 대해서는 단어를 정수로 바꾸는 과정에서 아예 단어를 제거하므로, 단어 집합에 없는 단어들을 OOV로 간주하여 보존하기 위한 방법. 'OOV'의 인덱스를 기본적으로 1로 함
tokenizer = Tokenizer(num_words = vocab_size + 2, oov_token = 'OOV')
# 02-07 패딩
* 패딩(Padding) : 병렬 연산을 위해서 여러 문장의 길이를 임의로 동일하게 맞춰주는 작업. 데이터에 특정 값을 채워서 데이터의 크기(shape)를 조정하는 것
1. Numpy로 패딩하기
-모든 문장의 길이를 가장 긴 문장의 길이인 n에 맞추어 숫자0으로 채워줌
-제로 패딩 : 숫자 0을 채워서 패딩하는 것
2. 케라스 전처리 도구로 패딩하기
- pad_sequences() : 기본적으로 문서의 앞에 0으로 채우기 때문에 뒤에 0을 채우고 싶다면 인자로 padding='post' 주기
- 꼭 가장 긴 문서의 길이를 기준으로 해야하는 것은 아니며, 가령 평균보다 너무 긴 문서가 있다면 길이에 제한을 두고 패딩할 수 있음.
- maxlen의 인자로 정수를 주면, 해당 정수로 모든 문서의 길이를 동일하게 함. 만약, 데이터가 손실될 경우에 앞의 단어가 아니라 뒤의 단어가 삭제되도록 하고싶다면 truncating='post'를 사용
- pad_sequences의 인자로 value를 사용하면 0이 아닌 다른 숫자로 패딩이 가능
padded = pad_sequences(encoded, padding='post', value=last_value)
# 02-08 원-핫 인코딩
1. 원-핫 인코딩이란?
-단어 집합(vocabulary) : 서로 다른 단어들의 집합
-원-핫 인코딩(One-Hot Encoding) : 단어 집합의 크기를 벡터의 차원으로 하고, 표현하고 싶은 단어의 인덱스에 1을, 다른 인덱스에는 0을 부여하는 벡터 표현 방식
-과정: 정수 인코딩 수행 -> 표현하고 싶은 단어의 고유한 정수를 인덱스로 간주하여 해당 위치에 1을, 나머지 위치에 0을 부여
2. 케라스를 이용한 원-핫 인코딩
-케라스 Tokenizer로 정수 인코딩 수행
-text_to_sequences()로 이를 정수 시퀀스로 변환
-to_categorical()로 정수 인코딩된 결과로부터 원-핫 인코딩 수행
[2, 5, 1, 6, 3, 7]
↓
[[0. 0. 1. 0. 0. 0. 0. 0.] # 인덱스 2의 원-핫 벡터
[0. 0. 0. 0. 0. 1. 0. 0.] # 인덱스 5의 원-핫 벡터
[0. 1. 0. 0. 0. 0. 0. 0.] # 인덱스 1의 원-핫 벡터
[0. 0. 0. 0. 0. 0. 1. 0.] # 인덱스 6의 원-핫 벡터
[0. 0. 0. 1. 0. 0. 0. 0.] # 인덱스 3의 원-핫 벡터
[0. 0. 0. 0. 0. 0. 0. 1.]] # 인덱스 7의 원-핫 벡터
3. 원-핫 인코딩의 한계
- 단어의 개수가 늘어날 수록, 벡터를 저장하기 위해 필요한 공간(=벡터의 차원)이 계속 늘어난다는 단점
- 단어의 유사도를 표현하지 못한다는 단점
-해결책 2가지
1) 카운트 기반의 벡터화 방법인 LSA(잠재 의미 분석), HAL 등
2) 예측 기반으로 벡터화하는 NNLM, RNNLM, Word2Vec, FastText 등
그 외 카운트 기반과 예측 기반 두 가지 방법을 모두 사용하는GloVe
# 02-09 데이터 분리
1. 지도 학습(Supervised Learning)
-훈련 데이터: X_train, y_train (문제지와 정답)
-테스트 데이터: X_test, y_test(시험지와 정답)
-훈련 데이터로 기계 학습 후 시험 데이터로 예측도 평가
2. X와 y 분리하기
-zip 함수로 분리하기
-데이터프레임으로 분리하기
-Numpy로 분리하기
3. 테스트 데이터 분리하기
- 사이킷런의 train_test_split() : 데이터의 순서를 섞고나서 훈련 데이터와 테스트 데이터를 분리
- X : 독립 변수 데이터
- y : 종속 변수 데이터
- test_size : 테스트용 데이터 개수(1보다 작을시 비율) 지정
- train_size : 학습용 데이터의 개수(1보다 작을시 비율) 지정
- random_state : 난수 시드
# 02-10 한국어 전처리 패키지
형태소와 문장 토크나이징 도구들인 KoNLPy와 KSS(Korean Sentence Splitter)와 함께 유용하게 사용할 수 있는 패키지들
1. PyKoSpacing
-띄어쓰기가 되어있지 않은 문장을 띄어쓰기를 한 문장으로 변환해주는 패키지
pip install git+https://github.com/haven-jeon/PyKoSpacing.git
GitHub - haven-jeon/PyKoSpacing: Automatic Korean word spacing with Python
Automatic Korean word spacing with Python . Contribute to haven-jeon/PyKoSpacing development by creating an account on GitHub.
github.com
2. Py-Hanspell
- 한글 맞춤법 검사기, 띄어쓰기 또한 보정함
pip install git+https://github.com/ssut/py-hanspell.git
GitHub - ssut/py-hanspell: 파이썬 한글 맞춤법 검사 라이브러리. (네이버 맞춤법 검사기 사용)
파이썬 한글 맞춤법 검사 라이브러리. (네이버 맞춤법 검사기 사용). Contribute to ssut/py-hanspell development by creating an account on GitHub.
github.com
3. SOYNLP
1) soynlp란?
- 품사 태깅, 단어 토큰화 등을 지원하는 단어 토크나이저
- 데이터에 자주 등장하는 단어들을 단어로 분석
2) 특징
- 기존의 형태소 분석기들은 신조어나 형태소 분석기에 등록되지 않은 단어 같은 경우에는 제대로 구분하지 못하는 단점
-> 특정 문자 시퀀스가 함께 자주 등장하는 빈도가 높고, 앞 뒤로 조사 또는 완전히 다른 단어가 등장하는 것을 고려해서 해당 문자 시퀀스를 형태소라고 판단하는 단어 토크나이저가 바로 soynlp
- 학습 기반의 단어 토크나이저이므로 기존의 KoNLPy에서 제공하는 형태소 분석기들과는 달리 학습 과정을 거쳐야 함
3) 내부구조
- 내부적으로 응집 확률(cohesion probability)과 브랜칭 엔트로피(branching entropy)를 활용한 단어 점수표로 동작
- WordExtractor.extract()로 전체 코퍼스에 대한 단어 점수표 계산
- 응집 확률 : 내부 문자열(substring)이 얼마나 응집하여 자주 등장하는지를 판단하는 척도
Ex) '반포한강공원에'보다 '반포한강궁원'의 응집 확률이 높음
- 브랜칭 엔트로피 : 주어진 문자열에서 얼마나 다음 문자가 등장할 수 있는지를 판단하는 척도
ㄴ하나의 완성된 단어에 가까워질수록 문맥으로 인해 점점 정확히 예측할 수 있게 되면서 점점 줄어드는 양상 보임
Ex) '디스' 다음에는 다양한 문자가 올 수 있으니까 1.63이라는 값을 가지는 반면, '디스플'이라는 문자열 다음에는 다음 문자로 '레'가 오는 것이 너무나 명백하기 때문에 0이란 값 가짐
4) L tokenizer
- L 토큰 + R 토큰으로 나누되, 분리 기준으로 점수가 가장 높은 L 토큰을 찾아내는 원리
Ex) 공원+에, 공부+하는
5) 최대 점수 토크나이저
- 띄어쓰기가 되지 않는 문장에서 점수가 높은 글자 시퀀스를 순차적으로 찾아내는 토크나이저
- MaxScoreTokenizer()
4. SOYNLP를 이용한 반복되는 문자 정제
- 의미없이 반복되는 것을 하나로 정규화시켜줌
Ex) ㅋㅋ, ㅋㅋㅋ, ㅋㅋㅋㅋ -> ㅋㅋ
5. Customized KoNLPy
- 형태소 분석기에 사용자 사전을 추가하는 패키지
pip install customized_konlpy
- Twitter()에 add_dictionary('단어', '품사')와 같은 형식으로 사전 추가
twitter.add_dictionary('은경이', 'Noun')
'딥러닝 > 딥러닝을 이용한 자연어처리 입문' 카테고리의 다른 글
[딥러닝 NLP] 06. 머신러닝(Linear, Logistic, Softmax Regression) (2) | 2023.12.06 |
---|---|
[딥러닝 NLP] 05. 벡터의 유사도(코사인, 유클리드, 자카드) (0) | 2023.11.29 |
[딥러닝 NLP] 04. 카운트 기반 단어 표현(BoW, DTM, TF-IDF) (1) | 2023.11.27 |
[딥러닝 NLP] 03. 언어 모델 (0) | 2023.10.18 |
[딥러닝 NLP] 01. 자연어처리 준비하기 (0) | 2023.03.05 |