Files
hands-on/03_classification.ipynb
2018-06-16 21:55:35 +09:00

4601 lines
438 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPython 3.6.5\n",
"IPython 6.4.0\n",
"\n",
"numpy 1.14.3\n",
"scipy 1.1.0\n",
"sklearn 0.19.1\n",
"pandas 0.23.0\n",
"matplotlib 2.2.2\n"
]
}
],
"source": [
"%load_ext watermark\n",
"%watermark -v -p numpy,scipy,sklearn,pandas,matplotlib"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**3장 분류**\n",
"\n",
"_이 노트북은 3장에 있는 모든 샘플 코드와 연습문제 해답을 가지고 있습니다._"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 설정"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"파이썬 2와 3을 모두 지원합니다. 공통 모듈을 임포트하고 맷플롯립 그림이 노트북 안에 포함되도록 설정하고 생성한 그림을 저장하기 위한 함수를 준비합니다:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# 파이썬 2와 파이썬 3 지원\n",
"from __future__ import division, print_function, unicode_literals\n",
"\n",
"# 공통\n",
"import numpy as np\n",
"import os\n",
"\n",
"# 일관된 출력을 위해 유사난수 초기화\n",
"np.random.seed(42)\n",
"\n",
"# 맷플롯립 설정\n",
"%matplotlib inline\n",
"import matplotlib\n",
"import matplotlib.pyplot as plt\n",
"plt.rcParams['axes.labelsize'] = 14\n",
"plt.rcParams['xtick.labelsize'] = 12\n",
"plt.rcParams['ytick.labelsize'] = 12\n",
"\n",
"# 한글출력\n",
"matplotlib.rc('font', family='NanumBarunGothic')\n",
"plt.rcParams['axes.unicode_minus'] = False\n",
"\n",
"# 그림을 저장할 폴드\n",
"PROJECT_ROOT_DIR = \".\"\n",
"CHAPTER_ID = \"classification\"\n",
"\n",
"def save_fig(fig_id, tight_layout=True):\n",
" path = os.path.join(PROJECT_ROOT_DIR, \"images\", CHAPTER_ID, fig_id + \".png\")\n",
" if tight_layout:\n",
" plt.tight_layout()\n",
" plt.savefig(path, format='png', dpi=300)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# MNIST"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"{'DESCR': 'mldata.org dataset: mnist-original',\n",
" 'COL_NAMES': ['label', 'data'],\n",
" 'target': array([0., 0., 0., ..., 9., 9., 9.]),\n",
" 'data': array([[0, 0, 0, ..., 0, 0, 0],\n",
" [0, 0, 0, ..., 0, 0, 0],\n",
" [0, 0, 0, ..., 0, 0, 0],\n",
" ...,\n",
" [0, 0, 0, ..., 0, 0, 0],\n",
" [0, 0, 0, ..., 0, 0, 0],\n",
" [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.datasets import fetch_mldata\n",
"mnist = fetch_mldata('MNIST original')\n",
"mnist"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(70000, 784)"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X, y = mnist[\"data\"], mnist[\"target\"]\n",
"X.shape"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(70000,)"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y.shape"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"784"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"28*28"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"import matplotlib\n",
"import matplotlib.pyplot as plt\n",
"\n",
"some_digit = X[36000]\n",
"some_digit_image = some_digit.reshape(28, 28)\n",
"plt.imshow(some_digit_image, cmap = matplotlib.cm.binary,\n",
" interpolation=\"nearest\")\n",
"plt.axis(\"off\")\n",
"\n",
"save_fig(\"some_digit_plot\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def plot_digit(data):\n",
" image = data.reshape(28, 28)\n",
" plt.imshow(image, cmap = matplotlib.cm.binary,\n",
" interpolation=\"nearest\")\n",
" plt.axis(\"off\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"# 숫자 그림을 위한 추가 함수\n",
"def plot_digits(instances, images_per_row=10, **options):\n",
" size = 28\n",
" images_per_row = min(len(instances), images_per_row)\n",
" images = [instance.reshape(size,size) for instance in instances]\n",
" n_rows = (len(instances) - 1) // images_per_row + 1\n",
" row_images = []\n",
" n_empty = n_rows * images_per_row - len(instances)\n",
" images.append(np.zeros((size, size * n_empty)))\n",
" for row in range(n_rows):\n",
" rimages = images[row * images_per_row : (row + 1) * images_per_row]\n",
" row_images.append(np.concatenate(rimages, axis=1))\n",
" image = np.concatenate(row_images, axis=0)\n",
" plt.imshow(image, cmap = matplotlib.cm.binary, **options)\n",
" plt.axis(\"off\")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAokAAAKACAYAAADw2OLpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3WegE9X6tvHLXkBBrCC2v10RUeDYxS6Kir13sWFHjw08VizYFRUrdlFRRMUC9i4gih27HBWwix3b++G8d9ZkJtk7OzuTtu/fF0KSnay0SeaeZz1rpn/++QczMzMzs6iZKz0AMzMzM6s+/pFoZmZmZgn+kWhmZmZmCf6RaGZmZmYJ/pFoZmZmZgn+kWhmZmZmCf6RaGZmZmYJ/pFoZmZmZgn+kWhmZmZmCbNWegAxXv7FzMzMLF0zFXIlJ4lmZmZmluAfiWZmZmaW4B+JZmZmZpbgH4lmZmZmluAfiWZmZmaW4B+JZmZmZpbgH4lmZmZmluAfiWZmZmaWUG3NtCvqlVdeyZwePHgwADfddBMA++yzDwBHHHEEAKuvvnqZR2dmxfjll18A+O233xKXzTrr/zaB8847b1nHZPm99NJLAFxzzTUADB06NHGdK664AoBddtkFgPnnn79Mo7M0zJgxA4Dff/+90evOMsssAMw999ypjqncTjvtNACmTJkCwLXXXgvA33//XakhAU4SzczMzCyHmf75p6pWwqvIYF577TUANtxww8x506dPz3ndNm3aAPDtt9+mPzBr0FNPPQXA6aefnjlviy22AGDvvfcG4Oabbwbg66+/BmDcuHFZ1zvwwAMzfzvffPOlO+Ay+O9//wvA3XffnTlPyUzcmmuuCUDHjh0BWGuttQBYbLHF0hxi6vTZHTVqFADnn38+ED7nUR06dADgueeeA2DJJZcswwiT/vrrLwDeeOONzHl33XVXk29H7+HDDjsMqI20RdtSvQb6TH711Vd5/0bfW/ocn3zyyVmXt23bNnO6U6dOpRtsSsaPHw/An3/+CYT09K233gLg+eefz7q+PrMAY8aMAWCFFVZIfZylptd4v/32A+Dhhx/OXKbXeKaZslePW2ihhQDo168fAAcccAAA7dq1S3ewKXnzzTcB2GabbYCwDZcTTzwxc7p///4AzDnnnKW4ay/LZ2ZmZmbFadFJ4tixYwHYYYcdAPj8888zl2nvRbVKs88+OxASKe31du3aNetyS993330HwLbbbgvAs88+m7ksvtcZF987VZIEIX059thjAZhtttlKNOLS097mxRdfDMDw4cOzzm+OnXbaKXP6wgsvBKo7Xfzxxx8BeOCBBwC45JJLgJDOFOK+++4Dwt58udxwww1ASFDuueeegv82X9ICsOCCCwJw3HHHAXDUUUcB1bmd0nt35513LvhvGnrsAIsuumjmtBJZJeWVpu3VvffemzlPNfBKlJtCydqAAQOAsB1rbFtYCT///DMATzzxBBCO+OQ6ctfYayw9evQA4Lbbbsuc1759++YPtkw22mgjIPt7LCr6ntDRs/XXX78Ud+0k0czMzMyK06KSRM1ynDBhAgB77rknENKX6HOhvRclhccffzwQZtPpumeddRaQrImpJp988gkAf/zxR+a8iy66CAizyeaZZx4AzjzzTKC6Z3vecsstAOy7775A7tdtgQUWAGCPPfYAQu2S3gOHH344AF988UXi9pW+nHfeeaUeerMpFdEYm5IcRhNCCLWKDd2G6hZffPHFJo0zbT/99FPmtGqSonWYTaU0RqnWuuuu24zR5aeaM22DtD359NNPE9ddfPHFAZhjjjmyzv/ggw+AMOuxkMRIXRkGDRqU8zYrQe+pLbfcEoAffvgh5/V69uyZOf3II48AhadMAEsssQQAH3/8cfGDLYEHH3wQCIlprtn2cd26dQPg/fffB0JCrPdALhMnTgRglVVWKX6wJabP6yGHHALAHXfckXW5Pn/RbVQ8LVPyeuedd+a8j+jRDm3bFllkkeYMO1X67XDuuecC+Wd2R5PE7t27A/Dyyy+XYghOEs3MzMysOC0qSdxrr70AuP3223PfeY5ESq6//nogzJZVbYCSgPieUSVob017nZohp16P0fRF4nvkZ599NgAnnHBCuoNthk033RQIdS25Xrdbb70VgN122y3nbSg9U3IK4TUW1YupR2Y1UArRWGoW3SM/5phjgPw1WXouVIuZ67Z1e8XMuC0F7U3rNVESDjBp0qSS3Y/67X344YdA6RN1zbCO91lt3bo1kD1TXzM+ozN1AUaMGAHA448/DmTXMr333nsAzDXXXAB8//33WX+rz44SxVVXXbXYh1KUaO2ZEr54gqhZuiNHjgRgyJAhmctUg9urVy8g1OFpVnfv3r2B7PeEemGqVrVv376leCgF0+xtJWNvv/124joao45u6ciUZjHrNjRbXY8FYODAgUD4jHTu3BkINfeVqkPVZwjC49KYREcBtI1accUV896e6hn1flcfQdUTR8WT82qpxb3uuusypw866CAg9H3MJ5okLrXUUkD2c9sMThLNzMzMrDgtYsUVraSimpB4errBBhsAsNVWW2XOU82XZr+uttpqQNhjffLJJ3PeViUoIbzxxhuBMJOxGNorffrpp4GQlEKYTaxekZWiGea5KPXTjPV8VL9y+eWXZ85TvZiS1zPOOCPrNqtBtD9aQ3bcccfM6cZmdeq50N80p7YvLfvvvz8Q6lELoSRus802A2DttdfOXKaU6oILLgBg8uTJAHzzzTdAcbNMG6KEb7vttss6Xwni1VdfDeRPvqN0G/o3WsukpE11fHoPK21RTz0lcNHZ1OVIW/T8QjJBVDcBpUDLLrssAKeeemrmOhtvvDEQ6hjj9LdHH3105jx9rj/77DMg1HLOPHN5MhKl8LkSRNEMVyXlcdEuDBBW54Bw9EQp9Ouvvw7ACy+8AITvt7TpfajvTt0/hARdtYdaMUe14kq+G9KqVSsgvLf1/1xJorbreq115EGJbblNnToVCEciIfx2aGxbE/2NUYnfG04SzczMzCzBPxLNzMzMLKFuJ65El+DScnvxhp06ZKFJJ5qMAmF5rD59+gCh9YDoUIUibx2ehWRRehpUxAtw8MEHA8VNnmlKKwkVROtwttoDlavVwujRo4HslhgACy+8cOa0FkcvhpZHWmeddYDwftEyYddcc03Rt90c0cki0cP/EA4V6/BarkPLhTYR1gQWPf7oeeWeuKJDMMUcZlZpiD6TOqSbiyYu6fCdPg+aOKA2Fc2l21O7C1GzchXul5oO6eqQnD67em9rUQDIPhyfFk1ggOQEQo1Nh8ybI1pyEy0pgTCZp1xtvnTYXJMNVK5z0kknZa6jBtj6PmkKNZNXexSVNmjShg7/pk2flWh5gOj7U9uPUjSDVpmVmmnnWnZT9J468sgjm32/TaH3miYcqkwNwjbOE1fMzMzMrObUXZKovahoYe+wYcOAsDejJXtUvB0t8i+UkkQlcNGEJ1+LnVJ49dVXATj//PMz5+VrLlqIpiSJcWoX8s4772T9Py1KElXsLCqGhuYliaI9fDXTVpsQPfflomJrtaaJUoKo176US47169cvc1p74OVKElX8rqa7mkQk2utu165d5ryvvvoq6zpqs6FGxIVYY401ABg3blzW+Sp8b67tt98eCImemtc/+uijQGhanjalrGq4HD1Coqb7hUwiaKovv/wSCM8DhIkNmox1//33A9ClS5dm358mKUJyqcVyJYl6zNp+TJs2DQiTF6KpailoaT+lZWokrSbiaTVQ1yINakuk1kxRjbUkaw4lidFUPE7bi/i2Im2aTJTriISTRDMzMzOrWXXTAic+/X7UqFGZy7THqD04JQy//vprye6/KcujFUNtfJRy5dpbawrVbyh1UXPWhto0xKmdhWp+oultGnItXQalb/FwzjnnACGB1p64llJLu+ZU76Vow1xR4qREL7oUVamoVUiUlrlKm2p24gmiEi8txahGtBBeD9Vm7b777gDcdtttQPi850rL9X5Pe8k2NcDWGJTylCtBlEMPPRQISW00WSlVapqLXtdoWxRRcliKBFGi9ZU6rftWQp/29ur5558HQoKoo016f5aaatNVE6i2K1pUQa95qSnBi38nRWu4owlyJagZedr0nOs5ueyyy8pyv2lykmhmZmZmCXWTJCrliSaIosa5ql2oRf379wcaThAXXXRRICyEfuWVVwIwfvx4AI4//vjMdTt16gSEvel8KV0h4k1x0xJt/BuV1pKIqsPTDFQtB5V2kqgaxFzptFKQNBLEhqSdeKmuValHnGYhRxNEUTqm5ds++OADINQZqgl8dDapZoLqMxJv0B5txlxP9t57byDMslYdIsCll14KhJnYpaTlPsslWrOqBRCkRPVcef32229AMrnbddddgfSaeKsZebzGTTWDaYkubQqwzDLLANmLEKTZxFrby4ZqEstFs5hffPHFCo+kdJwkmpmZmVlC3SSJmpGp2brROrU0EsT4rPC0Z4lrZm+uuir1CXzooYeAkBKqJkSzo3LNbtPeruo1VbuhPpHR2az5etUpwXn33XcBePjhhwt7UM3Ut2/fstyPPPLII0Dzlj1siJ7r+LJ4SjShtLOY47T3W65l+aK9PtWLMl6ztuSSSwIhActFqZiSQ9UzauawZhSrRgzg2muvzXl/SyyxBBCWsysV9Z7U/SntVK1ifLm+tMw555xA7mTnscceA9JJElXvmGs7mfa2U9s/3Y9m2qqGb9111y3p/WlWs+o9F1hgAQC23nrr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ZmZmZlYc/0g0MzMzswT/SDQzMzOzBP9INDMzM7ME/0g0MzMzswT/SDQzMzOzBP9INDMzM7ME/0g0MzMzswT/SDQzMzOzBP9INDMzM7ME/0g0MzMzswT/SDQzMzOzBP9INGshunTpQpcuXRg/fjzjx4+v9HDMzKzK+UeimZmZmSXMWukBWPlMmzYtc3qRRRYB4PTTTwfg8MMPB6Bdu3blH5ilatKkSQBMnDgRgOHDhwPQrVu3io2plIYMGQLAHHPMAcB+++1XyeFYFRg5cmTm9CWXXALAU089BcAHH3wAwNJLL132cZnJyy+/DEDPnj0BuOuuuwDYdNNNKzamXJwkmpmZmVmCk8QmmjJlCgD9+/cHYOjQoQDss88+metceOGFAMw///xlHl3D5pxzzsR5p512GvC/ejWAbbbZppxDKpv7778fgN69e2edP3r06MzpatuDK5V//vmnwf/Xur59+wKw9tprAy0vSbz00kszp++77z4AnnzyyUoNp6KefvppAPbaa6/MeT///DMAM800U0XGVIwBAwYAcPbZZwMhBV1//fUrNaSK++GHHwBo27YtAN27dwfgzjvvBGCppZaqzMCKdNJJJwHw/fffV3gkDXOSaGZmZmYJThILpD107eG9/fbbALRq1QqAb775JnPd2WabrcyjK0y177GkSY89niaoLgTqN0kcN25c1v8XWmihCo0kXW+++WbWv506darkcFL33nvvATBw4MDMedHtUEv06aefAiE9rDX33nsvEBJEba/effddoGUmidtvvz0Ar776atb52q5dc801AJxzzjnlHVgzvfPOO5UeQkGcJJqZmZlZgpPERkydOhWABx54AAgJomy33XYA3HLLLeUdWBEef/zxSg+hYq699tpKD6Fixo4dm/X/Hj16VGgk6frxxx8B+Omnnyo8kvJ48cUXgez0cLnllqvUcCrqqKOOAhreDut9v8ACC5RlTMX46quvgPqvI1aN+PTp07PO32qrrTKndfTuwQcfBOCPP/7IeVv63L///vuZ85ZddtnEedHzrXBOEs3MzMwswT8SzczMzCzBh5vz+Pzzz4EQf6sRsdrIXHDBBQDsuuuuFRhdceLRe0vw3XffAS170k69t0Opt0NxhXrooYcS50UP17UEanlz+eWXA7nb3Ogw8xNPPFG+gRVJ48/3b73Ycsstc54/yyyzZE6rjZFe2wkTJmRdd8MNNwRCC6jo30o1H16ule2Wk0QzMzMzS3CSmIf2XpQgipb+2mCDDYDaWsbu2WefTZyndj219Dia4q233sr6t6VQywwIrVKUgrdu3boiYyolFbND/aYtjVESEU0k/v7770oNp6wefvhhAPbYY4+cly+55JKZ0yNGjCjHkEpivfXWA5Ip09VXXw3AQQcdVPYxpWHWWRv/6fHGG28Aycmi2o7tvPPOQO4EsRbUyvbKSaKZmZmZJThJJCy1p6adkKx/0B7eHXfcAUCHDh3KNLrm++ijjwB47bXXEpdpiaN11123rGMqlyFDhjR4+eqrr16mkZTX+PHjM6fVOmKxxRYDYIUVVqjImEqpa9eulR5CxeVKUOu9JlFNsgcNGgSEpdrijjjiiMzpNm3apD+wEllxxRWB5Gs788wtL8+5+eabAfjtt9+yzt9ss80AOOSQQ8o+pjQoVZ199tkrPJLcWt47z8zMzMwa1aKTRNV9TJo0Ccheok306/7UU08FaitBlBkzZgDwyy+/JC5bfPHFyz2cslBT2ldeeaXB69XrUnz33HNP4rx6Spnat2+f9zI1Tl9zzTXLNZyymjZtGpB71roaC9cTzWAGuOSSSwB45plncl535ZVXBsIiB7VKR65y1ZHXM30XQ5gXIIsssgiQnRLXAzV3r9ZFDpwkmpmZmVlCi04SBw8eDIQlnXLRgvELL7xwWcZUbptsskmlh5AKJYnRPdMozU6v11qfXIvH77TTThUYSfriM0FVt1avdGRAy/FFl+Kr1jSiOaIdJkaOHJnzOp07dwbgscceA6p76b1CqDbxueeeq/BIykN10wMHDsyc9+eff2ZdZ+211wbq5ztL261qn+Vcn9+QZmZmZtYsLTJJnDp1KpDswD/PPPNkTqsj/Lzzzlu+gVXAMsssU+khpGLUqFENXt6/f3+gdnts5aP3tlKmqOj7u54suuiiQOhSUO8uvvhiICQRq666auayWprJ2xj1x4umS/lSl3pJEOXee+8FamdVjuZSQnzLLbfkvc4pp5xSruGkJnpk66effgKqf7vsJNHMzMzMEvwj0czMzMwSWtThZhXHrrPOOgB8/PHHWZdHp9zvvffe5RtYyoYOHQrkPnRRr020G1uGr1OnTmUaSXmNHTsWgK+//jpznpYoi05wqCdanuvSSy8F4LPPPgNCy6e55567MgNLWbUXvBdLE1XUxkaT0CA8ZrUmO/bYY4H6OcwsWthB7Zzq1YcffgjA2Wefnfc6J554IgCrrLJKWcaUJk2EhTDBbvfdd6/UcAriJNHMzMzMElpUkqhF4eMJovZYt91227KPqRxyLd9VrwXRmrDxyCOP5LxczcPnmGOOso2pnHK1CJlzzjkBmGuuuco9nLKIL6344osvAmEywzbbbFP2MaVp2LBhWf+vl4RYE1W0PY6mLnFKEM8666z0B1YBV199NVC/abGMHj0agFdffTXvdU466SSg/iYZipbGrVZOEs3MzMwsoUUkie+++y4Au+w7pZ7yAAAgAElEQVSyS9b5ahehqfX12u5m8uTJlR5C2aju9Msvv8x5+UYbbQRU/95bsT766KPEeRtvvHEFRlI+aiAdT8e1nFu9JYlqc6SUSe26ap2O5HzyySdZ57ekWmrJdfSnnvz2228AjBkzJu91VGtcr0dAaoWTRDMzMzNLaBFJ4nnnnQfA77//DkCrVq0AOOiggwBo3bp1ZQZWJqrNitKM1wUXXLDMo6msww47rNJDSIUS1Hi9LdTvcnxx8dTloYceAuDCCy+sxHBSU2/1xEoOf/31VyD5Oi6xxBKZ03ovr7/++uUZXIXU22sc169fPwBGjBiRdX67du0yp9VYe7bZZivfwCzBSaKZmZmZJdRtknj44YdnTt90001Zl6mGRwljvXr22WcBmD59euKyDTfcEMjec6sHesxxyy+/PJCdStST1157Dcg9I3T++ecv93CqQteuXSs9hFQoadN7etlll63kcIqm/odbb701AF988UXO6/Xu3TtzetCgQekPrArUa03iX3/9BeSfzdy5c+fMafXCrCdKy2uJk0QzMzMzS6i7JFG9tu66667EZT179gTg5JNPLuuYKuXbb78FQi1mlDr61xv1yItT6lJvKzOIZvKKak7jp+tR+/btAejVqxcAo0aNAvInU7Xqvffey/q/EuJaTYoHDhwIhG12PvW6rWqI6uWvueaaCo+ktO655x4AXnrppazz1W3ixhtvLPeQyipXgqpVZ6qVk0QzMzMzS/CPRDMzMzNLqJvDzb/88gsQCpu//vrrxHXOOOMMAFZdddXyDawK5Cp+3mqrrSowknT8+eefmdNaerGlGT58eNb/ow1otZzV33//DcDMM9fXvuGss/5vM6blB9U+5Mcff6zYmNIwZcqUrP/X4sSc999/P3P6sssuy3kdTcSZNGlSWcZUzept4sqQIUNynq8FLep1YqGojADgkksuAUKrLj03hxxySPkH1oD6+rYwMzMzs5KomyTx1FNPBeDmm29OXKbzVltttbKOqZppCayjjjoKCC1xatGwYcMyp/OlDx988AEA33zzDVC7xf75xFOmd955J3O6Q4cOQGiTU6976/G2IRMmTKjkcErulVdeAUJSOm7cuEoOpyiauAD5UzKlSi2ZXmP9G20DVIt0tCc++UpHNXbYYYeyj6kStC0G2GuvvQAYPHgwECZdOkk0MzMzs6pX80niTz/9BMBzzz2Xdf7iiy+eOa3WN6rNMhg7dixQH+1RCmm6uswyywD1lyDKYostBsDkyZMBWGWVVTKXqSWMrmO1SXXExx13HFCbtaXRxKh///5Zl3Xv3h0I2+uWLJ6Kjxw5EoABAwZUbEzNscUWWwDw+eefZ52/8847A/V7dKMhqqGudrW3lTEzMzOz1NV8kjh16lQAXn755azz+/btmzldrw2UG6O9s/XWWw+A5ZZbLnPZWWedBcDCCy9c/oGV2E477ZQ5/cgjjwDJpqz1PqM9nqS3RH369AHg9ddfB+qvti36+a1VCy64YOZ0jx49gNAI/uCDDwZa7vY6Kl6TqOU29Z6O1tdXa7PxaNeJ+HJ0ap699957l3VM1WTjjTcG4IILLgBgqaWWquRw8nKSaGZmZmYJM2lPpUo0eTCarbruuusC0LFjRyC7X576qFn9u/POOwHYbbfdADj66KOB0D/T7wWrdW3atAFCram2fVY/Hn30UQC23HJLIBwNuuiiiwBYffXVKzOwJoguB3v77bcDIe1XbWqu5XOtbApqwukk0czMzMwSaj5JNDMzM7MmcZJoZmZmZsXxj0QzMzMzS/CPRDMzMzNL8I9EMzMzM0vwj0QzMzMzS/CPRDMzMzNL8I9EMzMzM0vwj0QzMzMzS/CPRDMzMzNL8I9EMzMzM0vwj0QzMzMzS/CPRDMzMzNLmLXSAyinXXbZBYC7774bgLZt2wKw++67A9CtW7fMdbfffnsA5p133nIOsSSuv/56AG655RYgPO6+fftmrrPssssCcMIJJwBwwAEHlHOIqbnhhhsAGDJkCACbbLIJAD169ABg7bXXBmDOOecEYLbZZiv3EC1ljzzyCAD33XcfAFdffTUAAwYMyFznzDPPLP/ALHV//vknANOnT8+cp8/4PPPMU5ExmTXFY489BsDHH38MwHrrrZe5bJZZZgHC93c5OEk0MzMzs4SZ/vnnn0qPISrVwVx88cUA3H777QC88sorAMw000yJ66600koAHHHEEQAcdNBBaQ6tJC655BIgpIPaq5boa63HPOus/wuTV1xxRQAGDx4MwLrrrpvuYFMybNgwAA499FAAfvjhByA8dj1uJYwnnXRS5m+VMs4xxxzlGWwRfv75ZwDeffddAAYOHAiE1EyPU68nwFlnnQWEdLzePPPMMwCcc845ADz66KNAeK3jrz2Eown1+pzIX3/9BYRtgbaBv/zyCwBrrbVW5ro9e/YEcm8PK0nveYApU6YAMG7cOACefPLJrOt+/fXXAIwYMSJz3pJLLgmE98Vyyy2X2lgL8eCDDwKw6KKLZs6bMGECADNmzMi6bq73LsCYMWMyp/XZ33XXXYGwDZTjjjsOgLFjx2bOe+qpp4oevzz77LM5b0ufw19//bXg21pqqaUA+M9//pM5b999923eAGvMSy+9BECvXr0A+O6774Dw/oXw3aTXWO/lueaaq5i7LOiD7iTRzMzMzBL8I9HMzMzMElrU4WZRDP7TTz8BMHLkyKx/AR5//HEAfv/9dwAOPvhgAK688spyDLEoJ598MgDnnXdezstzHW6O69ixIxCeiy5dupRyiGXz9ttvA+EQy9lnnw3AV199BYTD0FGbbbYZEA7XV8vh53feeSdzeocddgBg0qRJQPJwVK7DU4svvjgQDtEtsMACKY84PTr0qENaEA656zFvvvnmAGy33XYATJ48GQjvAQgTm2qhjKQYep5UdnHrrbc2+jea7NG6dev0BlaE/fffP3N66NChRd+ODtudccYZAOy1117NGldT6X2pbVKrVq0yl2m7lK9EqNQlACpDaA5N/jr11FOzztd3hh5vLu+99x6QXRYA2Y9TkymPP/54AJZZZplmjri67bfffgDcdNNNBf/NiSeeCGRv25rAh5vNzMzMrDgtqgWOqMhT//bp0yfrXwhFpMcccwwAd9xxBxCmnuv8WqW9PBVzy2effQaEvZlaTRI18Uj/qgj6ueeeA+CQQw4BQuIIMHr06Kx/H374YaDhPeI0jR8/HgiFzABffvklkD810+XRNPmTTz4BQpp09NFHpzjqdChNjSepENob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8ODBANx6662Zy7RHN9tsswHhV/7hhx9eziFm6hbGjh1b0ttddNFFs/5VctqzZ08AOnToUNL7K4Zm+Knubp555gGgT58+FRmP7r9t27YVuX8INYlKxXfYYQeg4Rq7n376CYABAwYAcOmllwJw4403ArDPPvukMtamUMqpuuDXX38dgB49egBhzEr+Zp01f2OGv//+G4AZM2YAcOWVVwIwcODAzHX++OMPAF544QUgJJSltMoqq2ROzzzz//bH//rrLwDefvttAJZffnkgJMCF0OM75ZRTgOz6U9Wn1SJ9Fz366KMA3HXXXQC8+OKLmessscQSAAwdOhSA9u3bl3OIqTnjjDMAOPXUUwHYaqutANhxxx0BmHvuubOu/+STT2ZOX3XVVVmX6XutmmY7a0zRND9KCaNe31w6d+4MwO67717i0VWG3td67EoZVbeome7ROsYSc5JoZnQQ37MAACAASURBVGZmZsVp0Uli3DfffJM5rbqOQw89NOs6Q4YMAULylramJIl77LEHALfddlvR96daxYcffhgINW+VcMQRRwAhCdJ7taFam8au05zb0CzZd955p9GxVxPV6On9oTrX66+/HggzKytJ7+///Oc/APTu3RuAPffcEwgpbinuA0KdrpJKpdWlFH3/6HSrVq2AkCgqYVStYrQ2UalxfBsdf39uvPHGmcu03dLzpduvZt999x0QtrV33nknAHPMMQeQPevz6aefBkJNbryuq1bp/fDDDz8A0K5duwav/9prr2VOa5st+o46+OCDSznEZvnwww+BkNjr/d4USt2feeYZoLZT81xUv6h6TdHRDij5DGgniWZmZmZWHCeJjXjllVeAUKunvm1Tp04FsmdEp0Ez4FSzIkoZIPTIU52K9kZPPvlkINQ6ROtYGqM+dErPKkG98dRHqtJJ4m677QZk167WAr0PzjnnHCDMetcM4lKkdLVmo402AsJe+vjx44HS1iZGuwqozk4pv2rp5pprLiAkZMcff3zmb04//XQgpC66jQkTJgANv4c//fRTINV6pqK8+eabmdOq81ayrfrvY489FgjJ4rzzzpv5G22P1O1BtW71lio1RvWoAGeddVbWZdWYJIpeU217tNJMU+g7OZ6g1ot4orjTTjtlLlOdbok4STQzMzOz4vhHopmZmZkl+HBzHloy6eWXXwbCoSPF4+U63JyPJiMA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OHFi0bd3zjnnAOFoQyXbGxVq5513BsL3kSac5Pq+1aIRShvL2CjbSaKZmZmZFafukkQrjBosT5gwAQj1itpba0gaSaJE6zO0B6k2JfEERU291VQ4qkOHDkBoiq4k0cxqixJVCEd9vv32WyC0TFlyySXLPi5rWHShAh3FUrP3t956Cwj18to+L7XUUpm/2WOPPYBQN1tIDa41iZNEMzMzMyuOk0SrWmoUHZ/dKZrhG2+4bGa1S0ur5pv9CXDDDTcAoUm+UyazJnOSaGZmZmbFcZJoZmZm1rI4STQzMzOz4vhHopmZmZkl+EeimZmZmSX4R6KZmZmZJfhHopmZmZkl+EeimZmZmSX4R6KZmZmZJfhHopmZmZkl+EeimZmZmSX4R6KZmZmZJcxa6QGYpem3334D4LTTTgOgbdu2AJx44omVGpKZmVlNcJJoZmZmZglOEq2unXfeeVn/XnnllZUcjpXRhAkTAHj55ZeB7Nf+zTffBOCHH34AYN555y3z6MzMqp+TRDMzMzNLcJLYgkyePDlzettttwVg1113BeD444+vyJjSMn78eCAkiL179wZgxx13rNiYqtUff/wBwAUXXADAkCFDMpe99dZbALRu3br8A2sipYJjx44FYO+99wZg2rRpAKy33nqZ677xxhsAtGrVqpxDtJS98847AKy00kqZ80aOHAnANttsU5ExWWldfPHFABx77LEAPPPMMwCsu+66FRtTKV144YUAnHnmmQBMnz49c5mOinTv3r1s43GSaGZmZmYJ/pFoZmZmZgl1d7hZh5b69OmTOe+xxx4DQtsTXbbooos2ensTJ04EoGfPngAMHjwYgB122KFEIy6fu+++O3P61VdfBeBf//pXpYaTii+++AIIhx7+H3tnHijV/P//h32LLJFdQolI1mxJlnzKTvat7GTfiUJ2skSSLcq+Z4miRLJEiI9CSUoI2dev5ffH5/c87zPbvXPvnTmz3Ofjnzv3zJmZ98ycc+ac5/v5er7atGkDwODBgwFYdtllSzOwMuTff/8FwrTs/fffD8Bqq61WsjE1hEmTJgHQpUuXlOULLLAAAOedd160rG3btskNzCSGjnHzzx9+2pZffvlSDScRdCzv3LkzAOuvvz4AY8eOLdmY8uXXX38F4NlnnwWCDQpg3nmza1ivvfYaAAsttBAACy64YDGHmDiyy/z0008A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AcChhx4KwHbbbVeyMdWVn376Kbr9xBNPAPDMM88AcP/996es+++//wJBeQPo3bs3AEcccQQA889fuF1q0qRJAPz555/Rso033jjrus899xwATz/9NAAffvhhzufTFXk6O++8MwBt27at54hLi76fnj17AjBkyJBaH7P99tsDMGrUqKKNq1BoW/3iiy+A8D0+/PDD0Tq//fYbALfddlvKY1deeWUAZs6cWfRxGpMvL7zwAgAHH3wwELbtmlhqqaUAuOyyy4o3sDLll19+AVJ/tyB8JsWYBbKSaIwxxhhjMrCSaOrNrbfeCsDQoUMBeOONNwCYMmVKycZUGx999BEAAwcOBGDs2LHRfe+++y4A88wzT8rfdOJXu8cffzwQVDgpNg1BCu1xxx0HBE8OwLLLLpv1MZ999hmQXcns0KEDAAcccAAA++23X9bnWnHFFRsy7JIjFTVdQZR3Kdv3udVWWxV9XHVh2LBh0e0PPvgACOrgmDFjgKAI10T6e821LRuTBPptuPvuuwG45557APjjjz+AsI3nw1dffVXg0ZWWOXPmADB16lQABg0alHPd//73vwBMnDgRCPu1ZkSWX355IHXG6cQTT2zQ+KwkGmOMMcaYDKwkFgF5yGbMmJGyfK211irFcAqGfBB9+vQBghonLr300sTHVBtSDgcMGADAAw88AMC3335bsjHVxnzzzQfADjvsAKQqidqm1l13XQD22msvAFq0aAHAYYcdltAoywd9l1JehXyi119/PQCLLrposgOrA/KQHnXUUdGy33//vcbHLLjggrU+b5s2bQDo27dv/QdnTD2QxxuCX/2HH36o8/OsvfbaABx55JFA6j5Sycg3fPXVVwPhGFAf1f/5559P+X+FFVZo4OgCVhKNMcYYY0wGVhLriK7u5Q145ZVXgOARgOBt01/xzz//JDHEnHz99dfR7fSMvFVWWQWA1VZbDQiZevH3cNpppwEwefJkAJo1awaEK7vdd9+9aGPPF427X79+QKhQ/v7774GGebM6deoEwEYbbZRx3+KLL17v582FFFtVrkHIMjz66KMB6NWrV8FftxL48ccfo9tdu3YFQuWufDnaBspZQRTyWcXVQ1Uq7rrrrkBQBfXe+/fvn+QQjckL+Q+lHkLtCqJmQuLH0dNPPx0IMyqFVMeS5rvvvgPgxhtvjJapOlv7/IYbbgiE32Qt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Offcc5McYmJIXTrhhBMAGD16NABXX311Scaj1//pp5+iZeuuu25JxlJJ/PLLLwAcdNBBQPB1SZWB4EPWcb9c+PTTT6PbP/74Y8oy+RXbtWuX9LCKwsyZMwG48847gdTvB1JrCBoL3333Xcr/N998MwBHH310KYaTEyuJxhhjjDEmg6pVEldbbbXo9kILLQQEBUXKSWND3geAU045JeW+jTbaCIALLrgg0TEVmieeeAII3hcpiFtvvTUAnTt3Ls3ASojUCSkq8t2J+eabDwif1e233x7dV01KYvx9SWnW1fx9990HwB577JHomL7++msAjjjiCCB1BqRbt26JjqWSeO211wDo378/EPb7bBx77LGJjKmuKEECggdc/PHHH0kPp6jcf//9QJjNS6d9+/ZJDqdkaPYGYNCgQSn3SQ0vN6wkGmOMMcaYDKpGSfz8888B+PPPPwH4+OOPo/viPh+AAQMGAKESbu21105iiCVj7NixAOy+++7RMnlClIOoK/EVVlgh4dEVFikMqnYUyiFbYIEFEh9TKXj88cej23vuuScQFMPaiG8n1cANN9wApKrnqnK/9957geQVRPH9998DMH36dCAo3pD/99WY+OGHHwA4+eSTAXjjjTeyrnfiiSdGtyvJ16fUhVatWpV4JA3n+eefj25feOGFKfctscQSACy55JIA7L333skNrATMnTsXSFW8f/7551INp05YSTTGGGOMMRlUjZKYnnsX9x1KPfq///s/IFyhx/0/1ci3334LhG4q8Yoy3VZFVSUriJ988kl0W7mIQllT6Vey1YoqOKW05IOU9KeeegqA5s2bF3xcSaIr9P322w8ImXlxdUbVlFIUS4Wqc4W6L5jAyy+/HN3W55OuIOp4dtRRRwGpVerzz1/+P3NrrrkmAMcffzwQFLZKRr5wgN9++w0ICuItt9wCwMYbbwxAkyZNEh5dsmjGIj7DKc466ywAFl544UTHlC9WEo0xxhhjTAY+STTGGGOMMRmUvw5fT+LB0Yr2EMsvvzxQ/dPNmnp55ZVXgFCkAmGauRqKFDStCCHmSJS7lF9oFHOTPo2ZDU0H7brrrkBqbFQlouIPTdkpOP3AAw8E4LLLLovWLfU0s7j77rtT/lcUlQlFiNdee220bNy4cSnraFpW27KihCoNWSQUql3JyOoVj/gRO+ywAwD77LNPomMqFYq4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8E2iMcYYY4xJ4ZtEY4wxxhiTwjeJxhhjjDEmhW8SjTHGGGNMCt8kGmOMMcaYFL5JNMYYY4wxKXyTaIwxxhhjUvgm0RhjjDHGpPBNojHGGGOMSeGbRGOMMcYYk2KZrAdgasc777wDwLnnngvAHXfcAcBbb70FwDrrrFN47emnnw7AYYcdBsAaa6zRsHGabLjvvvsAuPnmmwG48cYbi57faqutALjpppsKj3Xv3r1BozMQzmGAq6++GoB//vOfALz00ktF/x4zZgwAP/zhDwvv+eY3v9mQcTaCe+65B4AXX3yx8Njo0aMBWGqppUq+Z+DAgQBMmzatzqMzprbMmTMHgLvuuguAmTNnArD66qsXXqPn9txzTwCuueYaADbbbLO6jctKojHGGGOMSbHU//73v6zHEJPpYD766KPC77feeisAd955JxBUGDFixAgAxo8fD8Aqq6zSiCGWRErhd77zHQD+9re/VfzebbbZBoDLLrsMgD322KPGo8uWhQsXAkGVef7554EwI4uPf6kT119/PQAHHXQQACuuuGJjBltDHnnkkcLvZ599NgCPP/44AF9++WWL7x07dmzh9zPOOKP2g6sxU6ZMAWDq1KkA/P73vwdgk002AeCQQw4B4Jxzzim8Z/nll2/kEMvy6aefAjB9+nQAfvSjHxWee++99yr6jN69exd+1+esvPLKtRpiw/jFL34BhHN10aJFAPz3v/8tvEbnazklUay33nqF33/zm98AsN9++9VusDXgs88+K/yuc1Pqqc7fZ555BoBBgwYBYTXolFNOKby3c+fO9R9sjfj3v/8NBHVYqxqTJ08ueh5go402AsKql87jVVddtSFjrQdSCwFeeOEFAG655RYgfCe1dmxDOA9+/OMfAzBp0qRqhtP6f4SVRGOMMcYYU4IOrSS++uqrQPCvXHLJJYXnXnnlFQCWXnppAFZbbTUAdtllFyDM+P74xz8CsPfee9d/wGWQD+fuu+8uelwzkhNOOAGAFVZYofDc3LlzAbj//vsBWGaZ/29P1az7iCOOKPqMZuHdd98FYMKECUDw10mVSSoRpZREPdatWzcATjrpJCAoi9/61rfqtwFV8vnnnwPw85//HIArr7yy8NzHH38MQL9+/YC0Orj//vsD8MEHHwBw5plnFp6L1bc88Je//AUIxzzA22+/DYT99+1vfxsIKt2CBQuA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\n",
"text/plain": [
"<Figure size 648x648 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(9,9))\n",
"example_images = np.r_[X[:12000:600], X[13000:30600:600], X[30600:60000:590]]\n",
"plot_digits(example_images, images_per_row=10)\n",
"save_fig(\"more_digits_plot\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5.0"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y[36000]"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"shuffle_index = np.random.permutation(60000)\n",
"X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 이진 분류기"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"y_train_5 = (y_train == 5)\n",
"y_test_5 = (y_test == 5)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"SGDClassifier(alpha=0.0001, average=False, class_weight=None, epsilon=0.1,\n",
" eta0=0.0, fit_intercept=True, l1_ratio=0.15,\n",
" learning_rate='optimal', loss='hinge', max_iter=5, n_iter=None,\n",
" n_jobs=1, penalty='l2', power_t=0.5, random_state=42, shuffle=True,\n",
" tol=None, verbose=0, warm_start=False)"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.linear_model import SGDClassifier\n",
"\n",
"sgd_clf = SGDClassifier(max_iter=5, random_state=42)\n",
"sgd_clf.fit(X_train, y_train_5)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ True])"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sgd_clf.predict([some_digit])"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.9502 , 0.96565, 0.96495])"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.model_selection import cross_val_score\n",
"cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.9502\n",
"0.96565\n",
"0.96495\n"
]
}
],
"source": [
"from sklearn.model_selection import StratifiedKFold\n",
"from sklearn.base import clone\n",
"\n",
"skfolds = StratifiedKFold(n_splits=3, random_state=42)\n",
"\n",
"for train_index, test_index in skfolds.split(X_train, y_train_5):\n",
" clone_clf = clone(sgd_clf)\n",
" X_train_folds = X_train[train_index]\n",
" y_train_folds = (y_train_5[train_index])\n",
" X_test_fold = X_train[test_index]\n",
" y_test_fold = (y_train_5[test_index])\n",
"\n",
" clone_clf.fit(X_train_folds, y_train_folds)\n",
" y_pred = clone_clf.predict(X_test_fold)\n",
" n_correct = sum(y_pred == y_test_fold)\n",
" print(n_correct / len(y_pred))"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.base import BaseEstimator\n",
"class Never5Classifier(BaseEstimator):\n",
" def fit(self, X, y=None):\n",
" pass\n",
" def predict(self, X):\n",
" return np.zeros((len(X), 1), dtype=bool)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.909 , 0.90715, 0.9128 ])"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"never_5_clf = Never5Classifier()\n",
"cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import cross_val_predict\n",
"\n",
"y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[53272, 1307],\n",
" [ 1077, 4344]])"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.metrics import confusion_matrix\n",
"\n",
"confusion_matrix(y_train_5, y_train_pred)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"y_train_perfect_predictions = y_train_5"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[54579, 0],\n",
" [ 0, 5421]])"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"confusion_matrix(y_train_5, y_train_perfect_predictions)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.7687135020350381"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.metrics import precision_score, recall_score\n",
"\n",
"precision_score(y_train_5, y_train_pred)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.7687135020350381"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"4344 / (4344 + 1307)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.801328168234643"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"recall_score(y_train_5, y_train_pred)"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.801328168234643"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"4344 / (4344 + 1077)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.7846820809248555"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.metrics import f1_score\n",
"f1_score(y_train_5, y_train_pred)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.7846820809248555"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"4344 / (4344 + (1077 + 1307)/2)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([161855.74572176])"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_scores = sgd_clf.decision_function([some_digit])\n",
"y_scores"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"threshold = 0\n",
"y_some_digit_pred = (y_scores > threshold)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ True])"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_some_digit_pred"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([False])"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"threshold = 200000\n",
"y_some_digit_pred = (y_scores > threshold)\n",
"y_some_digit_pred"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [],
"source": [
"y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3,\n",
" method=\"decision_function\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"노트: 만약 사이킷런 0.19.0 버전을 사용하고 있다면 `method=\"decision_function\"` 옵션으로 `cross_val_predict()` 함수를 사용할 때 이진 분류에서 1차원 배열이 아니고 2차원 배열을 반환하는 [버그](https://github.com/scikit-learn/scikit-learn/issues/9589)가 있습니다. 사이킷런 0.19.1로 업그레이드하거나 다음 셀에서 y_scores\\[:, 1\\] 처럼 두 번째 열만 사용해야 합니다."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(60000,)"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_scores.shape"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [],
"source": [
"# hack to work around issue #9589 introduced in Scikit-Learn 0.19.0\n",
"# if y_scores.ndim == 2:\n",
"# y_scores = y_scores[:, 1]"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.metrics import precision_recall_curve\n",
"\n",
"precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):\n",
" plt.plot(thresholds, precisions[:-1], \"b--\", label=\"정밀도\", linewidth=2)\n",
" plt.plot(thresholds, recalls[:-1], \"g-\", label=\"재현율\", linewidth=2)\n",
" plt.xlabel(\"임계값\", fontsize=16)\n",
" plt.legend(loc=\"upper left\", fontsize=16)\n",
" plt.ylim([0, 1])\n",
"\n",
"plt.figure(figsize=(8, 4))\n",
"plot_precision_recall_vs_threshold(precisions, recalls, thresholds)\n",
"plt.xlim([-700000, 700000])\n",
"save_fig(\"precision_recall_vs_threshold_plot\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(y_train_pred == (y_scores > 0)).all()"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [],
"source": [
"y_train_pred_90 = (y_scores > 70000)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.8659205116491548"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"precision_score(y_train_5, y_train_pred_90)"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.6993174691016417"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"recall_score(y_train_5, y_train_pred_90)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def plot_precision_vs_recall(precisions, recalls):\n",
" plt.plot(recalls, precisions, \"b-\", linewidth=2)\n",
" plt.xlabel(\"재현율\", fontsize=16)\n",
" plt.ylabel(\"정밀도\", fontsize=16)\n",
" plt.axis([0, 1, 0, 1])\n",
"\n",
"plt.figure(figsize=(8, 6))\n",
"plot_precision_vs_recall(precisions, recalls)\n",
"save_fig(\"precision_vs_recall_plot\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ROC 곡선"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.metrics import roc_curve\n",
"\n",
"fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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AyeeeGLUYYmIiKQk5l1UasOpj2XLllFQUMDkyZMB6Ny5s5IbERFpUuKd4EQdQBNz+PBhrr32WoqKijj77LOZOnVq1CGJiIjUS7wTHGU4Kdu2bRt9+/Zl3rx53HLLLZSUlHDmmWdGHZaIiEi9xHoMjqkNJ2WtWrWisrKSZ555hksvvTTqcERERI5LrFtwpGb79+/nxz/+MZWVleTn57N161YlNyIiEguxTnDURVW9F198kV69enHbbbexceNGAHJyYv2fg4iIZBE90bJMZWUlM2bMYMCAAeTk5LB27Vr69esXdVgiIiJpFesxOJXuUYfQ6BQXF7Nw4UJGjhzJvHnzNCOxiIjEUqwTnBPU5fIpd8fMKC4uZsCAARQXF2ueIBERia1YJzjNcvUA/+STT5g6dSrNmjVjxowZDBw4kIEDB0YdloiISEbFuokj21so3nzzTfr378+9997LoUOHcHXZiYhIloh1C05uTvYmOA8//DDXXnstubm5PPbYY4wYMSLqkERERBpMrBOcbM1vdu3aRXFxMX369GHx4sV06dIl6pBEREQaVMwTnOzKcHbt2kV+fj75+fmsWbOGPn36cMIJsa5iERGRY4r5GJyoI2gY7s59991Ht27dWLZsGQAXXnihkhsREclasX4CZkMLzvvvv09xcTG//e1vueyyyxg0aFDUIYmIiEQu1i04cR9kXFJSQq9evXj66aeZNWsWTz75JKeeemrUYYmIiEQu1i04cW/A2b17Ny1btqS0tJTevXtHHY6IiEijYXGdG6XFaWf5O3/cyimtW0QdSlrt2rWLTZs2MXz4cADKysrIy8uLOCoREZH0M7NN7t6nPufGuosqbmNwnnjiCXr16sW4ceP48MMPAZTciIiIHEPME5yoI0iPsrIybrzxRoYPH07Xrl1Zt24drVu3jjosERGRRivWY3DiMMi4vLycwsJCNm/ezKRJk5gxYwYtWsSr201ERCTdYt2CE4e1qFq0aEFRURFPPfUUM2fOVHIjIiKSglgnOE3VwYMHueqqqygpKQFg6tSpXHbZZRFHJSIi0nTEOsFpiu03L730Eueffz5Llixhy5YtUYcjIiLSJMU7wWlCGU5lZSX33HMPF110ERUVFTz33HNMmDAh6rBERESapFgnOE3J0qVLmTJlCsOGDWPz5s30798/6pBERESarFi/RWVNoJNq3759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\n",
"text/plain": [
"<Figure size 576x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def plot_roc_curve(fpr, tpr, label=None):\n",
" plt.plot(fpr, tpr, linewidth=2, label=label)\n",
" plt.plot([0, 1], [0, 1], 'k--')\n",
" plt.axis([0, 1, 0, 1])\n",
" plt.xlabel('거짓 양성 비율', fontsize=16)\n",
" plt.ylabel('진짜 양성 비율', fontsize=16)\n",
"\n",
"plt.figure(figsize=(8, 6))\n",
"plot_roc_curve(fpr, tpr)\n",
"save_fig(\"roc_curve_plot\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9624496555967155"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.metrics import roc_auc_score\n",
"\n",
"roc_auc_score(y_train_5, y_scores)"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.ensemble import RandomForestClassifier\n",
"forest_clf = RandomForestClassifier(random_state=42)\n",
"y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3,\n",
" method=\"predict_proba\")"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"y_scores_forest = y_probas_forest[:, 1] # 점수는 양상 클래스의 확률입니다\n",
"fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5,y_scores_forest)"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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E5ydQJNcZU2C5TmY2dnAl8A459zUUE6+Zg18991pxyjFUKtWLerVq8c777zDlClTqFWrltchiYhIJeNlgvMJ0M7MLgAws0uAc4G5ZvaNmbUMljclkNw87Zx7L9STV68ONWqUQtSSp7S0NEaOHMnOnTsJCwtjxowZ3HrrrV6HJSIilZRngyKccylm1ht4y8wcge6p/wZqAE2B6GDVcUAMMMLMRgTL0pxznQo6//nna6mGsrJx40b69OnD8uXLadq0KUOHDvU6JBERqeQ8HfXpnJsH5JWGNMpW56ayi0iK6t1332XYsGFERETwj3/8g549e3odkoiIiH9nMpbS98Ybb3DbbbcRGxvLypUrldyIiEi54dvndlevhmXL4KKLvI7Ef06cOEGVKlXo27cvqamp3HvvvVSpUsXrsERERLL4NsFJS4Pjx72Owl8yMzN5+eWXSUxM5OuvvyY6OpoHHnjA67BExAOHDh0iOTmZ9PR0r0ORCig8PJwGDRoQFRVVatfwbYLTti1ceKHXUfhHcnIy8fHxzJ49m169epGWlkZERITXYYmIBw4dOsTevXtp2LAhkZGRmJnXIUkF4pwjNTWVXbt2AZRakuPbMTgRERAZ6XUU/vDll1/Svn175s6dy1//+lc++ugjoqOjCz9QRHwpOTmZhg0bUqNGDSU3UmRmRo0aNWjYsCHJycmldh3ftuBIycjMzGTEiBHUrl2bzz//nHbt2nkdkoh4LD09nUj9BSmnKTIyslS7OH2b4OzcCdu3Q5PccyVLSLZt20adOnWIiori448/pl69epxxxhlehyUi5YRabuR0lfb3kG+7qPbuhT17vI6iYvrwww9p3749w4cPB6BJkyZKbkREpELxbYLTqJFab4oqNTWVu+66i969e9O6dWtGjRrldUgiIiLF4tsEJyYGzjrL6ygqjg0bNnDxxRczYcIEHn74YZKSkjjnnHO8DktERKRYfJvgSNHUqFGDzMxM/vWvfzFmzBiqVavmdUgiImVq8uTJXHzxxURFRdGgQQO6dOnChx9+mKNOWloar776KnFxcURHR1OrVi3atm3LoEGD+P7777PqNWvWDDPDzIiIiKBRo0Zcf/31TJs2jRMnTpT1W6uUfJvgHD4c2CR/P//8M88//zyZmZk0btyY1atX061bN6/DEhEpcy+88ALDhg2jX79+/N///R9Tp06lc+fOJCQkZNXZu3cvcXFxPP7443Tt2pVZs2Yxb948Ro4cyfr16xkyZEiOc/bt25f//Oc/fPPNN7z22mvExMQQHx9Ply5dOHToUBm/w0rIOefLDTq6Zcuc5GPhwoWuadOmrmrVqu7bb7/1OhwRqUDWrl3rdQglrn79+m748OGnlB8+fNg551xmZqa78sorXdOmTd2WLVvyPMenn36a9XXTpk3d3XfffUqdhQsXuho1ari+ffuWTOAVXGHfS8ASV8w8wLctODVrBjbJKTMzk+eee44rr7ySsLAwFixYwCWXXOJ1WCIinjp+/Hiec7LUDH6QzJo1i6SkJN58802aNWuW5zmuu+66Qq8TFxfH6NGjSUxMzNGlJSXPtwlO69bQsqXXUZQ/t99+O6NGjeKmm25i+fLl/O53v/M6JBERz11++eVMmjSJTz75JM/9H374IS1btqRLly6nfa1bbrkF5xxz5sw57XNJ/nyb4EhOgZa+QIIzadIkpk2bpuUWRKREmQW27Hr2DJTNmvVr2cSJgbLsQ1Z27w6U/eY3OY/v2DFQvnTpr2UJCYGybMNjcuwvjvHjx1O/fn169epFbGwsH3/8cY79a9asITY29vQuEtS4cWOio6PZtGlTiZxP8qYEx+d++eUXHnrooaw5ba666iruuOMOzUIqIpJNq1atWLlyJaNGjeL777/nhhtuoFOnTvz4449AYIHR3H8UTpw4kapVq2ZtHTp0CPl6NWvW5OjRoyX6HiQn3yY4y5fDxo1eR+GtTZs2cfnllzNu3DgOHz6c1YojIlIanAts2c2aFSjr2fPXsiFDAmUTJ/5a9pvfBMp27855/NKlgfKOHX8tS0gIlGVvwcm+v7hq167NM888w/bt23n44YdZsGABV111FcePHycqKoqUlJQc9Xv37s2KFStYsWIFPXr0ICMjI+RrpaSkULdu3dMPWvLl27WoMjNPbSqtTN577z3uuusuqlSpwowZM7jxxhu9DklEpEKIjo5mzJgxNG/enKFDh/LRRx/Rpk0bVqxYkaNenTp1qFOnDhBIjkK1adMmjhw5Qvv27Us0bsnJty04F14Iv/2t11F4Y8eOHdx+++20a9eOFStWKLkRESmG/v37A7B9+3Z69uzJmjVrWHq6g32ASZMmERUVRffu3U/7XJI/3yY4YWGBrTLZsWMHEBjANn/+fObPn0/Tpk09jkpEpHxLTk7m888/P6X85GPcLVq04MYbb6Rt27bccccdHDx4sNjX+vTTTxk3bhxPPfVUkVp9pOgqWQrgT845Xn31VVq0aJE1rfill15K1aq+7YEUESkxx44do0ePHgwbNowvvviCpUuXMm3aNPr168d5551Hz549CQ8PZ8aMGRw4cID27dvz0ksv8c0337Bs2TLGjRvH9OnTCcv1V/WBAwdYvXo1S5Ys4YMPPqBPnz7ccMMNPProo9x3330evdvKw/w68LRu3Vj3/fdLqFfP60hK1/79+7n99tv5xz/+wXXXXcfkyZOpX7++12GJiI+tW7eONm3aeB1GiXHOMXHiRN5++21++OEHDh8+TOPGjenVqxcPP/ww9bJ9kKSkpDBu3DhmzpzJDz/8QGZmJq1ataJHjx4MHTqURo0aAYG1qLZt2wZAZGQkTZo0oXPnzgwdOlRjb7Ip7HvJzJY654r1fL5vExyzWLdr15JT5lTwk6SkJPr168fevXt54YUXuO+++/T4t4iUOr8lOOKd0kxwfNuH0bw5BAe3+9bOnTuJjIxk0aJFXHTRRV6HIyIiUm74dgxO3boQGel1FCVvx44dWTNs9u3bl1WrVim5ERERycW3CY4fffLJJ3To0IHBgwdz5MgRACIiIjyOSkREpPzxbYKzfz/88ovXUZSM48ePc88999CrVy+aNWvGwoULs1a4FRERkVP5dgzO1q1w/DhUq+Z1JKcnLS2NuLg4VqxYwQMPPMBzzz1H9erVvQ5LRESkXPNtC07duhAe7nUUp6969er07t2bTz/9lJdeeknJjYiISAh8m+A0b15xBxkfOnSIW265haSkJABGjRrFdddd53FUIiIiFYdvE5yK6rvvvuPCCy9k2rRprFq1yutwREREKiTfJjgnTkBFmsMwMzOTF198kcsuu4yMjAy++uor7r77bq/DEhERqZB8m+CsWAGpqV5HEbrp06czYsQIrr/+elasWMHll1/udUgiIiIVlm+foqpSxesIQnPw4EHq1KnDH/7wByIiIvif//kfLbcgIiJymnzbgtOhA9So4XUU+UtPT2fkyJG0atWKnTt3EhYWRq9evZTciIiIlADftuCUZ1u2bKFfv34sWrSIIUOGULduXa9DEhGptGJjY1m6dGmOsrFjx/LQQw8RHx/Pzz//zMcff0xCQgIffvghq1evBiAhIYEnn3wyz3POnj2ba6+9FoD4+Hi2bt3K/Pnz841h9+7dHDp0qNBYGzVqlDXR6759+9i3b1+O/U2aNKFGjRps3bqV5s2bk5SUREZGBldffTVbtmyhWbNm+Z77ggsuoGPHjrz99tsFxpDXdXOLjo7m7LPPLvT9lCYlOGVs+vTpDB48GDNj+vTp9O7d2+uQREQqtY8//pjjx49nve7cuXPIx5555plZU3pk17hx4yLFMHz4cN5///1C682cOZNevXoB8PLLL/PMM8/k2D9v3rwixZ9dcnIy9evXL7ReXtfN7bbbbis0USptvk1w1q8PLNVQ3mYynjlzJueddx7Tpk0rMJMWEZGy0ahRoxyvq1YN/aOxSpUqnHvuuTnKUlJS2LFjR47XhUlMTCQxMZEZM2YQGxtL06ZNs/Z9/fXXREZGcvHFF+c45s9//jN//vOfAbJabIpr/fr1JCcnk5ycHFL93/72t2zatKnY1ysLvk1wjh4tP4+Jr169mmrVqtGqVSv+9re/Ub16dcL9MM2yiIgP7NmzJ0cLTkZGRo79W7Zs4bXXXmPx4sUhne+DDz5g8ODBOco6deoU0rF9+vTh9ddfZ9CgQVllo0ePpk2bNqckOCXplVdeoW7durz33nsMGDCArl27Flj/xIkT7Ny5M9/9devWpYbHA2F9m+C0bu39Ug3OOSZMmMADDzxA586dmT17thbJFBEpZ/r06cNXX32V7/4ffviB1157jX379nHWWWcVer5BgwblSFBOjsEJRfXq1fkl10rRqampeSYLhw4dyhq3s2fPnqzyWbNmFZh85DZ79mwmTJjAe++9x5o1a7j55ptJSkqibdu2+R6zdevWArvhJk+eTHx8fMgxlAbfJjg1a0KYh8+IHTx4kMGDBzNjxgy6devmeV+kiEhpajbyM69DAGDr88Vb1qagMSNdunTJMcg4uxMnTmR11WRkZHDkyBH27t3L5s2b2b17N88//3yR4sgvwTnjjDNOqfvSSy/lOcj56aefDqmryTnHm2++yT333MN9993HzTffTEZGBmvWrOGaa65h6tSp+bbkqIuqktq4cSNdu3Zl9+7djB07luHDhxPmZbYlIiIF+uWXX9i7dy8pKSkcPHiQLVu2hDTgdt++fbRs2TLrdUREBPXr16dZs2bExcWFfP1NmzaRkZFBlSpV2LNnT47k4ciRIxw9epT169dTr169HHE1adKENWvWZL2OjIxk8eLFhY7JSUxM5Nlnn2XdunUkJCQwevRoIDD+KDExkaFDh9KtWzf69+/PiBEjaNeuXcjvpbzwbYKzZw9kZnrTitOkSRMuuugiPvjgAy655JKyD0BEpIwVt+WkvJg2bRrTpk0jLCyMBg0a0KpVK4YNG1bgMY899hgjR44EwMyoWrUqVYo5y+yll17K/v37ARgzZgxjxozJsX/8+PGMHz+eBx98kBdffDGr3MyKNfRh1apVnHPOObz77rt06NAhx77w8HAmTZpEjx49eOKJJ1iyZMkpCc7mzZsLnLetdevWrF+/vshxlSTfJji7dpXtIOPdu3czevRoxo8fT1RUFDNnziy7i4uISLF99NFHpKenU61aNaKionIkKbNnz873uKpVq1K1alVSUlL48ccf8613yy23FPpkVu55ZZ5//nkSEhJyDH4uSc8++2yhdXr16pX1SHp2999/PwMGDCjw2OrVqxc7tpLi2wTnrLOgrCYF/uyzz4iPj+fYsWPceuutXH311WVzYREROW0nJ1tNS0vj4MGDnHnmmUU6fubMmQwcOLDAOp06dSpwor/iSk9PZ926daSmprJnzx42bNjAxo0beeSRR0r8WiedeeaZRf4/8oJvE5yGDUu/eyotLY2RI0fy8ssv065dOxITE2nTpk3pXlRERErFtGnTGDhwIOnp6VktLoMGDcoa9Fu7dm0aNmyY7/Eun26Dgp6iOnDgAAcOHDilfP/+/Tjn8h3Ie3J8ze7du7nggguoWbMmMTExNG/evNDHyYszODg6OpoTJ04UuUUpPDy8wP+z0uTbBKcsPPDAA7z++uv88Y9/ZOzYsURERHgdkoiIlKArrrgi6+v777+f+++/v0TP/8orr+S73AOQYwBzdj/++CMJCQkkJCTkub+gx9LzO2dB7rzzTtavX1/g4/R58XIsjm8TnNTU0jv38ePHiYiI4NFHH+Xaa6/l+uuvL72LiYhImdqwYUOBg4VbtWqV55Ox+X2QFzST8eOPP85jjz1W5BiLMttybunp6UU+JiwsjIyMDDIzM4t8nFd8m+CsXVvy5zx8+DB33303P/30E5999hmNGzcu8nojIiJSvp1//vkF7j948CC1a9c+pbygIQr5zWQcFhZW5klAcZOjauVt7aNCWH59hhVdZGSsS01dUmLnW7ZsGX369GHz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\n",
"text/plain": [
"<Figure size 576x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(8, 6))\n",
"plt.plot(fpr, tpr, \"b:\", linewidth=2, label=\"SGD\")\n",
"plot_roc_curve(fpr_forest, tpr_forest, \"랜덤 포레스트\")\n",
"plt.legend(loc=\"lower right\", fontsize=16)\n",
"save_fig(\"roc_curve_comparison_plot\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9931243366003829"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"roc_auc_score(y_train_5, y_scores_forest)"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9852973447443494"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_train_pred_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3)\n",
"precision_score(y_train_5, y_train_pred_forest)"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.8282604685482383"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"recall_score(y_train_5, y_train_pred_forest)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 다중 분류"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([5.])"
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sgd_clf.fit(X_train, y_train)\n",
"sgd_clf.predict([some_digit])"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-311402.62954431, -363517.28355739, -446449.5306454 ,\n",
" -183226.61023518, -414337.15339485, 161855.74572176,\n",
" -452576.39616343, -471957.14962573, -518542.33997148,\n",
" -536774.63961222]])"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"some_digit_scores = sgd_clf.decision_function([some_digit])\n",
"some_digit_scores"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.argmax(some_digit_scores)"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sgd_clf.classes_"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5.0"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sgd_clf.classes_[5]"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([5.])"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.multiclass import OneVsOneClassifier\n",
"ovo_clf = OneVsOneClassifier(SGDClassifier(max_iter=5, random_state=42))\n",
"ovo_clf.fit(X_train, y_train)\n",
"ovo_clf.predict([some_digit])"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"45"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(ovo_clf.estimators_)"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([5.])"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"forest_clf.fit(X_train, y_train)\n",
"forest_clf.predict([some_digit])"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.1, 0. , 0. , 0.1, 0. , 0.8, 0. , 0. , 0. , 0. ]])"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"forest_clf.predict_proba([some_digit])"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.84063187, 0.84899245, 0.86652998])"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring=\"accuracy\")"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.91011798, 0.90874544, 0.906636 ])"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.preprocessing import StandardScaler\n",
"scaler = StandardScaler()\n",
"X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))\n",
"cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring=\"accuracy\")"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[5725, 3, 24, 9, 10, 49, 50, 10, 39, 4],\n",
" [ 2, 6493, 43, 25, 7, 40, 5, 10, 109, 8],\n",
" [ 51, 41, 5321, 104, 89, 26, 87, 60, 166, 13],\n",
" [ 47, 46, 141, 5342, 1, 231, 40, 50, 141, 92],\n",
" [ 19, 29, 41, 10, 5366, 9, 56, 37, 86, 189],\n",
" [ 73, 45, 36, 193, 64, 4582, 111, 30, 193, 94],\n",
" [ 29, 34, 44, 2, 42, 85, 5627, 10, 45, 0],\n",
" [ 25, 24, 74, 32, 54, 12, 6, 5787, 15, 236],\n",
" [ 52, 161, 73, 156, 10, 163, 61, 25, 5027, 123],\n",
" [ 43, 35, 26, 92, 178, 28, 2, 223, 82, 5240]])"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)\n",
"conf_mx = confusion_matrix(y_train, y_train_pred)\n",
"conf_mx"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [],
"source": [
"def plot_confusion_matrix(matrix):\n",
" \"\"\"컬러 오차 행렬을 원할 경우\"\"\"\n",
" fig = plt.figure(figsize=(8,8))\n",
" ax = fig.add_subplot(111)\n",
" cax = ax.matshow(matrix)\n",
" fig.colorbar(cax)"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 288x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.matshow(conf_mx, cmap=plt.cm.gray)\n",
"save_fig(\"confusion_matrix_plot\", tight_layout=False)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"row_sums = conf_mx.sum(axis=1, keepdims=True)\n",
"norm_conf_mx = conf_mx / row_sums"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 288x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"np.fill_diagonal(norm_conf_mx, 0)\n",
"plt.matshow(norm_conf_mx, cmap=plt.cm.gray)\n",
"save_fig(\"confusion_matrix_errors_plot\", tight_layout=False)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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DMMwDMNIGWzhYxiGYRhGymALH8MwDMMwUgZb+BiGYRiGkTLYwscwDMMwjJTBFj6GYRiGYaQMtvAxDMMwDCNlsIWPYRiGYRgpgy18DMMwDMNIGWzhYxiGYRhGypAv0QMwcgfr16/nww8/THPb5s2bAXjsscfSPf7VV18FcB3LmzZtGuMRGoYRKc8++ywAM2fOBGDGjBnuvgIFCgBw4403AvDMM89w4oknxnmEhpF1TPExDMMwDCNlsO7sScZHH30EwKJFiwD4+uuvmTJlSsTP79mzJwBt27bluOOOi/r4duzYAcCKFSsA6NixIwBbt25lyZIlABw4cACAvHnzZvg6ekzBggUBqFq1Ku+88w4AJ510UtTHnV3WrVsHQPPmzfnqq68yfFy5cuUA6N27NwA33HBDzMd26NAhtyN/+umnAfj222/d/UWKFAHggQceSPO82267jbPOOivm4yOHd2ffvHkzEyZMAOCbb74BPMUyHIMGDaJYsWJA4LtOVpYuXQrAxIkTef/99wHcuSxFtl69elx++eUArFmzBoD+/fsDcN555/HDDz/Edcziv//+A7z5JBSFChWK13CyRI8ePULe/tRTT4V9Xp06dQD47LPPojyi2LJ7924APvjgAwAmT57Mm2++meYx1apVA2D8+PGULFkyMy9v3dkNwzAMwzD85GjFR7vaMWPGAHDvvfe6+0aPHg3A999/n+Y5ixcv5n//+x8ApUqVAnArygIFCnDmmWcCgZ09QPny5QHIly82dqjp06cDgTg5eDtKrYqzSu3atXnvvfcAohp/f/311wFo06ZNho/JjOLjf8ygQYMAeOihh7I7zKih3bD8DCtWrEDnTJ48GW8u5IPQTljHUSzYs2cPRx99dKaf17RpU2rVqgXAfffdB4T/zbJBjlZ8Fi1axHnnnZelNznqqKMAOPfccwEYOnQoABdeeGGWXi+avPDCCwC0b98egP/97380bNgQgOeeew6AY489FoD8+fO7561duxbw5s8GDRq4eSyW7N+/H4CNGzfy7rvvAt68qTGFol27dgB06tQJwKlwyUDdunX5/PPPs/UaOUH52bRpk/ONSZ3etm0bAA0bNuSWW24BApED3QaBY3PgwIGZeStTfAzDMAzDMPzkaMVHqozi0pHsxA8dOnTY+/2v8fXXXwNezDGaDBs2zHlkFKs+8sgjAahfvz4A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MqS04hMuDT5RhQslI6poodLVM0ImREnSd9xxB5A8ikNGqBCczIW7du1KeFgoHArlvfbaa8ybNw/wQpB+pKZEodpxVKhRo4aTzhWWlEE3FKq2PWrUKHebjiWZEY3Q/Pfff4BXbmLSpEnuNplmddwnA1J19Ft36dLFmWkVhghVfT3RNGrUiAULFqS5rUCBAkDge1aV9R9//BHwCgL++uuvAAlRe6QKB9sxhg8fHlLpgUBhQCn5UllU9C+nIMWzW7dunHzyyQCuaraUuERgio9hGIZhGClDrld8tMIO17PLT7IULoykbPq6deu45557AG+36S8amIyoU7KK4an/WI0aNVzH5GRALTW0Q5dZWambfuSruuqqq9xuU73IEk2JEiXCqk/qVSQDtDwI+/fvd54enUNKX01llLqu3/ndd991RTllXA3li5F3Tzv/m266KeZjPRwqLqeinOecc47boetcVNG5ZKJy5cruuF2+fHm6+9Vm5vjjjwfgtNNOA2DRokVAQM3SPK+khTvvvBOAE044ISaFU1UIUiqbWvhccMEFGT6nadOmbl5XK4gGDRpEfWzRRK19ggu/du/e3XmCpDwnkuQ7qg3DMAzDMGJEripg6CdU2fiIBpBc30catPpX3Ldt27ZOMVHTxBdeeCExgwvD2rVrXYEwxdsVk9dOa/jw4QkZW0aoSWOoho7aBd9www0APPLII2mek6xotymFYvTo0c4jJj+EOPPMM+nVqxfg+ZayQY4uYPjff/+5Haz8gKHml+AmpeHuu+mmm9xryvsQL1TC4Oqrr04ztu+++861RMgpqNCrihWeddZZ7r5KlSqleeyWLVuAQNkBfXa1ftB30KRJEze/RhM1FVUkQVm7oTycUpkffvhhpyKqIOptt90W9bFlF6k8AwcOdP/WXCNFrWTJkm4euf322wFcQc0okzrd2UOR1YWPKtdmtyZQNFGNHtWeUOVdPzIJqw9TMjFmzBhnutbvotRqSf5jxoxJzOAyINzCRyEgyc+ie/fu7kRPJpQSq7Do119/DaSt3BzM4sWL0104skGOXvjceeed7vgMt7jRcfHkk08CULZsWXdf//79gUD9HqGLtC4W8eqH9c8//wC48hHqt1ewYEGXctypU6c0j8nt1KpVCwic75MmTQICoetooSr0+u6DawuBd55q8anwKHgLCIXV69ev75IWZBLW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9G79DBcZdEuXLg0khuKjEG126Nq1qwvjqiClzpHOnTtHbnDZROrr999/D3hm7FBUrVo1Q6KFfwhPxvNEUHoADh065ELmMlrH0/Bvio9hGIZhGClDSio+yc7NN98MeDFS8Fb2l156aUzHonTXLVu2uFLxOUU7Ailw4rzzzsvRzi7WpKenM23aNCD+rSr80WenwnPZRenA/q0v8praGAlq1KgBJGYLnPXr1zulT8qAWsKEi4rB+itZ4PP+yMQdTWRAvvfee3P1OqtWrcpgRA+3TEUsUJkVeakyQ54rqTv6+7bbbnP9DmPBvn37AF8Pycw8VnPnznUqm0quxJPEO0MNwzAMwzCiREoqPvInqDN1oqOCVup8qywS/9LsallRoUKFmI5N6b0333yzayvRtGlTIHuFqQ4dOuQy6oJbVgQ3TIw0ataoMgc5LWY2bdq0TAv6lS1bNteKWCw4ePAg4CvmqIKSEyZMALzvGuDqq6+O/eCSBGW63XLLLezatQvwKaLgZSHFWsHs2rWr68audg3ZRW07glufxCpFv2vXru7/56bz+vXXX+++j7JlywKeapLoKEt02LBhPPHEE4CnkEtRqV+/vvNhRRN52+SNPf3001mxYgXgtVdSdKJFixbO06PrQzxJuYXP/v37ufXWWwFvkheJULlZFXH9015VZ0PhEy0I8uXL52TReI1dhrxKlSq5g121JoYPHx7260ycONHV2dD7K1OmDADHHntsxMbrjz7rBx98EIB33nkHCL93kdDFLdRkrIVohw4dombm++2331xNFkn2/osUEeq2YHbv3g14vY9CUaVKFbfQNjwUavjkk08Az0wMXrq0woaxXvgoTAW4C6bMsypTULNmTQoVKgR4YU2Ne+3atW4DJjp16gREv5O2UIird+/e7rNWTRiFGUOhcgyqZr9hwwZXr02LBXVwT3R03n366aeu7Mf48eMBL1khVt+H5mnNfzJlgxfOUs2nihUruu8hwpWac4SFugzDMAzDSBnyhOKjCr8y+1atWpVSpUqFfGzfvn0z7beTW9NcJFDhwXBW7bfffrt7fDwLb4FPhpZSotCUxtSxY0enTGWGfzXjokWLAl5oT39HGknEUv4WLFgA+HrmqEdXVkhBUYdoFVz0R8XIstnNPEtURViFwCZMmBCyKnOk0Y65Tp06rmJuqqDQXlaf89q1awFYt25d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ZStll7JEM43fH+f93s+ZM2fGLGedc33+Gc55Zs59nvM897nv7/W9rmvlSp577rmgx/z999+cfPLJALz88ssA3HfffZEZ4P/YvXs3AF26dAFg+fLl/Prrrxker3tA596fMmXKAPDQQw8B0KtXr5wOK09Xbt6zZw8AX3/9NYA73x07dvReLJPznJVj5s2bB0Djxo1DMOLc8csvvwBQv359AIoWLcrSpUsByJ8/f9TGZRhY5WbDMAzDMIy05EnFp2rVqqxZs8b3BzPZRWXluXr16gE+FSlWSE5OBuC7775zj1122WUA5MuXLypjCoZUkp49e7Jt2zbAO9eB595f8dFzZ5xxBgAff/wxl156aeQG7sekSZMAePTRRwGfoiJVJ5AyZcrQv39/AK655hoAKlSoEIFRekjpeeWVV4C05zUYWVEi/u///g+Ar776KqfDyrOKz5gxY3j//fcBeO+99zI87u+//wbI8No50TFz584FoFGjRjkea26ZPn06AD169ADg/PPPB2Dq1KmcddZZURtXIiA18d///jcAc+bMcXP+HXfckeHv1a1bF4DLL788zCNMy2+//QbAhRdeCMD+/fvdtTtw4MA0x5500knUqFEjVC9tio9hGIZhGIY/eUrxkRJStWpVp4ZccsklALRo0QKA8uXLs2XLFt+L/e+9y/OjFbQ/MnaWKlUqN0MLCYsXLwZgwoQJAEycONG9B+3CRowYEZWxBUOKT/v27Tl06BCQPcVH/z/99NPdjqds2bJhH/f69etp3749AD///DMA+/btA9L6eMRbb70FQJUqVSKu8ASyevVqAK699loADh06lE7Nadu2LQA333xzlv5m1apVAbjgggtyOqw8q/g0a9bM+W8Cr4vixYs7c3vgNX322WfTvHlzwPNSSVkLhuahwoULh2LYJ+TgwYOAN9eMGjXKeZfk+Ro0aBAABQoUiMiYsoq+B958882gz2fmu1u0aBGbN28GPNVU3s/zzz+fZs2anfBvhIrk5GSXbDBnzhzA+1yySrFixQAoUqQIANu3bw/hCNOjc3XjjTcCngH+RFSqVAmAypUrA9CqVSsAmjRpkt1r3hQfwzAMwzAMf/KU4qMMIf+drNJ15bmIRxRb7927N4Dzy4C3k9TKvmbNmumeC9zxly9f3qVbR4Lq1auzYsWKNGNR5lawrK7Acbds2ZKJEycCodvx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\n",
"text/plain": [
"<Figure size 576x576 with 4 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"cl_a, cl_b = 3, 5\n",
"X_aa = X_train[(y_train == cl_a) & (y_train_pred == cl_a)]\n",
"X_ab = X_train[(y_train == cl_a) & (y_train_pred == cl_b)]\n",
"X_ba = X_train[(y_train == cl_b) & (y_train_pred == cl_a)]\n",
"X_bb = X_train[(y_train == cl_b) & (y_train_pred == cl_b)]\n",
"\n",
"plt.figure(figsize=(8,8))\n",
"plt.subplot(221); plot_digits(X_aa[:25], images_per_row=5)\n",
"plt.subplot(222); plot_digits(X_ab[:25], images_per_row=5)\n",
"plt.subplot(223); plot_digits(X_ba[:25], images_per_row=5)\n",
"plt.subplot(224); plot_digits(X_bb[:25], images_per_row=5)\n",
"save_fig(\"error_analysis_digits_plot\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 다중 레이블 분류"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
" metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
" weights='uniform')"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.neighbors import KNeighborsClassifier\n",
"\n",
"y_train_large = (y_train >= 7)\n",
"y_train_odd = (y_train % 2 == 1)\n",
"y_multilabel = np.c_[y_train_large, y_train_odd]\n",
"\n",
"knn_clf = KNeighborsClassifier()\n",
"knn_clf.fit(X_train, y_multilabel)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[False, True]])"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"knn_clf.predict([some_digit])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**경고**: 다음 셀은 실행하는데 매우 오래 걸립니다(하드웨어에 따라 몇 시간이 걸릴 수 있습니다)."
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.97709078477525"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3, n_jobs=-1)\n",
"f1_score(y_multilabel, y_train_knn_pred, average=\"macro\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 다중 출력 분류"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [],
"source": [
"noise = np.random.randint(0, 100, (len(X_train), 784))\n",
"X_train_mod = X_train + noise\n",
"noise = np.random.randint(0, 100, (len(X_test), 784))\n",
"X_test_mod = X_test + noise\n",
"y_train_mod = X_train\n",
"y_test_mod = X_test"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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jvtOeq3ULD4112/GjBluntTZqDoC16xZQxcfMDjo4gMADE0UKABASBQoAEBIFCgAQEgUKABASGnv4jt48KC74dSpU+U1LS0tbl5VVeXmjY2Nbt7d3S33mDt3rptfuXLFzVUXnZnuQFMz7BoaGtx8wYIFco+6ujo3V92F6mRSM7P8/Hw3VycW//bbb26+atUqucfFixfdXL22SXP9qqur3fzBgwdurjox1ZxFM7Py8nI3z8jIoIsPGBx08QEAhiYKFAAgJAoUACAkChQAICQKFAAgJAoUACCkrHRvqNqHz58/n/Jao0aNcnPVMp7Uaq2OfB83bpybq0GqZrqdvaamxs1Vm3eSmTNnunlzc3NK92Smn8dz5865uRq+euTIEbmHGiRbVlbm5moQsJnZnj173Fw9j6otvampSe6h3g8FBQXyGgCDi29QAICQKFAAgJAoUACAkChQAICQKFAAgJDSPiwWAIC/g29QAICQKFAAgJAoUACAkChQAICQKFAAgJAoUACAkChQAICQKFAAgJAoUACAkChQAICQKFAAgJAoUACAkChQAICQKFAAgJAoUACAkChQAICQKFAAgJAoUACAkChQAICQKFAAgJAoUACAkChQAICQKFAAgJAoUACAkChQAICQ/gfa1MycECD7swAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"some_index = 5500\n",
"plt.subplot(121); plot_digit(X_test_mod[some_index])\n",
"plt.subplot(122); plot_digit(y_test_mod[some_index])\n",
"save_fig(\"noisy_digit_example_plot\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"knn_clf.fit(X_train_mod, y_train_mod)\n",
"clean_digit = knn_clf.predict([X_test_mod[some_index]])\n",
"plot_digit(clean_digit)\n",
"save_fig(\"cleaned_digit_example_plot\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 추가 내용"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 더미 (즉, 랜덤) 분류기"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.dummy import DummyClassifier\n",
"dmy_clf = DummyClassifier()\n",
"y_probas_dmy = cross_val_predict(dmy_clf, X_train, y_train_5, cv=3, method=\"predict_proba\")\n",
"y_scores_dmy = y_probas_dmy[:, 1]"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fprr, tprr, thresholdsr = roc_curve(y_train_5, y_scores_dmy)\n",
"plot_roc_curve(fprr, tprr)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## KNN 분류기"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
" metric_params=None, n_jobs=-1, n_neighbors=4, p=2,\n",
" weights='distance')"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.neighbors import KNeighborsClassifier\n",
"knn_clf = KNeighborsClassifier(n_jobs=-1, weights='distance', n_neighbors=4)\n",
"knn_clf.fit(X_train, y_train)"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [],
"source": [
"y_knn_pred = knn_clf.predict(X_test)"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9714"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.metrics import accuracy_score\n",
"accuracy_score(y_test, y_knn_pred)"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from scipy.ndimage.interpolation import shift\n",
"def shift_digit(digit_array, dx, dy, new=0):\n",
" return shift(digit_array.reshape(28, 28), [dy, dx], cval=new).reshape(784)\n",
"\n",
"plot_digit(shift_digit(some_digit, 5, 1, new=100))"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"((300000, 784), (300000,))"
]
},
"execution_count": 83,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train_expanded = [X_train]\n",
"y_train_expanded = [y_train]\n",
"for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):\n",
" shifted_images = np.apply_along_axis(shift_digit, axis=1, arr=X_train, dx=dx, dy=dy)\n",
" X_train_expanded.append(shifted_images)\n",
" y_train_expanded.append(y_train)\n",
"\n",
"X_train_expanded = np.concatenate(X_train_expanded)\n",
"y_train_expanded = np.concatenate(y_train_expanded)\n",
"X_train_expanded.shape, y_train_expanded.shape"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
" metric_params=None, n_jobs=-1, n_neighbors=4, p=2,\n",
" weights='distance')"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"knn_clf.fit(X_train_expanded, y_train_expanded)"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [],
"source": [
"y_knn_expanded_pred = knn_clf.predict(X_test)"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9763"
]
},
"execution_count": 86,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"accuracy_score(y_test, y_knn_expanded_pred)"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0. , 0. , 0.5053645, 0. , 0. , 0. ,\n",
" 0. , 0.4946355, 0. , 0. ]])"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ambiguous_digit = X_test[2589]\n",
"knn_clf.predict_proba([ambiguous_digit])"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_digit(ambiguous_digit)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"# 연습문제 해답"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. 97% 정확도의 MNIST 분류기"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Fitting 5 folds for each of 6 candidates, totalling 30 fits\n",
"[CV] n_neighbors=3, weights=uniform ..................................\n",
"[CV] n_neighbors=3, weights=uniform ..................................\n",
"[CV] n_neighbors=3, weights=uniform ..................................\n",
"[CV] n_neighbors=3, weights=uniform ..................................\n",
"[CV] n_neighbors=3, weights=uniform, score=0.9698458975426906, total=12.0min\n",
"[CV] n_neighbors=3, weights=uniform ..................................\n",
"[CV] n_neighbors=3, weights=uniform, score=0.9714214297617064, total=12.0min\n",
"[CV] n_neighbors=3, weights=distance .................................\n",
"[CV] n_neighbors=3, weights=uniform, score=0.9726666666666667, total=12.0min\n",
"[CV] n_neighbors=3, weights=distance .................................\n",
"[CV] n_neighbors=3, weights=uniform, score=0.9728265399683255, total=12.0min\n",
"[CV] n_neighbors=3, weights=distance .................................\n",
"[CV] n_neighbors=3, weights=distance, score=0.9712619741774261, total=11.9min\n",
"[CV] n_neighbors=3, weights=distance .................................\n",
"[CV] n_neighbors=3, weights=uniform, score=0.9717405801933978, total=11.9min\n",
"[CV] n_neighbors=3, weights=distance .................................\n",
"[CV] .... n_neighbors=3, weights=distance, score=0.9745, total=12.0min\n",
"[CV] n_neighbors=4, weights=uniform ..................................\n",
"[CV] n_neighbors=3, weights=distance, score=0.9725879020163306, total=12.0min\n",
"[CV] n_neighbors=4, weights=uniform ..................................\n",
"[CV] n_neighbors=3, weights=distance, score=0.9743269150620989, total=11.9min\n",
"[CV] n_neighbors=4, weights=uniform ..................................\n",
"[CV] n_neighbors=4, weights=uniform, score=0.9691795085381091, total=11.9min\n",
"[CV] n_neighbors=4, weights=uniform ..................................\n",
"[CV] n_neighbors=3, weights=distance, score=0.9724074691563854, total=11.9min\n",
"[CV] n_neighbors=4, weights=uniform ..................................\n",
"[CV] n_neighbors=4, weights=uniform, score=0.9698383602732877, total=11.9min\n",
"[CV] n_neighbors=4, weights=distance .................................\n",
"[CV] n_neighbors=4, weights=uniform, score=0.9718333333333333, total=11.9min\n",
"[CV] n_neighbors=4, weights=distance .................................\n",
"[CV] n_neighbors=4, weights=uniform, score=0.9709093940151705, total=11.9min\n",
"[CV] n_neighbors=4, weights=distance .................................\n",
"[CV] n_neighbors=4, weights=uniform, score=0.9680726908969657, total=11.9min\n",
"[CV] n_neighbors=4, weights=distance .................................\n",
"[CV] n_neighbors=4, weights=distance, score=0.9714285714285714, total=11.9min\n",
"[CV] n_neighbors=4, weights=distance .................................\n",
"[CV] n_neighbors=4, weights=distance, score=0.9729211798033661, total=11.9min\n",
"[CV] n_neighbors=5, weights=uniform ..................................\n",
"[CV] n_neighbors=4, weights=distance, score=0.9745833333333334, total=11.9min\n",
"[CV] n_neighbors=5, weights=uniform ..................................\n",
"[CV] n_neighbors=4, weights=distance, score=0.9752438109527382, total=11.9min\n",
"[CV] n_neighbors=5, weights=uniform ..................................\n",
"[CV] n_neighbors=4, weights=distance, score=0.9720740246748917, total=11.9min\n",
"[CV] n_neighbors=5, weights=uniform ..................................\n",
"[CV] n_neighbors=5, weights=uniform, score=0.9693461057892545, total=11.9min\n",
"[CV] n_neighbors=5, weights=uniform ..................................\n",
"[CV] n_neighbors=5, weights=uniform, score=0.9699216797200466, total=11.9min\n",
"[CV] n_neighbors=5, weights=distance .................................\n",
"[CV] n_neighbors=5, weights=uniform, score=0.9726666666666667, total=11.9min\n",
"[CV] n_neighbors=5, weights=distance .................................\n",
"[CV] n_neighbors=5, weights=uniform, score=0.9713261648745519, total=11.9min\n",
"[CV] n_neighbors=5, weights=distance .................................\n",
"[CV] n_neighbors=5, weights=uniform, score=0.969406468822941, total=11.9min\n",
"[CV] n_neighbors=5, weights=distance .................................\n",
"[CV] n_neighbors=5, weights=distance, score=0.9711786755518534, total=11.9min\n",
"[CV] n_neighbors=5, weights=distance .................................\n",
"[CV] n_neighbors=5, weights=distance, score=0.9712547908681887, total=11.9min\n",
"[CV] n_neighbors=5, weights=distance, score=0.9738333333333333, total=11.9min\n",
"[CV] n_neighbors=5, weights=distance, score=0.9724931232808202, total=11.1min\n",
"[CV] n_neighbors=5, weights=distance, score=0.9714904968322774, total=11.1min\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"[Parallel(n_jobs=-1)]: Done 30 out of 30 | elapsed: 465.3min finished\n"
]
},
{
"data": {
"text/plain": [
"GridSearchCV(cv=5, error_score='raise',\n",
" estimator=KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
" metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
" weights='uniform'),\n",
" fit_params=None, iid=True, n_jobs=-1,\n",
" param_grid=[{'weights': ['uniform', 'distance'], 'n_neighbors': [3, 4, 5]}],\n",
" pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
" scoring=None, verbose=3)"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.model_selection import GridSearchCV\n",
"\n",
"param_grid = [{'weights': [\"uniform\", \"distance\"], 'n_neighbors': [3, 4, 5]}]\n",
"\n",
"knn_clf = KNeighborsClassifier()\n",
"grid_search = GridSearchCV(knn_clf, param_grid, cv=5, verbose=3, n_jobs=-1)\n",
"grid_search.fit(X_train, y_train)"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'n_neighbors': 4, 'weights': 'distance'}"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"grid_search.best_params_"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.97325"
]
},
"execution_count": 91,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"grid_search.best_score_"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9714"
]
},
"execution_count": 92,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.metrics import accuracy_score\n",
"\n",
"y_pred = grid_search.predict(X_test)\n",
"accuracy_score(y_test, y_pred)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. 데이터 증식"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [],
"source": [
"from scipy.ndimage.interpolation import shift"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [],
"source": [
"def shift_image(image, dx, dy):\n",
" image = image.reshape((28, 28))\n",
" shifted_image = shift(image, [dy, dx], cval=0, mode=\"constant\")\n",
" return shifted_image.reshape([-1])"
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x216 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"image = X_train[1000]\n",
"shifted_image_down = shift_image(image, 0, 5)\n",
"shifted_image_left = shift_image(image, -5, 0)\n",
"\n",
"plt.figure(figsize=(12,3))\n",
"plt.subplot(131)\n",
"plt.title(\"Original\", fontsize=14)\n",
"plt.imshow(image.reshape(28, 28), interpolation=\"nearest\", cmap=\"Greys\")\n",
"plt.subplot(132)\n",
"plt.title(\"Shifted down\", fontsize=14)\n",
"plt.imshow(shifted_image_down.reshape(28, 28), interpolation=\"nearest\", cmap=\"Greys\")\n",
"plt.subplot(133)\n",
"plt.title(\"Shifted left\", fontsize=14)\n",
"plt.imshow(shifted_image_left.reshape(28, 28), interpolation=\"nearest\", cmap=\"Greys\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [],
"source": [
"X_train_augmented = [image for image in X_train]\n",
"y_train_augmented = [label for label in y_train]\n",
"\n",
"for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):\n",
" for image, label in zip(X_train, y_train):\n",
" X_train_augmented.append(shift_image(image, dx, dy))\n",
" y_train_augmented.append(label)\n",
"\n",
"X_train_augmented = np.array(X_train_augmented)\n",
"y_train_augmented = np.array(y_train_augmented)"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {},
"outputs": [],
"source": [
"shuffle_idx = np.random.permutation(len(X_train_augmented))\n",
"X_train_augmented = X_train_augmented[shuffle_idx]\n",
"y_train_augmented = y_train_augmented[shuffle_idx]"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [],
"source": [
"knn_clf = KNeighborsClassifier(**grid_search.best_params_)"
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
" metric_params=None, n_jobs=1, n_neighbors=4, p=2,\n",
" weights='distance')"
]
},
"execution_count": 99,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"knn_clf.fit(X_train_augmented, y_train_augmented)"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9763"
]
},
"execution_count": 100,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_pred = knn_clf.predict(X_test)\n",
"accuracy_score(y_test, y_pred)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"간단한 데이터 증식으로 0.5%의 정확도가 향상되었습니다. :)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. 타이타닉 데이터셋에 도전"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"승객의 나이, 성별, 승객 등급, 승선 위치 같은 속성을 기반으로 하여 승객의 생존 여부를 예측하는 것이 목표입니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"먼저 [캐글](https://www.kaggle.com)에 로그인 하고 [타이타닉 챌린지](https://www.kaggle.com/c/titanic)에서 `train.csv`와 `test.csv`를 다운로드합니다. 두 파일을 `datasets/titanic` 디렉토리에 저장하세요."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"그다음 데이터를 적재합니다:"
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"TITANIC_PATH = os.path.join(\"datasets\", \"titanic\")"
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"\n",
"def load_titanic_data(filename, titanic_path=TITANIC_PATH):\n",
" csv_path = os.path.join(titanic_path, filename)\n",
" return pd.read_csv(csv_path)"
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {},
"outputs": [],
"source": [
"train_data = load_titanic_data(\"train.csv\")\n",
"test_data = load_titanic_data(\"test.csv\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"데이터는 이미 훈련 세트와 테스트 세트로 분리되어 있습니다. 그러나 테스트 데이터는 레이블을 가지고 있지 않습니다: 훈련 데이터를 이용하여 가능한 최고의 모델을 만들고 테스트 데이터에 대한 예측을 캐글(Kaggle)에 업로드하여 최종 점수를 확인하는 것이 목표입니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"훈련 세트에서 맨 위 몇 개의 열을 살펴 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>PassengerId</th>\n",
" <th>Survived</th>\n",
" <th>Pclass</th>\n",
" <th>Name</th>\n",
" <th>Sex</th>\n",
" <th>Age</th>\n",
" <th>SibSp</th>\n",
" <th>Parch</th>\n",
" <th>Ticket</th>\n",
" <th>Fare</th>\n",
" <th>Cabin</th>\n",
" <th>Embarked</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>3</td>\n",
" <td>Braund, Mr. Owen Harris</td>\n",
" <td>male</td>\n",
" <td>22.0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>A/5 21171</td>\n",
" <td>7.2500</td>\n",
" <td>NaN</td>\n",
" <td>S</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>Cumings, Mrs. John Bradley (Florence Briggs Th...</td>\n",
" <td>female</td>\n",
" <td>38.0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>PC 17599</td>\n",
" <td>71.2833</td>\n",
" <td>C85</td>\n",
" <td>C</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>1</td>\n",
" <td>3</td>\n",
" <td>Heikkinen, Miss. Laina</td>\n",
" <td>female</td>\n",
" <td>26.0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>STON/O2. 3101282</td>\n",
" <td>7.9250</td>\n",
" <td>NaN</td>\n",
" <td>S</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>Futrelle, Mrs. Jacques Heath (Lily May Peel)</td>\n",
" <td>female</td>\n",
" <td>35.0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>113803</td>\n",
" <td>53.1000</td>\n",
" <td>C123</td>\n",
" <td>S</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5</td>\n",
" <td>0</td>\n",
" <td>3</td>\n",
" <td>Allen, Mr. William Henry</td>\n",
" <td>male</td>\n",
" <td>35.0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>373450</td>\n",
" <td>8.0500</td>\n",
" <td>NaN</td>\n",
" <td>S</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" PassengerId Survived Pclass \\\n",
"0 1 0 3 \n",
"1 2 1 1 \n",
"2 3 1 3 \n",
"3 4 1 1 \n",
"4 5 0 3 \n",
"\n",
" Name Sex Age SibSp \\\n",
"0 Braund, Mr. Owen Harris male 22.0 1 \n",
"1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 \n",
"2 Heikkinen, Miss. Laina female 26.0 0 \n",
"3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 \n",
"4 Allen, Mr. William Henry male 35.0 0 \n",
"\n",
" Parch Ticket Fare Cabin Embarked \n",
"0 0 A/5 21171 7.2500 NaN S \n",
"1 0 PC 17599 71.2833 C85 C \n",
"2 0 STON/O2. 3101282 7.9250 NaN S \n",
"3 0 113803 53.1000 C123 S \n",
"4 0 373450 8.0500 NaN S "
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_data.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"속성은 다음과 같은 의미를 가집니다:\n",
"* **Survived**: 타깃입니다. 0은 생존하지 못한 것이고 1은 생존을 의미합니다.\n",
"* **Pclass**: 승객 등급. 1, 2, 3등석.\n",
"* **Name**, **Sex**, **Age**: 이름 그대로 의미입니다.\n",
"* **SibSp**: 함께 탑승한 형제, 배우자의 수.\n",
"* **Parch**: 함께 탑승한 자녀, 부모의 수.\n",
"* **Ticket**: 티켓 아이디\n",
"* **Fare**: 티켓 요금 (파운드)\n",
"* **Cabin**: 객실 번호\n",
"* **Embarked**: 승객이 탑승한 곳. C(Cherbourg), Q(Queenstown), S(Southampton)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"누락된 데이터가 얼마나 되는지 알아보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 891 entries, 0 to 890\n",
"Data columns (total 12 columns):\n",
"PassengerId 891 non-null int64\n",
"Survived 891 non-null int64\n",
"Pclass 891 non-null int64\n",
"Name 891 non-null object\n",
"Sex 891 non-null object\n",
"Age 714 non-null float64\n",
"SibSp 891 non-null int64\n",
"Parch 891 non-null int64\n",
"Ticket 891 non-null object\n",
"Fare 891 non-null float64\n",
"Cabin 204 non-null object\n",
"Embarked 889 non-null object\n",
"dtypes: float64(2), int64(5), object(5)\n",
"memory usage: 83.6+ KB\n"
]
}
],
"source": [
"train_data.info()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"괜찮네요. **Age**, **Cabin**, **Embarked** 속성의 일부가 null입니다(891개의 non-null 보다 작습니다). 특히 **Cabin**은 77%가 null입니다. 일단 **Cabin**은 무시하고 나머지를 활용하겠습니다. **Age**는 19%가 null이므로 이를 어떻게 처리할지 결정해야 합니다. null을 중간 나이로 바꾸는 것이 괜찮아 보입니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Name**과 **Ticket** 속성도 값을 가지고 있지만 머신러닝 모델이 사용할 수 있는 숫자로 변환하는 것이 조금 까다롭습니다. 그래서 지금은 이 두 속성을 무시하겠습니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"통계치를 살펴 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>PassengerId</th>\n",
" <th>Survived</th>\n",
" <th>Pclass</th>\n",
" <th>Age</th>\n",
" <th>SibSp</th>\n",
" <th>Parch</th>\n",
" <th>Fare</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>891.000000</td>\n",
" <td>891.000000</td>\n",
" <td>891.000000</td>\n",
" <td>714.000000</td>\n",
" <td>891.000000</td>\n",
" <td>891.000000</td>\n",
" <td>891.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>446.000000</td>\n",
" <td>0.383838</td>\n",
" <td>2.308642</td>\n",
" <td>29.699118</td>\n",
" <td>0.523008</td>\n",
" <td>0.381594</td>\n",
" <td>32.204208</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>257.353842</td>\n",
" <td>0.486592</td>\n",
" <td>0.836071</td>\n",
" <td>14.526497</td>\n",
" <td>1.102743</td>\n",
" <td>0.806057</td>\n",
" <td>49.693429</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>1.000000</td>\n",
" <td>0.000000</td>\n",
" <td>1.000000</td>\n",
" <td>0.420000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>223.500000</td>\n",
" <td>0.000000</td>\n",
" <td>2.000000</td>\n",
" <td>20.125000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>7.910400</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>446.000000</td>\n",
" <td>0.000000</td>\n",
" <td>3.000000</td>\n",
" <td>28.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>14.454200</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>668.500000</td>\n",
" <td>1.000000</td>\n",
" <td>3.000000</td>\n",
" <td>38.000000</td>\n",
" <td>1.000000</td>\n",
" <td>0.000000</td>\n",
" <td>31.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>891.000000</td>\n",
" <td>1.000000</td>\n",
" <td>3.000000</td>\n",
" <td>80.000000</td>\n",
" <td>8.000000</td>\n",
" <td>6.000000</td>\n",
" <td>512.329200</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" PassengerId Survived Pclass Age SibSp \\\n",
"count 891.000000 891.000000 891.000000 714.000000 891.000000 \n",
"mean 446.000000 0.383838 2.308642 29.699118 0.523008 \n",
"std 257.353842 0.486592 0.836071 14.526497 1.102743 \n",
"min 1.000000 0.000000 1.000000 0.420000 0.000000 \n",
"25% 223.500000 0.000000 2.000000 20.125000 0.000000 \n",
"50% 446.000000 0.000000 3.000000 28.000000 0.000000 \n",
"75% 668.500000 1.000000 3.000000 38.000000 1.000000 \n",
"max 891.000000 1.000000 3.000000 80.000000 8.000000 \n",
"\n",
" Parch Fare \n",
"count 891.000000 891.000000 \n",
"mean 0.381594 32.204208 \n",
"std 0.806057 49.693429 \n",
"min 0.000000 0.000000 \n",
"25% 0.000000 7.910400 \n",
"50% 0.000000 14.454200 \n",
"75% 0.000000 31.000000 \n",
"max 6.000000 512.329200 "
]
},
"execution_count": 106,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_data.describe()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* 이크, 38%만 **Survived**입니다. :( 거의 40%에 가까우므로 정확도를 사용해 모델을 평가해도 괜찮을 것 같습니다.\n",
"* 평균 **Fare**는 32.20 파운드라 그렇게 비싸보이지는 않습니다(아마 요금을 많이 반환해 주었기 때문일 것입니다)\n",
"* 평균 **Age**는 30보다 작습니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"타깃이 0과 1로 이루어졌는지 확인합니다:"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 549\n",
"1 342\n",
"Name: Survived, dtype: int64"
]
},
"execution_count": 107,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_data[\"Survived\"].value_counts()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"범주형 특성들을 확인해 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3 491\n",
"1 216\n",
"2 184\n",
"Name: Pclass, dtype: int64"
]
},
"execution_count": 108,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_data[\"Pclass\"].value_counts()"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"male 577\n",
"female 314\n",
"Name: Sex, dtype: int64"
]
},
"execution_count": 109,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_data[\"Sex\"].value_counts()"
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"S 644\n",
"C 168\n",
"Q 77\n",
"Name: Embarked, dtype: int64"
]
},
"execution_count": 110,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_data[\"Embarked\"].value_counts()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Embarked** 특성은 승객이 탑승한 곳을 알려 줍니다: C=Cherbourg, Q=Queenstown, S=Southampton."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`CategoricalEncoder` 클래스는 범주형 특성을 원-핫 벡터로 변환시켜 줍니다. 이 클래스는 사이킷런 0.20에 포함될 예정이지만 지금은 아래 코드를 사용합니다([#9151](https://github.com/scikit-learn/scikit-learn/pull/9151) 풀 리퀘스트에서 복사했습니다)."
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {},
"outputs": [],
"source": [
"# PR #9151에서 가져온 CategoricalEncoder 클래스의 정의.\n",
"# 이 클래스는 사이킷런 0.20에 포함될 예정입니다.\n",
"# 이 셀을 실행하거나 복사해서 사용하세요. 이 코드를 모두 이해할 필요는 없습니다.\n",
"\n",
"from sklearn.base import BaseEstimator, TransformerMixin\n",
"from sklearn.utils import check_array\n",
"from sklearn.preprocessing import LabelEncoder\n",
"from scipy import sparse\n",
"\n",
"class CategoricalEncoder(BaseEstimator, TransformerMixin):\n",
" \"\"\"Encode categorical features as a numeric array.\n",
" The input to this transformer should be a matrix of integers or strings,\n",
" denoting the values taken on by categorical (discrete) features.\n",
" The features can be encoded using a one-hot aka one-of-K scheme\n",
" (``encoding='onehot'``, the default) or converted to ordinal integers\n",
" (``encoding='ordinal'``).\n",
" This encoding is needed for feeding categorical data to many scikit-learn\n",
" estimators, notably linear models and SVMs with the standard kernels.\n",
" Read more in the :ref:`User Guide <preprocessing_categorical_features>`.\n",
" Parameters\n",
" ----------\n",
" encoding : str, 'onehot', 'onehot-dense' or 'ordinal'\n",
" The type of encoding to use (default is 'onehot'):\n",
" - 'onehot': encode the features using a one-hot aka one-of-K scheme\n",
" (or also called 'dummy' encoding). This creates a binary column for\n",
" each category and returns a sparse matrix.\n",
" - 'onehot-dense': the same as 'onehot' but returns a dense array\n",
" instead of a sparse matrix.\n",
" - 'ordinal': encode the features as ordinal integers. This results in\n",
" a single column of integers (0 to n_categories - 1) per feature.\n",
" categories : 'auto' or a list of lists/arrays of values.\n",
" Categories (unique values) per feature:\n",
" - 'auto' : Determine categories automatically from the training data.\n",
" - list : ``categories[i]`` holds the categories expected in the ith\n",
" column. The passed categories are sorted before encoding the data\n",
" (used categories can be found in the ``categories_`` attribute).\n",
" dtype : number type, default np.float64\n",
" Desired dtype of output.\n",
" handle_unknown : 'error' (default) or 'ignore'\n",
" Whether to raise an error or ignore if a unknown categorical feature is\n",
" present during transform (default is to raise). When this is parameter\n",
" is set to 'ignore' and an unknown category is encountered during\n",
" transform, the resulting one-hot encoded columns for this feature\n",
" will be all zeros.\n",
" Ignoring unknown categories is not supported for\n",
" ``encoding='ordinal'``.\n",
" Attributes\n",
" ----------\n",
" categories_ : list of arrays\n",
" The categories of each feature determined during fitting. When\n",
" categories were specified manually, this holds the sorted categories\n",
" (in order corresponding with output of `transform`).\n",
" Examples\n",
" --------\n",
" Given a dataset with three features and two samples, we let the encoder\n",
" find the maximum value per feature and transform the data to a binary\n",
" one-hot encoding.\n",
" >>> from sklearn.preprocessing import CategoricalEncoder\n",
" >>> enc = CategoricalEncoder(handle_unknown='ignore')\n",
" >>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])\n",
" ... # doctest: +ELLIPSIS\n",
" CategoricalEncoder(categories='auto', dtype=<... 'numpy.float64'>,\n",
" encoding='onehot', handle_unknown='ignore')\n",
" >>> enc.transform([[0, 1, 1], [1, 0, 4]]).toarray()\n",
" array([[ 1., 0., 0., 1., 0., 0., 1., 0., 0.],\n",
" [ 0., 1., 1., 0., 0., 0., 0., 0., 0.]])\n",
" See also\n",
" --------\n",
" sklearn.preprocessing.OneHotEncoder : performs a one-hot encoding of\n",
" integer ordinal features. The ``OneHotEncoder assumes`` that input\n",
" features take on values in the range ``[0, max(feature)]`` instead of\n",
" using the unique values.\n",
" sklearn.feature_extraction.DictVectorizer : performs a one-hot encoding of\n",
" dictionary items (also handles string-valued features).\n",
" sklearn.feature_extraction.FeatureHasher : performs an approximate one-hot\n",
" encoding of dictionary items or strings.\n",
" \"\"\"\n",
"\n",
" def __init__(self, encoding='onehot', categories='auto', dtype=np.float64,\n",
" handle_unknown='error'):\n",
" self.encoding = encoding\n",
" self.categories = categories\n",
" self.dtype = dtype\n",
" self.handle_unknown = handle_unknown\n",
"\n",
" def fit(self, X, y=None):\n",
" \"\"\"Fit the CategoricalEncoder to X.\n",
" Parameters\n",
" ----------\n",
" X : array-like, shape [n_samples, n_feature]\n",
" The data to determine the categories of each feature.\n",
" Returns\n",
" -------\n",
" self\n",
" \"\"\"\n",
"\n",
" if self.encoding not in ['onehot', 'onehot-dense', 'ordinal']:\n",
" template = (\"encoding should be either 'onehot', 'onehot-dense' \"\n",
" \"or 'ordinal', got %s\")\n",
" raise ValueError(template % self.handle_unknown)\n",
"\n",
" if self.handle_unknown not in ['error', 'ignore']:\n",
" template = (\"handle_unknown should be either 'error' or \"\n",
" \"'ignore', got %s\")\n",
" raise ValueError(template % self.handle_unknown)\n",
"\n",
" if self.encoding == 'ordinal' and self.handle_unknown == 'ignore':\n",
" raise ValueError(\"handle_unknown='ignore' is not supported for\"\n",
" \" encoding='ordinal'\")\n",
"\n",
" X = check_array(X, dtype=np.object, accept_sparse='csc', copy=True)\n",
" n_samples, n_features = X.shape\n",
"\n",
" self._label_encoders_ = [LabelEncoder() for _ in range(n_features)]\n",
"\n",
" for i in range(n_features):\n",
" le = self._label_encoders_[i]\n",
" Xi = X[:, i]\n",
" if self.categories == 'auto':\n",
" le.fit(Xi)\n",
" else:\n",
" valid_mask = np.in1d(Xi, self.categories[i])\n",
" if not np.all(valid_mask):\n",
" if self.handle_unknown == 'error':\n",
" diff = np.unique(Xi[~valid_mask])\n",
" msg = (\"Found unknown categories {0} in column {1}\"\n",
" \" during fit\".format(diff, i))\n",
" raise ValueError(msg)\n",
" le.classes_ = np.array(np.sort(self.categories[i]))\n",
"\n",
" self.categories_ = [le.classes_ for le in self._label_encoders_]\n",
"\n",
" return self\n",
"\n",
" def transform(self, X):\n",
" \"\"\"Transform X using one-hot encoding.\n",
" Parameters\n",
" ----------\n",
" X : array-like, shape [n_samples, n_features]\n",
" The data to encode.\n",
" Returns\n",
" -------\n",
" X_out : sparse matrix or a 2-d array\n",
" Transformed input.\n",
" \"\"\"\n",
" X = check_array(X, accept_sparse='csc', dtype=np.object, copy=True)\n",
" n_samples, n_features = X.shape\n",
" X_int = np.zeros_like(X, dtype=np.int)\n",
" X_mask = np.ones_like(X, dtype=np.bool)\n",
"\n",
" for i in range(n_features):\n",
" valid_mask = np.in1d(X[:, i], self.categories_[i])\n",
"\n",
" if not np.all(valid_mask):\n",
" if self.handle_unknown == 'error':\n",
" diff = np.unique(X[~valid_mask, i])\n",
" msg = (\"Found unknown categories {0} in column {1}\"\n",
" \" during transform\".format(diff, i))\n",
" raise ValueError(msg)\n",
" else:\n",
" # Set the problematic rows to an acceptable value and\n",
" # continue `The rows are marked `X_mask` and will be\n",
" # removed later.\n",
" X_mask[:, i] = valid_mask\n",
" X[:, i][~valid_mask] = self.categories_[i][0]\n",
" X_int[:, i] = self._label_encoders_[i].transform(X[:, i])\n",
"\n",
" if self.encoding == 'ordinal':\n",
" return X_int.astype(self.dtype, copy=False)\n",
"\n",
" mask = X_mask.ravel()\n",
" n_values = [cats.shape[0] for cats in self.categories_]\n",
" n_values = np.array([0] + n_values)\n",
" indices = np.cumsum(n_values)\n",
"\n",
" column_indices = (X_int + indices[:-1]).ravel()[mask]\n",
" row_indices = np.repeat(np.arange(n_samples, dtype=np.int32),\n",
" n_features)[mask]\n",
" data = np.ones(n_samples * n_features)[mask]\n",
"\n",
" out = sparse.csc_matrix((data, (row_indices, column_indices)),\n",
" shape=(n_samples, indices[-1]),\n",
" dtype=self.dtype).tocsr()\n",
" if self.encoding == 'onehot-dense':\n",
" return out.toarray()\n",
" else:\n",
" return out"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 전처리 파이프라인을 만듭니다. `DataFrame`으로부터 특정 속성만 선택하기 위해 이전 장에서 만든 `DataframeSelector`를 재사용하겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.base import BaseEstimator, TransformerMixin\n",
"\n",
"# 사이킷런이 DataFrame을 바로 사용하지 못하므로\n",
"# 수치형이나 범주형 컬럼을 선택하는 클래스를 만듭니다.\n",
"class DataFrameSelector(BaseEstimator, TransformerMixin):\n",
" def __init__(self, attribute_names):\n",
" self.attribute_names = attribute_names\n",
" def fit(self, X, y=None):\n",
" return self\n",
" def transform(self, X):\n",
" return X[self.attribute_names]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"숫자 특성을 위한 파이프라인을 만듭니다:"
]
},
{
"cell_type": "code",
"execution_count": 113,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.pipeline import Pipeline\n",
"from sklearn.preprocessing import Imputer\n",
"\n",
"imputer = Imputer(strategy=\"median\")\n",
"\n",
"num_pipeline = Pipeline([\n",
" (\"select_numeric\", DataFrameSelector([\"Age\", \"SibSp\", \"Parch\", \"Fare\"])),\n",
" (\"imputer\", Imputer(strategy=\"median\")),\n",
" ])"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[22. , 1. , 0. , 7.25 ],\n",
" [38. , 1. , 0. , 71.2833],\n",
" [26. , 0. , 0. , 7.925 ],\n",
" ...,\n",
" [28. , 1. , 2. , 23.45 ],\n",
" [26. , 0. , 0. , 30. ],\n",
" [32. , 0. , 0. , 7.75 ]])"
]
},
"execution_count": 114,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"num_pipeline.fit_transform(train_data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"문자열로된 범주형 열을 위해 별도의 Imputer 클래스가 필요합니다(일반 `Imputer` 클래스는 이를 처리하지 못합니다):"
]
},
{
"cell_type": "code",
"execution_count": 115,
"metadata": {},
"outputs": [],
"source": [
"# stackoverflow.com/questions/25239958 에서 착안했습니다\n",
"class MostFrequentImputer(BaseEstimator, TransformerMixin):\n",
" def fit(self, X, y=None):\n",
" self.most_frequent_ = pd.Series([X[c].value_counts().index[0] for c in X],\n",
" index=X.columns)\n",
" return self\n",
" def transform(self, X, y=None):\n",
" return X.fillna(self.most_frequent_)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 범주형 특성을 위한 파이프라인을 만듭니다:"
]
},
{
"cell_type": "code",
"execution_count": 116,
"metadata": {},
"outputs": [],
"source": [
"cat_pipeline = Pipeline([\n",
" (\"select_cat\", DataFrameSelector([\"Pclass\", \"Sex\", \"Embarked\"])),\n",
" (\"imputer\", MostFrequentImputer()),\n",
" (\"cat_encoder\", CategoricalEncoder(encoding='onehot-dense')),\n",
" ])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### future_encoders.py를 사용한 방법 ==========================\n",
"\n",
"주의: 번역서는 `CategoricalEncoder`를 사용하여 각 범주형 값을 원-핫 벡터로 변경합니다. `OneHotEncoder`를 사용하는 것이 더 낫습니다. 지금은 정수형 범주 입력만 다룰 수 있지만 사이킷런 0.20에서는 문자열 범주 입력도 다룰 수 있을 것입니다(PR #10521). 지금은 `future_encoders.py` 파일에서 임포트하지만 사이킷런 0.20 버전이 릴리스되면 `sklearn.preprocessing`에서 바로 임포팅할 수 있습니다."
]
},
{
"cell_type": "code",
"execution_count": 117,
"metadata": {},
"outputs": [],
"source": [
"from future_encoders import OneHotEncoder\n",
"\n",
"cat_pipeline = Pipeline([\n",
" (\"select_cat\", DataFrameSelector([\"Pclass\", \"Sex\", \"Embarked\"])),\n",
" (\"imputer\", MostFrequentImputer()),\n",
" (\"cat_encoder\", OneHotEncoder(sparse=False)),\n",
" ])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### ===================================================="
]
},
{
"cell_type": "code",
"execution_count": 118,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0., 0., 1., ..., 0., 0., 1.],\n",
" [1., 0., 0., ..., 1., 0., 0.],\n",
" [0., 0., 1., ..., 0., 0., 1.],\n",
" ...,\n",
" [0., 0., 1., ..., 0., 0., 1.],\n",
" [1., 0., 0., ..., 1., 0., 0.],\n",
" [0., 0., 1., ..., 0., 1., 0.]])"
]
},
"execution_count": 118,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cat_pipeline.fit_transform(train_data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"마지막으로 숫자와 범주형 파이프라인을 연결합니다:"
]
},
{
"cell_type": "code",
"execution_count": 119,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.pipeline import FeatureUnion\n",
"preprocess_pipeline = FeatureUnion(transformer_list=[\n",
" (\"num_pipeline\", num_pipeline),\n",
" (\"cat_pipeline\", cat_pipeline),\n",
" ])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"좋습니다! 이제 원본 데이터를 받아 머신러닝 모델에 주입할 숫자 입력 특성을 출력하는 전처리 파이프라인을 만들었습니다."
]
},
{
"cell_type": "code",
"execution_count": 120,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[22., 1., 0., ..., 0., 0., 1.],\n",
" [38., 1., 0., ..., 1., 0., 0.],\n",
" [26., 0., 0., ..., 0., 0., 1.],\n",
" ...,\n",
" [28., 1., 2., ..., 0., 0., 1.],\n",
" [26., 0., 0., ..., 1., 0., 0.],\n",
" [32., 0., 0., ..., 0., 1., 0.]])"
]
},
"execution_count": 120,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train = preprocess_pipeline.fit_transform(train_data)\n",
"X_train"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"레이블을 가져옵니다:"
]
},
{
"cell_type": "code",
"execution_count": 121,
"metadata": {},
"outputs": [],
"source": [
"y_train = train_data[\"Survived\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 분류기를 훈련시킬 차례입니다. 먼저 `SVC`를 사용해 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 122,
"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='rbf',\n",
" max_iter=-1, probability=False, random_state=None, shrinking=True,\n",
" tol=0.001, verbose=False)"
]
},
"execution_count": 122,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.svm import SVC\n",
"\n",
"svm_clf = SVC()\n",
"svm_clf.fit(X_train, y_train)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"모델이 잘 훈련된 것 같습니다. 이를 사용해서 테스트 세트에 대한 예측을 만듭니다:"
]
},
{
"cell_type": "code",
"execution_count": 123,
"metadata": {},
"outputs": [],
"source": [
"X_test = preprocess_pipeline.transform(test_data)\n",
"y_pred = svm_clf.predict(X_test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이 예측 결과를 (캐글에서 기대하는 형태인) CSV 파일로 만들어 업로드하고 평가를 받아볼 수 있습니다. 하지만 그냥 좋을거라 기대하는 것보다 교차 검증으로 모델이 얼마나 좋은지 평가하는 것이 좋습니다."
]
},
{
"cell_type": "code",
"execution_count": 124,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.7365250822835092"
]
},
"execution_count": 124,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.model_selection import cross_val_score\n",
"\n",
"svm_scores = cross_val_score(svm_clf, X_train, y_train, cv=10)\n",
"svm_scores.mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"정확도가 73% 이상입니다. 확실히 무작위로 선택한 것보다는 좋습니다. 하지만 아주 높은 점수는 아닙니다. 캐글에서 타이타닉 경연 대회의 [리더보드](https://www.kaggle.com/c/titanic/leaderboard)를 보면 상위 10%내에 들려면 80% 이상의 정확도를 내야합니다. 어떤 사람들은 100%를 달성했습니다. 하지만 타이타닉의 [희생자 목록](https://www.encyclopedia-titanica.org/titanic-victims/)을 쉽게 찾을 수 있으므로 머신러닝을 사용하지 않고도 이런 정확도를 달성할 수 있습니다! ;-) 우리는 80% 정도의 정확도를 내는 모델을 만들어 보겠습니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`RandomForestClassifier`를 적용해 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 125,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.8115690614005221"
]
},
"execution_count": 125,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.ensemble import RandomForestClassifier\n",
"\n",
"forest_clf = RandomForestClassifier(random_state=42)\n",
"forest_scores = cross_val_score(forest_clf, X_train, y_train, cv=10)\n",
"forest_scores.mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"훨씬 좋네요!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"10 폴드 교차 검증에 대한 평균 정확도를 보는 대신 모델에서 얻은 10개의 점수를 1사분위, 3사분위를 명료하게 표현해주는 상자 수염 그림(box-and-whisker) 그래프를 만들어 보겠습니다(이 방식을 제안해 준 Nevin Yilmaz에게 감사합니다). `boxplot()` 함수는 이상치(플라이어(flier)라고 부릅니다)를 감지하고 수염 부분에 이를 포함시키지 않습니다. 1사분위가 $Q_1$이고 3사분위가 $Q_3$이라면 사분위수 범위는 $IQR = Q_3 - Q_1$가 됩니다(이 값이 박스의 높이가 됩니다). $Q_1 - 1.5 \\times IQR$ 보다 낮거나 $Q3 + 1.5 \\times IQR$ 보다 높은 점수는 이상치로 간주됩니다."
]
},
{
"cell_type": "code",
"execution_count": 126,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(8, 4))\n",
"plt.plot([1]*10, svm_scores, \".\")\n",
"plt.plot([2]*10, forest_scores, \".\")\n",
"plt.boxplot([svm_scores, forest_scores], labels=(\"SVM\",\"Random Forest\"))\n",
"plt.ylabel(\"정확도\", fontsize=14)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이 결과를 더 향상시키려면:\n",
"* 교차 검증과 그리드 탐색을 사용하여 더 많은 모델을 비교하고 하이퍼파라미터를 튜닝하세요.\n",
"* 특성 공학을 더 시도해 보세요, 예를 들면:\n",
" * **SibSp**와 **Parch**을 이 두 특성의 합으로 바꿉니다.\n",
" * **Survived** 특성과 관련된 이름을 구별해 보세요(가령, 이름에 \"Countess\"가 있는 경우 생존할 가능성이 높습니다).\n",
"* 수치 특성을 범주형 특성으로 바꾸어 보세요: 예를 들어, 나이대가 다른 경우 다른 생존 비율을 가질 수 있습니다(아래 참조). 그러므로 나이 구간을 범주로 만들어 나이 대신 사용하는 것이 도움이 될 수 있스니다. 비슷하게 생존자의 30%가 혼자 여행하는 사람이기 때문에 이들을 위한 특별한 범주를 만드는 것이 도움이 될 수 있습니다(아래 참조)."
]
},
{
"cell_type": "code",
"execution_count": 126,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Survived</th>\n",
" </tr>\n",
" <tr>\n",
" <th>AgeBucket</th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0.0</th>\n",
" <td>0.576923</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15.0</th>\n",
" <td>0.362745</td>\n",
" </tr>\n",
" <tr>\n",
" <th>30.0</th>\n",
" <td>0.423256</td>\n",
" </tr>\n",
" <tr>\n",
" <th>45.0</th>\n",
" <td>0.404494</td>\n",
" </tr>\n",
" <tr>\n",
" <th>60.0</th>\n",
" <td>0.240000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75.0</th>\n",
" <td>1.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Survived\n",
"AgeBucket \n",
"0.0 0.576923\n",
"15.0 0.362745\n",
"30.0 0.423256\n",
"45.0 0.404494\n",
"60.0 0.240000\n",
"75.0 1.000000"
]
},
"execution_count": 126,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_data[\"AgeBucket\"] = train_data[\"Age\"] // 15 * 15\n",
"train_data[[\"AgeBucket\", \"Survived\"]].groupby(['AgeBucket']).mean()"
]
},
{
"cell_type": "code",
"execution_count": 127,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Survived</th>\n",
" </tr>\n",
" <tr>\n",
" <th>RelativesOnboard</th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.303538</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0.552795</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0.578431</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0.724138</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0.200000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>0.136364</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>0.333333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Survived\n",
"RelativesOnboard \n",
"0 0.303538\n",
"1 0.552795\n",
"2 0.578431\n",
"3 0.724138\n",
"4 0.200000\n",
"5 0.136364\n",
"6 0.333333\n",
"7 0.000000\n",
"10 0.000000"
]
},
"execution_count": 127,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_data[\"RelativesOnboard\"] = train_data[\"SibSp\"] + train_data[\"Parch\"]\n",
"train_data[[\"RelativesOnboard\", \"Survived\"]].groupby(['RelativesOnboard']).mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. 스팸 필터"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"먼저 데이터를 다운받습니다:"
]
},
{
"cell_type": "code",
"execution_count": 128,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import tarfile\n",
"from six.moves import urllib\n",
"\n",
"DOWNLOAD_ROOT = \"http://spamassassin.apache.org/old/publiccorpus/\"\n",
"HAM_URL = DOWNLOAD_ROOT + \"20030228_easy_ham.tar.bz2\"\n",
"SPAM_URL = DOWNLOAD_ROOT + \"20030228_spam.tar.bz2\"\n",
"SPAM_PATH = os.path.join(\"datasets\", \"spam\")\n",
"\n",
"def fetch_spam_data(spam_url=SPAM_URL, spam_path=SPAM_PATH):\n",
" if not os.path.isdir(spam_path):\n",
" os.makedirs(spam_path)\n",
" for filename, url in ((\"ham.tar.bz2\", HAM_URL), (\"spam.tar.bz2\", SPAM_URL)):\n",
" path = os.path.join(spam_path, filename)\n",
" if not os.path.isfile(path):\n",
" urllib.request.urlretrieve(url, path)\n",
" tar_bz2_file = tarfile.open(path)\n",
" tar_bz2_file.extractall(path=SPAM_PATH)\n",
" tar_bz2_file.close()"
]
},
{
"cell_type": "code",
"execution_count": 129,
"metadata": {},
"outputs": [],
"source": [
"fetch_spam_data()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"다음, 모든 이메일을 읽어 들입니다:"
]
},
{
"cell_type": "code",
"execution_count": 130,
"metadata": {},
"outputs": [],
"source": [
"HAM_DIR = os.path.join(SPAM_PATH, \"easy_ham\")\n",
"SPAM_DIR = os.path.join(SPAM_PATH, \"spam\")\n",
"ham_filenames = [name for name in sorted(os.listdir(HAM_DIR)) if len(name) > 20]\n",
"spam_filenames = [name for name in sorted(os.listdir(SPAM_DIR)) if len(name) > 20]"
]
},
{
"cell_type": "code",
"execution_count": 131,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2500"
]
},
"execution_count": 131,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(ham_filenames)"
]
},
{
"cell_type": "code",
"execution_count": 132,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"500"
]
},
"execution_count": 132,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(spam_filenames)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"파이썬의 `email` 모듈을 사용해 이메일을 파싱합니다(헤더, 인코딩 등을 처리합니다):"
]
},
{
"cell_type": "code",
"execution_count": 133,
"metadata": {},
"outputs": [],
"source": [
"import email\n",
"import email.policy\n",
"\n",
"def load_email(is_spam, filename, spam_path=SPAM_PATH):\n",
" directory = \"spam\" if is_spam else \"easy_ham\"\n",
" with open(os.path.join(spam_path, directory, filename), \"rb\") as f:\n",
" return email.parser.BytesParser(policy=email.policy.default).parse(f)"
]
},
{
"cell_type": "code",
"execution_count": 134,
"metadata": {},
"outputs": [],
"source": [
"ham_emails = [load_email(is_spam=False, filename=name) for name in ham_filenames]\n",
"spam_emails = [load_email(is_spam=True, filename=name) for name in spam_filenames]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"데이터가 어떻게 구성되어 있는지 감을 잡기 위해 햄 메일과 스팸 메일을 하나씩 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 135,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Martin A posted:\n",
"Tassos Papadopoulos, the Greek sculptor behind the plan, judged that the\n",
" limestone of Mount Kerdylio, 70 miles east of Salonika and not far from the\n",
" Mount Athos monastic community, was ideal for the patriotic sculpture. \n",
" \n",
" As well as Alexander's granite features, 240 ft high and 170 ft wide, a\n",
" museum, a restored amphitheatre and car park for admiring crowds are\n",
"planned\n",
"---------------------\n",
"So is this mountain limestone or granite?\n",
"If it's limestone, it'll weather pretty fast.\n",
"\n",
"------------------------ Yahoo! Groups Sponsor ---------------------~-->\n",
"4 DVDs Free +s&p Join Now\n",
"http://us.click.yahoo.com/pt6YBB/NXiEAA/mG3HAA/7gSolB/TM\n",
"---------------------------------------------------------------------~->\n",
"\n",
"To unsubscribe from this group, send an email to:\n",
"forteana-unsubscribe@egroups.com\n",
"\n",
" \n",
"\n",
"Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/\n"
]
}
],
"source": [
"print(ham_emails[1].get_content().strip())"
]
},
{
"cell_type": "code",
"execution_count": 136,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help wanted. We are a 14 year old fortune 500 company, that is\n",
"growing at a tremendous rate. We are looking for individuals who\n",
"want to work from home.\n",
"\n",
"This is an opportunity to make an excellent income. No experience\n",
"is required. We will train you.\n",
"\n",
"So if you are looking to be employed from home with a career that has\n",
"vast opportunities, then go:\n",
"\n",
"http://www.basetel.com/wealthnow\n",
"\n",
"We are looking for energetic and self motivated people. If that is you\n",
"than click on the link and fill out the form, and one of our\n",
"employement specialist will contact you.\n",
"\n",
"To be removed from our link simple go to:\n",
"\n",
"http://www.basetel.com/remove.html\n",
"\n",
"\n",
"4139vOLW7-758DoDY1425FRhM1-764SMFc8513fCsLl40\n"
]
}
],
"source": [
"print(spam_emails[6].get_content().strip())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"어떤 이메일은 이미지나 첨부 파일을 가진 멀티파트(multipart)입니다(메일에 포함되어 있을수 있습니다). 어떤 파일들이 있는지 살펴 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 137,
"metadata": {},
"outputs": [],
"source": [
"def get_email_structure(email):\n",
" if isinstance(email, str):\n",
" return email\n",
" payload = email.get_payload()\n",
" if isinstance(payload, list):\n",
" return \"multipart({})\".format(\", \".join([\n",
" get_email_structure(sub_email)\n",
" for sub_email in payload\n",
" ]))\n",
" else:\n",
" return email.get_content_type()"
]
},
{
"cell_type": "code",
"execution_count": 138,
"metadata": {},
"outputs": [],
"source": [
"from collections import Counter\n",
"\n",
"def structures_counter(emails):\n",
" structures = Counter()\n",
" for email in emails:\n",
" structure = get_email_structure(email)\n",
" structures[structure] += 1\n",
" return structures"
]
},
{
"cell_type": "code",
"execution_count": 139,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"[('text/plain', 2408),\n",
" ('multipart(text/plain, application/pgp-signature)', 66),\n",
" ('multipart(text/plain, text/html)', 8),\n",
" ('multipart(text/plain, text/plain)', 4),\n",
" ('multipart(text/plain)', 3),\n",
" ('multipart(text/plain, application/octet-stream)', 2),\n",
" ('multipart(multipart(text/plain, text/plain, text/plain), application/pgp-signature)',\n",
" 1),\n",
" ('multipart(text/plain, text/enriched)', 1),\n",
" ('multipart(text/plain, video/mng)', 1),\n",
" ('multipart(text/plain, multipart(text/plain))', 1),\n",
" ('multipart(text/plain, application/x-java-applet)', 1),\n",
" ('multipart(text/plain, application/ms-tnef, text/plain)', 1),\n",
" ('multipart(text/plain, multipart(text/plain, text/plain), multipart(multipart(text/plain, application/x-pkcs7-signature)))',\n",
" 1),\n",
" ('multipart(text/plain, application/x-pkcs7-signature)', 1),\n",
" ('multipart(text/plain, multipart(text/plain, text/plain), text/rfc822-headers)',\n",
" 1)]"
]
},
"execution_count": 139,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"structures_counter(ham_emails).most_common()"
]
},
{
"cell_type": "code",
"execution_count": 140,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[('text/plain', 218),\n",
" ('text/html', 183),\n",
" ('multipart(text/plain, text/html)', 45),\n",
" ('multipart(text/html)', 20),\n",
" ('multipart(text/plain)', 19),\n",
" ('multipart(multipart(text/html))', 5),\n",
" ('multipart(text/plain, image/jpeg)', 3),\n",
" ('multipart(text/html, application/octet-stream)', 2),\n",
" ('multipart(multipart(text/html), application/octet-stream, image/jpeg)', 1),\n",
" ('multipart(multipart(text/plain, text/html), image/gif)', 1),\n",
" ('multipart(text/plain, application/octet-stream)', 1),\n",
" ('multipart(text/html, text/plain)', 1),\n",
" ('multipart/alternative', 1)]"
]
},
"execution_count": 140,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"structures_counter(spam_emails).most_common()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"햄 메일은 평범한 텍스트가 많고 스팸은 HTML일 경우가 많습니다. 적은 수의 햄 이메일이 PGP로 서명되어 있지만 스팸 메일에는 없습니다. 요약하면 이메일 구조는 유용한 정보입니다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 이메일 헤더를 살펴보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 141,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Return-Path : <12a1mailbot1@web.de>\n",
"Delivered-To : zzzz@localhost.spamassassin.taint.org\n",
"Received : from localhost (localhost [127.0.0.1])\tby phobos.labs.spamassassin.taint.org (Postfix) with ESMTP id 136B943C32\tfor <zzzz@localhost>; Thu, 22 Aug 2002 08:17:21 -0400 (EDT)\n",
"Received : from mail.webnote.net [193.120.211.219]\tby localhost with POP3 (fetchmail-5.9.0)\tfor zzzz@localhost (single-drop); Thu, 22 Aug 2002 13:17:21 +0100 (IST)\n",
"Received : from dd_it7 ([210.97.77.167])\tby webnote.net (8.9.3/8.9.3) with ESMTP id NAA04623\tfor <zzzz@spamassassin.taint.org>; Thu, 22 Aug 2002 13:09:41 +0100\n",
"From : 12a1mailbot1@web.de\n",
"Received : from r-smtp.korea.com - 203.122.2.197 by dd_it7 with Microsoft SMTPSVC(5.5.1775.675.6);\t Sat, 24 Aug 2002 09:42:10 +0900\n",
"To : dcek1a1@netsgo.com\n",
"Subject : Life Insurance - Why Pay More?\n",
"Date : Wed, 21 Aug 2002 20:31:57 -1600\n",
"MIME-Version : 1.0\n",
"Message-ID : <0103c1042001882DD_IT7@dd_it7>\n",
"Content-Type : text/html; charset=\"iso-8859-1\"\n",
"Content-Transfer-Encoding : quoted-printable\n"
]
}
],
"source": [
"for header, value in spam_emails[0].items():\n",
" print(header,\":\",value)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"보낸사람의 이메일 주소와 같이 헤더에는 유용한 정보가 많이 있지만 여기서는 `Subject` 헤더만 다뤄 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 142,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Life Insurance - Why Pay More?'"
]
},
"execution_count": 142,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spam_emails[0][\"Subject\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"좋습니다. 데이터에를 더 살펴보기 전에 훈련 세트와 테스트 세트로 나누도록 하겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 143,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"X = np.array(ham_emails + spam_emails)\n",
"y = np.array([0] * len(ham_emails) + [1] * len(spam_emails))\n",
"\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 전처리 함수를 작성하겠습니다. 먼저 HTML을 일반 텍스트로 변환하는 함수가 필요합니다. 이 작업에는 당연히 [BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/) 라이브러리를 사용하는게 좋지만 의존성을 줄이기 위해서 정규식을 사용하여 대강 만들어 보겠습니다([un̨ho͞ly radiańcé destro҉ying all enli̍̈́̂̈́ghtenment](https://stackoverflow.com/a/1732454/38626)의 위험에도 불구하고). 다음 함수는 `<head>` 섹션을 삭제하고 모든 `<a>` 태그를 HYPERLINK 문자로 바꿉니다. 그런 다음 모든 HTML 태그를 제거하고 텍스트만 남깁니다. 보기 편하게 여러개의 개행 문자를 하나로 만들고 (`&gt;`나 `&nbsp;` 같은) html 엔티티를 복원합니다:"
]
},
{
"cell_type": "code",
"execution_count": 144,
"metadata": {},
"outputs": [],
"source": [
"import re\n",
"from html import unescape\n",
"\n",
"def html_to_plain_text(html):\n",
" text = re.sub('<head.*?>.*?</head>', '', html, flags=re.M | re.S | re.I)\n",
" text = re.sub('<a\\s.*?>', ' HYPERLINK ', text, flags=re.M | re.S | re.I)\n",
" text = re.sub('<.*?>', '', text, flags=re.M | re.S)\n",
" text = re.sub(r'(\\s*\\n)+', '\\n', text, flags=re.M | re.S)\n",
" return unescape(text)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"잘 작동하는지 확인해 보겠습니다. 다음은 HTML 스팸입니다:"
]
},
{
"cell_type": "code",
"execution_count": 145,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<HTML><HEAD><TITLE></TITLE><META http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1252\"><STYLE>A:link {TEX-DECORATION: none}A:active {TEXT-DECORATION: none}A:visited {TEXT-DECORATION: none}A:hover {COLOR: #0033ff; TEXT-DECORATION: underline}</STYLE><META content=\"MSHTML 6.00.2713.1100\" name=\"GENERATOR\"></HEAD>\n",
"<BODY text=\"#000000\" vLink=\"#0033ff\" link=\"#0033ff\" bgColor=\"#CCCC99\"><TABLE borderColor=\"#660000\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\" width=\"100%\"><TR><TD bgColor=\"#CCCC99\" valign=\"top\" colspan=\"2\" height=\"27\">\n",
"<font size=\"6\" face=\"Arial, Helvetica, sans-serif\" color=\"#660000\">\n",
"<b>OTC</b></font></TD></TR><TR><TD height=\"2\" bgcolor=\"#6a694f\">\n",
"<font size=\"5\" face=\"Times New Roman, Times, serif\" color=\"#FFFFFF\">\n",
"<b>&nbsp;Newsletter</b></font></TD><TD height=\"2\" bgcolor=\"#6a694f\"><div align=\"right\"><font color=\"#FFFFFF\">\n",
"<b>Discover Tomorrow's Winners&nbsp;</b></font></div></TD></TR><TR><TD height=\"25\" colspan=\"2\" bgcolor=\"#CCCC99\"><table width=\"100%\" border=\"0\" ...\n"
]
}
],
"source": [
"html_spam_emails = [email for email in X_train[y_train==1]\n",
" if get_email_structure(email) == \"text/html\"]\n",
"sample_html_spam = html_spam_emails[7]\n",
"print(sample_html_spam.get_content().strip()[:1000], \"...\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"변환된 텍스트입니다:"
]
},
{
"cell_type": "code",
"execution_count": 146,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"OTC\n",
" Newsletter\n",
"Discover Tomorrow's Winners \n",
"For Immediate Release\n",
"Cal-Bay (Stock Symbol: CBYI)\n",
"Watch for analyst \"Strong Buy Recommendations\" and several advisory newsletters picking CBYI. CBYI has filed to be traded on the OTCBB, share prices historically INCREASE when companies get listed on this larger trading exchange. CBYI is trading around 25 cents and should skyrocket to $2.66 - $3.25 a share in the near future.\n",
"Put CBYI on your watch list, acquire a position TODAY.\n",
"REASONS TO INVEST IN CBYI\n",
"A profitable company and is on track to beat ALL earnings estimates!\n",
"One of the FASTEST growing distributors in environmental & safety equipment instruments.\n",
"Excellent management team, several EXCLUSIVE contracts. IMPRESSIVE client list including the U.S. Air Force, Anheuser-Busch, Chevron Refining and Mitsubishi Heavy Industries, GE-Energy & Environmental Research.\n",
"RAPIDLY GROWING INDUSTRY\n",
"Industry revenues exceed $900 million, estimates indicate that there could be as much as $25 billi ...\n"
]
}
],
"source": [
"print(html_to_plain_text(sample_html_spam.get_content())[:1000], \"...\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"아주 좋습니다! 이제 포맷에 상관없이 이메일을 입력으로 받아서 일반 텍스트를 출력하는 함수를 만들겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 147,
"metadata": {},
"outputs": [],
"source": [
"def email_to_text(email):\n",
" html = None\n",
" for part in email.walk():\n",
" ctype = part.get_content_type()\n",
" if not ctype in (\"text/plain\", \"text/html\"):\n",
" continue\n",
" try:\n",
" content = part.get_content()\n",
" except: # in case of encoding issues\n",
" content = str(part.get_payload())\n",
" if ctype == \"text/plain\":\n",
" return content\n",
" else:\n",
" html = content\n",
" if html:\n",
" return html_to_plain_text(html)"
]
},
{
"cell_type": "code",
"execution_count": 148,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"OTC\n",
" Newsletter\n",
"Discover Tomorrow's Winners \n",
"For Immediate Release\n",
"Cal-Bay (Stock Symbol: CBYI)\n",
"Wat ...\n"
]
}
],
"source": [
"print(email_to_text(sample_html_spam)[:100], \"...\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"어간 추출을 해보죠! 이 작업을 하려면 자연어 처리 툴킷([NLTK](http://www.nltk.org/))을 설치해야 합니다. 다음 명령으로 간단히 설치할 수 있습니다(먼저 virtualenv 환경을 활성화시켜야 합니다. 별도의 환경이 없다면 어드민 권한이 필요할지 모릅니다. 아니면 `--user` 옵션을 사용하세요):\n",
"\n",
"`$ pip install nltk`"
]
},
{
"cell_type": "code",
"execution_count": 149,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Computations => comput\n",
"Computation => comput\n",
"Computing => comput\n",
"Computed => comput\n",
"Compute => comput\n",
"Compulsive => compuls\n"
]
}
],
"source": [
"try:\n",
" import nltk\n",
"\n",
" stemmer = nltk.PorterStemmer()\n",
" for word in (\"Computations\", \"Computation\", \"Computing\", \"Computed\", \"Compute\", \"Compulsive\"):\n",
" print(word, \"=>\", stemmer.stem(word))\n",
"except ImportError:\n",
" print(\"Error: stemming requires the NLTK module.\")\n",
" stemmer = None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"인터넷 주소는 \"URL\" 문자로 바꾸겠습니다. [정규식](https://mathiasbynens.be/demo/url-regex)을 하드 코딩할 수도 있지만 [urlextract](https://github.com/lipoja/URLExtract) 라이브러리를 사용하겠습니다. 다음 명령으로 설치합니다(먼저 virtualenv 환경을 활성화시켜야 합니다. 별도의 환경이 없다면 어드민 권한이 필요할지 모릅니다. 아니면 `--user` 옵션을 사용하세요):\n",
"\n",
"`$ pip install urlextract`"
]
},
{
"cell_type": "code",
"execution_count": 150,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['github.com', 'https://youtu.be/7Pq-S557XQU?t=3m32s']\n"
]
}
],
"source": [
"try:\n",
" import urlextract # 루트 도메인 이름을 다운로드하기 위해 인터넷 연결이 필요할지 모릅니다\n",
" \n",
" url_extractor = urlextract.URLExtract()\n",
" print(url_extractor.find_urls(\"Will it detect github.com and https://youtu.be/7Pq-S557XQU?t=3m32s\"))\n",
"except ImportError:\n",
" print(\"Error: replacing URLs requires the urlextract module.\")\n",
" url_extractor = None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이들을 모두 하나의 변환기로 연결하여 이메일을 단어 카운트로 바꿀 것입니다. 파이썬의 `split()` 메서드를 사용하면 구둣점과 단어 경계를 기준으로 문장을 단어로 바꿉니다. 이 방법이 많은 언어에 통하지만 전부는 아닙니다. 예를 들어 중국어와 일본어는 일반적으로 단어 사이에 공백을 두지 않습니다. 베트남어는 음절 사이에 공백을 두기도 합니다. 여기서는 데이터셋이 (거의) 영어로 되어 있기 때문에 문제없습니다."
]
},
{
"cell_type": "code",
"execution_count": 151,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.base import BaseEstimator, TransformerMixin\n",
"\n",
"class EmailToWordCounterTransformer(BaseEstimator, TransformerMixin):\n",
" def __init__(self, strip_headers=True, lower_case=True, remove_punctuation=True,\n",
" replace_urls=True, replace_numbers=True, stemming=True):\n",
" self.strip_headers = strip_headers\n",
" self.lower_case = lower_case\n",
" self.remove_punctuation = remove_punctuation\n",
" self.replace_urls = replace_urls\n",
" self.replace_numbers = replace_numbers\n",
" self.stemming = stemming\n",
" def fit(self, X, y=None):\n",
" return self\n",
" def transform(self, X, y=None):\n",
" X_transformed = []\n",
" for email in X:\n",
" text = email_to_text(email) or \"\"\n",
" if self.lower_case:\n",
" text = text.lower()\n",
" if self.replace_urls and url_extractor is not None:\n",
" urls = list(set(url_extractor.find_urls(text)))\n",
" urls.sort(key=lambda url: len(url), reverse=True)\n",
" for url in urls:\n",
" text = text.replace(url, \" URL \")\n",
" if self.replace_numbers:\n",
" text = re.sub(r'\\d+(?:\\.\\d*(?:[eE]\\d+))?', 'NUMBER', text)\n",
" if self.remove_punctuation:\n",
" text = re.sub(r'\\W+', ' ', text, flags=re.M)\n",
" word_counts = Counter(text.split())\n",
" if self.stemming and stemmer is not None:\n",
" stemmed_word_counts = Counter()\n",
" for word, count in word_counts.items():\n",
" stemmed_word = stemmer.stem(word)\n",
" stemmed_word_counts[stemmed_word] += count\n",
" word_counts = stemmed_word_counts\n",
" X_transformed.append(word_counts)\n",
" return np.array(X_transformed)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이 변환기를 몇 개의 이메일에 적용해 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 152,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([Counter({'chuck': 1, 'r': 1, 'stuff': 1, 'murcko': 1, 'yawn': 1, 'wrote': 1}),\n",
" Counter({'the': 11, 'of': 9, 'and': 8, 'by': 3, 'to': 3, 'all': 3, 'christian': 3, 'superstit': 2, 'teach': 2, 'been': 2, 'half': 2, 'jefferson': 2, 'i': 2, 'have': 2, 'one': 2, 'ha': 2, 'rogueri': 2, 'on': 2, 'jesu': 2, 'great': 1, 'found': 1, 'coercion': 1, 'they': 1, 'short': 1, 'band': 1, 'fabl': 1, 'corrupt': 1, 'known': 1, 'imprison': 1, 'url': 1, 'particular': 1, 'million': 1, 'make': 1, 'untruth': 1, 'in': 1, 'our': 1, 'paul': 1, 'featur': 1, 'thoma': 1, 'world': 1, 'william': 1, 'thi': 1, 'burnt': 1, 'men': 1, 'redeem': 1, 'support': 1, 'sinc': 1, 'over': 1, 'some': 1, 'find': 1, 'are': 1, 'letter': 1, 'a': 1, 'innoc': 1, 'becom': 1, 'what': 1, 'john': 1, 'larg': 1, 'word': 1, 'first': 1, 'histor': 1, 'led': 1, 'dupe': 1, 'earth': 1, 'perpetr': 1, 'mytholog': 1, 'import': 1, 'fine': 1, 'again': 1, 'shone': 1, 'introduct': 1, 'e': 1, 'were': 1, 'ever': 1, 'pervert': 1, 'american': 1, 'fool': 1, 'women': 1, 'absurd': 1, 'man': 1, 'quot': 1, 'do': 1, 'system': 1, 'children': 1, 'that': 1, 'effect': 1, 'other': 1, 'most': 1, 'six': 1, 'remsburg': 1, 'interest': 1, 'examin': 1, 'error': 1, 'upon': 1, 'alik': 1, 'not': 1, 'hypocrit': 1, 'tortur': 1}),\n",
" Counter({'url': 5, 's': 3, 'group': 3, 'to': 3, 'an': 2, 'and': 2, 'in': 2, 'we': 2, 'martin': 2, 'unsubscrib': 2, 'is': 2, 'forteana': 2, 'yahoo': 2, 'altern': 1, 'email': 1, 'hamza': 1, 'subject': 1, 'dvd': 1, 'use': 1, 'free': 1, 't': 1, 'y': 1, 'base': 1, 'be': 1, 'includ': 1, 'join': 1, 'your': 1, 'more': 1, 'yemen': 1, 'send': 1, 'rob': 1, 'unbias': 1, 'murder': 1, 'now': 1, 'for': 1, 'on': 1, 'should': 1, 'sponsor': 1, 'p': 1, 'that': 1, 'thi': 1, 'memri': 1, 'know': 1, 'don': 1, 'outright': 1, 'rather': 1, 'number': 1, 'muslim': 1, 'factual': 1, 'belief': 1, 'non': 1, 'html': 1, 'wrote': 1, 'all': 1, 'hi': 1, 'career': 1, 'of': 1, 'adamson': 1, 'how': 1, 'from': 1, 'rundown': 1})],\n",
" dtype=object)"
]
},
"execution_count": 152,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_few = X_train[:3]\n",
"X_few_wordcounts = EmailToWordCounterTransformer().fit_transform(X_few)\n",
"X_few_wordcounts"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"제대로 작동하는 것 같네요!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 단어 카운트를 벡터로 변환해야 합니다. 이를 위해서 또 다른 변환기를 만들겠습니다. 이 변환기는 (자주 나타나는 단어 순으로 정렬된) 어휘 목록을 구축하는 `fit()` 메서드와 어휘 목록을 사용해 단어를 벡터로 바꾸는 `transform()` 메서드를 가집니다. 출력은 희소 행렬이 됩니다."
]
},
{
"cell_type": "code",
"execution_count": 153,
"metadata": {},
"outputs": [],
"source": [
"from scipy.sparse import csr_matrix\n",
"\n",
"class WordCounterToVectorTransformer(BaseEstimator, TransformerMixin):\n",
" def __init__(self, vocabulary_size=1000):\n",
" self.vocabulary_size = vocabulary_size\n",
" def fit(self, X, y=None):\n",
" total_count = Counter()\n",
" for word_count in X:\n",
" for word, count in word_count.items():\n",
" total_count[word] += min(count, 10)\n",
" most_common = total_count.most_common()[:self.vocabulary_size]\n",
" self.most_common_ = most_common\n",
" self.vocabulary_ = {word: index + 1 for index, (word, count) in enumerate(most_common)}\n",
" return self\n",
" def transform(self, X, y=None):\n",
" rows = []\n",
" cols = []\n",
" data = []\n",
" for row, word_count in enumerate(X):\n",
" for word, count in word_count.items():\n",
" rows.append(row)\n",
" cols.append(self.vocabulary_.get(word, 0))\n",
" data.append(count)\n",
" return csr_matrix((data, (rows, cols)), shape=(len(X), self.vocabulary_size + 1))"
]
},
{
"cell_type": "code",
"execution_count": 154,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<3x11 sparse matrix of type '<class 'numpy.int64'>'\n",
"\twith 19 stored elements in Compressed Sparse Row format>"
]
},
"execution_count": 154,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"vocab_transformer = WordCounterToVectorTransformer(vocabulary_size=10)\n",
"X_few_vectors = vocab_transformer.fit_transform(X_few_wordcounts)\n",
"X_few_vectors"
]
},
{
"cell_type": "code",
"execution_count": 155,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n",
" [104, 11, 8, 9, 1, 3, 3, 1, 0, 0, 3],\n",
" [ 60, 0, 2, 1, 5, 3, 1, 2, 3, 3, 0]],\n",
" dtype=int64)"
]
},
"execution_count": 155,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_few_vectors.toarray()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이 행렬은 무엇을 의미하나요? 세 번째 행의 첫 번째 열의 65는 세 번째 이메일이 어휘 목록에 없는 단어를 65개 가지고 있다는 뜻입니다. 그 다음의 0은 어휘 목록에 있는 첫 번째 단어가 한 번도 등장하지 않는다는 뜻이고 그 다음의 1은 한 번 나타난다는 뜻입니다. 이 단어들이 무엇인지 확인하려면 어휘 목록을 보면 됩니다. 첫 번째 단어는 \"the\"이고 두 번째 단어는 \"of\"입니다."
]
},
{
"cell_type": "code",
"execution_count": 156,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'all': 6,\n",
" 'and': 2,\n",
" 'christian': 10,\n",
" 'group': 8,\n",
" 'in': 7,\n",
" 'of': 3,\n",
" 's': 9,\n",
" 'the': 1,\n",
" 'to': 5,\n",
" 'url': 4}"
]
},
"execution_count": 156,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"vocab_transformer.vocabulary_"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"이제 스팸 분류기를 훈련시킬 준비를 마쳤습니다! 전체 데이터셋을 변환시켜보죠:"
]
},
{
"cell_type": "code",
"execution_count": 157,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.pipeline import Pipeline\n",
"\n",
"preprocess_pipeline = Pipeline([\n",
" (\"email_to_wordcount\", EmailToWordCounterTransformer()),\n",
" (\"wordcount_to_vector\", WordCounterToVectorTransformer()),\n",
"])\n",
"\n",
"X_train_transformed = preprocess_pipeline.fit_transform(X_train)"
]
},
{
"cell_type": "code",
"execution_count": 158,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[CV] ................................................................\n",
"[CV] .................................. , score=0.98375, total= 0.0s\n",
"[CV] ................................................................\n",
"[CV] .................................... , score=0.985, total= 0.0s\n",
"[CV] ................................................................\n",
"[CV] ................................... , score=0.9925, total= 0.1s\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"[Parallel(n_jobs=1)]: Done 1 out of 1 | elapsed: 0.0s remaining: 0.0s\n",
"[Parallel(n_jobs=1)]: Done 2 out of 2 | elapsed: 0.1s remaining: 0.0s\n",
"[Parallel(n_jobs=1)]: Done 3 out of 3 | elapsed: 0.2s finished\n"
]
},
{
"data": {
"text/plain": [
"0.9870833333333334"
]
},
"execution_count": 158,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.model_selection import cross_val_score\n",
"\n",
"log_clf = LogisticRegression(random_state=42)\n",
"score = cross_val_score(log_clf, X_train_transformed, y_train, cv=3, verbose=3)\n",
"score.mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"98.7%가 넘네요. 첫 번째 시도치고 나쁘지 않습니다! :) 그러나 이 데이터셋은 비교적 쉬운 문제입니다. 더 어려운 데이터셋에 적용해 보면 결과가 그리 높지 않을 것입니다. 여러개의 모델을 시도해 보고 제일 좋은 것을 골라 교차 검증으로 세밀하게 튜닝해 보세요.\n",
"\n",
"하지만 전체 내용을 파악했으므로 여기서 멈추겠습니다. 테스트 세트에서 정밀도/재현율을 출력해 보겠습니다:"
]
},
{
"cell_type": "code",
"execution_count": 159,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"정밀도: 94.90%\n",
"재현율: 97.89%\n"
]
}
],
"source": [
"from sklearn.metrics import precision_score, recall_score\n",
"\n",
"X_test_transformed = preprocess_pipeline.transform(X_test)\n",
"\n",
"log_clf = LogisticRegression(random_state=42)\n",
"log_clf.fit(X_train_transformed, y_train)\n",
"\n",
"y_pred = log_clf.predict(X_test_transformed)\n",
"\n",
"print(\"정밀도: {:.2f}%\".format(100 * precision_score(y_test, y_pred)))\n",
"print(\"재현율: {:.2f}%\".format(100 * recall_score(y_test, y_pred)))"
]
}
],
"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.5"
},
"nav_menu": {},
"toc": {
"navigate_menu": true,
"number_sections": true,
"sideBar": true,
"threshold": 6,
"toc_cell": false,
"toc_section_display": "block",
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 1
}