Programming Exercise 5:\n",
" Regularized Linear Regression and Bias vs. Variance
\n",
" \n",
"
Introduction
\n",
"In this exercise, we will implement regularized linear regression and use it to study models with different bias-variance properties. To start, we will import necessary modules, implement some useful functions from previous exercises, and load our data.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# used for manipulating directory paths\n",
"import os\n",
"\n",
"# Scientific and vector computation for python\n",
"import numpy as np\n",
"\n",
"# Plotting library\n",
"from matplotlib import pyplot as plt\n",
"\n",
"# Optimization module in scipy\n",
"from scipy import optimize\n",
"\n",
"# will be used to load MATLAB mat datafile format\n",
"from scipy.io import loadmat\n",
"\n",
"# tells matplotlib to embed plots within the notebook\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def trainLinearReg(linearRegCostFunction, X, y, lambda_=0.0, maxiter=200):\n",
" \"\"\"\n",
" Trains linear regression using scipy's optimize.minimize.\n",
"\n",
" Parameters\n",
" ----------\n",
" X : array_like\n",
" The dataset with shape (m x n+1). The bias term is assumed to be concatenated.\n",
"\n",
" y : array_like\n",
" Function values at each datapoint. A vector of shape (m,).\n",
"\n",
" lambda_ : float, optional\n",
" The regularization parameter.\n",
"\n",
" maxiter : int, optional\n",
" Maximum number of iteration for the optimization algorithm.\n",
"\n",
" Returns\n",
" -------\n",
" theta : array_like\n",
" The parameters for linear regression. This is a vector of shape (n+1,).\n",
" \"\"\"\n",
" # Initialize Theta\n",
" initial_theta = np.zeros(X.shape[1])\n",
"\n",
" # Create \"short hand\" for the cost function to be minimized\n",
" costFunction = lambda t: linearRegCostFunction(X, y, t, lambda_)\n",
"\n",
" # Now, costFunction is a function that takes in only one argument\n",
" options = {'maxiter': maxiter}\n",
"\n",
" # Minimize using scipy\n",
" res = optimize.minimize(costFunction, initial_theta, jac=True, method='TNC', options=options)\n",
" return res.x"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def featureNormalize(X):\n",
" \"\"\"\n",
" Normalizes the features in X returns a normalized version of X where the mean value of each\n",
" feature is 0 and the standard deviation is 1. This is often a good preprocessing step to do when\n",
" working with learning algorithms.\n",
"\n",
" Parameters\n",
" ----------\n",
" X : array_like\n",
" An dataset which is a (m x n) matrix, where m is the number of examples,\n",
" and n is the number of dimensions for each example.\n",
"\n",
" Returns\n",
" -------\n",
" X_norm : array_like\n",
" The normalized input dataset.\n",
"\n",
" mu : array_like\n",
" A vector of size n corresponding to the mean for each dimension across all examples.\n",
"\n",
" sigma : array_like\n",
" A vector of size n corresponding to the standard deviations for each dimension across\n",
" all examples.\n",
" \"\"\"\n",
" mu = np.mean(X, axis=0)\n",
" X_norm = X - mu\n",
"\n",
" sigma = np.std(X_norm, axis=0, ddof=1)\n",
" X_norm /= sigma\n",
" return X_norm, mu, sigma"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def plotFit(polyFeatures, min_x, max_x, mu, sigma, theta, p):\n",
" \"\"\"\n",
" Plots a learned polynomial regression fit over an existing figure.\n",
" Also works with linear regression.\n",
" Plots the learned polynomial fit with power p and feature normalization (mu, sigma).\n",
"\n",
" Parameters\n",
" ----------\n",
" polyFeatures : func\n",
" A function which generators polynomial features from a single feature.\n",
"\n",
" min_x : float\n",
" The minimum value for the feature.\n",
"\n",
" max_x : float\n",
" The maximum value for the feature.\n",
"\n",
" mu : float\n",
" The mean feature value over the training dataset.\n",
"\n",
" sigma : float\n",
" The feature standard deviation of the training dataset.\n",
"\n",
" theta : array_like\n",
" The parameters for the trained polynomial linear regression.\n",
"\n",
" p : int\n",
" The polynomial order.\n",
" \"\"\"\n",
" # We plot a range slightly bigger than the min and max values to get\n",
" # an idea of how the fit will vary outside the range of the data points\n",
" x = np.arange(min_x - 15, max_x + 25, 0.05).reshape(-1, 1)\n",
"\n",
" # Map the X values\n",
" X_poly = polyFeatures(x, p)\n",
" X_poly -= mu\n",
" X_poly /= sigma\n",
"\n",
" # Add ones\n",
" X_poly = np.concatenate([np.ones((x.shape[0], 1)), X_poly], axis=1)\n",
"\n",
" # Plot\n",
" plt.plot(x, np.dot(X_poly, theta), '--', lw=2)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
1 Regularized Linear Regression
\n",
"In the first half of this exercize, we will implement regularized linear regression to predict the amount of water flowing out of a dam using the change of water level in a reservoir. We begin by visualizing the dataset which is split into a training set (X,y), a cross validation set (Xval, yval), and a test set (Xtest, ytest)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Load from ex5data1.mat, where all variables will be store in a dictionary\n",
"data = loadmat(os.path.join('Data', 'ex5data1.mat'))\n",
"\n",
"# Extract train, test, validation data from dictionary\n",
"# and also convert y's form 2-D matrix (MATLAB format) to a numpy vector\n",
"X, y = data['X'], data['y'][:, 0]\n",
"Xtest, ytest = data['Xtest'], data['ytest'][:, 0]\n",
"Xval, yval = data['Xval'], data['yval'][:, 0]\n",
"\n",
"# m = Number of examples\n",
"m = y.size\n",
"\n",
"# Plot training data\n",
"plt.plot(X, y, 'ro', ms=10, mec='k', mew=1)\n",
"plt.xlabel('Change in water level (x)')\n",
"plt.ylabel('Water flowing out of the dam (y)');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we implement a regularized linear regression cost function."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"def linearRegCostFunction(X, y, theta, lambda_=0.0):\n",
" \"\"\"\n",
" Compute cost and gradient for regularized linear regression \n",
" with multiple variables. Computes the cost of using theta as\n",
" the parameter for linear regression to fit the data points in X and y. \n",
" \n",
" Parameters\n",
" ----------\n",
" X : array_like\n",
" The dataset. Matrix with shape (m x n + 1) where m is the \n",
" total number of examples, and n is the number of features \n",
" before adding the bias term.\n",
" \n",
" y : array_like\n",
" The functions values at each datapoint. A vector of\n",
" shape (m, ).\n",
" \n",
" theta : array_like\n",
" The parameters for linear regression. A vector of shape (n+1,).\n",
" \n",
" lambda_ : float, optional\n",
" The regularization parameter.\n",
" \n",
" Returns\n",
" -------\n",
" J : float\n",
" The computed cost function. \n",
" \n",
" grad : array_like\n",
" The value of the cost function gradient w.r.t theta. \n",
" A vector of shape (n+1, ).\n",
" \"\"\"\n",
" # Initialize some useful values\n",
" m = y.size # number of training examples\n",
" J = 0\n",
" grad = np.zeros(theta.shape)\n",
"\n",
" h = X.dot(theta)\n",
" J = h-y\n",
" J = np.square(J)\n",
" J = np.sum(J)\n",
" J = J / (2*m)\n",
" tempTheta = theta[0]\n",
" theta[0] = 0\n",
" J += (lambda_/(2*m))*np.sum(np.sum(np.square(theta)))\n",
" theta[0] = tempTheta\n",
" \n",
" grad = (1/m)*X.transpose().dot(h-y)\n",
" grad[1:] += (lambda_/m)*theta[1:]\n",
" \n",
" return J, grad"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Cost at theta = [1, 1]:\t 303.993192 \n",
"Gradient at theta = [1, 1]: [-15.303016, 598.250744] \n"
]
}
],
"source": [
"# Test case for cost function\n",
"\n",
"theta = np.array([1, 1])\n",
"J, grad = linearRegCostFunction(np.concatenate([np.ones((m, 1)), X], axis=1), y, theta, 1)\n",
"\n",
"print('Cost at theta = [1, 1]:\\t %f ' % J)\n",
"print('Gradient at theta = [1, 1]: [{:.6f}, {:.6f}] '.format(*grad))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next we run train our linear regression model using this cost function and graph the resulting line of best fit."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# add a columns of ones for the y-intercept\n",
"X_aug = np.concatenate([np.ones((m, 1)), X], axis=1)\n",
"theta = trainLinearReg(linearRegCostFunction, X_aug, y, lambda_=0)\n",
"\n",
"# Plot fit over the data\n",
"plt.plot(X, y, 'ro', ms=10, mec='k', mew=1.5)\n",
"plt.xlabel('Change in water taylor(x)')\n",
"plt.ylabel('Water flowing out of the dam (y)')\n",
"plt.plot(X, np.dot(X_aug, theta), '--', lw=2);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
2 Bias-Variance
\n",
"An important concept in machine learning is the bias-variance tradeoff. High bias models are not complex enough for the data and tend to underfit, while high variance models over fit the training data.\n",
"\n",
"In this portion of the exercise we attempt to diagnose bias-variance problems by plotting training and test errors on a learning curve. \n",
"\n",
"We begin by creating a function to return a vector of errors for the training and cross validation set, then plotting it on a graph."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"def learningCurve(X, y, Xval, yval, lambda_=0):\n",
" \"\"\"\n",
" Generates the train and cross validation set errors needed to plot a learning curve\n",
" returns the train and cross validation set errors for a learning curve. \n",
" \n",
" Parameters\n",
" ----------\n",
" X : array_like\n",
" The training dataset. Matrix with shape (m x n + 1) where m is the \n",
" total number of examples, and n is the number of features \n",
" before adding the bias term.\n",
" \n",
" y : array_like\n",
" The functions values at each training datapoint. A vector of\n",
" shape (m, ).\n",
" \n",
" Xval : array_like\n",
" The validation dataset. Matrix with shape (m_val x n + 1) where m is the \n",
" total number of examples, and n is the number of features \n",
" before adding the bias term.\n",
" \n",
" yval : array_like\n",
" The functions values at each validation datapoint. A vector of\n",
" shape (m_val, ).\n",
" \n",
" lambda_ : float, optional\n",
" The regularization parameter.\n",
" \n",
" Returns\n",
" -------\n",
" error_train : array_like\n",
" A vector of shape m. error_train[i] contains the training error for\n",
" i examples.\n",
" error_val : array_like\n",
" A vecotr of shape m. error_val[i] contains the validation error for\n",
" i training examples.\n",
" \"\"\"\n",
" # Number of training examples\n",
" m = y.size\n",
"\n",
" # You need to return these values correctly\n",
" error_train = np.zeros(m)\n",
" error_val = np.zeros(m)\n",
"\n",
" # ====================== YOUR CODE HERE ======================\n",
" \n",
" for i in range(1, m+1):\n",
" X_train = X[:i, :]\n",
" y_train = y[:i]\n",
" Theta = trainLinearReg(linearRegCostFunction, X_train, y_train, lambda_=0.0, maxiter=200)\n",
" error_train[i-1] = linearRegCostFunction(X_train,y_train,Theta,0)[0];\n",
" error_val[i-1] = linearRegCostFunction(Xval,yval,Theta,0)[0];\n",
" \n",
" # =============================================================\n",
" return error_train, error_val"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# Training Examples\tTrain Error\tCross Validation Error\n",
" \t1\t\t0.000000\t205.121096\n",
" \t2\t\t0.000000\t110.302641\n",
" \t3\t\t3.286595\t45.010231\n",
" \t4\t\t2.842678\t48.368911\n",
" \t5\t\t13.154049\t35.865165\n",
" \t6\t\t19.443963\t33.829962\n",
" \t7\t\t20.098522\t31.970986\n",
" \t8\t\t18.172859\t30.862446\n",
" \t9\t\t22.609405\t31.135998\n",
" \t10\t\t23.261462\t28.936207\n",
" \t11\t\t24.317250\t29.551432\n",
" \t12\t\t22.373906\t29.433818\n"
]
},
{
"data": {
"image/png": "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PfdcAHbt2sX555/PmDFjOPbYY1m6dGlof1dccQWTJk1i8ODBXZZErJOdWEoPQN9hsG2561vBmtE28Wxmryhtt6LFWcuWLWPixIktzl+4cCHLli1j0KBBLF68mAcffJD33nsPVeWYY47h5JNPZu3atQwYMICXXnJNf1dUVLBr1y6eeeYZVq5ciYiwe/fug7b9rW99i/Hjx/PHP/6RtLQ0nnjiCZ566inA9dHw7rvvIiLcd999/O53v+O2225rMc7LL7+cP/7xj5x88sn87Gc/C03v168fc+bMIRAIsHr1aqZOncqiRYuYNWsWt956Ky+++CIA8+bNC61z4403Mn78eJ599lneeOMNLr300lBHRCtXrmTu3LlUVVUxbNgwrrnmGtLT01uMqz3sSiHWQvUKS/2Nw5gEdPTRRzNo0CAAFixYwDe+8Q169uxJdnY23/zmN5k/fz6jR4/mtdde4/rrr2f+/Pn06tWL3NxcAoEAV111FX//+9/Jyso6aNsFBQWMHDmS119/nSVLlpCenh6qCygrK+OMM85g9OjR3HLLLXzyySctxlhRUcHu3bs5+eSTAbjkkktC8+rq6vjud7/L6NGjueiiiyI2993cggULQts49dRT2blzJxUVLrGec845ZGZmkp+fT79+/SJewXSUXSnEWsFoWPqE1SuY+NfKL/poGTlyJE8//XSL88Obz26p3bYvfelLLF68mJdffpkbbriBr33ta/zyl79k4cKFvP766zz++OP86U9/4o033jho3WARUv/+/UNFRwA/+MEP+OlPf8p5553HvHnzmDlzZosxqirNugYIueOOO+jfvz8fffQRjY2NBAKBFrfT2nEGt5+ZmRma1lVNg9uVQqzZHUjGtOjUU0+lpqaGe++9NzTt/fff58033zxo2ZNOOolnn32Wffv2sXfvXp555hlOPPFENm/eTFZWFhdffDHXXXcdH3zwAXv27KGiooKzzz6bO++8M1T80twFF1zAyy+/zBNPPMGUKVNC0ysqKigqKgLgoYceavUY8vLy6NWrFwsWLADgkUceabKdwsJCUlJS+Otf/xqqMM/JyaGqqiri9k466aTQNubNm0d+fj65ubmtxnAo7Eoh1vo361shJdXfeIyJIyLCM888w49//GNmzZpFIBCgpKSEO++8k02bNjVZdsKECUybNi10d9BVV13F+PHjeeWV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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"X_aug = np.concatenate([np.ones((m, 1)), X], axis=1)\n",
"Xval_aug = np.concatenate([np.ones((yval.size, 1)), Xval], axis=1)\n",
"error_train, error_val = learningCurve(X_aug, y, Xval_aug, yval, lambda_=0)\n",
"\n",
"plt.plot(np.arange(1, m+1), error_train, np.arange(1, m+1), error_val, lw=2)\n",
"plt.title('Learning curve for linear regression')\n",
"plt.legend(['Train', 'Cross Validation'])\n",
"plt.xlabel('Number of training examples')\n",
"plt.ylabel('Error')\n",
"plt.axis([0, 13, 0, 150])\n",
"\n",
"print('# Training Examples\\tTrain Error\\tCross Validation Error')\n",
"for i in range(m):\n",
" print(' \\t%d\\t\\t%f\\t%f' % (i+1, error_train[i], error_val[i]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Looking at the resulting figure, we can see that both the taining and cross validation errors are high when the number of training examples is increase (specifically the training error increases to math cross validation). This reflects a problem of high bias in our model. That is to say, our model is too simple and unable to fit our data set well. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
3 Polynomial Regression
\n",
"The problem with our model was that it was too simple for the data and resulted in underfitting (high bias). In this portion of the exercise, we will address this problem by adding more features to produce a more complex fit to the data. We begin by creating a function to map the original training set into its higher powers."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"def polyFeatures(X, p):\n",
" \"\"\"\n",
" Maps X (1D vector) into the p-th power.\n",
" \n",
" Parameters\n",
" ----------\n",
" X : array_like\n",
" A data vector of size m, where m is the number of examples.\n",
" \n",
" p : int\n",
" The polynomial power to map the features. \n",
" \n",
" Returns \n",
" -------\n",
" X_poly : array_like\n",
" A matrix of shape (m x p) where p is the polynomial \n",
" power and m is the number of examples. That is:\n",
" \n",
" X_poly[i, :] = [X[i], X[i]**2, X[i]**3 ... X[i]**p]\n",
" \"\"\"\n",
" X_poly = np.zeros((X.shape[0], p))\n",
" X_poly[:,0] = X[:,0]\n",
" for i in range(1,p):\n",
" X_poly[:,i] = np.power(X.transpose(), i+1)\n",
"\n",
" return X_poly"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now apply this function to our training set, test set, and cross validation set."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"p = 8\n",
"\n",
"# Map X onto Polynomial Features and Normalize\n",
"X_poly = polyFeatures(X, p)\n",
"X_poly, mu, sigma = featureNormalize(X_poly)\n",
"X_poly = np.concatenate([np.ones((m, 1)), X_poly], axis=1)\n",
"\n",
"# Map X_poly_test and normalize (using mu and sigma)\n",
"X_poly_test = polyFeatures(Xtest, p)\n",
"X_poly_test -= mu\n",
"X_poly_test /= sigma\n",
"X_poly_test = np.concatenate([np.ones((ytest.size, 1)), X_poly_test], axis=1)\n",
"\n",
"# Map X_poly_val and normalize (using mu and sigma)\n",
"X_poly_val = polyFeatures(Xval, p)\n",
"X_poly_val -= mu\n",
"X_poly_val /= sigma\n",
"X_poly_val = np.concatenate([np.ones((yval.size, 1)), X_poly_val], axis=1)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now that we have the ability to map polynomial features, we can train our model via linear regression and plot to see how it fits our data. We will also plot a learning curve for lambda = 0 to see if we still have a bias/variance problem."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Polynomial Regression (lambda = 0.000000)\n",
"\n",
"# Training Examples\tTrain Error\tCross Validation Error\n",
" \t1\t\t0.000000\t160.721900\n",
" \t2\t\t0.000000\t160.121511\n",
" \t3\t\t0.000000\t59.071634\n",
" \t4\t\t0.000000\t77.997728\n",
" \t5\t\t0.000000\t6.448961\n",
" \t6\t\t0.000000\t10.831639\n",
" \t7\t\t0.000000\t27.916727\n",
" \t8\t\t0.000064\t21.128258\n",
" \t9\t\t0.000147\t30.474290\n",
" \t10\t\t0.021425\t50.335502\n",
" \t11\t\t0.032329\t55.153697\n",
" \t12\t\t0.036300\t37.781163\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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aJn25SdLKEFjCcUksKlTp5KWlsbQoUPzlnXs2JHu3bszbdo0jj32WP7617/Srl07AB5++GHatm1L27ZtGTlyJABbt27llFNOoUOHDrRt25YxY8YAMGzYMFq3bk379u0PmGMFYODAgbzxxht599944w0GDhwIwPvvv8+RRx5Jp06d6N279wEJDtz8LQ8++CAAs2fPzhsy/4knnshbZ9myZXTv3j1vUMsvv/wyL7bp06fTsWNHRowYwbRp0zj11FMBWL9+Pf3796d9+/Z069aNH374Ie94F198Mb169aJZs2ZxkYBs6JWgyWgMSz6xibZM+X00DFb+GNl9NmgHJw8v9OG5c+fSpUuXQh+fOXMmc+fOpWnTpsyePZtRo0bx9ddfo6oceeSR9OzZk6VLl9KwYUM++OADwA1hv379esaNG8fChQsRETZu3HjAvs8991w6derEY489RmpqKmPGjOGtt94C3BwrX331FSLCc889x3/+8x8eeuihQuMcPHgwjz32GD179uSmm27KW16vXj0mT55Meno6ixcvZuDAgcyaNYvhw4fz4IMPMmHCBACmTZuWt82dd95Jp06dGD9+PJ9++ikXXHBB3iRkCxcuZOrUqWRnZ9OyZUsuv/xy0tLSCo0r2qyEEjQZmbB7G2zf4HckxkTcEUccQdOmTQGYMWMGZ5xxBlWrVqVatWqceeaZTJ8+nXbt2vHJJ59wyy23MH36dDIyMqhRowbp6elceumljB07lipVqhyw7wYNGtCmTRumTJnCnDlzSEtLy7v2sXz5ck488UTatWvHAw88wLx58wqNcdOmTWzcuJGePXsCcP755+c9tnv3bi677DLatWvHOeecU+CQ+/nNmDEjbx/HHXcc69atY9OmTQCccsopVKpUibp161KvXr0CS06xZCWUoAmfaKtKbX9jMYmtiJJEtLRp04a333670MfDh7AvbBzCww47jNmzZ/Phhx9y6623csIJJ3DHHXcwc+ZMpkyZwhtvvMHjjz/Op58eOOZdbrVX/fr186q7AK666iquv/56Tj/9dKZNm8Zdd91VaIyqihRSOzBixAjq16/P999/z969e0lPTy90P0WdZ+7+K1WqlLcsHobntxJK0FhfFJPAjjvuOHbu3Mmzzz6bt+ybb77hs88+O2DdHj16MH78eLZt28bWrVsZN24c3bt3588//6RKlSoMGjSIG2+8kW+//ZYtW7awadMm+vbty8iRI/OqjPI766yz+PDDDxkzZgwDBgzIW75p0yYaNXLN8l966aUiz6FmzZpkZGQwY8YMAF577bX99nPQQQeRkpLCK6+8kte4oHr16mRnZxe4vx49euTtY9q0adStW5caNWoUGYNfrIQSNDbRlklgIsK4ceO49tprGT58OOnp6TRp0oSRI0fyxx/7DynUuXNnLrroorxWWJdeeimdOnVi4sSJ3HTTTaSkpJCWlsaTTz5JdnY2/fr1Y8eOHagqI0aMKPD4NWvWpFu3bqxatSqvag3cBfBzzjmHRo0a0a1bN3755Zciz2PUqFFcfPHFVKlShRNPPDFv+d///nfOOuss3nrrLY499ti8Elf79u1JTU2lQ4cOXHTRRXTq1Gm/Yw8ePJj27dtTpUqVYhOan2z4+qBRhX/VhyOHwAn/8jsak2Bs+PrgseHrTdnlTbRlJRRjTGxZQgkiSyjGGB9YQgmijMaWUEyZJXI1uNlfrF9LSyhBlJEJ2SshZ5ffkZgEk56ezrp16yypBICqsm7duhI1TY4Ua+UVRBmZgEL2n1Crid/RmASSmZnJ8uXLWbNmjd+hmAhIT08nMzMzZsezhBJE4X1RLKGYUkhLS9uvuawxpWFVXkFkfVGMMT7wJaGIyHUiMk9E5orIaBFJF5GmIvK1iCwWkTEiUtGP2AIhI3eiLZsXxRgTOzFPKCLSCLga6KqqbYEKwADgfmCEqrYANgCXxDq2wEirDFXqWgnFGBNTflV5pQKVRSQVqAKsAI4DckeFewno71NswWB9UYwxMRbzhKKqfwAPAr/hEskmYDawUVVzh8pcDjQqaHsRGSIis0RklrVEKYIlFGNMjPlR5VUL6Ac0BRoCVYGTC1i1wIbwqvqMqnZV1a6hUCh6gSa63M6N1p/AGBMjflR59QZ+UdU1qrobGAv8BajpVYEBZAJ/+hBbcGRkwq4tsOPAmemMMSYa/EgovwHdRKSKuFlijgfmA1OBs711LgTe9SG24PBzXpTfZ8JPH8X+uMYYX/lxDeVr3MX3b4EfvRieAW4BrheRJUAd4PlYxxYofvVF2bYeRg+A96+J7XGNMb7zpae8qt4J3Jlv8VLgCB/CCSa/SiiT74Bt69ztbettGmJjkoj1lA+qqiGoUDG2nRuXfQHfvQIHdXT31y6K3bGNMb6zhBJUKSlQo1HsSig5O2HCtVDzYDjjKbds9YLYHNsYExdscMggi2VflC8ecSWS896Gui0hrQqs+Sk2xzbGxAUroQRZrCbaWrsEPn8Q2pwBLfq40lGoJaxZGP1jG2PihiWUIMvIhOwVsGd39I6hCh9cB6npcNLwfctDWZZQjEkyllCCLCMTdK9LKtHywxj45XPofSdUb7BveailO+5261hpTLKwhBJk0W46vHUdTPwHZB4OXQbv/1iolftv11GMSRqWUIIs2p0bJ98BOzbBaY+46ybhQi3df6v2MiZpWEIJsmhOtPXLdJjzKhx1JdRvc+DjNQ+B1MpWQjEmiVhCCbKKVaFy7ciXUHJ2woTrXNLoeUvB66SkQOgwWGN9UYxJFpZQgi4afVFmjIR1i+GUh6FilcLXC2VZCcWYJGIJJegi3Rdl7WKY/iC0PQta9C563VAWbP4DdmyO3PGNMXHLEkrQRbKEouqqulIrw4n3Fb9+KMv9t1KKMUnBEkrQZWTCzs2uNVZ5fT8alk2HPndB9frFr28tvYxJKpZQgi5SfVG2roOJt0HjI6HzRSXbplYT14PeEooxScESStBFqi/K5P9zJZ1TRx7Y56QwKRWgbgtLKMYkCUsoQZdXQilHX5RfPoc5r8Ffrob6rUu3baiVXUMxJklYQgm6avUhJa3sJZTdO9yF+FpNoMdNpd8+1NIls53ZZTu+MSZhWEIJupQUqNGw7AllxghYtwROeajoPieFyWvpZbM3GhN0llCSQVn7oqxZBDMehrZnw6HF9DkpTL3cQSKtx7wxQWcJJRmUpS9Kbp+TtMpwUgn6nBSmVhOoUMkuzBuTBCyhJIOMTNj8J+zJKfk2c16DX2dAn7uhWr2yHzulAtQ9zC7MG5MELKEkg4xM0D2wZWXJ1t+6FibdDo27QacLyn/8UEtYbSUUY4LOEkoyKG1flEm3w84tcFop+pwUJZQFm35z+zTGBJYllGRQmt7ySz9zQ6wcfc2+C+rlVc9r6bXWWnoZE2SWUJJBSSfayutz0hR63Bi54+c1HbZqL2OCLNXvAEwMVKoO6TWLL6FMfwjW/wznj3OtuyKlVlOoUNESijEBZyWUZFFcX5Q1P7lOjO3OhebHRfbYFVKhTgu7MG9MwFlCSRZF9UXZuxfev9ZNGXzivdE5fqillVCMCThLKMkiI7PwayhzXoPfvoQT7oFqoegcv14r2Pgb7Noanf0bY3xnCSVZZGS6SbbyT8e7ZY1rJnzwX6DjoOgdP9QSUGvpZUyAWUJJFrlNhzf/sf/ySbe5UsOpIyLT56QwNh2wMYFnCSVZFNS58eep8MMYOObafX1FoqV2MzeMvl1HMSawLKEki/wTbe3eDh9c777ou98Q/eNXSIM6h1pLL2MCzJeEIiI1ReRtEVkoIgtE5CgRqS0ik0Vksfe/lh+xBVb1BiAV9pVQpj8E65e6qq5I9jkpirX0MibQ/CqhPAJ8rKpZQAdgATAMmKKqLYAp3n0TKSkVoEYjl1BWL4QZI6H9AGjWK3Yx1GsFG5bBrm2xO6YxJmZinlBEpAbQA3geQFV3qepGoB/wkrfaS0D/WMcWeBmZrunuhGuhUjU48d+xPX5uS691i2N7XGNMTPhRQmkGrAFGich3IvKciFQF6qvqCgDvf4GTcIjIEBGZJSKz1qxZE7uogyAjE377Cn77H/S5B6rWje3xQ7mzN1pLL2OCyI+Ekgp0Bp5U1U7AVkpRvaWqz6hqV1XtGgpFqRNeUGVkAgqHHA2dotjnpDC1m0FKKqy26YCNCSI/EspyYLmqfu3dfxuXYFaJyEEA3v/VPsQWbAe1h4rV4NSRIBL746dWhNrNrYRiTEDFPKGo6krgdxFp6S06HpgPvAdc6C27EHg31rEFXpsz4OalEDrMvxjqZVlLL2MCyq/h668CXhORisBSYDAuub0pIpcAvwHn+BRbsKVW8vf4oSxY8L6beyUt3d9YjDER5UtCUdU5QNcCHjo+1rGYGAu1BN3rWno1aOd3NMaYCLKe8ia2clt6WY95YwLHEoqJrTrNXY99u45iTOBYQjGxlVrJJRVLKMYEjiUUE3s2ppcxgWQJxcReKMsNTJmz0+9IjCnayrkw4Xp4rg9kr/Q7mrjnV7Nhk8xCWV5LryVQv43f0Rizv93bYf678M3zsHwmVKgEKLx/DQx8w59OwQmi2BKKiFQQkQdiEYxJErmzN9oQLCaerF0CE2+Dh1vBuL/B9vVw4r1ww0Loczcs+hi+e9XvKONasSUUVd0jIl1ERFRVYxGUCbg6h4Kk2BAsxn85u+CnD2DWC/DL526suVanQdeLoUn3faWRI/4GCz+Aj2+Fpj2g1iH+xh2nSlrl9R3wroi8hRvMEQBVHRuVqEywpaW7gSLXWAnF+GTjbzD7Jfj2Zdi6GjIOhuPvgI6DoHr9A9dPSYF+T8CTR8O7V8AF77llZj8lTSi1gXXAcWHLFLCEYsomlGUlFBNbe/fA4smuNLJ4kit9tDjRlUYOPd5NQleUWofASffCe1fBzGeg29DYxJ1ASpRQVHVwtAMxSSaUBT995KocUiv6HY0JsuyV8O0r8O1LsOl3qNYAetwEnS+Amo1Lt69O58OCCfDJnS4J1W0RnZgTVInKbCKSKSLjRGS1iKwSkXdEJDPawZkAC2WB7nEtvYyJtL17Yek0GHM+jGgDU//lrt2d+wpcNxeOu630yQRcqeb0RyE1HcYNhT05EX3JT2cAABv0SURBVA89kZW0ymsU8Dr7RgAe5C3rE42gTBIIebMXrFkI9Vv7G4sJjm3rYc5rMGsUrP8ZKteGbpdDl8FuhIZIqN4ATnkI3rkEvnwEut8Qmf0GQEkTSkhVR4Xdf1FEro1GQCZJ1G1hLb1MZKjC71+7ayPzxsOenXDwUdBrGLQ6PTrTJLQ7GxZOgKn3QYsTbORsT0kTyloRGQSM9u4PxF2kN6Zs0ipDrSbW0suUnaprpfX107B6HlSqAV0udKWRWJR6+z4Ey75wVV+XTbVrgZR86JWLgXOBlcAK4GxvmTFlF2plJRRTdj++Be9fDRVS4bRH4foF0PeB2FWhVq3jrqesmgufDY/NMeNcsSUUEakAnKWqp8cgHpNMQi1h8URr6WVKb8dmmHQ7NOwEl04pvslvtLQ82fVdmTECWvaFzILmDUwexZZQVHUP0C8GsZhkE8qCvTluoEhjSuOz+2HLalft5FcyyXXSfVCjkRuuZdc2f2PxWUmrvL4QkcdFpLuIdM79i2pkJvjqeWN62VD2pjRWL4Svn4LO50NmF7+jgfQarhf9uiUw5W6/o/FVSS/K/8X7H/5sKfv3nDemdOq0AMQSiik5VfjoJqhYFY6/0+9o9mnW04339fWTkNXXjfeVhEpyDSUFeFJV34xBPCaZVKzihrOwhGJKat44N4hj3wehal2/o9lf77tgyScw/gq4/AtXckkyJbmGshe4MgaxmGQUauWqMIwpzs4t7kJ8g3Zu/K14U7EKnPE0bF4OE//hdzS+KOk1lMkicqOINBaR2rl/UY3MJIdQS1f3vGe335GYeDf9Qdj8R3xciC9M48Ph6Gvhu1dg0US/o4m50vRDuQL4HJjt/c2KVlAmidRrBXt3w/pf/I7ExLO1i+HLx6HDX+HgI/2Opmi9hkH9tm5U4m3r/Y4mpkqUUFS1aQF/zaIdnEkCeWN6WY95UwhV+OhmN7pCn3/6HU3xUivBGU+5ZPJBco3zVWRCEZGbw26fk++xe6MVlEkidQ9z/63HvCnMwgnw86dw7D+gWj2/oymZBu2g1y0wbyzMfcfvaGKmuBLKgLDbt+Z77KQIx2KSUcWqUNNaeplC7Nrmpt2t1xoOv8zvaErn6OugURdXSsle6Xc0MVFcQpFCbhd035iyCWVZSy9TsBkj3KRYfR90Y3Ylkgqp0P8p2L0d3r/GVd0FXHEJRQu5XdB9Y8om1BLWLbbJisz+1i+FLx6BdudAk6P9jqZsQoe5/imLPobvXvU7mqgrLqF0EJHNIpINtPdu5963CQBMZNRrBXt2wQZr6WXCfDQMKqRBn3v8jqR8jvgbNOnuqu42/uZ3NFFVZEJR1QqqWkNVq6tqqnc7935arII0ARc+e6MxAD997Eai7nkL1DjI72jKJyXFjfWFwvi/u+mJA6qk/VCMiZ66llBMmN074ONb3Pui2+V+RxMZtQ6BE++FZdPhm2f9jiZqLKEY/1WqBhkH24V543zxCGxYBn3/46q8gqLzBW664Ml3wtolfkcTFZZQTHwItbS+KAY2/AozHobW/aFZL7+jiSwRN7NkaiUYPzSQjVAsoZj4UC8L1i6CvXv8jsT4aeI/QFLgxH/7HUl01DgITnkIln8DXz7idzQR51tCEZEKIvKdiEzw7jcVka9FZLGIjBERmxM2mYSyYM9OV9VhktPiT1yv+B43QUam39FET7uzoc0ZMPU+WDnX72giys8SyjVA+ABO9wMjVLUFsAG4xJeojD9CNntjUsvZ6cbrqt0cjrrC72iir+9DULkWjBsKObv8jiZifEkoIpIJnAI8590X3OyPb3urvAT09yM245PcpsOrbZDIpPS/x2H9z+5CfGolv6OJvqp14PRHYdWP8Nn9fkcTMX6VUEYCNwO5DbLrABtVNfcq1XKgUUEbisgQEZklIrPWrFkT/UhNbFSqDjUy7cJ8Mtr4O3z+IGSdCof29jua2Gl5MnQc5BohLA/GbCAxTygiciqwWlVnhy8uYNUCh3ZR1WdUtauqdg2FQlGJ0fikXpZVeSWjSbeD7nX9NJLNSfdBjUYw7m9uIMwE50cJ5WjgdBFZBryBq+oaCdQUkdzR3zKBP32IzfgpZC29ks7PU2H+eOh+g+v8l2zSa7he9OuWwJS7/Y6m3GKeUFT1VlXNVNUmuOHxP1XV84CpwNneahcC78Y6NuOzUEvI2QEbf/U7EhMLObvchfhaTeAvV/sdjX+a9XTjfX39JPzyud/RlEs89UO5BbheRJbgrqk873M8JtZCrdx/u46SHL5+ypVIT7of0tL9jsZfve9yLdzGX+GGnklQvk4woKrTgGne7aXAEX7GY3wW8mZvXL3AXbA0wbV5hWvddNhJ0NLm6qNiFTjzGdi6JqGTa4LNWGMCLT0Dqje0EkoymHQ77NntLkobJ7Or3xGUWzxVeRnjtfSyviiBtmwGzH0bjr4GajfzOxoTQZZQTHwJZcGaRYGeMyKp7dkNH97kRpc+5jq/ozERZgnFxJdQFuRsh03Bntkuac18FlbPd1VdFav4HY2JMEsoJr7kjullc6MET/YqmHYfND8esk7xOxoTBZZQTHyx6YCD65M7Yfd2OPk/bm4QEziWUEx8qVwTqh9kLb2C5rev4PvR8JeroO6hfkdjosQSiok/oZbW0itI9u6BD250Y1b1uNHvaEwUWUIx8cdaegXLrBfcMO0n/hsqVvU7GhNFllBM/Allwe6tsOl3vyMx5bV1LXx6DzTt4eaJN4FmCcXEn7zZG+06SsL75C7YtRX6PmgX4pOAJRQTf6ylVzAsnwXfvQLdLt/3mppAs4Ri4k+V2lCtviWURLZ3D3xwA1RrAD1v8TsaEyM2OKSJT6GWllAS2bcvw4o5cOZzbnpnkxSshGLiU6iVu4aiBc4EbeLZD2/Bx7fCIUdDu7OLX98EhiUUE59CLWHXFti03O9ITEnt2Q0fDYOxl0LDTnDOi3YhPslYlZeJT/XCZm+s2djfWEzxtqyGty6CX7+AIy+HE+6BCml+R2VizBKKiU95TYcXQIve/sZiivb7N/Dm+bB9I5z5LLQ/1++IjE8soZj4VKU2VA3Zhfl4pgqzR8GHN0NGI7h0MjRo53dUxkd2DcXEr1BW8nRuXLvYXche97PfkZTM7h3w3pUw4Tpo1guGTLNkYiyhmDiWm1CC3tIrZye8eSF89V944kiY9H+wY5PfURVu4+/wwonw3avQ42b46xioXMvvqEwcsIRi4leoJezcDJv/9DuS6Jr6b1g9D/o94a4/fPkoPNYFZr/oOgjGk6XT4JmesH4pDBgNx90GKRX8jsrECUsoJn7ltfQK8FD2y76ALx6FLhdBp0HQ/79w2VSo3Rzev8Z9eS+b4XeUrpT4xSPwyhnu2tZlUyGrr99RmThjCcXEr6APErljM4wfCrWawAn/3re8UWe4+GM4+wXXcurFU2DMIFj/iz9x7syGty6EyXdAq9Ph0ik2SZYpkLXyMvGral2oUje4Lb0+vtV13Lx4IlSqtv9jItD2LGjZF758DGaMgEUT4agroPsNsRvOZO1il8zWLoI+97gZF62zoimElVBMfAtlweoAJpQFE2DOq3DM9dD4iMLXS6sMPW+Gq2ZDmzNdYnmsi7sgHu0JyBZ+AM8eB1vXwPnj4eirLZmYIllCMfEt1DJ4Lb22rIb3r4YG7Us+Em+NhnDm03Dpp1DzEHj3Cni2F/z6ZeTj27sHPv0XvPFXqNMchnwGzXpG/jgmcCyhmPhWrxXs3ATZK/2OJDJU4b2rYecW16s8tWLpts/sApdMcqP4bl0Lo052Q55s/C0y8W1bD6+fC58/4BoJDP7Yhr4xJWYJxcS3vMm2AtLS67tXYNFH0PsuqJdVtn2IQPtz4MpZ0OtW+OljePxwV6rYuaXssa38EZ7pBUs/g1NHwumPQ1p62fdnko4lFBPfgtTSa/0v7kJ80x5w5NDy769iFeg1DK6aBa1Oc6WKx7vCnNGlv77y/Rh4ro8bMXjwR9B1sF0vMaVmCcXEt6ohqFwbVid4CWXvHhg3FKQC9H8SUiL40cvIhLOeg0smu2st44fCc8fDb18Xv+2e3fDRLTBuiGuu/LfPoPHhkYvNJBVLKCa+iQRjTK8vHoHfv4K+D7gEEA2Nj4BLPoEznobsFfDCCfD2JYXPKZO9Cl46Hb5+CrpdARe8C9XqRSc2kxQsoZj4Vy/L9UVJ1JZeK36AqfdC6/7RH9o9JQU6DHDXV3rcDAsnwGNdYep9sGvbvvV+nwlP94A/v4OznoeT7rX5S0y5WUIx8S+UBTs2wpZVfkdSert3wNghUKUOnDoidtclKlVz42xd+Q20PBk+G+6ur/zwJnzzHIzq6y64X/qJTdNrIibmCUVEGovIVBFZICLzROQab3ltEZksIou9/zZ8qXHyWnolYAfHT+9xLdT6PeHmeIm1mgfDOaNcb/yqIRh7GXxwAzQ/1htyvm3sYzKB5UcJJQe4QVVbAd2AK0SkNTAMmKKqLYAp3n1jIBQ2HXAi+WU6/O8J6HqJ/7NOHtzNDeh4xtNw0v0w0IacN5EX87G8VHUFsMK7nS0iC4BGQD+gl7faS8A0oITdiE2gVasH6TUTq6XXjk0w/nKo3czNrx4Pcq+vGBMlvl5DEZEmQCfga6C+l2xyk06BzU1EZIiIzBKRWWvWrIlVqMZPidjS66Nb3DwuZz4DFav6HY0xMeFbQhGRasA7wLWqurmk26nqM6raVVW7hkKh6AVo4ku9LHctIhFaes1/F74fDT1uhMyufkdjTMz4klBEJA2XTF5T1bHe4lUicpD3+EHAaj9iM3EqlAXbN7iRb+NZ9kp4/1po2Al63OR3NMbElB+tvAR4Hligqg+HPfQecKF3+0Lg3VjHZuJY3hAscdzSSxXeuwp2b4MznrF+HSbp+FFCORo4HzhOROZ4f32B4UAfEVkM9PHuG+PkJpR4nhtl9ihYPAn63A2hw/yOxpiY86OV1wygsN5dx8cyFpNAqjeAShnxW0JZ9zNMvA2a9YLDL/M7GmN8YT3lTWIQ8S7Mx2FLrz05buDHCmnQ77+RHfjRmARi73yTOEIt43NelC9GwPKZcMrDkNHI72iM8Y0lFJM4QlmwbZ2bqTBe/DkHpg2HtmfZmFgm6VlCMYkj78J8nJRSdm93Az9WDUHfB/2OxhjfWUIxiSPemg5PuRvW/gT9/+vPwI/GxBlLKCZx1GgIlWrEx4X5pdPgq//CEUOg+XF+R2NMXLCEYhKHiHdh3ucSyvaNMP7vUKcF9P6nv7EYE0csoZjEEg8J5cOb3BArZz4NFav4G4sxccQSikksoVZuPK+t6/w5/tyx8OOb0PNmaNTFnxiMiVOWUExi8fPC/OYVMOE6l0i63xD74xsT5yyhmMRSz6eEogrvXgE5O23gR2MKEfOxvIwplxqNoGK12CeUb56Dn6e4/iZ1D43tsY1JEFZCMYnFj5Zea5fApP+D5sfD4ZfG7rjGJBhLKCbxhFrFri/K2sUw9lJIrQT9nnAJzRhTIKvyMokn1BLmvArb1kenh/q29TBvLMwZDX/MAqkA57wINQ6K/LGMCRBLKCbx5LX0+gkOOSoy+9yzG5Z8AnNeh0Ufw55dUK819LkH2p/r5mMxxhTJEopJPOEtvcqTUFRh5Q+uJPLjW7BtLVSpC10vgY4DoUF7q+IyphQsoZjEUyMT0qqW/cJ89irXOXHOaFg9DypUhMNOgo5/hUN7W5NgY8rIEopJPCkppW/ptXsH/PSBSyI/TwHdC426wikPQZszbbRgYyLAEopJTKEs+PnTotdRhd+/dtdF5o2HnZtcP5ajr4UOAyF0WGxiNSZJWEIxiSnUEr5/HbZvgMq19n9sw6/wwxj4fjSsXwppVaDV6e66SJPukFLBn5iNCThLKCYx1Wvl/q9ZBAcfCTuzYf67rkrr1xnusSbdocdN0Oo0qFTdv1iNSRKWUExiCrV0/38Y44ZFWfA+5GyH2s3h2Nuhw/+Dmgf7G6MxScYSiklMGQe7ll6znof0DOgwwLXSyjzcmvoa4xNLKCYxpaTAWc/Bnp1w2MmQlu53RMYkPUsoJnFl9fU7AmNMGBsc0hhjTERYQjHGGBMRllCMMcZEhCUUY4wxEWEJxRhjTERYQjHGGBMRllCMMcZEhCUUY4wxEWEJxRhjTETEVUIRkZNE5CcRWSIiw/yOxxhjTMnFzdArIlIBeALoAywHvhGR91R1vr+RGWMShaoWsCzf/ZJsU8w+ShTLAXspmUqpiTtfT9wkFOAIYImqLgUQkTeAfoCvCeXo4Z+ycdsuP0MwJuGEf5XmfhnnfsHuu7//yvkfD18n90t/3/1IRhs/MmtVZsYtx/kdRpnFU0JpBPwedn85cGT+lURkCDDEu7tTRObGILZYqQus9TuICAnSuUCwzidI5wIBOp9foa4Mi8m5HBKNncZTQiloEosDfoeo6jPAMwAiMktVu0Y7sFgJ0vkE6VwgWOcTpHOBYJ1Pop9LPF2UXw40DrufCfzpUyzGGGNKKZ4SyjdACxFpKiIVgQHAez7HZIwxpoTipspLVXNE5EpgIlABeEFV5xWz2TPRjyymgnQ+QToXCNb5BOlcIFjnk9DnIgU1mTPGGGNKK56qvIwxxiQwSyjGGGMiImETSlCGaRGRxiIyVUQWiMg8EbnG75jKS0QqiMh3IjLB71jKS0RqisjbIrLQe42O8jum8hCR67z32VwRGS0i6X7HVFIi8oKIrA7veyYitUVksogs9v7X8jPG0ijkfB7w3ms/iMg4EanpZ4yllZAJJWyYlpOB1sBAEWntb1RllgPcoKqtgG7AFQl8LrmuARb4HUSEPAJ8rKpZQAcS+LxEpBFwNdBVVdviGr8M8DeqUnkROCnfsmHAFFVtAUzx7ieKFznwfCYDbVW1PbAIuDXWQZVHQiYUwoZpUdVdQO4wLQlHVVeo6rfe7WzcF1Yjf6MqOxHJBE4BnvM7lvISkRpAD+B5AFXdpaob/Y2q3FKByiKSClQhgfp6qernwPp8i/sBL3m3XwL6xzSocijofFR1kqrmeHe/wvXHSxiJmlAKGqYlYb+Ec4lIE6AT8LW/kZTLSOBmYK/fgURAM2ANMMqrwntORKr6HVRZqeofwIPAb8AKYJOqTvI3qnKrr6orwP04A+r5HE8kXQx85HcQpZGoCaVEw7QkEhGpBrwDXKuqm/2OpyxE5FRgtarO9juWCEkFOgNPqmonYCuJVaWyH+/6Qj+gKdAQqCoig/yNyhRERG7DVYe/5ncspZGoCSVQw7SISBoumbymqmP9jqccjgZOF5FluGrI40TkVX9DKpflwHJVzS0xvo1LMImqN/CLqq5R1d3AWOAvPsdUXqtE5CAA7/9qn+MpNxG5EDgVOE8TrKNgoiaUwAzTIiKCq6NfoKoP+x1PeajqraqaqapNcK/Jp6qasL+AVXUl8LuItPQWHY/P0ymU029ANxGp4r3vjieBGxl43gMu9G5fCLzrYyzlJiInAbcAp6vqNr/jKa2ETCjeRavcYVoWAG+WYJiWeHU0cD7u1/wc76+v30GZPFcBr4nID0BH4F6f4ykzr6T1NvAt8CPu858wQ32IyGjgf0BLEVkuIpcAw4E+IrIYNznfcD9jLI1CzudxoDow2fsueMrXIEvJhl4xxhgTEQlZQjHGGBN/LKEYY4yJCEsoxhhjIsISijHGmIiwhGKMMSYiLKGYMhERFZGHwu7fKCJ3RWjfL4rI2ZHYVzHHOccbQXhqvuVNROSvZdznlyVY57kADAC6HxHZ4ncMxn+WUExZ7QTOFJG6fgcSzhuJuqQuAf6uqsfmW94EKDCheIMqFkpVi+15rqqXqmoid5A0pkCWUExZ5eA6xV2X/4H8JYzcX68i0ktEPhORN0VkkYgMF5HzRGSmiPwoIs3DdtNbRKZ7653qbV/Bmy/iG2++iL+F7XeqiLyO67CXP56B3v7nisj93rI7gGOAp0TkgXybDAe6ex3LrhORi0TkLRF5H5gkItVEZIqIfOvtt1/YscLPdZrsm0vlNa93Ot7yrrnri8i/ReR7EflKROp7y5t7978RkbsLKwGIyCDv+ZsjIk97z9Eh4uYHqSsiKd7zeIK3/ngRmS1uTpQh4XGLyP3eY5+IyBFenEtF5HRvnYtE5F0R+VjcXER3FhLTTWGv0T+9ZVVF5APvPOeKyP8raFuT4FTV/uyv1H/AFqAGsAzIAG4E7vIeexE4O3xd738vYCNwEFAJ+AP4p/fYNcDIsO0/xv3gaYEbUysdGALc7q1TCZiFG+iwF27gxqYFxNkQN+RICDfY46dAf++xabi5QfJv0wuYEHb/Ii+G2t79VKCGd7susIR9nYTDz3UTbpy5FFyP6GPyHxc3qOlp3u3/hJ3fBGCgd3to7n7zxdkKeB9I8+7/F7jAu30prlf8TcDTYdvknkNlYC5QJyyOk73b44BJQBpuDpg5Yc/DCqBO2PZd8533CbgfGuKd9wTcFABnAc+GxZHh93vY/iL/ZyUUU2bqRkV+GTdpU0l9o24OmJ3Az7gvLnAliyZh672pqntVdTGwFMjCfVldICJzcEP818ElHICZqvpLAcc7HJimbkDE3NFbe5Qi3lyTVTV37goB7vWGY/kEN3VC/QK2mamqy1V1LzAn3/nl2oX70gWYHbbOUcBb3u3XC4npeKAL8I33nByPG3IfVX0ON4THUFyyz3W1iHyPm2ujMfuev124JA7utfhM3QCS+V+Xyaq6TlW34waXPCZfTCd4f9/hhnjJ8o7xI67Ueb+IdFfVTYWck0lgRdYHG1MCI3FfHKPCluXgVad61TwVwx7bGXZ7b9j9vez/fsw/JpDivsivUtWJ4Q+ISC9cCaUgBU11UBbh+z8PV+Lpoqq7xY2uXNBUuuHnuoeCP2+7VVWLWacwArykqgfM6iciVdg3OVM1INt7nnoDR6nqNhGZFhZ3eBx5r4uq7s133aig1yV/TPep6tMFxNQF6AvcJyKTVPXukp2mSRRWQjHl4v1qfxN3gTvXMtwvZ3Dzb6SVYdfnePX/zXG/un/CDQZ6ubjh/hGRw6T4Ca++Bnp61xMqAAOBz4rZJhv3674wGbh5X3aLyLHAISU4n9L6CldNBIVP0zsFOFtE6kHe/Oq5sdyPK43dATwbFvcGL5lk4aacLq0+3nEq42ZH/CLf4xOBi8XN74OINBKReiLSENimqq/iJvlK5GkATCGshGIi4SHc6M+5ngXeFZGZuC+9wkoPRfkJ98VfHxiqqjtE5Dlc9cu3XslnDcVM+aqqK0TkVmAq7tfzh6pa3BDnPwA5XtXQi8CGfI+/BrwvIrNwVVkLS3NiJXQt8KqI3AB8gLsesx9VnS8it+MaCqQAu4ErxM38eThwtKruEZGzRGQwrupsqFdV9xMuaZXWDOAV4FDgdVWdlS+mSSLSCvif1wZhCzDIW/8BEdnrxXl5GY5t4pyNNmxMHPKqrLarqorIANwF+n7FbRflmC7CXYS/srh1TXKyEoox8akL8LhXEtuIm1/cmLhmJRRjjDERYRfljTHGRIQlFGOMMRFhCcUYY0xEWEIxxhgTEZZQjDHGRMT/B4oPf/P1CoQTAAAAAElFTkSuQmCC\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"lambda_ = 0\n",
"theta = trainLinearReg(linearRegCostFunction, X_poly, y,\n",
" lambda_=lambda_, maxiter=55)\n",
"\n",
"# Plot training data and fit\n",
"plt.plot(X, y, 'ro', ms=10, mew=1.5, mec='k')\n",
"\n",
"plotFit(polyFeatures, np.min(X), np.max(X), mu, sigma, theta, p)\n",
"\n",
"plt.xlabel('Change in water level (x)')\n",
"plt.ylabel('Water flowing out of the dam (y)')\n",
"plt.title('Polynomial Regression Fit (lambda = %f)' % lambda_)\n",
"plt.ylim([-20, 50])\n",
"\n",
"plt.figure()\n",
"error_train, error_val = learningCurve(X_poly, y, X_poly_val, yval, lambda_)\n",
"plt.plot(np.arange(1, 1+m), error_train, np.arange(1, 1+m), error_val)\n",
"\n",
"plt.title('Polynomial Regression Learning Curve (lambda = %f)' % lambda_)\n",
"plt.xlabel('Number of training examples')\n",
"plt.ylabel('Error')\n",
"plt.axis([0, 13, 0, 100])\n",
"plt.legend(['Train', 'Cross Validation'])\n",
"\n",
"print('Polynomial Regression (lambda = %f)\\n' % lambda_)\n",
"print('# Training Examples\\tTrain Error\\tCross Validation Error')\n",
"for i in range(m):\n",
" print(' \\t%d\\t\\t%f\\t%f' % (i+1, error_train[i], error_val[i]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Looking at the resulting figures, we can see that our curve fits the data extremely well. In fact, it fits it too well. Along the samples it follows perfectly, however it fails to follow the trend along the extremes. We can also see this in the learning curve, as while the training error is extremely low, the cross validation error (the error we would realistically expect to see) is still high. This imply we now have an issue of high-variance, or overfitting. To address this, we can add a regularization term. In order to choose an effective lambda, we automate the process by testing a sequence of lambdas and choosing the one with the least error."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"def validationCurve(X, y, Xval, yval):\n",
" \"\"\"\n",
" Generate the train and validation errors needed to plot a validation\n",
" curve that we can use to select lambda_.\n",
" \n",
" Parameters\n",
" ----------\n",
" X : array_like\n",
" The training dataset. Matrix with shape (m x n) where m is the \n",
" total number of training examples, and n is the number of features \n",
" including any polynomial features.\n",
" \n",
" y : array_like\n",
" The functions values at each training datapoint. A vector of\n",
" shape (m, ).\n",
" \n",
" Xval : array_like\n",
" The validation dataset. Matrix with shape (m_val x n) where m is the \n",
" total number of validation examples, and n is the number of features \n",
" including any polynomial features.\n",
" \n",
" yval : array_like\n",
" The functions values at each validation datapoint. A vector of\n",
" shape (m_val, ).\n",
" \n",
" Returns\n",
" -------\n",
" lambda_vec : list\n",
" The values of the regularization parameters which were used in \n",
" cross validation.\n",
" \n",
" error_train : list\n",
" The training error computed at each value for the regularization\n",
" parameter.\n",
" \n",
" error_val : list\n",
" The validation error computed at each value for the regularization\n",
" parameter.\n",
" \"\"\"\n",
" # Selected values of lambda\n",
" lambda_vec = [0, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3, 10]\n",
"\n",
" error_train = np.zeros(len(lambda_vec))\n",
" error_val = np.zeros(len(lambda_vec))\n",
"\n",
" for i in range(len(lambda_vec)):\n",
" lambda_ = lambda_vec[i]\n",
" Theta = trainLinearReg(linearRegCostFunction, X, y, lambda_, maxiter=200)\n",
" error_train[i] = linearRegCostFunction(X,y,Theta,0)[0]\n",
" error_val[i] = linearRegCostFunction(Xval,yval,Theta,0)[0]\n",
"\n",
" return lambda_vec, error_train, error_val"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now plot a cross validation curve of error vs lambda which allows us to select which lambda paremeter to use."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'pyplot' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mlambda_vec\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0merror_train\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0merror_val\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mvalidationCurve\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mX_poly\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mX_poly_val\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0myval\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mpyplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlambda_vec\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0merror_train\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'-o'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlambda_vec\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0merror_val\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'-o'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlw\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[0mpyplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlegend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'Train'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'Cross Validation'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mpyplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mxlabel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'lambda'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mNameError\u001b[0m: name 'pyplot' is not defined"
]
}
],
"source": [
"lambda_vec, error_train, error_val = validationCurve(X_poly, y, X_poly_val, yval)\n",
"\n",
"pyplot.plot(lambda_vec, error_train, '-o', lambda_vec, error_val, '-o', lw=2)\n",
"pyplot.legend(['Train', 'Cross Validation'])\n",
"pyplot.xlabel('lambda')\n",
"pyplot.ylabel('Error')\n",
"\n",
"print('lambda\\t\\tTrain Error\\tValidation Error')\n",
"for i in range(len(lambda_vec)):\n",
" print(' %f\\t%f\\t%f' % (lambda_vec[i], error_train[i], error_val[i]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With this, we can see the optimal lambda would be around 3"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(-20, 50)"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"lambda_ = 3\n",
"theta = trainLinearReg(linearRegCostFunction, X_poly, y,\n",
" lambda_=lambda_, maxiter=55)\n",
"\n",
"# Plot training data and fit\n",
"plt.plot(X, y, 'ro', ms=10, mew=1.5, mec='k')\n",
"\n",
"plotFit(polyFeatures, np.min(X), np.max(X), mu, sigma, theta, p)\n",
"\n",
"plt.xlabel('Change in water level (x)')\n",
"plt.ylabel('Water flowing out of the dam (y)')\n",
"plt.title('Polynomial Regression Fit (lambda = %f)' % lambda_)\n",
"plt.ylim([-20, 50])\n"
]
},
{
"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.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}