티스토리 뷰

Data/Analytics

[DA] NLP Pipeline - NLTK & KoNLPy

jeong_reneer 2022. 2. 9. 14:09

1. Introdunction to NLP

1) NLP (Natural Language Processing)

: 자연어처리, 즉 우리가 일상생활에서 사용하는 언어의 의미를 분석해 컴퓨터가 처리할 수 있도록 하는 일 

 Ex. Sentiment Classification, Machine Translation

 

2) NLP Pipeline

 

 

(1) Text Data (Corpus, 말뭉치, 코퍼스)

 

(2) Data Preprocessing (데이터 전처리) + FE

- Tokenization

- Stemming or Lemmatization

- Stopwords removal

- Text Representation

 

(3) Modeling (모델링)

Train - Test - Evaluate Model

 

3) 관련 패키지

(1) NLTK

- 자연어처리 및 문서 분석용 파이썬 패키지

- 주로 외국어 한정 사용

 

(2) KoNLPy

- 한국어를 위한 자연어처리 패키지

 

 

2. NLP Process

1) Tokenization (토큰화)

(1) 문장 토큰화

- 토큰의 단위를 문장으로 하여, 코퍼스 내 텍스트를 문장 단위로 구분하는 작업

- 영어의 경우 NLTK의 sent_tokenize 를 사용해 영어 문장 토큰화 수행 가능

from nltk.tokenize import sent_tokenize
print(sent_tokenize('<text>'))

 

(2) 단어 토큰화

- 토큰의 단위를 단어로 하여, 코퍼스 내 텍스트를 단어 단위로 구분하는 작업

- 영어의 경우 텍스트를 단어 단위로 구분할 때 보통 띄어쓰기, 즉 공백(whitespace)을 기준으로 함 

# word_tokenize : Don't => Do/n't & Jone's => Jone/'s
from nltk.tokenize import word_tokenize
print(word_tokenize('<text>'))

# WordPunctTokenizer: Don't => Don/'/t & Jone's => Jone/'/s
from nltk.tokenize import WordPunctTokenizer
print(WordPunctTokenizer().tokenize('<text>'))

 

Peen Treebank Tokenization

: 표준으로 쓰이고 있는 대표적인 토큰화 방법

- 규칙1. 하이픈(-)으로 구성된 단어는 하나로 유지

- 규칙2. 아포스트로피(')로 접어가 함께 하는 단어는 분리

from nltk.tokenize import TreebankWordTokenizer
tokenizer = TreebankWordTokenizer()
print(tokenizer.tokenize('<text>'))

 

 

2) 형태소 분석, 품사 태깅

(1) 형태소 분석

- 영어의 경우 단어 토큰화를 수행할 때 띄어쓰기를 단어 구분 기준으로 함 (어절 토큰화)

- 한국어의 경우 단어 토큰화를 수행할 때 형태소를 토큰의 단위로 함 (형태소 토큰화)

  한국어는 교착어(조사, 어미 등을 붙여서 말을 만드는 언어)이기 때문

- 형태소(morpheme) : 뜻을 가진 가장 작은 말의 단위

 

 

(2) 품사 태깅 (Part-Of-Speech Tagging, POS Tagging)

: 단어 토큰화 과정에서 각 단어가 어떤 품사로 쓰였는지 구분하는 것

- 때때로 단어는 표기는 같지만, 품사에 따라 의미가 달라지는 경우 발생. Ex) "fly" : 날다, 파리

- 단어의 의미를 제대로 파악하기 위해서는 해당 단어의 품사 정보 필요

 

Penn Treebank

Num Tag Description
1. CC Coordinating conjunction
2. CD Cardinal number
3. DT Determiner
4. EX Existential there
5. FW Foreign word
6. IN Preposition or subordinating conjunction
7. JJ Adjective
8. JJR Adjective, comparative
9. JJS Adjective, superlative
10. LS List item marker
11. MD Modal
12. NN Noun, singular or mass
13. NNS Noun, plural
14. NNP Proper noun, singular
15. NNPS Proper noun, plural
16. PDT Predeterminer
17. POS Possessive ending
18. PRP Personal pronoun
19. PRP\$ Possessive pronoun
20. RB Adverb
21. RBR Adverb, comparative
22. RBS Adverb, superlative
23. RP Particle
24. SYM Symbol
25. TO to
26. UH Interjection
27. VB Verb, base form
28. VBD Verb, past tense
29. VBG Verb, gerund or present participle
30. VBN Verb, past participle
31. VBP Verb, non-3rd person singular present
32. VBZ Verb, 3rd person singular present
33. WDT Wh-determiner
34. WP Wh-pronoun
35. WP$ Possessive wh-pronoun
36. WRB Wh-adverb

 

 

3) Stemming & Lemmatization

: 단어의 형태 변화(Lexical variations of term ; term variation)에 따라 같은 단어라도 다른 단어인 것처럼 취급되는 문제를 해결하기 위해 사용되는 보편적인 방법

 

(1) Stemming (어간 추출)

: 어형이 변형된 단어로부터 접사 등을 제거하고 그 단어의 어간을 분리하는 방법

from nltk.tokenize import word_tokenize
from nltk.stem import PorterStemmer

# word tokenization
words = word_tokenize('<text>')

# stemming
s = PorterStemmer()
result = [s.stem(w) for w in words]

# 결과 출력
print('original text:', text)
print('tokenized words:',words)
print('stemmed words:',result)

 

from nltk.stem import PorterStemmer
from nltk.stem import LancasterStemmer

# word tokenization
words = word_tokenize('<text>')

# stemming
s = PorterStemmer() # 포터 스태머
l = LancasterStemmer() # 랭커스터 스태머
ss = [s.stem(w) for w in words]
ll = [l.stem(w) for w in words]

# 결과 출력
print('original words:', words)
print('porter stemmer:', ss)
print('lancaster stemmer:',ll)

 

(2) Lemmatization (표제어 추출, 원형복원)

: 한 단어가 여러 형식으로 표현되어 있는 것을 단일 형식으로 묶어주는 기법

- 품사 정보가 남아있기에 stemming 에 비해 의미론적 관점에서 더 효과적

- BUT, stemming 만큼 DTM dimension reduction 측면에서는 덜 효과적

from nltk.stem import WordNetLemmatizer

# word tokenization
words = word_tokenize('<text>')

# lemmatization
n = WordNetLemmatizer()
result = [n.lemmatize(w) for w in words]

# 결과 출력
print('tokenized words:',words)
print('lemmatized words:',result)

 

Stemming VS Lemmatization

- 영어 텍스트 : stemming과 lemmatization이 명확히 구분되어 텍스트 전처리 과정에서 무엇을 사용할지 결정해야 함

- 한글 텍스트 : 형태소 분석 과정에서 stemming과 lemmatization이 함게 이루어짐

 

 

4) Stopwords removal (불용어 제거)

▪ Stopwords : 자연어 말뭉치 표현에 나타나는 단어들을 사용빈도가 높은 순으로 나열했을 때, 왼쪽에 존재하는 고빈도 단어

  Ex) 영어 : 정관사, 전치사 등 / 한글 : 조사 등

- 너무 자주 나타나는 단어들은 기능적인 역할을 하거나 문헌집단 전반에 걸쳐 나타나기에 특정 문헌의 내용을 대표할 수 X

▪ 목적 : 단어 정제를 통해 보다 제대로 된 분석 수행 & 차원 축소

 

① NLTK에서 제공하는 불용어 리스트를 활용해 불용어 제거 가능

from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

example = "Family is not an important thing. It's everything."

# 불용어 리스트 생성
stop_words = set(stopwords.words('english')) 

# 단어 토큰화 실시
word_tokens = word_tokenize(example)

# 단어 토큰화 결과로부터 불용어 제거 실시
result = []
for w in word_tokens: 
    if w not in stop_words: 
        result.append(w)

 

② 사용자 정의 불용어 제거

import nltk
nltk.download('punkt')
from nltk.corpus import stopwords 
from nltk.tokenize import word_tokenize

example = "막 답답하고 숨이 막히고 내게 빠진 거 맞지 너무 겁먹지 마 난 바로 너야."

# 불용어 리스트 생성
stop_words = "답답하고 숨이 빠진 맞지 겁먹지"
stop_words = stop_words.split(' ')

# 단어 토큰화
word_tokens = word_tokenize(example)

# 불용어 제거
result = [word for word in word_tokens if word not in stop_words]

 

* 한국어 불용어 리스트 참고 사이트
https://www.ranks.nl/stopwords/korean
https://bab2min.tistory.com/544

 

 

5) 텍스트 표현 (text representation)

(1) 정수 인코딩 (Integer encoding)

▪ 인코딩 (Encoding) : 텍스트를 숫자로 변환해 컴퓨터가 데이터를 처리할 수 있도록 하는 절차

▪ 정수 인코딩 (Interger encoding) : 각 단어를 고유한 정수에 매핑하는 인코딩 방법

- 단어에 인덱스를 부여하는 방법에 따라 다양한 정수 인코딩 방법 존재

 

 

Dictionary 사용

from nltk.tokenize import sent_tokenize
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
import nltk
nltk.download('punkt')
nltk.download('stopwords')

word_to_index (빈도 수가 높은 상위 5개의 단어들만을 가지는 딕셔너리)

# text : 여러 문장(sentence)으로 구성된 문서(document)
text = "A barber is a person. a barber is good person. a barber is huge person. he Knew A Secret! The Secret He Kept is huge secret. Huge secret. His barber kept his word. a barber kept his word. His barber kept his secret. But keeping and keeping such a huge secret to himself was driving the barber crazy. the barber went up a huge mountain."

# 문장 토큰화 -> text : 문장 단위로 토큰화된 문장들을 요소로 가지는 리스트(list)
text = sent_tokenize(text)

# 텍스트 전처리 및 단어 토큰화
vocab = {} # 단어(key)와 단어 빈도 수(value)를 갖는 딕셔너리
sentences = [] # 단어 토큰화 이후 텍스트
stop_words = set(stopwords.words('english')) # 불용어

for i in text: # 문장에 대하여 반복
    sentence = word_tokenize(i) # 문장을 단어로 토큰화 하여 sentence 변수에 저장
    result = []
    for word in sentence: # 단어에 대하여 반복
        word = word.lower() # 모두 소문자로 변경
        if word not in stop_words: # 불용어 제거
            if len(word) > 2: # 길이가 짧은 단어 제거
                # result에 word 추가
                result.append(word)
                # 빈도 초기값 생성
                if word not in vocab:
                    vocab[word] = 0
                # vocab에 빈도 추가
                vocab[word] += 1
    
    sentences.append(result)
    
    
# sentences : 단어 단위로 토큰화된 단어들을 요소로 갖는 리스트를 요소로 갖는 이중 리스트
print(sentences)
>>> [['barber', 'person'], ['barber', 'good', 'person'], ['barber', 'huge', 'person'], ['knew', 'secret'], ['secret', 'kept', 'huge', 'secret'], ['huge', 'secret'], ['barber', 'kept', 'word'], ['barber', 'kept', 'word'], ['barber', 'kept', 'secret'], ['keeping', 'keeping', 'huge', 'secret', 'driving', 'barber', 'crazy'], ['barber', 'went', 'huge', 'mountain']]
    
    
# vocab : 단어를 키(key), 단어의 빈도 수를 값(value)으로 갖는 딕셔너리 - 단어 중복 X
# 빈도 수가 높은 순서대로 정렬
vocab_sorted = sorted(vocab.items(), 
                      key=lambda x: x[1], # vocab의 value인 빈도 수를 key로 할당
                      reverse=True)
print(vocab_sorted)
>>> [('barber', 8), ('secret', 6), ('huge', 5), ('kept', 4), ('person', 3), ('word', 2), ('keeping', 2), ('good', 1), ('knew', 1), ('driving', 1), ('crazy', 1), ('went', 1), ('mountain', 1)]


# 단어 빈도 수가 높은 순서대로 낮은 인덱스 부여한 딕셔너리
word_to_index = {}
i = 0
for word, frequency in vocab_sorted:
    if frequency > 1: # 빈도 수가 1인 단어 제거
        i += 1
        word_to_index[word] = i
print(word_to_index)
>>> {'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5, 'word': 6, 'keeping': 7}

# 보통 NLP에서는 모든 단어들을 사용하기보다 빈도 수가 높은 n개의 단어들만 사용
# 빈도 수가 가장 높은 5개의 단어들만을 사용
vocab_size = 5
words_frequency = [w for w, c in word_to_index.items() if c >= vocab_size+1] # 인덱스가 5 초과인 단어들
for w in words_frequency:
    del word_to_index[w] # 인덱스가 5 초과인 단어 제거
print(word_to_index)
>>> {'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5}

② 정수 인덱싱 (word_to_index를 이용해 sentences에 있는 각 단어들을 인덱스로 매핑)

 * OOV(Out-Of-Vocabulary) : 단어 집합(word_to_index)에 존재하지 않는 단어들

# OOV에 인덱스 부여
word_to_index['OOV'] = len(word_to_index)+1

# sentences의 모든 단어들을 고유 정수에 매핑 => 정수 인코딩
encoded = [] # 정수 인코딩 한 sentences를 담을 리스트
for s in sentences: # 문장에 대하여 반복
    temp = []
    for w in s: # 단어에 대하여 반복
        try: # 단어 집합에 존재하는 단어인 경우
            temp.append(word_to_index[w]) # temp에 해당 단어의 인덱스 추가
        except KeyError: # 단어 집합에 존재하지 않는 단어인 경우
            temp.append(word_to_index['OOV']) # temp에 OOV의 인덱스 추가
    encoded.append(temp) # encoded에 정수 인코딩 한 리스트 추가
    
print(encoded)
>>> [[1, 5], [1, 6, 5], [1, 3, 5], [6, 2], [2, 4, 3, 2], [3, 2], [1, 4, 6], [1, 4, 6], [1, 4, 2], [6, 6, 3, 2, 6, 1, 6], [1, 6, 3, 6]]

 

▣ Counter 사용

: 단어에 인덱스를 부여하는 방법 중 하나로, 단어를 빈도 수 기준으로 정렬한 단어 집합(vocabulary)을 만들고, 빈도 수가 높은 순서대로 낮은 숫자부터 차례대로 정수를 부여하는 방법

▪ Counter() : 단어의 중복을 제거하고 단어의 빈도 수를 계산하여 단어를 key로, 빈도 수를 value로 갖는 dictionary 반환

▪ most_common() : 빈도 수가 높은 상위 n개의 단어만을 갖는 dictionary 반환

from collections import Counter
# 이중 리스트를 리스트로 변환
words = sum(sentences, [])
print(words)
>>> ['barber', 'person', 'barber', 'good', 'person', 'barber', 'huge', 'person', 'knew', 'secret', 'secret', 'kept', 'huge', 'secret', 'huge', 'secret', 'barber', 'kept', 'word', 'barber', 'kept', 'word', 'barber', 'kept', 'secret', 'keeping', 'keeping', 'huge', 'secret', 'driving', 'barber', 'crazy', 'barber', 'went', 'huge', 'mountain']

# Counter() : 단어 중복 제거하고 단어 빈도 수 계산해 단어를 key, 빈도 수를 value로 갖는 딕셔너리 반환
vocab = Counter(words)
print(vocab)
>>> Counter({'barber': 8, 'secret': 6, 'huge': 5, 'kept': 4, 'person': 3, 'word': 2, 'keeping': 2, 'good': 1, 'knew': 1, 'driving': 1, 'crazy': 1, 'went': 1, 'mountain': 1})

# most_common() : 빈도 수가 높은 상위 n개 단어만을 갖는 딕셔너리 반환
vocab_size = 5
vocab = vocab.most_common(vocab_size)
print(vocab)
>>> [('barber', 8), ('secret', 6), ('huge', 5), ('kept', 4), ('person', 3)]

# 높은 빈도수를 가진 단어일수록 낮은 정수 인덱스 부여
# 정수 인코딩
word_to_index = {}
i = 0
for (word, frequency) in vocab:
    i = i+1
    word_to_index[word] = i
print(word_to_index)
>>> {'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5}

 

NLTK의 FreqDIst 사용

▪ FreqDist() : 빈도 수 계산. Counter()와 같은 방식으로 사용 가능

▪ most_common() : 빈도 수가 높은 상위 n개의 단어만을 갖는 dictionary 반환

from nltk import FreqDist
import numpy as np
# 이중 리스트를 리스트로 변환하여 (문장 구분을 제거하여) 입력
vocab = FreqDist(np.hstack(sentences))
print(vocab)
>>> <FreqDist with 13 samples and 36 outcomes>
print(vocab["barber"]) # 단어 'barber'의 빈도 수 출력
>>> 8

# most_common() : 빈도 수가 높은 상위 n개 단어만을 갖는 딕셔너리 반환
vocab_size = 5
vocab = vocab.most_common(vocab_size)
print(vocab)
>>> [('barber', 8), ('secret', 6), ('huge', 5), ('kept', 4), ('person', 3)]

# 정수 인코딩
word_to_index = {word[0] : index+1 for index, word in enumerate(vocab)}
print(word_to_index)
>>> {'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5}

 

 

(2) 원-핫 인코딩 (One-hot encoding)

▪ 단어 집합 (Vocabulary) : 서로 다른 단어들의 집합 (코퍼스에 나타난 모든 단어들이 중복 없이 존재)

  기본적으로 book과 books와 같은 단어의 변형 형태도 다른 단어로 간주

▪ 원-핫 인코딩 (One-hot encoding) : 단어 집합의 크기를 벡터의 차원으로 하고, 표현하고 싶은 단어의 인덱스에 1, 나머지 단어들의 인덱스에 0의 값을 부여하는 벡터 표현 방식 → 원-핫 벡터 생성

 

  코퍼스에 대하여 단어 집합 생성 by 단어 토큰화

단어 집합에 존재하는 각 단어에 고유한 정수(인덱스) 부여 by 정수 인코딩

표현하고 싶은 단어의 인덱스 위치에 1, 나머지 단어들의 인덱스 위치에 0의 값을 부여

!pip install konlpy
from konlpy.tag import Okt

okt = Okt() # 형태소 분석기 선언
token = okt.morphs('나는 자연어 처리를 배운다') # 단어 토큰화
print(token)
>>> ['나', '는', '자연어', '처리', '를', '배운다']

word2index = {}
for voca in token:
    if voca not in word2index.keys():
        word2index[voca] = len(word2index)
print(word2index)
>>> {'나': 0, '는': 1, '자연어': 2, '처리': 3, '를': 4, '배운다': 5}

# 토큰을 입력하면 해당 토큰에 대한 원-핫 벡터를 반환하는 함수
def one_hot_encoding(word, word2index):
    one_hot_vector = [0]*(len(word2index)) # 단어 집합의 크기가 벡터의 차원, 모든 값을 0으로 초기화
    index = word2index[word] # 표현하고 싶은 단어의 인덱스
    one_hot_vector[index] = 1 # 표현하고 싶은 단어의 인덱스 위치에 1을 값으로 부여
    return one_hot_vector # 원-핫 벡터를 반환
    
one_hot_encoding('자연어', word2index)
>>> [0, 0, 1, 0, 0, 0]

one_hot_encoding('배운다', word2index)
>>> [0, 0, 0, 0, 0, 1]

 

원-핫 인코딩의 한계

 단어 집합의 단어 개수가 늘어날수록 원-핫 벡터의 차원(단어 집합의 크기)이 증가해 필요한 공간이 늘어나 비효율적

 단어의 유사도 표현 불가 : 검색 시스템 등에서 치명적인 단점으로 작용 (연관 검색어)

 

(3) 워드 임베딩 (Word embedding)

▪ 워드 임베딩 (Word Embedding) : 단순 숫자가 아닌, 단어를 밀집 벡터 (Dense vector)로 표현하는 것

- 단어 간 유사성을 알 수 없다는 인코딩의 단점을 해결하고자, 단어의 잠재 의미를 반영해 다차원 공간에 단어를 벡터화

- 다양한 임베딩 방법 존재

Ex. CounterVectorizer

: 입력된 문장을 토큰화하여, 해당 문장을 토큰의 등장 빈도 벡터로 표현하는 워드 임베딩 기법

 

① import 및 객체 생성

from sklearn.feature_extraction.text import CountVectorizer
sample_vectorizer = CountVectorizer() # 객체 생성

CounterVectorizer 학습

- 어떤 단어들을 사용할지, 어떤 단어가 중요한지 학습하는 과정

- 토큰의 출현 빈도를 기준으로, 문장을 벡터로 표현

sample_text1 = ["hello, my name is dacon and I am a data scientist!"]
sample_vectorizer.fit(sample_text1) # 학습

print(sample_vectorizer.vocabulary_) # 학습한 단어 목록 (Vocabulary)
>>> {'hello': 4, 'my': 6, 'name': 7, 'is': 5, 'dacon': 2, 'and': 1, 'am': 0, 'data': 3, 'scientist': 8}

# Vocabulary를 기준으로 새로운 문장을 벡터로 표현
vocab = sample_vectorizer.vocabulary_
sorted_vocab = sorted(vocab.items())
print(sorted_vocab)
>>> [('am', 0), ('and', 1), ('dacon', 2), ('data', 3), ('hello', 4), ('is', 5), ('my', 6), ('name', 7), ('scientist', 8)]

새로운 문장에 대해 CounterVectorizer 적용

sample_text2 = ["you are learning dacon data science"]
sample_vector = sample_vectorizer.transform(sample_text2)
print(sample_vector.toarray())
>>> [[0 0 1 1 0 0 0 0 0]]

- 단어들의 출현 빈도로 이루어진 크기 9의 벡터가 출력됨

- dacon, data → 1번씩 출현하여 '1' / 나머지는 '0'

sample_text3 = ["you are learning dacon data science with movie data"]
sample_vector2 = sample_vectorizer.transform(sample_text3)
print(sample_vector2.toarray())
>>> [[0 0 1 2 0 0 0 0 0]]

- dacon → 1번 출현하여 '1' / 'data' → 2번 출현하여 '2' / 나머지는 '0'

 

 

 

3. 한국어 텍스트 NLP (KoNLPY)

!pip install konlpy

 

1) KoNLPy의 내장된 분석기 종류

(1) Hannanum

(2) Kkma

(3) Komoran

(4) Mecab

(5) Okt(Twitter) : 인터넷 용어

 

- 분석기마다 로딩 시간, 실행 시간 다름

- 동일 문장이라도 분석기에 따라 품사 태깅 결과 다름

- KoNLPy의 분석기 중에서 사용할 것 불러와 인스턴스(객체) 생성

from konlpy.tag import Okt,Kkma
okt = Okt()
kkma = Kkma()

 

2) KoNLPy 공통 사용 함수

▪ morphs : 형태소 분석

pos : 품사 태깅

nouns : 명사 추출

 

분석기에 따라 사용할 수 있는 함수가 조금씩 다름

Ex) okt 함수의 기능

morphs(phrase, norm=False, stem=False) # phrase 를 형태소 단위로 나눔
nouns(phrase) # phrase 의 형태소 중에서 noun 만 추출
phrases(phrase) # phrase 에서 어절을 추출
pos(phrase, norm=False, stem=False) # 품사(POS) 태깅

 

3) 실습

(1) 토큰화

text = "아버지가 방에 들어가신다"

print("kkma :", kkma.morphs(text)) 
print("okt :", okt.morphs(text))

 

(2) 품사 태깅

print(kkma.pos(text))
print(okt.pos(text))

# 품사가 명사인 단어들만 남기기
nouns = []
pos_text = okt.pos(text)

for each_tuple in pos_text:
    if each_tuple[1] == "Noun":
        nouns.append(each_tuple[0])

nouns

 

(3) 정규화

text = "안녕하세욬ㅋㅋㅋ 반가워요 샤릉해"

print("정규화 적용 X:", okt.pos(text, norm=False))
print("정규화 적용 O:", okt.pos(text, norm=True))

 

(4) 어근화

text = "달콤한 너의 러시안 룰렛"

print("어근화 적용 X:", okt.pos(text, stem=False))
print("어근화 적용 O:", okt.pos(text, stem=True))

 

세종 품사 태그

대분류 태그 설명
체언 NNG 일반 명사
체언 NNP 고유 명사
체언 NNB 의존 명사
체언 NR 수사
체언 NP 대명사
용언 VV 동사
용언 VA 형용사
용언 VX 보조 용언
용언 VCP 긍정 지정사
용언 VCN 부정 지정사
관형사 MM 관형사
부사 MAG 일반 부사
부사 MAJ 접속 부사
감탄사 IC 감탄사
조사 JKS 주격 조사
조사 JKC 보격 조사
조사 JKG 관형격 조사
조사 JKO 목적격 조사
조사 JKB 부사격 조사
조사 JKV 호격 조사
조사 JKQ 인용격 조사
조사 JX 보조사
조사 JC 접속 조사
선어말 어미 EP 선어말 어미
어말 어미 EF 종결 어미
어말 어미 EC  
어말 어미 ETN 명사형 전성 어미
어말 어미 ETM 관형형 전성 어미
접두사 XPN 체언 접두사
접미사 XSN 명사 파생 접미사
접미사 XSV 동사 파생 접미사
접미사 XSA 형용사 파생 접미사
어근 XR 어근
부호 SF 마침표, 물음표, 느낌표
부호 SP 쉼표, 가운뎃점, 콜론, 빗금
부호 SS 따옴표, 괄호표, 줄표
부호 SE 줄임표
부호 SO 붙임표 (물결, 숨김, 빠짐)
부호 SW 기타기호 (논리수학기호, 화폐기호)
분석 불능 NF 명사추정범주
분석 불능 NV 용언추정범주
분석 불능 NA 분석불능범주
한글 이외 SL 외국어
한글 이외 SH 한자
한글 이외 SN 숫자

 

'Data > Analytics' 카테고리의 다른 글

[DA] WordCloud  (0) 2022.02.10
[DA] FE (Feature Engineering)  (0) 2022.01.18
[DA] EDA & 시각화  (0) 2022.01.17
[DA] Numpy & Pandas  (0) 2022.01.13
댓글
공지사항