Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save DiegoHernanSalazar/614bc5986b195d553602eed1da71be5a to your computer and use it in GitHub Desktop.
Save DiegoHernanSalazar/614bc5986b195d553602eed1da71be5a to your computer and use it in GitHub Desktop.
Stanford Online/ DeepLearning.AI. Supervised Machine Learaning: Regression and Classification, Simple Linear Regression.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Model Representation\n",
"\n",
"<figure>\n",
" <img src=\"./images/C1_W1_L3_S1_Lecture_b.png\" style=\"width:600px;height:200px;\">\n",
"</figure>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goals\n",
"In this lab you will:\n",
"- Learn to implement the model $f_{w,b}$ for linear regression with one variable"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Notation\n",
"Here is a summary of some of the notation you will encounter. \n",
"\n",
"|General <img width=70/> <br /> Notation <img width=70/> | Description<img width=350/>| Python (if applicable) |\n",
"|: ------------|: ------------------------------------------------------------||\n",
"| $a$ | scalar, non bold ||\n",
"| $\\mathbf{a}$ | vector, bold ||\n",
"| **Regression** | | | |\n",
"| $\\mathbf{x}$ | Training Example feature values (in this lab - Size (1000 sqft)) | `x_train` | \n",
"| $\\mathbf{y}$ | Training Example targets (in this lab Price (1000s of dollars)) | `y_train` \n",
"| $x^{(i)}$, $y^{(i)}$ | $i_{th}$Training Example | `x_i`, `y_i`|\n",
"| m | Number of training examples | `m`|\n",
"| $w$ | parameter: weight | `w` |\n",
"| $b$ | parameter: bias | `b` | \n",
"| $f_{w,b}(x^{(i)})$ | The result of the model evaluation at $x^{(i)}$ parameterized by $w,b$: $f_{w,b}(x^{(i)}) = wx^{(i)}+b$ | `f_wb` | \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tools\n",
"In this lab you will make use of: \n",
"- NumPy, a popular library for scientific computing\n",
"- Matplotlib, a popular library for plotting data"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np # Get numpy library as 'np' constructor\n",
"import matplotlib.pyplot as plt # Get matplotlib, pyplot library as 'plt' constructor\n",
"plt.style.use('./deeplearning.mplstyle') # Use or import available style sheets, using its 'name', \n",
" # on a common set of example plots: scatter plot, image, \n",
" # bar graph, patches, line plot and histogram."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Problem Statement\n",
"<img align=\"left\" src=\"./images/C1_W1_L3_S1_trainingdata.png\" style=\" width:380px; padding: 10px; \" /> \n",
"\n",
"As in the lecture, you will use the motivating example of housing price prediction. \n",
"This lab will use a simple data set with only two data points - a house with 1000 square feet(sqft) sold for \\\\$300,000 and a house with 2000 square feet sold for \\\\$500,000. These two points will constitute our *data or training set*. In this lab, the units of size are 1000 sqft and the units of price are 1000s of dollars.\n",
"\n",
"| Size (1000 sqft) | Price (1000s of dollars) |\n",
"| -------------------| ------------------------ |\n",
"| 1.0 | 300 |\n",
"| 2.0 | 500 |\n",
"\n",
"You would like to fit a linear regression model (shown above as the blue straight line) through these two points, so you can then predict price for other houses - say, a house with 1200 sqft.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Please run the following code cell to create your `x_train` and `y_train` variables. The data is stored in one-dimensional NumPy arrays."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x_train = [1. 2.]\n",
"y_train = [300. 500.]\n"
]
}
],
"source": [
"# x_train is the input variable (size in 1000 square feet)\n",
"# y_train is the target (price in 1000s of dollars)\n",
"x_train = np.array([1.0, 2.0])\n",
"y_train = np.array([300.0, 500.0])\n",
"print(f\"x_train = {x_train}\")\n",
"print(f\"y_train = {y_train}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
">**Note**: The course will frequently utilize the python 'f-string' output formatting described [here](https://docs.python.org/3/tutorial/inputoutput.html) when printing. The content between the curly braces is evaluated when producing the output."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Number of training examples `m`\n",
"You will use `m` to denote the number of training examples. Numpy arrays have a `.shape` parameter. `x_train.shape` returns a python tuple with an entry for each dimension. `x_train.shape[0]` is the length of the array at the first tuple position and also the total number of examples, as shown below."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x_train.shape: (2,)\n",
"Total number of training examples is: 2\n"
]
}
],
"source": [
"# m contains the total number of training examples\n",
"print(f\"x_train.shape: {x_train.shape}\")\n",
"\n",
"m = x_train.shape[0] # Pick the first tuple position, to extract the total number of training examples\n",
"print(f\"Total number of training examples is: {m}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One can also use the Python `len()` function as shown below."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Number of training examples is: 2\n"
]
}
],
"source": [
"# m is the number of training examples\n",
"m = len(x_train)\n",
"print(f\"Number of training examples is: {m}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Training example `x_i, y_i`\n",
"\n",
"You will use (x$^{(i)}$, y$^{(i)}$) to denote the $i^{th}$ training example. Since Python is zero indexed, (x$^{(0)}$, y$^{(0)}$) is (1.0, 300.0) and (x$^{(1)}$, y$^{(1)}$) is (2.0, 500.0). \n",
"\n",
"To access a value in a Numpy array, one indexes the array with the desired offset. For example the syntax to access location zero of `x_train` is `x_train[0]`.\n",
"Run the next code block below to get the $i^{th}$ training example."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(x^(0), y^(0)) = (1.0, 300.0)\n",
"(x^(1), y^(1)) = (2.0, 500.0)\n"
]
}
],
"source": [
"index = [0,1] # Change this to 1 to see (x^1, y^1)\n",
"\n",
"for i in index: # Iterate through index=[0,1] list of indexes, one at a time\n",
" x_i = x_train[i] # Select the ith (i=0, i=1) element of ‘x_train’ numpy vector/array\n",
" y_i = y_train[i] # Select the ith (i=0, i=1) element of ‘y_train’ numpy vector/array \n",
" print(f\"(x^({i}), y^({i})) = ({x_i}, {y_i})\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Plotting the data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can plot these two points using the `scatter()` function in the `matplotlib` library, as shown in the cell below. \n",
"- The function arguments `marker` and `c` show the points as red crosses (the default is blue dots).\n",
"\n",
"You can use other functions in the `matplotlib` library to set the title and labels to display"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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nDixkSutPwsXLjRat25t9O/f3+jfv7+xfv16U/NLN3CJiDgZpxjjFxGR3yj4RUScjIJfRMTJKPhFRJyMgl9ExMko+OWyMWHCBEJDQwkLCyMqKopTp06Rn5/PPffcU+dtT5o0iVWrVgHw4osvcu2111a5nvrIkSPExsYSFBTEmDFjKCsrA+DMmTMMGzaMzp07k5iYyKlTpwAoLy/nL3/5C0FBQURFRZGfn1/nOm+//XZ69OjBggULePnll+3tu3fvJiUlpc7bF+eg4JfLwvr161m/fj1bt27l22+/5Z133sHDw4OAgADeeeedOm373LlzrFixgqFDhwIwePBgNmzYUOVzL774IsnJyezevRsPDw+WLl0KwMyZMwkNDWXXrl3069eP1157DYCMjAxOnz7N7t27eeCBB5g0aVKd6iwoKGDPnj1s3bqV5OTkSsEfFBTEsWPHOHjwYJ32Ic5BwS+XhcOHD+Pv72+fhycoKAhPT09++OEHIiMjAbj55puJiIggIiKCpk2bsnXrVkpKSkhOTqZPnz707duXr7/+usq2MzMz6devn/39DTfcQEBAQJXPffzxx/bpL0aPHm2/K3rFihXcfffd1bbfeeedrF69uso2s7KyCAsLIyIigptuugmA06dPM3LkSEJDQxk3bpz9L4+kpCR27txJREQEd955J4WFhURERNin8U1MTOS9996r7T+tOKN6uQ1MxGQnT540unbtaoSHhxv/9V//ZVgsFsMwDGPfvn1G3759K312+fLlxqBBg4yysjLjiSeeMJYtW2YYhmHs2bPnglP5Pvvss8bs2bOrtF9zzTWV3gcEBNhff/fdd8agQYMMwzCMbt26GcePHzcMwzB+/vlno1OnToZhGMbNN99sbN682b5OYGCgUV5eXmmbSUlJxhdffGEYhmGcOHHCMIyK6ZYff/xxwzAMIyMjw/j1v+nv+/r7+nJzc40777yzSj9Efk9H/HJZ8Pb2ZsuWLbz00ktYrVb69evHt99+W+Vz+/fv5+mnn2bBggW4urry+eef8+yzzxIREcFtt912wYnMCgoKaN26db3UWdspsKOionjqqad4/fXXsVqtQMWw1q9TSyclJXHVVVc5tC1/f38KCgpqV7A4JaeYpE2uDE2aNCExMZHExETKy8tZvXo1t99+u325zWZj1KhRTJ8+nWuuuQaoeCLXypUrLzh086umTZvaQ7c6Xl5elJSU0KJFCw4dOkTbtm0BCAgI4NChQ/j6+vLjjz9WaY+IiODs2bM0adKkyhfDM888Q2JiIitWrKBPnz588803GJc4i4rVarXP6S5SHR3xy2UhLy+Pffv2ARUzGebl5dG+fftKn3niiSe4+eabGTBggL0tPj7efrIVKmYt/b0uXbqwd+/eGmtITExk4cKFACxcuJBbbrkFqDi3MH/+/Grb3333XRISEqpsc+/evURERPCPf/yDDh06cPDgQW666SaWLFkCVJwnuNjUwy4uLpSXl9vf7969+4qejVTqj4JfLgunTp1i1KhRhIaGEh4eTkhICHfccUelz0ydOpV3333XfoI3Ly+PCRMmcOjQIcLDw+nWrRsLFiyosu0hQ4awbt06+/v//u//pl27dhw9epR27drx5ptvAvD3v/+d+fPnExQUhNVqtf+1kZaWhsViISgoiPXr1zNu3DgAhg8fTrNmzejUqRNvvPEGzz77bJV9p6en2/sUGhpKjx49GDduHLt376Znz56sXbvW/tfL740ePZru3bvbT+5mZ2czZMiQS/jXFWej2TlFqBhL/7//+z+uvvrqxi6lijZt2tQ4dl9aWsqAAQNYs2aN0zyBTC6dgl+EiiEgm81G7969G7uUKhwJ/v3797Nnzx4GDhzYQFXJ5UzBLyLiZDTGLyLiZBT8IiJORsEvIuJkFPwiIk5GwS8i4mQU/CIiTub/AdtOrR2H7MLzAAAAAElFTkSuQmCC\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot the data points as scatter plot, with two samples (x^(0), y^(0)) = (1.0, 300.0) \n",
"# (x^(1), y^(1)) = (2.0, 500.0)\n",
"plt.scatter(x_train, y_train, marker='x', c='r')\n",
"\n",
"# Set the title of scatter plot\n",
"plt.title(\"Housing Prices\")\n",
"\n",
"# Set the y-axis label\n",
"plt.ylabel('Price (in 1000s of dollars)')\n",
"\n",
"# Set the x-axis label\n",
"plt.xlabel('Size (1000 sqft)')\n",
"\n",
"plt.show() # Display image"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Model function\n",
"\n",
"<img align=\"left\" src=\"./images/C1_W1_L3_S1_model.png\" style=\" width:380px; padding: 10px; \" > As described in lecture, the model function for linear regression (which is a function that maps from `x` to `y`) is represented as \n",
"\n",
"$$ f_{w,b}(x^{(i)}) = wx^{(i)} + b \\tag{1}$$\n",
"\n",
"The formula above is how you can represent straight lines - different values of $w$ and $b$ give you different straight lines on the plot. <br/> <br/> <br/> <br/> <br/> \n",
"\n",
"Let's try to get a better intuition for this through the code blocks below. Let's start with $w = 100$ and $b = 100$. \n",
"\n",
"**Note: You can come back to this cell to adjust the model's w and b parameters**"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"w: 200\n",
"b: 100\n"
]
}
],
"source": [
"w = 200 # Weigh/slope value \n",
"b = 100 # intercept value\n",
"print(f\"w: {w}\")\n",
"print(f\"b: {b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, let's compute the value of $f_{w,b}(x^{(i)})$ for your two data points. You can explicitly write this out for each data point as - \n",
"\n",
"for $x^{(0)}$, `f_wb = w * x[0] + b`\n",
"\n",
"for $x^{(1)}$, `f_wb = w * x[1] + b`\n",
"\n",
"For a large number of data points, this can get unwieldy and repetitive. So instead, you can calculate the function output in a `for` loop as shown in the `compute_model_output` function below.\n",
"> **Note**: The argument description `(ndarray (m,))` describes a Numpy n-dimensional array of shape (m,). `(scalar)` describes an argument without dimensions, just a magnitude. \n",
"> **Note**: `np.zero(n)` will return a one-dimensional numpy array with $n$ entries, all set as zero (0) value.\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def compute_model_output(x, w, b): # inputs: x[1 x m], w (weigh/slope), b(intercept)\n",
"\n",
" \"\"\" \n",
" Computes the prediction of a linear model \n",
"\n",
" Args: \n",
" x (ndarray (m,)): Data, m examples -> [1 x m] size \n",
" w,b (scalar) : model parameters \n",
" \n",
" Returns \n",
" f_wb (ndarray (m,)): model prediction - > [1 x m] size \n",
" \"\"\" \n",
"\n",
" m = x.shape[0] # Pick the first tuple position [0] -> (_,), to extract the total number of \n",
" # ‘m’ examples from the x input, with size [1 x m] 1D array. \n",
"\n",
" f_wb = np.zeros(m) # Create f_wb(x) output, as a 1D numpy array initialized as ALL zero 0 values, \n",
" # and the same size ‘m’ of the x input [1 x m] 1D array, to be filled. \n",
"\n",
" for i in range(m): # Create indexes i =0 and i = 1, for m = 2 total samples/rows analyzed \n",
"\n",
" f_wb[i] = w * x[i] + b # Use each index value to iterate, x^(0) and x^(1), getting a different f_wb( x^(i) ) \n",
" # prediction value, implementing the regression model f(x) = wx+b each i-th iteration. \n",
" # Then overwrite this value at each 1D array position, \n",
" # previously initialized as ALL 0 values, and size [1 x m]. \n",
"\n",
" return f_wb # Return i-th f_wb( x^(i) ) prediction, after every for loop execution has ended"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's call the `compute_model_output` function and plot the output.."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Call the prediction function, including linear regression model, and return the for loop predicted values, \n",
"# as a [1 x m] 1D numpy array. y^ = yhat = [y^(0), y^(1)]\n",
"tmp_f_wb = compute_model_output(x_train, w, b) # inputs: x_train [1 x m], w (weigh/slope), b (intercept)\n",
"\n",
"# Plot our model prediction, y^ = yhat = [y^(0), y^(1)]\n",
"plt.plot(x_train, tmp_f_wb, c='b',label='y^ Prediction')\n",
"\n",
"# Plot the data points, [ (x^(0)_train, y^(0)_train), (x^(1)_train, y^(1)_train) ] \n",
"plt.scatter(x_train, y_train, marker='x', c='r',label='True values')\n",
"\n",
"# Set the title\n",
"plt.title(\"Housing Prices\")\n",
"\n",
"# Set the y-axis label\n",
"plt.ylabel('Price (in 1000s of dollars)')\n",
"\n",
"# Set the x-axis label\n",
"plt.xlabel('Size (1000 sqft)')\n",
"\n",
"# Add legend\n",
"plt.legend()\n",
"\n",
"# Display matplotlib plot\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As you can see, setting weight/slope to $w = 100$ and intercept to $b = 100$ does *not* result in a line that fits our data. \n",
"\n",
"### Challenge\n",
"Try experimenting with different values of $w$ and $b$. What should the values be for a line that fits our data?\n",
"\n",
"#### Tip:\n",
"You can use your mouse to click on the green \"Hints\" below to reveal some hints for choosing b and w."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<details>\n",
"<summary>\n",
" <font size='3', color='darkgreen'><b>Hints</b></font>\n",
"</summary>\n",
" <p>\n",
" <ul>\n",
" <li>Try $w = 200$ and $b = 100$ </li>\n",
" </ul>\n",
" </p>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Prediction\n",
"Now that we have a model, we can use it to make our original prediction. Let's predict the price of a house with 1200 sqft. Since the units of $x$ are in 1000's of sqft, $x$ is 1.2.\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" The predicted price of the house is $340 thousand dollars\n"
]
}
],
"source": [
"w = 200 # Weight/slope \n",
"b = 100 # Intercept \n",
"x_i = 1.2 # Input size of the house is x = 1.200, since x units are in 1000's of square feets \n",
"\n",
"# Linear Regression model\n",
"cost_1200sqft = w * x_i + b \n",
"\n",
"# prediction:.0f eliminates the decimal of 340.0 -> 340\n",
"print(f\" The predicted price of the house is ${cost_1200sqft:.0f} thousand dollars\") "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Congratulations!\n",
"In this lab you have learned:\n",
" - Linear regression builds a model which establishes a relationship between features and targets\n",
" - In the example above, the feature was house size and the target was house price\n",
" - for simple linear regression, the model has two parameters $w$ and $b$ whose values are 'fit' using *training data*.\n",
" - once a model's parameters have been determined, the model can be used to make predictions on novel data."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
},
"toc-autonumbering": false
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment