上一集,我们讨论了单变量的情况下,如何利用sklearn模块的线性回归模型预测房价,拟合出了一条回归直线。
在上一集,我们假定只考虑房屋面积这一个变量,那么预测函数应该是:
h(x)=theta0+theta1*x1
用模型求出theta0和theta1,拟合出了一条直线,其中x1是训练数据(房屋的面积)。
然而,如果需要考虑两个以上的变量,如在预测中加入房间数量对房价的影响,那么构造的预测函数就应该是:
h(x)=theta0+theta1*x1+theta2*x2
其中,x1和x2是训练数据面积和房屋数量。
模型求出theta0,theta1,theta2后,我们可以发现,这其实是一个平面,我们可以在图上画出这个平面,观查他拟合情况的好坏!
1、构造模型需要的训练数据
上一集中我们已经知道了线性回归模型需要的训练数据:
对下面的训练数据:
我们可以采用和上一集同样的方法来处理:
# Function to get data
def get_data(file_name):
data = pd.read_csv(file_name)
print data
X1_parameter = []
X2_parameter = []
Y_parameter = []
for single_square_feet, single_bedroom,price_value in zip(data['livingarea']\
,data['bedrooms'],data['prices']):
X1_parameter.append([float(single_square_feet)])
X2_parameter.append([float(single_bedroom)])
Y_parameter.append([float(price_value)])
return X1_parameter,X2_parameter,Y_parameter
可以看到,我们只是添加了一个变量X2_parameter
,同时将数据集中 bedrooms
列的数据传给了它。
但是,模型需要的训练数据的形式是(X,y),X是一个变量矩阵,y是一个目标值数组。
所以,我们还需要对X1_parameter,X2_parameter
进行重组,这里numpy
提供了一个非常好用的函数column_stack
他可以将一维数组变成矩阵的一列,如:
X,Z = np.column_stack((X1,X2)),zz
最终的矩阵X的第一列为X1,第二列为X2。
2、用模型计算预测函数h(x)的参数。
X1,X2,zz=get_data('./2dimension_input.csv')
X,Z = np.column_stack((X1,X2)),zz
regr = linear_model.LinearRegression()
regr.fit(X,Z)
a,b = regr.coef_, regr.intercept_
print 'theta0 is:%s;\ntheta1 is:%s;\ntheta2 is:%s' %(b[0],a[0][0],a[0][1])
print regr.predict(X)
那么问题是?这些参数是否是合理?
3、下面,我们从图形上来看看:
#plot the training data and predict plane.
fig = plt.figure()
ax = fig.gca(projection='3d')
# define the predict range.
xxx1 = np.linspace(1100,3000,10)
xxx2 = np.linspace(1,10,10)
# Function meshgrid is very important.
xx1, xx2 = np.meshgrid(xxx1, xxx2)
XX=np.column_stack((xx1.flatten(),xx2.flatten()))
# plot the training data points with red color.
ax.scatter(X1, X2, zz,c='r',s=50)
# plot the wirefrme of predict plane.
ax.plot_wireframe(xx1, xx2, regr.predict(XX).reshape(10,10))
ax.plot_surface(xx1, xx2, regr.predict(XX).reshape(10,10), alpha=0.11)
plt.show()
从图中可以看出,预测的平面与训练数据契合度非常好!
4、完整代码
# coding = utf-8
import numpy as np
import pandas as pd
from sklearn import datasets, linear_model
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import pdb
# Function to get data
def get_data(file_name):
data = pd.read_csv(file_name)
print data
X1_parameter = []
X2_parameter = []
Y_parameter = []
for single_square_feet, single_bedroom,price_value in zip(data['livingarea']\
,data['bedrooms'],data['prices']):
X1_parameter.append([float(single_square_feet)])
X2_parameter.append([float(single_bedroom)])
Y_parameter.append([float(price_value)])
return X1_parameter,X2_parameter,Y_parameter
pdb.set_trace()
X1,X2,zz=get_data('./2dimension_input.csv')
X,Z = np.column_stack((X1,X2)),zz
regr = linear_model.LinearRegression()
regr.fit(X,Z)
a,b = regr.coef_, regr.intercept_
print 'theta0 is:%s;\ntheta1 is:%s;\ntheta2 is:%s' %(b[0],a[0][0],a[0][1])
print regr.predict(X)
#plot the training data and predict plane.
fig = plt.figure()
ax = fig.gca(projection='3d')
# define the predict range.
xxx1 = np.linspace(1100,3000,10)
xxx2 = np.linspace(1,10,10)
# Function meshgrid is very important.
xx1, xx2 = np.meshgrid(xxx1, xxx2)
XX=np.column_stack((xx1.flatten(),xx2.flatten()))
# plot the training data points with red color.
ax.scatter(X1, X2, zz,c='r',s=50)
# plot the wirefrme of predict plane.
ax.plot_wireframe(xx1, xx2, regr.predict(XX).reshape(10,10))
ax.plot_surface(xx1, xx2, regr.predict(XX).reshape(10,10), alpha=0.11)
plt.show()