线性回归实战1:预测boston房价

boston房价数据集包括506个样本,每个样本包括13个特征变量和该地区的平均房价,房价显然和多个特征变量相关,对于线性回归模型,先选择一元线性回归与多个特征建立线性方程,观察模型预测的好坏,再选择多元线性回归进行房价预测。

简单线性回归:当回归模型包含一个因变量和一个自变量时。
多项式回归:当只有一个自变量,但同时含有变量的幂(X2,X3)时,称为多项式回归。
多元线性回归:当有不止一个自变量时。

 一、加载数据集

1、导包

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import xgboost as xgb
from sklearn import datasets
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import mean_squared_error

2、读入数据并展示

boston = datasets.load_boston()
boston_data = pd.DataFrame(boston.data)
boston_data.columns = boston.feature_names
boston_data['price'] = boston.target
print(boston_data.columns)
print(boston_data.head())

特征(13个): 

 前几行数据:线性回归实战1:预测boston房价_第1张图片

3、拆分特征和标签

y = boston_data.pop('price')

二、数据集处理

1、查看空值

print(boston_data.isnull().sum())

线性回归实战1:预测boston房价_第2张图片

2、查看数据大小

print(boston_data.shape)

3、查看数据描述信息

print(boston_data.describe())

线性回归实战1:预测boston房价_第3张图片

4、查看各特征相关性

import seaborn as sns
plt.figure(figsize=(12, 8))
sns.heatmap(boston_data.corr(), annot=True, fmt='.2f', cmap='PuBu')
plt.show()

线性回归实战1:预测boston房价_第4张图片

5、画出各个特征与房价的散点图

data_xTitle = ['CRIM','ZN','INDUS','CHAS','NOX','RM','AGE','DIS','RAD','TAX','PTRATIO','B', 'LSTAT']
plt.figure(figsize=[20,18])
fig, a = plt.subplots(5, 3)
m = 0
for i in range(0, 5):
    if i == 4:
        a[i][0].scatter(data[str(data_xTitle[m])], y, s=30, edgecolor='white')
        a[i][0].set_title(str(data_xTitle[m]))
    else:
        for j in range(0, 3):
            a[i][j].scatter(data[str(data_xTitle[m])], y, s=30, edgecolor='white')
            a[i][j].set_title(str(data_xTitle[m]))
            m = m + 1
plt.show()

线性回归实战1:预测boston房价_第5张图片

从上图可以看出‘RM’,‘LSTAT’,‘CRIM’三个特征值与房价存在一定的相关性,所以选择该三个特征作为特征值,移除其余不相关的特征值。

new_boston_df = boston_data[['LSTAT', 'CRIM', 'RM']]
print(new_boston_df.describe())
new_boston_df = np.array(new_boston_df)
data = np.array(boston_data)
y = np.array(y)

 6、划分数据集

x_train, x_test, y_train, y_test = train_test_split(data, y, test_size=0.2, random_state=14)

三、建立线性模型

1、建立线性回归模型

我们分别用选择前的特征(13个)和选择后的特征(3个)来建模, 并绘制拟合曲线。

data_list = [boston_data, new_boston_df]


for index, data in enumerate(data_list):
    x_train, x_test, y_train, y_test = train_test_split(data, y, test_size=0.2, random_state=14)

    # 线性回归
    lr_reg = linear_model.LinearRegression()
    lr_reg.fit(x_train, y_train)
    print("线性回归的系数:w = {}, b = {}".format(lr_reg.coef_, lr_reg.intercept_))
    pred = lr_reg.predict(x_test)
    train_pred = lr_reg.predict(x_train)
    # 计算MSE
    test_MSE =mean_squared_error(pred, y_test)
    train_MSE = mean_squared_error(train_pred, y_train)
    # 计算MAE
    test_MAE = mean_absolute_error(y_test, pred)
    train_MAE = mean_absolute_error(y_train, train_pred)
    score = lr_reg.score(x_test, y_test)
    # 预测值与真实值的可视化
    y_test = tuple(y_test)
    test = []
    pre = []
    for i in np.argsort(pred):
        test.append(y_test[i])
        pre.append(pred[i])
    plt.plot(test, label='true')
    plt.plot(pre, label='predict')
    if index == 0:
        plt.title('all_feature,ACC:{:.2f}%,MSE:{:.2f},MAE:{:.2f}'.format(score*100, test_MSE, test_MAE))
    else:
        plt.title('three_feature,ACC:{:.2f}%,MSE:{:.2f},MAE:{:.2f}'.format(score*100, test_MSE, test_MAE))
    plt.legend()
    plt.grid()
    plt.show()

线性回归实战1:预测boston房价_第6张图片

 我们发现,特征选择前的准确率竟然比特征选择后的准确率要高,均方误差也比选择后的要小,这是为什么呢?正规方程求解的线性回归适用于特征不是特别多,不是特别复杂度的数据

线性回归模型存在不适用的场合:

1、自变量个数大于样本量。

2、自变量直接存在多重共线性(值高度相关)。

为了解决上述问题,需要使用岭回归模型Lasso回归模型。下面我们分别用特征选择前和特征选择后的特征,使用SDG、岭回归和Lasso回归观察模型结果。

2、SDG 

SGD线性回归,随机梯度下降线性回归sgd适用于特征较大,数据量较多的情况,进行自我学习需要设置学习率,默认学习率为0.01,想要更改学习率---learning_rate = 'constant'且eta0=‘要设置的学习率’,梯度方向不需要考虑,因为他是沿着损失减小的方向的,学习率过大会造成梯度爆炸,梯度爆炸出现在复杂的神经网络中,梯度爆炸是损失或准确率全部变成NAN类型,梯度也不能过小,如果过小,会造成原地打转,此时梯度消失,--损失不减小,一直那么大。

from sklearn.linear_model import SGDRegressor
sgd = SGDRegressor(max_iter=1000, penalty=None, tol=1e-3,eta0=0.0001)
sgd.fit(x_train, y_train)
sgd_predict = sgd.predict(x_test)
sgd_MSE = mean_squared_error(y_test, sgd_predict)
sgd_MAE = mean_absolute_error(y_test, sgd_predict)
sgd_score = sgd.score(x_test, y_test)
print('SGD模型:MSE:{}\nMAE:{}\nACC:{}'.format(sgd_MSE, sgd_MAE, sgd_score*100))

3、岭回归

线性回归模型:J(\beta) = \sum (y-x_\beta )^2

岭回归模型:J(\beta)=\sum(y-x_\beta)^2+\sum\lambda\beta^2

在线性回归模型的基础上添加一个L2惩罚项(也称平方项、正则项),(让某些特征值的权重趋于0),在小的数据集上效果会比LinearRegression效果好一些,正规方程求解的线性回归特征不是特别多,不是特别复杂度的数据。缺点:无法降低模型的复杂度。(始终保留建模时的所有变量)。

岭回归交叉验证的参数

RidgeCV(alphas=(0.1, 1.0, 10.0), fit_intercept=True, normalize=False,
scoring=None, cv=None)
# 参数
alphas:⽤于指定多个lambda值的元组或数组对象,默认该参数包含0.1、1和10三种值。
fit_intercept:bool类型参数,是否需要拟合截距项,默认为True。
normalize:bool类型参数,建模时是否需要对数据集做标准化处理,默认为False。
scoring:指定⽤于评估模型的度量⽅法。
cv:指定交叉验证的重数。

交叉验证的思想

1.将数据集拆分成k个样本量相当的数据组,组件无重叠样本。
2.从k组数据中挑选k-1组用于构建模型,剩下一组用于测试。
3.以此类推,会获得k种训练集和测试集,每一个数据组都将参与构建以及测试。
4.从中选择准确度最高的模型。

# 步骤一:求最准确的Lamda值。
from sklearn.linear_model import RidgeCV
# 为了方便比较,采用上述模型的相同数据集
# x_train, x_test, y_train, y_test = train_test_split(data, y, test_size=0.2, random_state=14)
lambdas = np.logspace(-5, 2, 200)
ridge_cv = RidgeCV(alphas=lambdas, normalize=True, scoring='neg_mean_squared_error', cv=10)
ridge_cv.fit(x_train, y_train)
ridge_best_lambda = ridge_cv.alpha_
print(ridge_best_lambda)
# 步骤二:基于最准确的lambda值建模。
from sklearn.metrics import mean_squared_error
ridge = Ridge(alpha=ridge_best_lambda, normalize=True)
ridge.fit(x_train, y_train)
print(ridge.intercept_)
print(ridge.coef_.tolist())
print(x_train)
# print(pd.Series(index=['Intercept']+boston_data.columns.tolist(), data=[ridge.intercept_] + ridge.coef_.tolist()))
ridge_predict = ridge.predict(x_test)
ridge_MSE = mean_squared_error(y_test, ridge_predict)
ridge_MAE = mean_absolute_error(y_test, ridge_predict)
ridge_score = ridge.score(x_test, y_test)
print('岭回归:MSE:{}\nMAE:{}\nACC:{}'.format(ridge_MSE, ridge_MAE, ridge_score*100))

4、Lasso回归

在线性回归模型的基础之上添加一个L1惩罚项(也称正则项)。相较于岭回归降低了模型的复杂度。

Lasso回归交叉验证的参数

LassoCV(alphas=None, fit_intercept=True, 
normalize=False,max_iter=1000, tol=0.0001)
# 参数
alphas:指定具体的Lambda值列表⽤于模型的运算
fit_intercept:bool类型参数,是否需要拟合截距项,默认为True
normalize:bool类型参数,建模时是否需要对数据集做标准化处理,默认为False
max_iter:指定模型最⼤的迭代次数,默认为1000次

# 步骤一:求最准确的Lamda值
from sklearn.linear_model import Lasso, LassoCV
lasso_cv = LassoCV(alphas=lambdas, normalize=True, cv=10, max_iter=10000)
lasso_cv.fit(x_train, y_train)
lasso_best_lambda = lasso_cv.alpha_
print(lasso_best_lambda)
# 步骤二:基于最准确的lamda值建模
lasso = Lasso(alpha=lasso_best_lambda, normalize=True)
lasso.fit(x_train, y_train)
lasso_predict = lasso.predict(x_test)
lasso_MSE = mean_squared_error(y_test, ridge_predict)
lasso_MAE = mean_absolute_error(y_test, ridge_predict)
lasso_score = lasso.score(x_test, y_test)
print('lasso回归:MSE:{}\nMAE:{}\nACC:{}'.format(lasso_MSE, lasso_MAE, lasso_score*100))

 5、预测值与真实值的可视化

线性回归实战1:预测boston房价_第7张图片

你可能感兴趣的:(线性回归,回归,算法)