如果特征值之间存在线性关系就可以使用线性回归建模对其预测结果。本次测试是对一个房屋售价的数据集进行探索,并找出与售价之间有相关性的特征值建立回归模型,来通过此特征值来预测房价。
下面,开始导入数据集:
import pandas as pd
df = pd.read_csv("house_data.csv")
# 查看前五行数据
df.head()
这样看数据集是很难看出有什么相关性的。所以,最佳的方法是将数据可视化。
下面可视化数据:
import matplotlib.pyplot as plt
import seaborn as sns
cols = ["LSTAT", "AGE", "DIS", "CRIM", "MEDV", "TAX", "RM"]
sns.pairplot(df[cols], size=2.5)
从图中可以看出LSTAT(人口百分比)和RM(房屋里的卧室平均数)分别与MEDV(房屋售价)有线性关系。那么接下来建立线性回归模型,再分别通过LSTAT和RM对MEDV做出预测。
这里使用梯度下降法对计算回归参数,实现回归模型建立。
import numpy as np
class LinearRegressionByMyself(object):
# 初始化学习率和循环迭代次数
def __init__(self, Learning_rate = 0.001, epoch = 20):
self.Learning_rate = Learning_rate
self.epoch = epoch
# 定义训练fit函数,传入训练集(X),测试集(y)
def fit(self, X, y):
# 初始化权重(w)
self.w = np.zeros(1 + X.shape[1])
self.cost_list = []
# 更新权重
for i in xrange(self.epoch):
output = self.Regression_input(X)
error = (y - output)
self.w[1:] += self.Learning_rate * X.T.dot(error)
self.w[0] += self.Learning_rate * error.sum()
cost = (error ** 2).sum() / 2.0
self.cost_list.append(cost)
return self
# 定义线性回归的输入计算函数
def Regression_input(self, X):
return np.dot(X, self.w[1:]) + self.w[0]
# 定义线性回归的预测函数
def predict(self, X):
return self.Regression_input(X)
这样就完成了线性回归模型的建立。
接下来导入数据集。
首先导入“RM”训练集和“MEDV”测试集
X = df[["RM"]].values
y = df["MEDV"].values
此时,要注意特征值之间的尺度。如果有差异,那么就首先应该进行归一化数据。
from sklearn.preprocessing import StandardScaler
StandardScaler_X = StandardScaler()
StandardScaler_y = StandardScaler()
X_Standard = StandardScaler_X.fit_transform(X)
y_Standard = StandardScaler_y.fit_transform(y)
到此时,已经完成数据准备的工作,接下来,导入进模型中。
model = LinearRegressionByMyself()
model.fit(X_Standard, y_Standard)
然后,对误差率进行可视化。
plt.plot(range(1, model.epoch+1), model.cost_list)
plt.ylabel("SSE")
plt.xlabel("Epoch")
可以看出在迭代第五次的时候,误差已经趋近于最小值。
下面,我们对线性模型可视化。
def Regression_plot(X, y, model):
plt.scatter(X, y, c="blue")
plt.plot(X, model.predict(X), color="red")
return None
Regression_plot(X_Standard, y_Standard, model)
plt.xlabel("RM")
plt.ylabel("House price")
这就得到了RM与房价之间的线性函数。
可以带入一个值来预测一下房价。
Rercentage_standard = StandardScaler_X.transform([7])
Price_standard = model.predict(Rercentage_standard)
# 因为之前是对数据进行了归一化,所以此时要得到房价,就要进行反归一化。
print "House price: %.3f" % StandardScaler_y.inverse_transform(Price_standard)
House price: 29.044
还可以得到斜率和截距。
print "Slope: %.3f" % model.w[1]
Slope: 0.695
print "Intercept: %.3f" % model.w[0]
Intercept:0.000
同理,我们可以用LSTAT对房价进行预测。
这就是用LSTAT对房价进行预测的线性回归图。可以看出是呈反相关的呢。