import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LinearRegression # 线性回归
from sklearn.model_selection import train_test_split # 训练测试集分割
from sklearn.metrics import mean_squared_error, r2_score # 模型评估方式:mse、r²
from sklearn.preprocessing import StandardScaler
import math
# 设置字体显示中文
# 设置显示负号
plt.style.use("fivethirtyeight") # 设置不同的绘图样式
# Pandas中只显示3位小数
pd.set_option('display.float_format', lambda x: '{:.3f}'.format(x))
1.处理数据集
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None) # 通过csv文件获取原始数据
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]]) # 提取房屋数据
target = raw_df.values[1::2, 2] # 提取房价列
X = data # 特征值(房屋数据)
y = target # 目标变量
feature_names = np.array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT'])
# print(feature_names.shape)
df = pd.DataFrame(X,columns=feature_names.reshape(13,)) # 房屋数据封装为dataframe,列名设置为feature_names
# 将目标变量(房价)合并到df数据表中
df['MEDV'] = y
2.拆分训练测试集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=123) # 将20%的数据作为测试集
3.使用线性回归算法
# 模型实例化
le = LinearRegression()
# 拟合数据
le.fit(X_train,y_train)
# 得到回归系数
coef = le.coef_ # 13个回归系数 θ1-θ13
intercept = le.intercept_ # 偏移量 θ0
print('回归系数:',coef)
print('偏移量:',intercept)
# 对测试集的数据进行预测
predict1 = le.predict(X_test)
4.评估模型得分
print('R^2:',r2_score(y_test,predict1)) # 1:预测值与真实值完全一致,0:相当于使用均值,<0:预测效果还不如使用均值
print('RMSE:',math.sqrt(mean_squared_error(y_test,predict1))) # 数值越小,表示模型的预测精度越高
R^2: 0.6592466510354102 RMSE: 5.309659665032167
5.将真实值的最小和最大值作为端点,绘制曲线
plt.scatter(y_test,predict1,label='真实值')
plt.plot([y_test.min(),y_test.max()],
[y_test.min(),y_test.max()],
'k--',
lw=3,
label='预测期望'
)
plt.legend()
plt.show()
6.模型改进
7.数据集标准化
ss = StandardScaler()
# 拟合并转换(特征数据)
X = ss.fit_transform(X)
# 拟合并转换(目标变量)
X[:5]
8.切分数据集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=9) # 将20%的数据作为测试集
y_train = pd.DataFrame(y_train).values.ravel() # 改为一维数组(n_samples,)
from sklearn.linear_model import LinearRegression # 线性回归
9.再次使用线性回归算法拟合数据
le = LinearRegression()
le.fit(X_train,y_train)
predict1 = le.predict(X_test)
print('R^2:',r2_score(y_test,predict1))
print('RMSE:',math.sqrt(mean_squared_error(y_test,predict1)))
R^2: 0.7660111574904014 RMSE: 4.86586274783735
10.决策树回归
from sklearn.tree import DecisionTreeRegressor # 决策树回归
# 模型实例化
dtr = DecisionTreeRegressor(max_depth=2)
# 拟合数据
dtr.fit(X_train,y_train)
# 预测
dtr_pre = dtr.predict(X_test)
# 模型评分
print('R^2:',r2_score(y_test,dtr_pre))
print('RMSE:',math.sqrt(mean_squared_error(y_test,dtr_pre)))
R^2: 0.7184184715912991 RMSE: 5.337825363757519
11.随机森林回归
from sklearn.ensemble import RandomForestRegressor
# 模型实例化
rfr = RandomForestRegressor(n_estimators=100,random_state=42)
# 拟合数据
rfr.fit(X_train,y_train)
# 预测
rfr_pre = rfr.predict(X_test)
# 模型评分
print('R^2:',r2_score(y_test,rfr_pre))
print('RMSE:',math.sqrt(mean_squared_error(y_test,rfr_pre)))
R^2: 0.8901060459378567 RMSE: 3.3346417245893964
12.GradientBoosting(梯度提升)
from sklearn.ensemble import GradientBoostingRegressor
# 模型实例化
gb = GradientBoostingRegressor()
# 拟合数据
gb.fit(X_train,y_train)
# 预测
y_pre = gb.predict(X_test)
# 模型评分
print('R^2:',r2_score(y_test,y_pre))
print('RMSE:',math.sqrt(mean_squared_error(y_test,y_pre)))
R^2: 0.896862759540496 RMSE: 3.230502144256022
13.Lasso回归
from sklearn.linear_model import Lasso
# 模型实例化
lo = Lasso(alpha=0.001)
# 拟合数据
lo.fit(X_train,y_train)
# 预测
y_pre = lo.predict(X_test)
# 模型评分
print('R^2:',r2_score(y_test,y_pre))
print('RMSE:',math.sqrt(mean_squared_error(y_test,y_pre)))
R^2: 0.7658874378817631 RMSE: 4.86714896959366
14.SVR-支持向量回归
from sklearn.svm import SVR
# 模型实例化
linear_svr = SVR(kernel='linear')
# 拟合数据
linear_svr.fit(X_train,y_train)
# 预测
y_pre = linear_svr.predict(X_test)
# 模型评分
print('R^2:',r2_score(y_test,y_pre))
print('RMSE:',math.sqrt(mean_squared_error(y_test,y_pre)))
R^2: 0.7176083205556385 RMSE: 5.345498698587928
结论
对数据进行标准化和采用不同的回归模型后,发现:
- 采用Gradient Boosting 算法的话,效果是最好的。最终的评分高达0.8969
- 在机器学习建模的过程中,数据预处理方案和特征工程的设计是很重要的,对我们最终的效果会有很大的影响
15.保存模型与加载
# 导入pickle包
import pickle
# 保存模型,用“wb”方式写入,即是二进制方式
pickle.dump(gb,open('gb.pkl','wb'))
# 加载模型
loaded_model = pickle.load(open('gb.pkl','rb'))
# 使用模型,对测试数据集进行预测
predict1 = loaded_model.predict(X_test)