728x90

1. 코사인 유사도(Cosine Similarity)

코사인 유사도란, 벡터 간의 코사인 각도를 이용하여 비교하는 두 벡터간의 유사도이다.
각도 = 유사도로 판별하여 거리가 중요하지 않을 경우에 사용하는 방식으로, 자연어 처리 등에 사용되는 기법이다.

코사인 유사도는 -1 ~ 1 사이의 값을 가진다.
1 : 두 벡터가 0도의 각을 가짐
0 : 두 벡터가 90 도의 각을 가짐
-1 : 두 벡터가 180도의 각을 가짐
예를 들어, 다음과 같은 두 문장을 각각 벡터화해보면
text1 = '파이썬은 쉬워요'
text2 = '파이썬은 쉬워요 파이썬은 쉬워요'
| 파이썬은 | 쉬워요 | |
| text1 | 1 | 1 |
| text2 | 2 | 2 |
단어가 똑같고 빈도수만 다르기 때문에, 코사인 유사도를 계산할 경우 값이 1이 나오게 된다. ( 빈도수는 상관 없다.)
2. 벡터화(CountVectorizer vs TF-IDF 차이)
| 표현 방법 | 가중치 | 정규화 | |
| CountVectorizer | 단어의 출현빈도 | 출현빈도 단순 계산 | |
| TF- IDF | 상대적인 중요성 평가 | 출현빈도와 역문서빈도를 곱한 값 | 문서의 길이에 따라 달라지는 효과 방지 |
TF-IDF
- 요약 ) 단어의 빈도를 그 단어가 나타난 문서의 수로 나눠쥼
- TF : Term Frequency(단어 빈도) : 해당단어의 출현 빈도를 전체 단어 수로 나눈 값
- IDF : Inverse Document Frequency(역문서 빈도) : 특정 단어가 전체 문서집합에서 얼마나 희귀한지 측정, 전체 문서 나누기 해당단어를 포함한 문서의 수에 로그를 취한 값 ( 흔하면 작은 값, 흔하지 않으면 큰값이 발생)
CountVectorizer 처럼 bow 기반으로 벡터화하게 되면, 단어가 많다는 것이 좋다는 뜻이 되므로, TF-IDF 처럼 빈도를 고려하는 것이 더 좋은 접근방법일 수 있다.
소스 코드
다음 4문장에 대해서, 각각 벡터화 방법으로 결과를 비교해본다.
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
text1 = '나는 강아지를 좋아한다.'
text2 = '나는 고양이를 좋아한다.'
text3 = '나는 강아지를 좋아하고 고양이를 좋아한다.'
text4 = '나는 강아지를 좋아한다 나는 강아지를 좋아한다.'
sentences = [text1, text2, text3, text4]
# CountVectorizer 벡터화
count_vectorizer = CountVectorizer()
count_vectors = count_vectorizer.fit_transform(sentences)
# TF-IDF 벡터화
tfidf_vectorizer = TfidfVectorizer()
tfidf_vectors = tfidf_vectorizer.fit_transform(sentences)
# 각각의 단어에 대한 인덱스 확인
print("CountVectorizer를 사용하여 벡터화한 결과:")
print(count_vectors.toarray())
print("CountVectorizer에서의 각 단어 인덱스:", count_vectorizer.vocabulary_)
print("\nTF-IDF를 사용하여 벡터화한 결과:")
print(tfidf_vectors.toarray())
print("TF-IDF에서의 각 단어 인덱스:", tfidf_vectorizer.vocabulary_)

CountVectorizer 는 bow count 기반이므로 일반적으로 정수 형태를 띄지만, TF-IDF는 빈도기반으로 실수형태를 띈다.
3.코사인 유사도 확인( CountVectorizer , TF-IDF)
소스 코드 - 코사인 유사도 계산
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
# CountVectorizer를 사용하여 벡터화
count_vectorizer = CountVectorizer()
count_vectors = count_vectorizer.fit_transform(texts)
# TF-IDF 벡터화
tfidf_vectorizer = TfidfVectorizer()
tfidf_vectors = tfidf_vectorizer.fit_transform(texts)
# 코사인 유사도 계산
cosine_sim_count = cosine_similarity(count_vectors, count_vectors)
cosine_sim_tfidf = cosine_similarity(tfidf_vectors, tfidf_vectors)
print("CountVectorizer를 사용한 코사인 유사도:")
print(cosine_sim_count)
print("\nTF-IDF를 사용한 코사인 유사도:")
print(cosine_sim_tfidf)
결과 화면

소스 코드 - 가장 유사한 문장 찾기
# text1을 제외한 나머지 문장들
texts_except_text1 = [text2, text3, text4]
# text1과 나머지 문장들 간의 코사인 유사도 계산
cosine_sim_text1 = cosine_similarity(tfidf_vectors[0], tfidf_vectorizer.transform(texts_except_text1)).flatten()
# 가장 유사한 문장의 인덱스 찾기
most_similar_text_index = np.argmax(cosine_sim_text1) # 가장 높은 유사도를 가진 인덱스
# 주어진 텍스트에서 가장 유사한 문장 출력
most_similar_text_to_text1 = texts_except_text1[most_similar_text_index]
print("text1 기준으로 가장 유사한 문장:", most_similar_text_to_text1)
# 해당 문장과 text1 간의 코사인 유사도 출력
cosine_sim_between_texts = cosine_similarity(tfidf_vectorizer.transform([text1]), tfidf_vectorizer.transform([most_similar_text_to_text1]))
print("text1과 가장 유사한 문장 간의 코사인 유사도:", cosine_sim_between_texts)
결과 화면
| text1 기준으로 가장 유사한 문장: 나는 강아지를 좋아한다 나는 강아지를 좋아한다. text1과 가장 유사한 문장 간의 코사인 유사도: [[1.]] |
728x90
'Data Science & AI > Data Analysis' 카테고리의 다른 글
| [텍스트 분석] nltk 영어 형태소 분석 - 토큰화/정규화/품사 태깅 (0) | 2024.02.21 |
|---|---|
| [텍스트 분석] Python 문법 , 정규표현식으로 텍스트 분석하기 - basic (0) | 2024.02.17 |
| Python 대용량 데이터 처리 라이브러리 - Dask (0) | 2024.02.04 |
| Python 대용량 데이터 처리 파라미터 - Pandas (1) | 2024.02.01 |
| Kaggle 시계열 데이터 분석 (2) | 2024.01.27 |