Skip to content

Instantly share code, notes, and snippets.

@sshojiro
Created November 13, 2019 11:32
Show Gist options
  • Save sshojiro/59b8b88c5fb312eac6c04a5d93f099f1 to your computer and use it in GitHub Desktop.
Save sshojiro/59b8b88c5fb312eac6c04a5d93f099f1 to your computer and use it in GitHub Desktop.
linear_svm.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "linear_svm.ipynb",
"provenance": [],
"collapsed_sections": [],
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/sshojiro/59b8b88c5fb312eac6c04a5d93f099f1/linear_svm.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YuHDkg4q5wi-",
"colab_type": "text"
},
"source": [
"# Kernel Multivariate Analysis\n",
"\n",
"[Kernel Multivariate Analysis (japanese one)](https://www.amazon.co.jp/%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E5%A4%9A%E5%A4%89%E9%87%8F%E8%A7%A3%E6%9E%90%E2%80%95%E9%9D%9E%E7%B7%9A%E5%BD%A2%E3%83%87%E3%83%BC%E3%82%BF%E8%A7%A3%E6%9E%90%E3%81%AE%E6%96%B0%E3%81%97%E3%81%84%E5%B1%95%E9%96%8B-%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E7%A2%BA%E7%8E%87%E3%81%A8%E6%83%85%E5%A0%B1%E3%81%AE%E7%A7%91%E5%AD%A6-%E8%B5%A4%E7%A9%82-%E6%98%AD%E5%A4%AA%E9%83%8E/dp/4000069713)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "i1x28bY37FFO",
"colab_type": "text"
},
"source": [
"http://cvxopt.org/examples/tutorial/qp.html\n",
"\n",
"$ \\rm{min}\\hspace{0.1cm}\\it{x}^{\\rm{T}}Qx+px $\n",
"\n",
"such that\n",
"\n",
"$ Gx\\leq h, Ax=b $\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "80a9oZ2xA1hL",
"colab_type": "code",
"colab": {}
},
"source": [
"import numpy as np\n",
"from scipy.spatial.distance import cdist,pdist, squareform\n",
"from sklearn.datasets import load_iris"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "Q4KjxsJkZw1K",
"colab_type": "code",
"colab": {}
},
"source": [
"Xorig,yorig = load_iris(return_X_y=True)\n",
"y = np.concatenate( (yorig[yorig==0], yorig[yorig==1]), axis=0)\n",
"y[y==0] = -1.\n",
"X = np.concatenate((Xorig[np.where(yorig==0)[0],:],Xorig[np.where(yorig==1)[0],:]),axis=0)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "_0Mjo3OggIOh",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 187
},
"outputId": "e2430238-c5d9-41a4-8c59-d3c73bd8c7a0"
},
"source": [
"KK = np.matrix([[np.dot(X[i,:],X[j,:]) for i in range(X.shape[0])]for j in range(X.shape[0])])\n",
"print(np.dot(X[0,:],X[0,:]), '\\n', squareform(pdist(X, lambda x,y:np.dot(x,y)))) # must be equal but...\n",
"\n",
"if not all(np.equal(squareform(pdist(X, lambda x,y:np.dot(x,y))), KK)):\n",
" print('pdist provides zero elements for the diagnal elements of the output.')\n",
"if all(np.equal(cdist(X, X, lambda x,y:np.dot(x,y)), KK)):\n",
" print('cdist is acceptable, but slow.')"
],
"execution_count": 174,
"outputs": [
{
"output_type": "stream",
"text": [
"40.26 \n",
" [[ 0. 37.49 37.03 ... 48.05 39.18 44.87]\n",
" [37.49 0. 34.49 ... 45.36 36.91 42.33]\n",
" [37.03 34.49 0. ... 44.27 36.09 41.34]\n",
" ...\n",
" [48.05 45.36 44.27 ... 0. 53.2 62.78]\n",
" [39.18 36.91 36.09 ... 53.2 0. 49.8 ]\n",
" [44.87 42.33 41.34 ... 62.78 49.8 0. ]]\n",
"pdist provides zero elements for the diagnal elements of the output.\n",
"cdist is acceptable, but slow.\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "mXjMLrI3_SMc",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 629
},
"outputId": "55d099f5-a606-4a7a-a73c-fe5102c7a146"
},
"source": [
"# ラグランジュ乗数を二次計画法(Quadratic Programming)で求める\n",
"N = X.shape[0]\n",
"K = np.zeros((N,N))\n",
"K_x = squareform(pdist(X, lambda x,y:np.dot(x,y)))\n",
"for i in range(N):\n",
" for j in range(N):\n",
" K[i, j] = y[i] * y[j] * np.dot(X[i,:],X[j,:])\n",
"# L_dual = gamma * alpha - alpha.T * (y.T * K * y) * alpha -> max\n",
"# - L_dual -> min in solvers.qp\n",
"Q = cvxopt.matrix(K)\n",
"p = cvxopt.matrix(-np.ones(N)) # -1がN個の列ベクトル\n",
"G = cvxopt.matrix(np.diag([-1.0]*N)) # 対角成分が-1のNxN行列\n",
"h = cvxopt.matrix(np.zeros(N)) # 0がN個の列ベクトル\n",
"A = cvxopt.matrix(array(y.tolist()).astype('double'), (1,N))# N個の教師信号が要素の行ベクトル(1xN)\n",
"# Cast A to double type, thanks to a post on stack overflow https://stackoverflow.com/questions/36510859/cvxopt-qp-solver-typeerror-a-must-be-a-d-matrix-with-1000-columns\n",
"b = cvxopt.matrix(0.0) # 定数0.0\n",
"sol = cvxopt.solvers.qp(Q, p, G, h, A, b) # 二次計画法でラグランジュ乗数aを求める\n",
"a = array(sol['x']).reshape(N) # 'x'がaに対応する\n",
"print(a)\n"
],
"execution_count": 161,
"outputs": [
{
"output_type": "stream",
"text": [
" pcost dcost gap pres dres\n",
" 0: -3.9465e+00 -6.9439e+00 2e+02 1e+01 2e+00\n",
" 1: -1.4432e+00 -2.0830e+00 2e+01 1e+00 1e-01\n",
" 2: -3.2790e-01 -1.3980e+00 2e+00 5e-02 5e-03\n",
" 3: -5.1882e-01 -7.6752e-01 3e-01 4e-03 5e-04\n",
" 4: -5.8889e-01 -8.1845e-01 3e-01 3e-03 3e-04\n",
" 5: -7.1313e-01 -7.5571e-01 4e-02 2e-04 2e-05\n",
" 6: -7.4690e-01 -7.4817e-01 1e-03 1e-06 1e-07\n",
" 7: -7.4805e-01 -7.4806e-01 1e-05 1e-08 2e-09\n",
" 8: -7.4806e-01 -7.4806e-01 1e-07 1e-10 2e-11\n",
"Optimal solution found.\n",
"[2.24761794e-09 4.09846137e-09 2.38370393e-09 4.80162818e-09\n",
" 2.05193612e-09 3.53769742e-09 2.58427175e-09 3.07558369e-09\n",
" 4.65617861e-09 4.21695047e-09 2.31827654e-09 4.08141748e-09\n",
" 3.53204549e-09 1.81086236e-09 1.39151465e-09 1.66336890e-09\n",
" 1.66502410e-09 2.42549572e-09 3.72787825e-09 2.22327217e-09\n",
" 6.91253905e-09 2.65134220e-09 1.23379963e-09 6.71332988e-01\n",
" 8.96125917e-07 1.44144088e-08 6.00850626e-09 2.77761071e-09\n",
" 2.48841471e-09 6.23200906e-09 8.73647367e-09 4.10038009e-09\n",
" 1.66529977e-09 1.51538144e-09 4.98468690e-09 2.03448823e-09\n",
" 1.96517255e-09 1.91842436e-09 2.89891210e-09 3.10373766e-09\n",
" 2.01062404e-09 7.67238122e-02 2.32688598e-09 7.27925672e-09\n",
" 1.31044187e-08 4.76233807e-09 2.49810991e-09 2.95683358e-09\n",
" 2.29919433e-09 2.72037255e-09 7.72610987e-10 8.79501736e-10\n",
" 6.53318498e-10 1.00790612e-09 7.21754720e-10 8.32220663e-10\n",
" 7.75383305e-10 4.54589082e-09 7.78502688e-10 1.31160073e-09\n",
" 1.74207133e-09 1.05262300e-09 1.04985551e-09 7.28852053e-10\n",
" 2.45299073e-09 9.31357247e-10 8.47958560e-10 1.23691146e-09\n",
" 6.72038323e-10 1.32311107e-09 6.95684275e-10 1.24239270e-09\n",
" 5.93801058e-10 7.40955572e-10 9.74641661e-10 8.99430639e-10\n",
" 6.53877169e-10 5.92273078e-10 8.06505799e-10 2.85841995e-09\n",
" 1.40759495e-09 1.70753937e-09 1.40122721e-09 5.70808264e-10\n",
" 8.56014999e-10 9.35129509e-10 7.36386413e-10 7.42965486e-10\n",
" 1.28069903e-09 1.09956701e-09 8.61392780e-10 7.97719715e-10\n",
" 1.18752595e-09 3.78344175e-09 1.00538007e-09 1.20115997e-09\n",
" 1.09546862e-09 9.82758941e-10 7.48057813e-01 1.14675695e-09]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "bo7Y93lEc_U8",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
},
"outputId": "8e50ca4e-6df3-4089-d371-d8b60c8bf617"
},
"source": [
"threshold = .00001\n",
"\n",
"SV = np.where(a>=threshold)[0]\n",
"SV"
],
"execution_count": 162,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"array([23, 41, 98])"
]
},
"metadata": {
"tags": []
},
"execution_count": 162
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pR8OxHc6Rlhx",
"colab_type": "text"
},
"source": [
"## Linear SVM\n",
"\n",
"[Blog Post](http://aidiary.hatenablog.com/entry/20100501/1272712699)\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "00hdXe7o6T5E",
"colab_type": "code",
"outputId": "c0e2b888-e74d-40fb-ad2e-4e89488f40ac",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 473
}
},
"source": [
"import numpy as np\n",
"from scipy.linalg import norm\n",
"import cvxopt\n",
"import cvxopt.solvers\n",
"from pylab import *\n",
"\n",
"N = 100 # データ数\n",
"\n",
"def f(x1, w, b):\n",
" return - (w[0] / w[1]) * x1 - (b / w[1])\n",
"\n",
"def kernel(x, y):\n",
" return np.dot(x, y) # 線形カーネル\n",
"\n",
"\n",
"# 訓練データを作成\n",
"cls1 = []\n",
"cls2 = []\n",
"\n",
"mean1 = [-1, 2]\n",
"mean2 = [1, -1]\n",
"cov = [[1.0,0.8], [0.8, 1.0]]\n",
"half_n = int(N/2)\n",
"cls1.extend(np.random.multivariate_normal(mean1, cov, half_n))\n",
"cls2.extend(np.random.multivariate_normal(mean2, cov, half_n))\n",
"\n",
"# データ行列Xを作成\n",
"X = vstack((cls1, cls2))\n",
"\n",
"# ラベルtを作成\n",
"t = []\n",
"for i in range(half_n):\n",
" t.append(1.0) # クラス1\n",
"for i in range(half_n):\n",
" t.append(-1.0) # クラス2\n",
"t = array(t)\n",
"\n",
"# ラグランジュ乗数を二次計画法(Quadratic Programming)で求める\n",
"K = np.zeros((N, N))\n",
"for i in range(N):\n",
" for j in range(N):\n",
" K[i, j] = t[i] * t[j] * kernel(X[i], X[j])\n",
"# L_dual = gamma * alpha - alpha.T * (y.T * K * y) * alpha -> max\n",
"# - L_dual -> min in solvers.qp\n",
"Q = cvxopt.matrix(K)\n",
"p = cvxopt.matrix(-np.ones(N)) # -1がN個の列ベクトル\n",
"G = cvxopt.matrix(np.diag([-1.0]*N)) # 対角成分が-1のNxN行列\n",
"h = cvxopt.matrix(np.zeros(N)) # 0がN個の列ベクトル\n",
"A = cvxopt.matrix(t, (1,N)) # N個の教師信号が要素の行ベクトル(1xN)\n",
"b = cvxopt.matrix(0.0) # 定数0.0\n",
"sol = cvxopt.solvers.qp(Q, p, G, h, A, b) # 二次計画法でラグランジュ乗数aを求める\n",
"a = array(sol['x']).reshape(N) # 'x'がaに対応する\n",
"# print( a)\n",
"\n",
"\n",
"\n",
"# サポートベクトルのインデックスを抽出\n",
"S = []\n",
"for i in range(len(a)):\n",
" if a[i] < 0.00001: continue\n",
" S.append(i)\n",
"\n",
"# wを計算\n",
"w = np.zeros(2)\n",
"for n in S:\n",
" w += a[n] * t[n] * X[n]\n",
"\n",
"# bを計算\n",
"sum = 0\n",
"for n in S:\n",
" temp = 0\n",
" for m in S:\n",
" temp += a[m] * t[m] * kernel(X[n], X[m])\n",
" sum += (t[n] - temp)\n",
"b = sum / len(S)\n",
"\n",
"print( S, b)\n",
"\n",
"# 訓練データを描画\n",
"x1, x2 = np.array(cls1).transpose()\n",
"plot(x1, x2, 'rx')\n",
"\n",
"x1, x2 = np.array(cls2).transpose()\n",
"plot(x1, x2, 'bx')\n",
"\n",
"# サポートベクトルを描画\n",
"for n in S:\n",
" scatter(X[n,0], X[n,1], s=80, c='c', marker='o')\n",
"\n",
"# 識別境界を描画\n",
"x1 = np.linspace(-6, 6, 1000)\n",
"x2 = [f(x, w, b) for x in x1]\n",
"plot(x1, x2, 'g-')\n",
"\n",
"xlim(-6, 6)\n",
"ylim(-6, 6)\n",
"show()"
],
"execution_count": 130,
"outputs": [
{
"output_type": "stream",
"text": [
" pcost dcost gap pres dres\n",
" 0: -7.3675e+00 -1.4603e+01 3e+02 2e+01 2e+00\n",
" 1: -1.0653e+01 -9.8805e+00 1e+02 7e+00 8e-01\n",
" 2: -2.6799e+01 -1.4985e+01 1e+02 4e+00 5e-01\n",
" 3: -2.4022e+01 -8.9103e+00 4e+01 1e+00 1e-01\n",
" 4: -5.0380e+00 -5.6137e+00 4e+00 6e-02 7e-03\n",
" 5: -4.5350e+00 -4.6529e+00 1e-01 7e-04 8e-05\n",
" 6: -4.6178e+00 -4.6203e+00 3e-03 8e-06 9e-07\n",
" 7: -4.6199e+00 -4.6199e+00 3e-05 8e-08 9e-09\n",
" 8: -4.6199e+00 -4.6199e+00 3e-07 8e-10 9e-11\n",
"Optimal solution found.\n",
"[28, 94] -1.8540954210053662\n"
],
"name": "stdout"
},
{
"output_type": "display_data",
"data": {
"image/png": "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\nTkSuQmCC\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"tags": []
}
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "H0iENk_-Y7Mv",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
},
"outputId": "a588b1b4-f60b-4d9e-d0bc-977435fdef79"
},
"source": [
"S"
],
"execution_count": 102,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"[34, 68, 93]"
]
},
"metadata": {
"tags": []
},
"execution_count": 102
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment