자연어 처리 강좌를 정리한다.
개념
- 문장을 분해하여 관계를 만들어 주어야 한다.
- 데이터를 서로 연결하다보면 2차원 이상으로 발전한다.
- 자연어는 모델링은 쉽지만, 전처리와 결과의 해석이 중요한다. 결과에 따른 해석이 따라 의미가 틀려진다. 이는 이미지/음성과 틀린 부분이다.
- 음운론, 형태론, 통사론, 의미론, 추리론
- Document -> Tokenizing -> Streaming/Tagging (컴퓨터가 이해하는 방식으로 배치하기) -> 최종 Word2Vec 에서 사용함
Tokenizing
- 구글 Colab을 사용한다.
- Token: document에서 쓸만한 것들로 의미를 같는 문자열 -> Tokenizing
- Colab에서 필요한 모듈 설치하기 in ubuntu
! apt-get update
! apt-get install g++ openjdk-8-jdk
! pip3 install nltk konlpy wordcloud matplotlib gensim
! apt-get install fonts-nanum*
! apt-get install fontconfig
! fc-cache -fv
! cp /usr/share/fonts/truetype/nanum/Nanum* /usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/fonts/ttf/
! rm -rf /content/.cache/matplotlib/*
- import nltk # Natural Language ToolKit 사용
+ sent_tokenize, word_tokenize
- import re #정규표현식 사용
// 패키지 사용
text = """갤럭시(GalaxyNote9)노트9. 2018년 08월 폭발적인 인기를 이끌고 있습니다.
담당자 010-222-9999. 홍보팀 010-8888-9999"""
from nltk import sent_tokenize, word_tokenize, FreqDist
sent_tokenize(text)
tokens = word_tokenize(text)
// 정규표현식
import re
tokenizer = re.compile(r'[가-힣]+')
tokenizer.findall(text)
Stemming & Tagging
순서 Tokenizing -> Stemming -> Tagging을 한다. 일반/평문이 결과값이 잘나오고, 강조문/도치문/압축문은 일반/평문으로 만들어하는게 좋다.
Stemming: 정규화
- 토큰의 어근/어간 추출
- 가능한 비슷한 의미 형태로 묶어주기 => 원형화한다
예) 가다, 가니, 가고 => 가-
산뜻하다, 산뜻하니, 산뜻하고 => 산뜻하-
Tagging: 문법/Filter
- Token별 높은 확률의 태그(속성값/문법)을 추가
- 단어의 품사별로 묶음: 동사, 명사, 부사
// 토큰
text = "Don't hesitate to ask question"
from nltk.tokenize import TreebankWordTokenizer
tokenizer = TreebankWordTokenizer()
token = tokenizer.tokenize(text)
// 태그
from nltk import pos_tag
pos_tag(token)
// 한글처리
// 테크
from konlpy.tag import Okt
twitter = Okt()
twitter.pos('서울R&D캠퍼스 수업자료')
//토큰, 스테밍을 같이 처리 stem === stemming
text = "워런 버핏은 삼성전자가 아닌 애플주식을 왜 샀을까"
print(twitter.pos(text, stem="true"))
Word Cloud로 시각화하기
- Visualization (시각화)
- 연설문을 워드클라우드로 표현하기
// 필요 모듈 설치
! apt-get update
! apt-get install g++ openjdk-8-jdk
! pip3 install nltk konlpy wordcloud matplotlib gensim
! apt-get install fonts-nanum*
! apt-get install fontconfig
! fc-cache -fv
! cp /usr/share/fonts/truetype/nanum/Nanum* /usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/fonts/ttf/
! rm -rf /content/.cache/matplotlib/*
speech_text = "https://raw.githubusercontent.com/YongBeomKim/nltk_tutorial/master/data/pyongyang_fin.txt"
script_text = "https://raw.githubusercontent.com/YongBeomKim/nltk_tutorial/master/data/movie_memories_of_murder_2003.txt"
font_file = "/usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/fonts/ttf/NanumGothicCoding.ttf"
// 워드클라우드 사용
import requests
import pandas as pd
import matplotlib.pyplot as plt
from wordcloud import WordCloud
from nltk import FreqDist
from nltk.tokenize import word_tokenize
import nltk
nltk.download('punkt')
texts = requests.get(speech_text).text
texts[:100]
// 그리기
%matplotlib inline
wcloud = WordCloud(font_file).generate(texts)
plt.figure(figsize=(12,12))
plt.imshow(wcloud)
plt.axis('off')
명사만을 사용하여 word cloud 표현
from konlpy.tag import Okt
twitter = Okt()
tokens = twitter.pos(texts, stem=True)
tokens_noun = [token[0] for token in tokens if token[1] == 'Noun']
texts_noun = " ".join(tokens_noun)
texts_noun[:300]
Deep Learning 수행
Natural Language Processing + Deep Learning을 결합하여 챗봇을 만들어가기
- RNN, LSTM, GRU가 챗봇만드는 기본 알고리즘
- Data 입력/전처리 (Train Data) -> Cell 선택 및 모델 구성 -> Training / Modeling / Validation -> Model 평가
- Input -> Hidden Layer -> Output
- Input Data 를 구성하는 Word2Vec
Word2Vec는 문장에 따라 데이터를 구조화한다.
- 하나의 중심데이터와 주변데이터로 구분함.
- 단어간 유사도 검사
- 구조자체가 작아서, 딥러닝이라 할 수 없다.
- 로지스틱 회귀식(2 Cell)을 통해 분류한다.
- Corpus (말뭉치) -> Vocabulary Builder -> Context Builder -> Input -> Output
새로운 방식
- Input 하나에 Output 여러개를 통해 학습 => Skip-gram (sg)
- try -> error를 통해 맞는 길로 찾아는 방식
과거 방식
- Input 여러개에 대한 Output 으로 중심 단어 하나 => CBOW (Content Back of Word)
실습
- 20차원의 구조를 만든다.
- Dimension(차원)안에 토큰을 넣는다. 비슷한 토큰은 같은 차원에 넣는다.
- 빈도수가 적은 것은 하나의 차원에 묶는다. 이안에 빈도수가 높은 것은 중심축에 놓는다.
- size: 차원 30개 (중요) <== 실습 단어가 151개여서 유의미화를 위해 30차원으로 줄여서 설정했음.
- window: 주변 데이터
- min_count: 10번이상 등장한 단어만 (중요)
- hs: ?
- workers: cpu parallel 동작
- sg: skip-gram
// 전처리후
...
// 명사 저장
sentences = txtnoun(sentences, skip=skips, tags=["Noun"])
script_file = 'scripts.txt'
with open(script_file, 'w', encoding="utf-8") as file:
file.write(sentences)
// gensim 이용 모델 만들기
%%time
from gensim.models import word2vec
data = word2vec.LineSentence(script_file)
model = word2vec.Word2Vec(data, size=30, window=2, min_count=10, hs=1, workers=4, iter=100, sg=1)
model_file = "script.model"
model.save(model_file)
결과
CPU times: user 1.59 s, sys: 113 ms, total: 1.71 s, Wall time: 1.7 s
// 모델의 단어수
model = word2vec.Word2Vec.load(model_file)
len(model.wv.vocab.keys())
list(model.wv.index2word)
결과
151
// 근접 백터값 확인하기, 참깨밭을 제거하고 추출해 봄
model.wv.most_similar(['현장','백광호'], negative=['참깨밭'], topn=20)
30차원을 시각화하기 위해 skitlearn의 TSNE를 이용해서 2차원으로 변경해서 표현한다.
<참조>
- KoNLP
'Deep Learning' 카테고리의 다른 글
[뉴로모픽] 인공지능과 하드웨어의 결합 워크샵 (0) | 2018.10.18 |
---|---|
[Cost Function] 로지스틱 회귀의 비용함수 이해 (0) | 2018.08.11 |
[인공지능] 공부 여정 (0) | 2018.07.31 |
[ML] 11주차 - 독립 특성 발견 (0) | 2015.03.07 |
[ML] 10주차 - 고급 분류 기법 (0) | 2015.02.28 |