Let me scroll back up to where we had our cost. 1
We're going to add two loops here. 2
The first one will be "for i in range()", 3
and then how far do we want to go? 4
We want to go across all the theta values. 5
So it's gonna be "nr_thetas" between the parentheses and then colon and we're going to 6
do the same thing for our second loop we're going to say "for j in range(nr_thetas 7
):". 8
Now what do we want to do inside the loop? 9
Let's do something very unimaginative 10
first. Let's print out all the values that we have inside our plot_t0 variable and we're 11
going to print them out one by one. 12
So we're gonna have "plot_t0[]" and now we have a choice - we can go row by 13
column or column by row. 14
So if we go by column then we'd have i in the first set of square brackets and then j in the second 15
set of square brackets. 16
Let's see what happens. 17
There we go. 18
This is us printing out 25 19
values, the 25 values that are stored inside our theta matrix, our theta five by five 20
array. The other way, say j and i, 21
our output would look like this. 22
In this case we're staying in the same column, namely the first one, and we're looking at all the first 23
elements. 24
If we have i and then j, then we're doing one row at a time. 25
So this is the first element in the row. 26
This the second element in the row. 27
This is the third one. 28
This is the fourth one. This is the fifth one. 29
And then this is the first element in the second row. On the other hand, if we have j and then i, then 30
we would be looking at the first element in the first row, the first element in the second row, the first 31
element in the third row and so on. 32
So the order in which we supply the indices here to our two dimensional array it matters in the sense 33
that it determines in which order our loop will go through the array. 34
But regardless in which order you go through you still hit up all the values. 35
So I'm going to comment this out and now I'm going to write the code to calculate our estimated y values. 36
So y_hat is equal to the first value in our theta_0 array. 37
It's going to be "plot_t0[i] 38
[j]". So this is gonna be our first t_0 value. I'm going to add "plot_t1 39
[i] 40
[j]*x_5". 41
So this is gonna calculate our predicted y values for the first set of theta parameters. And then what 42
we're gonna say is we're going to say that the plot_cost matrix is going to update and it's going 43
to update in the same position. 44
It's gonna be updating in [i][j]. 45
And it's gonna be equal to the output from our lovely mean squared error function, 46
so "mse(y_5, y_hat)", so we're gonna calculate our y_hat 47
value for these theta parameters and then based on that we're going to calculate our mean squared 48
error and we're gonna update our two dimensional cost array. And we're gonna do that for all of the theta 49
values so we can plot them later on. 50
So there's a lot of calculations going on here but there's only four lines of code. 51
This is very, very terse but very powerful at the same time. 52
Let's take a look at what the plot_cost variable actually looks like after the loop has 53
run. 54
Let's take a look. 55
I'm going to hit Shift+Enter and here we see that it is a five by five matrix. 56
I can prove this even though it's hard to see because of the lines wrapping. 57
If I say "plot_cost.shape", you can see here it's five by five and we can see that any for 58
each element we've got a mean squared error for a particular combination of thetas. Let's print this 59
stuff out so that we can verify what's going on when we make changes later on. 60
So I'm going to say "print", and then the string 'Shape of plot_t0', comma, "plot_t0 61
.shape", then I'm going to copy this print statement, paste it two more times and in the second one 62
way to change it to t1, and then the third one I'm going to change it to "plot_cost" so this 63
is printing out the dimensions of all the three arrays that we're using and at the moment they're all 64
five by five. Good stuff. 65
Now it's time to throw the stuff up onto a chart. 66
A 3D chart, 67
no less. 68
Let's take a look. I'm going to add a comment in this new cell "Plotting MSE". 69
And I'm going to do our old trick with the figure, I'm going to say "fig=plt.figure( 70
figsize=[16,12]" and then you've got some axes that I've got 71
to create. 72
So it's going to be "fig.gca", get current axes, and it's gonna be for a 3D projection, so "projection=" 73
and then the string "3d", lowercase d. And our chart's gonna have three axes, it's gonna have 74
a Y label on X label and a Z label. 75
So I'm going to see "ax.set_xlabel('Theta 0')". So 76
theta 0 is gonna be on our x axis and it's gonna be at font size say 20. 77
Copy that whole line, paste it two more times and then I will make some changes. 78
Second one is gonna set the Y label. 79
The third one is gonna set the Z label and then the string is gonna be updated to theta 1 and then 80
for the z axis, 81
this is gonna be it's gonna be our cost, right? 82
"Cost - MSE". 83
So we've created our plot, set the size of our figure, then we've grabbed our axes object from our figure, 84
we've set some of the attributes of the axes using the set_xlabel, set_ylabel 85
and "set_zlabel" functions and now we do the best part - "ax.plot_surface()", 86
and inside the parentheses, we have to supply three two dimensional arrays; the first one was gonna be 87
our theta 0, 88
so this is on our x axis. 89
The second one it's gonna be plot_t1, and this is gonna be for our y axis. And the third 90
one is gonna be the cost that we calculated in our nested loop so plot_cpst. 91
And finally we're gonna say "plot.show()" with some parentheses at the end. 92
Now we should be able to get a visualization of all that work we just did. 93
And before I hit Shift+Enter, let me just quickly check the code that I've written, 94
see if I've made any typos I'm spotting one of them here in setting the figure we've got to use our 95
matplotlib object which is "plt.figure" not "plot.figure". 96
So plt was our matplotlib object and plt.figure grabs our figure object. 97
I think we're good now. 98
So let me hit Shift+Enter and see what this looks like. Voila! It looks like.. 99
so I realize this might be a little bit underwhelming and it looks like a video game from the 1990s. 100
This is I think the kind of graphics they had but we can change this very, very easily. If I scroll 101
back up and increase the number of data points we're using from 5 to say 200 and I update 102
this cell then we're gonna generate a lot more theta zeros and a lot more theta ones with our 103
linspace function as such. 104
I'm going to hit Shift+Enter on this cell. I can see that we're now dealing with a 200 by 200 array. 105
So a lot more data points that we're plotting now. 106
And when I replot our surface by hitting Shift+Enter to update this cell then it will look something 107
like this. 108
Brilliant. 109
How are you liking the navy blue? 110
I think we've got to add a splash of color to this to make it a bit more interesting. 111
I'm going to go back up to my plot_surface function and I'm going to make use of this color map that 112
we imported earlier. 113
It's gonna be an extra argument I'm gonna supply here, 114
"cmap" and it's going to be set equal to our cm module, 115
put a dot after it and then I'm going to use "hot" and hit Shift+Enter. 116
Now this is starting to look pretty good. 117
I personally think this surface doesn't just look hot, 118
you could say it almost looks super hot. 119
But before I lose you to this video game, let's compare our function and our calculations to our regression 120
estimates because we can actually pull out the lowest mean squared error from our plot variable, 121
right? 122
So if I come down here and I write print and then write "Min value of plot_cost", comma 123
"plot_ 124
cost.min", 125
and then some parentheses, I can actually pull out the lowest mean squared error from our surface plot 126
that we just used for graphing and that is 0.94838. 127
But hold on, I hear you say, what are the theta 0 and theta 1 values associated with that cost that 128
we just pulled out? 129
I mean, after all, we care about our parameter values, 130
right? 131
So how can we grab the row and the column indices which correspond to this minimum cost? 132
And for that numpy has you covered. 133
It's got a function called "unravel_index". 134
So I'm going to say "ij_min=np.unravel_index()" and it needs two 135
inputs - 136
it needs the indices and that's going to be equal to "plot_ 137
cost." 138
and then "argmin", 139
so this will output the indices from our 2D array where the mean squared 140
error is at its lowest. 141
And then we have a comma afterwards. 142
And we supply that second input to the unravel_index function and that's the dimensions, 143
"dims" of the 2D array that we are supplying, so we can say "dims = plot_cost. 144
shape" and this will give us the row and the column index. 145
Let's print this out. 146
"print('Min occurs at (i, 147
j) 148
:', ij_min". So the minimum occurs at the 111th throw and 149
91st column. 150
So this is where after running that nested for loop the mean squared error was the lowest. The theta 0 151
value associated with row number 111 and column 91 is as follows: 152
"print('Min MSE for Theta 0 at plot_t0[111][91]', 153
plot_t0[111][91])". Hitting Shift+ 154
Enter we can see that this is fiendishly close to what the scikit learn package calculated. Now of course 155
using a nested for loop is not better, it's very much a brute force method but I kind of wanted 156
to show you how you can use these 2d arrays and how you can work with them and how you can access particular 157
values using the row and the column indices. So let's do that one more time, but this time we'll grab the 158
theta 1 value just for good measure so it'll be "print('Min MSE for Theta 1 at plot_ 159
t1[111][91]', plot_t1 160
[111][91])". 161
So this should be close to 1.2. 162
Let's take a look. And it is, it's 1.23. 163
Brilliant. 164
Now all that's left to do is run our gradient descent algorithm on this cost function and then we've 165
come full circle. 166
I'll see you in the next lesson. 167
Super hot is actually one of the most interesting games I've played recently by the way. So I just had 168
to mention it. It's this first person shooter but with a twist, time only moves forward when you move 169
and there's no music it's just the sound effect of glass shattering. That's right. That's it. 170
So yeah. 171
If you're curious, check it out on Steam if you want a break from programming. 172
I do hope you give Super Hot a try and let me know what you think. 173
Just the don't do what I did and play it really late at night because if you're anything like me you'll 174
get too excited and you'll have trouble sleeping. 175
So yeah take care.