算法小白的第一次尝试---BoostingTree(手撕提升树)

import org.apache.spark.ml.feature.LabeledPoint
import org.apache.spark.ml.linalg.Vectors
import scala.collection.mutable.ArrayBuffer
/**
  * @author XiaoTangBao
  * @date 2019/3/10 16:00
  * @version 1.0
  * 基于统计学习方法--李航 例8.2 提升树(回归)
  */
object BoostingTree {
  def main(args: Array[String]): Unit = {
    //初始化训练数据
    var orignaldata = ArrayBuffer[LabeledPoint]()
    val arr = Array((1,5.56),(2,5.70),(3,5.91),(4,6.40),(5,6.80),(6,7.05),(7,8.90),(8,8.70),(9,9.00),(10,9.05))
    for(ar <- arr) orignaldata.append(LabeledPoint(ar._2,Vectors.dense(ar._1)))
    //定义切割点
    val cutpoints = ArrayBuffer[Double]()
    for(i <- 0 until arr.length-1) {cutpoints.append(arr(i)._1 + 0.5)}
    //定义满足条件的损失误差Li,当损失误差 <= Li时,退出训练
    val Li = 0.2
    //存放最终训练好的模型
    val modelArr = ArrayBuffer[Double => Double]()
    var flag = true
    while(flag){
      val bestModel = getTree(orignaldata.toArray,cutpoints.toArray)
      modelArr.append(bestModel)
      //更新训练数据data,生成残差表,供下次迭代使用
      for(i<-0 until orignaldata.length ){
        val newLabel = orignaldata(i).label - bestModel(orignaldata(i).features(0))
        orignaldata(i) = LabeledPoint(newLabel,Vectors.dense(orignaldata(i).features(0)))
      }
      //根据残差表计算平方损失误差lx
      var sle = 0.0
      for(s <- orignaldata) sle += math.pow(s.label,2)
      if(sle <= Li) flag = false
    }
    //定义最终的模型
    val finalModel =(x:Double) => {
      var result = 0.0
      for(model <- modelArr) result += model(x)
      result
    }
    //准备相关的测试数据
    val csdata = Array(1.4,2.5,2.8,3.5,4.0,4.5,5.6,6.5,6.7)
    for(cs <- csdata) println(finalModel(cs))
  }

  def getTree(data:Array[LabeledPoint],cutpoints:Array[Double])= {
    //存储每一次迭代产生的(cutpoint,(ms,c1,c2))
    val msArr = ArrayBuffer[(Double,(Double,Double,Double))]()
    for (cutpoint <- cutpoints) msArr.append((cutpoint,calms(cutpoint, data)))
    val best = msArr.sortBy(x => x._2._1).take(1)(0)
    //生成此次迭代的最佳模型更新训练数据data,生成残差表
    val bestModel =(x:Double) =>{
      val cp = best._1
      val c1 = best._2._2
      val c2 = best._2._3
      if(x < cp) c1 else c2
    }
    bestModel
  }

  //假设回归树的损失函数为平方误差损失函数 f(x) = min[min(yi-c1)**2 + min(yi-c2)**2]
  def calms(cutpoint:Double,data:Array[LabeledPoint])={
    //计算误差
    var ms = 0.0
    //min(yi-c1)**2
    var c1 = 0.0
    //min(yi-c2)**2
    var c2 = 0.0
    //c1、c2所对应的数据和
    var s1 = 0.0
    var s2 = 0.0
    //满足条件c1、c2的样本点个数
    var n1 = 0
    var n2 = 0
    for(dt <- data) if(dt.features(0) <= cutpoint) {n1 += 1;s1 += dt.label} else {n2 += 1;s2 += dt.label}
    c1 = s1 / n1
    c2 = s2 / n2
    for(dt <- data) if(dt.features(0) <= cutpoint) ms += math.pow((dt.label - c1),2) else ms += math.pow((dt.label - c2),2)
    (ms,c1,c2)
  }
}
----------------------------------------------------------result---------------------------------------
5.63
5.818310185185186
5.818310185185186
6.551643518518518
6.551643518518518
6.819699074074074
6.819699074074074
8.950162037037037
8.950162037037037
该实验结果完全等价于统计学习上的提升树函数
### 如何在 IntelliJ IDEA 中配置和使用 Swagger #### 添加 Maven 依赖 为了使 Swagger 能够工作,在 `pom.xml` 文件中需加入特定的依赖项。这可以通过编辑项目的构建文件来完成: ```xml <dependencies> <!-- swagger2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <!-- swagger ui --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> </dependencies> ``` 这些依赖会引入必要的库用于生成 API 文档以及提供交互式的 UI 页面[^4]。 #### 创建 Swagger 配置类 接着创建一个新的 Java 类用来初始化并配置 Swagger 实例。通常命名为类似于 `SwaggerConfig.java` 的名称,并放置于合适的位置,比如 `config` 包内: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; @Configuration public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .build(); } private ApiInfo apiInfo(){ return new ApiInfoBuilder().title("API文档").description("").termsOfServiceUrl("") .contact(new Contact("", "", "")) .license("").licenseUrl("").version("1.0") .build(); } } ``` 这段代码定义了一个 Spring Bean 来设置 Swagger 的基本信息和其他选项。 #### 启动应用测试 当上述步骤完成后,启动应用程序即可访问默认路径 `/swagger-ui.html` 查看自动生成的 RESTful 接口文档界面。通过浏览器打开该链接可以浏览到所有已暴露出来的 HTTP 请求方法及其参数说明等信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值