감성분석과 문서분류

Python을 이용해 텍스트에 나타난 감성과 의견을 분석하고, 문서를 카테고리에 따라 분류합니다.


수강중

3. 문서분류 준비

동영상이 없는 텍스트 강의 자료입니다.

문서 분류는 문서들을 2개 이상의 미리 정해진 그룹으로 분류하는 것입니다. 기계 학습으로 문서 분류를 할 경우 기본 원리 자체는 감성 분석과 동일합니다. 다만 감성분석은 긍/부정 2가지로만 분류되는 반면, 문서 분류는 여러 가지로 분류될 수 있다는 차이가 있습니다.

데이터 불러들이기

20 newsgroup 데이터로 문서 분류를 연습해보겠습니다. 이 데이터는 20개의 뉴스 그룹(일종의 주제별 커뮤니티 게시판)에서 모은 게시물로 이뤄져 있습니다.

scikit-learn에는 20 newsgroup 데이터를 바로 다운받을 수 있는 fetch_20newsgroups 함수가 있습니다.

from sklearn.datasets import fetch_20newsgroups

원래는 20개의 카테고리가 여기서는 3개 카테고리를 대상으로 문서 분류를 진행합니다. rec.motorcycles, rec.sport.baseball, rec.sport.hockey 3개 카테고리를 대상으로 하고, 이를 categories 변수로 저장합니다.

categories = [
    'rec.motorcycles',
    'rec.sport.baseball',
    'rec.sport.hockey'
]

훈련용과 테스트용이 미리 분할되어 있으므로 다운만 받으면 됩니다.

  • subset : 훈련(train)과 테스트(test)를 설정
  • categories : 분류하고자 하는 카테고리를 대입. 여기에서는 위에서 categories 로 정의한 변수를 대입합니다.
newsgroups_train = fetch_20newsgroups(subset='train', categories=categories)
newsgroups_test = fetch_20newsgroups(subset='test', categories=categories)

데이터를 확인합니다. 훈련과 테스트셋에서 분류의 대상이 되는 데이터는 각각 newsgroups_train.data , newsgroups_test.data 에 저장되어 있습니다. newsgroups_train.data[1] 으로 훈련셋의 두번째 데이터를 확인할 수 있습니다.

print(newsgroups_train.data[1])
Organization: University of Notre Dame - Office of Univ. Computing
From: <RVESTERM@vma.cc.nd.edu>
Subject: Re: ugliest swing
 <1993Apr12.235334.25031@ptdcs2.intel.com> <34244@oasys.dt.navy.mil>
Lines: 16

In article <34244@oasys.dt.navy.mil>, kiviat@oasys.dt.navy.mil (Brian Kiviat)
says:
>
>What I think is hotdogish about his AB's is the way he leans out over
>the plate to watch outside pitches etc. This not done to get a better
>look at the pitch, but to make it seem,"this ball is so far out I need
>to lean just to get near it so you better call it a ball". This is my
>"unbiased" opinion of what I see. Your mileage will vary.......
>Rickey is agreat player to watch if you forget who he is at the time.

a lot of batters lean in when pitches come.  rickey's crouch tends
to exaggerate that, i think.

"a great player to watch if you forget who he is" - "unbiased"... hmmm...

bob vesterman.

3개의 카테고리 라벨은 0, 1, 2 3개입니다. 이 번호는 위에서 categories에서 나타난 순서입니다.

훈련과 테스트셋에서 데이터의 카테고리는 각각 newsgroups_train.target , newsgroups_test.target 에 저장되어 있습니다.

newsgroups_train.target[1] 으로 훈련셋의 두번째 데이터가 어떤 카테고리에 속하는지 확인할 수 있습니다.

print(newsgroups_train.target[1])
1

훈련셋의 두번째 데이터의 카테고리는 1번이므로 rec.sport.baseball에 속하는 것을 확인할 수 있습니다.

TF-IDF로 단어 문서 행렬 만들기

TF-IDF로 단어 문서 행렬을 만들어보겠습니다.

from sklearn.feature_extraction.text import TfidfVectorizer
  • stop_words: 영어 불용어(관사 등) 제거
  • max_features: 분석에 포함될 단어의 수
tfidf = TfidfVectorizer(stop_words='english', max_features=1000)
  • x_train.shape 으로 훈련셋의 크기를 확인할 수 있습니다.
x_train = tfidf.fit_transform(newsgroups_train.data)
x_train.shape
(1795, 1000)

위 결과에서 (1795, 1000)이란 문서의 수가 1,795개 이고, 단어가 1000종이라는 뜻입니다.

이어서 테스트용 데이터도 단어 문서 행렬로 만듭니다. 이때는 x_train과 똑같은 방식으로 단어 문서 행렬을 만들어야 하므로 fit_transform 대신에 transform을 사용합니다.

x_test = tfidf.transform(newsgroups_test.data)

y_testy_train은 다음과 같이 간단하게 만들 수 있습니다.

y_train = newsgroups_train.target
y_test = newsgroups_test.target

저장

이후의 분석을 위해 데이터를 저장합니다.

import joblib

joblib.dump((x_train, x_test, y_train, y_test, tfidf), 'newsgroup.pkl')
['newsgroup.pkl']