本文主要通过波士顿房价预测这个案例,来学习机器学习中的线性回归模型,和了解如何去运用模型,如何去解决实际问题,最后还有对模型进行评价与反思,不足在于没有进行可视化分析。
什么是线性回归,我觉得是想通过一个可描述的方程来表达因变量与自变量之间的关系。我们就是在寻找最符合原数据(事物本来关系)的表达形式。
向量形式为:
而如何去达到优化的目的,这里有两种方式处理均方误差,1.最小二乘法 2.梯度下降法
波士顿房价模型,是通过13个指标来预测房价,如何确定相应的模型。
一、数据处理
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
def load_data(type = 0):
# 线性回归,对于明显非线性的元素,可以认为白噪声,给与剔除
# 根据线性相关性判断
boston = load_boston()
x, y, feature_names = boston.data, boston.target, boston.feature_names
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=3)
if type == 1:
z = []
for i in range(x.shape[1]):
z.append(pearsonr(x[:, i], y)[0])
index = [i for i in range(x.shape[1]) if abs(z[i]) >= 0.5]
x_train = x_train[:, tuple(index)]
x_test = x_test[:, tuple(index)]
return x_train, x_test, y_train, y_test
def Minmax(x_train , x_test ,y_train ,y_test):
#数据标准化,归于[0,1]。
scaler = MinMaxScaler()
train_x = scaler.fit_transform(x_train)
test_x = scaler.fit_transform(x_test)
train_y = scaler.fit_transform(y_train.reshape(-1, 1)).reshape(-1)
test_y = scaler.fit_transform(y_test.reshape(-1, 1)).reshape(-1)
return train_x,test_x,train_y,test_y
二、模型的建立
(1)使用sklearn机器学习库
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
train_x, test_x, train_y, test_y = load_data.load_data()
model = LinearRegression()# 线性回归模型
model.fit(train_x, train_y)# 拟合
train_y_predit = model.predict(train_x)
train_loss = mean_squared_error(train_y, train_y_predit)# 均方误差
print("训练误差:", train_loss)
test_y_predit = model.predict(test_x)
test_loss = mean_squared_error(test_y, test_y_predit)
print("测试误差:", test_loss)
print("R2=", r2_score(test_y, test_y_predit))
(2)自己定义的最小二乘与梯度下降算法
import numpy as np
class LinearRegression:
"""
模型是同一个线性回归模型
不同的是模型拟合方法
1:梯度下降法
2:最小二乘法
"""
def __init__(self, alpha=0.05, times=20000):
self.alpha = alpha
self.times = times
self.w = None
self.loss = None
def fit1(self, x, y):
x = np.asarray(x)
y = np.asarray(y)
self.w = np.zeros(1 + x.shape[1])
self.loss = [] # 记录每次的均方误差
for i in range(self.times):
y_hat = np.dot(x, self.w[:-1]) + self.w[-1]
error = y - y_hat
self.loss.append(np.sum(error ** 2) / (2 * x.shape[0]))
self.w[-1] = self.w[-1] + self.alpha * np.sum(error * 1) / x.shape[0]
self.w[:-1] = self.w[:-1] + self.alpha * np.dot(x.T, error) / x.shape[0]
def predict1(self, x):
x = np.asarray(x)
result = np.dot(x, self.w[:-1]) + self.w[-1]
return result
def fit2(self, x, y):
x = np.asarray(x)
y = np.asarray(y)
self.w = np.matmul(np.linalg.inv(np.matmul(x.T, x)), np.matmul(x.T, y))
def predict2(self, x):
x = np.asarray(x)
result = np.matmul(x, self.w.T)
return result
(3)看到模型效果不佳,或者说减少了非线性因素,效果还是不佳,考虑加入非线性。
# 这里仅仅展示相关代码块
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2)
poly.fit(train_x)
train_x = poly.transform(train_x)
poly = PolynomialFeatures(degree=2)
poly.fit(test_x)
test_x = poly.transform(test_x)
三、代码总体预览
# load_data()
# MinMax()
# model
# 类比使用sklearn库的形式,对自己写的优化方法进行结果分析。
# 使用非线性项的回归,是把非回归项,整体作为回归项,进行线性回归。
谢谢大家的观看,欢迎大家大的评论,交流,我会多多改进的。