자연어 처리(NLP)는 컴퓨터 과학, 인공지능, 언어학이 합쳐진 분야이다.
자연어 처리 업무
난이도 쉬움: 스펠링 체크, 키워드 검사, 유사어 감지
난이도 중간: 웹사이트 및 서류의 형태 해석, 구문해석
ex) 영수증 해석
난이도 어려움:기계번역, 감정분석, 질의응답 시스템
자연어 처리의 어려움
언어,상황,환경,지각 지식의 학습 및 표현의 복잡함 -> Rule 기반만으로는 무리인가?
영상은 벡터로 분석, 수치화 가능했다. 그런데 언어는? 기존의 알고리즘을 적용하기 어렵다.
DNN은 분산표현의 장점으로 인해 모호하지만 풍부한 정보를 얻을 수 있다. -> 단어의 벡터화로부터 시작
언어 데이터의 특성
불연속적인 심볼의 sequence (영상, 음성은 연속적이다. Text는 불연속적)
계열 길이가 샘플에 따라 다르다.
계층적, 재귀적인 구조를 지닌다. (문자, 단어, 구, 문)
- 계열 -> 계열
- 형태소 해석
- 기계번역, 자동요약
- 질의응답, 챗봇
- 계열 -> tree 구조 초반에 많이 했던 것. 어렵다. 알고리즘 보진 않을 거고 갖다 쓸 거야.
- 구문 해석
- 계열 -> 그래프 구조 연구가 많이 이뤄지고 있진 않다. 문맥을 이해하는 부분.
- 의미해석
단어의 국소표현: 단어를 벡터로 (one-hot encoding과 비슷) 한다면 -> 단어의 의미를 파악하는 벡터가 필요, 차원이 매우 커진다.
분포가설
비슷한 문맥을 가진 단어는 비슷한 의미를 가진다. = 현대의 통계적 자연어 처리에서 획기적인 발상
분포가설은 크게 2종류이다.
count-based methods
- ex) SVD(LSA), HAL
- 단어, 문맥 출현 횟수를 세는 방법
predictive methods
- ex) NPLM, ...
- 학습을 해서(특징을 만듦) 연산도 가능(단어 간 거리 측정 가능), 예측하는...
자연어 처리의 기반은 rule base이다.
규칙을 이용한 학습.
가위바위보 규칙
-1 % 3
= (-1+3) % 3
= 2
0:비김, 1:이김, 2:짐
NLP Basic
- 설치
pip install gensim #단어들을 벡터로 만드는 알고리즘
pip install wordcloud #구름 그리기
pip install konlpy --user #한국어 형태소 분석
pip install jpype1 #윈도우에서 안 돼서 아래 라인 코드로 설치
conda install -c conda -forge jpype1 #depending konlpy library. 자바기반. ----- 오류남
import numpy as np
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.linear_model import SGDClassifier
from sklearn.svm import LinearSVC
from tensorflow.keras.datasets import imdb
from konlpy.tag import Twitter
from konlpy.tag import Okt
from konlpy.tag import Kkma
from konlpy.tag import Twitter
from pprint import pprint
import nltk
from nltk.classify.scikitlearn import SklearnClassifier
from wordcloud import WordCloud, STOPWORDS
from gensim import corpora, models
import numpy as np
from PIL import Image
from wordcloud import ImageColorGenerator
import glob
import re
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
%matplotlib inline
1. char 코드 기반 자연어 처리
언어마다 히스토그램을 분석하여 각 캐릭터의 분포를 구한다 - 특정 코드의 빈도수를 계산하는 방법
ko_str = '이것은 한국어 문장입니다.'
ja_str = 'これは日本語の文章です。'
en_str = 'This is English Sentences.'
ch_str = '统一码'
print(ord(ko_str[0])) #51060
print(ord(ja_str[0])) #12371
print(ord(en_str[0])) #84
print(ord(ch_str[0])) #32479
유니코드는 9byte. 코드가 0~65535번까지 있다.
ord()
: 아스키코드(쉽게 생각해서 유니코드)로 변환
주어진 문장에 대해 히스토그램이 계산된다.
벡터의 65535개 요소 중 대부분의 요소는 0일 것이다. -> 굉장히 비효율적이다.
# Unicode 코드 포인트로 출현 빈도 판정하기 --- (*1)
def count_codePoint(str):
# Unicode 코드 포인트를 저장할 배열 준비하기 --- (*2)
counter = np.zeros(65535)
for i in range(len(str)):
# 각 문자를 Unicode 코드 포인트로 변환하기 --- (*3)
code_point = ord(str[i])
if code_point > 65535 :
continue
# 출현 횟수 세기 --- (*4)
counter[code_point] += 1
# 각 요소를 문자 수로 나눠 정규화하기 --- (*5)
counter = counter/len(str)
return counter
# 학습 전용 데이터 준비하기
ko_str = '이것은 한국어 문장입니다.'
ja_str = 'これは日本語の文章です。'
en_str = 'This is English Sentences.'
x_train = [count_codePoint(ko_str),count_codePoint(ja_str),count_codePoint(en_str)]
y_train = ['ko','ja','en']
print( x_train[0] ) #[0. 0. 0. ... 0. 0. 0.]
print( np.where(x_train[0] > 0) ) #(array([ 32, 46, 44163, 44397, 45768, 45796, 47928, 50612, 51008, 51060, 51077, 51109, 54620], dtype=int64),)
data = x_train[0]
print( data[[32,46,44163]] ) #[0.14285714 0.07142857 0.07142857]
idx = np.where(x_train[0] > 0)
data = x_train[0]
print( data[idx] ) #[0.14285714 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857]
variable[[idx1, idx2, idx3, ...]]
: particle slicing 방법으로 해당 idx의 값을 가져오는 방법이다.
#X = np.array([[-1, -1], [3, 2]])
#Y = np.array([1, 2])
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
Y = np.array(['r', 'r', 'r', 'b', 'b', 'b'])
color = [ 'red' if y == 'r' else 'blue' for y in Y]
plt.scatter(X[:, 0], X[:, 1], color=color)
t = np.array([[-0.8, -1]])
plt.scatter(t[:,0], t[:,1], color='yellow')
clf = GaussianNB()
clf.fit(X,Y) #학습: mean, sd 구하는 것.
print(clf.predict[[-0.8,-1]])
딥러닝은 데이터가 많아야 의미있는 결론이 나오는데, 여기는 데이터가 적어 적용하지 않는다. 차원수가 65k개면 샘플수도 그만큼은 있어야 딥러닝이 가능하다.
GaussianNB 학습(naive bayesian) : mean, sd를 구하는 것으로 데이터가 하나여도 동작한다.
Y값은 참고하는 label일 뿐이어서 값이 숫자가 아니어도 괜찮다.
#학습하기
clf = GaussianNB()
clf.fit(x_train, y_train)
# 평가 전용 데이터 준비하기
ko_test_str = '안녕. 어디야'
ja_test_str = 'こんにちは'
en_test_str = 'Hello'
x_test = [count_codePoint(en_test_str),count_codePoint(ja_test_str),count_codePoint(ko_test_str)]
#자연어 자체로 읽을 수 없어. 한 번은 변환이 필요해. feature를 transformation
y_test = ['en', 'ja', 'ko']
# 평가하기 --- (*7)
y_pred = clf.predict(x_test)
print(y_pred)
print("정답률 = " , accuracy_score(y_test, y_pred))
'Python > NLP 자연어처리' 카테고리의 다른 글
Word Embeddimg (0) | 2020.02.14 |
---|---|
형태소 분석 (0) | 2020.02.10 |
단어 빈도수 기반 자연어 처리 (0) | 2020.02.10 |