Skip to content

Instantly share code, notes, and snippets.

@asberk
Last active February 28, 2024 12:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save asberk/f3ae3c29f1fb5ff53b329114296dbf99 to your computer and use it in GitHub Desktop.
Save asberk/f3ae3c29f1fb5ff53b329114296dbf99 to your computer and use it in GitHub Desktop.
Gradient Descent (master).ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {
"toc": "true"
},
"cell_type": "markdown",
"source": "# Table of Contents\n <p><div class=\"lev1 toc-item\"><a href=\"#Introduction-&amp;-Set-up\" data-toc-modified-id=\"Introduction-&amp;-Set-up-1\"><span class=\"toc-item-num\">1&nbsp;&nbsp;</span>Introduction &amp; Set-up</a></div><div class=\"lev2 toc-item\"><a href=\"#Re-cap-from-last-time\" data-toc-modified-id=\"Re-cap-from-last-time-11\"><span class=\"toc-item-num\">1.1&nbsp;&nbsp;</span>Re-cap from last time</a></div><div class=\"lev2 toc-item\"><a href=\"#Model-assumptions\" data-toc-modified-id=\"Model-assumptions-12\"><span class=\"toc-item-num\">1.2&nbsp;&nbsp;</span>Model assumptions</a></div><div class=\"lev2 toc-item\"><a href=\"#Create-fake-data\" data-toc-modified-id=\"Create-fake-data-13\"><span class=\"toc-item-num\">1.3&nbsp;&nbsp;</span>Create fake data</a></div><div class=\"lev2 toc-item\"><a href=\"#Writing-a-basic-Logistic-Regressor-class\" data-toc-modified-id=\"Writing-a-basic-Logistic-Regressor-class-14\"><span class=\"toc-item-num\">1.4&nbsp;&nbsp;</span>Writing a basic Logistic Regressor class</a></div><div class=\"lev3 toc-item\"><a href=\"#A-black-box\" data-toc-modified-id=\"A-black-box-141\"><span class=\"toc-item-num\">1.4.1&nbsp;&nbsp;</span>A black box</a></div><div class=\"lev3 toc-item\"><a href=\"#Logistic-Regressor-shell-class\" data-toc-modified-id=\"Logistic-Regressor-shell-class-142\"><span class=\"toc-item-num\">1.4.2&nbsp;&nbsp;</span>Logistic Regressor shell class</a></div><div class=\"lev2 toc-item\"><a href=\"#Test-run\" data-toc-modified-id=\"Test-run-15\"><span class=\"toc-item-num\">1.5&nbsp;&nbsp;</span>Test run</a></div><div class=\"lev2 toc-item\"><a href=\"#Visualizing-Progress\" data-toc-modified-id=\"Visualizing-Progress-16\"><span class=\"toc-item-num\">1.6&nbsp;&nbsp;</span>Visualizing Progress</a></div><div class=\"lev1 toc-item\"><a href=\"#Setting-alpha\" data-toc-modified-id=\"Setting-alpha-2\"><span class=\"toc-item-num\">2&nbsp;&nbsp;</span>Setting alpha</a></div><div class=\"lev2 toc-item\"><a href=\"#From-above/last-time\" data-toc-modified-id=\"From-above/last-time-21\"><span class=\"toc-item-num\">2.1&nbsp;&nbsp;</span>From above/last time</a></div><div class=\"lev2 toc-item\"><a href=\"#Lipschitz-constant\" data-toc-modified-id=\"Lipschitz-constant-22\"><span class=\"toc-item-num\">2.2&nbsp;&nbsp;</span>Lipschitz constant</a></div><div class=\"lev2 toc-item\"><a href=\"#Adaptive-step-size\" data-toc-modified-id=\"Adaptive-step-size-23\"><span class=\"toc-item-num\">2.3&nbsp;&nbsp;</span>Adaptive step-size</a></div><div class=\"lev2 toc-item\"><a href=\"#Backtracking-line-search\" data-toc-modified-id=\"Backtracking-line-search-24\"><span class=\"toc-item-num\">2.4&nbsp;&nbsp;</span>Backtracking line-search</a></div><div class=\"lev2 toc-item\"><a href=\"#Comparison-of-the-three\" data-toc-modified-id=\"Comparison-of-the-three-25\"><span class=\"toc-item-num\">2.5&nbsp;&nbsp;</span>Comparison of the three</a></div><div class=\"lev1 toc-item\"><a href=\"#Coordinate-optimization\" data-toc-modified-id=\"Coordinate-optimization-3\"><span class=\"toc-item-num\">3&nbsp;&nbsp;</span>Coordinate optimization</a></div><div class=\"lev2 toc-item\"><a href=\"#Lipschitz-and-Uniform-Sampling\" data-toc-modified-id=\"Lipschitz-and-Uniform-Sampling-31\"><span class=\"toc-item-num\">3.1&nbsp;&nbsp;</span>Lipschitz and Uniform Sampling</a></div><div class=\"lev2 toc-item\"><a href=\"#So-which-is-better?\" data-toc-modified-id=\"So-which-is-better?-32\"><span class=\"toc-item-num\">3.2&nbsp;&nbsp;</span>So which is better?</a></div><div class=\"lev1 toc-item\"><a href=\"#Exercises\" data-toc-modified-id=\"Exercises-4\"><span class=\"toc-item-num\">4&nbsp;&nbsp;</span>Exercises</a></div><div class=\"lev2 toc-item\"><a href=\"#Compare-run-time-on-larger-data-sets\" data-toc-modified-id=\"Compare-run-time-on-larger-data-sets-41\"><span class=\"toc-item-num\">4.1&nbsp;&nbsp;</span>Compare run time on larger data sets</a></div><div class=\"lev2 toc-item\"><a href=\"#UMass-Amherst-smoking-data-set-for-logistic-regression\" data-toc-modified-id=\"UMass-Amherst-smoking-data-set-for-logistic-regression-42\"><span class=\"toc-item-num\">4.2&nbsp;&nbsp;</span>UMass Amherst smoking data set for logistic regression</a></div><div class=\"lev1 toc-item\"><a href=\"#Stochastic-Gradient-Descent\" data-toc-modified-id=\"Stochastic-Gradient-Descent-5\"><span class=\"toc-item-num\">5&nbsp;&nbsp;</span>Stochastic Gradient Descent</a></div><div class=\"lev2 toc-item\"><a href=\"#Mini-batch-SGD\" data-toc-modified-id=\"Mini-batch-SGD-51\"><span class=\"toc-item-num\">5.1&nbsp;&nbsp;</span>Mini-batch SGD</a></div><div class=\"lev2 toc-item\"><a href=\"#Stochastic-Average-Gradient\" data-toc-modified-id=\"Stochastic-Average-Gradient-52\"><span class=\"toc-item-num\">5.2&nbsp;&nbsp;</span>Stochastic Average Gradient</a></div><div class=\"lev3 toc-item\"><a href=\"#References\" data-toc-modified-id=\"References-521\"><span class=\"toc-item-num\">5.2.1&nbsp;&nbsp;</span>References</a></div><div class=\"lev2 toc-item\"><a href=\"#SVRG\" data-toc-modified-id=\"SVRG-53\"><span class=\"toc-item-num\">5.3&nbsp;&nbsp;</span>SVRG</a></div><div class=\"lev3 toc-item\"><a href=\"#References\" data-toc-modified-id=\"References-531\"><span class=\"toc-item-num\">5.3.1&nbsp;&nbsp;</span>References</a></div><div class=\"lev1 toc-item\"><a href=\"#Further-reading\" data-toc-modified-id=\"Further-reading-6\"><span class=\"toc-item-num\">6&nbsp;&nbsp;</span>Further reading</a></div><div class=\"lev2 toc-item\"><a href=\"#Regularization\" data-toc-modified-id=\"Regularization-61\"><span class=\"toc-item-num\">6.1&nbsp;&nbsp;</span>Regularization</a></div><div class=\"lev3 toc-item\"><a href=\"#$L^2$-regularization\" data-toc-modified-id=\"$L^2$-regularization-611\"><span class=\"toc-item-num\">6.1.1&nbsp;&nbsp;</span><span class=\"MathJax_Preview\" style=\"color: inherit;\"><span class=\"MJXp-math\" id=\"MJXp-Span-11537\"><span class=\"MJXp-msubsup\" id=\"MJXp-Span-11538\"><span class=\"MJXp-mi MJXp-italic\" id=\"MJXp-Span-11539\" style=\"margin-right: 0.05em;\">L</span><span class=\"MJXp-mn MJXp-script\" id=\"MJXp-Span-11540\" style=\"vertical-align: 0.5em;\">2</span></span></span></span><script type=\"math/tex\" id=\"MathJax-Element-858\">L^2</script> regularization</a></div><div class=\"lev3 toc-item\"><a href=\"#$L^1$-regularization\" data-toc-modified-id=\"$L^1$-regularization-612\"><span class=\"toc-item-num\">6.1.2&nbsp;&nbsp;</span><span class=\"MathJax_Preview\" style=\"color: inherit;\"><span class=\"MJXp-math\" id=\"MJXp-Span-11541\"><span class=\"MJXp-msubsup\" id=\"MJXp-Span-11542\"><span class=\"MJXp-mi MJXp-italic\" id=\"MJXp-Span-11543\" style=\"margin-right: 0.05em;\">L</span><span class=\"MJXp-mn MJXp-script\" id=\"MJXp-Span-11544\" style=\"vertical-align: 0.5em;\">1</span></span></span></span><script type=\"math/tex\" id=\"MathJax-Element-859\">L^1</script> regularization</a></div><div class=\"lev3 toc-item\"><a href=\"#Block-sparsity\" data-toc-modified-id=\"Block-sparsity-613\"><span class=\"toc-item-num\">6.1.3&nbsp;&nbsp;</span>Block sparsity</a></div><div class=\"lev2 toc-item\"><a href=\"#Constrained-Optimization\" data-toc-modified-id=\"Constrained-Optimization-62\"><span class=\"toc-item-num\">6.2&nbsp;&nbsp;</span>Constrained Optimization</a></div><div class=\"lev3 toc-item\"><a href=\"#Projected-Gradient\" data-toc-modified-id=\"Projected-Gradient-621\"><span class=\"toc-item-num\">6.2.1&nbsp;&nbsp;</span>Projected Gradient</a></div><div class=\"lev3 toc-item\"><a href=\"#Proximal-Gradient\" data-toc-modified-id=\"Proximal-Gradient-622\"><span class=\"toc-item-num\">6.2.2&nbsp;&nbsp;</span>Proximal Gradient</a></div><div class=\"lev3 toc-item\"><a href=\"#Newton's-method\" data-toc-modified-id=\"Newton's-method-623\"><span class=\"toc-item-num\">6.2.3&nbsp;&nbsp;</span>Newton's method</a></div><div class=\"lev3 toc-item\"><a href=\"#References:\" data-toc-modified-id=\"References:-624\"><span class=\"toc-item-num\">6.2.4&nbsp;&nbsp;</span>References:</a></div><div class=\"lev2 toc-item\"><a href=\"#Dual-methods\" data-toc-modified-id=\"Dual-methods-63\"><span class=\"toc-item-num\">6.3&nbsp;&nbsp;</span>Dual methods</a></div><div class=\"lev3 toc-item\"><a href=\"#The-Fenchel-Dual,-geometric-multipliers-and-the-KKT-conditions\" data-toc-modified-id=\"The-Fenchel-Dual,-geometric-multipliers-and-the-KKT-conditions-631\"><span class=\"toc-item-num\">6.3.1&nbsp;&nbsp;</span>The Fenchel Dual, geometric multipliers and the KKT conditions</a></div><div class=\"lev3 toc-item\"><a href=\"#Dual-coordinate-ascent\" data-toc-modified-id=\"Dual-coordinate-ascent-632\"><span class=\"toc-item-num\">6.3.2&nbsp;&nbsp;</span>Dual coordinate ascent</a></div>"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "$\\newcommand{\\reals}{\\mathbb{R}}\n\\newcommand{\\ip}[1]{\\langle #1 \\rangle}\n\\DeclareMathOperator*{\\argmin}{\\arg\\min}\n\\newcommand{\\E}{\\mathbb{E}}$"
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "import numpy as np\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport timeit",
"execution_count": 1,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "np.random.seed(101)",
"execution_count": 2,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# Introduction & Set-up\n## Re-cap from last time\n\nFor a real-valued continuously differentiable function $f \\in \\mathcal{C}^1(\\reals^n)$, the gradient of $f$ — denoted $\\nabla f$ — gives the direction of \"steepest ascent\". This is the direction in which $f$ increases most quickly. This statement can be verified by optimizing the directional derivative of $f$ to see which direction $u \\in \\reals^n$ gives the largest d.d. \n\nThe directional derivative of $f$ at a point $w^0 \\in \\reals^n$ in the direction $u \\in \\reals^n$ is given by $\\nabla f(w^0) u \\equiv \\ip{\\nabla f(w^0), u}$ and denotes the rate of change of $f$ in the direction $u$ when $\\|u\\|_2 = 1$. In this case, it follows from the Cauchy-Schwarz inequality that\n$$\n\\nabla f(w^0) u \n\\leq \\|\\nabla f(w^0)\\|_2 \\|u\\|_2 \n= \\|\\nabla f(w^0)\\|_2 \n$$ \nThe two sides achieve equality precisely when $u = \\nabla f(w^0) / \\|\\nabla f(w^0)\\|_2$.\n\nCorrespondingly, the direction $v \\in \\reals^n$ of steepest **descent** of $f$ at $w^0$ is *opposite* the direction of the gradient, *i.e.,* $v = -\\nabla f(w^0)/\\|\\nabla f(w^0)\\|_2$. Hence, if we're looking to minimize a function $f$, then a seemingly reasonable approach is to *march* in the direction opposite the gradient until [hopefully] we find the smallest value of $f$. \n\n<img src=\"https://upload.wikimedia.org/wikipedia/commons/f/ff/Gradient_descent.svg\" height=\"300px\" width=\"300px\" />\n\n## Model assumptions \n\nThis is a quick re-cap from last time and for consistency of notation.\n\nThe **data** is comprised of the **features**/**covariates** $X \\in \\reals^{n\\times d}$ and the **labels**/**response** $y \\in \\reals^n$. Suppose for the time being that $f(w; X,y): \\reals^d \\to \\reals$ defines a convex objective (\"cost\") function parametrized by the data. We think of $w$ as a vector of weights or **parameters** for a linear combination of the $d$ features. \n\nFor example, the objective function for $L^2$ regularized least squares regression is given by \n$$\n\\argmin_{w\\in \\reals^d} f(X,y; w,\\lambda) = \\argmin_{w\\in\\reals^d}\\big\\{\\frac{1}{2} \\|Xw - y\\|_2^2 + \\frac{\\lambda}{2}\\|w\\|_2^2\\big\\}\n$$\n\nSince the function $f$ is assumed to be convex, a global minimizer $w^*$ exists. To find $w^*$ we need simply start at some point $w^0$ and *march* for a sufficiently long time in the direction opposite the gradient (*cf.* picture above):\n\\begin{align*}\nw^1 &:= w^0 - \\alpha_0 \\nabla f(w^0)\\\\\nw^2 &:= w^1 - \\alpha_1 \\nabla f(w^1)\\\\\n&\\,\\,\\vdots\\\\\nw^{j+1} &:= w^j - \\alpha_j \\nabla f(w^j)\n\\end{align*}\nIt may not always be sensible while marching to take a step of size equal to the magnitude of the gradient. In general, one instead takes walks in the direction of the gradient scaled by some a parameter $\\alpha_t, t\\geq 0$. But how does one choose $\\alpha_t$? Should they all be the same? Is there an optimal $\\alpha$? "
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Create fake data"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Throughout this example, we'll be performing logistic regression on a two-dimensional data set, which will allow us to visualize the results. We'll be examining how long our code takes to fit and predict, by looking at both run-time and number of iterations."
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "n = 500\nd = 2\nX = np.random.randn(n, d)\ny = np.zeros((n,1))\nfor j in range(n):\n if X[j,1] > X[j,0]:\n if np.random.rand(1) >= .9:\n y[j] = 1\n else:\n y[j] = -1\n else:\n if np.random.rand(1) < .1:\n y[j] = -1\n else:\n y[j] = 1",
"execution_count": 3,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "plt.scatter(X[:,0], X[:,1], s=10, lw=0, alpha=.8, c=y);",
"execution_count": 4,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\nRK5CYII=\n",
"text/plain": "<matplotlib.figure.Figure at 0x10cb5b828>"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print('#{y == 1} = %d\\n#{y == -1} = %d' % ((y == 1).sum(), (y == -1).sum()))",
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"text": "#{y == 1} = 253\n#{y == -1} = 247\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Writing a basic Logistic Regressor class"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Last time, we wrote a very simple gradient descent method. I've re-written it here in a slightly more general form so that it cooperates with what we'll be defining below."
},
{
"metadata": {
"code_folding": [
0
],
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "def vanillaGradientDescent(funObj, w, X, y, \n objectiveParms={}, \n gdParms={}):\n # optimality tolerance\n optTol = gdParms.get('optTol')\n if optTol is None:\n optTol = 1e-2\n maxEvals = gdParms.get('maxEvals')\n if maxEvals is None:\n maxEvals = 500\n verbose = gdParms.get('verbose')\n if verbose is None:\n verbose = False\n # initial objective and gradient value\n f,g = funObj(w, X, y, **objectiveParms)\n # this took a single function evaluation\n funEvals = 1\n \n # initialize the step size\n alpha = gdParms.get('alpha')\n if alpha is None:\n alpha = .01\n \n # Gradient Descent loop\n while True:\n # Step in search direction\n w = w - alpha*g\n # Update objective and gradient values\n f, g = funObj(w, X, y, **objectiveParms)\n # This cost one more function evaluation\n funEvals += 1\n # Test terminate conditions — largest magnitude of derivative\n optCond = np.linalg.norm(g, np.inf)\n if verbose:\n print('%6d %15.5e %15.5e %15.5e' % (funEvals, alpha, f, optCond))\n if optCond < optTol:\n if verbose:\n print('Problem solved up to optimality tolerance')\n break\n if funEvals >= maxEvals:\n if verbose:\n print('At maximum number of function evaluations')\n break\n return (w, f, funEvals)",
"execution_count": 6,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "### A black box"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "We'll also be using a function [translated and modified from Mark Schmidt's Matlab version] that can be — for now — be treated as a black box. This function is not available, to my knowledge, on his website; however, you can find `minFunc` [through his website](https://www.cs.ubc.ca/~schmidtm/Software/minFunc.html), which is likely a generalization of `findMin`. "
},
{
"metadata": {
"code_folding": [
1
],
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "# checks if a number v is in the appropriate real range\ndef isLegal(v):\n # assumes v is a scalar or vector\n return any(np.imag(x) for x in [v]) and any(np.isnan(x) for x in [v]) and any(np.isinf(x) for x in [v])",
"execution_count": 7,
"outputs": []
},
{
"metadata": {
"code_folding": [
0
],
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "def findMin(funObj, w, X, y, \n objectiveParms={}, \n gdParms={}):\n \"\"\"\n findMin computes the optimal parameter vector w to \n funObj given the data X, y and execution parameters \n objectiveParms & gdParms using gradient descent with \n backtracking via Armijo rule, setting alpha via cubic\n Hermite interpolation (I think)\n \"\"\"\n optTol = gdParms.get('optTol')\n if optTol is None:\n optTol = 1e-2\n maxEvals = gdParms.get('maxEvals')\n if maxEvals is None:\n maxEvals = 500\n verbose = gdParms.get('verbose')\n if verbose is None:\n verbose = False\n gamma = gdParms.get('gamma')\n if gamma is None:\n gamma = 1e-4\n \n f,g = funObj(w, X, y, **objectiveParms)\n funEvals = 1\n \n alpha = 1\n while True:\n # Line-search to find an acceptable value of alpha\n w_new = w - alpha*g\n f_new, g_new = funObj(w_new, X, y, **objectiveParms)\n funEvals += 1\n \n gg = g.T @ g\n while f_new > f - gamma*alpha*gg:\n if verbose:\n print('Backtracking...')\n alpha = alpha**2 * gg/(2*(f_new - f + alpha*gg))\n w_new = w - alpha*g\n f_new, g_new = funObj(w_new, X, y, **objectiveParms)\n funEvals += 1\n # Update step size for next iteration\n dg = g_new - g\n alpha - -alpha*(dg.T @ g)/(dg.T @ dg)\n # Sanity check on step-size\n if (not isLegal(alpha)) or (alpha < 1e-10) or (alpha > 1e10):\n alpha = 1\n # Update parameters/function/gradient\n w = w_new\n f = f_new\n g = g_new\n # Test terminate conditions\n optCond = np.linalg.norm(g, np.inf)\n if verbose:\n print('%6d %15.5e %15.5e %15.5e' % (funEvals, alpha, f, optCond))\n if optCond < optTol:\n if verbose:\n print('Problem solved up to optimality tolerance')\n break\n if funEvals >= maxEvals:\n if verbose:\n print('At maximum number of function evaluations')\n break\n return (w, f, funEvals)",
"execution_count": 8,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "### Logistic Regressor shell class"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Below, we construct a class called `LogisticRegressor` which has `fit` and `predict` methods. One major difference between this and `sklearn`'s `LogisticRegression` class object is that I more easily know how to alter these moving parts without breaking the whole thing. This will let us alter the gradient descent method and the objective function so that we can compare run time, iteration cost, *etc.*"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "The logistic regression objective function is given by \n$$\nf(w; X,y) := \\sum_{i=1}^n \\log (1 + \\exp(-y^i w^T x^i)) + \\frac{\\lambda}{2} \\|w\\|_2^2\n$$\nand its gradient is given by \n$$\n\\nabla_w f(w; X,y) = g(w; X,y) = X^T r + \\lambda w, \\quad r_i := -y^i \\sigma(-y^i w^T x^i)\n$$\nwhere $\\sigma(x) := (1 + e^{-x})^{-1}$ is the *logistic function*.\n\n<img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/88/Logistic-curve.svg/320px-Logistic-curve.svg.png\" width=\"300px\" height=\"200px\"/>"
},
{
"metadata": {
"code_folding": [
17,
45,
76,
85
],
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "class LogisticRegressor:\n \"\"\"\n LogisticRegressor takes data [X, y] and optimization parameters and computes a \n logistic regression linear model to perform binary classification.\n X: an n-by-d numpy.ndarray object whose rows are samples/observations of d features\n y: an n-by-1 numpy.ndarray vector whose elements lie in the set {-1, +1}\n objectiveParms: A dictionary of parameters to pass to the objective function \n (e.g., an L2-regularization parameter lam)\n gdParms: A dictionary of parameters to pass to the gradient descent method\n (e.g., the optimality tolerance, the gradient descent step size, etc.)\n kwargs:\n intercept: whether to fit a linear model a.T * X or affine model a.T * X + a0\n maxIter: maximum number of iterations before loop breaks\n verbose: whether to print progress during the optimization\n objective: the objective function to use in the optimization\n gd: the gradient descent method to use in the optimization\n \"\"\"\n def __init__(self,objectiveParms={},gdParms={},**kwargs):\n # # # Optional Parameters # # #\n # Whether to include the intercept term \n # (default: yes)\n self.intercept = kwargs.get('intercept')\n # Whether to print out information along the way \n # (default: yes)\n self.verbose = gdParms.get('verbose')\n if self.verbose is None:\n self.verbose = False\n gdParms['verbose'] = False\n # Objective function for logistic regression \n # (default: L2 regularized LR)\n self.objective = kwargs.get('objective')\n self.objectiveParms = objectiveParms\n if self.objective is None:\n self.objective = LogisticRegressor.simpleObjective\n if (objectiveParms is None) or (objectiveParms.get('lam') is None):\n self.objectiveParms = {'lam': 1}\n # Gradient descent algorithm\n # (default: vanillaGradientDescent)\n self.gd = kwargs.get('gd')\n self.gdParms = gdParms\n if self.gd is None:\n self.gd = vanillaGradientDescent\n if (gdParms is None) or (gdParms.get('alpha') is None):\n self.gdParms = gdParms = {'alpha': .01}\n return\n def fit(self, X, y, w=None):\n \"\"\"\n LogisticRegressor.fit fits the objective function `objective` to the \n data `[X, y]` using `w` as the initial starting point for the parameters\n and lam as the regularization parameter.\n \"\"\"\n # # # Necessary parameters # # #\n self.X = X\n self.n, self.d = self.X.shape\n self.y = y\n self.w = w\n if self.w is None:\n self.w = np.zeros((self.d,1))\n # Whether to fit intercept\n if self.intercept:\n self.X = np.hstack((np.ones((self.n,1)),self.X))\n self.w = np.vstack((np.ones((1,1)),self.w))\n # # # Gradient descent algorithm # # #\n if self.verbose:\n st = timeit.time.clock()\n w, oM, fE = self.gd(self.objective, self.w, \n self.X, self.y, \n self.objectiveParms,\n self.gdParms)\n if self.verbose:\n et = timeit.time.clock()\n print('total elapsed time: %15.5g s' % (et-st))\n self.w = w\n self.objMin = oM\n self.funEvals = fE\n return\n def predict(self, Xhat):\n \"\"\"\n LogisticRegressor.predict computes the predicted values `yhat` from the\n data `Xhat` and the parameters `w` computed from `fit`.\n \"\"\"\n t,d = Xhat.shape\n if self.intercept:\n Xhat = np.hstack((np.ones((t,1)),Xhat))\n return np.sign(np.dot(Xhat, self.w))\n def simpleObjective(w,X,y,lam):\n \"\"\"\n LogisticRegressor.simpleObjective returns the objective value and its \n gradient given the parameters `w`, data `[X, y]` and regularization\n parameter `lam`. It does this without regard to number of computations\n required for matrix multiplication, etc. (hence, 'simple')\n \"\"\"\n yXw = y*(X @ w)\n nll = np.sum(np.log(1 + np.exp(-yXw))) + .5*lam*np.dot(w.T,w)\n sigmoid = 1/(1+np.exp(-yXw))\n g = - np.dot(X.T, y*(1-sigmoid)) + lam*w\n return (nll, g)",
"execution_count": 9,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Test run"
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "LR_vanilla1 = LogisticRegressor(gdParms={'alpha':1e-1})\nLR_vanilla2 = LogisticRegressor(gdParms={'alpha':1e-2})",
"execution_count": 10,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false,
"scrolled": true
},
"cell_type": "code",
"source": "%timeit LR_vanilla1.fit(X,y)\n%timeit LR_vanilla2.fit(X,y)",
"execution_count": 11,
"outputs": [
{
"output_type": "stream",
"text": "10 loops, best of 3: 40.6 ms per loop\n100 loops, best of 3: 2.28 ms per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print('LR_vanilla1.funEvals = {}'.format(LR_vanilla1.funEvals))\nprint('LR_vanilla2.funEvals = {}'.format(LR_vanilla2.funEvals))",
"execution_count": 12,
"outputs": [
{
"output_type": "stream",
"text": "LR_vanilla1.funEvals = 500\nLR_vanilla2.funEvals = 28\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Now compare against the \"black box\" from Mark Schmidt. "
},
{
"metadata": {
"trusted": true,
"collapsed": false,
"scrolled": true
},
"cell_type": "code",
"source": "LR_findMin = LogisticRegressor(gd=findMin)\n%timeit LR_findMin.fit(X,y)",
"execution_count": 13,
"outputs": [
{
"output_type": "stream",
"text": "100 loops, best of 3: 2.21 ms per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print('LR_findMin.funEvals = {}'.format(LR_findMin.funEvals))",
"execution_count": 14,
"outputs": [
{
"output_type": "stream",
"text": "LR_findMin.funEvals = 26\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Visualizing Progress"
},
{
"metadata": {
"code_folding": [
0
],
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "def binaryClassifier2DPlot(model):\n \"\"\"\n binaryClassifier2DPlot makes a plot of the two dimensional data X\n used by model, coloured by class membership y. The background of the \n plot is coloured according to the decision function computed by \n fitting the model to the data [X, y].\n \"\"\"\n increment = 500\n X = model.X\n if model.intercept:\n X = X[:, 1:]\n # Get the label values\n yu = np.unique(y).tolist()\n # This sets the axis limits\n plt.scatter(X[y.ravel() == yu[0], 0], X[y.ravel() == yu[0], 1], s=20, lw=1, alpha=.5, c='g', marker='+');\n plt.hold(True)\n plt.scatter(X[y.ravel() == yu[1], 0], X[y.ravel() == yu[1], 1], s=10, lw=0, alpha=.5, c='b', marker='o');\n # Fetch axis limits\n xLim = plt.xlim()\n yLim = plt.ylim()\n # Domain on which to compute the decision function\n domain1 = np.linspace(*xLim, increment+1)\n domain2 = np.linspace(*yLim, increment+1)\n d1, d2 = np.meshgrid(domain1, domain2)\n d12 = np.array([d1.ravel(), d2.ravel()]).T\n # Compute the decision function\n vals = model.predict(d12)\n zData = vals.reshape(d1.shape)\n # Set the colour map\n if all(zData.ravel() == yu[0]):\n cm = [0, .4, 0]\n elif all(zData.ravel() == yu[1]):\n cm = [0, 0, .5]\n else:\n cm = np.array([[0, .4, 0], [0, 0, .5]])\n # Filled contour plot of the decision function\n plt.contourf(d1,d2,zData+np.random.rand(*zData.shape)/1000,colors=cm)\n # Plot the data [X, y] over top (it has been covered by the filled contours)\n plt.scatter(X[y.ravel() == yu[1], 0], X[y.ravel() == yu[1], 1], s=10, lw=0, c=[0,.5,1], marker='o');\n plt.scatter(X[y.ravel() == yu[0], 0], X[y.ravel() == yu[0], 1], s=20, lw=1, c=[0,1,0], marker='+');\n return",
"execution_count": 15,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "plt.figure(figsize=(10,10))\nfor j, model, pTitle in zip(range(221,224), \n [LR_vanilla1, LR_vanilla2, LR_findMin], \n ['Vanilla, alpha=1e-1', 'Vanilla, alpha=1e-2', 'findMin']):\n plt.subplot(j)\n binaryClassifier2DPlot(model)\n plt.title(pTitle)\n plt.axis('tight');",
"execution_count": 16,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\nhjWhX6ZxMnOVfAnbhw8nER/fff2235hEhL75TWD7TdOfmzlFehnPpV9mn8BkB7FG60BamYK85NUw\n6hdznqJStNhbGUK2CoeOyVdtXBaM2kyXTs/gtHGyPzOvObQF+N5TE+PkasNsX/PM8bVmfoFek9c3\noEt4XDNAe63dnOWVDSnb3184Jay9IiLScuEhHaBuDWtKv1zGCZjcs3YU50MfSl8qM8++A5Ljod72\nG279ApJ72WecfAUxze+aj01oGPUrFZqnopRJss6LKXa+w3v1Z4D/ZHGXgOm27NpMetlNFibGCUjq\nNekjV05/KHnUHH/A3YbdvmbVquQmNmuP+MTG5Oix2cM2gXQRKBNStr9/5OHehahJB6lLw2yzZuOq\n02RrWF792maURFk4Zbo45f790xtONFn3tZ34DSQalle/gKR/G7P0gQ01rHVw2W6e0OHtK6zXGm2s\nXOFx/V7Wtl6xSg2YS22P7EzqNclCYpw09506/R27DZM//GByQOaqVcDP/hbw8g9MPhuuDROflSuA\n245OznLSlXvTwtllQ966X3tpsIeiw2W7jGupX270kpt51pxvuc5XjiBEv0zjZC/H6ZMJzNIB9llw\nWee+Acmhvhs/MltaoIh+HTgAnHtutjZRw6IQS79onpomtHZKiNC4roH13kFM71ZJI80kTZkqTx6U\njf7Ovn3JyeG6uq5deyQENUwSMl31VWx0HShNnkM989IDMaJ5yriW+uW/NmuyZ19jHwAcol96uc6+\n7/Xhu4D7APEsbPOycErSXtX65fotVWkY9WuKynKeRGSziOwTkR+JyPPLtNVbQneYpOUp7E65xn4v\n1DgB/qU8YLLDDpjNb3Jh5iScfz5wzLhBdZ5A1jr+4p7kj7kr77w3J8+zbviqQtTmmHtW56QLUMNK\nkveIFZeG2acX+A4ADtEvM8/JtVSlMXfYheQQuXKOdHuh+gUAe24spl+A+8iWslC/ClP2eJa7Afwi\n3McukjTMGVaeIwpceQr29w46rima32AfsxKCa9lOGzEdeTJv/q3rgJvuBw58In0WONw72fYbOtuz\nj3aJiV0dnUcdzCPUsCIU1S9gVotc37M1LES/XLWc8hz6bRJyNIomVL8AYHBvolt5olX2rryiS3a+\ndqlfhSgVeVJKHVRKfRtA9+PUsQvKFd3xEnLdasd7eXbU2FEkl3HyRaVcieSaQ1umi8RpVq4ALvnd\n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\n",
"text/plain": "<matplotlib.figure.Figure at 0x10cbe2b00>"
},
"metadata": {}
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "The first performs **terribly**! But we could already predict this by looking at `optCond` in the right-hand column of the `verbose` output: the largest magnitude of the derivative not only stops shrinking beyond ~70 but actually bounces around between about 70 and 200.\n\nThe second performs much better. and looks like it's properly separated the points. Furthermore, fitting only required $28$ function evaluations compared to `findMin`'s $26$. "
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# Setting alpha\n\n## From above/last time\n\nLast time, we used the approach with $\\alpha = \\alpha_0 = \\alpha_1 = \\ldots$ and we saw that the results obtained were highly dependent on the [sequence of] learning rates.\n\n## Lipschitz constant\n\nIf we can determine the Lipschitz constant of our objective function, then we get a very nice progress bound under certain assumptions on the objective function.\n\nNamely, assume that $f$ is strongly smooth. In particular, there exists $L$ such that for any $v, z$, \n$$\nv^T \\nabla^2 f(z) v \\leq L\\|v\\|_2^2\n$$\nFor some $z$, it then follows by Taylor's theorem that \n$$\nf(y) = f(x^t) + \\nabla f(x^t) (y-x^t) + \\frac{1}{2}(y-x^t)^T \\nabla^2 f(z) (y-x^t) %\n\\leq f(x^t) + \\nabla f(x^t) (y-x^t) + \\frac{L}{2}\\|y-x^t\\|_2^2\n$$\nSetting $y = x^{t+1}$ to be the minimizer of this equation yields\n$$\nx^{t+1} = x^t - \\frac{1}{L} \\|\\nabla f(x^t)\\|_2^2\n$$\nIn particular, gradient descent with $\\alpha_t := 1/L$ minimizes the upper bound (*i.e.*, maximizes the *worst-case* progress). Substituting this into the expression above, \n$$\nf(x^{t+1}) \\leq f(x^t) - \\frac{1}{2L} \\|\\nabla f(x^t)\\|_2^2\n$$\n*Caveat* *via* a direct quote from Mark Schmidt: \"In practice, you should never use $\\alpha = 1/L$.\""
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "def logisticLipschitz(X, lam=0):\n return .25 * np.max(np.linalg.eigvals(X.T @ X)) + lam",
"execution_count": 17,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "objectiveParms_Lip = {'lam': 1}\nL_logist = logisticLipschitz(X, **objectiveParms_Lip)\n\nprint('Lipschitz constant is {:5.5g}, implying alpha is {:5.3e}'.format(L_logist, 1/L_logist))\n\nLR_Lip = LogisticRegressor(objectiveParms=objectiveParms_Lip, \n gdParms={'alpha':1/L_logist})",
"execution_count": 18,
"outputs": [
{
"output_type": "stream",
"text": "Lipschitz constant is 140.75, implying alpha is 7.105e-03\n",
"name": "stdout"
}
]
},
{
"metadata": {
"scrolled": true,
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "%timeit LR_Lip.fit(X,y)",
"execution_count": 19,
"outputs": [
{
"output_type": "stream",
"text": "100 loops, best of 3: 3.39 ms per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print('LR_Lip.funEvals = {}'.format(LR_Lip.funEvals))",
"execution_count": 20,
"outputs": [
{
"output_type": "stream",
"text": "LR_Lip.funEvals = 42\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Stops after only 42 function evaluations; largest partial derivative has magnitude .0090. This is *much* better than the step size of $1\\mathrm{e}-1$ but *worse* than taking a step size of $1\\mathrm{e}-2$. Why is that we can get away with a *larger* value of $\\alpha$? "
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Adaptive step-size"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "This approach often gives bigger steps and faster progress, but step size never increases.\n\n1. Start with a small guess for $L$ \n$ L \\leftarrow 1$\n2. Double $L$ if the *progress inequality* from above \n$f(x^{t+1}) \\leq f(x^t) - \\frac{1}{2L}\\|\\nabla f(x^t)\\|_2^2$\nis not satisfied."
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Notice that this \"backtracking\" approach makes sense when it is cheap to evaluate our function and expensive to compute the matrix product $Xw$. "
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "def adaptiveGradientDescent(funObj, w, X, y,\n objectiveParms={}, \n gdParms={}):\n # optimality tolerance\n optTol = gdParms.get('optTol')\n if optTol is None:\n optTol = 1e-2\n maxEvals = gdParms.get('maxEvals')\n if maxEvals is None:\n maxEvals = 500\n verbose = gdParms.get('verbose')\n if verbose is None:\n verbose = True\n # armijo?\n gamma = gdParms.get('gamma')\n if gamma is None:\n gamma = .5\n elif (gamma > .5) or (gamma <= 0):\n gamma = 1e-4\n # initial objective and gradient value\n f,g = funObj(w, X, y, **objectiveParms)\n # this took a single function evaluation\n funEvals = 1\n \n # initialize the step size\n L0 = gdParms.get('L0')\n if L0 is None:\n L0 = 1\n alpha = 1/L0\n \n # Gradient Descent loop\n while True:\n w_new = w - alpha*g\n f_new, g_new = funObj(w_new, X, y, **objectiveParms)\n funEvals += 1\n gg = g.T @ g\n while f_new > f - gamma*alpha*gg:\n if verbose:\n print('Backtracking...')\n alpha /= 2\n w_new = w - alpha*g\n f_new, g_new = funObj(w_new, X, y, **objectiveParms)\n funEvals += 1\n # Update parameters/function/gradient\n w = w_new\n f = f_new\n g = g_new\n # Test terminate conditions\n optCond = np.linalg.norm(g, np.inf)\n if verbose:\n print('%6d %15.5e %15.5e %15.5e' % (funEvals, alpha, f, optCond))\n # Reset alpha for next\n alpha = 1/L0\n if optCond < optTol:\n if verbose:\n print('Problem solved up to optimality tolerance')\n break\n if funEvals >= maxEvals:\n if verbose:\n print('At maximum number of function evaluations')\n break\n return (w, f, funEvals)",
"execution_count": 21,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "LR_adap = LogisticRegressor(objectiveParms={'lam':1},\n gdParms={'L0':1},\n gd=adaptiveGradientDescent)",
"execution_count": 22,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false,
"scrolled": true
},
"cell_type": "code",
"source": "%timeit LR_adap.fit(X, y)",
"execution_count": 23,
"outputs": [
{
"output_type": "stream",
"text": "100 loops, best of 3: 4.08 ms per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print('LR_adap.funEvals = {}'.format(LR_adap.funEvals))",
"execution_count": 24,
"outputs": [
{
"output_type": "stream",
"text": "LR_adap.funEvals = 54\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Backtracking line-search\n\nChecks against the Armijo condition\n$$\nf(x^{t+1}) \\leq f(x^t) - \\alpha\\gamma \\|\\nabla f(x^t)\\|_2^2, \\quad \\gamma \\in (0, 1/2]\n$$\nSee Wikipedia for a more detailed discussion on the more technical [Wolfe conditions](https://en.wikipedia.org/wiki/Wolfe_conditions) (of which the Armijo rule is a special case)."
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Since this version was implemented above in `adaptiveGradientDescent` the only step required for this section is to choose `gamma` and fit the model."
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "LR_armijo = LogisticRegressor(objectiveParms={'lam':1},\n gdParms={'L0':1,'gamma':1e-4},\n gd=adaptiveGradientDescent)",
"execution_count": 25,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "%timeit LR_armijo.fit(X,y)",
"execution_count": 26,
"outputs": [
{
"output_type": "stream",
"text": "100 loops, best of 3: 4.88 ms per loop\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print('LR_armijo.funEvals = {}'.format(LR_armijo.funEvals))",
"execution_count": 27,
"outputs": [
{
"output_type": "stream",
"text": "LR_armijo.funEvals = 70\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Comparison of the three"
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "plt.figure(figsize=(10,10))\nfor j, model, pTitle in zip(range(221,224), \n [LR_Lip, LR_adap, LR_armijo], \n ['Lipschitz', 'Adaptive', 'Armijo']):\n plt.subplot(j)\n binaryClassifier2DPlot(model)\n plt.title(pTitle)\n plt.axis('tight');",
"execution_count": 28,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": "<matplotlib.figure.Figure at 0x11351ccc0>"
},
"metadata": {}
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# Coordinate optimization\n\nIn this case, we must assume that our function $f(w; X,y)$ is the sum of a smooth function and a separable function\n$$\nf(w; X,y) = g(w; X,y) + \\sum_{j=1}^d h_j(w_i; X,y)\n$$\nThen at each iteration $t$ select an index $j_t$ and update that index via \n$$\nx^{t+1}_{j_t} = x^t_{j_t} + \\gamma_t \\quad\\iff \\quad x^{t+1} = x^t + \\gamma_t e_{j_t}\n$$\nfor some constant $\\gamma_t$ and where $e_{j_t}$ is the $j_t$-th unit vector.\n\nIn the case of logistic regression, one of the key tools here is that this allows us to track updates via \n$$\nXw^{t+1} = Xw^t + \\gamma_t X e_{j_t} = Xw^t + \\gamma_t x_{j_t}\n$$\nso that it is only necessary to keep track of the index $j_t$ that is selected and the update constant $\\gamma_t$ — no more than one expensive matrix multiplication is required [to compute $Xw^0$]. But how does one go about choosing $j_t$ on iteration $t$? We'll mention two ways. "
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Lipschitz and Uniform Sampling\n\nIn the first selection method that we'll discuss, $j_t$ is chosen uniformly at random on each iteration from $[d] := \\{1, 2, \\ldots, d\\}$ – *i.e.*, $j_t \\sim \\mathrm{Unif}([d])$ and $j_t$ chosen according to $P(j_t = k) = L_k/Z$ for $k \\in [d]$, where $L_k$ denotes the $k$th coordinate-wise Lipschitz constant and $Z$ a normalizing factor so that $Z^{-1}\\sum_k L_k = 1$ gives a pmf on $[d]$."
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "def weightedIndexSample(weights):\n \"\"\"\n weightedIndexSample returns a random integer in {1, 2, ..., weights.size}\n according to the probability mass function induced by weights\n \"\"\"\n return np.random.choice(range(weights.size), p=weights/weights.sum())",
"execution_count": 29,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "def uniformIndexSample(v):\n \"\"\"\n uniformIndexSample returns a random integer in {1, 2, ..., v.size}\n uniformly at random. \n \"\"\"\n return np.random.choice(range(v.size))",
"execution_count": 30,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "def lipschitzLogisticLipschitz(X, lam=0):\n \"\"\"\n lipschitzLogisticLipschitz returns a vector of the coordinate-wise\n Lipschitz constants for the logistic function given data X and \n regularizer lam. (i.e., each L_j, j in [d] satisfies the Lipschitz\n continuity inequality for coordinate j)\n \"\"\"\n return .25 * (X**2).sum(axis=0) + lam\ndef uniformLogisticLipschitz(X, lam=0):\n \"\"\"\n uniformLogisticLipschitz returns the uniform coordinate-wise Lipschitz \n constant for the logistic function given data X and regularizer lam \n (i.e., the smallest Lipschitz constant for which the Lipschitz continuity \n inequality is satisfied for each coordinate)\n \"\"\"\n return np.max(lipschitzLogisticLipschitz(X, lam))\n",
"execution_count": 31,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "def randomizedCoordinateDescent(funObj, w, X, y, \n objectiveParms={}, \n gdParms={}):\n \"\"\"\n randomizedCoordinateDescent performs randomized coordinate \n descent on the convex function funObj to find the optimal \n parameter vector w given labeled training data [X, y]. \n \"\"\"\n # progress tolerance\n progTol = gdParms.get('progTol')\n if progTol is None:\n progTol = 1e-4\n # maximum number of passes through the data\n maxPasses = gdParms.get('maxPasses')\n if maxPasses is None:\n maxPasses = 500\n # whether to print output along the way\n verbose = gdParms.get('verbose')\n if verbose is None:\n verbose = False\n # Which Lipschitz method to use?\n # default: uniformLogisticLipschitz\n lipschitzMethod = gdParms.get('lipschitzMethod')\n if lipschitzMethod is None:\n L = uniformLogisticLipschitz(X, **objectiveParms)\n else:\n L = lipschitzMethod(X, **objectiveParms)\n # How to choose the coordinate/index jt on iteration t\n # default: weighted index sampling\n # default: if L is a uniform Lipschitz constant, then \n # uniform index sampling is performed.\n coordSample = gdParms.get('coordSample')\n if coordSample is None:\n coordSample = weightedIndexSample\n if isinstance(L, float):\n unif = np.ones(w.shape).ravel()\n funEvals = 0\n # For fast mulitiplication\n Xw = X @ w\n # For tracking progress\n w_old = w.copy()\n \n for t in range(maxPasses*d):\n # Choose index and Lipschitz coefficient\n if isinstance(L, float):\n Lt = L\n j = coordSample(unif)\n else:\n j = coordSample(L)\n Lt = L[j]\n # Compute objective value and partial derivative g_j\n Xj = X[:,j].reshape(-1,1)\n f, g_j = funObj(w, Xw, Xj, y, j, **objectiveParms)\n funEvals += 1\n # Variable update\n Xw -= g_j*Xj/Lt\n w[j] = w[j] - g_j/Lt\n # Check for lack of progress after each pass\n if np.mod(t,d) == 0:\n change = np.linalg.norm(w-w_old,2)*np.sqrt(d)\n if verbose:\n print('Passes = %d, function = %.4e, change = %15.4e' % (t/d, f, change))\n if change < progTol:\n if verbose:\n print('Parameters changed by less than progTol on pass %d.' % t)\n break\n w_old = w\n return (w, f, funEvals)\n \n \ndef coordinateObjective(w,Xw,Xj,y,j,lam):\n \"\"\"\n coordinateObjective computes the negative log-likelihood of the MAP estimate\n and the jth gradient for the logistic function using the matrix-product Xw,\n the labels y, an index j and regularizer lam\n \"\"\"\n yXw = y*Xw\n invsigmoid = 1+np.exp(-yXw)\n nll = np.sum(np.log(invsigmoid)) + .5*lam*np.linalg.norm(w,2)\n g_j = -Xj.T @ (y*(1-1/invsigmoid)) + lam*w[j, 0]\n return (nll, g_j)",
"execution_count": 32,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "coordModels = {}\nfor name1, coordSamp in zip(['weighted', 'uniform'], \n [weightedIndexSample, uniformIndexSample]):\n for name2, lipMethod in zip(['coordLip', 'unifLip'], \n [lipschitzLogisticLipschitz, uniformLogisticLipschitz]):\n coordModels[(name1, name2)] = LogisticRegressor(objectiveParms={'lam':1},\n gdParms={'coordSample': coordSamp,\n 'lipschitzMethod': lipMethod},\n objective=coordinateObjective,\n gd=randomizedCoordinateDescent)",
"execution_count": 33,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "for key, value in coordModels.items():\n print(key)\n %timeit value.fit(X,y)\n print('Number of Passes: {}\\n'.format(value.funEvals))",
"execution_count": 34,
"outputs": [
{
"output_type": "stream",
"text": "('uniform', 'coordLip')\n1000 loops, best of 3: 526 µs per loop\nNumber of Passes: 3\n\n('uniform', 'unifLip')\n1000 loops, best of 3: 541 µs per loop\nNumber of Passes: 3\n\n('weighted', 'coordLip')\nThe slowest run took 26.07 times longer than the fastest. This could mean that an intermediate result is being cached.\n1000 loops, best of 3: 649 µs per loop\nNumber of Passes: 3\n\n('weighted', 'unifLip')\n1000 loops, best of 3: 665 µs per loop\nNumber of Passes: 3\n\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "plt.figure(figsize=(10,10))\nj = 221\nfor pTitle, model in coordModels.items():\n plt.subplot(j)\n j += 1\n binaryClassifier2DPlot(model)\n plt.title(pTitle)\n plt.axis('tight');",
"execution_count": 35,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": "<matplotlib.figure.Figure at 0x11351c828>"
},
"metadata": {}
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## So which is better?"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "**Note:** For a more concrete/realistic example of which is better, see the exercises below. "
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Note that where uniform sampling is used - $\\forall j \\in [d], \\,\\, p(j) = d^{-1}$ - we achieve the guaranteed progress bound\n$$\n \\E (f(x^{t+1})) \\leq f(x^t) - \\frac{1}{2dL} \\|\\nabla f(x^t)\\|^2\n$$\nwhere $[d] := \\{1, \\ldots, d\\}$. Correspondingly, for Lipschitz sampling, the\npmf is given by\n$$\n\\forall j \\in [d],\\quad p(j) = \\frac{L_j}{\\sum_{j \\in [d]} L_j} =: \\frac{L_j}{d \\overline{L}}\n$$\nwhere $d\\overline{L}$ is the normalizing constant for the pmf, with\n$\\overline{L}$ the arithmetic mean of the coordinate-wise Lipschitz constants\n$L_j$. Hence, the guaranteed progress bound for Lipschitz sampling is\n$$\n\\E f(x^{t+1}) \\leq \\E \\big( f(x^t) - \\frac{1}{2L} |\\nabla_{j_t} f(x^t)|^2\\big) %\n= \\sum_{j=1}^d \\frac{L_{j_t}}{d\\overline{L}} \\big( f(x^t) - \\frac{1}{2L} |\\nabla_j f(x^t)|^2 \\big)\n$$\n$$\n= f(x^t) - \\frac{1}{2d L} \\sum_{j\\in d} \\frac{L_{j_t}}{\\overline{L}} |\\nabla_{j_t} f(x^t)|^2\n$$\nIn particular, by comparing the two equations above, uniform sampling is on average preferred to Lipschitz sampling if"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "$$\n\\ip{\\mathbf{1}, |\\nabla_{j_t} f(x^t)|^2} = \\|\\nabla f(x^t)\\|^2 > \\sum_{j_t\\in [d]} \\frac{L_{j_t}}{\\overline{L}}\n|\\nabla_{j_t} f(x^t)|^2 = \\ip{\\frac{L_{j_t}}{\\overline{L}}, |\\nabla_{j_t}\n f(x^t)|^2}.\n$$\nFirstly, by the Cauchy-Schwarz inequality, this certainly occurs if\n$\\|L_{j_t}\\|_2 < \\overline{L}$. Moreover, as an example, perhaps\nLipschitz sampling is sub-optimal on its second pass through the data, where\nthe gradient on the highly-preferred indices is already quite small. This would\ncause the two vectors to be closer to orthogonal, thereby being more likely to\nsatisfy the above inequality. Note: more generally, it is desirable to have a\nsampling scheme $p(j_t)$ which is well-aligned with the squared modulus of the $j_t$-gradient vector\n$\\big(|\\nabla_{j_t} f(x^t)|^2 \\big)$."
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# Exercises"
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "import pandas as pd\nimport requests",
"execution_count": 36,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Compare run time on larger data sets"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "This is a test data set that includes 500 observations of 100 features (*i.e.,* $X \\in \\reals^{n\\times d}$ with $n = 500$, $d = 100$; correspondingly, $y \\in \\{-1,1\\}^{500}$). The labels `y` are stored in the very last column. "
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "bigData = pd.read_csv(filepath_or_buffer='./data/logisticData.csv',header=None)",
"execution_count": 37,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print('bigData.shape = {}'.format(bigData.shape))\nbigData.head()",
"execution_count": 38,
"outputs": [
{
"output_type": "stream",
"text": "bigData.shape = (500, 101)\n",
"name": "stdout"
},
{
"output_type": "execute_result",
"data": {
"text/html": "<div>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n <th>1</th>\n <th>2</th>\n <th>3</th>\n <th>4</th>\n <th>5</th>\n <th>6</th>\n <th>7</th>\n <th>8</th>\n <th>9</th>\n <th>...</th>\n <th>91</th>\n <th>92</th>\n <th>93</th>\n <th>94</th>\n <th>95</th>\n <th>96</th>\n <th>97</th>\n <th>98</th>\n <th>99</th>\n <th>100</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>-4.8111</td>\n <td>8.805800</td>\n <td>-0.72609</td>\n <td>-0.30079</td>\n <td>-3.21490</td>\n <td>-1.5162</td>\n <td>-1.2692</td>\n <td>-5.19650</td>\n <td>-2.6087</td>\n <td>-11.405000</td>\n <td>...</td>\n <td>0.007660</td>\n <td>-0.23342</td>\n <td>-4.8693</td>\n <td>-3.99460</td>\n <td>-0.58243</td>\n <td>3.7657</td>\n <td>-0.32883</td>\n <td>0.10334</td>\n <td>-7.69890</td>\n <td>1</td>\n </tr>\n <tr>\n <th>1</th>\n <td>-6.4098</td>\n <td>0.087018</td>\n <td>1.32850</td>\n <td>-2.27460</td>\n <td>-0.81732</td>\n <td>-2.0283</td>\n <td>4.1054</td>\n <td>6.07750</td>\n <td>1.8039</td>\n <td>-0.732550</td>\n <td>...</td>\n <td>-0.076810</td>\n <td>-0.33024</td>\n <td>3.1960</td>\n <td>0.11645</td>\n <td>0.40308</td>\n <td>-1.3252</td>\n <td>-6.79520</td>\n <td>-0.15148</td>\n <td>-3.02960</td>\n <td>1</td>\n </tr>\n <tr>\n <th>2</th>\n <td>1.1746</td>\n <td>-0.499140</td>\n <td>-0.87776</td>\n <td>1.82510</td>\n <td>-0.73334</td>\n <td>4.7900</td>\n <td>-2.5747</td>\n <td>3.17360</td>\n <td>1.5446</td>\n <td>2.381600</td>\n <td>...</td>\n <td>-0.372870</td>\n <td>1.38220</td>\n <td>14.2960</td>\n <td>-3.01820</td>\n <td>1.59510</td>\n <td>3.1386</td>\n <td>1.27750</td>\n <td>-0.19646</td>\n <td>1.06080</td>\n <td>-1</td>\n </tr>\n <tr>\n <th>3</th>\n <td>-6.8093</td>\n <td>-10.860000</td>\n <td>1.73060</td>\n <td>-5.93960</td>\n <td>-1.53990</td>\n <td>-5.7733</td>\n <td>1.7528</td>\n <td>0.53843</td>\n <td>1.8374</td>\n <td>-0.045946</td>\n <td>...</td>\n <td>-0.098437</td>\n <td>-0.52114</td>\n <td>5.4197</td>\n <td>-1.16710</td>\n <td>-0.22531</td>\n <td>3.2550</td>\n <td>-0.72864</td>\n <td>0.41821</td>\n <td>-5.98750</td>\n <td>-1</td>\n </tr>\n <tr>\n <th>4</th>\n <td>-3.3811</td>\n <td>4.828100</td>\n <td>0.83346</td>\n <td>3.51870</td>\n <td>1.79240</td>\n <td>-20.6810</td>\n <td>-1.2216</td>\n <td>8.84820</td>\n <td>1.9447</td>\n <td>-3.840400</td>\n <td>...</td>\n <td>-0.033342</td>\n <td>-0.56903</td>\n <td>-3.0519</td>\n <td>-0.96726</td>\n <td>-0.61491</td>\n <td>-1.6502</td>\n <td>0.63276</td>\n <td>-0.31118</td>\n <td>0.85608</td>\n <td>1</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 101 columns</p>\n</div>",
"text/plain": " 0 1 2 3 4 5 6 7 \\\n0 -4.8111 8.805800 -0.72609 -0.30079 -3.21490 -1.5162 -1.2692 -5.19650 \n1 -6.4098 0.087018 1.32850 -2.27460 -0.81732 -2.0283 4.1054 6.07750 \n2 1.1746 -0.499140 -0.87776 1.82510 -0.73334 4.7900 -2.5747 3.17360 \n3 -6.8093 -10.860000 1.73060 -5.93960 -1.53990 -5.7733 1.7528 0.53843 \n4 -3.3811 4.828100 0.83346 3.51870 1.79240 -20.6810 -1.2216 8.84820 \n\n 8 9 ... 91 92 93 94 95 \\\n0 -2.6087 -11.405000 ... 0.007660 -0.23342 -4.8693 -3.99460 -0.58243 \n1 1.8039 -0.732550 ... -0.076810 -0.33024 3.1960 0.11645 0.40308 \n2 1.5446 2.381600 ... -0.372870 1.38220 14.2960 -3.01820 1.59510 \n3 1.8374 -0.045946 ... -0.098437 -0.52114 5.4197 -1.16710 -0.22531 \n4 1.9447 -3.840400 ... -0.033342 -0.56903 -3.0519 -0.96726 -0.61491 \n\n 96 97 98 99 100 \n0 3.7657 -0.32883 0.10334 -7.69890 1 \n1 -1.3252 -6.79520 -0.15148 -3.02960 1 \n2 3.1386 1.27750 -0.19646 1.06080 -1 \n3 3.2550 -0.72864 0.41821 -5.98750 -1 \n4 -1.6502 0.63276 -0.31118 0.85608 1 \n\n[5 rows x 101 columns]"
},
"metadata": {},
"execution_count": 38
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "Xbig = bigData.values[:,:-1]\nybig = bigData.values[:, -1].reshape(-1,1)",
"execution_count": 39,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "coordModelsBig = {}\nfor name1, coordSamp in zip(['weighted', 'uniform'], \n [weightedIndexSample, uniformIndexSample]):\n for name2, lipMethod in zip(['coordLip', 'unifLip'], \n [lipschitzLogisticLipschitz, uniformLogisticLipschitz]):\n coordModelsBig[(name1, name2)] = LogisticRegressor(objectiveParms={'lam':1},\n gdParms={'coordSample': coordSamp,\n 'lipschitzMethod': lipMethod},\n objective=coordinateObjective,\n gd=randomizedCoordinateDescent)",
"execution_count": 40,
"outputs": []
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "for key, value in coordModelsBig.items():\n print(key)\n %timeit value.fit(Xbig,ybig)\n print('Number of Passes: {}\\n'.format(value.funEvals))",
"execution_count": 41,
"outputs": [
{
"output_type": "stream",
"text": "('uniform', 'coordLip')\n1000 loops, best of 3: 768 µs per loop\nNumber of Passes: 3\n\n('uniform', 'unifLip')\n1000 loops, best of 3: 729 µs per loop\nNumber of Passes: 3\n\n('weighted', 'coordLip')\n1000 loops, best of 3: 967 µs per loop\nNumber of Passes: 3\n\n('weighted', 'unifLip')\n1000 loops, best of 3: 962 µs per loop\nNumber of Passes: 3\n\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "for key,value in coordModelsBig.items():\n print(key)\n print(value.w[value.w != 0])",
"execution_count": 42,
"outputs": [
{
"output_type": "stream",
"text": "('uniform', 'coordLip')\n[-0.37028504 -0.01520011 0.03269032]\n('uniform', 'unifLip')\n[-0.00073539 0.00089338 0.001223 ]\n('weighted', 'coordLip')\n[-0.03147521 0.01811496 -0.01268993]\n('weighted', 'unifLip')\n[-0.00070923 -0.00031989 0.00034754]\n",
"name": "stdout"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## UMass Amherst smoking data set for logistic regression"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "We could try testing out these methods on real data. For this:\n* Need to think about missing values\n* May have to think about using a kernel (argument may not longer be best represented as a linear combination of the input data)\n\nFor example, we include below a data set from the UMass Amherst website. Many more data sets can be found on this site – and for more than just logistic regression. The ones specifically for logistic regression are [here](https://www.umass.edu/statdata/statdata/stat-logistic.html). "
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "descr = requests.get('https://www.umass.edu/statdata/statdata/data/nhanes3.txt')\nprint(descr.text)",
"execution_count": 43,
"outputs": [
{
"output_type": "stream",
"text": "NAME: \tNational Health and Nutrition Survey (NHANES3.DAT)\nSIZE:\t17,030 observations, 16 variables\n\nSOURCE:\tHosmer and Lemeshow (2000) Applied Logistic Regression: Second \n\tEdition. These data are copyrighted by John Wiley & Sons Inc. and must \n\tbe acknowledged and used accordingly.\n\n\nDESCRIPTIVE ABSTRACT:\n\nThese data are described in Table 6.3 page 215 in the source text.\n\n\nLIST OF VARIABLES:\n\nVariable Description Codes/Values Name\n___________________________________________________________________\n\n1 Respondent Identification \t SEQN\n Number \n\n2 Pseudo-PSU 1,2 SDPPSU6\n\n3 Pseudo-stratum 01 - 49 SDPSTRA6 \n\n4 Statistical weight 225.93 - 139744.9 WTPFHX6\n\n5 Age years HSAGEIR\n\n6 Sex 0 = Female, 1 = Male HSSEX\n\n7 Race 1 = White DMARACER\n 2 = Black \n\t\t\t\t 3 = Other \n\n8 Body Weight pounds BMPWTLBS\n\n9 Standing Height inches BMPHTIN\n\n10 Average Systolic BP mm Hg PEPMNK1R\n\n11 Average Diastolic BP mm Hg PEPMNK5R\n\n12 Has respondent smoked 1 = Yes, 2 = No HAR1\n > 100 cigarettes in life \n\n13 Does repondent smoke 1 = Yes, 2 = No HAR3\n cigarettes now?\n\n14 Smoking 1 = if HAR1 = 2 SMOKE\n 2 = if HAR1=1 & HAR3=2\n 3 = if HAR1=1 & HAR3=1\n\n15 Serum Cholesterol mg/100ml TCP\n\n16 High Blood Pressure 0 if PEPMNK1R <= 140 HBP\n 1 if PEPMNK1R > 140\n______________________________________________________________________\n\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "smoking = pd.read_csv(filepath_or_buffer='https://www.umass.edu/statdata/statdata/data/nhanes3.dat', sep=' *', header=None, na_values='.')",
"execution_count": 44,
"outputs": [
{
"output_type": "stream",
"text": "/Users/berkas/anaconda/lib/python3.5/site-packages/ipykernel/__main__.py:1: ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'.\n if __name__ == '__main__':\n/Users/berkas/anaconda/lib/python3.5/site-packages/pandas/io/parsers.py:1961: FutureWarning: split() requires a non-empty pattern match.\n yield pat.split(line.strip())\n/Users/berkas/anaconda/lib/python3.5/site-packages/pandas/io/parsers.py:1963: FutureWarning: split() requires a non-empty pattern match.\n yield pat.split(line.strip())\n",
"name": "stderr"
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print('smoking.shape = {}'.format(smoking.shape))\nsmoking.head()",
"execution_count": 45,
"outputs": [
{
"output_type": "stream",
"text": "smoking.shape = (17031, 16)\n",
"name": "stdout"
},
{
"output_type": "execute_result",
"data": {
"text/html": "<div>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n <th>1</th>\n <th>2</th>\n <th>3</th>\n <th>4</th>\n <th>5</th>\n <th>6</th>\n <th>7</th>\n <th>8</th>\n <th>9</th>\n <th>10</th>\n <th>11</th>\n <th>12</th>\n <th>13</th>\n <th>14</th>\n <th>15</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>3.0</td>\n <td>1.0</td>\n <td>44.0</td>\n <td>1735.14</td>\n <td>21.0</td>\n <td>1.0</td>\n <td>1.0</td>\n <td>179.5</td>\n <td>70.4</td>\n <td>120.0</td>\n <td>67.0</td>\n <td>2.0</td>\n <td>NaN</td>\n <td>1.0</td>\n <td>268.0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>4.0</td>\n <td>1.0</td>\n <td>43.0</td>\n <td>1725.01</td>\n <td>32.0</td>\n <td>0.0</td>\n <td>1.0</td>\n <td>135.6</td>\n <td>63.9</td>\n <td>126.0</td>\n <td>86.0</td>\n <td>2.0</td>\n <td>NaN</td>\n <td>1.0</td>\n <td>160.0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>9.0</td>\n <td>2.0</td>\n <td>43.0</td>\n <td>19451.83</td>\n <td>48.0</td>\n <td>0.0</td>\n <td>1.0</td>\n <td>149.7</td>\n <td>61.8</td>\n <td>131.0</td>\n <td>73.0</td>\n <td>1.0</td>\n <td>2.0</td>\n <td>2.0</td>\n <td>236.0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>10.0</td>\n <td>1.0</td>\n <td>6.0</td>\n <td>27769.56</td>\n <td>35.0</td>\n <td>1.0</td>\n <td>1.0</td>\n <td>203.5</td>\n <td>69.8</td>\n <td>130.0</td>\n <td>82.0</td>\n <td>2.0</td>\n <td>NaN</td>\n <td>1.0</td>\n <td>225.0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>11.0</td>\n <td>2.0</td>\n <td>40.0</td>\n <td>1245.52</td>\n <td>48.0</td>\n <td>1.0</td>\n <td>1.0</td>\n <td>155.3</td>\n <td>66.2</td>\n <td>120.0</td>\n <td>70.0</td>\n <td>1.0</td>\n <td>2.0</td>\n <td>2.0</td>\n <td>260.0</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": " 0 1 2 3 4 5 6 7 8 9 10 11 \\\n0 3.0 1.0 44.0 1735.14 21.0 1.0 1.0 179.5 70.4 120.0 67.0 2.0 \n1 4.0 1.0 43.0 1725.01 32.0 0.0 1.0 135.6 63.9 126.0 86.0 2.0 \n2 9.0 2.0 43.0 19451.83 48.0 0.0 1.0 149.7 61.8 131.0 73.0 1.0 \n3 10.0 1.0 6.0 27769.56 35.0 1.0 1.0 203.5 69.8 130.0 82.0 2.0 \n4 11.0 2.0 40.0 1245.52 48.0 1.0 1.0 155.3 66.2 120.0 70.0 1.0 \n\n 12 13 14 15 \n0 NaN 1.0 268.0 0 \n1 NaN 1.0 160.0 0 \n2 2.0 2.0 236.0 0 \n3 NaN 1.0 225.0 0 \n4 2.0 2.0 260.0 0 "
},
"metadata": {},
"execution_count": 45
}
]
},
{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "smoking.tail()",
"execution_count": 46,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/html": "<div>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n <th>1</th>\n <th>2</th>\n <th>3</th>\n <th>4</th>\n <th>5</th>\n <th>6</th>\n <th>7</th>\n <th>8</th>\n <th>9</th>\n <th>10</th>\n <th>11</th>\n <th>12</th>\n <th>13</th>\n <th>14</th>\n <th>15</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>17026</th>\n <td>53589.0</td>\n <td>2.0</td>\n <td>8.0</td>\n <td>4667.32</td>\n <td>81.0</td>\n <td>0.0</td>\n <td>1.0</td>\n <td>190.2</td>\n <td>61.8</td>\n <td>129.0</td>\n <td>72.0</td>\n <td>1.0</td>\n <td>2.0</td>\n <td>2.0</td>\n <td>168.0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>17027</th>\n <td>53593.0</td>\n <td>2.0</td>\n <td>17.0</td>\n <td>18911.40</td>\n <td>23.0</td>\n <td>1.0</td>\n <td>1.0</td>\n <td>172.7</td>\n <td>76.2</td>\n <td>123.0</td>\n <td>83.0</td>\n <td>2.0</td>\n <td>NaN</td>\n <td>1.0</td>\n <td>188.0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>17028</th>\n <td>53594.0</td>\n <td>2.0</td>\n <td>11.0</td>\n <td>9323.23</td>\n <td>26.0</td>\n <td>0.0</td>\n <td>1.0</td>\n <td>234.9</td>\n <td>67.1</td>\n <td>124.0</td>\n <td>83.0</td>\n <td>2.0</td>\n <td>NaN</td>\n <td>1.0</td>\n <td>137.0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>17029</th>\n <td>53616.0</td>\n <td>2.0</td>\n <td>21.0</td>\n <td>2341.16</td>\n <td>85.0</td>\n <td>1.0</td>\n <td>1.0</td>\n <td>189.1</td>\n <td>68.0</td>\n <td>157.0</td>\n <td>94.0</td>\n <td>2.0</td>\n <td>NaN</td>\n <td>1.0</td>\n <td>285.0</td>\n <td>1</td>\n </tr>\n <tr>\n <th>17030</th>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": " 0 1 2 3 4 5 6 7 8 9 10 \\\n17026 53589.0 2.0 8.0 4667.32 81.0 0.0 1.0 190.2 61.8 129.0 72.0 \n17027 53593.0 2.0 17.0 18911.40 23.0 1.0 1.0 172.7 76.2 123.0 83.0 \n17028 53594.0 2.0 11.0 9323.23 26.0 0.0 1.0 234.9 67.1 124.0 83.0 \n17029 53616.0 2.0 21.0 2341.16 85.0 1.0 1.0 189.1 68.0 157.0 94.0 \n17030 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN \n\n 11 12 13 14 15 \n17026 1.0 2.0 2.0 168.0 0 \n17027 2.0 NaN 1.0 188.0 0 \n17028 2.0 NaN 1.0 137.0 0 \n17029 2.0 NaN 1.0 285.0 1 \n17030 NaN NaN NaN NaN 0 "
},
"metadata": {},
"execution_count": 46
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "**Note:** something's up with the last row there; should remove it. "
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# Stochastic Gradient Descent"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "So far what we've talked about has had a big effect on speed-up in the case where $d$ is large. When instead $n$ is very large we should look to Stochastic gradient descent. Note that Randomized coordinate descent is an example of stochastic gradient descent. Here, instead, we talk about \n\n* mini-batch stochast gradient descent (mini-batch SGD)\n* stochastic average gradient descent (SAG)\n* stochastic variance-reduced gradient methods (SVRG)"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Generally, SGD operates as follows. We seek to minimize an objective function \n$$\nf(w; X,y) = \\frac{1}{n}\\sum_{i=1}^n f_i(w)\n$$\nwhere, typically, $f_i$ is associated to the $i$-th observation. In usual gradient descent, we march *via* the updates\n$$\nw \\leftarrow w - \\alpha \\nabla_w f(w; X,y)\n$$\nwhereas in SGD we approximate the gradient $\\nabla_w f(w; X,y)$ by $\\nabla_w f_i(w)$ so that the SGD algorithm is given by \n1. Let $w^0$ be an initial parameter vector; $(\\alpha_t)$ a sequence of learning rates\n2. Repeat until stopping condition satisfied:\n 1. Randomly shuffle $[n]$; \n 2. For each $i$ (in the new order):\n 1. $w^{t+1} \\leftarrow w^t - \\alpha_t \\nabla_w f_i(w)$\n\n3. Return $w^T$"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Mini-batch SGD"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "In mini-batch SGD we take *batches* of observations (say of size $m_t$ on iteration $t$) and approximate $\\nabla_w f(w; X,y)$ *via*\n$$\n\\nabla_w f(w; X,y) \\approx \\frac{1}{m_t} \\sum_{i=1}^{m_t} \\nabla_w f_i(w)\n$$"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "**Exercise:** Using the `randomizedCoordinateDescent` function as a starting point, write your own function that performs mini-batch SGD."
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Stochastic Average Gradient\n\n$w$ is computed according to the updates\n$$\nw^{t+1} \\leftarrow w^t - \\frac{\\alpha_t}{n} \\sum_{i=1}^n g_i^t\n$$\nwhere $g_i^t$ is defined in the following way. On each iteration $t$, an index $i_t \\in [n]$ is chosen randomly and we define\n$$\ng_i^t := \\begin{cases}\n\\nabla_i f(w^t) & i = i_t\\\\\ng_i^{t-1} & \\text{otherwise}\n\\end{cases}\n$$\nwhere $\\nabla_i$ corresponds to the $i$-th element of the gradient (*i.e.*, $\\partial/\\partial w_i$)"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "### References\n1. [Original paper](https://arxiv.org/pdf/1202.6258.pdf)\n2. [Minimizing Finite Sums with SAG](https://arxiv.org/pdf/1309.2388.pdf)\n2. [SAG software](https://www.cs.ubc.ca/~schmidtm/Software/SAG.html)\n3. [SAG slides](https://www.cs.ubc.ca/~schmidtm/Documents/2014_Google_SAG.pdf)"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## SVRG"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "We refer the interested reader to reference 3. below instead of repeating the derivation and intuition here."
},
{
"metadata": {},
"cell_type": "markdown",
"source": "### References\n1. [Accelerating SGD using predictive variance reduction](https://papers.nips.cc/paper/4937-accelerating-stochastic-gradient-descent-using-predictive-variance-reduction.pdf)\n2. [Practical SVRG](https://arxiv.org/pdf/1511.01942.pdf)\n3. [SVRG intro from Stanford](http://cs.stanford.edu/~ppasupat/a9online/1321.html)"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# Further reading\n\nWe've barely scratched the surface. Some things for which there was not enough time to write notes...\n\n## Regularization\n\n**Idea:** avoid *overfitting* the model to the data by constraining the size/magnitude/norm/behaviour of the parameters\n\n### $L^2$ regularization\n\n*cf.* Ridge regression, elastic net, *etc.*\n\n### $L^1$ regularization\n\nRobust linear regression is an excellent way of demonstrating the difference between optimizing the $L^1$ norm and optimizing the $L^2$ norm. \n\nAlso *cf.* Compressed Sensing; the $\\ell^1$ norm is *sparsity promoting*. That is, under certain conditions, the solution to the constrained $\\ell^1$ minimization problem \n$$\n\\hat x := \\argmin \\|x\\|_1 \\quad \\text{s.t.}\\quad \\|Ax - y\\|_2^2 \\leq \\eta\n$$\nis unique and $s$-sparse if elements of $A$ come from a certain distribution and $m \\geq C s \\log (N/s)$ for a known [and small] constant $C$.\n\n### Block sparsity\n\nThis constrains the structure of the parameters - *e.g.* if some parameters are zero then it forces other parameters to be zero as well. \n\n## Constrained Optimization\n### Projected Gradient\n\n### Proximal Gradient\n\n### Newton's method\n\nFrom a second-order Taylor expansion, one sees \n$$\nf(w^*) = f(w^j) + \\nabla f(w^j) p^j + \\frac{1}{2} (p^j)^T \\nabla^2 f(w^j) p_j + O (\\|p^j\\|^3)\n$$\nfor an unknown vector $p_j$. Since $\\nabla^2 f(w^j)$ is PSD, seek a particular vector that \"cancels\" this second-order term with the gradient term. Gets superlinear convergence. \n\n### References: \n1. Boyd & Vandenberghe's [Convex Optimization](https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf)\n2. Bertsekas's Convex Optimization Algorithms\n3. [Ascher & Greif](http://gw2jh3xr2c.search.serialssolutions.com/?sid=sersol&SS_jc=TC0001261310&title=A%20first%20course%20in%20numerical%20methods) (pg. 261–265)\n\n## Dual methods\n### The Fenchel Dual, geometric multipliers and the KKT conditions\n### Dual coordinate ascent"
}
],
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"name": "python",
"nbconvert_exporter": "python",
"mimetype": "text/x-python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"toc": {
"threshold": 4,
"number_sections": true,
"toc_cell": true,
"toc_window_display": false,
"toc_section_display": "block",
"sideBar": true,
"navigate_menu": true,
"nav_menu": {
"width": "252px",
"height": "336px"
}
},
"gist": {
"id": "f3ae3c29f1fb5ff53b329114296dbf99",
"data": {
"description": "Gradient Descent (master).ipynb",
"public": true
}
},
"_draft": {
"nbviewer_url": "https://gist.github.com/f3ae3c29f1fb5ff53b329114296dbf99"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment