머신 러닝 - 자연어 처리(3)
◾문장 유사도 측정
- 두 점 사이의 거리를 구하는 것 : 유클리드 거리()
- 문장을 점처럼 일종의 벡터로 표현할 수 있다면 거리를 구하여 유사한 문장을 찾을 수 있다.
CountVectorizer
,TfidfVectorizer
등으로 문장을 벡터로 변환할 수 있다.
◾Count Vectorize
CountVectorizer
- 단어들의 카운트(출현 빈도(frequency))로 여러 문서들을 벡터화, 카운트 행렬, 단어 문서 행렬 (Term-Document Matrix, TDM))
- 모두 소문자로 변환시키기 때문에 me 와 Me 는 모두 같은 특성이 된다.
- CountVectorizer 선언
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(min_df=1)
- 훈련용 문장
- 훈련용 문장 구성
contents = ['상처받은 아이들은 너무 일찍 커버려',
'내가 상처받은 거 아는 사람 불편해',
'잘 사는 사람들은 좋은 사람 되기 쉬워',
'아무 일도 아니야 괜찮아']
- 형태소 분석 엔진 선언(한글은 형태소 분석이 필수)
from konlpy.tag import Okt
t = Okt()
Okt().morphs()
: 텍스트를 형태소 단위로 나누는데, 이때 각 단어에서 어간을 추출
contents_tokens = [t.morphs(row) for row in contents]
contents_tokens
nltk
로 구분하기 쉽도록 형태소로 나눈 것으로 다시 문장으로 합쳐준다.
contents_for_vectorize = []
for content in contents_tokens:
sentence = ''
for word in content:
sentence = sentence + ' ' + word
contents_for_vectorize.append(sentence)
contents_for_vectorize
- 벡터 라이즈 수행
- 네 개의 문장에 전체 말뭉치 단어는 17개
X = vectorizer.fit_transform(contents_for_vectorize)
X
num_samples, num_features = X.shape
num_samples, num_features
# vectorizer.get_feature_names_out() : ndarray 형태로 반환
vectorizer.get_feature_names()
- 벡터 형태 확인
X.toarray().transpose()
- 테스트용 문장
- 테스트용 문장
new_post = ['상처받기 싫어 괜찮아']
new_post_tokens = [t.morphs(row) for row in new_post]
new_post_for_vectorize = []
for content in new_post_tokens:
sentence = ''
for word in content:
sentence = sentence + ' ' + word
new_post_for_vectorize.append(sentence)
new_post_for_vectorize
- 벡터로 표현
new_post_vec = vectorizer.transform(new_post_for_vectorize)
new_post_vec.toarray()
- 거리 계산
- 단순 기하학적인 거리
- scipy의 linalg 사용 : 선형 대수 함수
- Norm은 벡터의 길이 혹은 크기를 측정하는 방법(함수)
import scipy as sp
def dist_raw(v1, v2):
delta = v1 - v2
return sp.linalg.norm(delta.toarray())
dist = [dist_raw(each, new_post_vec) for each in X]
dist
print('Best post is',dist.index(min(dist)), 'dist =', min(dist))
print('Test post is -->', new_post)
print('Best dist post is -->', contents[dist.index(min(dist))])
- 벡터 확인
- 관건은 벡터로 잘 만드는 것과 벡터 사이의 거리를 잘 계산하는 것
for i in range(0, len(contents)):
print(X.getrow(i).toarray())
print('-'*40)
print(new_post_vec.toarray())
◾Tfidf Vectorize
TF-IDF
: 정보 검색과 텍스트 마이닝에서 이용하는 가중치로 여러 문서로 이루어진 문서군이 있을 때 어떤 단어가 특정 문서 내에서 얼마나 중요한 것인지를 나타내는 통계적 수치- 위키 피디아
- 한 문서에서 많이 등장한 단어에 가중치를(Term Freq.) 전체 문서에서 많이 나타나는 단어는 중요하지 않게(Inverse Document Freq.)
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(min_df=1, decode_error='ignore')
- 훈련용 데이터(Count Vecotize의 데이터 사용)
X = vectorizer.fit_transform(contents_for_vectorize)
num_samples, num_features = X.shape
num_samples, num_features
X.toarray().transpose()
- 테스트용 데이터(Count Vectorizer 데이터 사용)
new_post_vec = vectorizer.transform(new_post_for_vectorize)
new_post_vec.toarray()
- 거리 계산
- 두 벡터의 크기를 비교할 때 1로 normalized하여 비교한다.
- 한 쪽 특성이 과하게 도드라지는 것을 막을 수 있다.
def dist_norm(v1, v2):
v1_normalized = v1 / sp.linalg.norm(v1.toarray())
v2_normalized = v2 / sp.linalg.norm(v2.toarray())
delta = v1_normalized - v2_normalized
return sp.linalg.norm(delta.toarray())
dist = [dist_norm(each, new_post_vec) for each in X]
dist
print('Best post is',dist.index(min(dist)), 'dist =', min(dist))
print('Test post is -->', new_post)
print('Best dist post is -->', contents[dist.index(min(dist))])
Author And Source
이 문제에 관하여(머신 러닝 - 자연어 처리(3)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@skarb4788/머신-러닝-자연어-처리3저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)