{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Kernelized Classification\n", "\n", "Both perceptron and SVM can be kernelized, i.e. the output of the regressor can be passed through the sign function. \n", "\n", "$$ \\hat{y} = \\text{sign} \\left[ \\sum_{i=1}^N \\alpha_i y_i K(x_i, x) \\right] $$ and a perceptron loss applied to the difference between the predictor and the true value. \n", "\n", "The perceptron loss can be posed as:\n", "\n", "$$ L(\\alpha;x_j, y_j) = \\max \\left\\{0, -\\sum_{j=1}^N y_j \\alpha_i K(x_i, x_j) \\right\\} $$ \n", "\n", "The parameters are updated as follows: \n", "If $\\hat{y}(x) \\neq y(x)$, set $\\alpha \\gets \\alpha + \\eta_t$. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Code source: Sebastian Curi and Andreas Krause, based on Jaques Grobler (sklearn demos).\n", "# License: BSD 3 clause\n", "\n", "%matplotlib inline\n", "%load_ext autoreload\n", "%autoreload 2\n", "import ipywidgets\n", "from ipywidgets import interact, interactive, interact_manual\n", "import IPython\n", "from IPython.display import display, clear_output\n", "from matplotlib import rcParams \n", "rcParams['figure.figsize'] = (10, 5)\n", "rcParams['font.size'] = 16\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "from utilities.util import gradient_descent\n", "from utilities.load_data import linear_separable_data, circular_separable_data\n", "from utilities import plot_helpers \n", "from utilities.classifiers import kNN\n", "from utilities.kernels import LinearKernel, PolynomialKernel, GaussianKernel, PeriodicKernel, LaplacianKernel, SumKernel\n", "\n", "from sklearn import svm\n", "from sklearn import datasets\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "num_points = 100 # Number of points per class\n", "noise = 0.2 # Noise Level (needed for data generation).\n", "\n", "X, Y = circular_separable_data(num_points, noise=noise, offset=1)\n", "fig = plt.subplot(111)\n", "opt = {'marker': 'r*', 'label': '+'}\n", "plot_helpers.plot_data(X[np.where(Y == 1)[0], 0], X[np.where(Y == 1)[0], 1], fig=fig, options=opt)\n", "opt = {'marker': 'bs', 'label': '-'}\n", "plot_helpers.plot_data(X[np.where(Y == -1)[0], 0], X[np.where(Y == -1)[0], 1], fig=fig, options=opt)\n", "fig.legend();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Kernelized Perceptron Demo" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rcParams['figure.figsize'] = (10, 5)\n", "rcParams['font.size'] = 16\n", "\n", "kernel_widget = ipywidgets.RadioButtons(options=['Linear', 'Polynomial-2', 'Polynomial-3', 'Gaussian', 'Laplacian'], \n", " value='Linear',\n", " description='Kernel type:', style={'description_width': 'initial'})\n", "bs_widget = ipywidgets.IntSlider(value=100, min=1, max=200, step=1, description='Batch Size:',\n", " style={'description_width': 'initial'}, continuous_update=False)\n", "n_iter_widget = ipywidgets.IntSlider(value=20, min=5, max=50, step=1, description='Number of iterations:',\n", " style={'description_width': 'initial'}, continuous_update=False)\n", "def kernelized_perceptron(kernel, batch_size, n_iter):\n", " if kernel == 'Linear':\n", " classifier = PolynomialKernel(X, Y, reg=0.00, deg=1, prediction=False)\n", " elif kernel == 'Polynomial-2':\n", " classifier = PolynomialKernel(X, Y, reg=0.00, deg=2, prediction=False)\n", " elif kernel == 'Polynomial-3':\n", " classifier = PolynomialKernel(X, Y, reg=0.00, deg=3, prediction=False)\n", " elif kernel == 'Gaussian':\n", " classifier = GaussianKernel(X, Y, reg=0.00, bw=0.2, prediction=False) \n", " elif kernel == 'Laplacian':\n", " classifier = LaplacianKernel(X, Y, reg=0.00, bw=0.2, prediction=False) \n", " \n", " alpha0 = 0 * np.random.randn(X.shape[0])\n", "\n", " opts = {'eta0': 0.5,\n", " 'n_iter': n_iter,\n", " 'batch_size': batch_size,\n", " 'n_samples': X.shape[0],\n", " 'algorithm': 'SGD',\n", " 'learning_rate_scheduling': None\n", " }\n", " try:\n", " alphas, indexes = gradient_descent(alpha0, classifier, opts=opts)\n", "\n", " fig = plt.subplot(111)\n", " opt = {'marker': 'r*', 'label': '+'}\n", " plot_helpers.plot_data(X[np.where(Y == 1)[0], 0], X[np.where(Y == 1)[0], 1], fig=fig, options=opt)\n", " opt = {'marker': 'bs', 'label': '-'}\n", " plot_helpers.plot_data(X[np.where(Y == -1)[0], 0], X[np.where(Y == -1)[0], 1], fig=fig, options=opt)\n", "\n", " contour_opts = {'n_points': 20, 'x_label': '$x$', 'y_label': '$y$', 'sgd_point': False, 'n_classes': 2}\n", " opts = {'contour_opts': contour_opts}\n", " plot_helpers.classification_progression(X, Y, alphas, indexes, classifier, contour_plot=fig, options=opts)\n", "\n", " except KeyboardInterrupt:\n", " pass \n", " \n", "interact_manual(kernelized_perceptron, kernel=kernel_widget, batch_size=bs_widget, n_iter=n_iter_widget);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Kernelized SVM Demo" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rcParams['figure.figsize'] = (10, 5)\n", "rcParams['font.size'] = 16\n", "\n", "def laplacian_kernel(X, Y, bw):\n", " rows = X.shape[0]\n", " cols = Y.shape[0]\n", " K = np.zeros((rows, cols))\n", " for col in range(cols):\n", " dist = bw * np.linalg.norm(X - Y[col, :], ord=1, axis=1)\n", " K[:, col] = np.exp(-dist)\n", " return K\n", "\n", "# Our dataset and targets\n", "n_samples = 200 # Number of points per class\n", "tol = 1e-1\n", "\n", "def kernelized_svm(dataset, kernel, reg, bw, deg, noise):\n", " if dataset is 'blobs':\n", " X, Y = datasets.make_blobs(n_samples=n_samples, centers=2, random_state=3, cluster_std=10*noise)\n", " elif dataset is 'circles':\n", " X, Y = datasets.make_circles(n_samples=n_samples, factor=.5, noise=noise, random_state=42)\n", " elif dataset is 'moons':\n", " X, Y = datasets.make_moons(n_samples=n_samples, noise=noise, random_state=42)\n", " elif dataset == 'xor':\n", " np.random.seed(42)\n", " step = int(n_samples/4)\n", " \n", " X = np.zeros((n_samples, 2))\n", " Y = np.zeros(n_samples)\n", " \n", " X[0*step:1*step, :] = noise * np.random.randn(step, 2)\n", " Y[0*step:1*step] = 1\n", " X[1*step:2*step, :] = np.array([1, 1]) + noise * np.random.randn(step, 2)\n", " Y[1*step:2*step] = 1\n", " \n", " X[2*step:3*step, :] = np.array([0, 1]) + noise * np.random.randn(step, 2)\n", " Y[2*step:3*step] = -1\n", " X[3*step:4*step, :] = np.array([1, 0]) + noise * np.random.randn(step, 2)\n", " Y[3*step:4*step] = -1\n", " \n", " elif dataset == 'periodic':\n", " np.random.seed(42)\n", " step = int(n_samples/4)\n", " \n", " X = np.zeros((n_samples, 2))\n", " Y = np.zeros(n_samples)\n", " \n", " X[0*step:1*step, :] = noise * np.random.randn(step, 2)\n", " Y[0*step:1*step] = 1\n", " X[1*step:2*step, :] = np.array([0, 2]) + noise * np.random.randn(step, 2)\n", " Y[1*step:2*step] = 1\n", " \n", " X[2*step:3*step, :] = np.array([0, 1]) + noise * np.random.randn(step, 2)\n", " Y[2*step:3*step] = -1\n", " X[3*step:4*step, :] = np.array([0, 3]) + noise * np.random.randn(step, 2)\n", " Y[3*step:4*step] = -1\n", " \n", " X = X[Y <= 1, :]\n", " Y = Y[Y <=1 ]\n", " Y[Y==0] = -1\n", " \n", " # Add the 1 feature. \n", " X = np.concatenate((X, np.ones((X.shape[0], 1))), axis=1)\n", " plot_support = True\n", " if kernel == 'poly':\n", " gamma = 1\n", " coef0 = 0\n", " elif kernel == 'sigmoid':\n", " gamma = np.power(10., bw)\n", " coef0 = 0\n", " elif kernel == 'rbf':\n", " gamma = np.power(10., -bw)\n", " coef0 = 0\n", " elif kernel == 'laplacian':\n", " gamma = np.power(10., -bw)\n", " coef0 = 0\n", " kernel = lambda X, Y: laplacian_kernel(X, Y, gamma)\n", " plot_support = False\n", "\n", " classifier = svm.SVC(kernel=kernel, C=np.power(10., -reg), gamma=gamma, degree=deg, coef0=coef0, tol=tol)\n", " classifier.fit(X, Y)\n", "\n", " # plot the line, the points, and the nearest vectors to the plane\n", " plt.figure()\n", " plt.clf()\n", " fig = plt.axes()\n", " opt = {'marker': 'r*', 'label': '+'}\n", " plot_helpers.plot_data(X[np.where(Y == 1)[0], 0], X[np.where(Y == 1)[0], 1], fig=fig, options=opt)\n", " opt = {'marker': 'bs', 'label': '-'}\n", " plot_helpers.plot_data(X[np.where(Y == -1)[0], 0], X[np.where(Y == -1)[0], 1], fig=fig, options=opt)\n", " \n", " if plot_support:\n", " plt.scatter(classifier.support_vectors_[:, 0], classifier.support_vectors_[:, 1], s=80,\n", " facecolors='none', edgecolors='k')\n", "\n", " mins = np.min(X, 0)\n", " maxs = np.max(X, 0)\n", " x_min = mins[0] - 1\n", " x_max = maxs[0] + 1\n", " y_min = mins[1] - 1\n", " y_max = maxs[1] + 1\n", "\n", " XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j] \n", " Xtest = np.c_[XX.ravel(), YY.ravel(), np.ones_like(XX.ravel())]\n", " Z = classifier.decision_function(Xtest)\n", "\n", " # Put the result into a color plot\n", " Z = Z.reshape(XX.shape)\n", " plt.contourf(XX, YY, Z > 0, cmap=plt.cm.jet, alpha=0.3)\n", " plt.contour(XX, YY, Z, colors=['k', 'k', 'k'], linestyles=['--', '-', '--'], levels=[-.99, 0, .99])\n", "\n", " plt.xlim(x_min, x_max)\n", " plt.ylim(y_min, y_max)\n", "\n", "\n", "interact(kernelized_svm, \n", " dataset=['blobs', 'circles', 'moons', 'xor', 'periodic'],\n", " kernel=['poly', 'rbf', 'laplacian'], \n", " reg=ipywidgets.FloatSlider(value=-3,\n", " min=-3,\n", " max=3,\n", " step=0.5,\n", " readout_format='.1f',\n", " description='Regularization 10^:',\n", " style={'description_width': 'initial'},\n", " continuous_update=False),\n", " bw=ipywidgets.FloatSlider(value=-1,\n", " min=-3,\n", " max=3,\n", " step=0.1,\n", " readout_format='.1f',\n", " description='Bandwidth 10^:',\n", " style={'description_width': 'initial'},\n", " continuous_update=False), \n", " deg=ipywidgets.IntSlider(\n", " value=1,\n", " min=1,\n", " max=10, \n", " step=1,\n", " description='Degree of Poly:',\n", " style={'description_width': 'initial'}),\n", " noise=ipywidgets.FloatSlider(value=0.05,\n", " min=0.01,\n", " max=0.3,\n", " step=0.01,\n", " readout_format='.2f',\n", " description='Noise level:',\n", " style={'description_width': 'initial'},\n", " continuous_update=False), \n", " );" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## KNN\n", "\n", "The K-Nearest Neighbors classifier is very easy. The label of a next sample is the label most voted by the $k$ training samples that are closer to this sample.\n", "\n", "A simple implementation is $$\\hat{y} = \\text{sign}\\left\\{\\sum_{i \\in \\mathcal{N}_k (x)} K(x_i, x) y_i\\right\\},$$\n", "\n", "where $\\mathcal{N}_k (x)$ is the set with the $k$ closest neighbours of $x$, $K(x_i, x)$ is a weighting coefficient, and $y_i$ is the label of example $i$. Usually $K(\\cdot, \\cdot)$ can be a kernel function, that measures the similarity between two points. In the vanilla k-NN method the kernel is just the identity function. \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "k_widget = ipywidgets.IntSlider(value=1, min=1, max=9, step=1, description='k',\n", " style={'description_width': 'initial'}, continuous_update=False)\n", "noise_widget = ipywidgets.FloatSlider(value=0.4, min=0, max=1, step=0.1, description='Noise',\n", " style={'description_width': 'initial'}, continuous_update=False)\n", "\n", "def change_k_nn(k, noise):\n", " np.random.seed(0)\n", " X, Y = circular_separable_data(num_points, noise=noise, offset=1)\n", " classifier = kNN(X, Y, k)\n", " fig = plt.subplot(111)\n", " opt = {'marker': 'r*', 'label': '+'}\n", " plot_helpers.plot_data(X[np.where(Y == 1)[0], 0], X[np.where(Y == 1)[0], 1], fig=fig, options=opt)\n", " opt = {'marker': 'bs', 'label': '-'}\n", " plot_helpers.plot_data(X[np.where(Y == -1)[0], 0], X[np.where(Y == -1)[0], 1], fig=fig, options=opt)\n", "\n", " opt = {'n_points': 20, 'x_label': '$x$', 'y_label': '$y$'}\n", " plot_helpers.plot_classification_boundaries(X, classifier, fig=fig, options=opt)\n", "\n", "interact(change_k_nn, k=k_widget, noise=noise_widget);\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Kernelized Regression\n", "\n", "The true response function $f: x \\to y$ is defined as: $$ f(x) = x + \\sin(5x) - \\cos(10x),$$ \n", "and measured outputs $y$ at inputs $x$ are corrupted with zero mean gaussian noise. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rcParams['figure.figsize'] = (10, 5)\n", "rcParams['font.size'] = 16\n", "\n", "num_points = 100\n", "xmin = 0\n", "xmax = 10\n", "noise = 0.2\n", "\n", "X = np.reshape(np.linspace(xmin, xmax, num_points), [-1, 1]) # create 1-D input data\n", "F = X + np.sin(X * 5) - np.cos(X * 10) # true functional response\n", "Y = F + noise * np.random.randn(num_points, 1) # generate noisy labels\n", "\n", "# Training Data\n", "training_idx = np.arange(0, 50, 2)\n", "Xtr = X[training_idx, :]\n", "Ytr = Y[training_idx]\n", "\n", "# Test Data\n", "test_idx = np.setdiff1d(np.arange(0, num_points, 1), training_idx)\n", "Xtest = X[test_idx, :]\n", "Ytest = Y[test_idx]\n", "\n", "fig = plt.subplot(111)\n", "opt = {'marker': 'r*', 'label': 'Training data'}\n", "plot_helpers.plot_data(Xtr, Ytr, fig=fig, options=opt)\n", "opt = {'marker': 'bo', 'label': 'Test data'}\n", "plot_helpers.plot_data(Xtest, Ytest, fig=fig, options=opt)\n", "opt = {'marker': 'k-', 'label': 'True Function', 'x_label': '$x$', 'y_label': '$y$', 'legend': True, 'linewidth': 2}\n", "plot_helpers.plot_data(X, F, fig=fig, options=opt)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rcParams['figure.figsize'] = (10, 5)\n", "rcParams['font.size'] = 16\n", "def kernel_regression(kernel, reg, deg, noise):\n", " np.random.seed(0)\n", " X = np.reshape(np.linspace(xmin, xmax, num_points), [-1, 1]) # create 1-D input data\n", " F = X + np.sin(X * 5) - np.cos(X * 10) # true functional response\n", " Y = F + noise * np.random.randn(num_points, 1) # generate noisy labels\n", " \n", " # Training Data\n", " training_idx = np.arange(0, 50, 2)\n", " Xtr = X[training_idx, :]\n", " Ytr = Y[training_idx]\n", " \n", " test_idx = np.setdiff1d(np.arange(0, num_points, 1), training_idx)\n", " Xtest = X[test_idx, :]\n", " Ytest = Y[test_idx]\n", "\n", "\n", " bw = 0.2\n", " freq = 1\n", " if kernel == 'Polynomial':\n", " regressor = PolynomialKernel(Xtr, Ytr, deg=deg, reg=reg)\n", " elif kernel == 'Laplacian':\n", " regressor = LaplacianKernel(Xtr, Ytr, reg=reg, bw=bw)\n", " elif kernel == 'Gaussian':\n", " regressor = GaussianKernel(Xtr, Ytr, reg=reg, bw=bw)\n", " elif kernel == 'Periodic':\n", " regressor = PeriodicKernel(Xtr, Ytr, reg=reg, bw=0.2, freq=freq)\n", " elif kernel == 'Gaussian + Periodic':\n", " regressor = SumKernel([GaussianKernel, PeriodicKernel], Xtr, Ytr, reg=reg, bw=[bw, bw], freq=freq)\n", " elif kernel == 'Linear + Periodic':\n", " regressor = SumKernel([PolynomialKernel, PeriodicKernel], Xtr, Ytr, reg=reg, deg=1, bw=bw, freq=freq)\n", " \n", " regressor.calculate_alpha(Ytr)\n", " ypr = regressor.predict(X)\n", "\n", " fig = plt.subplot(111)\n", " opt = {'marker': 'r*', 'label': 'Training data'}\n", " plot_helpers.plot_data(Xtr, Ytr, fig=fig, options=opt)\n", " opt = {'marker': 'bo', 'label': 'Test data'}\n", " plot_helpers.plot_data(Xtest, Ytest, fig=fig, options=opt)\n", " opt = {'marker': 'g-', 'label': kernel + ' Kernel', 'x_label': '$x$', 'y_label': '$y$', 'legend': True, 'linewidth': 3}\n", " plot_helpers.plot_data(X, ypr, fig=fig, options=opt)\n", " \n", " opt = {'marker': 'k-', 'label': 'True Function', 'x_label': '$x$', 'y_label': '$y$', 'legend': True, 'linewidth': 2}\n", " plot_helpers.plot_data(X, F, fig=fig, options=opt)\n", "\n", " fig.set_xlim([-1, 11])\n", " fig.set_ylim([-1, 11])\n", "\n", "interact(kernel_regression,\n", " kernel=['Polynomial', 'Laplacian', 'Gaussian', 'Periodic', \n", " 'Gaussian + Periodic', 'Linear + Periodic'],\n", " reg=ipywidgets.FloatLogSlider(\n", " value=-1,\n", " min=-3,\n", " max=3,\n", " step=1e-12,\n", " readout_format='.3f',\n", " description='Regularization:',\n", " style={'description_width': 'initial'},\n", " continuous_update=False),\n", " deg = ipywidgets.IntSlider(\n", " value=1,\n", " min=1,\n", " max=10, \n", " step=1,\n", " description='Degree of Polynomial kernel:',\n", " style={'description_width': 'initial'}),\n", " kernel_width=ipywidgets.FloatSlider(\n", " value=0.2,\n", " min=0.01,\n", " max=3,\n", " step=0.01,\n", " readout_format='.3f',\n", " description='Kernel Width:',\n", " style={'description_width': 'initial'},\n", " continuous_update=False),\n", " noise=ipywidgets.FloatSlider(value=0.2, min=0, max=1)\n", " );\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Parameter Selection" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rcParams['figure.figsize'] = (10, 5)\n", "rcParams['font.size'] = 16\n", "\n", "def parameter_variation(kernel, reg=0.05, kernel_width=5, frequency=1):\n", " if kernel == 'Laplacian':\n", " regressor = LaplacianKernel(Xtr, Ytr, reg=reg, bw=kernel_width)\n", " elif kernel == 'Gaussian':\n", " regressor = GaussianKernel(Xtr, Ytr, reg=reg, bw=kernel_width)\n", " elif kernel == 'Periodic':\n", " regressor = PeriodicKernel(Xtr, Ytr, reg=reg, bw=kernel_width, freq=frequency)\n", " regressor.calculate_alpha(Ytr)\n", " ypr = regressor.predict(X)\n", " \n", " fig = plt.subplot(111)\n", " opt = {'marker': 'r*', 'label': 'Training data'}\n", " plot_helpers.plot_data(Xtr, Ytr, fig=fig, options=opt)\n", " opt = {'marker': 'bo', 'label': 'Test data'}\n", " plot_helpers.plot_data(Xtest, Ytest, fig=fig, options=opt)\n", "\n", " opt = {'marker': 'g-', 'label': 'Gaussian Kernel', 'x_label': '$x$', 'y_label': '$y$', 'legend': True}\n", " plot_helpers.plot_data(X, ypr, fig=fig, options=opt)\n", "\n", "\n", "interact(parameter_variation,\n", " kernel=['Laplacian', 'Gaussian', 'Periodic'],\n", " kernel_width=ipywidgets.FloatSlider(\n", " value=0.2,\n", " min=0.01,\n", " max=10,\n", " step=0.01,\n", " readout_format='.3f',\n", " description='Kernel Width:',\n", " style={'description_width': 'initial'},\n", " continuous_update=False),\n", " reg=ipywidgets.FloatSlider(\n", " value=1e-2,\n", " min=0,\n", " max=1,\n", " step=1e-3,\n", " readout_format='.3f',\n", " description='Regularization Coefficient:',\n", " style={'description_width': 'initial'},\n", " continuous_update=False),\n", " frequency=ipywidgets.FloatSlider(\n", " value=0.1,\n", " min=0.1,\n", " max=2,\n", " step=1e-3,\n", " readout_format='.3f',\n", " description='Periodic Frequency:',\n", " style={'description_width': 'initial'},\n", " continuous_update=False)\n", " );\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Kernelized SGD" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rcParams['figure.figsize'] = (10, 5)\n", "rcParams['font.size'] = 16\n", "\n", "def kernelized_sgd():\n", " regressor = GaussianKernel(Xtr, Ytr, reg=0.0, bw=0.2)\n", " alpha0 = np.random.randn(Xtr.shape[0])\n", "\n", " opts = {'eta0': 1,\n", " 'n_iter': 50,\n", " 'batch_size': 5,\n", " 'n_samples': Xtr.shape[0],\n", " 'algorithm': 'SGD',\n", " 'learning_rate_scheduling': None\n", " }\n", " try:\n", " alphas, indexes = gradient_descent(alpha0, regressor, opts=opts)\n", "\n", " fig = plt.subplot(111)\n", " opt = {'marker': 'r*', 'label': 'Training data'}\n", " plot_helpers.plot_data(Xtr, Ytr, fig=fig, options=opt)\n", " opt = {'marker': 'bo', 'label': 'Test data'}\n", " plot_helpers.plot_data(Xtest, Ytest, fig=fig, options=opt)\n", "\n", " opt = {'marker': 'g-', 'label': 'Gaussian Kernel', 'x_label': '$x$', 'y_label': '$y$', 'legend': True, 'sgd_point': True}\n", " plot_helpers.kernelized_regression_progression(X, Xtr, Ytr, alphas, indexes, regressor, fig=fig, options=opt)\n", " except KeyboardInterrupt:\n", " pass\n", " \n", "interact_manual(kernelized_sgd);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.7.6" } }, "nbformat": 4, "nbformat_minor": 2 }