Skip to content

Commit 90f328a

Browse files
author
Ragav Venkatesan
committed
Ready for lec 1
1 parent 07734aa commit 90f328a

File tree

3 files changed

+77
-17
lines changed

3 files changed

+77
-17
lines changed

workshop/lec1/analytical_solution.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,28 @@ def plot(self, data = None):
6969
plt.plot(grid, predictions, 'r')
7070
plt.show()
7171

72+
class ridge_regressor(regressor):
73+
"""
74+
This is a sample class for lecture 1.
75+
76+
Args:
77+
data: Is a tuple, ``(x,y)``
78+
``x`` is a two or one dimensional ndarray ordered such that axis 0 is independent
79+
data and data is spread along axis 1. If the array had only one dimension, it implies
80+
that data is 1D.
81+
``y`` is a 1D ndarray it will be of the same length as axis 0 or x.
82+
alpha: Co-efficient for L2 regularizer.
83+
84+
"""
85+
def __init__(self, data, alpha = 0.0001):
86+
self.x, self.y = data
87+
# Here is where your training and all the other magic should happen.
88+
# Once trained you should have these parameters trained.
89+
x = np.concatenate((np.ones((self.x.shape[0],1)), self.x), axis = 1)
90+
w = np.dot(np.linalg.pinv(np.dot(x.T,x) + alpha*np.eye(x.shape[1])), np.dot(x.T,self.y))
91+
alpha
92+
self.w = w[1:]
93+
self.b = w[0]
94+
7295
if __name__ == '__main__':
7396
pass
97.8 KB
Loading

workshop/lec1/lec1.ipynb

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"\n",
1111
"## Supervised Learning.\n",
1212
"\n",
13-
"Supervised learning is the task of arriving at a mathematical mapping function from the co-variate space to the variate space using a labeled training dataset. The training dataset is of a set of co-variate - variate sample mapping. In supervised learning, each example is a pair consisting of an input object (typically a vector) and a desired output value (also called the supervisory signal). Colloquially, various names are used for the co-variates and variates, the most common ones being 'features' and 'lables'.\n",
13+
"**Supervised learning is the task of arriving at a mathematical mapping function from the co-variate space to the variate space using a labeled training dataset.** The training dataset is of a set of co-variate - variate sample mapping. In supervised learning, each example is a pair consisting of an input object (typically a vector) and a desired output value (also called the supervisory signal). Colloquially, various names are used for the co-variates and variates, the most common ones being 'features' and 'lables'.\n",
1414
"\n",
1515
"Let us create a relatable and lower-dimensional dataset to study supervised learning. Assume that you are a human resource manager at Amazon and that you are planning to make strategic human resource expansions in your department. While interviewing candidates, you would like to know antecedently how much that candidate’s pay scale is likely to be. In today’s market where data scientists are in strong demand, most candidates have a free-market value they are predisposed to expect. As a data scientist yourself, and following with Amazon's tradition of relenetlessly relying on data, you could use machine learning to model a future candidate’s potential compensation. Using this knowledge, you can negotiate during the interview. \n",
1616
"\n",
@@ -22,15 +22,13 @@
2222
" \\bf{x_n} & y_n \\end{bmatrix},$$\n",
2323
"where, $\\bf{x_i} \\in \\mathbb{R}^d$ is a d-dimensional (vector) sample where each sample represents an existing employee and each dimesnion of this ample corresponds to an attribute of the employee that is related to their compensation and $y_i \\in \\mathbb{R}^1$ is the salary of the respective employee. \n",
2424
"\n",
25-
"In this dataset, to *learn* is to establish a mapping between the features and the labels. To model the compensation of the employees, consider for now that, $x_i \\in \\mathbb{R}^1$, is a one-dimensional feature, perhaps the number of years of experience a candidate has in the field. The provided code has a data simulator that will generate some syntehtic data to mimic this scenario. The data might look like something like what is generated by the code-block below."
25+
"In this dataset, **to *learn* is to establish a mapping between the features and the labels.** To model the compensation of the employees, consider for now that, $x_i \\in \\mathbb{R}^1$, is a one-dimensional feature, perhaps the number of years of experience a candidate has in the field. The provided code has a data simulator that will generate some syntehtic data to mimic this scenario. The data might look like something like what is generated by the code-block below."
2626
]
2727
},
2828
{
2929
"cell_type": "code",
3030
"execution_count": null,
31-
"metadata": {
32-
"collapsed": true
33-
},
31+
"metadata": {},
3432
"outputs": [],
3533
"source": [
3634
"from dataset import dataset_generator\n",
@@ -49,25 +47,25 @@
4947
"\n",
5048
"## Least Squares Linear Regression.\n",
5149
"\n",
52-
"Let us posit that the experience of the candidates and their compensation are linearly related. What this means is that we are making a decision that the relationship between the candidates’ experience and the salaries is captured by a straight line. With this assumption, we have are limiting the architecture of our problem to linear models and converted our problem into a linear regression problem. Essentially, if our data is $x \\in \\mathbb{R}^1$, then our prediction is, \n",
50+
"Let us posit that the experience of the candidates and their compensation are **linearly related**. What this means is that we are making a decision that the relationship between the candidates’ experience and the salaries is captured by a straight line. With this assumption, we have are limiting the architecture of our problem to linear models and converted our problem into a linear regression problem. Essentially, if our data is $x \\in \\mathbb{R}^1$, then our prediction is, \n",
5351
"$$ \\hat{y} = w_1x + b.$$\n",
5452
"If $\\bf{x} \\in \\mathbb{R}^d $, then \n",
5553
"$$ \\hat{y} = \\sum_{i=1}^d w_ix^i + b.$$\n",
5654
"\n",
5755
"To know how good our predictions are we need some metric to measure our errors. Consider the root-mean-squared error or the RMSE,\n",
5856
"$$ e_i(\\bf{w}) = \\vert \\vert \\hat{y_i} - y_i \\vert \\vert_2, $$\n",
59-
"which, will tell us how *far* away our prediction $\\hat{y_i}$ is from the actual value $y_i, \\forall i \\in [0,n]$ in the Euclidean sense. For our entire dataset, we can have a cumulative error defined as,\n",
57+
"which, will tell us **how *far* away our prediction $\\hat{y_i}$ is from the actual value $y_i, \\forall i \\in [0,n]$ in the Euclidean sense**. For our entire dataset, we can have a cumulative error defined as,\n",
6058
"$$e(\\bf{w}) = \\sum_{i=1}^n \\vert \\vert y_i - \\hat{y_i} \\vert \\vert_2,$$\n",
6159
"or,\n",
6260
"$$ e(\\bf{w}) = \\sum_{i=1}^n \\vert \\vert y_i - W^TX + b \\vert \\vert_2.$$\n",
6361
"\n",
64-
"This error is often referred to as the objective. This is what we want to minimize. We want those parameters $w$, that will get us to be as low as possible $e(w)$. Formally, we want,\n",
62+
"This error is often referred to as the objective. This is what we want to **minimize**. We want those parameters $w$, that will get us to be as low as possible $e(w)$. Formally, we want,\n",
6563
"$$ \\hat{w} = \\arg\\min_w e(w). $$\n",
6664
"We can derive a solution for this optimization problem analytically.\n",
6765
"$$ e(w) = \\frac{1}{2}(y-w^TX)^T(y-w^TX),$$\n",
6866
"$$\\frac{\\partial e}{\\partial w} = -X^Tt + X^TXw,$$\n",
6967
"equating this to zero to obtain minima we get,\n",
70-
"$$X^TXw = X^TX,$$\n",
68+
"$$X^TXw = X^Ty,$$\n",
7169
"$$\\hat{w} = (X^TX)^{-1}X^Ty.$$\n",
7270
"$\\hat{w}$ is will give us the minimum most error possible and this solution is called the analytical solution.\n",
7371
"\n",
@@ -93,7 +91,7 @@
9391
"from analytical_solution import regressor\n",
9492
"data_train = dataset.query_data(samples = 40) # Create a training dataset. \n",
9593
"r = regressor(data_train) # This call should return a regressor object that is fully trained.\n",
96-
"params = r.get_params() # This call should return parameters of the model that are \n",
94+
"reg_params = r.get_params() # This call should return parameters of the model that are \n",
9795
" # fully trained."
9896
]
9997
},
@@ -107,9 +105,7 @@
107105
{
108106
"cell_type": "code",
109107
"execution_count": null,
110-
"metadata": {
111-
"collapsed": true
112-
},
108+
"metadata": {},
113109
"outputs": [],
114110
"source": [
115111
"from errors import rmse\n",
@@ -140,15 +136,56 @@
140136
"cell_type": "markdown",
141137
"metadata": {},
142138
"source": [
143-
"We can clearly see here that our simple model works pretty fine. Although for this simple linear model an analytical solution does exist, we find that for more complex problem structures we have to rely on some optimization procedures that are described in the later lectures."
139+
"We can clearly see here that our simple model works pretty fine. Although for this simple linear model an analytical solution does exist, we find that for more complex problem structures we have to rely on some optimization procedures that are described in the later lectures.\n",
140+
"\n",
141+
"## Ridge Regression.\n",
142+
"\n",
143+
"We used a ``numpy.linalg.pinv`` to solve this problem. We did this because **not always is $x^Tx$ invertible**. What can we do in our analytical solution to make this invertible? One thing that can be done to make this solution more stable is to ensure that the diagonal elements of $w^Tw$ behave nicely. Consider the following analytical solution for $\\hat{w}$,\n",
144+
"$$\\hat{w} = (X^TX + \\alpha_2I)^{-1}X^Ty.$$\n",
145+
"In this solution, you can be quite sure that this will give a reasonablly good solution. What is this a solution for? \n",
146+
"Consider the error function,\n",
147+
"$$e(w)=(y-w^Tx)^T(y-w^Tx) + \\alpha_2wTw.$$\n",
148+
"Now,\n",
149+
"$$\\frac{\\partial e}{\\partial w} = \\frac{\\partial e}{\\partial w} ( w^Tx^Txw - 2y^Txw + y^Ty + \\alpha_2w^Tw),$$\n",
150+
"$$ = 2x^Txw - 2x^Ty + 2\\alpha_2I,$$\n",
151+
"$$ = 2(x^Tx + \\alpha_2I)w - 2X^Ty,$$\n",
152+
"which, when equated to zero to obtain the minima we get,\n",
153+
"$$(x^Tx + \\alpha_2I)w = X^Ty,$$\n",
154+
"$$\\hat{w} = (X^TX + \\alpha_2I)^{-1}X^Ty.$$"
155+
]
156+
},
157+
{
158+
"cell_type": "code",
159+
"execution_count": null,
160+
"metadata": {},
161+
"outputs": [],
162+
"source": [
163+
"from analytical_solution import ridge_regressor\n",
164+
"data_train = dataset.query_data(samples = 40) # Create a training dataset. \n",
165+
"r = ridge_regressor(data_train, alpha = 0.0001) # This call should return a regressor object that is fully trained.\n",
166+
"ridge_params = r.get_params() # This call should return parameters of the model that are \n",
167+
" # fully trained.\n",
168+
"data_test = dataset.query_data(samples = 40) # Create a random testing dataset.\n",
169+
"predictions = r.get_predictions(data_test[0]) # This call should return predictions.\n",
170+
"print (\"Rmse error of predictions = \" + str(rmse(data_test[1], predictions)))"
171+
]
172+
},
173+
{
174+
"cell_type": "markdown",
175+
"metadata": {},
176+
"source": [
177+
"## Geometry of the $L_2$ regularizer\n",
178+
"![Geometry of L2 Regularization](figures/regularization.png)\n",
179+
"\n",
180+
"The errors we use above are squared errors. With that in mind, if we drew out the errors in the parameters space, we will get an error function which will be a *bowl*. At $\\alpha_2 = 0$, we will be at the center. There are a lot of reasons why we might not want to prefer that. For instance, Smaller weights imply that we know that our weights are stable. In the future, we will notice that smaller weights will help us with noisy data or even to enforce sparsity. We will also see other types of regularizers in later lectures."
144181
]
145182
}
146183
],
147184
"metadata": {
148185
"kernelspec": {
149-
"display_name": "conda_python3",
186+
"display_name": "Python 3",
150187
"language": "python",
151-
"name": "conda_python3"
188+
"name": "python3"
152189
},
153190
"language_info": {
154191
"codemirror_mode": {
@@ -160,7 +197,7 @@
160197
"name": "python",
161198
"nbconvert_exporter": "python",
162199
"pygments_lexer": "ipython3",
163-
"version": "3.6.2"
200+
"version": "3.6.3"
164201
}
165202
},
166203
"nbformat": 4,

0 commit comments

Comments
 (0)