All right. 1
So now let's change track a little bit. 2
We now have our template for our property that we want to get an estimate for. 3
That template is currently populated with the average values in the dataset, 4
so now let's get the estimated theta values for our model. 5
And while we're doing that, we can also calculate the root mean squared error for our prediction interval. 6
I'm going to be using scikit-learn to do this. 7
Let's store our regression in a variable called "regr" and that's going to be equal to LinearRegression(), 8
so this is scikit-learn's linear regression, and we can use that linear regression to already fit our values, 9
so we can calculate all the theta parameters simply by calling the fit method on this and the fit method 10
needs two inputs, namely the features and our target. If I hit Shift+Enter, 11
this calculates all the theta values in the background. To get the predicted values or the fitted values, 12
we can use "regr.predict(features)", 13
so based on our features dataframe we are calculating all the predicted values using the thetas from 14
our model. 15
Let me store this in a variable called "fitted_vals". "fitted_vals" 16
now has all our predictions. 17
The next step is calculating our mean squared error and our root mean squared error. 18
And this is where I'm going to throw it over to you. Can you calculate the mean squared error and the root 19
mean squared error using our scikit-learn module? 20
I'll give you a few seconds to pause the video and give this a go. 21
Ready? 22
Here's the solution. 23
The MSE is going to be equal to the return value from our mean_squared_error 24
function that we've imported at the top, "mean_squared_error" needs two inputs - the 25
target and the fitted values. 26
If we output the mean_squared_error for our regression it's currently equal to 0.035 27
approximately. 28
Now what about the root mean squared error, 29
the RMSE? That's simply going to be equal to the square root of the mean squared error. 30
Now I'm going to use numpy again, 31
so "np.sqrt(MSE)" 32
will give me the root mean squared error. 33
The value of the RMSE is equal to 0.175, and the units for both, 34
the mean squared error and the root mean squared error 35
are still log dollar prices in thousands. 36
Now we have everything in place to make our predictions. 37
I'm going to delete this here, hit Shift+Enter and go down to the next cell. 38
What I want to do here is I want to create a Python function which will estimate the log house prices 39
for a specific property. 40
We'll get the log prices first, the log estimate, using our data set and afterwards we'll do step 2 where 41
we convert this output into today's dollar values. 42
Now we've not written a Python function of our own for a little while. 43
So this is a good chance to review this as well. 44
The way you create a function is with the "def" keyword, "def" and then the function name, 45
I'm going to call this function 46
"get_log_estimate():". 47
Let's have this function return a dummy value for now, so I'm going to say "log_estimate = 48
21" and then down here 49
I'll specify a return value for this function, so I'll say "return log_estimate". 50
Now that we've defined our function, we can use it. 51
We can call it, so "get_log_estimate()" 52
will output the value 21. 53
Fair enough. 54
So this is pretty much all the review. 55
The thing I actually want to show you in this lesson is not just how to create your own Python function, 56
but how to create a Python function with arguments some of which have a default value, because once you 57
do that when calling the function the arguments that already have a default value are optional. 58
Let me show you what I mean by that. 59
If I come in here into my function definition and I specify an argument, say "nr_rooms", 60
and hit Shift+Enter, when it comes to calling our Python function, I now need to supply this argument, 61
so if I hit Shift+Enter now, I'll get a type error, because I'm missing one required positional argument, 62
nr_rooms. 63
Calling the function now requires that I have some value for the number of rooms. 64
Only then will the code execute. Let's add four arguments to this function total, number of rooms being 65
1, the next one being "students_per_classroom", 66
so this will be our "PTRATIO", comma, and then we'll have "next_to_river", 67
comma, and then we'll have a fourth argument, "high_ 68
confidence", and this last argument will be for whether or not we want to have a 95% prediction 69
interval. 70
All right. 71
So now we have four arguments, 72
meaning we need to specify values for all of these arguments here. To make one of these arguments optional, 73
say next_to_river, 74
I can give it a default value in our function signature, in our function definition. 75
So next_to_river can be equal to say False and high_confidence can be equal to say True. 76
What we've just done is made two of these arguments optional, meaning we only need to specify the number 77
of rooms and the students per classroom. 78
So coming down here where I'm calling this function, I can have 5 and say 19 and this cell will now 79
execute just fine. All right, 80
so we can't have this function returned the value 21 all the time. 81
That's, that's just silly. 82
What we actually want is we want this function to return the price estimate for a particular property, 83
so we're going to use our regression object, regr, and the predict method on that object 84
and then, as an argument to the predict method, we need to supply a single row of features. That single 85
row will be our property_stats, which currently hold on to the average values for all the features in 86
our dataset. 87
Check it out, if I press Shift+Enter to refresh the cell and then pull up the values stored inside property_ 88
stats, 89
I can see an array with 11 features and all the average values. 90
Okay, let's see what the log price estimate for this particular property is. 91
"regr.predict(property_stats)", Shift+Enter and Shift+Enter again, we see that we get 92
an array of two dimensions, 93
mind you, it has two sets of square brackets, and then we get a price estimate in log dollars. 94
Now if I wanted to get the raw number instead of an array we can access that value with 95
"[0][0]", 96
so first row, first column, Shift+Enter and Shift+Enter again will give us the log price estimate of the 97
array. 98
Now of course this is fairly boring, right? 99
Because even though we've inputed some values here as arguments the number of rooms and students per 100
classroom, we're not really making use of them inside our function. 101
So I'm going add a comment here that reads "Configure property" 102
and then I'll add a second comment here that reads "Make prediction". When it comes to configuring our 103
property, I'm thinking we can do it in a very, very similar way to the way we did it up here, so check 104
it out. 105
We can make use of this input, the number of rooms, by changing a particular index of our n-dimensional 106
array, so "property_stats[0]", 107
so row number 1 and then column number will be "RM_IDX", which is column number 4, 108
and we're gonna set that equal to "nr_rooms". 109
Now we have this number here 110
when calling the function, filtering through into configuring the feature that we're then going to make 111
the prediction on. 112
So Shift+Enter and Shift+Enter, you'll see that number change. 113
Now as that changes from 5 to say 8, to 9, to 3, we can now get price estimates for properties 114
that have the average values for Crime and LSTAT and Pollution from the dataset for all the features 115
except for one feature, namely the number of rooms. 116
This now depends on the input to our function. Let's do the same thing for PTRATIO, 117
the students per classroom. I'll let you pause the video to add that line of Python code. Ready? 118
Here it goes. 119
So "property_stats[0][ 120
PTRATIO_IDX] = students_per 121
_classroom" 122
Now we can adjust the valuation of our property, based on how many kids there are per teacher, Shift+Enter, 123
and Shift+Enter again and changing this and hitting Shift+ 124
Enter again, 125
se can see that for a PTRATIO of 10 to 1, the log price estimate is 3.05 and then for 126
a PTRATIO of say 20, 127
so a much bigger class, the log price estimate will go down. 128
Right? 129
So it'll be 2.68. Brilliant. 130
Now you can see where this is going. 131
Right? 132
Next up is this "next_to_river" argument that I've given here. 133
This is gonna be all about our CHAS variable. Now, 134
CHAS was a dummy variable, right? 135
It's either equal to 0 or it's equal to 1. 136
The way we're gonna configure our features is using an if-else clause, 137
so "if next_to_river:", new line, "property_stats[0] 138
[CHAS_IDX] = 1", 139
new line, "else:", "property_stats[0][CHAS_ 140
IDX] 141
= 0" 142
What code 143
did I just write here? In English, 144
this would read "if the property is next to the river, 145
if next to the river is true, then we're going to change one feature, namely the column for Charles River, 146
to 1, otherwise, 147
if next to river is false which is the default in this case, property_stats for the Charles 148
River column should be equal to 0". 149
The value of this point in our array is conditional on the value of next_to_river, which should either 150
be true or false. 151
We're calling our function 152
like so. This value here that we're getting for a three room dwelling with PTRATIO of 20, we're getting 153
a value of 2.68. 154
This property here is not next to the river. 155
If I hit Shift+Enter on this cell to refresh and refresh this cell, then we see what this property would be priced 156
that if it was not next to the river. 157
If however, "next_to_river = True" and I refresh the cell, then we can see 158
the premium of this property reflected in the price 159
if it was next to the river. 160
And that's because again living next to the river is a desirable thing. 161
All right, so you can see where this is going. 162
What we've just done is we've created a function and we're configuring the property that we're getting 163
the estimate for using the arguments to that function. 164
So number of rooms, students per classroom and whether the property is next to the river. For all the 165
other features, like pollution and highway accessibility, 166
we're just using the average values of the dataset. 167
If we wanted to, we could add more lines of code here and increase the number of arguments that are being 168
supplied to this function to set those as well. 169
But for this exercise, let's keep it simple, let's keep it to 3 custom inputs. 170
Now, what about this fourth one that I made you add earlier, "high_confidence"? What I had in 171
mind for this one was to calculate the range. 172
So let's add another comment here and I'm going to have that read "Calc Range". 173
This is our prediction interval. 174
I'm going to adopt the same pattern, so "if high_confidence:", "Do X", "else:", "Do Y". 175
Now what am I trying to get at here? 176
If high confidence is equal to True, then I want to calculate the two standard deviation prediction interval, 177
I want to calculate the 95% prediction interval and otherwise, I want to calculate the one standard 178
deviation prediction interval, 179
68% prediction interval. The prediction intervals of course have an upper and a lower 180
bound, 181
so "upper_bound = log_estimate + 2*RMSE", 182
yes that's our root mean squared error 183
coming back in here, and the "lower_bound = log_estimate - 2* 184
RMSE" 185
Now what about if we don't want a high confidence prediction interval? 186
What if we don't want a large range? 187
Well, I can copy these two lines and I can paste them in here and instead of using two times the root 188
mean squared error, we can simply use 1 times the root means squared error to calculate our range. 189
So this is a wide range and this is a narrow range. 190
The last thing I'm going to do is I want to make this very explicit, so I'll say "interval = 95" and here 191
I'm going to say "interval = 68". 192
I'm going to use this variable here in a print statement later on. 193
For now what we're gonna do is return all of these calculations, so check it out, we're going to return our "log_ 194
estimate", we're going to return our "upper_bound", 195
we're gonna return our "lower_bound" and we're going to return our interval. Hitting Shift+Enter, I 196
refresh the cell and hitting Shift+Enter on this one, 197
I can now see that I get a tuple. 198
This is what the parentheses are telling us and that tuple consists of four things, the log price estimate, 199
plus two standard deviations and minus two standard deviations for the range - an upper and a lower bound, 200
plus an indication if this is a wide range or a narrow range. 201
In this case, it is a wide range. Why? Because confidence is set to True by default. To get a narrow range, 202
I can use "high_confidence = False" in which case we will enter the else block of 203
the function and get the following output. We get the same log estimate, but the upper and the lower bound 204
will be plus and minus one standard deviation, one times the root mean squared error, and our prediction 205
interval 206
in this case, will be 68%, so this is the 68% prediction interval 207
and this is the 95% prediction interval. 208
Now that we have a price estimate and an upper and a lower bound and a prediction interval, the next 209
thing to do is to convert all of these log prices into dollar values.