이번에는 Python을 사용하여 코사인 유사도 함수를 이용한 텍스트 분석 과정을 단계별로 보여드리겠습니다. 이 예제에서는 두 개의 텍스트 문서 간 유사도를 계산하는 과정을 설명하겠습니다.
Python을 이용한 코사인 유사도 텍스트 분석
필요한 라이브러리 설치
먼저 필요한 라이브러리를 설치합니다. scikit-learn
라이브러리는 벡터화와 코사인 유사도 계산에 유용합니다.
pip install scikit-learn
단계 1: 데이터 준비
비교할 두 개의 텍스트 문서를 준비합니다.
# 샘플 문서
documents = [
"Data science is an interdisciplinary field that uses scientific methods.",
"Machine learning is a branch of artificial intelligence based on the idea that systems can learn from data."
]
단계 2: 텍스트 전처리 및 벡터화
CountVectorizer
를 사용하여 텍스트를 벡터로 변환합니다.
from sklearn.feature_extraction.text import CountVectorizer
# CountVectorizer 인스턴스 생성
vectorizer = CountVectorizer()
# 문서를 벡터화
vectorized_documents = vectorizer.fit_transform(documents)
단계 3: 코사인 유사도 계산
cosine_similarity
함수를 사용하여 벡터화된 문서 간의 코사인 유사도를 계산합니다.
from sklearn.metrics.pairwise import cosine_similarity
# 코사인 유사도 계산
cosine_similarities = cosine_similarity(vectorized_documents)
# 결과 출력
print(cosine_similarities)
전체 코드
# 필요한 라이브러리 임포트
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
# 샘플 문서
documents = [
"Data science is an interdisciplinary field that uses scientific methods.",
"Machine learning is a branch of artificial intelligence based on the idea that systems can learn from data."
]
# CountVectorizer 인스턴스 생성
vectorizer = CountVectorizer()
# 문서를 벡터화
vectorized_documents = vectorizer.fit_transform(documents)
# 코사인 유사도 계산
cosine_similarities = cosine_similarity(vectorized_documents)
# 결과 출력
print(cosine_similarities)
결과 해석
출력된 코사인 유사도 행렬은 다음과 같습니다:
[[1. 0.40824829]
[0.40824829 1. ]]
[0, 0]
및[1, 1]
위치의 값은 1로, 각 문서가 자기 자신과 완벽히 유사함을 나타냅니다.[0, 1]
및[1, 0]
위치의 값은 약 0.408로, 두 문서 간의 유사도를 나타냅니다.
위의 코사인 유사도 행렬 값은 다양한 텍스트 분석 작업에 활용할 수 있습니다.
1. 문서 유사도 평가 및 검색
코사인 유사도 행렬은 문서 간의 유사도를 평가하고, 가장 유사한 문서를 검색하는 데 사용할 수 있습니다.
1. 텍스트 데이터를 준비합니다.
비교할 문서들을 리스트 형태로 준비합니다.
documents = [
"Data science is an interdisciplinary field that uses scientific methods.",
"Machine learning is a branch of artificial intelligence based on the idea that systems can learn from data.",
"Deep learning is a subset of machine learning focused on neural networks.",
"Data science includes techniques from many fields, including statistics, computer science, and domain-specific knowledge."
]
2. 문서를 벡터화합니다.
CountVectorizer
를 사용하여 문서를 벡터로 변환합니다.
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
vectorized_documents = vectorizer.fit_transform(documents)
3. 코사인 유사도를 계산합니다.
cosine_similarity
함수를 사용하여 벡터화된 문서 간의 코사인 유사도를 계산합니다.
from sklearn.metrics.pairwise import cosine_similarity
cosine_similarities = cosine_similarity(vectorized_documents)
4. 특정 문서와 가장 유사한 문서를 찾습니다.
특정 문서(예: 두 번째 문서)와 가장 유사한 문서를 찾기 위해 코사인 유사도 행렬을 사용합니다.
import numpy as np
# 특정 문서와 가장 유사한 문서를 찾는 함수
def find_most_similar_document(document_index, similarities):
similar_indices = similarities[document_index].argsort()[:-2:-1] # 자기 자신을 제외한 가장 유사한 문서 찾기
return similar_indices[0]
# 두 번째 문서와 가장 유사한 문서 찾기
document_index = 1 # 두 번째 문서
most_similar_document_index = find_most_similar_document(document_index, cosine_similarities)
print(f"The document most similar to document {document_index} is document {most_similar_document_index}.")
이 코드는 argsort()
메서드를 사용하여 주어진 문서의 유사도 배열을 정렬하고, 가장 유사한 문서의 인덱스를 반환합니다.
1. similarities[document_index]
이 부분은 특정 문서의 유사도 배열을 가져옵니다. 예를 들어, document_index
가 1인 경우, similarities[1]
은 두 번째 문서와 다른 모든 문서 간의 유사도를 포함하는 배열입니다.
2. argsort()
argsort()
메서드는 배열의 요소를 정렬한 후, 원래 배열에서 정렬된 요소의 인덱스를 반환합니다. 예를 들어, 배열 [3, 1, 2]
에 대해 argsort()
를 호출하면 결과는 [1, 2, 0]
이 됩니다. 이는 원래 배열을 정렬했을 때, 원소 1은 인덱스 1에, 원소 2는 인덱스 2에, 원소 3은 인덱스 0에 위치한다는 의미입니다. [1,2,3]
에서 원래 자리의 인덱스가 각각 1, 2, 0 이라는 뜻
3. 슬라이싱 [:-2:-1]
슬라이싱 부분을 설명하겠습니다:
[:-2:-1]
는 배열의 마지막에서부터 시작하여 역순으로 한 요소를 가져옵니다.:-2
는 배열의 끝에서 두 번째 요소까지 자르라는 의미입니다.-1
는 역순으로 슬라이스를 하겠다는 의미입니다.
이 슬라이싱은 배열의 마지막 요소 하나를 가져오라는 뜻입니다.
왜 이렇게 할까?
위 코드에서 argsort()
는 문서 간의 유사도 배열을 정렬된 인덱스로 변환합니다. 마지막에서 두 번째 요소는 자신을 제외한 가장 유사한 문서를 찾기 위해 사용됩니다.
예시로 설명
예를 들어, similarities[1]
배열이 [0.1, 1.0, 0.4, 0.3]
이라면:
similarities[1].argsort()
는[0, 3, 2, 1]
을 반환합니다. 이는 오름차순으로 정렬된 유사도의 인덱스를 나타냅니다.[:-2:-1]
는[2]
를 반환합니다. 즉, 자기 자신을 제외한 가장 높은 유사도를 가지는 인덱스입니다.
따라서, 이 코드는 특정 문서와 가장 유사한 문서의 인덱스를 찾는 데 사용됩니다.
결과 해석
cosine_similarities
행렬은 각 문서 쌍 사이의 유사도를 나타냅니다.- 예를 들어,
cosine_similarities[1][2]
는 두 번째 문서와 세 번째 문서 간의 코사인 유사도를 나타냅니다. find_most_similar_document
함수는 특정 문서와 가장 유사한 문서의 인덱스를 반환합니다.
이 과정을 통해 특정 문서와 가장 유사한 문서를 쉽게 찾을 수 있습니다. 예를 들어, 문서 검색 시스템에서 사용자가 입력한 쿼리와 가장 유사한 문서를 추천하는 데 사용할 수 있습니다. 이 방법은 문서 분류, 클러스터링, 추천 시스템 등 다양한 텍스트 분석 작업에 활용될 수 있습니다.
2. 문서 클러스터링
문서 간의 유사도를 기반으로 문서를 클러스터로 묶을 수 있습니다. 이는 K-Means 클러스터링과 같은 알고리즘을 사용할 때 유용합니다.
from sklearn.cluster import KMeans
# KMeans 클러스터링 수행
num_clusters = 2
km = KMeans(n_clusters=num_clusters)
km.fit(vectorized_documents)
# 클러스터 할당 결과 출력
clusters = km.labels_.tolist()
print(f"Document clusters: {clusters}")
3. 추천 시스템
추천 시스템은 사용자의 과거 행동 및 선호도를 기반으로 유사한 아이템을 추천하는 시스템입니다. 코사인 유사도를 사용하면 텍스트나 문서 간의 유사성을 측정하여 사용자가 관심을 가질 만한 다른 문서를 추천할 수 있습니다. 여기서는 코사인 유사도를 활용한 문서 추천 시스템을 단계별로 자세히 설명하겠습니다.
추천 시스템 구현 과정
1. 텍스트 데이터를 준비합니다.
비교할 문서들을 리스트 형태로 준비합니다.
documents = [
"Data science is an interdisciplinary field that uses scientific methods.",
"Machine learning is a branch of artificial intelligence based on the idea that systems can learn from data.",
"Deep learning is a subset of machine learning focused on neural networks.",
"Data science includes techniques from many fields, including statistics, computer science, and domain-specific knowledge."
]
2. 문서를 벡터화합니다.
CountVectorizer
를 사용하여 문서를 벡터로 변환합니다.
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
vectorized_documents = vectorizer.fit_transform(documents)
3. 코사인 유사도를 계산합니다.
cosine_similarity
함수를 사용하여 벡터화된 문서 간의 코사인 유사도를 계산합니다.
from sklearn.metrics.pairwise import cosine_similarity
cosine_similarities = cosine_similarity(vectorized_documents)
4. 특정 문서와 유사한 상위 문서를 추천합니다.
특정 문서와 유사한 상위 N개의 문서를 추천하는 함수를 작성합니다.
import numpy as np
# 특정 문서와 유사한 상위 N개의 문서를 추천하는 함수
def recommend_similar_documents(document_index, similarities, top_n=2):
# 자기 자신을 제외한 유사도가 높은 상위 N개 문서 찾기
similar_indices = similarities[document_index].argsort()[:-top_n-1:-1]
similar_indices = similar_indices[similar_indices != document_index] # 자기 자신 제외
return similar_indices
# 두 번째 문서와 유사한 상위 2개 문서 추천
document_index = 1 # 두 번째 문서
recommended_documents = recommend_similar_documents(document_index, cosine_similarities, top_n=3)
print(f"Documents similar to document {document_index}: {recommended_documents}")
결과 해석
cosine_similarities
행렬은 각 문서 쌍 사이의 유사도를 나타냅니다.recommend_similar_documents
함수는 특정 문서와 가장 유사한 상위 N개의 문서 인덱스를 반환합니다.- 예를 들어,
document_index = 1
인 두 번째 문서와 가장 유사한 상위 2개의 문서를 추천합니다.
4. 감정 분석
한국어로 이미 라벨링된 데이터셋은 여러 가지가 있습니다. 대표적으로 많이 사용되는 것은 Naver Sentiment Movie Corpus(NSMC)입니다. 이 데이터셋은 네이버 영화 리뷰에 대한 긍정 및 부정 라벨이 포함된 데이터셋입니다. 이 데이터셋을 사용하여 감정 분석을 수행할 수 있습니다.
다음은 NSMC 데이터셋을 사용하여 감정 분석을 수행하는 예제입니다.
Python을 사용한 NSMC 데이터셋 감정 분석
1. 필요한 라이브러리 설치
필요한 라이브러리를 설치합니다.
pip install konlpy pandas scikit-learn
2. NSMC 데이터셋 다운로드
NSMC 데이터셋은 Kaggle에서 다운로드할 수 있습니다. NSMC 데이터셋을 다운로드한 후, CSV 파일로 저장합니다.
3. 데이터 로드 및 전처리
데이터를 로드하고 전처리합니다.
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from konlpy.tag import Okt
# NSMC 데이터 로드
train_data = pd.read_csv('ratings_train.txt', delimiter='\t')
test_data = pd.read_csv('ratings_test.txt', delimiter='\t')
# Null 값 제거
train_data = train_data.dropna(how='any')
test_data = test_data.dropna(how='any')
# 형태소 분석기 생성
okt = Okt()
# 텍스트 전처리 함수 정의
def tokenize(text):
return okt.morphs(text)
# CountVectorizer 인스턴스 생성
vectorizer = CountVectorizer(tokenizer=tokenize)
# 훈련 데이터 벡터화
train_texts = train_data['document'].tolist()
train_labels = train_data['label'].tolist()
vectorized_train_documents = vectorizer.fit_transform(train_texts)
4. 새로운 문서의 벡터화 및 코사인 유사도 계산
새로운 문서를 벡터화하고, 라벨링된 문서들과의 코사인 유사도를 계산합니다.
from sklearn.metrics.pairwise import cosine_similarity
# 새로운 문서
new_document = ["이 영화 정말 재미있고 감동적이었어요."]
new_vector = vectorizer.transform(new_document)
# 코사인 유사도 계산
new_similarity = cosine_similarity(new_vector, vectorized_train_documents)
5. 가장 유사한 라벨 추론
가장 유사한 라벨을 추론합니다.
import numpy as np
# 가장 유사한 문서의 인덱스 찾기
most_similar_label_index = np.argmax(new_similarity)
# 해당 인덱스의 라벨 추출
predicted_label = train_labels[most_similar_label_index]
label_dict = {0: "negative", 1: "positive"}
print(f"The new document is most similar to the '{label_dict[predicted_label]}' document.")
전체 코드 예시
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from konlpy.tag import Okt
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
# NSMC 데이터 로드
train_data = pd.read_csv('ratings_train.txt', delimiter='\t')
test_data = pd.read_csv('ratings_test.txt', delimiter='\t')
# Null 값 제거
train_data = train_data.dropna(how='any')
test_data = test_data.dropna(how='any')
# 형태소 분석기 생성
okt = Okt()
# 텍스트 전처리 함수 정의
def tokenize(text):
return okt.morphs(text)
# CountVectorizer 인스턴스 생성
vectorizer = CountVectorizer(tokenizer=tokenize)
# 훈련 데이터 벡터화
train_texts = train_data['document'].tolist()
train_labels = train_data['label'].tolist()
vectorized_train_documents = vectorizer.fit_transform(train_texts)
# 새로운 문서
new_document = ["이 영화 정말 재미있고 감동적이었어요."]
new_vector = vectorizer.transform(new_document)
# 코사인 유사도 계산
new_similarity = cosine_similarity(new_vector, vectorized_train_documents)
# 가장 유사한 문서의 인덱스 찾기
most_similar_label_index = np.argmax(new_similarity)
# 해당 인덱스의 라벨 추출
predicted_label = train_labels[most_similar_label_index]
label_dict = {0: "negative", 1: "positive"}
print(f"The new document is most similar to the '{label_dict[predicted_label]}' document.")
결과 해석
이 과정에서는 NSMC 데이터셋을 사용하여 감정 분석을 수행했습니다. 새로운 문서가 라벨링된 문서와 얼마나 유사한지를 코사인 유사도를 통해 측정하고, 가장 유사한 문서의 감정을 예측합니다. 이를 통해 새로운 텍스트의 감정을 효과적으로 분석할 수 있습니다. 실제 프로젝트에서는 데이터 전처리 및 모델 튜닝을 통해 정확도를 향상시킬 수 있습니다.
모델 튜닝은 감정 분석 모델의 성능을 향상시키기 위해 다양한 방법을 적용하는 과정을 말합니다. 여기서는 감정 분석 모델의 튜닝을 위해 사용할 수 있는 몇 가지 일반적인 기법을 설명하고, 실제 예제를 통해 이를 구현하는 방법을 보여드리겠습니다.
모델 튜닝 방법
1. 데이터 전처리 향상
데이터 전처리 과정에서 불필요한 정보를 제거하고, 텍스트를 정제하여 모델의 성능을 향상시킬 수 있습니다.
- 불용어(stopwords) 제거
- 특수 문자 제거
- 텍스트 정규화 (소문자 변환 등)
- 형태소 분석을 통한 명사, 동사 등 주요 품사 추출
2. 피처 추출 및 선택
텍스트를 벡터화할 때 더 유용한 피처를 추출하거나 불필요한 피처를 제거하는 방법입니다.
- TF-IDF(Vectorizer 사용)
- n-그램(n-grams) 사용
- 최대 빈도와 최소 빈도 제한
3. 모델 선택 및 하이퍼파라미터 튜닝
적절한 모델을 선택하고, 그 모델의 하이퍼파라미터를 조정하여 성능을 최적화할 수 있습니다.
- 여러 분류 모델 시도 (로지스틱 회귀, SVM, 랜덤 포레스트 등)
- Grid Search, Random Search 등을 사용한 하이퍼파라미터 튜닝
4. 교차 검증
교차 검증을 통해 모델의 일반화 성능을 평가하고, 과적합을 방지할 수 있습니다.
예제: NSMC 데이터셋을 사용한 모델 튜닝
다음은 앞서 설명한 방법들을 적용하여 NSMC 데이터셋을 이용한 감정 분석 모델을 튜닝하는 예제입니다.
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from konlpy.tag import Okt
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report
# NSMC 데이터 로드
train_data = pd.read_csv('ratings_train.txt', delimiter='\t')
test_data = pd.read_csv('ratings_test.txt', delimiter='\t')
# Null 값 제거
train_data = train_data.dropna(how='any')
test_data = test_data.dropna(how='any')
# 형태소 분석기 생성
okt = Okt()
# 텍스트 전처리 함수 정의
def tokenize(text):
return okt.morphs(text, stem=True)
# TF-IDF Vectorizer와 SVM 분류기를 사용한 파이프라인 생성
pipeline = Pipeline([
('tfidf', TfidfVectorizer(tokenizer=tokenize, stop_words=['영화', '정말'])),
('clf', SVC())
])
# 하이퍼파라미터 그리드 설정
param_grid = {
'tfidf__max_df': [0.8, 0.9],
'tfidf__ngram_range': [(1, 1), (1, 2)],
'clf__C': [1, 10, 100],
'clf__gamma': [0.001, 0.01, 0.1]
}
# 그리드 서치 수행
grid_search = GridSearchCV(pipeline, param_grid, cv=5, n_jobs=-1, verbose=1)
grid_search.fit(train_data['document'], train_data['label'])
# 최적 하이퍼파라미터 출력
print(f"Best parameters: {grid_search.best_params_}")
# 테스트 데이터로 예측 수행
predictions = grid_search.predict(test_data['document'])
# 결과 출력
print(classification_report(test_data['label'], predictions))
설명
- 데이터 전처리 향상: 형태소 분석기를 사용하여 텍스트를 형태소 단위로 분해하고, 불용어를 제거했습니다.
- 피처 추출 및 선택: TF-IDF를 사용하여 텍스트를 벡터화하고, n-그램과 최대/최소 빈도 제한을 적용했습니다.
- 모델 선택 및 하이퍼파라미터 튜닝: SVM 분류기를 사용하고, 그리드 서치를 통해 최적의 하이퍼파라미터를 찾았습니다.
- 교차 검증: 그리드 서치 과정에서 교차 검증을 수행하여 모델의 일반화 성능을 평가했습니다.
결과 해석
이 예제에서는 NSMC 데이터셋을 사용하여 감정 분석 모델을 튜닝했습니다. 최적의 하이퍼파라미터를 찾고, 이를 기반으로 테스트 데이터에 대한 예측을 수행한 결과를 출력했습니다. 실제 프로젝트에서는 이와 같은 튜닝 과정을 반복하여 모델의 성능을 지속적으로 개선할 수 있습니다.
FAQs
1. NSMC 데이터셋이란 무엇인가요?
NSMC(Naver Sentiment Movie Corpus)는 네이버 영화 리뷰에 대해 긍정 및 부정 라벨이 포함된 한국어 감정 분석 데이터셋입니다.
2. TF-IDF(Vectorizer)는 무엇인가요?
TF-IDF(Vectorizer)는 단어의 빈도와 역문서 빈도를 사용하여 텍스트를 벡터로 변환하는 기법입니다. 텍스트 데이터의 중요한 단어들을 강조하는 데 사용됩니다.
3. SVM(서포트 벡터 머신)이란 무엇인가요?
SVM은 분류 및 회귀 분석에 사용되는 지도 학습 모델입니다. 데이터 포인트 간의 최대 마진을 찾는 것을 목표로 합니다.
4. 하이퍼파라미터 튜닝이란 무엇인가요?
하이퍼파라미터 튜닝은 모델의 성능을 최적화하기 위해 하이퍼파라미터의 값을 조정하는 과정입니다. 그리드 서치나 랜덤 서치 같은 기법을 사용하여 최적의 하이퍼파라미터를 찾습니다.
5. 교차 검증이란 무엇인가요?
교차 검증은 데이터를 여러 개의 폴드로 나누어 각 폴드에 대해 모델을 훈련 및 평가하는 방법입니다. 이를 통해 모델의 일반화 성능을 평가하고 과적합을 방지할 수 있습니다.
'데이터 분석의 모든 것 > 7. 비정형 데이터 분석' 카테고리의 다른 글
워드 클라우드로 비정형 데이터 분석하기 (1) | 2024.06.08 |
---|---|
비정형 데이터 분석에서의 유사도 거리 함수 (0) | 2024.06.08 |
KoBERT: 한국어 자연어 처리의 새로운 지평 (1) | 2024.06.07 |
KoGPT: 한국어 자연어 생성의 새로운 가능성 (0) | 2024.06.07 |
PyKoSpacing: 한국어 텍스트의 완벽한 띄어쓰기 교정 도구 (0) | 2024.06.07 |