{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Linear Algebra and Numpy\n",
    "\n",
    "Linear algebra is the math underlying much of machine learning, including sklearn's LinearRegression we've been using.  You should probably take a linear algrebra course at some point if you haven't already.\n",
    "\n",
    "In 320, we'll some very basic ideas.  Let's start with some intuition."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "plt.rcParams[\"font.size\"] = 16"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A linear relationship between two variables looks like a straight line when plotted (contrast this with the quadtratic line, which is not linear):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'y')"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df = pd.DataFrame({\"x\": np.arange(0, 4, 0.1)})\n",
    "df[\"linear relation\"] = df[\"x\"] * -2 + 5\n",
    "df[\"quadratic relation\"] = (df[\"x\"] - 2) ** 2\n",
    "ax = df.set_index(\"x\").plot.line()\n",
    "ax.set_ylabel(\"y\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Straight lines generalize to flat planes in 3 dimensions (or hyperplanes in more dimensions!)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<mpl_toolkits.mplot3d.art3d.Poly3DCollection at 0x7fab20d716a0>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111, projection='3d', xlim=(0,10), ylim=(0,10), zlim=(0,10))\n",
    "ax.plot_trisurf(np.array([0, 0, 10, 10]),\n",
    "                   np.array([0, 10, 10, 0]),\n",
    "                   np.array([5,7,5,3]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Numpy Arrays"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Linear algebra will involve working with matrices and vectors; we'll learn numpy for that.  Pandas and sklearn are already based on numpy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>x1</th>\n",
       "      <th>x2</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>8</td>\n",
       "      <td>5</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   x1  x2  y\n",
       "0   0   2  1\n",
       "1   2   3  4\n",
       "2   8   5  6"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame([[0,2,1], [2,3,4], [8,5,6]], columns=[\"x1\", \"x2\", \"y\"])\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Internally, we have a numpy array:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 2, 1],\n",
       "       [2, 3, 4],\n",
       "       [8, 5, 6]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.values # a 2-dimensional numpy array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(df.values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "lr = LinearRegression()\n",
    "lr.fit(df[[\"x1\", \"x2\"]], df[\"y\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-2.,  7.])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lr.coef_ # a 1-dimension numpy array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A 2-dimensional array is called a *matrix*, and a 1-dimensional array is called a *vector*.  A *tensor* is a general term for an N-dimensional array.  A 0-dimensional array is called a *scalar*, and is also possible in numpy:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(3.14)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.array(3.14)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Reshaping an array is easy: just specify the number of rows, columns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [4, 5, 6]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([[1,2,3], [4,5,6]])\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2],\n",
       "       [3, 4],\n",
       "       [5, 6]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = a.reshape(3, 2)\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Some shapes wouldn't work (e.g., `a.reshape(3, 4)` would fail, because a only has 6 values, but the reshape would require 12).  If we pass -1 for a dimension, numpy calculates how large it should be."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2],\n",
       "       [3, 4],\n",
       "       [5, 6]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = a.reshape(3, -1)\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can index into an array with `ARRAY[ROW, COL]`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[2, 1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Be careful with modifications!  Even after reshape or slicing, these get reflected back to the original (in contrast, a slice of a list produces a new list object)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[  1,   2,   3],\n",
       "       [  4,   5, 100]])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b[2, 1] = 100\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can always explicitly make a copy if necessary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ -3,   2,   3],\n",
       "       [  4,   5, 100]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = a.copy()\n",
    "c[0,0] = -3\n",
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[  1,   2,   3],\n",
       "       [  4,   5, 100]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dot Product\n",
    "\n",
    "In its simplest form, the dot product in linear algebra multiplies a horizontal vector by a vertical vector.  Numpy doesn't have a way to specify a vector's direction, so we'll actually encode them as matrices that have one row (horizontal) or one column (vertical)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([10,  0, 20, -1])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([10, 0, 20, -1])\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2. , 9. , 0.5, 3. ])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = np.array([2, 9, 0.5, 3])\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[10,  0, 20, -1]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = a.reshape(1, -1) # one row, however many columns necessary (horizontal vector)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2. ],\n",
       "       [9. ],\n",
       "       [0.5],\n",
       "       [3. ]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = b.reshape(-1, 1) # one column, however many rows necessary (vertical vector)\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`@` is the dot product operator in Python."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[27.]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a @ b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To get that, we multiplied the first number in a by the first number in b; then we multiplied the second number in a by the second number in b, and so on.  At the end, we added the four products.\n",
    "\n",
    "It was like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "27.0"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "10*2 + 0*9 + 20*0.5 + -1*3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The dot product is key to how sklearn's LinearRegression model as well as the classification model we'll learn in a week make predictions.  We won't explain more about the following code here, but observe that lr's predictions can be computed with a simple expression using a dot product."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 4., 6.])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lr.predict(df[[\"x1\", \"x2\"]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    1.0\n",
       "1    4.0\n",
       "2    6.0\n",
       "dtype: float64"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[[\"x1\", \"x2\"]] @ lr.coef_ + lr.intercept_"
   ]
  }
 ],
 "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.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
