基本算法——回归

目录

创建工程

加载数据

分析属性

创建与评估回归模型

线性回归

回归树

评估

完整代码

结论


本节将通过分析能源效率数据集(Tsanas和Xifara,2012)学习基本的回归算法。我们将基 于建筑的结构特点(比如表面、墙体与屋顶面积、高度、紧凑度)研究它们的加热与冷却负载要 求。研究者使用一个模拟器设计了12种不同的房屋配置,这些房屋配置通过改变18种建筑特征得 出,他们总共模拟了768种建筑。

我们的首要目标是系统分析每种建筑特征对目标变量------加热或冷却负载------产生的影响。 第二个目标是比较经典线性回归模型相对于其他方法(比如SVM回归、随机森林、神经网络)的 性能。这个任务中,我们将使用Weka库。

创建工程

接着使用上一篇文章的工程:

加载数据

        // 加载数据
        CSVLoader loader = new CSVLoader();
        loader.setFieldSeparator(",");  // 设置CSV文件的字段分隔符为逗号
        loader.setSource(new File(PATH));  // 设置数据源为CSV文件
        Instances data = loader.getDataSet();  // 从CSV文件中加载数据集

分析属性

进行属性分析之前,先了解要处理什么。总共有8个属性描述建筑特征,有两个目标变量:

heating与cooling。
X1 ------相对密实性
X2 ------表面积
X3 ------墙体面积
X4 ------屋顶面积
X5 ------总体高度
X6 ------方向
X7 ------玻璃窗面积
X8 ------玻璃窗区域分布
Y1 ------加热负载
Y2 ------冷却负载

创建与评估回归模型

首先,在特征位置设置分类属性,为加热负载建立学习模型。第二个目标变量(冷却负载)现在可以移除:

java 复制代码
        /*
         * 构建回归模型
         */
        // 设置类别索引为Y1(加热负荷),即目标变量
        data.setClassIndex(data.numAttributes() - 2);  // 设置类别索引为倒数第二个属性,表示Y1
        // 移除最后一个属性Y2,因为Y2是另一个目标变量,我们只处理Y1
        Remove remove = new Remove();
        remove.setOptions(new String[]{"-R", String.valueOf(data.numAttributes())});  // 移除最后一个属性
        remove.setInputFormat(data);  // 设置输入格式
        data = Filter.useFilter(data, remove);  // 应用过滤器,移除最后一个属性

线性回归

首先,使用LinearRegression类创建一个基本的线性回归模型。正如在分类示例中所做的 那样,先初始化一个新模型实例,传递参数与数据,并调用buildClassifier(Instances)方 法:

java 复制代码
        // 构建线性回归模型
        LinearRegression model = new LinearRegression();
        model.buildClassifier(data);  // 使用数据训练线性回归模型
        System.out.println(model);  // 输出线性回归模型的详细信息

结果如下:

Y1 =

    -64.774  * X1 +
     -0.0428 * X2 +
      0.0163 * X3 +
     -0.089  * X4 +
      4.1699 * X5 +
     19.9327 * X7 +
      0.2038 * X8 +
     83.9329

线性回归模型构建了一个函数,它把输入变量线性组合在一起,对加热负载进行评估。特征 前面的数字解释特征对目标变量的影响:符号表示正面影响或负面影响,而大小对应于影响程度。 比如特征X1(相对紧凑度),它与加热负载是负相关的,而玻璃窗面积与加热负载是正相关的。

这两个特征也对最后加热负载的评估有明显影响。

使用交叉验证技术可以对模型性能做类似评估。 做10折交叉验证(10-fold cross-validation)如下:

java 复制代码
        // 10折交叉验证
        Evaluation evaluation = new Evaluation(data);  // 创建评估对象
        evaluation.crossValidateModel(model, data, 10, new Random(1), new String[]{});  // 执行10折交叉验证
        System.out.println(evaluation.toSummaryString());  // 输出交叉验证的概要信息
        double[] coefficients = model.coefficients();  // 获取线性回归模型的系数

结果如下:

Correlation coefficient                  0.956 
Mean absolute error                      2.0923
Root mean squared error                  2.9569
Relative absolute error                 22.8555 %
Root relative squared error             29.282  %
Total Number of Instances              768     

回归树

另一个方法是构建一组回归模型,每一个模型对应于数据中与其自身相关的部分。图3-5展 示了回归模型与回归树之间的主要不同。回归模型指的是一个与所有数据达到最好拟合的独立模 型;而回归树是一组回归模型,每个模型只对一部分数据进行建模。Weka中的M5类用于实现回归树。创建模型时,遵从步骤与前面一样:初始化模型、传递参 数与数据、调用buildClassifier(Instances)方法。

java 复制代码
        // 构建回归树模型(M5P模型)
        M5P m5p = new M5P();
        m5p.setOptions(new String[]{""});  // 设置选项,这里为空
        m5p.buildClassifier(data);  // 使用数据训练M5P回归树模型
        System.out.println(m5p);  // 输出M5P回归树模型的详细信息

结果如下:

M5 pruned model tree:
(using smoothed linear models)

X1 <= 0.75 : 
|   X7 <= 0.175 : 
|   |   X1 <= 0.65 : LM1 (48/1.264%)
|   |   X1 >  0.65 : LM2 (96/3.201%)
|   X7 >  0.175 : 
|   |   X1 <= 0.65 : LM3 (80/3.652%)
|   |   X1 >  0.65 : 
|   |   |   X7 <= 0.325 : LM4 (80/3.724%)
|   |   |   X7 >  0.325 : 
|   |   |   |   X1 <= 0.675 : LM5 (20/1.687%)
|   |   |   |   X1 >  0.675 : 
|   |   |   |   |   X8 <= 2.5 : LM6 (24/1.314%)
|   |   |   |   |   X8 >  2.5 : 
|   |   |   |   |   |   X8 <= 4.5 : LM7 (24/2.737%)
|   |   |   |   |   |   X8 >  4.5 : 
|   |   |   |   |   |   |   X1 <= 0.7 : LM8 (4/0.91%)
|   |   |   |   |   |   |   X1 >  0.7 : LM9 (8/1.265%)
X1 >  0.75 : 
|   X1 <= 0.805 : 
|   |   X7 <= 0.175 : LM10 (48/5.775%)
|   |   X7 >  0.175 : 
|   |   |   X7 <= 0.325 : LM11 (40/5.26%)
|   |   |   X7 >  0.325 : LM12 (40/5.756%)
|   X1 >  0.805 : 
|   |   X7 <= 0.175 : 
|   |   |   X8 <= 1.5 : 
|   |   |   |   X7 <= 0.05 : 
|   |   |   |   |   X2 <= 539 : LM13 (4/0%)
|   |   |   |   |   X2 >  539 : LM14 (12/4.501%)
|   |   |   |   X7 >  0.05 : 
|   |   |   |   |   X1 <= 0.94 : LM15 (12/4.329%)
|   |   |   |   |   X1 >  0.94 : LM16 (4/0.226%)
|   |   |   X8 >  1.5 : 
|   |   |   |   X1 <= 0.94 : LM17 (48/5.693%)
|   |   |   |   X1 >  0.94 : LM18 (16/1.119%)
|   |   X7 >  0.175 : 
|   |   |   X1 <= 0.84 : 
|   |   |   |   X7 <= 0.325 : 
|   |   |   |   |   X8 <= 2.5 : LM19 (8/3.901%)
|   |   |   |   |   X8 >  2.5 : LM20 (12/3.913%)
|   |   |   |   X7 >  0.325 : LM21 (20/5.632%)
|   |   |   X1 >  0.84 : 
|   |   |   |   X7 <= 0.325 : LM22 (60/4.548%)
|   |   |   |   X7 >  0.325 : 
|   |   |   |   |   X3 <= 306.25 : LM23 (40/4.504%)
|   |   |   |   |   X3 >  306.25 : LM24 (20/6.934%)

LM num: 1
Y1 = 
	72.2602 * X1 
	+ 0.0053 * X3 
	+ 41.5669 * X7 
	- 0.0049 * X8 
	- 37.6688

LM num: 2
Y1 = 
	-14.6772 * X1 
	+ 0.0053 * X3 
	+ 40.2316 * X7 
	+ 0.0181 * X8 
	+ 15.649

LM num: 3
Y1 = 
	84.5112 * X1 
	+ 0.0053 * X3 
	+ 13.9115 * X7 
	- 0.1471 * X8 
	- 42.4943

LM num: 4
Y1 = 
	-2.8359 * X1 
	+ 0.0053 * X3 
	+ 4.3146 * X7 
	- 0.0111 * X8 
	+ 12.0357

LM num: 5
Y1 = 
	-6.0295 * X1 
	+ 0.0053 * X3 
	+ 4.3146 * X7 
	- 0.0524 * X8 
	+ 16.0295

LM num: 6
Y1 = 
	-4.3262 * X1 
	+ 0.0053 * X3 
	+ 4.3146 * X7 
	- 0.0665 * X8 
	+ 14.5905

LM num: 7
Y1 = 
	-4.3262 * X1 
	+ 0.0053 * X3 
	+ 4.3146 * X7 
	- 0.0888 * X8 
	+ 14.5832

LM num: 8
Y1 = 
	-4.3262 * X1 
	+ 0.0053 * X3 
	+ 4.3146 * X7 
	- 0.1025 * X8 
	+ 14.5352

LM num: 9
Y1 = 
	-0.8154 * X1 
	+ 0.0053 * X3 
	+ 4.3146 * X7 
	- 0.1025 * X8 
	+ 11.9531

LM num: 10
Y1 = 
	105.9033 * X1 
	+ 0.0113 * X3 
	+ 59.6616 * X7 
	+ 0.0975 * X8 
	- 58.7462

LM num: 11
Y1 = 
	81.6537 * X1 
	+ 0.0113 * X3 
	+ 10.8932 * X7 
	+ 0.0559 * X8 
	- 33.0837

LM num: 12
Y1 = 
	64.6565 * X1 
	+ 0.0113 * X3 
	+ 10.8932 * X7 
	- 0.0337 * X8 
	- 18.0037

LM num: 13
Y1 = 
	3.2622 * X1 
	- 0.0018 * X2 
	+ 0.0164 * X3 
	+ 44.6313 * X7 
	+ 0.0592 * X8 
	+ 11.9461

LM num: 14
Y1 = 
	9.1337 * X1 
	- 0.0018 * X2 
	+ 0.0164 * X3 
	- 0.0494 * X6 
	+ 44.6313 * X7 
	+ 0.0592 * X8 
	+ 7.321

LM num: 15
Y1 = 
	11.8776 * X1 
	- 0.0018 * X2 
	+ 0.0164 * X3 
	- 0.0428 * X6 
	+ 44.6313 * X7 
	+ 0.0592 * X8 
	+ 7.0198

LM num: 16
Y1 = 
	3.2622 * X1 
	- 0.0018 * X2 
	+ 0.0164 * X3 
	+ 44.6313 * X7 
	+ 0.0592 * X8 
	+ 14.1593

LM num: 17
Y1 = 
	35.1381 * X1 
	- 0.0018 * X2 
	+ 0.0164 * X3 
	+ 16.7723 * X7 
	+ 0.0592 * X8 
	- 10.1661

LM num: 18
Y1 = 
	3.2622 * X1 
	- 0.0018 * X2 
	+ 0.0164 * X3 
	+ 16.7723 * X7 
	+ 0.0592 * X8 
	+ 16.4949

LM num: 19
Y1 = 
	8.5464 * X1 
	- 0.0012 * X2 
	+ 0.029 * X3 
	+ 15.2851 * X7 
	- 0.2151 * X8 
	+ 7.86

LM num: 20
Y1 = 
	8.5464 * X1 
	- 0.0012 * X2 
	+ 0.029 * X3 
	+ 15.2851 * X7 
	- 0.0475 * X8 
	+ 7.4789

LM num: 21
Y1 = 
	8.5464 * X1 
	- 0.0012 * X2 
	+ 0.029 * X3 
	+ 15.2851 * X7 
	+ 0.013 * X8 
	+ 8.5537

LM num: 22
Y1 = 
	1.4309 * X1 
	- 0.0012 * X2 
	+ 0.1248 * X3 
	+ 9.5464 * X7 
	+ 0.0373 * X8 
	- 10.9927

LM num: 23
Y1 = 
	5.1744 * X1 
	- 0.0012 * X2 
	+ 0.0633 * X3 
	+ 9.5464 * X7 
	+ 0.0235 * X8 
	+ 5.7355

LM num: 24
Y1 = 
	5.1744 * X1 
	- 0.0012 * X2 
	+ 0.0761 * X3 
	+ 9.5464 * X7 
	- 0.0805 * X8 
	+ 3.4386

Number of Rules : 24

这棵树总共有13个叶子,每个叶子对应于一个线性方程。

评估

java 复制代码
        // 10折交叉验证
        evaluation = new Evaluation(data);  // 重新创建评估对象
        evaluation.crossValidateModel(m5p, data, 10, new Random(1), new String[]{});  // 执行10折交叉验证
        System.out.println(evaluation.toSummaryString());  // 输出交叉验证的概要信息

结果如下:

Correlation coefficient                  0.996 
Mean absolute error                      0.6497
Root mean squared error                  0.9164
Relative absolute error                  7.0972 %
Root relative squared error              9.0753 %
Total Number of Instances              768  

完整代码

java 复制代码
    private static String PATH = ClassUtils.getDefaultClassLoader().getResource("ENB2012_data.csv").getPath();

    public static void main(String[] args) throws Exception {
        // 加载数据
        CSVLoader loader = new CSVLoader();
        loader.setFieldSeparator(",");  // 设置CSV文件的字段分隔符为逗号
        loader.setSource(new File(PATH));  // 设置数据源为CSV文件
        Instances data = loader.getDataSet();  // 从CSV文件中加载数据集
        /*
         * 构建回归模型
         */
        // 设置类别索引为Y1(加热负荷),即目标变量
        data.setClassIndex(data.numAttributes() - 2);  // 设置类别索引为倒数第二个属性,表示Y1
        // 移除最后一个属性Y2,因为Y2是另一个目标变量,我们只处理Y1
        Remove remove = new Remove();
        remove.setOptions(new String[]{"-R", String.valueOf(data.numAttributes())});  // 移除最后一个属性
        remove.setInputFormat(data);  // 设置输入格式
        data = Filter.useFilter(data, remove);  // 应用过滤器,移除最后一个属性
        // 构建线性回归模型
        LinearRegression model = new LinearRegression();
        model.buildClassifier(data);  // 使用数据训练线性回归模型
        System.out.println(model);  // 输出线性回归模型的详细信息
        // 10折交叉验证
        Evaluation evaluation = new Evaluation(data);  // 创建评估对象
        evaluation.crossValidateModel(model, data, 10, new Random(1), new String[]{});  // 执行10折交叉验证
        System.out.println(evaluation.toSummaryString());  // 输出交叉验证的概要信息
        double[] coefficients = model.coefficients();  // 获取线性回归模型的系数
        // 构建回归树模型(M5P模型)
        M5P m5p = new M5P();
        m5p.setOptions(new String[]{""});  // 设置选项,这里为空
        m5p.buildClassifier(data);  // 使用数据训练M5P回归树模型
        System.out.println(m5p);  // 输出M5P回归树模型的详细信息
        // 10折交叉验证
        evaluation = new Evaluation(data);  // 重新创建评估对象
        evaluation.crossValidateModel(m5p, data, 10, new Random(1), new String[]{});  // 执行10折交叉验证
        System.out.println(evaluation.toSummaryString());  // 输出交叉验证的概要信息
    }

结论

对于线性回归模型:

(1)相关性系数(Correlation coefficient)为0.956,表明模型预测值与实际值之间有较强的相关性。

(2)平均绝对误差(Mean absolute error)为2.0923,表示预测值与实际值之间的平均绝对差距。

(3)均方根误差(Root mean squared error)为2.9569,它衡量了预测值与实际值之间的标准偏差。

(4)相对绝对误差(Relative absolute error)和相对均方根误差(Root relative squared error)分别为22.8555%和29.282%,这些指标是相对于实际值的误差比例。

对于M5模型树:

(1)相关性系数为0.996,比线性回归模型更高,说明M5模型树的预测值与实际值的相关性更强。

(2)平均绝对误差降低到0.6497,表明M5模型树的预测更为准确。

(3)均方根误差也降低到0.9164,说明预测值与实际值的偏差更小。

(4)相对绝对误差和相对均方根误差分别降低到7.0972%和9.0753%,显示M5模型树在相对误差上也有显著改善。

相关推荐
Q_19284999061 小时前
基于Spring Boot的便民医疗服务小程序
spring boot·后端·小程序
Studying 开龙wu1 小时前
机器学习算法的分类
算法·机器学习·分类·回归
高工智能汽车2 小时前
商用车自动驾驶,迎来大规模量产「临界点」?
人工智能·机器学习·自动驾驶
Java知识日历3 小时前
【内含例子代码】Spring框架的设计模式应用(第二集)
java·开发语言·后端·spring·设计模式
尘浮生5 小时前
Java项目实战II基于微信小程序的家庭大厨(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven
Java知识技术分享5 小时前
spring boot通过文件配置yaml里面的属性
java·spring boot·后端
Demons_kirit5 小时前
Spring Boot + Redis + Sa-Token
spring boot·redis·后端
一休哥助手5 小时前
深入解析Spring Boot项目的类加载与启动流程
java·spring boot·后端
丁总学Java5 小时前
定义一个名为 MyCache 的 Spring 配置类
java·spring