Files
2024-08-31 12:07:21 +03:00

1915 lines
216 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"id": "latin-fiber",
"metadata": {},
"source": [
"# A.I. Assignment 2"
]
},
{
"cell_type": "markdown",
"id": "agreed-ferry",
"metadata": {},
"source": [
"## Learning Goals\n",
"\n",
"By the end of this lab, you should be able to:\n",
"* Perform some data preproscessing like: data scaling, normalisatin, encoding categorical features\n",
"* Feel comfortable with simple linear regression\n",
"* Feel comfortable with a regularization in ML\n",
"\n",
"\n",
"### Content:\n",
"\n",
"The Lab. has 3 sections: \n",
"\n",
"1. Preprocessing\n",
"2. Simple Linear regression\n",
"3. Regularization\n",
"\n",
"At the end of each section there is an exercise, each worthing 3 points. All the work must be done during the lab and uploaded on teams by the end of the lab. \n",
"\n",
"\n",
"If there are any python libraries missing, please install them on your working environment. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "independent-bench",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import scipy as sp\n",
"import matplotlib as mpl\n",
"import matplotlib.cm as cm\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd"
]
},
{
"cell_type": "markdown",
"id": "brown-auditor",
"metadata": {},
"source": [
"# Section 1. Preprocessing data\n",
"\n",
"### Standardization, or mean removal and variance scaling\n",
"\n",
"Standardization of datasets is a common requirement for many machine learning estimators; they might behave badly if the individual features do not more or less look like standard normally distributed data: Gaussian with zero mean and unit variance.\n",
"\n",
"\n",
"In practice we often ignore the shape of the distribution and just transform the data to center it by removing the mean value of each feature, then scale it by dividing non-constant features by their standard deviation.\n",
"\n",
"\n",
"For instance, many elements used in the objective function of a learning algorithm may assume that all features are centered around zero or have variance in the same order. If a feature has a variance that is orders of magnitude larger than others, it might dominate the objective function and make the estimator unable to learn from other features correctly as expected.\n",
"\n",
"The preprocessing module provides the StandardScaler utility class, which is a quick and easy way to perform the following operation on an array-like dataset:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "fabulous-washer",
"metadata": {},
"outputs": [],
"source": [
"from sklearn import preprocessing"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "cathedral-china",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>#sk-container-id-1 {color: black;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">StandardScaler</label><div class=\"sk-toggleable__content\"><pre>StandardScaler()</pre></div></div></div></div></div>"
],
"text/plain": [
"StandardScaler()"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train = np.array([[ 1., -1., 2.],\n",
"... [ 2., 0., 0.],\n",
"... [ 0., 1., -1.]])\n",
"\n",
"scaler = preprocessing.StandardScaler().fit(X_train)\n",
"scaler"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "incredible-tokyo",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1. , 0. , 0.33333333])"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"scaler.mean_"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "heavy-stereo",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.81649658, 0.81649658, 1.24721913])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"scaler.scale_"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "sized-royal",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0. , -1.22474487, 1.33630621],\n",
" [ 1.22474487, 0. , -0.26726124],\n",
" [-1.22474487, 1.22474487, -1.06904497]])"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_scaled = scaler.transform(X_train)\n",
"X_scaled"
]
},
{
"cell_type": "markdown",
"id": "adverse-compact",
"metadata": {},
"source": [
"Scaled data has zero mean and unit variance:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "african-citizen",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"mean: [0. 0. 0.] , std: [1. 1. 1.]\n"
]
}
],
"source": [
"print(\"mean:\", X_scaled.mean(axis=0),\", std:\", X_scaled.std(axis=0))"
]
},
{
"cell_type": "markdown",
"id": "understood-genealogy",
"metadata": {},
"source": [
"It is possible to disable either centering or scaling by either passing $with\\_mean=False$ or $with\\_std=False$ to the constructor of StandardScaler."
]
},
{
"cell_type": "markdown",
"id": "based-lightweight",
"metadata": {},
"source": [
"### Scaling features to a range\n",
"\n",
"An alternative standardization is scaling features to lie between a given minimum and maximum value, often between zero and one, or so that the maximum absolute value of each feature is scaled to unit size. This can be achieved using *MinMaxScaler* or *MaxAbsScaler*, respectively.\n",
"\n",
"Here is an example to scale a simle data matrix to the $[0, 1]$ range:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "cooperative-confusion",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.5 , 0. , 1. ],\n",
" [1. , 0.5 , 0.33333333],\n",
" [0. , 1. , 0. ]])"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train = np.array([[ 1., -1., 2.],\n",
"... [ 2., 0., 0.],\n",
"... [ 0., 1., -1.]])\n",
"\n",
"min_max_scaler = preprocessing.MinMaxScaler()\n",
"X_train_minmax = min_max_scaler.fit_transform(X_train)\n",
"X_train_minmax"
]
},
{
"cell_type": "markdown",
"id": "metropolitan-deviation",
"metadata": {},
"source": [
"The same instance of the transformer can then be applied to some new test data unseen during the fit call: the same scaling and shifting operations will be applied to be consistent with the transformation performed on the train data:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "imposed-brother",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-1.5 , 0. , 1.66666667]])"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_test = np.array([[-3., -1., 4.]])\n",
"X_test_minmax = min_max_scaler.transform(X_test)\n",
"X_test_minmax"
]
},
{
"cell_type": "markdown",
"id": "amino-package",
"metadata": {},
"source": [
"It is possible to inspect the scaler attributes to find about the exact nature of the transformation learned on the training data:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "embedded-entrepreneur",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.5 , 0.5 , 0.33333333])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"min_max_scaler.scale_"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "backed-companion",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0. , 0.5 , 0.33333333])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
" min_max_scaler.min_"
]
},
{
"cell_type": "markdown",
"id": "rubber-shepherd",
"metadata": {},
"source": [
"If *MinMaxScaler* is given an explicit $feature\\_range=(min, max)$ the full formula is:\n",
"\n",
"$$ X_{std} = \\frac{(X - X.min)}{ (X.max - X.min)} $$\n",
"\n",
"$$ X_{scaled} = X_{std} * (max - min) + min$$\n",
"\n",
"*MaxAbsScaler* works in a very similar fashion, but scales in a way that the training data lies within the range $[-1, 1]$ by dividing through the largest maximum value in each feature. It is meant for data that is already centered at zero or sparse data.\n",
"\n",
"Here is how to use the data from the previous example with this scaler:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "acknowledged-couple",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0.5, -1. , 1. ],\n",
" [ 1. , 0. , 0. ],\n",
" [ 0. , 1. , -0.5]])"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train = np.array([[ 1., -1., 2.],\n",
"... [ 2., 0., 0.],\n",
"... [ 0., 1., -1.]])\n",
"\n",
"max_abs_scaler = preprocessing.MaxAbsScaler()\n",
"X_train_maxabs = max_abs_scaler.fit_transform(X_train)\n",
"X_train_maxabs"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "spiritual-being",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-1.5, -1. , 2. ]])"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_test = np.array([[ -3., -1., 4.]])\n",
"X_test_maxabs = max_abs_scaler.transform(X_test)\n",
"X_test_maxabs"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "progressive-miller",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([2., 1., 2.])"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"max_abs_scaler.scale_"
]
},
{
"cell_type": "markdown",
"id": "bacterial-nomination",
"metadata": {},
"source": [
"## Normalization\n",
"\n",
"Normalization is the process of scaling individual samples to have unit norm. This process can be useful if you plan to use a quadratic form such as the dot-product or any other kernel to quantify the similarity of any pair of samples.\n",
"\n",
"This assumption is the base of the Vector Space Model often used in text classification and clustering contexts.\n",
"\n",
"The function normalize provides a quick and easy way to perform this operation on a single array-like dataset, either using the $l1$, $l2$, or $max$ norms:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "obvious-buyer",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0.40824829, -0.40824829, 0.81649658],\n",
" [ 1. , 0. , 0. ],\n",
" [ 0. , 0.70710678, -0.70710678]])"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X = [[ 1., -1., 2.],\n",
"... [ 2., 0., 0.],\n",
"... [ 0., 1., -1.]]\n",
"\n",
"X_normalized = preprocessing.normalize(X, norm='l2')\n",
"\n",
"X_normalized"
]
},
{
"cell_type": "markdown",
"id": "received-promise",
"metadata": {},
"source": [
"## Encoding categorical features\n",
"Often features are not given as continuous values but categorical. For example a person could have features [\"male\", \"female\"], [\"from Europe\", \"from US\", \"from Asia\"], [\"uses Firefox\", \"uses Chrome\", \"uses Safari\", \"uses Internet Explorer\"]. Such features can be efficiently coded as integers, for instance [\"male\", \"from US\", \"uses Internet Explorer\"] could be expressed as $[0, 1, 3]$ while [\"female\", \"from Asia\", \"uses Chrome\"] would be $[1, 2, 1]$.\n",
"\n",
"To convert categorical features to such integer codes, we can use the OrdinalEncoder. This estimator transforms each categorical feature to one new feature of integers ($0$ to $n_{categories} - 1$):"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "closing-miami",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>#sk-container-id-2 {color: black;}#sk-container-id-2 pre{padding: 0;}#sk-container-id-2 div.sk-toggleable {background-color: white;}#sk-container-id-2 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-2 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-2 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-2 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-2 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-2 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-2 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-2 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-2 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-2 div.sk-item {position: relative;z-index: 1;}#sk-container-id-2 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-2 div.sk-item::before, #sk-container-id-2 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-2 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-2 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-2 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-2 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-2 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-2 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-2 div.sk-label-container {text-align: center;}#sk-container-id-2 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-2 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>OrdinalEncoder()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">OrdinalEncoder</label><div class=\"sk-toggleable__content\"><pre>OrdinalEncoder()</pre></div></div></div></div></div>"
],
"text/plain": [
"OrdinalEncoder()"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"enc = preprocessing.OrdinalEncoder()\n",
"X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]\n",
"enc.fit(X)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "standard-crossing",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0., 1., 1.]])"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"enc.transform([['female', 'from US', 'uses Safari']])"
]
},
{
"cell_type": "markdown",
"id": "threaded-editing",
"metadata": {},
"source": [
"Such integer representation can, however, not be used directly with all scikit-learn estimators, as these expect continuous input, and would interpret the categories as being ordered, which is often not desired (i.e. the set of browsers was ordered arbitrarily).\n",
"\n",
"By default, *OrdinalEncoder* will also passthrough missing values that are indicated by *np.nan*."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "balanced-attention",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 1.],\n",
" [ 0.],\n",
" [nan],\n",
" [ 0.]])"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"enc = preprocessing.OrdinalEncoder()\n",
"X = [['male'], ['female'], [np.nan], ['female']]\n",
"enc.fit_transform(X)"
]
},
{
"cell_type": "markdown",
"id": "excellent-glance",
"metadata": {},
"source": [
"OrdinalEncoder provides a parameter encoded_missing_value to encode the missing values without the need to create a pipeline and using SimpleImputer."
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "pleased-flour",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 1.],\n",
" [ 0.],\n",
" [-1.],\n",
" [ 0.]])"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"enc = preprocessing.OrdinalEncoder(encoded_missing_value=-1)\n",
"X = [['male'], ['female'], [np.nan], ['female']]\n",
"enc.fit_transform(X)"
]
},
{
"cell_type": "markdown",
"id": "awful-hurricane",
"metadata": {},
"source": [
"***Exercise 1***\n",
"\n",
"Load the dataset *WA_Fn-UseC_-Telco-Customer-Churn.csv* provided. Perform transformations on it so it is prepared to build a model (scaling the numerical data and the cathegorical features transformed in numerical integer labels. "
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "inside-alaska",
"metadata": {},
"outputs": [],
"source": [
"# your code here!\n",
"with open('WA_Fn-UseC_-Telco-Customer-Churn.csv') as f:\n",
" df = pd.read_csv(f)\n",
" # Encoding Categorical Data\n",
" ec = preprocessing.OrdinalEncoder()\n",
" df[\"gender\"] = ec.fit_transform(np.array(df['gender']).reshape(-1, 1)).flatten()\n",
" df[\"SeniorCitizen\"] = ec.fit_transform(np.array(df['SeniorCitizen']).reshape(-1, 1)).flatten()\n",
" df[\"Partner\"] = ec.fit_transform(np.array(df['Partner']).reshape(-1, 1)).flatten()\n",
" df[\"Dependents\"] = ec.fit_transform(np.array(df['Dependents']).reshape(-1, 1)).flatten()\n",
" df['tenure'] = ec.fit_transform(np.array(df['tenure']).reshape(-1, 1)).flatten()\n",
" df['PhoneService'] = ec.fit_transform(np.array(df['PhoneService']).reshape(-1, 1)).flatten()\n",
" df['MultipleLines'] = ec.fit_transform(np.array(df['MultipleLines']).reshape(-1, 1)).flatten()\n",
" df['InternetService'] = ec.fit_transform(np.array(df['InternetService']).reshape(-1, 1)).flatten()\n",
" df['OnlineSecurity'] = ec.fit_transform(np.array(df['OnlineSecurity']).reshape(-1, 1)).flatten()\n",
" df['OnlineBackup'] = ec.fit_transform(np.array(df['OnlineBackup']).reshape(-1, 1)).flatten()\n",
" df['DeviceProtection'] = ec.fit_transform(np.array(df['DeviceProtection']).reshape(-1, 1)).flatten()\n",
" df['TechSupport'] = ec.fit_transform(np.array(df['TechSupport']).reshape(-1, 1)).flatten()\n",
" df['StreamingTV'] = ec.fit_transform(np.array(df['StreamingTV']).reshape(-1, 1)).flatten()\n",
" df['StreamingMovies'] = ec.fit_transform(np.array(df['StreamingMovies']).reshape(-1, 1)).flatten()\n",
" df['Contract'] = ec.fit_transform(np.array(df['Contract']).reshape(-1, 1)).flatten()\n",
" df['PaperlessBilling'] = ec.fit_transform(np.array(df['PaperlessBilling']).reshape(-1, 1)).flatten()\n",
" df['PaymentMethod'] = ec.fit_transform(np.array(df['PaymentMethod']).reshape(-1, 1)).flatten()\n",
" df[\"Churn\"] = ec.fit_transform(np.array(df['Churn']).reshape(-1, 1)).flatten()\n",
"\n",
" \n",
" df['MonthlyCharges'] = preprocessing.StandardScaler().fit_transform(np.array(df['MonthlyCharges']).reshape(-1, 1)).flatten()\n",
" df['TotalCharges'] = preprocessing.StandardScaler().fit_transform(np.array(pd.to_numeric(df['TotalCharges'], errors='coerce')).reshape(-1,1)).flatten()\n",
"\n",
" df.to_csv('output1.csv', index=False)\n",
" \n",
" "
]
},
{
"cell_type": "markdown",
"id": "convinced-prior",
"metadata": {},
"source": [
"# Section 2. Simple linear regression"
]
},
{
"cell_type": "markdown",
"id": "pending-content",
"metadata": {},
"source": [
"Linear regression is defined as an algorithm that provides a linear relationship between an independent variable and a dependent variable to predict the outcome of future events. \n",
"\n",
"Most of the major concepts in machine learning can be and often are discussed in terms of various linear regression models. Thus, this section will introduce you to building and fitting linear regression models and some of the process behind it, so that you can \n",
"\n",
"1. fit models to data you encounter \n",
"\n",
"1. experiment with different kinds of linear regression and observe their effects\n",
"\n",
"1. see some of the technology that makes regression models work."
]
},
{
"cell_type": "markdown",
"id": "southwest-shanghai",
"metadata": {},
"source": [
"### Linear regression with a simple dataset\n",
"\n",
"Lets build first a very problem, focusing our efforts on fitting a linear model to a small dataset with three observations. Each observation consists of one predictor $x_i$ and one response $y_i$ for $i \\in \\{ 1, 2, 3 \\}$,\n",
"\n",
"\\begin{align*}\n",
"(x , y) = \\{(x_1, y_1), (x_2, y_2), (x_3, y_3)\\}.\n",
"\\end{align*}\n",
"\n",
"To be very concrete, let's set the values of the predictors and responses.\n",
"\n",
"\\begin{equation*}\n",
"(x , y) = \\{(1, 2), (2, 2), (3, 4)\\}\n",
"\\end{equation*}\n",
"\n",
"There is no line of the form $a x + b = y$ that passes through all three observations, since the data are not collinear. Thus our aim is to find the line that best fits these observations in the *least-squares sense*."
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "charged-couple",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"numpy.ndarray"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x_train = np.array([1,2,3])\n",
"y_train = np.array([2,3,6])\n",
"type(x_train)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "everyday-environment",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3,)"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x_train.shape"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "filled-european",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3, 1)"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x_train = x_train.reshape(3,1)\n",
"x_train.shape"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "diagnostic-portable",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(3, 1) (3,)\n"
]
},
{
"data": {
"image/png": "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a6vmzp0rSfJ4POru7g7WZ2dn69VXX9XatWv18ssvKyMjQ5s2beJjvQAAIMhmDe8oncL8fr+cTqd8Pp8cDofp4QAAgDEY6/M3v00DAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAAAKMIIwAAwCjCCAAAMIowAgAAjCKMAAAAowgjAADAKMIIAAAwijACAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAAAKMIIwAAwCjCCAAAMIowAgAAjCKMAAAAowgjAADAKMIIAAAwijACAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAAAKMIIwAAwKhxhZGamhrZbDY9/fTTYWsaGxtls9kuOE6cODGeSwMAgDiREG3Ho0ePqq6uTosWLRpTfWdnpxwOR/B8zpw50V4aAADEkaheGfn888/10EMPacuWLbrqqqvG1Cc1NVXp6enBY/r06dFcGgAAxJmowkhFRYXuvvtuLVu2bMx9Fi9eLJfLpeLiYh05cmTU2kAgIL/fH3IAAID4FPHbNLt379bbb7+to0ePjqne5XKprq5O+fn5CgQC+pd/+RcVFxersbFRd9xxx4h9ampq9MMf/jDSoQEAgBhksyzLGmtxT0+PCgoKdPDgQd1www2SpG9+85u68cYbtXHjxjFftKysTDabTQ0NDSM+HggEFAgEgud+v19ZWVny+Xwh+04AAMDU5ff75XQ6L/r8HdHbNMeOHVNfX5/y8/OVkJCghIQENTU1adOmTUpISNC5c+fG9HcKCwt18uTJsI/b7XY5HI6QAwAAxKeI3qYpLi7W8ePHQ9oeffRRLViwQOvWrRvzptT29na5XK5ILg0AAOJURGEkOTlZCxcuDGm74oorlJKSEmyvrq5Wb2+vduzYIUnauHGj5s2bp7y8PA0ODqq+vl5ut1tut3uCpgAAAGJZ1N8zEo7H41F3d3fwfHBwUFVVVert7dXMmTOVl5enffv2qbS0dKIvDQAAYlBEG1hNGesGGAAAMHVckg2sAAAAE40wAgAAjCKMAAAAowgjAADAKMIIAAAwijACAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAAAKMIIwAAwCjCCAAAMIowAgAAjCKMAAAAowgjAADAKMIIAAAwijACAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAAAKMI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YbG0Dsc6v1hdh9Hcv1hZgzk5OXrnnXf02Wefye12a9WqVWpqagobSKbCGrxsXxlJT0+/INX19fUpISFBKSkpo9Z8NSFOdb/4xS/02GOP6Ze//KWWLVs2au20adN08803x8QrIyMpLCwMGXu83EPLsrRt2zatXLlSM2bMGLXW9D186qmn1NDQoCNHjigzM3PU2lhdh5HMcVgsrcNo5vdlU30dRjO/WFqDM2bM0DXXXKOCggLV1NTohhtu0Isvvjhi7VRZg5dtGCkqKtKhQ4dC2g4ePKiCggIlJiaOWnPbbbdN2jjHa9euXVq9erV27typu++++6L1lmXpnXfekcvlmoTRTbz29vaQscfDPZS++BTA73//ez322GMXrTV1Dy3L0pNPPqk9e/bo8OHDys7OvmifWFuH0cxRip11GO38vmqqrsPxzC8W1mA4lmUpEAiM+NiUWYMTthXWsP7+fqu9vd1qb2+3JFk/+clPrPb2duvUqVOWZVnWM888Y61cuTJY/9FHH1lf+9rXrLVr11offvihtXXrVisxMdH6t3/7t2DNG2+8YU2fPt3asGGD1dHRYW3YsMFKSEiwWltbJ31+lhX5HHfu3GklJCRYL7/8suXxeILHZ599Fqx57rnnrAMHDlj/9V//ZbW3t1uPPvqolZCQYL355ptTfn7/9E//ZO3du9f63e9+Z73//vvWM888Y0my3G53sCbW7+Gwhx9+2Lr11ltH/JtT5R4+8cQTltPptBobG0P+vf3P//xPsCbW12E0c4yldRjN/GJpHUYzv2GxsAYty7Kqq6ut5uZmq6ury3rvvfes9evXW9OmTbMOHjxoWdbUXYNxE0aGP1721WPVqlWWZVnWqlWrrG984xshfRobG63FixdbM2bMsObNm2fV1tZe8Hf/9V//1crJybESExOtBQsWhCywyRbpHL/xjW+MWm9ZlvX0009bV199tTVjxgxrzpw5VklJifXb3/52cif2/yKd3/PPP299/etft5KSkqyrrrrKWrJkibVv374L/m4s30PLsqzPPvvMmjlzplVXVzfi35wq93CkeUmytm/fHqyJ9XUYzRxjaR1GM79YWofR/huNlTVoWZb1ne98x5o7d25wLMXFxcEgYllTdw3aLOv/d6oAAAAYcNnuGQEAAFMDYQQAABhFGAEAAEYRRgAAgFGEEQAAYBRhBAAAGEUYAQAARhFGAACAUYQRAABgFGEEAAAYRRgBAABGEUYAAIBR/wd/86KlGUn9AAAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Make a simple scatterplot\n",
"plt.scatter(x_train,y_train)\n",
"\n",
"# check dimensions \n",
"print(x_train.shape,y_train.shape)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "quiet-extraction",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Axes: title={'center': 'A nice plot'}, xlabel='$x$', ylabel='$y$'>"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAArcAAAHNCAYAAAAEzFNNAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABSIUlEQVR4nO3deXxU1f3/8fedSTIzSUhYBdQouFJURKxgwbW1bl8pfv3Wb60LbrTVqrVUxS5WwaVUa8Wl1q1ftS5drP78ili1tepXRUWtIi7FWkFEZJWQhCQzycw9vz+Smc5AMnPvATKZm9fz8cjjkUnumTnzPnOST27OnOsYY4wAAACAAAgVuwMAAADA1kJxCwAAgMCguAUAAEBgUNwCAAAgMChuAQAAEBgUtwAAAAgMilsAAAAEBsUtAAAAAoPiFgAAAIFBcQsARXLGGWfIcRydccYZxe5Kj5g5c6Ycx9Fhhx1W7K4ACDCKWwB9Qn19vaLRqBzHkeM4+vDDD4vdJWwlCxcu1MyZM3XjjTcWuysAegGKWwB9woMPPqhEIpG5fffddxexNx2GDx+uPffcU8OHDy92V0rawoULNWvWLIpbAJIobgH0Ef/zP/8jSbrgggskSb/97W+VSqWK2SXNnj1bixcv1uzZs4vaDwAIEopbAIH35ptvauHCherfv7+uu+467bLLLlq5cqWefPLJYncNALCVUdwCCLz0WdtvfOMbikajOu2003K+bmvTN4Q9/PDDOuywwzRw4EBVVlZq7Nixuummm+S6rqf2XVm+fLlmzJihsWPHqra2VrFYTLvuuqumTJmi++67T/F4vMt2b731ls466yztuuuuqqysVHV1tfbdd19ddtllWrdundXz3fQNYQ899JAOPfRQDRw4UFVVVdp///31q1/9aovOiL/11luaOnWqdt55Z0WjUQ0YMEATJ07UjTfemLOsJM1xHJ155pmSpGXLlmXWVKc/Zs6cad0XACXKAECAtba2mv79+xtJZv78+cYYYz766CPjOI4pKyszq1atsr7v008/3Ugyp59+ujnvvPOMJBMKhTKPl/6YOnVqwfZdue+++0w0Gs3cT0VFhamtrc2577feemuzdpdffrlxHCdzTGVlpamoqMjcHj58uHnzzTd9P98rrrjCSDKHHnqomTFjhpFkHMcxAwYMMKFQKHP/Rx11lInH43nbd2XOnDk5/a6trTXl5eWZ22PGjDGfffZZTpuhQ4eampqaTPZDhw7N+fjFL37h+3kCKG2cuQUQaI888og2bNig3XbbTRMnTpQk7bLLLjrooIOUTCZ1//33b/FjzJ07V3fddZduuOEG1dfXq76+XuvWrdO0adMkSffdd5+effZZX/f55z//Waeffrri8bgmTZqkF198Ua2trdqwYYMaGhr0wgsv6Fvf+pYqKipy2t1444268sorVV1drdmzZ2vlypVqbm5WS0uL3njjDX35y1/WypUr9bWvfU0bN260er4LFy7Uddddp/PPP1+rV6/W+vXrVV9fr6uuukqO4+jpp5/Wj370I1/3OW/ePE2fPl3GGE2ZMkVLlizRhg0btHHjRt13333q16+fFi1apK9//es5Z4ZXrVqlm266SZJUV1enVatW5XxcfPHFVs8RQAkrdnUNANvS4YcfbiSZK6+8Mufrd911l5FkRo0aZX3f6TOvksw999zT5TH777+/kWSmTZvWbftNz9y2t7ebkSNHGknmoIMOMolEwlN/1q5dayorK43jOOaZZ57p8pj29vZMn+bMmePpftPSZ14lmdNOO63LYy677DIjyZSVlZkVK1Z02b6rM7ejR4/OPN9kMrnZ9+fOnZt57D/96U8537vnnnuMJLPzzjv7ej4AgokztwACa8mSJXr++eflOE5mnW3af//3fysWi2nx4sV6+eWXt+hx6urqNHXq1C6/97WvfU2StGjRIs/399xzz2np0qWSpDlz5mx2drY7Dz74oFpaWvTFL35RX/nKV7o8pqysTN/85jclSU8//bTnPm3q8ssv7/Lrl1xyiWKxmJLJpB555BFP97Vo0SK9//77kqSf/vSnCofDmx0zefJkjR8/XpL0+9//3rLXAPoCilsAgXX33XfLGKODDz5YI0aMyPleTU2Njj/++MxxW+KAAw5QKNT1j9Ptt99ekrR+/XrP95cutocNG6YvfvGLntu99NJLkqR3331Xw4YN6/bjyiuvlNTxBiwbdXV12m233br8Xk1Njfbff39J0htvvOHp/tLHlZWV6dBDD+32uK9+9au+7hdA30RxCyCQXNfVb3/7W0nq9qzq6aefLkn64x//aL3+VJL69evX7ffKysokSe3t7Z7vb9WqVZKknXfe2Vc/PvvsM0lSa2urVq9e3e1HY2OjJKmlpcXX/aftsMMOnr6/Zs0aT/eXPm7w4MGKRCLdHrfjjjv6ul8AfRPFLYBAevrpp/Xpp59KkqZNm7bZFlGO4+joo4+WJG3cuFEPPfRQMbvbJcdxfB2ffqPVOeecI2NMwY+PP/64R/q1te93Wz0+gGCguAUQSH73sO0Nl+NNS1+ON73u1qthw4ZJkt55552t3qds6T8aurNixQpJ0nbbbefp/tLHrV27tsu9bDd93CFDhni6XwB9E8UtgMBZu3at5s6dK6njwgpNTU3dfrz22muSpPnz52vx4sXF7HZGesuy1atX+1pfOmnSJEnSq6++ar2e1ovly5fro48+6vJ7TU1N+vvf/y5JntcLp49LJpP6v//7v26Pe+aZZyR1rHHOll7vbIzx9HgAgo3iFkDg3H///Wpvb1dtba0mT56s6urqbj8OOOAAjRo1SlLvOXt7+OGHa5dddpEkTZ8+XW1tbZ7anXbaaYrFYkqlUjrvvPPyXinMdV1t2LDBuo9XXXVVl1//5S9/qdbWVpWVlemEE07wdF9jxozR6NGjJUlXX311l/3+85//rAULFkhSZreHtJqaGknaoucDIDgobgEETrpInTJliqdttE488URJHRdbSCaT27RvXoTDYf3qV7+S4zh66aWX9JWvfEUvvfRS5jK+jY2Nev7553XqqadmttCSOpYl/PznP5ckPfHEE/rqV7+q+fPnZ4pFY4wWL16sG264QXvvvbfmzZtn1b/a2lr99re/1YUXXpi5lG9TU5N+9rOfZYre8847r+Abz7Jde+21kqQXX3xRX//61zNLMtrb2/Xggw9mCtqJEydmdrlI23vvvSV15NIb104D6FkUtwAC5dVXX9V7770n6d9FayHp41avXq0nnnhim/XNj2OOOUb33nuvIpGIXnrpJR188MGqrKzUgAEDVFtbq8MPP1wPPvjgZmd1v/e97+m6665TOBzWc889p4MOOkiVlZWZnQi+8IUv6KKLLtI//vEP6zdmjR07VjNmzNDNN9+soUOHatCgQRowYIB+8pOfyHVdHXHEEZki26vjjjtON9xwgxzH0f/+7/9ql1120YABA1RdXa1TTz1VjY2N2mefffSnP/1ps31wd9ttt8y+vt/4xjdUU1OjESNGaMSIEbrxxhutniOA0kVxCyBQ0m8kq62t1ZFHHumpzT777KMvfOELOe17g6lTp2rx4sX6/ve/r9GjR6usrExtbW3adddddfzxx+v+++/P9DvbJZdcosWLF2v69OkaM2aMotGoNmzYkFmGMWPGDL388ss6+eSTrft27bXX6g9/+IMmTZok13VVUVGhsWPH6qabbtJTTz2laDTq+z6nT5+uN954Q6eeeqrq6urU0tKiWCymAw88UDfccINee+21zL7Bm3r44Yc1ffp07bHHHmpvb9eyZcu0bNkylioAfZBjSmQFvp8zDIcddpiee+65bdgbAOh7Zs6cqVmzZunQQw/V888/X+zuAECXyordAa+GDh2a9/vt7e2ZKwBt+k5aAAAA9A0lU9ymr9jTnV/+8pe6+OKLJUlnn312T3QJAAAAvUxg1tym18kddNBB2nPPPYvcGwAAABRDIIrbl19+Wf/4xz8kdVxmEwAAAH1TybyhLJ+zzz5bd999t2pqarRy5UpVVlYWu0sAAAAogpJZc9udjRs3ZjbtPvnkkwsWtolEIufa5a7rav369Ro0aJD1no8AAADYdowxampq0vbbb5+55HZ3Sr64/cMf/qCNGzdK8rYkYfbs2Zo1a9a27hYAAAC2suXLl2vHHXfMe0zJL0s48MADtWDBAu27775auHBhweM3PXPb0NCgnXbaSR9//HHm+uRdyb4ijjEmcxnMfPy2cRwn568Rmzau66rQkNq0CYVCOWe2bdrku879lrTpibGxacN49t7xZGx679jYtOmpsWE8mWtBGhubNsWcaw0NDRoxYoQ2bNig2travO1L+szte++9pwULFkjy/kaySCSiSCSy2ddra2vVv3//rdm9wHJdV+3t7ZKk8vLygv8eAJnZIjf/yMwOuflHZnbIzb/szLwsIS3p4vY3v/mNJCkajeqUU07Zovsq8RPYPcoYk3mRlZWV9Euox5CZHXLzj8zskJt/ZGaH3PzLzsyLkv1zoa2tTQ888IAk6b/+6780YMCAIvcIAAAAxVayxe1jjz2mdevWSWJvWwAAAHQo2eI2vSRht91206GHHlrk3gAAAKA3KMni9pNPPtEzzzwjSTrrrLPYnxYAAACSSrS4vfvuu+W6rsrKynTGGWcUuzsAAADoJUquuHVdV/fee68k6dhjj9Xw4cOL2yEAAAD0GiVX3D7zzDNatmyZJN5IBgAAgFwlt8HakUceuU32pGXdrneO42QuhEFu3pCZHXLzj8zskJt/ZGaH3PzLzsyLkitutxWuEOJdKBQiL5/IzA65+UdmdmxyS28s7+Uyp0Hn5ZKy2Fxfyy0UCqm8vNx3UZ9u5xXFLQAAPqRSKa1bt05NTU2+rpoEoOOSw/369dPgwYMVDoe3yWNQ3AIA4FEqldLy5cuVSCRUW1ur6upqhcNh/r0MFGCMUSqV0saNG7Vhwwa1traqrq5umxS4FLed+LeSd67rKpFISJIikQj/AvWAzOyQm39kZsdrbuvWrVMikdBOO+2kWCzWk13sdYwxmffAOI5Dge9RX8+turpatbW1+uSTT7Ru3ToNHTq0YBvXddXa2ur5Mfip12lbvEktqNJ/faVSKXLziMzskJt/ZGbHS27GGDU1Nam2trbPF7Zp2YUavOvrucViMdXU1KipqclTDun56RXFLQAAHrS3t6u9vV3V1dXF7gpQ8vr165eZU1sbxS0AAB6kl69tqzfBAH1Jeh5ti2WhFLcAAPjQ19ZIAtvCtpxHFLcAAAAIDIpbAAAABAbFLQAAAAKD4hYAAACBwUUcOrHRuXehUEjRaDTzOQojMzvk5h+Z2SE3O2Rlh9z8yZ6fXlDcduLdr945jqOyMl46fpCZHXLzj8zskJt//N60Q27++Z2f/OkAAADQy/3kJz+R4zg68sgji92VXo8/UwEAAHq5t956S5K03377bfX7fvHFF/W3v/1NdXV1Ovvss7f6/fc0ztx28nPN4r4ulUqppaVFLS0t5OYRmdkhN//IzA65+WeMUSqVUiqVkjGm2N0pGba5tba2as8999SkSZO2ep/uvPNOzZo1S6+88spWv++tIT0/veLMLaxsi8vlBR2Z2SE3/8jMDrmhN3vuuee22X0vWLBAkjRhwoRt9hhbys/85MwtAABAH1VfX68PP/xQkjR+/Pgi92broLgFAABFcdFFF8lxHP3Hf/yHJOl3v/udvvKVr2jQoEGqqanRIYccknPGsr29XXfccYcmTpyo/v37q7q6WkcddZQWLVqUc7+rV6+W4zhyHEdPP/103j6cf/75chxHEydOzLtM4KqrrpLjODr88MPV1NSka665RuPHj9eAAQMUiUQ0atQozZ49u+Cylvfee0/Tp0/XPvvso5qaGlVXV2v8+PG69dZbu22bzmny5Mmbfe/CCy+U4zj6z//8T0nSk08+qf/8z//U9ttvr6qqKo0ZM0a33nrrZmc+P/zwQzmOo4EDB2a+Nnbs2ExujuPo6quvznxv0aJFOvfcczV69GhVV1crEoloxx131KRJk/TjH/9Yixcvzvu8exLLEgAAKCEp1+i1peu1pimu7fpFNX7kQIVDpbm91MKFCyVJu+++uyZPnqx58+apoqJC5eXlam5u1osvvqijjz5a8+fP17Bhw3TCCSfo9ddfVywWkzFG8Xhcf/nLX7Rw4UL985//VG1trSRp6NCh2mWXXbRkyRItWLBARx11VJeP//bbb+v2229XKBTSLbfcknebrjfffFOSNGjQIO27775aunSpHMdRVVWV2tra9MEHH+jHP/6x3nvvPT3wwAObtTfG6KqrrtJVV12lZDIpSaqpqVFTU5Nef/11vf7663r88cf1+OOPq7y8vMucunozWfp7X/jCF/TNb35Tf/jDHxQOh9WvXz+1tLTonXfe0fnnn6/6+npddtllmXYffvihhg4dqo0bN6q5uVkVFRUaMGBAzn1/8YtflCRdd911+vGPf5wpvqPRqCKRiFasWKEVK1bo5Zdf1pgxYzRq1Khu8+tRpo9raGgwksz69euL3ZWSkUwmTVNTk2lqajLJZLLY3SkJZGaH3PwjMztecmttbTXvv/++aW1t7eHe/duT73xmDvzZM2bnS+dlPg782TPmyXc+6/G+uK5rksmkSSaTxnVdq/sYOHCgkWT69+9vdtppJ/Poo4+atrY2Y4wxTz31lIlGo0aSOeGEE8xee+1l9t13X/Pcc88Z13VNKpUy99xzj5FkJJmbb745575PO+00I8kce+yx3T7+wQcfbCSZb3/72wX7utNOO2Ueq1+/fubmm282TU1NxhhjPvroI3P44Ydnvv/CCy9s1v6iiy4ykkx5ebm54oorzGeffWZc1zXNzc3mlltuMeXl5UaSufzyy7vN6f/9v/+32fdqa2uNJDN48GAzfPhw8+CDD5qWlhZjjDHLly/PPMfq6uoux+nMM880ksxpp53W5fN+8sknjSQTiUTM7Nmzzaeffpr5Xn19vXnmmWfM1KlTzUcffVQww2x+5lMymTQrVqwwkkxDQ0PB4yluKW5945enf2Rmh9z8IzM7pVDcPvnOZ2ZEVlGb/hjR+dHTBe6WFrcff/xxphjcbrvtzIoVKzY7Ztq0aZljRo8ebTZu3LjZMYcccoiRZL773e/mfP22224zksygQYO6fPz777/fSDIDBgwwa9euzdvXzz//PNOP6upq88Ybb2x2zLp160y/fv2MJHPxxRfnfO/BBx80kkw4HDZ//vOfu8ztggsuyGSR/fXsnJYuXZpzvx999FHmewMHDjQff/zxZv167bXXMscsX758s++PHTvWSDJz5szp8rlPmTLFSDJXXnllvoh825bFLWtuAQDo5VKu0azH31dXK0LTX5v1+PtKuaWzJVd631ZJuuuuu7T99ttvdsyOO+4oqeMKVX/84x9VVVW12TE77LCDpI71uNnSW2Z9/vnn+te//pXzvaamJs2YMUNSx1rawYMH5+1reklC+vj9999/s2MGDRqkiRMnSpKWLFmS+Xoymcw81ve+9z0dffTRXT5G+utr1qzRypUrM19P59S/f3+NGDEip012hnfccYd23nnnLvuVFg6Hc77X1tam9957T1L3++cuW7ZMUmltmUpxCwBAL/fa0vVa2RDv9vtG0sqGuF5bur7nOrWF0oXZ8OHDddxxx3V5zMcffyxJmjhxovbee+8uj1m6dKkkaaeddsr5+l577ZVZg5ve6ipt1qxZWrlypcaMGaNzzjmnYF/Txe2AAQPyHj98+PDNvvbEE09oxYoVCofDuvDCCz21zS7U8128Ib3edrvttsu8oWxT6Z0QqqqqNGzYsJzvvfvuu2pvb5fjOBo7dmyX7ffZZx9J0tVXX63vfe97evvtt7t9Dr0FxW2nUIgovAqFQorFYorFYuTmEZnZITf/yMxOb89tTVP3ha3NcVtLKBSyzitdtB133HHd3ke6eJsyZUqX33ddV++8844kacyYMZv1Lb1v66uvvpr5+uLFi3XzzTdLkm655ZbNzmYW6ms0Gu32uM8//1xSxxva0v76179Kkg455JDMmdWucmtoaMh8nn0mOV9xm92v7p5HOsMxY8Zs9oa5dPtddtkl84fApq699lpNmDBBqVRKt9xyi8aOHasddthB3/72t/XSSy912WZrS89Pz8dvw76UlHzvkEQux3EUDocVDofJzSMys0Nu/pGZnd6e23b9ui+obI7bGrK3jLLJLF1YHXDAAV1+P/tf5ul37W/qww8/VHNzsyRp3Lhxm30/vTQh+8ztBRdcoPb2dp188sk65JBDPPU1fea2u36kpR8nuxBNF9/77ruvpO5zS29ntscee+Qsv0jn1NWZ1fT38u1Pm+57vuI43yV9hw8frpdffll/+ctf9J3vfEe77767PvvsM9111106+OCDdeKJJ27zC6Ck56dXFLcAAPRy40cO1PDaqLorIR1Jw2s7tgUrBZ9//rk+/fRTSV0XpVJHUZj+l3l3x6SLsyFDhmTW52ZLr4F9++23lUgk9Mgjj+iZZ55RdXW1rrvuOk993bhxY2bNbr61uc8//7zWrFkjx3F07LHHZr5eX18vqWPbr3zmzp0rSfrqV7+a+Vp2TpsWoGvXrtVnn30mqfsMpX8Xt10dk6/wzRYKhfTVr35Vt99+u/75z39q0aJFmb2JH374YT3xxBN52/c0ilsAAHq5cMjRFZNHS9JmBW769hWTR5fMfrfporS8vDyzpnNT6cJr11137fZf5un76a64O/DAAxUOh9XW1qb58+froosukiRddtllmTeiFbJw4cLMmcm1a9d2e9y1114rSfr617+ec9/V1dWSlPMmsU298sorevbZZyVJZ511Vubr6ecXjUY320M2O8NNl2SkNTY26qOPPpK0eQFrjMmcLe5uvW139tlnH82dO1dDhgyRJC1fvtxX+22N4rZTKb0LsNhSqZSam5vV3NxMbh6RmR1y84/M7JRCbkfvPVy3nTpOw2pzlx4Mq43qtlPH6ei9N38z07ZkjFEqlVIqlcp7Za+upAuzvfbaSxUVFXmPyXdWMr2etLtjqqurM8Xz2WefrWXLlmn33XfX9OnTPfc1e6eEJ598sstj7rzzTj311FOKRqO68sorc76X7tszzzyj9vb2zXJbtWqVTjvtNBljdPLJJ+c8l3QG++yzj8rKcq+7lX7uo0ePViQS6bJfCxculDFG5eXlm70hr76+PrOko6tCP5FIdHmfaatXr1ZjY6Mkdftmv60lPT+9oriFFdOxR3Kxu1FSyMwOuflHZnZKIbej9x6uly79sn7/rQN100lj9ftvHaiXLv1yjxe2W8pL4ZouKrvadsvP/aTX3aZ3Xrjpppu6Lajz9aN///56+umn9dOf/lRNTU2SOs7GXnLJJTr33HMldWzHtekZ1mnTpikUCmnp0qU644wzMmdwE4mEHnroIY0fP14fffSRxo0bp9tvv73L55dvvWy+fNJ97+qPiP79+2fepPXwww9vtm72nnvu0X777aebb75ZH374YWZuJBIJPfbYYzriiCOUSCT0pS99SQcffHC3fdha/MxNilsAAEpIOOToS7sO0pSxO+hLuw4qmaUI2QoVpalUKvMv8+6KtxUrVmSWCeQrbtPrbiVp8uTJOuaYY6z6OnPmTO299966+uqrVVtbq9raWm2//fa6/vrr5TiObrzxRk2dOnWz9mPHjtXs2bMlSb/73e+0ww47aODAgaqpqdFJJ52k5cuX66ijjtJTTz2lfv36dfnY+bYBs11vGwqF9N///d+SOrb5Sm8VNmzYMD311FN66623tHDhQl144YXaY489FIvFNGjQIMViMR1//PF6//33NWHCBP3v//5vr3sTZlnhQwAAALaOlpYW/fOf/5TUfWG2ePFitba25j0m++IGu+yyS7ePlz47GYlENGfOHF99TSQSev/99yV1rN+dOnWqLr/8cj322GNavXq1dthhB335y1/WxRdf3O26V0maMWOG9t13X82ZM0evvfaampubtcMOO2jcuHE67bTTdMIJJ2zWJjunTdfEeslQKrwbwq233qqBAwfq0Ucf1aeffqrVq1dL6ljqsNNOO2mPPfbQ//3f/2nx4sVas2aNmpqaNHToUI0bN04nnXSSTj75ZF+7GPQUx/T2/8FsY42NjaqtrdX69es1YMCAYnenJKRSqcwPnVgs1itf2L0NmdkhN//IzI6X3OLxuJYuXaqRI0fm3eu0rzDGZP6VHQqFet3ZO6ljXMeNG6dFixbpsssu01VXXeWr/euvv67x48crHA6rqanJ116r3SmF3HqCn/mUSqUyf0w0NDQU3HmCZQkAACCQbr75Zi1atEgjRozQj370I9/t02c+99xzz61S2KJnUNwCAIDA+f3vf69LL71UjuPozjvvVGVlpe/7SK9Z9btVFoqLNbcAACAQnnjiCZ133nmqr6/PbFP105/+NOfCCH54vcgBeheKWwAAEAjz58/XsmXLVFlZqf3220/nnXeezj77bKv7SiaTmUvncua2tPCGss43lG3YsKHbK6Ag16Yvmb66GN4PMrNDbv6RmR0vufGGsly81uyQWwc/88kYo8bGRvXv39/TG8o4c9upr764bJCVf2Rmh9z8IzM75OYfmdkhN/8cx/GVG28oAwAAQGBQ3MJKKVymsrchMzvk5h+Z2SE3/8jMDrn55ycvliV0SqVSxe5CyWCTeP/IzA65+UdmdsjNPy5GYIfc/EulUmpubvZ8PGduAQAAEBgUtwAA+MC/k4Etty3nUUkWt42Njbr22ms1ceJEDRky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",
"text/plain": [
"<Figure size 800x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def nice_scatterplot(x, y, title):\n",
" # font size\n",
" f_size = 18\n",
" \n",
" # make the figure\n",
" fig, ax = plt.subplots(1,1, figsize=(8,5)) # Create figure object\n",
"\n",
" # set axes limits to make the scale nice\n",
" ax.set_xlim(np.min(x)-1, np.max(x) + 1)\n",
" ax.set_ylim(np.min(y)-1, np.max(y) + 1)\n",
"\n",
" # adjust size of tickmarks in axes\n",
" ax.tick_params(labelsize = f_size)\n",
" \n",
" # remove tick labels\n",
" ax.tick_params(labelbottom=False, bottom=False)\n",
" \n",
" # adjust size of axis label\n",
" ax.set_xlabel(r'$x$', fontsize = f_size)\n",
" ax.set_ylabel(r'$y$', fontsize = f_size)\n",
" \n",
" # set figure title label\n",
" ax.set_title(title, fontsize = f_size)\n",
"\n",
" # you may set up grid with this \n",
" ax.grid(True, lw=1.75, ls='--', alpha=0.15)\n",
"\n",
" # make actual plot (Notice the label argument!)\n",
" #ax.scatter(x, y, label=r'$My points$')\n",
" #ax.scatter(x, y, label='$My points$')\n",
" ax.scatter(x, y, label=r'$my\\,points$')\n",
" ax.legend(loc='best', fontsize = f_size);\n",
" \n",
" return ax\n",
"\n",
"nice_scatterplot(x_train, y_train, 'A nice plot')\n"
]
},
{
"cell_type": "markdown",
"id": "checked-nickname",
"metadata": {},
"source": [
"#### Formulae\n",
"Linear regression is special among the models we study because it can be solved explicitly. While most other models (and even some advanced versions of linear regression) must be solved itteratively, linear regression has a formula where you can simply plug in the data.\n",
"\n",
"For the single predictor case it is:\n",
"\\begin{aligned}\n",
" a &= \\frac{\\sum_{i=1}^n{(x_i-\\bar{x})(y_i-\\bar{y})}}{\\sum_{i=1}^n{(x_i-\\bar{x})^2}},\\\\\n",
" b &= \\bar{y} - a \\bar{x}.\n",
"\\end{aligned}\n",
" \n",
"Where $\\bar{y}$ and $\\bar{x}$ are the mean of the y values and the mean of the x values, respectively."
]
},
{
"cell_type": "markdown",
"id": "close-vegetation",
"metadata": {},
"source": [
"### Building a model from scratch\n",
"\n",
"We will solve the equations for simple linear regression and find the best fit solution to our simple problem."
]
},
{
"cell_type": "markdown",
"id": "athletic-disability",
"metadata": {},
"source": [
"The snippets of code below implement the linear regression equations on the observed predictors and responses, which we'll call the training data set. Let's walk through the code.\n",
"\n",
"We have to reshape our arrrays to 2D. We will see later why."
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "smart-reading",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3, 2)"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#solution\n",
"xx = np.array([[1,2,3],[4,6,8]])\n",
"xxx = xx.reshape(-1,2)\n",
"xxx.shape"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "satellite-standard",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(3, 1)\n"
]
}
],
"source": [
"# Reshape to be a proper 2D array\n",
"x_train = x_train.reshape(x_train.shape[0], 1)\n",
"y_train = y_train.reshape(y_train.shape[0], 1)\n",
"\n",
"print(x_train.shape)"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "artificial-learning",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"() ()\n"
]
}
],
"source": [
"# first, compute means\n",
"y_bar = np.mean(y_train)\n",
"x_bar = np.mean(x_train)\n",
"\n",
"# build the two terms\n",
"numerator = np.sum( (x_train - x_bar)*(y_train - y_bar) )\n",
"denominator = np.sum((x_train - x_bar)**2)\n",
"\n",
"print(numerator.shape, denominator.shape) #check shapes"
]
},
{
"cell_type": "markdown",
"id": "corresponding-overall",
"metadata": {},
"source": [
"* Why the empty brackets? (The numerator and denominator are scalars, as expected.)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "banner-america",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The best-fit line is -0.33 + 2.00 * x\n",
"The best fit is -0.3333333333333335\n"
]
}
],
"source": [
"#slope beta1\n",
"a = numerator/denominator\n",
"\n",
"#intercept beta0\n",
"b = y_bar - a * x_bar\n",
"\n",
"print(\"The best-fit line is {0:3.2f} + {1:3.2f} * x\".format(b, a))\n",
"print(f'The best fit is {b}')"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "every-humor",
"metadata": {},
"outputs": [],
"source": [
"def simple_linear_regression_fit(x_train: np.ndarray, y_train: np.ndarray) -> np.ndarray:\n",
" \"\"\"\n",
" Inputs:\n",
" x_train: a (num observations by 1) array holding the values of the predictor variable\n",
" y_train: a (num observations by 1) array holding the values of the response variable\n",
"\n",
" Returns:\n",
" beta_vals: a (num_features by 1) array holding the intercept and slope coeficients\n",
" \"\"\"\n",
" \n",
" # Check input array sizes\n",
" if len(x_train.shape) < 2:\n",
" print(\"Reshaping features array.\")\n",
" x_train = x_train.reshape(x_train.shape[0], 1)\n",
"\n",
" if len(y_train.shape) < 2:\n",
" print(\"Reshaping observations array.\")\n",
" y_train = y_train.reshape(y_train.shape[0], 1)\n",
"\n",
" # first, compute means\n",
" y_bar = np.mean(y_train)\n",
" x_bar = np.mean(x_train)\n",
"\n",
" # build the two terms\n",
" numerator = np.sum( (x_train - x_bar)*(y_train - y_bar) )\n",
" denominator = np.sum((x_train - x_bar)**2)\n",
" \n",
" #slope a\n",
" a = numerator/denominator\n",
"\n",
" #intercept b\n",
" b = y_bar - a*x_bar\n",
"\n",
" return np.array([b,a])"
]
},
{
"cell_type": "markdown",
"id": "identified-ridge",
"metadata": {},
"source": [
"* Let's run this function and see the coefficients"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "musical-galaxy",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Reshaping features array.\n",
"Reshaping observations array.\n",
"The best-fit line is 0.666667 * x + 1.000000.\n"
]
}
],
"source": [
"x_train = np.array([1 ,2, 3])\n",
"y_train = np.array([2, 2, 4])\n",
"\n",
"coeficients = simple_linear_regression_fit(x_train, y_train)\n",
"\n",
"a = coeficients[1]\n",
"b = coeficients[0]\n",
"\n",
"print(\"The best-fit line is {1:8.6f} * x + {0:8.6f}.\".format(a, b))"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "coordinate-cookie",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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zZo19evw+W0aR44c0Weffaa77777lOV8fk9nmqZmzJihkSNHqk+fPmddj/m3cdwd359i/nWfu2PMHNw4jfkMMwef37Zt2xQcHCw/Pz/dd999Wrx4sXr16nXGdVvy/Ouw9LtDkmQYximPTdM8bfmZ1vnpMpzb+++/rz/+8Y/66KOPFBkZWb982LBhGjZsWP3jSy65RBdffLH++te/6vnnn7ciaovRvXt3de/evf7x8OHDlZubq2eeeUajR4+uX87n98K99dZbateuna699tpTlvP5Pd20adP07bffat26deddl/m34Royvj9g/m0Yd8eYObhxGvMZZg4+v+7du+vrr7/WiRMntHDhQt12221avXr1WQtUS51/2fNksejo6NMadEFBgRwOhyIiIs65zk/bOM7u73//u+666y794x//0MSJE8+5rs1m0+DBg9vkX42awrBhw04ZOz6/F840Tb3xxhuaMmWKfH19z7luW//8PvDAA1qyZIlWrVql2NjYc67L/NtwDRnfHzD/NkxjxvjHmIPPrTHjyxzsHl9fXyUlJWnQoEGaNWuWLrroIs2dO/eM67bk+ZfyZLHhw4crLS3tlGXLli3ToEGD5OPjc851RowY0Ww5W7L3339ft99+u9577z1dccUV513fNE19/fXXiomJaYZ0rU9GRsYpY8fn98KtXr1a2dnZuuuuu867blv9/JqmqWnTpmnRokVauXKlunbtet7XMP+6rzHjKzH/NkRjx/inmIPP7ELGlzm4cUzTVFVV1Rmfa9HzbzNenKJNKC0tNTMyMsyMjAxTkjl79mwzIyPDPHjwoGmapvn444+bU6ZMqV9/3759ZmBgoDl9+nRz586d5uuvv276+PiY//znP+vX+eKLL0y73W4+/fTT5q5du8ynn37adDgc5saNG5v9/VmtoeP73nvvmQ6Hw3zxxRfNI0eO1H+dOHGifp0//vGP5tKlS829e/eaGRkZ5h133GE6HA5z06ZNzf7+rNbQ8Z0zZ465ePFiMzMz09y+fbv5+OOPm5LMhQsX1q/D5/c/Gjq+P7jlllvMoUOHnnGbfH7r3H///WZYWJiZnp5+yr/1ioqK+nWYfxuvMePL/NswjRlj5mD3NWZ8f8AcfH5PPPGEuWbNGnP//v3mt99+a86cOdO02WzmsmXLTNNsXfMv5amJ/XDZ0J9+3XbbbaZpmuZtt91mjhkz5pTXpKenmwMGDDB9fX3NhIQEc968eadt98MPPzS7d+9u+vj4mD169DhlYmxLGjq+Y8aMOef6pmmaDz/8sBkfH2/6+vqaHTt2NCdNmmSuX7++ed+Yl2jo+P7f//2f2a1bN9Pf399s3769OXLkSPOTTz45bbt8fus0Zn44ceKEGRAQYL7yyitn3Caf3zpnGldJ5ptvvlm/DvNv4zVmfJl/G6YxY8wc7L7GzhHMwe658847zS5dutSPw4QJE+qLk2m2rvnXMM3vz84CAAAAAJwV5zwBAAAAgBsoTwAAAADgBsoTAAAAALiB8gQAAAAAbqA8AQAAAIAbKE8AAAAA4AbKEwAAAAC4gfIEAAAAAG6gPAEAAACAGyhPAIBW4f3335e/v7/y8vLql919993q16+fiouLLUwGAGgtDNM0TatDAABwoUzTVP/+/TVq1Ci98MILevLJJ/Xaa69p48aN6ty5s9XxAACtgMPqAAAANAXDMPTnP/9ZP//5z9WpUyfNnTtXa9eurS9O+/bt044dO3TVVVc1aLvLly/Xtm3bNH36dE/EBgC0IOx5AgC0KhdffLF27NihZcuWacyYMfXLX3zxRVVUVOg3v/nNaa9xOp2y2+3NGRMA0AJxzhMAoNX4/PPPtXv3bjmdTkVFRdUvX716tX7/+9/r1Vdf1YABA3Ty5Elddtll+u1vf6vRo0dr/vz5eueddzR06FD17dtXV199taqrqyVJl112mXbt2lX/33/4wx80bNgwdenSRTt37rTkfQIArEF5AgC0Cl999ZVuuOEGvfzyy5o8ebL++7//u/65MWPGqE+fPlqxYoUyMjIUEBCg7du3q3PnzlqzZo3uuOMOXX755dq0aZO2bdumDh06aO3atZKkrKwsJScnS5K2b9+url27auPGjbrnnnv08ccfW/JeAQDW4JwnAECLd+DAAV1xxRV6/PHHNWXKFPXq1UuDBw/W1q1bNXDgQEnSoUOHFBcXJ0kqLi6WYRh66KGHJNVdbOKVV17RokWLVF1drZycHN11110qLi5WcHCwHA6HiouL5ePjo9tvv12S5Ovrq7CwMEveLwDAGux5AgC0aMeOHdNll12mq6++WjNnzpQkDRw4UFdddZV+97vfSaorTj++4t727ds1YsSI+sdvvfWWsrOztWbNGn3zzTcKDQ1Vr169tH37dvXu3bv+NUOGDDllGz88BwBoG9jzBABo0cLDw+vPSfqxjz76qP6/9+/fr06dOtU/3r59u/r27Vv/eMeOHRoxYoQCAgI0d+5cuVwutW/fXtu3b1efPn3O+Jpt27bVPwcAaBvY8wQAaPX69OmjrKws9e3bV7t379aOHTtOKUJTpkzRn/70J40ZM0ZFRUX1z+3YsaO+IP34NbW1tSorK1O7du2a/b0AAKzDpcoBAAAAwA3seQIAAAAAN1CeAAAAAMANlCcAAAAAcAPlCQAAAADcQHkCAAAAADdQngAAAADADZQnAAAAAHAD5QkAAAAA3EB5AgAAAAA3UJ4AAAAAwA2UJwAAAABww/8PlEMLVwuxfwwAAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# %load solutions/best_fit_scatterplot.py\n",
"fig_scat, ax_scat = plt.subplots(1,1, figsize=(10,6))\n",
"\n",
"# Plot best-fit line\n",
"x_train = np.array([[1, 2, 3]]).T\n",
"\n",
"best_fit = b + a * x_train\n",
"\n",
"ax_scat.scatter(x_train, y_train, s=300, label='Training Data')\n",
"ax_scat.plot(x_train, best_fit, ls='--', label='Best Fit Line')\n",
"\n",
"ax_scat.set_xlabel(r'$x_{train}$')\n",
"ax_scat.set_ylabel(r'$y$');\n"
]
},
{
"cell_type": "markdown",
"id": "monetary-brisbane",
"metadata": {},
"source": [
"The values of `a` and `b` seem roughly reasonable. They capture the positive correlation. The line does appear to be trying to get as close as possible to all the points."
]
},
{
"cell_type": "markdown",
"id": "naked-bullet",
"metadata": {},
"source": [
"## 4 - Building a model with `statsmodels` and `sklearn`\n",
"\n",
"Now that we can concretely fit the training data from scratch, let's learn two `python` packages to do it all for us:\n",
"* [statsmodels](http://www.statsmodels.org/stable/regression.html) and \n",
"* [scikit-learn (sklearn)](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html).\n",
"\n",
"Our goal is to show how to implement simple linear regression with these packages. For an important sanity check, we compare the $a$ and $b$ from `statsmodels` and `sklearn` to the ones that we found from above with our own implementation.\n",
"\n",
"For the purposes of this lab, `statsmodels` and `sklearn` do the same thing. More generally though, `statsmodels` tends to be easier for inference \\[finding the values of the slope and intercept and dicussing uncertainty in those values\\], whereas `sklearn` has machine-learning algorithms and is better for prediction \\[guessing y values for a given x value\\]. (Note that both packages make the same guesses, it's just a question of which activity they provide more support for.\n",
"\n",
"**Note:** `statsmodels` and `sklearn` are different packages! Unless we specify otherwise, you can use either one."
]
},
{
"cell_type": "markdown",
"id": "asian-lemon",
"metadata": {},
"source": [
"below is the code for `statsmodels`. `Statsmodels` does not by default include the column of ones in the $X$ matrix, so we include it manually with `sm.add_constant`."
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "breeding-silver",
"metadata": {},
"outputs": [],
"source": [
"import statsmodels.api as sm"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "weekly-newton",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[1. 1.]\n",
" [1. 2.]\n",
" [1. 3.]]\n",
"The regression coef from statsmodels are: beta_0 = 0.666667 and beta_1 = 1.000000\n"
]
}
],
"source": [
"# create the X matrix by appending a column of ones to x_train\n",
"X = sm.add_constant(x_train)\n",
"\n",
"# this is the same matrix as in our scratch problem!\n",
"print(X)\n",
"\n",
"# build the OLS model (ordinary least squares) from the training data\n",
"toyregr_sm = sm.OLS(y_train, X)\n",
"\n",
"# do the fit and save regression info (parameters, etc) in results_sm\n",
"results_sm = toyregr_sm.fit()\n",
"\n",
"# pull the beta parameters out from results_sm\n",
"beta0_sm = results_sm.params[0]\n",
"beta1_sm = results_sm.params[1]\n",
"\n",
"print(f'The regression coef from statsmodels are: beta_0 = {beta0_sm:8.6f} and beta_1 = {beta1_sm:8.6f}')"
]
},
{
"cell_type": "markdown",
"id": "designed-kruger",
"metadata": {},
"source": [
"Besides the beta parameters, `results_sm` contains a ton of other potentially useful information."
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "accepting-shower",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" OLS Regression Results \n",
"==============================================================================\n",
"Dep. Variable: y R-squared: 0.750\n",
"Model: OLS Adj. R-squared: 0.500\n",
"Method: Least Squares F-statistic: 3.000\n",
"Date: Wed, 06 Mar 2024 Prob (F-statistic): 0.333\n",
"Time: 12:17:32 Log-Likelihood: -2.0007\n",
"No. Observations: 3 AIC: 8.001\n",
"Df Residuals: 1 BIC: 6.199\n",
"Df Model: 1 \n",
"Covariance Type: nonrobust \n",
"==============================================================================\n",
" coef std err t P>|t| [0.025 0.975]\n",
"------------------------------------------------------------------------------\n",
"const 0.6667 1.247 0.535 0.687 -15.181 16.514\n",
"x1 1.0000 0.577 1.732 0.333 -6.336 8.336\n",
"==============================================================================\n",
"Omnibus: nan Durbin-Watson: 3.000\n",
"Prob(Omnibus): nan Jarque-Bera (JB): 0.531\n",
"Skew: -0.707 Prob(JB): 0.767\n",
"Kurtosis: 1.500 Cond. No. 6.79\n",
"==============================================================================\n",
"\n",
"Notes:\n",
"[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n"
]
}
],
"source": [
"import warnings\n",
"warnings.filterwarnings('ignore')\n",
"print(results_sm.summary())"
]
},
{
"cell_type": "markdown",
"id": "coordinated-warrior",
"metadata": {},
"source": [
"Now let's turn our attention to the `sklearn` library."
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "collective-static",
"metadata": {},
"outputs": [],
"source": [
"from sklearn import linear_model"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "broadband-terrace",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The regression coefficients from the sklearn package are: beta_0 = 0.666667 and beta_1 = 1.000000\n"
]
}
],
"source": [
"# build the least squares model\n",
"toyregr = linear_model.LinearRegression()\n",
"\n",
"# save regression info (parameters, etc) in results_skl\n",
"results = toyregr.fit(x_train, y_train)\n",
"\n",
"# pull the beta parameters out from results_skl\n",
"beta0_skl = toyregr.intercept_\n",
"beta1_skl = toyregr.coef_[0]\n",
"\n",
"print(\"The regression coefficients from the sklearn package are: beta_0 = {0:8.6f} and beta_1 = {1:8.6f}\".format(beta0_skl, beta1_skl))"
]
},
{
"cell_type": "markdown",
"id": "pregnant-dining",
"metadata": {},
"source": [
"Same results! We can try a real problem now."
]
},
{
"cell_type": "markdown",
"id": "fifteen-charles",
"metadata": {},
"source": [
"### The `scikit-learn` library and the shape of things"
]
},
{
"cell_type": "markdown",
"id": "wicked-allen",
"metadata": {},
"source": [
"Before diving into a \"real\" problem, let's discuss more of the details of `sklearn`.\n",
"\n",
"`Scikit-learn` is the main `Python` machine learning library. It consists of many learners which can learn models from data, as well as a lot of utility functions such as `train_test_split()`. \n",
"\n",
"Use the following to add the library into your code:\n",
"\n",
"```python\n",
"import sklearn \n",
"```\n",
"\n",
"In `scikit-learn`, an **estimator** is a Python object that implements the methods `fit(X, y)` and `predict(T)`\n",
"\n",
"Let's see the structure of `scikit-learn` needed to make these fits. `fit()` always takes two arguments:\n",
"```python\n",
"estimator.fit(Xtrain, ytrain)\n",
"```\n",
"We will consider one estimator in this lab: `LinearRegression`.\n",
"\n",
"It is very important to understand that `Xtrain` must be in the form of a **2x2 array** with each row corresponding to one sample, and each column corresponding to the feature values for that sample.\n",
"\n",
"`ytrain` on the other hand is a simple array of responses. These are continuous for regression problems."
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "stuck-leone",
"metadata": {},
"outputs": [],
"source": [
"#we load the dataset (be sure that this file is in the same folder with the j. notebook)\n",
"df = pd.read_csv('Salary_dataset.csv')"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "czech-island",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Unnamed: 0 YearsExperience Salary\n",
"0 0 1.2 39344.0\n",
"1 1 1.4 46206.0\n",
"2 2 1.6 37732.0\n",
"3 3 2.1 43526.0\n",
"4 4 2.3 39892.0\n"
]
}
],
"source": [
"print(df.head())"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "closing-prison",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Unnamed: 0 YearsExperience Salary\n",
"0 0 1.2 39344.0\n",
"1 1 1.4 46206.0\n",
"2 2 1.6 37732.0\n",
"3 3 2.1 43526.0\n",
"4 4 2.3 39892.0\n"
]
}
],
"source": [
"from sklearn.linear_model import LinearRegression\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"print(df.head())\n",
"X = np.array(df['YearsExperience'])\n",
"y = np.array(df['Salary'])\n",
"\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "greater-toolbox",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 5.4, 8. , 3. , 5.2, 3.3, 4.6, 8.3, 6.9, 1.4, 10.6, 3.1,\n",
" 2.3, 6. , 6.1, 3.8, 3.3, 9.1, 2.1, 1.2, 7.2, 5. , 4.1])"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X_train"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "improving-nickname",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 83089., 101303., 56643., 66030., 64446., 61112., 113813.,\n",
" 91739., 46206., 121873., 60151., 39892., 81364., 93941.,\n",
" 57190., 54446., 105583., 43526., 39344., 98274., 67939.,\n",
" 56958.])"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_train"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "extra-alaska",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Linear Regression-Training set score: 0.94\n",
"Linear Regression-Test set score: 0.98\n"
]
}
],
"source": [
"# rember to reshape the X list in order to have a two dimensional array. \n",
"# Since we have only one feature the reshape looks like below: \n",
"X_train = X_train.reshape(-1, 1)\n",
"X_test = X_test.reshape(-1, 1)\n",
"\n",
"# we perform the regression\n",
"lr = LinearRegression().fit(X_train, y_train)\n",
"\n",
"\n",
"print(f\"Linear Regression-Training set score: {lr.score(X_train, y_train):.2f}\")\n",
"print(f\"Linear Regression-Test set score: {lr.score(X_test, y_test):.2f}\")"
]
},
{
"cell_type": "markdown",
"id": "lesbian-tuning",
"metadata": {},
"source": [
"To fnd the coeficients from the formula $ax + b = y$ we have the following:"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "british-sherman",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"9379.710491946016 * x + 26049.720267542645 = y\n"
]
}
],
"source": [
"a = lr.coef_[0] # we ahve one feature with index 0\n",
"\n",
"b = lr.intercept_ # a scalar\n",
" \n",
"print(a, \"* x +\", b, \"= y\")"
]
},
{
"cell_type": "markdown",
"id": "declared-powder",
"metadata": {},
"source": [
"Now that we have the model let's make a prediction:"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "professional-passport",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([213643.93010646])"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lr.predict([[20]])"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "equivalent-remove",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"213643.93010646297"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a * 20 + b"
]
},
{
"cell_type": "markdown",
"id": "surprising-track",
"metadata": {},
"source": [
"In other words our model predicted that we get after 20 years a salary of 213643.9. "
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "interesting-chess",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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V69eeuutt9zSgcrKSt14441asmTJZceqqqr06aef6mc/+5k+/fRTrVy5UocPH9b48eMvazt16lSdOnXK+fXGG2+4HJ80aZL27duntWvXau3atdq3b5/S09Odx2trazVmzBhVVlZq+/btWrFihd5++23NmDHD2aa8vFwjRoxQfHy8du/ercWLF2vhwoVatGiRW+4FAKBlWbIxR8+tzJLN7rjqwFafHUeLdfeiLVqxK9dt5wQAtGzNmipZ589//rN++tOfKjo6Wq+99pqGDRvmns6YTFq1apXuvffeK7bZvXu3brvtNp04cUKJiYmSLoy43XTTTfrlL39Z73MOHDigvn37KiMjQwMHDpQkZWRkaPDgwTp48KCSkpL04YcfauzYscrLy1N8fLwkacWKFZoyZYqKiooUERGh119/XbNmzVJhYaEsFosk6cUXX9TixYt18uRJmUymJr1OpkoCQMu3YleunluZ5fHrzBzZW08N7+Xx6wAAfMMjUyXrfO9739Phw4c1btw4jRkzRt/61rd05MiRq+5sc5SVlclkMql9+/Yujy9fvlzR0dFKTk7WzJkzVVFR4Ty2c+dOWa1WZ2iTpEGDBslqtWrHjh3ONikpKc7QJkmjRo2SzWbTnj17nG1SU1Odoa2uTX5+vo4fP37FPttsNpWXl7t8AQBarrySKs1Zne2Vay1cd1h/383IGwC0dVcV3CTJMAyNHDlSjz32mFavXq2UlBTNmDHDJTC52/nz5/Xcc89p0qRJLmn0oYce0t/+9jdt3rxZP/vZz/T2229r4sSJzuMFBQWKibm8IldMTIwKCgqcbWJjY12Od+jQQcHBwQ22qfu+rk19XnjhBefaOqvVSoEXAGjhZq/Mkt2NUyMb8/y72ax5A4A2rlnbAfzud7/T7t27tXv3bh04cEABAQH6xje+oSeffFI33XSTli9frr59+2rVqlUaMGCAWztaU1OjBx98UA6HQ7/97W9djk2dOtX575SUFPXq1UsDBgzQp59+qltuuUWS6p3GaBiGy+NX06ZupmlD0yRnzZql6dOnO78vLy8nvAFAC5VTWKFtR0579Zp2h6HZK7O07NGBjTcGALRKzQpuv/jFLzRo0CBNnjxZgwYN0oABA1ymDX7/+9/XggULNGXKFO3fv99tnaypqdH999+vY8eOaePGjY2uC7vlllsUFBSknJwc3XLL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ffq0N7rc6rzzzjs6c+aMpkyZcsU2vNfdr6CgQJLqfT/XHbvS85r7HNTv/Pnzeu655zRp0iRFRERcsV2fPn20dOlSrV69Wn/729/Url073X777crJyfFib1u20aNHa/ny5dq4caNeffVV7d69W8OHD5fNZrvic3ivu9ef/vQnhYeHa+LEiQ224/3edPV9XmxNP9sDfXZloBmeeuopff7559q+fXuD7ZKSkpSUlOT8fvDgwcrLy9PChQt15513erqbrcLo0aOd/+7Xr58GDx6s66+/Xn/60580ffr0ep9z6aiQYRj1Po6m+cMf/qDRo0crPj7+im14r3tOfe/nxt7LV/McuKqpqdGDDz4oh8Oh3/72tw22HTRokEshjdtvv1233HKLFi9erF//+tee7mqr8MADDzj/nZKSogEDBqhr165as2ZNg0GC97r7/PGPf9RDDz3U6Fo13u9N19Dnxdbws50RN/i9p59+WqtXr9amTZvUpUuXZj9/0KBB/FXqGoSFhalfv35XvIdxcXGX/fWpqKhIgYGBioqK8kYXW5UTJ05ow4YNevTRR5v9XN7r16auemp97+dL/+p66fOa+xy4qqmp0f33369jx45p/fr1DY621cdsNuvWW2/l/X8NOnXqpK5duzZ4D3mvu8+2bdt06NChq/pZz/u9flf6vNiafrYT3OC3DMPQU089pZUrV2rjxo3q3r37VZ1n79696tSpk5t713bYbDYdOHDgivdw8ODBzgqIddatW6cBAwYoKCjIG11sVd566y3FxMRozJgxzX4u7/Vr0717d8XFxbm8n6urq7VlyxYNGTLkis+70v8DDT0H/1EX2nJycrRhw4ar+oOPYRjat28f7/9rUFxcrLy8vAbvIe919/nDH/6g/v3768Ybb2z2c3m/u2rs82Kr+tnum5ooQOMef/xxw2q1Gps3bzZOnTrl/KqqqnK2ee6554z09HTn96+99pqxatUq4/Dhw8b+/fuN5557zpBkvP322754CS3SjBkzjM2bNxtHjx41MjIyjLFjxxrh4eHG8ePHDcO4/J4fPXrUCA0NNX70ox8ZX3zxhfGHP/zBCAoKMv7v//7PVy+hxaqtrTUSExONn/zkJ5cd473uHhUVFcbevXuNvXv3GpKMRYsWGXv37nVWMHzxxRcNq9VqrFy50sjKyjK++93vGp06dTLKy8ud50hPTzeee+455/f/+te/jICAAOPFF180Dhw4YLz44otGYGCgkZGR4fXX548auuc1NTXG+PHjjS5duhj79u1z+Vlvs9mc57j0ns+dO9dYu3at8eWXXxp79+41/uu//ssIDAw0MjMzffES/VJD972iosKYMWOGsWPHDuPYsWPGpk2bjMGDBxudO3fmvX6NGvsZYxiGUVZWZoSGhhqvv/56vefg/d48Tfm82Fp+thPc4Lck1fv11ltvOdtMnjzZSE1NdX7/0ksvGddff73Rrl07o0OHDsYdd9xhrFmzxvudb8EeeOABo1OnTkZQUJARHx9vTJw40cjOznYev/SeG4ZhbN682bj55puN4OBgo1u3blf8ZYSGffTRR4Yk49ChQ5cd473uHnXbKFz6NXnyZMMwLpSNnjNnjhEXF2dYLBbjzjvvNLKyslzOkZqa6mxf55///KeRlJRkBAUFGX369CFAX6She37s2LEr/qzftGmT8xyX3vNnnnnGSExMNIKDg42OHTsaI0eONHbs2OH9F+fHGrrvVVVVxsiRI42OHTsaQUFBRmJiojF58mQjNzfX5Ry815uvsZ8xhmEYb7zxhhESEmKcOXOm3nPwfm+epnxebC0/202G8e8qAgAAAAAAv8QaNwAAAADwcwQ3AAAAAPBzBDcAAAAA8HMENwAAAADwcwQ3AAAAAPBzBDcAAAAA8HMENwAAAADwcwQ3AAAAAPBzBDcAAAAA8HMENwAAAADwcwQ3AAC86G9/+5vatWunr776yvnYo48+qm984xsqKyvzYc8AAP7MZBiG4etOAADQVhiGoZtuuklDhw7VkiVLNG/ePL355pvKyMhQ586dfd09AICfCvR1BwAAaEtMJpN+8Ytf6Nvf/rbi4+P1q1/9Stu2bSO0AQAaxIgbAAA+cMsttyg7O1vr1q1Tamqqr7sDAPBzrHEDAMDLPvroIx08eFC1tbWKjY31dXcAAC0AI24AAHjRp59+qmHDhuk3v/mNVqxYodDQUP3zn//0dbcAAH6ONW4AAHjJ8ePHNWbMGD333HNKT09X3759deutt2rPnj3q37+/r7sHAPBjjLgBAOAFJSUluv3223XnnXfqjTfecD4+YcIE2Ww2rV271oe9AwD4O4IbAAAAAPg5ipMAAAAAgJ8juAEAAACAnyO4AQAAAICfI7gBAAAAgJ8juAEAAACAnyO4AQAAAICfI7gBAAAAgJ8juAEAAACAnyO4AQAAAICfI7gBAAAAgJ8juAEAAACAnyO4AQAAAICf+/989/P43rBGFQAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"pred = lr.predict([[20]])\n",
"fig_scat, ax_scat = plt.subplots(1,1, figsize=(10,6))\n",
"\n",
"\n",
"x = X.T\n",
"\n",
"best_fit = b + a * (np.append(x, [20]))\n",
"\n",
"ax_scat.scatter(x, y, s=300, label='Training Data')\n",
"ax_scat.plot(np.append(x,[20]), best_fit, ls='--', label='Best Fit Line')\n",
"\n",
"ax_scat.plot([20],pred, \"ys\", label=\"LinearRegression\")\n",
"ax_scat.set_xlabel(r'$x$')\n",
"ax_scat.set_ylabel(r'$y$');\n"
]
},
{
"cell_type": "markdown",
"id": "numerous-spray",
"metadata": {},
"source": [
"***Exercise 2***\n",
"\n",
"Download from https://www.kaggle.com/ the regression dataset: Student Study Hours. Create a model and make 3 predictions. Make some nice graphics to depict the model (training set, test set, predictions). "
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "centered-python",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"10.013973783379312 * x + 1.4392455960044117 = y\n",
"Linear Regression-Training set score: 0.9853328028\n",
"Linear Regression-Test set score: 0.9648473420\n"
]
},
{
"data": {
"image/png": "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ipGp02w2m1q3bm11GQ2Kw+Gw/P8oDQnvd93jPa97vOd1j/e8bvF+1z3e87oXLu95sBGpMjSgAAAAAIBqIEwBAAAAQDUQplDn7Ha7pk+fLrvdbnUpDQLvd93jPa97vOd1j/e8bvF+1z3e87oXie85DSgAAAAAoBoYmQIAAACAaiBMAQAAAEA1EKYAAAAAoBoIUwAAAABQDYQp1KjZs2friiuuUEJCgpKTk3XTTTdp165dQZ+zatUqGYZR4Wvnzp11VHXkmjFjRoX3zel0Bn3O6tWr1aNHD8XFxemCCy7Qq6++WkfV1g/t2rXz+3mdNGmS3+v5fFfdmjVrNHLkSKWlpckwDL333nvlzpumqRkzZigtLU2NGjVS//79tW3btkrv+84776hLly6y2+3q0qWL3n333Vp6BZEn2HteXFyshx9+WN27d1d8fLzS0tJ055136vDhw0HvOW/ePL+f/cLCwlp+NeGvss/4+PHjK7xvvXv3rvS+fMYDq+w99/dZNQxDv//97wPek894YKH8PlhffpYTplCjVq9erUmTJmn9+vVaunSpSkpKNGTIEBUUFFT63F27dikrK8v31aFDhzqoOPJ17dq13Pu2ZcuWgNdmZmZq+PDhuuaaa/TFF1/okUce0f3336933nmnDiuObBs3biz3fi9dulSS9KMf/Sjo8/h8h66goECXXHKJXn75Zb/nn3nmGT333HN6+eWXtXHjRjmdTg0ePFh5eXkB77lu3TqNGTNGd9xxh7766ivdcccduuWWW7Rhw4baehkRJdh7fvLkSW3evFmPPvqoNm/erIULF2r37t0aNWpUpfd1OBzlPvdZWVmKi4urjZcQUSr7jEvS9ddfX+59W7x4cdB78hkPrrL3/NzP6d///ncZhqGbb7456H35jPsXyu+D9eZnuQnUopycHFOSuXr16oDXrFy50pRkHj9+vO4KqyemT59uXnLJJSFf/9BDD5mdO3cud2zixIlm7969a7iyhuOXv/yl2b59e9Pj8fg9z+f7/Egy3333Xd9jj8djOp1O86mnnvIdKywsNBMTE81XX3014H1uueUW8/rrry93bOjQoeatt95a4zVHunPfc38+++wzU5J54MCBgNfMnTvXTExMrNni6iF/7/e4cePMG2+8sUr34TMeulA+4zfeeKN53XXXBb2Gz3jozv19sD79LGdkCrUqNzdX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",
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#your code here\n",
"from sklearn.linear_model import LinearRegression\n",
"from sklearn.model_selection import train_test_split\n",
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"\n",
"df = pd.read_csv('score_updated.csv')\n",
"\n",
"X = np.array(df['Hours'])\n",
"y = np.array(df['Scores'])\n",
"\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)\n",
"\n",
"X_train = X_train.reshape(-1, 1)\n",
"X_test = X_test.reshape(-1, 1)\n",
"\n",
"# we perform the regression\n",
"lr = LinearRegression().fit(X_train, y_train)\n",
"a = lr.coef_[0]\n",
"b = lr.intercept_ \n",
"print(a, \"* x +\", b, \"= y\")\n",
"print(f\"Linear Regression-Training set score: {lr.score(X_train, y_train):.10f}\")\n",
"print(f\"Linear Regression-Test set score: {lr.score(X_test, y_test):.10f}\")\n",
"\n",
"pred1 = lr.predict([[9.25]])\n",
"pred2 = lr.predict([[5.5]])\n",
"pred3 = lr.predict([[6.75]])\n",
"\n",
"fig_scat, ax_scat = plt.subplots(1,1, figsize=(10,6))\n",
"\n",
"\n",
"x = X.T\n",
"\n",
"best_fit = b + a * (np.append(x, [20]))\n",
"\n",
"ax_scat.scatter(X_train.flatten().T, y_train, s=30, label='Training Data')\n",
"ax_scat.scatter(X_test.flatten().T, y_test, s=30, label='Training Data')\n",
"\n",
"\n",
"ax_scat.plot(np.append(x,[20]), best_fit, ls='--', label='Best Fit Line')\n",
"\n",
"ax_scat.plot([9.25],pred1, \"ys\", label=\"LinearRegression\")\n",
"ax_scat.plot([5.5],pred2, \"ys\", label=\"LinearRegression\")\n",
"ax_scat.plot([6.75],pred3, \"ys\", label=\"LinearRegression\")\n",
"\n",
"ax_scat.set_xlabel(r'$x$')\n",
"ax_scat.set_ylabel(r'$y$');\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "printable-breast",
"metadata": {},
"source": [
"# Section 3. Regularization\n",
"\n",
"- restricting a model to avoid overfitting by shrinking the coefficient estimates to zero. \n",
"\n",
"To avoid overfitting we control the models complexity by adding a penalty to the models loss function:\n",
"\n",
"$$\\text{ Regularization} = \\text{Loss Function} + \\text{Penalty} $$\n",
"\n",
"There are three commonly used regularization techniques to control the complexity of machine learning models, as follows:\n",
"\n",
"* L2 regularization\n",
"* L1 regularization\n",
"* Elastic Net\n",
"\n",
"\n",
"## L2 regularisation\n",
"\n",
"A *ridge* regression -- a regularization term is added to the cost function of the linear regression, which keeps the magnitude of the models weights (coefficients) as small as possible. The L2 regularization technique tries to keep the models weights close to zero, but not zero, which means each feature should have a low impact on the output while the models accuracy should be as high as possible.\n",
" \n",
" $$ \\text{Ridge Regression Cost Function} = \\text{Loss Function} + \\frac{1}{2}\\lambda \\sum_{j=1}^m \\omega_j^2$$\n",
"\n",
"Where $\\lambda$ controls the strength of regularization, and $\\omega$ are the models weights (coefficients).\n",
"\n",
"By increasing $\\lambda$, the model becomes flattered and underfit. On the other hand, by decreasing $\\lambda$, the model becomes more overfit, and with $\\lambda = 0$, the regularization term will be eliminated."
]
},
{
"cell_type": "code",
"execution_count": 49,
"id": "acknowledged-agenda",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Ridge Regression-Training set score: 0.94\n",
"Ridge Regression-Test set score: 0.98\n"
]
}
],
"source": [
"# rember to reshape the X list in order to have a two dimensional array. \n",
"# Since we have only one feature the reshape looks like below: \n",
"X_train = X_train.reshape(-1, 1)\n",
"X_test = X_test.reshape(-1, 1)\n",
"\n",
"from sklearn.linear_model import Ridge\n",
"\n",
"ridge = Ridge(alpha=0.7).fit(X_train, y_train)\n",
"\n",
"print(f\"Ridge Regression-Training set score: {ridge.score(X_train, y_train):.2f}\")\n",
"print(f\"Ridge Regression-Test set score: {ridge.score(X_test, y_test):.2f}\")"
]
},
{
"cell_type": "markdown",
"id": "indie-copper",
"metadata": {},
"source": [
"## L1 Regularization\n",
"\n",
"Least Absolute Shrinkage and Selection Operator (lasso) regression is an alternative to ridge for regularizing linear regression. Lasso regression also adds a penalty term to the cost function, but slightly different, called $L1$ regularization. $L1$ regularization makes some coefficients zero, meaning the model will ignore those features. Ignoring the least important features helps emphasize the models essential features.\n",
"\n",
"$$ \\text{Lasso Regrestion Cost Function} = \\text{Loss Function} + r \\lambda \\sum_{j=1}^m |wj|$$\n",
"\n",
"Where $\\lambda$ controls the strength of regularization, and $\\omega$ are the models weights (coefficients).\n",
"\n",
"Lasso regression automatically performs feature selection by eliminating the least important features."
]
},
{
"cell_type": "code",
"execution_count": 50,
"id": "behavioral-thailand",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Lasso Regression-Training set score: 0.94\n",
"Lasso Regression-Test set score: 0.98\n"
]
}
],
"source": [
"# rember to reshape the X list in order to have a two dimensional array. \n",
"# Since we have only one feature the reshape looks like below: \n",
"X_train = X_train.reshape(-1, 1)\n",
"X_test = X_test.reshape(-1, 1)\n",
"\n",
"from sklearn.linear_model import Lasso\n",
"\n",
"lasso = Lasso(alpha=1.0).fit(X_train, y_train)\n",
"\n",
"print(f\"Lasso Regression-Training set score: {lasso.score(X_train, y_train):.2f}\")\n",
"print(f\"Lasso Regression-Test set score: {lasso.score(X_test, y_test):.2f}\")"
]
},
{
"cell_type": "markdown",
"id": "extraordinary-sauce",
"metadata": {},
"source": [
"## Elastic Net\n",
"The Elastic Net is a regularized regression technique combining ridge and lassos regularization terms. The \n",
" parameter controls the combination ratio. When \n",
", the L2 term will be eliminated, and when \n",
", the L1 term will be removed.\n",
"\n",
"$$\\text{Elastic Net Cost Function} = \\text{Loss Function} + r \\lambda \\sum_{j=1}^m |wj|+ \\dfrac{(1-r)}{2} \\lambda\\sum_{j=1}^m w_j^2$$\n",
"\n",
"Although combining the penalties of lasso and ridge usually works better than only using one of the regularization techniques, adjusting two parameters, \n",
" and \n",
", is a little tricky."
]
},
{
"cell_type": "code",
"execution_count": 51,
"id": "informative-reputation",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Elastic Net-Training set score: 0.94\n",
"Elastic Net-Test set score: 0.98\n"
]
}
],
"source": [
"# rember to reshape the X list in order to have a two dimensional array. \n",
"# Since we have only one feature the reshape looks like below: \n",
"X_train = X_train.reshape(-1, 1)\n",
"X_test = X_test.reshape(-1, 1)\n",
"\n",
"from sklearn.linear_model import ElasticNet\n",
"\n",
"elastic_net = ElasticNet(alpha=0.01, l1_ratio=0.01).fit(X_train, y_train)\n",
"\n",
"print(f\"Elastic Net-Training set score: {elastic_net.score(X_train, y_train):.2f}\")\n",
"print(f\"Elastic Net-Test set score: {elastic_net.score(X_test, y_test):.2f}\")"
]
},
{
"cell_type": "markdown",
"id": "diverse-studio",
"metadata": {},
"source": [
"***Exercise 3***\n",
"\n",
"For your build previous model perform all three regularizations presented here. "
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "loved-light",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Ridge Regression-Training set score: 0.9853305493\n",
"Ridge Regression-Test set score: 0.9650085396\n",
"Lasso Regression-Training set score: 0.9850943391\n",
"Lasso Regression-Test set score: 0.9662654100\n",
"Elastic Net-Training set score: 0.9853304615\n",
"Elastic Net-Test set score: 0.9650115988\n"
]
}
],
"source": [
"#your code here\n",
"\n",
"from sklearn.linear_model import Ridge\n",
"from sklearn.linear_model import Lasso\n",
"from sklearn.linear_model import ElasticNet\n",
"\n",
"ridge = Ridge(alpha=0.7).fit(X_train, y_train)\n",
"lasso = Lasso(alpha=1.0).fit(X_train, y_train)\n",
"elastic_net = ElasticNet(alpha=0.01, l1_ratio=0.01).fit(X_train, y_train)\n",
"\n",
"print(f\"Ridge Regression-Training set score: {ridge.score(X_train, y_train):.10f}\")\n",
"print(f\"Ridge Regression-Test set score: {ridge.score(X_test, y_test):.10f}\")\n",
"\n",
"print(f\"Lasso Regression-Training set score: {lasso.score(X_train, y_train):.10f}\")\n",
"print(f\"Lasso Regression-Test set score: {lasso.score(X_test, y_test):.10f}\")\n",
"\n",
"print(f\"Elastic Net-Training set score: {elastic_net.score(X_train, y_train):.10f}\")\n",
"print(f\"Elastic Net-Test set score: {elastic_net.score(X_test, y_test):.10f}\")"
]
}
],
"metadata": {
"kernel_info": {
"name": "python"
},
"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.12.2"
},
"nteract": {
"version": "nteract-front-end@1.0.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}