{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **SVM을 이용한 뉴스 Topic 분류기**\n", "뉴스 데이터를 활용하여 주제를 구분하는 모델을 만든다\n", "1. **Tf-IDF**\n", "1. **SVM**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **1 스펨메일을 활용한 Tf-Idf를 정의한다**\n", "1. Naive Bayse 에서 실습한 분류기 학습을 복습한다\n", "1. 텍스트 데이터 **임베딩을 Tf-Idf** 로 생성한다\n", "1. 앞의 **Smoothing / Naive Bayse** 보다, **Tf-IDF / Naive Bayse** 의 AUC가 더 큼을 알 수 있다.\n", "\n", "### **01 Naive Bayse 내용의 복습**\n", "앞에서 진행한 파일 불러오기 및 전처리 작업을 진행합니다" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# 앞에서 진행한 내용 복습\n", "# 정상매일은 0, 스펨매일은 1\n", "import glob,os\n", "\n", "emails, labels = [], []\n", "for no, file_path in enumerate(['./data/enron1/ham/','./data/enron1/spam/']):\n", " for filename in glob.glob(os.path.join(file_path, '*.txt')):\n", " with open(filename, 'r', encoding = \"ISO-8859-1\") as infile:\n", " emails.append(infile.read())\n", " labels.append(no)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from nltk.corpus import names\n", "from nltk.stem import WordNetLemmatizer\n", "\n", "def letters_only(astr):\n", " for c in astr:\n", " if not c.isalpha():\n", " return False\n", " return True\n", "\n", "def clean_text(docs):\n", " cleaned_docs = []\n", " for doc in docs:\n", " cleaned_docs.append(' '.join([lemmatizer.lemmatize(word.lower())\n", " for word in doc.split()\n", " if letters_only(word) and word not in all_names]))\n", " return cleaned_docs" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "all_names = set(names.words())\n", "lemmatizer = WordNetLemmatizer()\n", "cleaned_emails = clean_text(emails)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import StratifiedKFold\n", "import numpy as np\n", "\n", "k = 10\n", "k_fold = StratifiedKFold(n_splits=k)\n", "cleaned_emails_np = np.array(cleaned_emails)\n", "labels_np = np.array(labels)\n", "\n", "smoothing_factor_option = [1.0, 2.0, 3.0, 4.0, 5.0]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from collections import defaultdict\n", "auc_record = defaultdict(float)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **02 Tf-IDf 객체를 생성한다**\n", "1. Naive Bayse 에서 실습한 분류기 학습을 복습한다\n", "1. 이를 활용하여 Tf-Idf 를 생성해본다" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "%timeit\n", "from sklearn.feature_extraction.text import TfidfVectorizer\n", "from sklearn.naive_bayes import MultinomialNB\n", "from sklearn.metrics import roc_auc_score\n", "\n", "for train_indices, test_indices in k_fold.split(cleaned_emails, labels):\n", " X_train, X_test = cleaned_emails_np[train_indices], cleaned_emails_np[test_indices]\n", " Y_train, Y_test = labels_np[train_indices], labels_np[test_indices]\n", " tfidf_vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.5, stop_words='english', max_features=8000)\n", " term_docs_train = tfidf_vectorizer.fit_transform(X_train)\n", " term_docs_test = tfidf_vectorizer.transform(X_test)\n", " for smoothing_factor in smoothing_factor_option:\n", " clf = MultinomialNB(alpha=smoothing_factor, fit_prior=True)\n", " clf.fit(term_docs_train, Y_train)\n", " prediction_prob = clf.predict_proba(term_docs_test)\n", " pos_prob = prediction_prob[:, 1]\n", " auc = roc_auc_score(Y_test, pos_prob)\n", " auc_record[smoothing_factor] += auc" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "defaultdict(,\n", " {1.0: 9.936451496663112,\n", " 2.0: 9.944332721241558,\n", " 3.0: 9.949654316234254,\n", " 4.0: 9.953068949176636,\n", " 5.0: 9.954994323342417})\n" ] } ], "source": [ "from pprint import pprint\n", "pprint(auc_record)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "max features smoothing fit prior auc\n", "\t8000 \t 1.0 \t true \t 0.9936\n", "\t8000 \t 2.0 \t true \t 0.9944\n", "\t8000 \t 3.0 \t true \t 0.9950\n", "\t8000 \t 4.0 \t true \t 0.9953\n", "\t8000 \t 5.0 \t true \t 0.9955\n" ] } ], "source": [ "print('max features smoothing fit prior auc')\n", "for smoothing, smoothing_record in auc_record.items():\n", " print('\\t8000 \\t {0} \\t true \\t {1:.4f}'.format(smoothing, smoothing_record/k))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "## **2 SVM 개념**\n", "1. 최적의 **Hyperplane (데이터가 잘 구분된 최적의 공간)** 을 찾는다\n", "1. 이를 구분하는 데이터 포인트 들을 **Support Vectors**라고 한다\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **01 SVM의 원리**\n", "1. 시나리오1 : **Hyperplane**로 데이터 선별 **ex) $wx + b > 0$ , $wx + b < 0$** 로 분할\n", "1. 시나리오2 : 최적의 **Hyperplane** 결정\n", "1. 시나리오3 : **Outlier(이상치)** 처리 - 에러값이 최소가 되게끔 해야 한다" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **02-1 2개 Topic을 구분하는 SVM (전처리)**\n", "1. 특정한 뉴스토픽 데이터를 불러온 뒤\n", "1. 테스트 데이터를 전처리 작업 후\n", "1. Tf-IDf 로 임베딩 한다" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# 구분할 2개의 카테고리 데이터를 불러온다\n", "from sklearn.datasets import fetch_20newsgroups\n", "\n", "categories = ['comp.graphics', 'sci.space']\n", "data_train = fetch_20newsgroups(subset='train', categories=categories, random_state=42)\n", "data_test = fetch_20newsgroups(subset='test', categories=categories, random_state=42)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "# 불러온 데이터들을 전처리 작업한다\n", "cleaned_train = clean_text(data_train.data)\n", "label_train = data_train.target\n", "cleaned_test = clean_text(data_test.data)\n", "label_test = data_test.target" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "훈련 데이터 : Counter({1: 593, 0: 584}) \n", "테스트 데이터 : Counter({1: 394, 0: 389})\n" ] } ], "source": [ "# 개별 뉴스그룹내 비슷한 분포로 0, 1 데이터가 분포되어 있다\n", "from collections import Counter\n", "print('훈련 데이터 : {} \\n테스트 데이터 : {}'.format(\n", " Counter(label_train), Counter(label_test)))" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "# 데이터를 Tf-IDF 로 임베딩 변환한다\n", "tfidf_vectorizer = TfidfVectorizer(sublinear_tf = True, \n", " max_df = 0.5, \n", " stop_words = 'english', \n", " max_features = 8000)\n", "term_docs_train = tfidf_vectorizer.fit_transform(cleaned_train)\n", "term_docs_test = tfidf_vectorizer.transform(cleaned_test)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **02-2 2개 Topic을 구분하는 SVM (학습)**\n", "1. Kernal 파라미터는 **Linear**로 설정\n", "1. 패널티 값은 1로 설정\n", "1. SVM 알고리즘 모델을 초기화 한다" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,\n", " decision_function_shape='ovr', degree=3, gamma='auto', kernel='linear',\n", " max_iter=-1, probability=False, random_state=42, shrinking=True,\n", " tol=0.001, verbose=False)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 위에서 정의한 파라미터로 모델을 학습한다\n", "from sklearn.svm import SVC\n", "svm = SVC(kernel='linear', C=1.0, random_state=42)\n", "svm.fit(term_docs_train, label_train)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The accuracy on testing set is: 96.4%\n" ] } ], "source": [ "# 학습한 모델을 활용하여 데이터를 예측해본다\n", "accuracy = svm.score(term_docs_test, label_test)\n", "print('The accuracy on testing set is: {0:.1f}%'.format(accuracy*100))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **03 여러개 Topic을 구분하는 SVM**\n", "1. **다중 클래스를** 분류하는 모델\n", "1. **K-클래스의** 문제를 **K개의 서로다른 분류기를** 생성한다\n", "1. **일대 일 방법**은 전체 중 **일부를 사용하여** 컴퓨팅 속도등이 빠르다\n", "1. **일대 다 방법**은 **전체 데이터를** 사용하여 **서로 다른 모듈을** 만든다\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "# 다양한 클래스의 뉴스데이터 불러오기\n", "categories = [\n", " 'alt.atheism',\n", " 'talk.religion.misc',\n", " 'comp.graphics',\n", " 'sci.space',\n", " 'rec.sport.hockey']\n", "\n", "data_train = fetch_20newsgroups(subset='train', categories=categories, random_state=42)\n", "data_test = fetch_20newsgroups(subset='test', categories=categories, random_state=42)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 5 µs, sys: 0 ns, total: 5 µs\n", "Wall time: 11 µs\n" ] } ], "source": [ "%time\n", "# 뉴스그룹 데이터 전처리 작업\n", "cleaned_train = clean_text(data_train.data)\n", "label_train = data_train.target\n", "cleaned_test = clean_text(data_test.data)\n", "label_test = data_test.target" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 8 µs, sys: 0 ns, total: 8 µs\n", "Wall time: 16 µs\n" ] }, { "data": { "text/plain": [ "SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,\n", " decision_function_shape='ovr', degree=3, gamma='auto', kernel='linear',\n", " max_iter=-1, probability=False, random_state=42, shrinking=True,\n", " tol=0.001, verbose=False)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%time\n", "# Tf-IDF 로 임베딩\n", "term_docs_train = tfidf_vectorizer.fit_transform(cleaned_train)\n", "term_docs_test = tfidf_vectorizer.transform(cleaned_test)\n", "\n", "# SVM 모델을 정의하고 학습한다\n", "svm = SVC(kernel='linear', C=1.0, random_state=42)\n", "svm.fit(term_docs_train, label_train)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The accuracy on testing set is: 88.6%\n" ] } ], "source": [ "# 학습 모델의 정확도 측정\n", "accuracy = svm.score(term_docs_test, label_test)\n", "print('The accuracy on testing set is: {0:.1f}%'.format(accuracy*100))" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 0 0.81 0.77 0.79 319\n", " 1 0.91 0.94 0.93 389\n", " 2 0.98 0.96 0.97 399\n", " 3 0.93 0.93 0.93 394\n", " 4 0.73 0.76 0.74 251\n", "\n", "avg / total 0.89 0.89 0.89 1752\n", "\n" ] } ], "source": [ "# 학습된 내용을 자세히 살펴보기\n", "from sklearn.metrics import classification_report\n", "prediction = svm.predict(term_docs_test)\n", "report = classification_report(label_test, prediction)\n", "print(report)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "## **3 SVM 커널 함수들**\n", "**RBF 커널을** 활용하여 **선형모델로 분류할 수 없는** 문제를 해결 (XOR) 가능하다" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **01 RBF 커널 살펴보기**\n", "1. 각각이 다른값을 갖는 데이터에 **RBF함수를** 적용해본다\n", "1. 특별한 목정이 정해지지 않은면 **RBF**를 많이 사용한다\n", "1. **Polynomial kernel(다항)** 커널은 변경해야 하는 파라미터가 많고\n", "1. **Sigmoid kernel(시그모이드)** 커널은 특정한 파라미터가 지정되었을 때 효과가 좋기 때문이다" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(16, 2)" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "X = np.c_[(.3,-.8),(-1.5, -1),(-1.3,-.8),(-1.1,-1.3),(-1.2,-.3),(-1.3, -.5),(-.6,1.1),(-1.4, 2.2),\n", " (1,1), (1.3,.8), (1.2, .5), (.2, -2), (.5,-2.4), (.2, -2.3), (0, -2.7), (1.3, 2.1)].T\n", "X.shape" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1]" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gamma_option = [1,2,4]\n", "Y = [-1] * 8 + [1] * 8\n", "Y" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/markbaum/Python/python/lib/python3.6/site-packages/matplotlib/contour.py:1000: UserWarning: The following kwargs were not used by contour: 'color'\n", " s)\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "plt.figure(1, figsize=(4*len(gamma_option), 4))\n", "for i, gamma in enumerate(gamma_option, 1):\n", " svm = SVC(kernel='rbf', gamma=gamma)\n", " svm.fit(X,Y)\n", " plt.subplot(1, len(gamma_option), i)\n", " plt.scatter(X[:,0], X[:,1], c=Y, zorder=10, cmap=plt.cm.Paired)\n", " plt.axis('tight')\n", " XX, YY = np.mgrid[-3:3:200j, -3:3:200j]\n", " Z = svm.decision_function(np.c_[XX.ravel(), YY.ravel()])\n", " Z = Z.reshape(XX.shape)\n", " plt.pcolormesh(XX, YY, Z > 0, cmap=plt.cm.Paired)\n", " plt.contour(XX, YY, Z, color=['k','k','k'],\n", " linestyles=['--','-','--'], levels=[-.5, 0, .5])\n", " plt.title('gamma=%d'%gamma)\n", " \n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **02 선형 커널 함수와 RBF 커널 함수의 비교**\n", "1. RBF 방식의 커널이 항상 유용한 것은 아니듯, 선형이 유용한 경우도 존재한다\n", "1. 시나리오1 : **Feacture** 갯수와 **Sample의** 갯수가 **모두 큰 경우** 계산량이 복잡하면 선형모델로 구분하는게 더 효과적이다\n", "1. 시나리오2 : **Feacture** 갯수가 학습데이터 샘플 갯수보다 **훨씬 큰 경우** RBF는 Overfitting이 잘 일어나기 때문이다\n", "1. 시나리오3 : Feacture 갯수보다 **학습데이터 샘플의 갯수가 훨씬 많은 경우**\n", "1. 위의 3가지 경우가 아니라면 **RBF**를 사용하여 분석해보자" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "## **4 SVM을 활용한 News Topic 분류**\n", "1. 뉴스그룹 20개의 데이터를 불러와서 정제작업을 진행한다\n", "1. 분류모델은 **선셩회귀식**을 사용한다\n", "1. **category 검정은** 반복문이 아닌 Sklearn의 **GridSearchCV를** 사용한다" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **01 SVC를 활용한 모델의 학습**\n", "\n", "> **GridSearchCV()**\n", "\n", "1. **데이터 분할, 폴드 생성, 교차학습 및 검증, 가장 효과적인 파라미터 추출등을** 함께 진행한다\n", "1. **n_jobs = -1 :** 개별 코어들을 병렬로 진행한다\n", "1. **cv = 3** : 3폴드 교차검증을 진행한다" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [], "source": [ "# 학습할 데이터를 불러온다\n", "categories = None\n", "data_train = fetch_20newsgroups(subset='train', categories=categories, random_state=42)\n", "data_test = fetch_20newsgroups(subset='test', categories=categories, random_state=42)\n", "\n", "# 데이터를 전처리 작업을 진행한다\n", "cleaned_train = clean_text(data_train.data)\n", "label_train = data_train.target\n", "cleaned_test = clean_text(data_test.data)\n", "label_test = data_test.target\n", "\n", "# Tf-IDF로 텍스트를 임베딩 작업 진행한다\n", "tfidf_vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.5, stop_words='english', max_features=8000)\n", "term_docs_train = tfidf_vectorizer.fit_transform(cleaned_train)\n", "term_docs_test = tfidf_vectorizer.transform(cleaned_test)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "# 텍스트 데이터를 분류하는 경우 선형함수를 사용한다\n", "arameters = {'C': [0.1, 1, 10, 100]}\n", "svc_libsvm = SVC(kernel='linear')\n", "\n", "# 전체 20개의 파라미터를 순차적 검증하기 위하여 for 반복문 대신에\n", "from sklearn.model_selection import GridSearchCV\n", "grid_search = GridSearchCV(svc_libsvm, parameters, n_jobs=-1, cv=3)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- 329.416s seconds ---\n", "{'C': 10}\n", "0.8665370337634789\n" ] } ], "source": [ "# 위에서 정의한 모델을 활용하여 학습을 진행한다\n", "import timeit\n", "start_time = timeit.default_timer()\n", "grid_search.fit(term_docs_train, label_train)\n", "print(\"--- %0.3fs seconds ---\" % (timeit.default_timer() - start_time))\n", "print(grid_search.best_params_)\n", "print(grid_search.best_score_)" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The accuracy on testing set is: 76.2%\n" ] } ], "source": [ "%time\n", "# 최적화된 파라미터로 세팅된 SVM모델을 Test 한다\n", "svc_libsvm_best = grid_search.best_estimator_\n", "accuracy = svc_libsvm_best.score(term_docs_test, label_test)\n", "print('The accuracy on testing set is: {0:.1f}%'.format(accuracy*100))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **02 SVC 모델의 튜닝 1**\n", "> **LinearSVC()**\n", "\n", "1. 원본 데이터세트를 활용하여 튜닝을 한다\n", "1. sklearn에서 제공하는 **LinearSVC()** 모듈을 사용해보자\n", "1. SVC와 유사하지만, **libsvm** 모듈 대신에, **liblinear** 를 기반으로 구성\n", "1. 모델생성 속도측면에서 10배 이상 빠르다" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- 11.786s seconds ---\n", "{'C': 1}\n", "0.8707795651405339\n" ] } ], "source": [ "# LinearSVC() 를 활용하여 분류모델을 생성한다\n", "from sklearn.svm import LinearSVC\n", "svc_linear = LinearSVC()\n", "grid_search = GridSearchCV(svc_linear, parameters, n_jobs=-1, cv=3)\n", "\n", "start_time = timeit.default_timer()\n", "grid_search.fit(term_docs_train, label_train)\n", "print(\"--- %0.3fs seconds ---\" % (timeit.default_timer() - start_time))\n", "print(grid_search.best_params_)\n", "print(grid_search.best_score_)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The accuracy on testing set is: 77.9%\n" ] } ], "source": [ "# 생성한 모델의 성능을 비교평가한다\n", "svc_linear_best = grid_search.best_estimator_\n", "accuracy = svc_linear_best.score(term_docs_test, label_test)\n", "print('The accuracy on testing set is: {0:.1f}%'.format(accuracy*100))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### **03 SVC 모델의 튜닝 2**\n", "> **Pipeline()**\n", "\n", "1. Feacture 추출기를 **Pipeline API로** 교체한다\n", "1. max_df : 문서빈도 중 최대값을 설정\n", "1. max_feature : 중요하게 모델에서 학습 할 Feacture 수\n", "1. sublinear_tf : 로그함수 또는 다른함수를 이용하여 출현빈도를 변환\n", "1. smooth_idf : 용어의 출현 빈도에 대한 Smoothing 초기값\n", "1. Grid 검색모델은 **파이프라인 전체에** 걸쳐서 **최적의 Setting을** 찾는다" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "# Tf-IDF 추출기와 SVM 분류기를 1개의 PipeLine로 묶는다\n", "from sklearn.pipeline import Pipeline\n", "pipeline = Pipeline([\n", " ('tfidf', TfidfVectorizer(stop_words='english')),\n", " ('svc', LinearSVC()), ])" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [], "source": [ "# Pipe Line 단계의 이름과 파라미터를 묶어서 키로 설정한다\n", "parameters_pipeline = {\n", " 'tfidf__max_df': (0.25, 0.5),\n", " 'tfidf__max_features': (40000, 50000),\n", " 'tfidf__sublinear_tf': (True, False),\n", " 'tfidf__smooth_idf': (True, False),\n", " 'svc__C': (0.1, 1, 10, 100),}" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- 468.816s seconds ---\n", "{'svc__C': 1, 'tfidf__max_df': 0.5, 'tfidf__max_features': 40000, 'tfidf__smooth_idf': False, 'tfidf__sublinear_tf': True}\n", "0.8883683931412409\n" ] } ], "source": [ "grid_search = GridSearchCV(pipeline, parameters_pipeline, n_jobs=-1, cv=3)\n", "start_time = timeit.default_timer()\n", "grid_search.fit(cleaned_train, label_train)\n", "print(\"--- %0.3fs seconds ---\" % (timeit.default_timer() - start_time))\n", "print(grid_search.best_params_)\n", "print(grid_search.best_score_)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The accuracy on testing set is: 80.6%\n" ] } ], "source": [ "pipeline_best = grid_search.best_estimator_\n", "accuracy = pipeline_best.score(cleaned_test, label_test)\n", "print('The accuracy on testing set is: {0:.1f}%'.format(accuracy*100))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "## **5 SVM을 활용한 심전도 데이터로 태아의 상태 분류**\n", "1. 뉴스그룹 20개의 데이터를 불러와서 정제작업을 진행한다\n", "1. 분류모델은 **선셩회귀식**을 사용한다\n", "1. **category 검정은** 반복문이 아닌 Sklearn의 **GridSearchCV를** 사용한다" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Counter({2.0: 295, 1.0: 1654, 3.0: 176})" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 태아의 심전도 데이터 불러오기\n", "import pandas as pd\n", "df = pd.read_excel('./data/CTG.xls', 'Raw Data')\n", "X = df.iloc[1:2126, 3:-2].values\n", "Y = df.iloc[1:2126, -1].values\n", "\n", "# 데이터 분포비율 분석\n", "Counter(Y)" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [], "source": [ "# Test를 위해 20% 데이터를 분리한다\n", "from sklearn.model_selection import train_test_split\n", "X_train, X_test, Y_train, Y_test = train_test_split(\n", " X, Y, test_size=.2, random_state=42)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- 6.878s seconds ---\n", "{'C': 100000.0, 'gamma': 1e-07}\n", "0.9447058823529412\n" ] }, { "data": { "text/plain": [ "SVC(C=100000.0, cache_size=200, class_weight=None, coef0=0.0,\n", " decision_function_shape='ovr', degree=3, gamma=1e-07, kernel='rbf',\n", " max_iter=-1, probability=False, random_state=None, shrinking=True,\n", " tol=0.001, verbose=False)" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# RBF 기반 SVM모델을 튜닝한다\n", "svc = SVC(kernel='rbf')\n", "parameters = {'C':(100, 1e3, 1e4, 1e5),\n", " 'gamma':(1e-8, 1e-7, 1e-6, 1e-5)}\n", "grid_search = GridSearchCV(svc, parameters, n_jobs=-1, cv=3)\n", "start_time = timeit.default_timer()\n", "grid_search.fit(X_train, Y_train)\n", "print(\"--- %0.3fs seconds ---\" % (timeit.default_timer() - start_time))\n", "print(grid_search.best_params_)\n", "print(grid_search.best_score_)\n", "\n", "# 최적화된 모델의 파라미터를 출력\n", "svc_best = grid_search.best_estimator_\n", "svc_best" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The accuracy on testing set is: 95.5%\n" ] } ], "source": [ "# 최적화 파라미터를 사용하여 모델을 Test 한다\n", "accuracy = svc_best.score(X_test, Y_test)\n", "print('The accuracy on testing set is: {0:.1f}%'.format(accuracy*100))" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 1.0 0.96 0.98 0.97 324\n", " 2.0 0.89 0.91 0.90 65\n", " 3.0 1.00 0.78 0.88 36\n", "\n", "avg / total 0.96 0.96 0.95 425\n", "\n" ] } ], "source": [ "# 개별 클래스멸 성능을 측정한다\n", "prediction = svc_best.predict(X_test)#, Y_test)\n", "report = classification_report(Y_test,prediction)\n", "print(report)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.9" } }, "nbformat": 4, "nbformat_minor": 4 }