-
[3월 1주차-3/6(2)]텍스트 전처리1-토큰화, 정제 및 정규화, 표제어 및 어간 추출, 불용어 제거Why Not SW CAMP 5기/수업 기록 2025. 3. 6. 17:35
✅텍스트 전처리
- 토큰화(tokenization)
- 정제(cleaning) and 정규화(normalization)
- 어간 추출 and 표제어 추출
- 불용어(stopword) 제거
- 정규 표현식(regular expression)
- 정수 인코딩(integer encoding)
- 패딩(padding)
- 원 핫 인코딩(one-hot encoding)
- 데이터의 분리(splitting data)
텍스트 전처리는 자연어 처리(NLP)에서 필수적인 과정으로, 데이터를 정제하고 분석에 적합한 형태로 변환하는 작업을 의미합니다. 이 과정에는 토큰화, 정제 및 정규화, 표제어 및 어간 추출, 불용어 제거 등이 포함됩니다.
정수 인코딩 이후 부터는 다음 게시글을 참고해주세요
1. 토큰화(Tokenization)
토큰화는 텍스트를 일정한 단위로 나누는 작업으로, 단어 토큰화(Word Tokenization)와 문장 토큰화(Sentence Tokenization)로 구분됩니다.
단어 토큰화(Word Tokenization)
단어 단위로 텍스트를 분리하는 과정입니다. 그러나 몇 가지 고려해야 할 사항이 있습니다.
- 단순히 공백을 기준으로 분리하면 안 됩니다.
- 구두점이나 특수 문자는 문장 경계를 구분하는 데 도움을 줄 수 있습니다.
- 줄임말, 복합 단어 등을 올바르게 인식해야 합니다.
파이썬을 활용한 단어 토큰화 예제
from nltk.tokenize import word_tokenize, WordPunctTokenizer from tensorflow.keras.preprocessing.text import text_to_word_sequence from nltk.tokenize import TreebankWordTokenizer import nltk nltk.download('punkt') text = "Ph.D researchers prefer a home-based approach, but Mr. Jone’s opinion is different." # NLTK 단어 토큰화 print(word_tokenize(text)) ''' ['Ph.D', 'researchers', 'prefer', 'a', 'home-based', 'approach', ',', 'but', 'Mr.', 'Jone', '’', 's', 'opinion', 'is', 'different', '.'] ''' # WordPunct 토큰화 print(WordPunctTokenizer().tokenize(text)) ''' ['Ph', '.', 'D', 'researchers', 'prefer', 'a', 'home', '-', 'based', 'approach', ',', 'but', 'Mr', '.', 'Jone', '’', 's', 'opinion', 'is', 'different', '.'] ''' # Keras 토큰화 print(text_to_word_sequence(text)) ''' ['ph', 'd', 'researchers', 'prefer', 'a', 'home', 'based', 'approach', 'but', 'mr', 'jone’s', 'opinion', 'is', 'different'] ''' # Treebank 토큰화 print(TreebankWordTokenizer().tokenize(text)) ''' ['Ph.D', 'researchers', 'prefer', 'a', 'home-based', 'approach', ',', 'but', 'Mr.', 'Jone’s', 'opinion', 'is', 'different', '.'] '''
문장 토큰화(Sentence Tokenization)
문장을 단위로 분리하는 과정입니다.
from nltk.tokenize import sent_tokenize text = "I love programming. NLP is fascinating!" print(sent_tokenize(text)) # ['I love programming.', 'NLP is fascinating!']
한국어 토큰화의 어려움
한국어에서의 토큰화는 영어보다 더 복잡합니다. 이는 한국어가 교착어이며, 어미 변형이 많기 때문입니다. 한국어 토큰화를 위해 형태소 분석이 필요합니다.
예) "루비가 학교에 가서 친구들과 함께 공부를 열심히 했다."
- 어근:
- '루비' (실질적 의미를 나타내는 중심 부분)
- '학교' (장소를 나타내는 중심 부분)
- '공부' (행동을 나타내는 중심 부분)
- 어간:
- '가' (동사 '가다'의 어간)
- '하' (동사 '하다'의 어간)
- 어미:
- '서' (동사 ‘가다’의 연결 어미)
- '였' (과거 시제 선어말 어미)
- '다' (어말 어미)
- 단어:
- '루비', '학교', '가서', '친구들', '공부', '열심히', '했다'
- 어절:
- '루비가', '학교에', '가서', '친구들과', '함께', '공부를', '열심히', '했다' (띄어쓰기 단위)
형태소 분석
형태소(Morpheme)는 뜻을 가진 가장 작은 말의 단위입니다. 형태소는 크게 자립 형태소와 의존 형태소로 나뉩니다.
- 자립 형태소: 명사, 대명사, 수사, 관형사, 부사, 감탄사 등 독립적으로 쓰일 수 있는 형태소
- 의존 형태소: 다른 형태소와 결합해서만 사용되는 형태소 (예: 조사, 어미, 접사, 어간)
예) "루비가 책을 읽었다"
- 형태소 단위로 분해하면:
- 자립 형태소: "루비", "책"
- 의존 형태소: "-가", "-을", "읽-", "-었-", "-다"
품사 태깅 (Part-of-Speech Tagging)
단어의 품사를 구분하는 과정으로, 문맥에 따라 단어의 의미가 달라질 수 있습니다.
예) "못"
- 명사: "못을 박다" (screw)
- 부사: "밥을 못 먹는다" (하지 못함)
품사 태깅을 통해 각 단어가 어떤 품사로 쓰였는지 구분하면 분석의 정확도를 높일 수 있습니다.
from konlpy.tag import Okt from konlpy.tag import Kkma okt = Okt() kkma = Kkma() text='열심히 코딩한 당신, 연휴에는 여행을 가라' # okt print(f'okt 형태소 분석: {okt.morphs(text)}') ''' okt 형태소 분석: ['열심히', '코딩', '한', '당신', ',', '연휴', '에는', '여행', '을', '가라'] ''' print(f'okt 품사 태깅: {okt.pos(text)}') ''' okt 품사 태깅: [('열심히', 'Adverb'), ('코딩', 'Noun'), ('한', 'Josa'), ('당신', 'Noun'), (',', 'Punctuation'), ('연휴', 'Noun'), ('에는', 'Josa'), ('여행', 'Noun'), ('을', 'Josa'), ('가라', 'Noun')] ''' print(f'okt 명사 추출: {okt.nouns(text)}') ''' okt 명사 추출: ['코딩', '당신', '연휴', '여행', '가라'] -> '가라'는 명사 아닌데? ''' # kkma print(f'kkma 형태소 분석: {kkma.morphs(text)}') ''' kkma 형태소 분석: ['열심히', '코딩', '하', 'ㄴ', '당신', ',', '연휴', '에', '는', '여행', '을', '가라'] ''' print(f'kkma 품사 태깅: {kkma.pos(text)}') ''' kkma 품사 태깅: [('열심히', 'MAG'), ('코딩', 'NNG'), ('하', 'XSV'), ('ㄴ', 'ETD'), ('당신', 'NP'), (',', 'SP'), ('연휴', 'NNG'), ('에', 'JKM'), ('는', 'JX'), ('여행', 'NNG'), ('을', 'JKO'), ('가라', 'VV')] ''' print(f'kkma 명사 추출: {kkma.nouns(text)}') ''' kkma 명사 추출: ['코딩', '당신', '연휴', '여행'] '''
2. 정제(Cleaning) 및 정규화(Normalization)
데이터에서 불필요한 정보를 제거하고 일관된 형태로 변환하는 과정입니다.
정제
- 토큰화 작업 전: 토큰화 작업에 방해되는 부분들 배제
- 토큰화 작업 이후: 여전히 남아있는 노이즈를 제거하기 위해 지속적으로 이루어짐
정규화
- 같은 의미를 가진 단어를 하나의 단어로 통합 (예: USA → US)
- 대소문자 통합 (예: Apple과 apple을 동일하게 처리. 단, US-미국/us-우리, 회사명 등 대소문자가 구분되어야 하는 경우 주의)
- 불필요한 단어 제거 (예: 불용어, 등장 빈도가 적은 단어, 길이가 짧은 단어 등)
3. 표제어 추출(Lemmatization) 및 어간 추출(Stemming)
단어를 기본 형태로 변환하여 단어 수를 줄이는 기법입니다.
표제어 추출(Lemmatization)
단어의 품사를 고려하여 기본 사전형 단어로 변환하는 과정입니다.
from nltk.stem import WordNetLemmatizer nltk.download('wordnet') lemmatizer = WordNetLemmatizer() lemmatizer.lemmatize('running', 'v') # run lemmatizer.lemmatize('dies', 'v') # die lemmatizer.lemmatize('watched', 'v') # watch lemmatizer.lemmatize('has', 'v') # have
어간 추출(Stemming)
어미를 제거하여 단어의 어간을 추출하는 방법
단순한 규칙 기반 변환이므로 의미를 보장하지 않습니다.
# 어간 추출 알고리즘: Porter 알고리즘과 lancaster stemmer 알고리즘 from nltk.stem import PorterStemmer from nltk.stem import LancasterStemmer from nltk.tokenize import word_tokenize por = PorterStemmer() lan = LancasterStemmer() tokenized_sentence = word_tokenize(text_eng) print([por.stem(word) for word in tokenized_sentence]) ''' ['ph.d', 'research', 'prefer', 'a', 'home-bas', 'approach', ',', 'but', 'mr.', 'jone', '’', 's', 'opinion', 'is', 'differ', '.'] ''' print([lan.stem(word) for word in tokenized_sentence]) ''' ['ph.d', 'research', 'pref', 'a', 'home-based', 'approach', ',', 'but', 'mr.', 'jon', '’', 's', 'opin', 'is', 'diff', '.'] '''
한국어에서의 어간 추출
- 체언: 명사, 대명사, 수사
- 수식언: 관형사, 부사
- 관계언: 조사
- 독립언: 감탄사
- 용언: 동사, 형용사 -> 어간과 어미의 결합임
- 규칙 활용: 어간이 어미를 취할때 어간의 모습이 일정
예) '잡다': '잡-'(어간) + '-다'(어미) - 불규칙 활용 : 어간이 어미를 취할때 어간의 모습이 바뀌거나 취하는 어미가 특수한 경우
예) '듣-, 돕, 곱-, 잇-, 오르-, 노랗-' 등이
'듣/들-, 돕/도우-, 곱/고우-, 잇/이-, 오르/올-, 노랗/노라- 로 쓰임
- 규칙 활용: 어간이 어미를 취할때 어간의 모습이 일정
4. 불용어(Stopword) 제거
분석에 불필요한 단어(예: "the", "is", "and")를 제거하여 데이터의 품질을 향상시키는 과정입니다.
from nltk.corpus import stopwords from nilt.tokenize import word_tokenize from konlpy.tag import Okt nltk.download('stopwords') nltk.download('punkt') # NLTK에서 불용어 사전 확인 198개 stopword_list = stopwords.words('english') print(stopword_list[:10]) # ['a', 'about', 'above', 'after', 'again', 'against', 'ain', 'all', 'am', 'an'] example = "Family is not an important thing. It's everything." stopwords = set(stopwords.words('english')) word_tokens = word_tokenize(example) print(word_tokens) # ['Family', 'is', 'not', 'an', 'important', 'thing', '.', 'It', "'s", 'everything', '.'] result = [] for word in word_tokens: if word not in stopwords: result.append(word) print(result) # ['Family', 'important', 'thing', '.', 'It', "'s", 'everything', '.'] okt = Okt() example = "고기를 아무렇게나 구우려고 하면 안 돼. 고기라고 다 같은 게 아니거든. 예컨대 삼겹살을 구울 때는 중요한 게 있지." # 임의의 불용어 사전 만들기 stop_words = "를 아무렇게나 구 우려 고 안 돼 같은 게 구울 때 는" stop_words = set(stop_words.split(' ')) word_list = okt.morphs(example) result = [] for word in word_list: if word not in stop_words: result.append(word) print(result) # ['고기', '하면', '.', '고기', '라고', '다', '아니거든', '.', '예컨대', '삼겹살', '을', '중요한', '있지', '.']
결론
텍스트 전처리는 자연어 처리의 핵심 단계로, 올바른 토큰화, 정제 및 정규화를 수행하면 모델의 성능을 크게 향상시킬 수 있습니다. 특히, 표제어 추출과 불용어 제거를 적절히 활용하면 데이터의 품질을 높이고 분석 효율을 개선할 수 있습니다.
'Why Not SW CAMP 5기 > 수업 기록' 카테고리의 다른 글
[3월 1주차-3/7(2)]텍스트 전처리3-정수 인코딩, 패딩 (0) 2025.03.07 [3월 1주차-3/7(1)]텍스트 전처리2-정규 표현식 (0) 2025.03.07 [3월 1주차-3/6(1)]🌍 자연어 처리 (Natural Language Processing, NLP) (1) 2025.03.06 [3월 1주차-3/5]파이썬과 MySQL을 활용한 주식 분석 시스템 구축하기 (1) 2025.03.05 [3월 1주차-3/4]SQL 프로그래밍 : 스토어드 프로시저, 함수, 인덱스, 뷰, 트리거 활용법 (0) 2025.03.04