텍스트 전처리 이론
- ex) James is working at Disney in London
- 입력: 벡터화된 텐서(숫자) --> NLP모델
- 토큰 정제: 토큰이 많다. 필요한 토큰만 남기자
(노이즈/불용어 제거, 원형복원, 품사태깅, 개체명인식)
- 토큰화(분절):
['James', 'is', 'working', 'at', 'Disney', 'in', 'London'] - 노이즈(불필요)/불용어(현재불필요) 제거:
의미적으로 중요한 토큰만 남김 (ex: 'at', 'in' 제거)
['James', 'is', 'working','at', 'Disney','in', 'London'] - 원형복원:
어간 및 표제어 추출 (시제 단순화, 과거/미래를 기본 시제로)
['James', 'work', 'Disney', 'London'] - 품사태깅:
추론 목적에 따라 특정 품사를 탈락할 수 있다.
[('James', 명사), ('work', 동사), ('Disney', 명사), ('London', 명사)] - 개체명 인식:
[('James', 사람), ('work', 동작), ('Disney', 단체), ('London', 도시)] - 벡터화:
[(1 0 0 0), (0 1 0 0), (0 0 1 0), (0 0 0 1)]
영문 전처리 실습
0. 영문 텍스트전처리 라이브러리
- !pip install nltk
- import nltk
- nltk.download('punkt_tab') #말뭉치 데이터
- nltk.download('omw-1.4')
1. 영문토큰
- 토큰화 함수1
- from nltk.tokenize import word_tokenize
- word_tokens = word_tokenize(text)
- 단어와 구두점(온점, 컴마, 물음표, 세미콜론, 느낌표 등과 같은 기호)으로
- 토큰화 함수2
- from nltk.tokenize import WordPunctTokenizer
- wordpuncttoken = WordPunctTokenizer().tokenize(text)
- 알파벳과 알파벳이 아닌 문자를 구분하여 토큰화
- 토큰화 함수3
- from nltk.tokenize import TreebankWordTokenizer
- treebankwordtoken = TreebankWordTokenizer().tokenize(text)
- 정규표현식에 기반한 토큰화
2-1. 불용어 처리
- stop_words = ["at", "be", "able", "in"]
- word_tokens = []
- for tag in treebankwordtoken:
- if len(tag) > 1:
- if tag not in stop_words:
- word_tokens.append(tag)
- print(word_tokens)
- from collections import Counter
- Counter(word_tokens).most_common()
[('James', 1), ('is', 1), ('working', 1), ('Disney', 1), ('London', 1)]
3-1. 원형복원, 어간추출
- 어간이 완성형 단어로 남는 것은 아니다. 그러나 같은 의미의 토큰으로 부여할 수 있다.
- from nltk.stem import PorterStemmer
- ps = PorterStemmer()
- print("believes -> "+ps.stem('believes'))
- believes -> believ
3-2. 원형복원, 표제어추출
- nltk.download('wordnet')
- from nltk.stem import WordNetLemmatizer
- wl = WordNetLemmatizer()
- print('studies -> '+ wl.lemmatize("studies"))
- studies -> study
4. 영문 품사 부착: PoS
- from nltk import pos_tag
- nltk.download('averaged_perceptron_tagger_eng')
- tagged_tokens = pos_tag(word_tokens)
- print(tagged_tokens)
- [('jame', 'NN'), ('is', 'VBZ'), ('work', 'JJ'), ('disney', 'NN'), ('london', 'NN')]
5. 개체명 인식
- nltk.download('words')
- nltk.download('maxent_ne_chunker_tab')
- from nltk import ne_chunk
- ne_tokens = ne_chunk(tagged_tokens)
- print(ne_tokens)
한글 전처리 실습
- 한글에서 의미의 최소 단위는 형태소
- 음절(글자) < 형태소 < 어절(단어, 띄어쓰기)
0. 한글 자연어 처리
- https://konlpy-ko.readthedocs.io/ko/v0.4.3/
- morphs : 형태소 토큰화
- nouns : 명사 토큰만 반환
- pos : 형태소에 품사 태깅하여 반환
1. 한글토큰
- Hannanum : KAIST에서 개발
- analyze : 다양한 형태학적 후보를 반환
- Kkma : 서울대에서 개발
- sentences : 문장 토큰화
- Komoran : Shineware팀에서 개발
- Mecab : 교토대에서 일본어용으로 개발된 분석기, 은전 프로젝트에 의해 한국어용 개발
- Okt(Twitter) : Will Hohyon Ryu가 개발
- phrases : 다양한 형태학적 후보를 반환
- #Okt 토큰화
- from konlpy.tag import Okt
- okt = Okt()
- okt_tokens = okt.morphs(kor_text)
- print(okt_tokens)
2. 한글 품사 부착
- # Okt 품사 태깅
- okt_tags = []
- for token in okt_tokens:
- okt_tags += okt.pos(token)
- print(okt_tags)
3. 노이즈 및 불용어 처리
- 불용어 처리
- stop_pos = ['Suffix','Punctuation','Josa','Foreign','Alpha','Number']
- 최빈어 조회: 최빈어를 조회하여 불용어 제거 대상을 선정
- from collections import Counter
- Counter(okt_tags).most_common()
정규표현식
- import re
- 숫자: \d
- 숫자열: \d+
- 문자: \w
- 모든문자: .
- re.search(pattern, string)
- string에서 pattern(정규표현식) 찾기. 여러개 라면 첫번째 것만
- re.findall(pattern, string)
- 정규표현식 패턴과 일치하는 모든 부분을 찾아 리스트로 반환
- re.match(pattern, string)
- str의 앞부분이 매치하는지 확인
- re.sub(pattern, repl, string) <-> re.findall()
- 패턴과 일치하는 모든 부분을 대체 문자열로 치환
- re.compile(pattern)
- 정규표현식 패턴을 재사용 가능한 패턴 객체로 생성
- pattern = re.compile(r'\d+')
- matches = pattern.findall('abc123def456')
- matches # ['123', '456']
- a? 에 쓸 수 있고 묶어서 [abc]? 로 쓸 수 있다.
- a* 은 '', 'a', 'aa', 'aaa', 'aaaa', 'aaaa...'
- a+ 은 'a', 'aa', 'aaa', 'aaaa, 'aaaa...'
- 그밖에
- | = or
- text5 = "I like apple and cherry but not banana"
- print(re.findall(r'apple|banana|cherry', text5)) # ['apple', 'cherry', 'banana']
- # ['apple', 'cherry', 'banana']
- ^ = not
- a부터 z까지가 아닌 것 중 하나
- re.findall(r'[^A-Za-z]+', text6)
- ( ) = 전체를 인식해서 , ( ) 안에 있는 것만 가져온다.
- text = "<사과>, 사과"
- pattern = r'<(사과)>'
- fruits = re.findall(pattern, text)
- print(fruits) # 사과
- text = "<사과>, <바나나>, <딸기>, <수박>, <오렌지>"
- pattern = r'<(사과|바나나|오렌지)>'
- fruits = re.findall(pattern, text)
- print(fruits) # 사과, 바나나, 오렌지
- \ = 회피용법
- 정규표현식이 아니라 문자 자체로 사용하고 싶을 때...
- ex( ?, *, + )
Greedy Q VS Reluctant Q
- Greedy: \(.+\)
- start: '('
- end: ')' 를 만나도 끝까지 갔다가, 마지막 ')'를 찾는다.
- Reluctant: \(.+?\)
- start: '('
- end: ')' 를 만나면 우선 반환한다. 그리고 또 찾는다.
- Quantifier(간접명시, 위치명시)부터 신경쓰고 직접명시를 사용하자.
Tags:
AI개발_교육