한국어는 단어의 기준이 명확하지 않음
공백으로 나뉘는 단어들은 각각이 의미적 기능을 하는 부분과 문법적 기능을 하는 부분의 조합으로 구성
<KoNLPy>
형태소 분석: 주어진 한국어 텍스트를 단어의 원형 형태로 분리해 주는 작업
KoNLPy 는 여러 한국어 형태소 사전을 기반으로 한국어 단어를 추출해 주는 파이썬 라이브러리
Mecab, 한나눔, 꼬꼬마, Komoran, Open Korean Text 라는 5가지의 형태소 사전이 라이브러리에 있음
class 객체 만들어주고, .nouns 를 이용해서 의미있는 단어만 추출
.pos로 각 기능에 대해 알려줌
* 각 형태소 사전별 형태소 표기 방법 및 기준의 차이가 존재
KoNLPy 를 이용한 한국어 전처리
# 경고문을 무시합니다.
import warnings
warnings.filterwarnings(action='ignore')
import pandas as pd
from konlpy.tag import Kkma, Okt
# sts-train.tsv 파일에 저장되어 있는 KorSTS 데이터셋을 불러옵니다.
sent = pd.read_table("sts-train.tsv", delimiter='\t', header=0)['sentence1']
# sent 변수에 저장된 첫 5개 문장을 확인해봅니다.
print(sent[:5])
# 꼬꼬마 형태소 사전을 이용해서 sent 내 문장의 명사를 nouns 리스트에 저장하세요.
nouns = []
kkma = Kkma()
for s in sent:
nouns += kkma.nouns(s) #명사 추출
# 명사의 종류를 확인해봅니다.
print(set(nouns)) #set()는 중복되는 원소 제거함
# Open Korean Text 형태소 사전을 이용해서 sent 내 형태소 분석 결과를 pos_results 리스트에 저장하세요.
pos_results = []
okt = Okt()
for s in sent:
pos_results.append(okt.pos(s))
# 분석 결과를 확인해봅니다.
print(pos_results)
# stemming 기반 형태소 분석이 적용된 sent의 두 번째 문장을 stem_pos_results 리스트에 저장하세요.
stem_pos_results = []
stem_pos_results = okt.pos(sent[1], stem = True) #두번째 문장
print(stem_pos_results)
soynlp
사전 기반의 단어 처리의 경우, 미등록 단어 문제가 발생 가능
ex) 하나의 고유명사를 인식하지 못하거나 소말리아를 소말리 까지만을 추출할 수도 있음
soynlp는 학습 데이터 내 자주 발생하는 패턴을 기반으로 단어의 경계선을 구분
ex) 아이오아이는 -> 아이(0.15), 아이오(0.1), 아이오아(0.2), 아이오아이(0.3),아이오아이(0.26) 이렇게 점수를 매겨서 가장 점수가 높은 것을 기준으로 단어를 추출
가정[1] : 단어는 연속으로 등장하는 글자의 조합이며 글자 간 연관성이 높다
가정[2] : 한국어의 어절은 좌 - 우 구조로 2등분 할 수 있다(의미적 기능 + 문법적 기능)
LRNounExtractor_v2(), WordExtractor() 를 이용해서 단어 추출 가능!
from soynlp.utils import DoublespaceLineCorpus
from soynlp.noun import LRNounExtractor_v2
sent = '트와이스 아이오아이 좋아여 tt가 저번에 1위 했었죠?'
# 학습에 사용할 데이터가 train_data에 저장되어 있습니다.
corpus_path = 'articles.txt'
train_data = DoublespaceLineCorpus(corpus_path)
print("학습 문서의 개수: %d" %(len(train_data)))
# LRNounExtractor_v2 객체를 이용해 train_data에서 명사로 추정되는 단어를 nouns 변수에 저장하세요.
noun_extr = LRNounExtractor_v2()
nouns = noun_extr.train_extract(train_data)
# 생성된 명사의 개수를 확인해봅니다.
print(len(nouns))
# 생성된 명사 목록을 사용해서 sent에 주어진 문장에서 명사를 sent_nouns 리스트에 저장하세요.
sent_nouns = []
#명사 추출하기, 단어 기준으로
for word in sent.split():
if word in nouns:
sent_nouns.append(word)
print(sent_nouns) #[아이오아이, 트와이스, 1위] 추출
문장 유사도
문장 간 유사도는 공통된 단어 혹은 의미를 기반으로 계산
<자카드(Jaccard) 지수>
문장 1과 문장 2의 유사도 = 문장 내 공통된 단어의 종류 / 두 문장 내 모든 단어의 종류
-> 범위는 0 ~1 사이로 정의
<코사인 유사도>
문장 벡터 간의 각도를 기반으로 계산
-> 벡터 간의 각도는 벡터 간 내적을 사용해서 계산
ex) A = [1,3] B = [0,2] -> 분자: 벡터 간 내적 / 분모: 각 벡터의 길이
(1x0) + (3 X 2) / (루트 1^2 + 3^2) X (루트 0^2 + 2^2)
유클리드 거리와 같은 다양한 거리 지표가 존재
코사인 유사도는 고차원의 공간에서 벡터 간의 유사성을 잘 보존하는 장점이 있음
<자카드 지수를 통한 문자 유사도 측정>
import nltk
sent_1 = "오늘 중부지방을 중심으로 소나기가 예상됩니다"
sent_2 = "오늘 전국이 맑은 날씨가 예상됩니다"
def cal_jaccard_sim(sent1, sent2):
# 각 문장을 토큰화 후 set 타입으로 변환하세요.
words_sent1 = set(sent1.split()) #set으로 변환하면 리스트 내 중복 요소 제거됨
words_sent2 = set(sent2.split())
# 공통된 단어의 개수를 intersection()사용해서 변수에 저장하세요.
intersection = words_sent1.intersection(words_sent2)
# 두 문장 내 발생하는 모든 단어의 개수를 union()함수 사용해서 변수에 저장하세요.
union = words_sent1.union(words_sent2)
# intersection과 union을 사용하여 자카드 지수를 계산하고 float 타입으로 반환하세요.
return float(len(intersection) / len(union))
# cal_jaccard_sim() 함수 실행 결과를 확인합니다.
print(cal_jaccard_sim(sent_1, sent_2))
# nltk의 jaccard_distance() 함수를 이용해 자카드 유사도를 계산하세요.
sent1_set = set(sent_1.split())
sent2_set = set(sent_2.split())
nltk_jaccard_sim = 1 - nltk.jaccard_distance(sent1_set, sent2_set)
#jaccard_distance(w1, w2)에 인자로 들어가는 w1, w2는 set 타입으로 정의된 각 문장별 단어 목록입니다.유사도와 거리는 다음과 같은 관계로 정의가 됩니다: 유사도 = 1 - 거리
# 직접 정의한 함수와 결과가 같은지 비교합니다. niltk의 자카드 거리를 계산해 주는 jaccard_distance(w1, w2)를 이용해 sent_1, sent_2 의 자카드 유사도를 계싼하여 변수에 저장
print(nltk_jaccard_sim)
<코사인 유사도를 통한 문장 유사도 측정>
from numpy import sqrt, dot
from scipy.spatial import distance
from sklearn.metrics import pairwise
sent_1 = [0.3, 0.2, 0.2133, 0.3891, 0.8852, 0.586, 1.244, 0.777, 0.882]
sent_2 = [0.03, 0.223, 0.1, 0.4, 2.931, 0.122, 0.5934, 0.8472, 0.54]
sent_3 = [0.13, 0.83, 0.827, 0.92, 0.1, 0.32, 0.28, 0.34, 0]
def cal_cosine_sim(v1, v2):
# 벡터 v1, v2 간 코사인 유사도를 계산 후 반환하세요.
top = dot(v1, v2) #내적 계산
size1 = sqrt(dot(v1,v1)) #자기 자신과의 벡터 크기
size2 = sqrt(dot(v2,v2))
return top / (size1 * size2)
# 정의한 코사인 유도 계산 함수를 확인합니다.
print(cal_cosine_sim(sent_1, sent_2))
# scipy의 distance.cosine() 함수를 이용한 코사인 유사도를 계산하세요.
scipy_cosine_sim = 1 - distance.cosine(sent_1, sent_2)
# scipy를 이용해 계산한 코사인 유사도를 확인합니다.
print(scipy_cosine_sim)
# scikit-learn의 pairwise.cosine_similarity() 함수를 이용한 코사인 유사도를 계산하세요.
all_sent = [sent_1] + [sent_2] + [sent_3]
scikit_learn_cosine_sim = pairwise.cosine_similarity(all_sent)
# scikit-learn을 이용해 계산한 코사인 유사도를 확인합니다.
print(scikit_learn_cosine_sim)
'Data Analysis' 카테고리의 다른 글
문서 유사도 및 언어 모델 (0) | 2022.07.29 |
---|---|
감정 분석 서비스 (0) | 2022.07.29 |
텍스트 전처리 및 단어 임베딩 (0) | 2022.07.26 |
한국어는 단어의 기준이 명확하지 않음
공백으로 나뉘는 단어들은 각각이 의미적 기능을 하는 부분과 문법적 기능을 하는 부분의 조합으로 구성
<KoNLPy>
형태소 분석: 주어진 한국어 텍스트를 단어의 원형 형태로 분리해 주는 작업
KoNLPy 는 여러 한국어 형태소 사전을 기반으로 한국어 단어를 추출해 주는 파이썬 라이브러리
Mecab, 한나눔, 꼬꼬마, Komoran, Open Korean Text 라는 5가지의 형태소 사전이 라이브러리에 있음
class 객체 만들어주고, .nouns 를 이용해서 의미있는 단어만 추출
.pos로 각 기능에 대해 알려줌
* 각 형태소 사전별 형태소 표기 방법 및 기준의 차이가 존재
KoNLPy 를 이용한 한국어 전처리
# 경고문을 무시합니다.
import warnings
warnings.filterwarnings(action='ignore')
import pandas as pd
from konlpy.tag import Kkma, Okt
# sts-train.tsv 파일에 저장되어 있는 KorSTS 데이터셋을 불러옵니다.
sent = pd.read_table("sts-train.tsv", delimiter='\t', header=0)['sentence1']
# sent 변수에 저장된 첫 5개 문장을 확인해봅니다.
print(sent[:5])
# 꼬꼬마 형태소 사전을 이용해서 sent 내 문장의 명사를 nouns 리스트에 저장하세요.
nouns = []
kkma = Kkma()
for s in sent:
nouns += kkma.nouns(s) #명사 추출
# 명사의 종류를 확인해봅니다.
print(set(nouns)) #set()는 중복되는 원소 제거함
# Open Korean Text 형태소 사전을 이용해서 sent 내 형태소 분석 결과를 pos_results 리스트에 저장하세요.
pos_results = []
okt = Okt()
for s in sent:
pos_results.append(okt.pos(s))
# 분석 결과를 확인해봅니다.
print(pos_results)
# stemming 기반 형태소 분석이 적용된 sent의 두 번째 문장을 stem_pos_results 리스트에 저장하세요.
stem_pos_results = []
stem_pos_results = okt.pos(sent[1], stem = True) #두번째 문장
print(stem_pos_results)
soynlp
사전 기반의 단어 처리의 경우, 미등록 단어 문제가 발생 가능
ex) 하나의 고유명사를 인식하지 못하거나 소말리아를 소말리 까지만을 추출할 수도 있음
soynlp는 학습 데이터 내 자주 발생하는 패턴을 기반으로 단어의 경계선을 구분
ex) 아이오아이는 -> 아이(0.15), 아이오(0.1), 아이오아(0.2), 아이오아이(0.3),아이오아이(0.26) 이렇게 점수를 매겨서 가장 점수가 높은 것을 기준으로 단어를 추출
가정[1] : 단어는 연속으로 등장하는 글자의 조합이며 글자 간 연관성이 높다
가정[2] : 한국어의 어절은 좌 - 우 구조로 2등분 할 수 있다(의미적 기능 + 문법적 기능)
LRNounExtractor_v2(), WordExtractor() 를 이용해서 단어 추출 가능!
from soynlp.utils import DoublespaceLineCorpus
from soynlp.noun import LRNounExtractor_v2
sent = '트와이스 아이오아이 좋아여 tt가 저번에 1위 했었죠?'
# 학습에 사용할 데이터가 train_data에 저장되어 있습니다.
corpus_path = 'articles.txt'
train_data = DoublespaceLineCorpus(corpus_path)
print("학습 문서의 개수: %d" %(len(train_data)))
# LRNounExtractor_v2 객체를 이용해 train_data에서 명사로 추정되는 단어를 nouns 변수에 저장하세요.
noun_extr = LRNounExtractor_v2()
nouns = noun_extr.train_extract(train_data)
# 생성된 명사의 개수를 확인해봅니다.
print(len(nouns))
# 생성된 명사 목록을 사용해서 sent에 주어진 문장에서 명사를 sent_nouns 리스트에 저장하세요.
sent_nouns = []
#명사 추출하기, 단어 기준으로
for word in sent.split():
if word in nouns:
sent_nouns.append(word)
print(sent_nouns) #[아이오아이, 트와이스, 1위] 추출
문장 유사도
문장 간 유사도는 공통된 단어 혹은 의미를 기반으로 계산
<자카드(Jaccard) 지수>
문장 1과 문장 2의 유사도 = 문장 내 공통된 단어의 종류 / 두 문장 내 모든 단어의 종류
-> 범위는 0 ~1 사이로 정의
<코사인 유사도>
문장 벡터 간의 각도를 기반으로 계산
-> 벡터 간의 각도는 벡터 간 내적을 사용해서 계산
ex) A = [1,3] B = [0,2] -> 분자: 벡터 간 내적 / 분모: 각 벡터의 길이
(1x0) + (3 X 2) / (루트 1^2 + 3^2) X (루트 0^2 + 2^2)
유클리드 거리와 같은 다양한 거리 지표가 존재
코사인 유사도는 고차원의 공간에서 벡터 간의 유사성을 잘 보존하는 장점이 있음
<자카드 지수를 통한 문자 유사도 측정>
import nltk
sent_1 = "오늘 중부지방을 중심으로 소나기가 예상됩니다"
sent_2 = "오늘 전국이 맑은 날씨가 예상됩니다"
def cal_jaccard_sim(sent1, sent2):
# 각 문장을 토큰화 후 set 타입으로 변환하세요.
words_sent1 = set(sent1.split()) #set으로 변환하면 리스트 내 중복 요소 제거됨
words_sent2 = set(sent2.split())
# 공통된 단어의 개수를 intersection()사용해서 변수에 저장하세요.
intersection = words_sent1.intersection(words_sent2)
# 두 문장 내 발생하는 모든 단어의 개수를 union()함수 사용해서 변수에 저장하세요.
union = words_sent1.union(words_sent2)
# intersection과 union을 사용하여 자카드 지수를 계산하고 float 타입으로 반환하세요.
return float(len(intersection) / len(union))
# cal_jaccard_sim() 함수 실행 결과를 확인합니다.
print(cal_jaccard_sim(sent_1, sent_2))
# nltk의 jaccard_distance() 함수를 이용해 자카드 유사도를 계산하세요.
sent1_set = set(sent_1.split())
sent2_set = set(sent_2.split())
nltk_jaccard_sim = 1 - nltk.jaccard_distance(sent1_set, sent2_set)
#jaccard_distance(w1, w2)에 인자로 들어가는 w1, w2는 set 타입으로 정의된 각 문장별 단어 목록입니다.유사도와 거리는 다음과 같은 관계로 정의가 됩니다: 유사도 = 1 - 거리
# 직접 정의한 함수와 결과가 같은지 비교합니다. niltk의 자카드 거리를 계산해 주는 jaccard_distance(w1, w2)를 이용해 sent_1, sent_2 의 자카드 유사도를 계싼하여 변수에 저장
print(nltk_jaccard_sim)
<코사인 유사도를 통한 문장 유사도 측정>
from numpy import sqrt, dot
from scipy.spatial import distance
from sklearn.metrics import pairwise
sent_1 = [0.3, 0.2, 0.2133, 0.3891, 0.8852, 0.586, 1.244, 0.777, 0.882]
sent_2 = [0.03, 0.223, 0.1, 0.4, 2.931, 0.122, 0.5934, 0.8472, 0.54]
sent_3 = [0.13, 0.83, 0.827, 0.92, 0.1, 0.32, 0.28, 0.34, 0]
def cal_cosine_sim(v1, v2):
# 벡터 v1, v2 간 코사인 유사도를 계산 후 반환하세요.
top = dot(v1, v2) #내적 계산
size1 = sqrt(dot(v1,v1)) #자기 자신과의 벡터 크기
size2 = sqrt(dot(v2,v2))
return top / (size1 * size2)
# 정의한 코사인 유도 계산 함수를 확인합니다.
print(cal_cosine_sim(sent_1, sent_2))
# scipy의 distance.cosine() 함수를 이용한 코사인 유사도를 계산하세요.
scipy_cosine_sim = 1 - distance.cosine(sent_1, sent_2)
# scipy를 이용해 계산한 코사인 유사도를 확인합니다.
print(scipy_cosine_sim)
# scikit-learn의 pairwise.cosine_similarity() 함수를 이용한 코사인 유사도를 계산하세요.
all_sent = [sent_1] + [sent_2] + [sent_3]
scikit_learn_cosine_sim = pairwise.cosine_similarity(all_sent)
# scikit-learn을 이용해 계산한 코사인 유사도를 확인합니다.
print(scikit_learn_cosine_sim)
'Data Analysis' 카테고리의 다른 글
문서 유사도 및 언어 모델 (0) | 2022.07.29 |
---|---|
감정 분석 서비스 (0) | 2022.07.29 |
텍스트 전처리 및 단어 임베딩 (0) | 2022.07.26 |