[Python] 텍스트 분류하기(Bag of words + SVM)

지식인 질문 제목으로 어느대학에 대한 질문인지 맞추기

  • 네이버 지식인에서 “아주대”, “경기대” 키워드로 1000개 수집
In [1]:
import os
os.getcwd()
Out[1]:
'C:\\Users\\ksg'
In [2]:
os.chdir("c:/data")
In [3]:
import pandas as pd
In [4]:
a_univ = pd.read_csv("c:/data/ajou.csv", encoding="utf-8")
k_univ = pd.read_csv("c:/data/kyunggi.csv", encoding="utf-8")
a_univ.head()
Out[4]:
Unnamed: 0 title q_date q_cont a_date a_cont
0 1 아주대전자 VS 인하대전자 2017.12.01. 22:53 아주대전자 VS 인하대전자둘다 집에서부터의 거리는 대중교통 시간입니다심각하게 고민중… 2017.12.01. 22:54 둘다 국숭광명 라인이네요 년 대학순위 참조하세요인서울 수도권 대학 선호현상 지방대 …
1 2 아주대 설빙 초코바나나 포장 2017.10.29. 11:41 말 그대로 아주대 설빙 집에서 초코바나나 포장해오는거 되나요ㅜㅜㅜ 2017.10.31. 14:42 넵 메뉴가 포장가능한 메뉴입니다가게 자체에서 포장이 가능하다고 되어있습니다
2 3 아주대 기계과 합격 가능한가요 2017.11.30. 15:06 국어 점 수학 점 영어 등급 물리 점 지학 점아주대 기계과 합격 가능한가요 서울시립… 2017.11.30. 15:48 안녕하세요 광릉한샘기숙학원 대학진학연구소입니다 아주대 기계공학과 합격권입니다 건국대…
3 4 수원 자궁근종 아주대 에덴메디 2016.12.15. 02:22 휴 자궁근종이 센티 있다는 진단을받아서 복강경으로 수술을해야된다고 하네요ㅠ 아직 아… 2016.12.15. 15:50 안녕하세요 하이닥 네이버 지식iN 상담의 최동석 입니다 둘 중에 자궁근종 치료 경험…
4 5 아주대 수원역 버스 분실문 질문합니다 2017.09.25. 02:33 년 월 일 시경 아주대에서 수원역 가는 버스를 타고 수원역에서 내렸는데 종이가방을 … 2017.09.25. 13:13 아주대에서 수원역 번버스 분실문 질문합니다 수원 번 운행하는 용남고속 호매실영업소전…
In [5]:
k_univ.head()
Out[5]:
title q_date q_cont a_date a_cont
0 경기대 전자공학과랑 한국산업기술대 컴퓨터공학과 중에서 2016.12.27. 09:35 둘 중 어느 쪽이 더 나을까요 2016.12.27. 11:15 안녕하세요 대한민국 호 벤처기업 비트컴퓨터에서 운영하는 소프트웨어 개발자 양성 전문…
1 경기대 체육학과 2017.12.05. 22:43 국 수나 영 사문 생윤 인데 경기대 체육학과 가능할까요 실기는 올만입니다 2017.12.07. 00:29 안녕하세요 답변입니다 안타깝지만 지원이 쉽지 않습니다 실기고사가 올만점이라해도 부족…
2 경기대 교과 차발표 2017.10.04. 14:41 경기대 교과전형 차 발표 하나요 한다면 언제 하는지 좀 알려주세요 2017.10.04. 19:25 안녕하세요 광릉한샘기숙학원 대학진학연구소입니다 경기대 학생부교과는 단계 발표없어요 …
3 경기대 토목공학과 학생부종합 예비 번 받았어요 2017.11.24. 10:19 경기대 토목공학과 학생부종합 예비 번 받았는데 가능성 없겠지요 휴우 2017.11.29. 20:11 대학별 수시 예비자의 추가합격 가능성을 정확하게 말할 수 있는 사람은 없지만 가장 …
4 경기대 외식조리 동덕 식품영양 2017.10.22. 13:44 경기 외식조리 동덕 식품영양 중 어느 과가 입결이 더 높나요 경기대 외식조리학과는 … 2017.10.23. 19:14 안녕하세요 질문자님께서 정말 궁금한것 답변 하도록 하겠습니다 우선 호텔외식조리 쪽으…
In [6]:
print(len(k_univ["q_cont"]),len(k_univ["q_cont"]))
1000 1000

데이터 라벨링

  • 아주대 질문 제목은 1로 경기대 질문 제목은 2로 라벨링
In [7]:
a = pd.DataFrame(a_univ["q_cont"])
a["label"]= 1
a.head()
Out[7]:
q_cont label
0 아주대전자 VS 인하대전자둘다 집에서부터의 거리는 대중교통 시간입니다심각하게 고민중… 1
1 말 그대로 아주대 설빙 집에서 초코바나나 포장해오는거 되나요ㅜㅜㅜ 1
2 국어 점 수학 점 영어 등급 물리 점 지학 점아주대 기계과 합격 가능한가요 서울시립… 1
3 휴 자궁근종이 센티 있다는 진단을받아서 복강경으로 수술을해야된다고 하네요ㅠ 아직 아… 1
4 년 월 일 시경 아주대에서 수원역 가는 버스를 타고 수원역에서 내렸는데 종이가방을 … 1
In [8]:
k = pd.DataFrame(k_univ["q_cont"])
k["label"]= 2
k.head()
Out[8]:
q_cont label
0 둘 중 어느 쪽이 더 나을까요 2
1 국 수나 영 사문 생윤 인데 경기대 체육학과 가능할까요 실기는 올만입니다 2
2 경기대 교과전형 차 발표 하나요 한다면 언제 하는지 좀 알려주세요 2
3 경기대 토목공학과 학생부종합 예비 번 받았는데 가능성 없겠지요 휴우 2
4 경기 외식조리 동덕 식품영양 중 어느 과가 입결이 더 높나요 경기대 외식조리학과는 … 2
In [9]:
data = a.append(k)

데이터 나누기

  • 3분의 2는 트레이닝셋으로 3분의 1을 테스트셋으로 분리
In [10]:
import numpy as np
from sklearn.model_selection import train_test_split
In [11]:
train, test = train_test_split(data, test_size=0.33, random_state=42)
In [12]:
train["label"] = pd.Categorical(train["label"])
c:\users\ksg\appdata\local\programs\python\python36\lib\site-packages\ipykernel_launcher.py:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  """Entry point for launching an IPython kernel.
In [13]:
train.groupby("label").count()
Out[13]:
q_cont
label
1 675
2 665
In [14]:
test.groupby("label").count()
Out[14]:
q_cont
label
1 325
2 335

명사 추출하여 TDM생성

In [15]:
from konlpy.tag import Twitter
from sklearn.feature_extraction.text import CountVectorizer
In [16]:
def get_noun(text):
    tokenizer = Twitter()
    nouns = tokenizer.nouns(text)
    return [n for n in nouns]
In [17]:
cv = CountVectorizer(tokenizer=get_noun)
In [18]:
tdm = cv.fit_transform(train["q_cont"])
In [19]:
cv.vocabulary_
Out[19]:

{‘동국대’: 871, ‘화공’: 3633, ‘생물공학’: 1591, ‘부’: 1369, ‘아주대’: 1982, ‘화학공학’: 3647, ‘홍익대’: 3631, ‘개’: 100, ‘중’: 2946, ‘여러’: 2129, ‘가지’: 41, ‘요인’: 2290, ‘고려’: 255, ‘때’: 938, ‘가장’: 36, ‘나은’: 591, ‘곳좀’: 285, ‘이유’: 2486, ‘수시’: 1758, ‘지원’: 3011, ‘둘’: 905, ‘하나’: 3453, ‘거’: 120, ‘대학’: 799, ‘더’: 814, ‘공대’: 295, ‘건물’: 141, ‘및’: 1210, ‘시설’: 1849, ‘인풋’: 2536, ‘어디가’: 2057, ‘아웃’: 1977, ‘풋’: 3428, ‘취직’: 3205, ‘기준’: 541, ‘제’: 2837, ‘일’: 2542, ‘토요일’: 3319, ‘시험’: 1865, ‘두’: 900, ‘학교’: 3476, ‘날짜’: 602, ‘겹’: 182, ‘경기대’: 188, …}

SVM으로 분류 모델 학습

In [20]:
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline

text_clf_svm = Pipeline([('vect', CountVectorizer(tokenizer=get_noun)),
                         ('tfidf', TfidfTransformer()),
                         ('clf-svm', SGDClassifier(loss='hinge', penalty='l2', alpha=1e-3, n_iter=5, random_state=42))])

text_clf_svm = text_clf_svm.fit(train["q_cont"], train["label"])

테스트 셋으로 정확도 평가

)In [21]:
predicted_svm = text_clf_svm.predict(test["q_cont"])
np.mean(predicted_svm == test["label"])
Out[21]:
0.97272727272727277
In [26]:
 text_clf_svm.predict(["인하대랑 아주대랑 어디가 더 좋나요", "경기대 교통편은 좋은가요"])
Out[26]:
array([1, 2], dtype=int64)
In [28]:
 text_clf_svm.predict(["인하대는 얼마나 좋아요"])
Out[28]:
array([1], dtype=int64

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다