深入理解XGBoost(何龙 著)学习笔记(五)
深入理解XGBoost(何龙 著)学习笔记(五)
本文接上一篇,内容为线性回归,介绍三部分,首先介绍了"模型评估”,然后分别提供了线性回归的模型代码:scikit-learn的LinearRegression 和 xgboost的gblinear 。
本文主要给出两种线性相关的python代码,初学者可以对照代码理解一下两种方法的差异。至此,线性相关的内容更新完毕~
3.2.2 🚜模型评估
模型评估是机器学习中的重要一环,用于评价模型是否具有实际应用价值。模型评估有很多种评估指标,分别适用于不同的机器学习任务,如分类、回归、排序等。很多评估指标同时适用于多种机器学习问题,如准确率、召回率,既可用于分类问题,也可用于 排序问题。线性回归主要用于解决回归问题,回归问题中常用的评估指标有MSE、RMSE、MAE等。本节主要介绍MSE,其他评估指标会在第7章中详细介绍。MSE(Mean Squared Error,均方误差)是指预测值和真实值差值平方的期望值,定义如下:
其中,N为样本数量;yᵢ 表示第i个样本的真实值;Pᵢ 表示第i个样本的预测值。MSE是衡量“平均误差”一种较方便的方法,可以反映数据的变化程度。MSE值越小,表示预测模型的准确性越高。
3.2.3 通过线性回归预测波士顿房价
1)数据样本以及特征说明如下:
🚜:Number of Instances: 506(样本506个)
🚜:Number of Attributes: 13 continuous attributes, 1 binary-valued attribute.(13个连续属性,1个二值属性)
🚜:Attribute Information:
▶ CRIM::::>>>per capita crime rate by town(城镇人均犯罪率)
▶ ZN::::>>>proportion of residential land zoned for lots over 25,000 sq.ft.(住宅用地超过25000平方尺的比例)
▶ INDUS::::>>>proportion of non-retail business acres per town(城镇非零售商业用地比例)
▶ CHAS::::>>>Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)(查尔斯河(如果边界是河流,则为1,否则为0))
▶ NOX::::>>>nitric oxides concentration (parts per 10 million)(一氧化碳浓度)
▶ RM::::>>>average number of rooms per dwelling(住宅的平均房间数量)
▶ AGE::::>>>proportion of owner-occupied units built prior to 1940(1940年以前建成的自住单位比例)
▶ DIS::::>>>weighted distances to five Boston employment centres(到波士顿五个就业中心的加权距离)
▶ RAD::::>>>index of accessibility to radial highways(放射状高速公路可达性指数)
▶ TAX::::>>>full-value property-tax rate per $10,000;(每1万美元房产的全额财产税率)
▶ PTRATIO::::>>>pupil-teacher ratio by town(城镇的学生-教师比例)
▶ B::::>>>1000( - 0.63)^2 where ** is the proportion of 某类 by town(城镇中**居民的占比,的转换值:1000×(Bk - 0.63)²)
▶ LSTAT::::>>>%lower status of the population(低收入阶层人口百分比)
▶ MEDV::::>>>Median value of owner-occupied homes in $1000's)(自住房屋的中位数价值(单位:千美元),这一属性为因变量,其他都是自变量)
本部分提供两种线性回归方法的模型代码展示:scikit-learn的LinearRegression 和 xgboost的gblinear
样本数据示例如下:
2)线性回归模型(scikit-learn的LinearRegression)
##以下为代码
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score, mean_squared_error
#读取数据(此处修改成自己的路径)
datafile = "D:/&%%&……/Boston Housing Dataset/Boston Housing/housing.data"
dataFrame = pd.read_csv(datafile,header=None,sep='\t')dataArray = np.zeros((len(dataFrame), 13)) # 创建dataframe存储 13 个特征
dataOutput = np.zeros((len(dataFrame), 1)) # 创建dataframe存储目标变量(房价)column_names = ["CRIM","ZN","INDUS","CHAS","NOX","RM","AGE","DIS","RAD","TAX","PTRATIO","B","LSTAT","MEDV"]#把自变量(特征)和因变量放入dataframe
for i in range(len(dataFrame)): feature_string = dataFrame.iloc[i][0]feature_list = feature_string.split() # 按空格分割字符串for j in range(len(feature_list)): if j != len(feature_list)-1:dataArray[i][j] = float(feature_list[j]) # 前 13 列是特征else:dataOutput[i] = float(feature_list[j]) # 最后一列是目标变量(房价 MEDV)#划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(dataArray, dataOutput ,test_size = 1/5.,random_state = 8) # 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 1. 训练线性模型 #
lr = LinearRegression()
lr = LinearRegression()
lr.fit(X_train, y_train)# 2. 预测测试集
y_pred = lr.predict(X_test)# 用均方误差评估预测效果
mse = mean_squared_error(y_test, y_pred)
print("MSE: " + repr(mse)) # 3. 可视化预测效果
plt.figure(figsize=(12, 5))# 子图1:真实值 vs 预测值散点图
plt.subplot(1, 2, 1)
plt.scatter(y_test, y_pred, alpha=0.6, color='blue')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2) # 红色对角线
plt.xlabel('真实值')
plt.ylabel('预测值')
plt.title(f'真实值 vs 预测值 (R²={r2_score(y_test, y_pred):.2f})')
plt.grid(True)# 子图2:残差图
plt.subplot(1, 2, 2)
residuals = y_test - y_pred
plt.scatter(y_pred, residuals, alpha=0.6, color='green')
plt.axhline(y=0, color='r', linestyle='--') # 零基准线
plt.xlabel('预测值')
plt.ylabel('残差')
plt.title(f'残差图 (MSE={mean_squared_error(y_test, y_pred):.2f})')
plt.grid(True)plt.tight_layout()
plt.show()# 打印模型系数
print("\n=== 模型系数 ===")# 处理截距项
if isinstance(lr.intercept_, (np.ndarray, list)):print("截距项:\n", np.array2string(lr.intercept_, formatter={'float_kind': lambda x: "%.4f" % x}))
else:print(f"截距项: {lr.intercept_:.4f}")# 处理系数(支持多维情况)
print("\n特征系数:")
if len(lr.coef_.shape) == 1: # 单输出for i, coef in enumerate(lr.coef_):print(f"特征 {i}: {coef:.4f}")
else: # 多输出for target_idx in range(lr.coef_.shape[0]):print(f"\n目标变量 {target_idx}:")for feat_idx, coef in enumerate(lr.coef_[target_idx]):print(f"特征 {feat_idx}: {coef:.4f}")
MSE: 21.638234406478805
3)线性回归模型(xgboost的gblinear)
import pandas as pd
import xgboost as xgb
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error#线性回归模型(xgboost的gblinear)
# 数据转换
train_xgb = xgb.DMatrix(X_train, y_train)
test_xgb = xgb.DMatrix(X_test, y_test) # 参数设置(修正后)
# 参数设置
params = {"objective": "reg:squarederror","booster": "gblinear","eval_metric": "rmse", # 评估指标"verbosity": 1 # 显示训练过程
}# 训练与验证(添加验证集监控)
evals_result = {} # 用于存储评估结果
model = xgb.train(params=params,dtrain=train_xgb,num_boost_round=100, # 迭代次数evals=[(train_xgb, "train"), (test_xgb, "test")], # 监控数据集evals_result=evals_result, # 记录评估结果verbose_eval=10 # 每10轮打印一次日志
)# 绘制训练曲线
plt.figure(figsize=(10, 6))
plt.plot(evals_result["train"]["rmse"], label="训练集RMSE")
plt.plot(evals_result["test"]["rmse"], label="测试集RMSE")
plt.xlabel("迭代次数")
plt.ylabel("RMSE值")
plt.title("XGBoost训练过程监控")
plt.legend()
plt.grid()
plt.show()# 训练与预测
y_pred = model.predict(xgb.DMatrix(X_test))# 用均方误差评估预测效果
mse = mean_squared_error(y_test, y_pred)
print("MSE: " + repr(mse)) # 计算R平方
from sklearn.metrics import r2_score
r2 = r2_score(y_test, y_pred)
print(f"R²分数: {r2:.4f}")# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题# 绘制散点图
plt.scatter(y_test, y_pred, alpha=0.5) # alpha设置点透明度
plt.xlabel("真实值")
plt.ylabel("预测值")
plt.title("预测效果散点图")# 添加参考线(理想情况下点应分布在这条线附近)
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--')plt.grid(True) # 显示网格线
plt.show()
MSE: 25.3748356194846 R²分数: 0.6575
小贴士1:xgboost的gblinear 和 scikit-learn的LinearRegression的区别是什么?