In [1]:
import pandas as pd
import numpy as np
from matplotlib.pyplot import subplots
house = pd.read_csv('house.csv')
house.head(3)
Out[1]:
| Order | PID | MS SubClass | MS Zoning | Lot Frontage | Lot Area | Street | Alley | Lot Shape | Land Contour | ... | Pool Area | Pool QC | Fence | Misc Feature | Misc Val | Mo Sold | Yr Sold | Sale Type | Sale Condition | SalePrice | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 526301100 | 20 | RL | 141.0 | 31770 | Pave | NaN | IR1 | Lvl | ... | 0 | NaN | NaN | NaN | 0 | 5 | 2010 | WD | Normal | 215000 |
| 1 | 2 | 526350040 | 20 | RH | 80.0 | 11622 | Pave | NaN | Reg | Lvl | ... | 0 | NaN | MnPrv | NaN | 0 | 6 | 2010 | WD | Normal | 105000 |
| 2 | 3 | 526351010 | 20 | RL | 81.0 | 14267 | Pave | NaN | IR1 | Lvl | ... | 0 | NaN | NaN | Gar2 | 12500 | 6 | 2010 | WD | Normal | 172000 |
3 rows × 82 columns
In [2]:
house = house[house['Bldg Type'] == '1Fam']
house = house[house['Sale Condition'] == 'Normal']
sales = house[['SalePrice', '1st Flr SF', '2nd Flr SF', 'Total Bsmt SF',
'Garage Area', 'Wood Deck SF', 'Open Porch SF', 'Lot Area',
'Year Built', 'Yr Sold']]
sales.head(3)
Out[2]:
| SalePrice | 1st Flr SF | 2nd Flr SF | Total Bsmt SF | Garage Area | Wood Deck SF | Open Porch SF | Lot Area | Year Built | Yr Sold | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 215000 | 1656 | 0 | 1080.0 | 528.0 | 210 | 62 | 31770 | 1960 | 2010 |
| 1 | 105000 | 896 | 0 | 882.0 | 730.0 | 140 | 0 | 11622 | 1961 | 2010 |
| 2 | 172000 | 1329 | 0 | 1329.0 | 312.0 | 393 | 36 | 14267 | 1958 | 2010 |
In [3]:
n = sales.shape[0] # Number of observations
X = np.ones((n, 1))
X = np.insert(X, 1, sales['1st Flr SF'], axis=1)
X = np.insert(X, 2, sales['2nd Flr SF'], axis=1)
y = sales['SalePrice'].reset_index(drop=True)
X
Out[3]:
array([[1.000e+00, 1.656e+03, 0.000e+00],
[1.000e+00, 8.960e+02, 0.000e+00],
[1.000e+00, 1.329e+03, 0.000e+00],
...,
[1.000e+00, 9.700e+02, 0.000e+00],
[1.000e+00, 1.389e+03, 0.000e+00],
[1.000e+00, 9.960e+02, 1.004e+03]])
In [4]:
Z = np.matmul(X.T, X)
t = np.linalg.inv(Z)@X.T@y
MSE = (1/n) * np.linalg.norm(y - X@t)**2
print('MSE = ', MSE)
print('Theta = ', t)
MSE = 1705349005.3197255 Theta = [-29985.3612312 155.19406373 91.35680257]
In [7]:
learning_rate = 0.0000000001
t = np.zeros(3).T
for i in range(3):
t = t + (2*learning_rate/n) * (X.T @ (y - X@t))
loss = (1/n) * np.linalg.norm(y - X@t)**2
MSE = (1/n) * np.linalg.norm(y - X@t)**2
print('MSE, Theta:', MSE, t)
X
MSE, Theta: 37417784909.067505 [1.07477231e-04 1.33284713e-01 4.37624711e-02]
Out[7]:
array([[1.000e+00, 1.656e+03, 0.000e+00],
[1.000e+00, 8.960e+02, 0.000e+00],
[1.000e+00, 1.329e+03, 0.000e+00],
...,
[1.000e+00, 9.700e+02, 0.000e+00],
[1.000e+00, 1.389e+03, 0.000e+00],
[1.000e+00, 9.960e+02, 1.004e+03]])
In [8]:
from sklearn.preprocessing import StandardScaler
# Scale the features
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_scaled[:, 0] = np.ones(sales.shape[0])
Z = np.matmul(X_scaled.T, X_scaled)
t = np.linalg.inv(Z)@X_scaled.T@y
MSE = (1/n) * np.linalg.norm(y - X_scaled@t)**2
print('MSE = ', MSE)
print('Theta = ', t)
MSE = 1705349005.3197255 Theta = [179184.62687313 56135.61010536 39157.22624338]
In [11]:
learning_rate = 0.01
t = np.zeros(3).T
for i in range(2000):
t = t + (2*learning_rate/n) * (X_scaled.T @ (y - X_scaled@t))
#MSE = (1/n) * np.linalg.norm(y - X_scaled@t)**2
#print('RMSE, Theta:', MSE, t)
MSE = (1/n) * np.linalg.norm(y - X_scaled@t)**2
print('RMSE, Theta:', MSE, t)
RMSE, Theta: 1705349005.3197255 [179184.62687313 56135.61010536 39157.22624338]
In [17]:
# This is stochastic gradient descent
learning_rate = 0.01
t = np.zeros(3)
n = sales.shape[0]
for i in range(1200):
for j in range(n):
t = t + (2*learning_rate) * (y[j] - X_scaled[j, :]@t) * X_scaled[j, :]
MSE = (1/n) * np.linalg.norm(y - X_scaled@t)**2
print('RMSE, Theta:', MSE, t)
RMSE, Theta: 1766798902.7592735 [174477.21671957 49694.33814832 37747.92307174]
In [30]:
# This is batch gradient descent
learning_rate = 0.01
t = np.zeros(3)
n = sales.shape[0]
m=100
for i in range(100):
for j in range(n//m):
t = t + (2*learning_rate/m) * X_scaled[j*m:(j+1)*m, :].T @ (y[j*m:(j+1)*m] - X_scaled[j*m:(j+1)*m, :]@t)
MSE = (1/n) * np.linalg.norm(y - X_scaled@t)**2
print('RMSE, Theta:', MSE, t)
RMSE, Theta: 1705564912.1929908 [178949.12523594 55787.08837227 39290.02664459]
In [21]:
sales.corr()
Out[21]:
| SalePrice | 1st Flr SF | 2nd Flr SF | Total Bsmt SF | Garage Area | Wood Deck SF | Open Porch SF | Lot Area | Year Built | Yr Sold | |
|---|---|---|---|---|---|---|---|---|---|---|
| SalePrice | 1.000000 | 0.642466 | 0.357522 | 0.652979 | 0.638594 | 0.352699 | 0.336909 | 0.290823 | 0.565165 | 0.025949 |
| 1st Flr SF | 0.642466 | 1.000000 | -0.230561 | 0.765052 | 0.464566 | 0.247685 | 0.220888 | 0.303834 | 0.316339 | 0.026647 |
| 2nd Flr SF | 0.357522 | -0.230561 | 1.000000 | -0.182213 | 0.172852 | 0.097926 | 0.227684 | 0.025948 | 0.079553 | -0.020525 |
| Total Bsmt SF | 0.652979 | 0.765052 | -0.182213 | 1.000000 | 0.456592 | 0.237535 | 0.204110 | 0.208933 | 0.425617 | 0.047675 |
| Garage Area | 0.638594 | 0.464566 | 0.172852 | 0.456592 | 1.000000 | 0.237945 | 0.240943 | 0.183717 | 0.487135 | 0.029293 |
| Wood Deck SF | 0.352699 | 0.247685 | 0.097926 | 0.237535 | 0.237945 | 1.000000 | 0.055236 | 0.127837 | 0.254986 | 0.019196 |
| Open Porch SF | 0.336909 | 0.220888 | 0.227684 | 0.204110 | 0.240943 | 0.055236 | 1.000000 | 0.095189 | 0.190891 | -0.031687 |
| Lot Area | 0.290823 | 0.303834 | 0.025948 | 0.208933 | 0.183717 | 0.127837 | 0.095189 | 1.000000 | 0.083281 | -0.008188 |
| Year Built | 0.565165 | 0.316339 | 0.079553 | 0.425617 | 0.487135 | 0.254986 | 0.190891 | 0.083281 | 1.000000 | 0.046000 |
| Yr Sold | 0.025949 | 0.026647 | -0.020525 | 0.047675 | 0.029293 | 0.019196 | -0.031687 | -0.008188 | 0.046000 | 1.000000 |
In [29]:
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(sales[['1st Flr SF']], sales['SalePrice'])
r_sq = model.score(sales[['1st Flr SF']], sales['SalePrice'])
print('One feature:', r_sq)
model = LinearRegression()
model.fit(sales[['1st Flr SF', '2nd Flr SF']], sales['SalePrice'])
r_sq = model.score(sales[['1st Flr SF', '2nd Flr SF']], sales['SalePrice'])
print('Two features:', r_sq)
model = LinearRegression()
model.fit(sales[['1st Flr SF', '2nd Flr SF', 'Year Built']], sales['SalePrice'])
r_sq = model.score(sales[['1st Flr SF', '2nd Flr SF', 'Year Built']], sales['SalePrice'])
print('Three features:', r_sq)
model = LinearRegression()
model.fit(sales[['1st Flr SF', '2nd Flr SF', 'Year Built', 'Garage Area']], sales['SalePrice'])
r_sq = model.score(sales[['1st Flr SF', '2nd Flr SF', 'Year Built', 'Garage Area']], sales['SalePrice'])
print('Four features:', r_sq)
One feature: 0.41276288766116953 Two features: 0.6827991925732996 Three features: 0.7726766859516288 Four features: 0.7880072396536026
In [ ]: