赞
踩
boston房价数据集包括506个样本,每个样本包括13个特征变量和该地区的平均房价,房价显然和多个特征变量相关,对于线性回归模型,先选择一元线性回归与多个特征建立线性方程,观察模型预测的好坏,再选择多元线性回归进行房价预测。
简单线性回归:当回归模型包含一个因变量和一个自变量时。
多项式回归:当只有一个自变量,但同时含有变量的幂(X2,X3)时,称为多项式回归。
多元线性回归:当有不止一个自变量时。
- 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
- 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个):
前几行数据:
y = boston_data.pop('price')
print(boston_data.isnull().sum())
print(boston_data.shape)
print(boston_data.describe())
- import seaborn as sns
- plt.figure(figsize=(12, 8))
- sns.heatmap(boston_data.corr(), annot=True, fmt='.2f', cmap='PuBu')
- plt.show()
-
- 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()
从上图可以看出‘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)
x_train, x_test, y_train, y_test = train_test_split(data, y, test_size=0.2, random_state=14)
我们分别用选择前的特征(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、自变量个数大于样本量。
2、自变量直接存在多重共线性(值高度相关)。
为了解决上述问题,需要使用岭回归模型与Lasso回归模型。下面我们分别用特征选择前和特征选择后的特征,使用SDG、岭回归和Lasso回归观察模型结果。
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))
线性回归模型:。
岭回归模型:。
在线性回归模型的基础上添加一个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))
在线性回归模型的基础之上添加一个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))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。