\n",
" ARTIFICIAL INTELLIGENCE (E016350A) \n",
"ALEKSANDRA PIZURICA \n",
"GHENT UNIVERSITY \n",
"AY 2024/2025 \n",
"Assistant: Nicolas Vercheval\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Linear regression"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A linear regression model predicts the output variable (target variable) $y$ by fitting a linear equation to observed data $x_1, x_2, ..., x_d$:$$y = w_0 + w_1x_1 + w_2x_2 + \\ldots + w_dx_d$$ \n",
"\n",
"The task is to find the coefficients $w_0, w_1,..., w_d$ such that this linear model best fits the data. In this model, the elements of the input vector $x_1, x_2, ..., x_d$ are also called the input attributes, and they constitute independent variables, while the target variable $y$ is the dependent variable. In statistics, the input vector $\\textbf{x}$ is also called the vector of regressors or explanatory variables and $y$ is also referred to as the response variable."
]
},
{
"attachments": {
"linear_regression.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The example aims to introduce the basic concepts and APIs of the library itself, which will be used later."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# !pip install scikit-learn\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt \n",
"import seaborn as sns\n",
"from sklearn import linear_model\n",
"from sklearn import model_selection\n",
"from sklearn import metrics"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.random.seed(7)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Linear Regression with One Variable\n",
"We start from the simplest case of univariate linear regression."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Making a synthetic dataset"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" \n",
"We work with synthetic dataset. The values of the attributes will be divisions of the equidistant grid on the interval [1, 5], and the values of the objective function will be generated by the formula $ y = 11\\sin (x) $ with the addition of noise."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`N` is a variable that will represent the size of the data set."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"N = 100"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we generate values for the `x` attribute and show a dependency graph with the target variable `y`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# extract equally spaced points from domain [1, 5] X\n",
"x = np.linspace(1, 5, N)\n",
"\n",
"# create a matrix by adding a 1 vector\n",
"X = np.vstack([np.ones_like(x), x]).T\n",
"\n",
"X.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y = 11 * np.sin(x) + 1.5 * np.random.randn(N)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ax = sns.scatterplot(x=x, y=y)\n",
"ax.set(xlabel='x', title='Scatter plot of training data')\n",
"ax.set_ylabel('y', rotation=0)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating the model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Our hypothesis is:$$h_\\textbf{w}(x) = w_0 + w_1x$$\n",
"We want to find the best values for the parameters $w_0$ and $w_1$ given our training data.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Gradient descent\n",
"We implement gradient descent ourself to get familiar with the concept.\n",
"We want to minimize the Mean Square Error (MSE):\n",
"\n",
"$$ \\textit{TrainLoss}(\\textbf{w}) = \\frac{1}{N} \\sum_{i=1}^N (y^{(i)} - h_\\textbf{w}(x^{(i)}))^2.$$\n",
"\n",
"Its partial derivatives with respect to the two coefficients are:\n",
"$$\\frac{\\partial}{\\partial{w_0}}\\textit{TrainLoss}(\\textbf{w})=-\\frac{2}{N}\\sum_{i=1}^Ny^{(i)}-h_{\\textbf{w}}(x^{(i)}), \\quad\n",
"\\frac{\\partial}{\\partial{w_1}}\\textit{TrainLoss}(\\textbf{w})=-\\frac{2}{N}\\sum_{i=1}^N(y^{(i)}-h_{\\textbf{w}}(x^{(i)}))x^{(i)}.$$\n",
"\n",
"\n",
"We use the batch gradient descent algorithm. In batch gradient descent, each iteration simultaneously updates $w_j$ for all $j$:\n",
"\n",
"$$ w_0:= w_0 + \\alpha \\frac{1}{N} \\sum_{i=1}^N y^{(i)} - h_\\textbf{w}(x^{(i)}), \\quad\n",
" w_1 := w_1 + \\alpha \\frac{1}{N} \\sum_{i=1}^N (y^{(i)} - h_\\textbf{w}(x^{(i)}))x^{(i)}.$$ \n",
" \n",
"Note that the factor of two has been absorbed into $\\alpha$.\n",
"\n",
"With each step of gradient descent, your parameters $w_j$ come closer to the optimal values that will achieve the lowest cost $\\textit{TrainLoss}(\\textbf{w})$."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"iterations = 2000\n",
"alpha = 0.02\n",
"w = np.zeros((X.shape[1], 1))\n",
"\n",
"Y = y.reshape(-1,1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Exercise: Implement Gradient Descent for MSE\n",
"\n",
"Implement the function `batch_gradient_descent_mse_update` that updates the weight vector $\\textbf{w}$ following the gradient descent procedure for univariate linear regression using the Mean Squared Error (MSE) loss, as described above.\n",
"\n",
"The function takes the following arguments:\n",
"- `X`: A 2D array with dimensions $(N, 2)$, where the first column contains all ones, and the second column represents the $x$-coordinates of the training data.\n",
"- `Y`: A 2D array with dimensions $(N, 1)$, containing the target variable $y$ of the training data.\n",
"- `w`: A 2D array with dimensions $(2, 1)$, containing the weights $w_0$ and $w_1$, respectively.\n",
"- `alpha`: A scalar representing the learning rate $\\alpha$.\n",
"\n",
"Implement the following steps:\n",
"1. Compute the predictions $h_\\textbf{w}(x) = w_0 + w_1 x$. Use the [`numpy.dot`](https://numpy.org/doc/stable/reference/generated/numpy.dot.html) method for this.\n",
"2. Compute the difference between the true target variables and the predictions.\n",
"3. Compute the partial derivatives with respect to $w_0$ and $w_1$ (ignore the factor of 2, as it is included in the $\\alpha$ parameter).\n",
"4. Update the weights $w_0$ and $w_1$ using $\\alpha$ and the partial derivatives.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def batch_gradient_descent_mse_update(X, Y, w, alpha):\n",
" N = Y.shape[0]\n",
" \n",
" # Your code here...\n",
" \n",
" return w"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"w_hist = []\n",
"# batch gradient descent\n",
"for _ in range(iterations):\n",
" w = batch_gradient_descent_mse_update(X, Y, w, alpha)\n",
" w_hist.append(w)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ax = sns.scatterplot(x=x, y=y)\n",
"plt.plot(x, X.dot(w), color='r')\n",
"ax.set(xlabel='x', title='Scatter plot of training data')\n",
"ax.set_ylabel('y', rotation=0)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Visualizing the cost function\n",
"We vizualize the cost function $\\textit{TrainLoss}(\\textbf{w})$ as a function of the two weights.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# create a grid around the final values\n",
"w0_final = w[0].item()\n",
"w1_final = w[1].item()\n",
"w0_range = np.arange(-1 + w0_final, 1 + w0_final, 0.01)\n",
"w1_range = np.arange(-1 + w1_final, 1 + w1_final, 0.01)\n",
"w0_values, w1_values = np.meshgrid(w0_range, w1_range)\n",
"h_values = np.tensordot(x, w1_values, axes = 0) + w0_values[None, :]\n",
"\n",
"# compute square error\n",
"L = np.mean((Y.reshape(-1, 1, 1) - h_values) ** 2, 0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ax = plt.contour(w0_values, w1_values, L, levels=np.logspace(-5,5,100))\n",
"for iter in (1249, 1499, 1749, 1999):\n",
" w0, w1 = w_hist[iter]\n",
" plt.plot(w0, w1, marker='x', color='r');\n",
"plt.xlabel(r'$w_0$', rotation=0);\n",
"plt.ylabel(r'$w_1$');\n",
"plt.title('Contour, showing minimum');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## scikit-learn implementation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[scikit-learn](https://scikit-learn.org/) is a Python library specifically for machine learning tasks. `linear_model` is a module that provides methods for working with linear models such as linear regression, linear regression with regularizations, logistic regression and others. `model_selection` is a module that has functionalities such as dividing a data set into training and testing sets, cross-validation, and others. The `metrics` module provides various metrics that can be used in evaluation.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `train_test_split` method divides a dataset into training and test datasets. The ratio of these sets is determined by the parameters `train_size` or` test_size`. These parameters are expressed by values from 0 to 1 and represent the percentage of the specified set. For example, assigning `test_size = 0.2` indicates that 20% of the data will be used for testing and 80% for training. As this division into training and testing sets is random, the `random_state` parameter can be used to control the division. This type of control is critical for the reproduction of experiments."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Exercise: Perform the train-test split\n",
"\n",
"Use a train-test split of size 3 : 2. Set the `random_state` to 7."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# remove the 1 vector from the matrix\n",
"X_sklearn = X[:, 1:2]\n",
"\n",
"X_train, X_test, y_train, y_test = model_selection.train_test_split(\n",
" # Your code here...\n",
" \n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We use the `LinearRegression` method to create a linear regression model. By default, the free term $w_0 $ is associated with the model. If it is necessary to omit it, the parameter `fit_intercept` of the constructor function can be set to `False`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model = linear_model.LinearRegression()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `fit` function is used to train the model. Training is done over a training set."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.fit(X_train, y_train)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"After training, we can read the model coefficients and the free member's value via the parameters `coef_` and` intercept_`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"type(model.coef_)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.coef_.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"w1 = model.coef_[0]\n",
"print(w1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"type(model.intercept_)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.intercept_.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"w0 = model.intercept_\n",
"print(w0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We draw a graph of the model obtained in this way."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ax = sns.scatterplot(x=x, y=y)\n",
"plt.plot(x, w0 + x * w1, color='r')\n",
"ax.set(xlabel='x', title='Scatter plot of training data')\n",
"ax.set_ylabel('y', rotation=0)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We show where the best parameters found by sklearn are in the previous countour plot. \n",
"\n",
"Why is it not in the minimum?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ax = plt.contour(w0_values, w1_values, L, levels=np.logspace(-5,5,100))\n",
"plt.plot(w0, w1, marker='x', color='r');\n",
"plt.xlabel(r'$w_0$');\n",
"plt.ylabel(r'$w_1$', rotation=0);\n",
"plt.title('Contour, showing minimum');"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Predicting values by using the learned model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `predict` function can be used to predict the value of the target variable over new instances. For individual predictions, its argument should be in the form of a matrix."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.predict(np.array([[23]])).item()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Model evaluation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To evaluate regression models, we can use the coefficient of determination, the standard error, or the mean absolute error. The root mean square and the mean absolute error are expressed in terms of the unit size of the target variable, while the value of the coefficient of determination is normalized. To compute each value, we need the target variable and the model prediction for the same set of instances."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Coefficient of determination $R^2$\n",
" \n",
"$$R^2 = 1 - \\frac{\\sum_i{(y^{(i)}-\\hat{y}^{(i)})^2}}{\\sum_i{(y^{(i)} - \\bar{y})^2}}$$\n",
"\n",
"The values of the coefficient of determination are from the interval ${(-\\infty, 1]}$ and the values closer to $1$ denote the \"better\" models."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def r_squared(y_true, y_predicted):\n",
" u = ((y_true - y_predicted)**2).sum()\n",
" \n",
" y_mean = y_true.mean(); \n",
" v = ((y_true - y_mean)**2).sum()\n",
" \n",
" return 1 - u/v"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Root mean squared error $RMSE$: \n",
" \n",
"$$MSE = \\sqrt{\\frac{1}{n} \\sum_i{(y^{(i)}-\\hat{y}^{(i)})^2}}$$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def root_mean_squared_error(y_true, y_predicted):\n",
" return np.sqrt(((y_true - y_predicted)**2).mean());"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Mean absolute error $MAE$: \n",
" \n",
"$$MAE = \\frac{1}{n} \\sum_i{|y^{(i)}-\\hat{y}^{(i)}|}$$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def mean_absolute_error(y_true, y_predicted):\n",
" return abs(y_true - y_predicted).mean();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will generate predictions of the training set model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y_predicted = model.predict(X_test)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"r_squared(y_test, y_predicted)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"root_mean_squared_error(y_test, y_predicted)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mean_absolute_error(y_test, y_predicted)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Equivalents of these functions, with some additional settings, are also available through the `metrics` package. The mean square error is calculated by the `mean_squared_error` function, and the coefficient of determination by the` r2_score` function."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"r2 = metrics.r2_score(y_test, y_predicted)\n",
"r2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another function that can calculate the value of the coefficient of determination is the `score` method of the model itself."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.score(X_test, y_test)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mse = metrics.mean_squared_error(y_test, y_predicted)\n",
"np.sqrt(mse)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mae = metrics.mean_absolute_error(y_test, y_predicted)\n",
"mae"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}