티스토리 뷰

학습목표

- Bag of Words의 개념과 원리를 이해한다.
- CountVectorizer를 활용해 텍스트 데이터를 벡터화하는 방법을 익힌다.
- 벡터화된 데이터를 분석하고 단어 사전과 행렬을 해석할 수 있다.
- 실습과 시각화를 통해 텍스트 데이터의 유용한 정보를 추출하고 활용한다.

1. Bag of Words ?

스파이의 암호 해독 이야기

어느 날, 스파이들이 사용하는 암호 메시지를 해독해야 하는 상황에 놓였다고 상상해보자. 메시지는 온갖 단어로 이루어져 있지만 그 안에 숨겨진 패턴을 찾아야 한다. 이때 우리가 사용하는 도구가 바로 "Bag of Words"이다. "Bag of Words"는 단어를 '그냥 모아놓은 주머니'처럼 생각하는 기법으로, 단어가 몇 번 사용되었는지만 세는 아주 단순하면서도 강력한 방법이다.

즉, 텍스트 데이터를 숫자 벡터로 변환하는 가장 기본적이고 널리 사용되는 기법 중 하나이며, BoW는 텍스트에서 단어의 순서와 문맥을 무시하고, "각 단어가 몇 번 등장했는가"에만 초점을 맞춘다.

이제 이 기술을 실제로 사용하는 법을 파이썬 코드를 통해 살펴보겠다.


Bag of Words의 작동 원리

  1. 텍스트 데이터 준비
    분석하고자 하는 문장이나 문서(텍스트)를 모은다.
  2. 토큰화(Tokenization)
    문장을 구성하는 단어(토큰)로 나눈다. 예:
    • 문장: "고양이가 집에서 뛰어다닌다."
    • 토큰: ["고양이", "집", "뛰어다닌다"]
  3. 단어 사전(Vocabulary) 생성
    전체 텍스트에서 등장한 고유한 단어를 모아 단어 사전을 만든다.
    예: ["고양이", "집", "뛰어다닌다", "강아지", "공원"]
  4. 단어 등장 횟수 계산
    각 문장에서 단어가 몇 번 등장했는지를 세어 숫자로 표현한다.
    • 문장 1: "고양이가 집에서 뛰어다닌다" → [1, 1, 1, 0, 0]
    • 문장 2: "강아지가 공원에서 뛴다" → [0, 0, 0, 1, 1]

Bag of Words의 특징

  1. 장점:
    • 구현이 간단하고 빠르게 계산할 수 있다.
    • 기본적인 자연어 처리에 적합하다.
  2. 단점:
    • 단어의 순서를 무시하므로 문맥을 이해하지 못한다.
    • 희소 행렬(Sparse Matrix) 문제가 발생한다. (데이터 대부분이 0으로 채워짐)

Bag of Words가 많이 사용되는 분야

  1. 텍스트 분류
    • 스팸 이메일 분류: 이메일의 텍스트를 분석하여 스팸 여부를 판단.
    • 뉴스 카테고리 분류: 뉴스 기사를 주제별로 분류.
  2. 감정 분석(Sentiment Analysis)
    • 영화 리뷰, 소셜 미디어 글 등에서 긍정/부정 감정을 예측.
  3. 정보 검색 및 추천 시스템
    • 문서 검색: 입력된 키워드와 관련성이 높은 문서를 추천.
    • 영화/상품 추천: 텍스트 설명을 기반으로 유사성을 분석.
  4. 자연어 처리 및 언어 모델링
    • 챗봇, 번역기, 요약 시스템 등 다양한 언어 기반 응용.
  5. 소셜 네트워크 분석
    • 트위터, 페이스북 같은 플랫폼에서 특정 키워드의 빈도를 분석하여 트렌드를 파악.

Bag of Words의 대표 응용 예시

  • 스팸 필터링:
    이메일 본문에서 단어 등장 횟수를 분석해 스팸 메일을 걸러냄.
  • 감정 분석:
    영화 리뷰에서 "좋다", "최고", "재밌다" 같은 긍정적인 단어와 "별로", "지루하다" 같은 부정적인 단어 빈도를 분석.
  • 키워드 추출:
    문서에서 빈도 기반으로 중요한 키워드를 자동으로 추출.

2. Bag of Words 기초 코드

1) 필요한 라이브러리 소개

  • scikit-learn(사이킷런): 텍스트를 벡터화하는 데 유용하다.
  • pandas: 데이터를 다루는 데 편리하다.
  • numpy: 수학 연산에 유용하다.
pip install scikit-learn pandas numpy

1. scikit-learn이란?

scikit-learn(사이킷런)은 파이썬에서 사용할 수 있는 머신러닝 라이브러리로, 데이터 처리부터 머신러닝 모델 생성, 평가까지 지원하는 강력한 도구이다.

  • 사용하기 쉽고 직관적인 API 제공
  • 다양한 데이터 전처리 및 모델링 기능
  • 텍스트 데이터 처리부터 이미지, 수치 데이터까지 지원
  • 단순한 텍스트 벡터화부터 고급 TF-IDF 계산까지 지원
  • 다른 머신러닝 모델과 쉽게 결합 가능.

* scikit-learn을 사용할 때는 주로 from sklearn,을 통해 필요한 모듈이나 클래스를 불러옵니다.
sklearn은 scikit-learn의 약어로, Python에서 표준적으로 사용하는 방법입니다.

2. 텍스트 벡터화에서의 역할

텍스트 데이터는 머신러닝 모델이 직접 처리하기 어렵기 때문에, 이를 숫자(벡터)로 변환해야 한다.
scikit-learn은 이를 위한 다양한 도구를 제공하며, 대표적으로 CountVectorizerTfidfVectorizer가 있다.

3. CountVectorizer: Bag of Words 생성

CountVectorizer는 텍스트 데이터를 벡터로 변환하는 데 사용하는 가장 기본적인 도구이다.

  • 텍스트 데이터를 단어(토큰) 단위로 나누어 빈도를 계산
  • 단어 사전(vocabulary)을 자동으로 생성
  • 벡터화된 데이터를 희소 행렬(sparse matrix) 형태로 반환
희소 행렬(sparse matrix) 
보통 행렬(matrix)에서 대부분의 값이 0 으로 이루어진 경우를 의미하며, 주로 머신러닝과 데이터 과학에서 큰 데이터를 효율적으로 표현하기 위해 사용된다.
from sklearn.feature_extraction.text import CountVectorizer

# 샘플 텍스트 데이터
documents = ["나는 데이터 분석을 좋아한다", "데이터는 미래의 자산이다", "분석은 데이터를 이해하는 도구이다"]

# CountVectorizer로 벡터화
vectorizer = CountVectorizer()
bow_matrix = vectorizer.fit_transform(documents)

# 결과 출력
print("단어 사전:", vectorizer.vocabulary_)
print("Bag of Words 행렬:\n", bow_matrix.toarray())
  • 필요한 라이브러리(scikit-learn, pandas, numpy)를 임포트합니다.
  • 분석할 텍스트 데이터를 리스트 형태로 정의합니다.
  • CountVectorizer 초기화: CountVectorizer는 텍스트 데이터를 숫자로 변환하기 위해 사용됩니다.
  • Bag of Words 생성: fit_transform을 통해 단어의 빈도를 계산하여 벡터 형태의 데이터로 변환합니다.
  • 결과 출력:
    • vocabulary_는 단어 사전을 출력합니다.
    • bow_matrix.toarray()는 문장별로 단어의 빈도를 행렬로 나타냅니다.


4. TfidfVectorizer: 단어 가중치 계산

TfidfVectorizer는 단어의 빈도와 함께 가중치(TF-IDF)를 계산해 더 정교한 벡터화를 지원한다.

TF-IDF란?

  • TF (Term Frequency): 특정 단어가 문서에서 얼마나 자주 등장하는지.
  • IDF (Inverse Document Frequency): 단어가 전체 문서에서 얼마나 드문지.
  • TF-IDF: 특정 단어가 문서에서 얼마나 중요한지를 수치로 표현한 값.
    (
    점수는 보통 0에서 1 사이 값을 가지며, 1에 가까울수록 해당 단어가 중요함을 의미합니다.)
#1.TfidfVectorizer를 사용하기 위해 라이브러리 불러오기
from sklearn.feature_extraction.text import TfidfVectorizer  

#2.샘플 텍스트 데이터
documents = [
    "나는 데이터 분석을 좋아한다",  # 문장 1
    "데이터는 미래의 자산이다",       # 문장 2
    "분석은 데이터를 이해하는 도구이다"  # 문장 3
]

#3.TfidfVectorizer 객체 생성 (TF-IDF 방식으로 텍스트를 벡터화)
vectorizer = TfidfVectorizer()

#4. 텍스트 데이터를 TF-IDF 방식으로 변환
tfidf_matrix = vectorizer.fit_transform(documents)

# 5. 출력 (단어와 해당 인덱스를 보여줌)
print("단어 사전:", vectorizer.vocabulary_)

# TF-IDF 행렬 출력 (각 문장에서 단어의 TF-IDF 점수를 배열로 나타냄)
print("TF-IDF 행렬:\n", tfidf_matrix.toarray())


대표적인 모듈과 주요 클래스/함수

모듈 설명 주요 클래스 / 함수
sklearn.preprocessing 데이터 전처리를 위한 도구 제공 StandardScaler, MinMaxScaler, LabelEncoder, OneHotEncoder
sklearn.model_selection 데이터 분리 및 모델 평가 train_test_split, GridSearchCV, RandomizedSearchCV
sklearn.metrics 모델 평가를 위한 지표 제공 accuracy_score, confusion_matrix, mean_squared_error, roc_auc_score
sklearn.linear_model 선형 모델 관련 알고리즘 LinearRegression, LogisticRegression, Ridge, Lasso
sklearn.ensemble 앙상블(Ensemble) 학습 관련 알고리즘 RandomForestClassifier, GradientBoostingClassifier, AdaBoostClassifier
sklearn.svm 서포트 벡터 머신(SVM) 모델 SVC (Support Vector Classifier), SVR (Support Vector Regressor)
sklearn.neighbors K-최근접 이웃(KNN) 알고리즘 KNeighborsClassifier, KNeighborsRegressor
sklearn.cluster 군집화(Clustering) 알고리즘 KMeans, DBSCAN, AgglomerativeClustering
sklearn.decomposition 차원 축소(Dimensionality Reduction) 도구 PCA (Principal Component Analysis), TruncatedSVD, NMF
sklearn.tree 의사결정 트리(Decision Tree) 모델 DecisionTreeClassifier, DecisionTreeRegressor
sklearn.feature_extraction 텍스트 및 이미지 데이터 벡터화 도구 CountVectorizer, TfidfVectorizer, DictVectorizer
sklearn.datasets 샘플 데이터셋 제공 load_iris, load_boston, load_digits, make_classification
sklearn.pipeline 데이터 전처리와 모델 학습을 연결하는 파이프라인 제공 Pipeline, make_pipeline

2) Bag of Words 기본 예제

from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

# 샘플 텍스트 데이터
documents = [
    "스파이는 암호를 해독해야 한다",
    "암호는 단어의 반복과 패턴을 포함한다",
    "스파이는 메시지의 단서를 찾는다"
]

# CountVectorizer를 사용하여 Bag of Words 생성
vectorizer = CountVectorizer()
bow_matrix = vectorizer.fit_transform(documents)

# 단어별 인덱스 확인
print("단어 사전 (Vocabulary):")
print(vectorizer.vocabulary_)

# Bag of Words 행렬을 데이터프레임으로 변환
bow_df = pd.DataFrame(bow_matrix.toarray(), columns=vectorizer.get_feature_names_out())

print("\nBag of Words 행렬:")
print(bow_df)
  • 데이터 준비: 텍스트 데이터가 들어 있는 리스트 documents를 준비한다.
  • CountVectorizer 사용:
    • CountVectorizer는 텍스트 데이터를 벡터로 변환한다.
    • 각 단어가 문서에서 몇 번 등장했는지를 세어 행렬로 나타낸다.
  • 결과 확인:
    • vocabulary_를 통해 단어와 인덱스를 확인한다.
    • 결과 행렬은 데이터프레임으로 만들어 더 보기 쉽게 출력한다.

실행 결과 예시

단어 사전 (Vocabulary):
{'스파이는': 5, '암호를': 6, '해독해야': 8, '한다': 7, '암호는': 4, '단어의': 1, '반복과': 2, '패턴을': 3, '포함한다': 9, '메시지의': 0, '단서를': 10, '찾는다': 11}

Bag of Words 행렬:
   단어의  단서를  메시지의  반복과  스파이는  암호는  암호를  찾는다  패턴을  포함한다  해독해야  한다
0     0     0      0     0      1      0      1     0      0      0      1     1
1     1     0      0     1      0      1      0     0      1      1      0     0
2     0     1      1     0      1      0      0     1      0      0      0     0

3. 연습문제

  • 1. 다음 텍스트 데이터로 Bag of Words를 만들어보자:
documents = ["너를 처음 봤을 때 마음이 떨려",
"사랑은 마치 불꽃처럼 뜨겁게 타올라",
"나의 마음속에 빛이 되어줘",
"우리는 하나가 되어 춤을 춘다",
"별처럼 빛나는 너의 눈동자"]

1)라이브러리 불러오기

from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

2) 문서 데이터 셋팅

documents = ["너를 처음 봤을 때 마음이 떨려",
"사랑은 마치 불꽃처럼 뜨겁게 타올라",
"나의 마음속에 빛이 되어줘",
"우리는 하나가 되어 춤을 춘다",
"별처럼 빛나는 너의 눈동자"]

3) 벡터화 및 BoW 생성

vectorizer = CountVectorizer()
bow_matrix = vectorizer.fit_transform(documents)

4) BoW 단어사전 출력

print('단어사전:', vectorizer.vocabulary_)

5) BoW 행렬을 데이터프레임으로 변환 후 출력

bow_df = pd.DataFrame(bow_matrix.toarray(), columns=vectorizer.get_feature_names_out())
print('Bag of Words 행렬:')
print(bow_df)
  • 2. 단어 사전과 Bag of Words 행렬을 출력하고, 가장 많이 등장한 단어를 찾아라.
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

# 노래 가사 데이터
documents = [
    "너를 처음 봤을 때 마음이 떨려",
    "사랑은 마치 불꽃처럼 뜨겁게 타올라",
    "나의 마음속에 빛이 되어줘",
    "우리는 하나가 되어 춤을 춘다",
    "별처럼 빛나는 너의 눈동자"
]

# CountVectorizer를 사용하여 Bag of Words 생성
vectorizer = CountVectorizer()
bow_matrix = vectorizer.fit_transform(documents)

# 단어 사전
vocab = vectorizer.vocabulary_

# Bag of Words 행렬을 데이터프레임으로 변환
bow_df = pd.DataFrame(bow_matrix.toarray(), columns=vectorizer.get_feature_names_out())

# 각 단어의 총 빈도 계산
word_frequencies = bow_df.sum(axis=0).sort_values(ascending=False)

# 결과 출력
print("단어 사전 (Vocabulary):", vocab)
print("\nBag of Words 행렬:\n", bow_df)
print("\n가장 많이 등장한 단어:")
print(word_frequencies.head(1))  # 가장 많이 등장한 단어 출력

과제

1. 추가 데이터로 실습: 뉴스 기사 제목 5개를 직접 검색하여 documents 리스트에 추가하고 Bag of Words를 만들어보자.

"한국 경제, 올해 성장률 2.5% 예상"
"AI 기술, 산업 전반에 혁신을 가져오다"
"기후 변화 대응, 각국 협력 중요성 부각"
"스포츠 이벤트, 지역 경제 활성화에 기여"
"우주 탐사, 새로운 행성 발견 가능성 열리다"
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

# 뉴스 기사 제목 샘플
documents = [
    "한국 경제, 올해 성장률 2.5% 예상",
    "AI 기술, 산업 전반에 혁신을 가져오다",
    "기후 변화 대응, 각국 협력 중요성 부각",
    "스포츠 이벤트, 지역 경제 활성화에 기여",
    "우주 탐사, 새로운 행성 발견 가능성 열리다"
]

# CountVectorizer를 사용하여 Bag of Words 생성
vectorizer = CountVectorizer()
bow_matrix = vectorizer.fit_transform(documents)

# 단어 사전 확인
print("단어 사전 (Vocabulary):")
print(vectorizer.vocabulary_)

# Bag of Words 행렬을 데이터프레임으로 변환
bow_df = pd.DataFrame(bow_matrix.toarray(), columns=vectorizer.get_feature_names_out())

print("\nBag of Words 행렬:")
print(bow_df)
  • 단어 사전: vocabulary_는 모든 단어와 그 단어의 인덱스를 보여준다.
    예: {'한국': 12, '경제': 3, '올해': 10, '성장률': 8, '예상': 11, ...}
  • Bag of Words 행렬: 각 문장(문서)을 행으로, 단어를 열로 하여 단어의 빈도를 숫자로 나타낸다.
    ai  경제  기여  기후  ...  우주  예상  열리다
0    0    1    0    0  ...    0    1    0
1    1    0    0    0  ...    0    0    0
...

2. 단어 빈도 시각화: Bag of Words 행렬에서 단어 빈도를 추출해 Matplotlib를 사용해 막대 그래프로 시각화하라.

import matplotlib.pyplot as plt
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer

# 뉴스 기사 제목 샘플
documents = [
    "한국 경제, 올해 성장률 2.5% 예상",
    "AI 기술, 산업 전반에 혁신을 가져오다",
    "기후 변화 대응, 각국 협력 중요성 부각",
    "스포츠 이벤트, 지역 경제 활성화에 기여",
    "우주 탐사, 새로운 행성 발견 가능성 열리다"
]

# CountVectorizer를 사용하여 Bag of Words 생성
vectorizer = CountVectorizer()
bow_matrix = vectorizer.fit_transform(documents)

# 단어 사전 및 빈도 추출
vocab = vectorizer.get_feature_names_out()
word_counts = bow_matrix.toarray().sum(axis=0)

# 데이터프레임 생성
bow_df = pd.DataFrame({'단어': vocab, '빈도': word_counts})
bow_df = bow_df.sort_values(by='빈도', ascending=False)

# 시각화
plt.figure(figsize=(12, 6))
plt.bar(bow_df['단어'], bow_df['빈도'])
plt.title('단어 빈도 시각화 (Bag of Words)', fontsize=16)
plt.xlabel('단어', fontsize=12)
plt.ylabel('빈도', fontsize=12)
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()


핵심 키워드

  • Bag of Words (BoW)
  • CountVectorizer
  • 텍스트 벡터화
  • 단어 사전 (Vocabulary)
  • 희소 행렬 (Sparse Matrix)
728x90
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
반응형