!pip install kiwipiepy
import kiwipiepy
kiwi = kiwipiepy.Kiwi()
defextract_nouns(text): # 명사 추출 함수for token in kiwi.tokenize(text):
if token.tag in {'NNG', 'NNP'}:
yield token.form
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(tokenizer=extract_nouns, min_df=10)
dtm = cv.fit_transform(df.abstract) # 문서 단어 행렬
words = list(cv.get_feature_names_out()) # 단어 목록
키워드 추출
자주 나오는 단어 중에 문서와 가장 비슷한 단어를 찾음
word_emb = sbert.encode(words)
dists = cosine_distances(doc_emb[[doc_idx]], word_emb).flatten()
for i in np.argsort(dists)[:5]:
print(words[i])
문서의 내용과 비슷한 단어들이 키워드로 뽑힘
비슷비슷한 키워드들이 뽑힐 수 있음
해결책:
Max Sum Similarity
Maximal Marginal Relevance
Max Sum Similarity
1차적으로 문서와 유사한 n개의 키워드를 추출
이중에서 k개의 키워드를 뽑아 조합하고, 그들 간의 유사도 합계를 구함
키워드들의 유사도 합계가 가장 낮은 조합을 선택
문서와 유사하면서, 서로 다른 키워드를 뽑는 방법
후보의 개수
n을 키우면 더 다양한 후보를 고려할 수 있음
그러나 조합의 개수는 n{!}(n−k)!k! 로 n이 크면 급격하게 증가
다양성과 계산 시간을 고려하여 n과 k를 적절히 선택
from scipy.special import factorial
n = 10
k = 5
factorial(n)/factorial(n-k)/factorial(k)
Max Sum Similarity (계속)
from itertools import combinations
max_dist = 0
keywords = None
candidates = np.argsort(dists)[:n] # n개의 후보for combi in combinations(candidates, k): # k개씩 조합해서 시도
word_dists = cosine_distances(word_emb[list(combi)]) # 키워드 간 거리 계산
sum_dist = word_dists.sum() # 거리 합계if sum_dist > max_dist: # 키워드들이 서로 거리가 최대인 것을 찾음
max_dist = sum_dist
keywords = combi
for i in keywords:
print(words[i])
Maximal Marginal Relevance
키워드를 하나씩 순차적으로 추가
문서와 유사도가 높으면서 기존의 키워드와 유사도가 낮은 키워드를 추가하는 방식
다양성(diversity) 하이퍼파라미터를 통해 문서-키워드 유사도와 키워드-키워드 유사도 중에 어느 쪽에 더 가중치를 줄지 결정할 수 있음
diversity = 0: 문서와 유사도가 가장 높은 키워드를 선택
diversity = 1: 기존 키워드와 유사도가 가장 낮은 키워드를 선택
Maximal Marginal Relevance (계속)
diversity = 0.0# 다양성이 0이면 처음에 했던 키워드 추출 방법과 같음
keyword, *candidates = np.argsort(dists)[:n].tolist()
keywords = [keyword]
for _ inrange(k - 1):
doc_sims = cosine_distances(doc_emb[[doc_idx]], word_emb[candidates])[0] # 문서와 유사도 계산
keyword_sims = cosine_distances(word_emb[keywords], word_emb[candidates]) # 키워드와 유사도 계산
keyword_sims = np.min(keyword_sims, axis=0) # 가장 높은 키워드 유사도를 선택# MMR: 문서와는 비슷하고, 기존 키워드와는 달라야
mmr = (1 - diversity) * doc_sims - diversity * keyword_sims
most_similar_idx = np.argmin(mmr) # MMR이 가장 높은 키워드 위치
keyword = candidates[most_similar_idx] # 후보에서 해당 키워드를 선택
keywords.append(keyword) # 새 키워드 추가
candidates.remove(keyword) # 추가된 키워드는 후보에서 제거
[words[i] for i in keywords] # 키워드 보기