回归剖析
介绍
回归剖析是一种统计剖析办法,用于树立变量之间的数学联系并对它们进行猜测和操控。回归剖析的首要意图是研讨一个或多个自变量与因变量之间的联系。简略线性回归剖析触及一个自变量和一个因变量,而多元回归剖析触及两个或更多个自变量和一个因变量。
我的了解:回归的意图是进行猜测,比方 2000 – 2020 年鱼塘的产值数据都存在,现在需求对 2020-2030 年鱼塘的产值进行猜测,就能够用回归剖析的算法
线性回归公式:y = ax + b
多元回归公式(举个例子):y = ax^n + bx^(n-1) + cx^(n-2) + ... + z
- 自变量(年份):x
- 因变量(产值):y
- 算法模型训练出来的常量:a、b、c、d ……
在回归剖析中,自变量通常是已知的,并用于猜测或操控因变量。当猜测因变量时,回归剖析可认为未来事件供给牢靠的猜测成果。当操控因变量时,回归剖析能够评价自变量对因变量的效果,以便在未来研讨或试验中应用这些发现。
回归剖析广泛应用于许多范畴,包含经济学、社会科学、医学、生物学、物理学等。一些常见的应用包含市场研讨、风险评价、物理建模、药物研发和轿车工程。
具体完成
1、导入依靠
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
2、导入东西类
/**
* 用于核算回归曲线
* 第一步:核算拟合数据 calcFittingData(x,y)
* 第二步:依据拟合数据,核算对应 x1 的回归数据 y1
*/
public class Regression {
/**
* 核算拟合数据,用于多项式的核算
*/
public static double[] calcFittingData(List<Double> x, List<Double> y){
// 构建数据点集合
WeightedObservedPoints points = new WeightedObservedPoints();
for (int i = 0; i < x.size(); i++) {
points.add(x.get(i), y.get(i));
}
// 选择多项式次数
int degree = 3;
// 构建多项式回归器
PolynomialCurveFitter fitter = PolynomialCurveFitter.create(degree);
// 拟合数据
return fitter.fit(points.toList());
}
/**
* 依据拟合数据,核算对应 x1 的回归数据 y1
* @param fittingData 上一步得到的拟合数据
* @param x 需求猜测的点位
* @return 猜测的值
*/
public static double calcRegressionValue(double[] fittingData, double x){
double result = 0.0;
for (int i = fittingData.length - 1; i >= 0; i--) {
result = result * x + fittingData[i];
}
return NumberUtil.round(result, 4).doubleValue();
}
}
3、生成历史数据
public class DataGenerate {
public static void main(String[] args) {
// List<Double> x = DoubleStream.iterate(2000, n -> n + 0.2).limit(100).boxed().collect(Collectors.toList());
// List<Double> y = DoubleStream.iterate(1, n-> n + RandomUtil.randomDouble(-10, 10)).limit(100).boxed().collect(Collectors.toList());
List<Double> x = JSON.parseArray("[2000.0, 2000.2, 2000.4, 2000.6000000000001, 2000.8000000000002, 2001.0000000000002, 2001.2000000000003, 2001.4000000000003, 2001.6000000000004, 2001.8000000000004, 2002.0000000000005, 2002.2000000000005, 2002.4000000000005, 2002.6000000000006, 2002.8000000000006, 2003.0000000000007, 2003.2000000000007, 2003.4000000000008, 2003.6000000000008, 2003.8000000000009, 2004.000000000001, 2004.200000000001, 2004.400000000001, 2004.600000000001, 2004.800000000001, 2005.0000000000011, 2005.2000000000012, 2005.4000000000012, 2005.6000000000013, 2005.8000000000013, 2006.0000000000014, 2006.2000000000014, 2006.4000000000015, 2006.6000000000015, 2006.8000000000015, 2007.0000000000016, 2007.2000000000016, 2007.4000000000017, 2007.6000000000017, 2007.8000000000018, 2008.0000000000018, 2008.2000000000019, 2008.400000000002, 2008.600000000002, 2008.800000000002, 2009.000000000002, 2009.200000000002, 2009.4000000000021, 2009.6000000000022, 2009.8000000000022, 2010.0000000000023, 2010.2000000000023, 2010.4000000000024, 2010.6000000000024, 2010.8000000000025, 2011.0000000000025, 2011.2000000000025, 2011.4000000000026, 2011.6000000000026, 2011.8000000000027, 2012.0000000000027, 2012.2000000000028, 2012.4000000000028, 2012.6000000000029, 2012.800000000003, 2013.000000000003, 2013.200000000003, 2013.400000000003, 2013.600000000003, 2013.8000000000031, 2014.0000000000032, 2014.2000000000032, 2014.4000000000033, 2014.6000000000033, 2014.8000000000034, 2015.0000000000034, 2015.2000000000035, 2015.4000000000035, 2015.6000000000035, 2015.8000000000036, 2016.0000000000036, 2016.2000000000037, 2016.4000000000037, 2016.6000000000038, 2016.8000000000038, 2017.0000000000039, 2017.200000000004, 2017.400000000004, 2017.600000000004, 2017.800000000004, 2018.000000000004, 2018.2000000000041, 2018.4000000000042, 2018.6000000000042, 2018.8000000000043, 2019.0000000000043, 2019.2000000000044, 2019.4000000000044, 2019.6000000000045, 2019.8000000000045]", Double.class);
List<Double> y = JSONArray.parseArray("[1.0, 10.42906325168871, 11.26071129761812, 14.634243269661564, 17.307783514340677, 14.445901316527763, 13.293616154532192, 23.237659619927054, 14.457660333900618, 5.921597276626496, 7.702984596970076, 6.524844239013698, -1.5960356170082886, -5.560994664449881, -6.2830433095772715, -13.337225004507358, -13.216263420456446, -17.304496396195166, -23.892387031375236, -14.371445291535515, -4.567274662509281, -13.70839788551179, -7.043528004304555, -2.5458381300587405, 7.162985271186795, 0.9621560164152587, 8.656852150628934, 8.001760651158149, 4.665505015132808, 11.06667379861096, 15.935532921303357, 11.772343753661755, 17.240023933014392, 20.725849565650947, 26.530486782767607, 33.65381775688789, 30.860190145623353, 33.64173445019578, 36.68001666381011, 43.041099209116034, 49.34199357956133, 49.28431164607146, 47.42987740061483, 46.181005186790195, 50.916612065393295, 55.92817502056798, 58.68406683831894, 57.056091061056144, 51.2465621566577, 59.54939721768027, 57.61449805533475, 49.33510392003578, 50.268702082462724, 53.05629699476951, 57.38147080259562, 55.54787439905726, 65.27895027772341, 58.92933730696279, 52.56821849857317, 55.73207898990508, 63.79709000231691, 56.27245713523001, 50.62707899653262, 59.19803055821095, 53.067329345898614, 55.80932675121849, 54.98240075838871, 46.25440822982649, 49.97837740104257, 59.55490162760393, 51.62529700925586, 45.82178379468647, 39.86561267351533, 46.79088499145376, 38.85287321384413, 40.855002655929795, 31.77199874359535, 34.84457819539462, 28.1545543743269, 28.115016953106398, 36.65232853824082, 45.942482890756054, 53.09468749771434, 60.87143535541702, 55.86161670529165, 59.13630259872876, 56.51387974596331, 55.00271108850981, 60.08807639190195, 54.34522427227326, 58.96382641685028, 67.15709893357109, 75.5639618703819, 65.81677636550283, 58.92258534065034, 49.22604248835671, 44.813368860886236, 36.6180611087144, 46.29321257791983, 56.056426120193535]", Double.class);
double[] fittingData = Regression.calcFittingData(x, y);
List<Double> y1 = x.stream().map(e -> {
return Regression.calcRegressionValue(fittingData, e);
}).collect(Collectors.toList());
System.out.println("x = " + x);
System.out.println("y = " + y);
System.out.println("y1 = " + y1);
}
}
4、制作图形
import matplotlib.pyplot as plt
x = [2000.0, 2000.2, 2000.4, 2000.6000000000001, 2000.8000000000002, 2001.0000000000002, 2001.2000000000003, 2001.4000000000003, 2001.6000000000004, 2001.8000000000004, 2002.0000000000005, 2002.2000000000005, 2002.4000000000005, 2002.6000000000006, 2002.8000000000006, 2003.0000000000007, 2003.2000000000007, 2003.4000000000008, 2003.6000000000008, 2003.8000000000009, 2004.000000000001, 2004.200000000001, 2004.400000000001, 2004.600000000001, 2004.800000000001, 2005.0000000000011, 2005.2000000000012, 2005.4000000000012, 2005.6000000000013, 2005.8000000000013, 2006.0000000000014, 2006.2000000000014, 2006.4000000000015, 2006.6000000000015, 2006.8000000000015, 2007.0000000000016, 2007.2000000000016, 2007.4000000000017, 2007.6000000000017, 2007.8000000000018, 2008.0000000000018, 2008.2000000000019, 2008.400000000002, 2008.600000000002, 2008.800000000002, 2009.000000000002, 2009.200000000002, 2009.4000000000021, 2009.6000000000022, 2009.8000000000022, 2010.0000000000023, 2010.2000000000023, 2010.4000000000024, 2010.6000000000024, 2010.8000000000025, 2011.0000000000025, 2011.2000000000025, 2011.4000000000026, 2011.6000000000026, 2011.8000000000027, 2012.0000000000027, 2012.2000000000028, 2012.4000000000028, 2012.6000000000029, 2012.800000000003, 2013.000000000003, 2013.200000000003, 2013.400000000003, 2013.600000000003, 2013.8000000000031, 2014.0000000000032, 2014.2000000000032, 2014.4000000000033, 2014.6000000000033, 2014.8000000000034, 2015.0000000000034, 2015.2000000000035, 2015.4000000000035, 2015.6000000000035, 2015.8000000000036, 2016.0000000000036, 2016.2000000000037, 2016.4000000000037, 2016.6000000000038, 2016.8000000000038, 2017.0000000000039, 2017.200000000004, 2017.400000000004, 2017.600000000004, 2017.800000000004, 2018.000000000004, 2018.2000000000041, 2018.4000000000042, 2018.6000000000042, 2018.8000000000043, 2019.0000000000043, 2019.2000000000044, 2019.4000000000044, 2019.6000000000045, 2019.8000000000045]
y = [1.0, 10.42906325168871, 11.26071129761812, 14.634243269661564, 17.307783514340677, 14.445901316527763, 13.293616154532192, 23.237659619927054, 14.457660333900618, 5.921597276626496, 7.702984596970076, 6.524844239013698, -1.5960356170082886, -5.560994664449881, -6.2830433095772715, -13.337225004507358, -13.216263420456446, -17.304496396195166, -23.892387031375236, -14.371445291535515, -4.567274662509281, -13.70839788551179, -7.043528004304555, -2.5458381300587405, 7.162985271186795, 0.9621560164152587, 8.656852150628934, 8.001760651158149, 4.665505015132808, 11.06667379861096, 15.935532921303357, 11.772343753661755, 17.240023933014392, 20.725849565650947, 26.530486782767607, 33.65381775688789, 30.860190145623353, 33.64173445019578, 36.68001666381011, 43.041099209116034, 49.34199357956133, 49.28431164607146, 47.42987740061483, 46.181005186790195, 50.916612065393295, 55.92817502056798, 58.68406683831894, 57.056091061056144, 51.2465621566577, 59.54939721768027, 57.61449805533475, 49.33510392003578, 50.268702082462724, 53.05629699476951, 57.38147080259562, 55.54787439905726, 65.27895027772341, 58.92933730696279, 52.56821849857317, 55.73207898990508, 63.79709000231691, 56.27245713523001, 50.62707899653262, 59.19803055821095, 53.067329345898614, 55.80932675121849, 54.98240075838871, 46.25440822982649, 49.97837740104257, 59.55490162760393, 51.62529700925586, 45.82178379468647, 39.86561267351533, 46.79088499145376, 38.85287321384413, 40.855002655929795, 31.77199874359535, 34.84457819539462, 28.1545543743269, 28.115016953106398, 36.65232853824082, 45.942482890756054, 53.09468749771434, 60.87143535541702, 55.86161670529165, 59.13630259872876, 56.51387974596331, 55.00271108850981, 60.08807639190195, 54.34522427227326, 58.96382641685028, 67.15709893357109, 75.5639618703819, 65.81677636550283, 58.92258534065034, 49.22604248835671, 44.813368860886236, 36.6180611087144, 46.29321257791983, 56.056426120193535]
y1 = [0.8864, 0.8444, 0.8631, 0.9407, 1.0758, 1.2667, 1.5119, 1.8097, 2.1586, 2.557, 3.0032, 3.4957, 4.033, 4.6133, 5.2352, 5.897, 6.5971, 7.334, 8.106, 8.9116, 9.7491, 10.6171, 11.5138, 12.4377, 13.3872, 14.3607, 15.3567, 16.3734, 17.4095, 18.4631, 19.5328, 20.617, 21.7141, 22.8224, 23.9404, 25.0665, 26.1992, 27.3367, 28.4776, 29.6202, 30.7629, 31.9042, 33.0424, 34.1761, 35.3034, 36.423, 37.5332, 38.6324, 39.7189, 40.7913, 41.848, 42.8872, 43.9075, 44.9073, 45.8849, 46.8388, 47.7674, 48.669, 49.5422, 50.3853, 51.1966, 51.9747, 52.7179, 53.4247, 54.0934, 54.7225, 55.3103, 55.8553, 56.3559, 56.8105, 57.2175, 57.5753, 57.8823, 58.1369, 58.3376, 58.4827, 58.5707, 58.5999, 58.5688, 58.4758, 58.3192, 58.0976, 57.8092, 57.4526, 57.0261, 56.5281, 55.957, 55.3113, 54.5894, 53.7896, 52.9104, 51.9501, 50.9073, 49.7802, 48.5674, 47.2672, 45.878, 44.3982, 42.8263, 41.1606]
plt.plot(x, y, x, y1)
plt.show()
成果
mybatis-enhance-actable
开源库房:gitee.com/sunchenbin/…
介绍
mybatis-enhance-actable 是一款 mybatis plus 的增强东西,能够依据实体类主动建表,实体类产生修正,会主动同步到数据库,这样修正字段就不用在数据库和实体类中频频切换了,能够较大进步开发功率。
运用这个东西之后,开发形式就能够从面向数据库转变到面向实体类开发了
运用步骤
条件:装备好数据库
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/config_center?useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=11111111
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
1、导入依靠
<dependency>
<groupId>com.gitee.sunchenbin.mybatis.actable</groupId>
<artifactId>mybatis-enhance-actable</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
2、启动类上参加注解
@MapperScan("com.gitee.sunchenbin.mybatis.actable.dao.*")
@ComponentScan(basePackages = {"com.gitee.sunchenbin.mybatis.actable.manager.*"})
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
3、增加装备
actable.table.auto=update
actable.model.pack=com.rabbit.entity
actable.database.type=mysql
mybatis-plus.mapper-locations=classpath*:com/gitee/sunchenbin/mybatis/actable/mapping/*/*Mapper.xml
4、实体类运用注解
缺点
- 装备太多,装备不行简略,没有用到 springboot 主动装配特性
- 强依靠于 mybatis-plus,不行解耦,类似这种底层结构,依靠越少越好,其实完全能够运用 jdbc 去做
- 主动建表、改表、删表功能不安全,可能我对这个项目部署,不知道他的开发流程,我先在数据库新建好了表,项目一启动因为没有增加实体类把我的表全给删除了。。。。。。
- 许多公司不答应项目直接操作数据库,供给的数据库只要查询权限,如果需求修正表,需求开发提 db 工单,经过层层审核,最后由 dba 进行履行,在这一层,许多公司都不会运用这
完成原理
1、获取数据表的元数据
数据库每张表的元数据都在 information_schema 这个 mysql 自带的库里存在,能够直接取出来
select * from information_schema.columns where table_name = 'pilot_task' and table_schema = (select database())
2、扫描代码中的实体类,运用反射提取字段、注解信息
3、将上面两堆数据进行比对,找出需求新建的表、需求修正、需求删除的表
4、拼接 sql 语句
最后
底座也有主动建表、改表功能,可是我发现有个问题,表注释不会生成
MapStruct
github:github.com/mapstruct/m…
介绍
389c3b3079459d553a01061fb41eab17.pdf
在开发过程中,我们经常会进行 AO、VO、DTO、PO 之间的特点复制,常用的办法有以下几种:
- spring 的
BeanUtils.copyProperties()
- hutool 的 Convert、BeanUtil 东西类
- 手动的 set 值
毫无疑问,手动的 set 值速度是最快的,可是代码就比较多;其他两种底层都是用了反射,在速度上略逊一筹,并且只能复制相同字段称号的特点,运用比较有局限性
下面介绍一下 MapStruct 的长处:
- 而 MapStruct 他的性能是远高于 BeanUtils 的,下面是测试成果:
- 并且 MapStruct 还满足灵活,能够应对特点复制的各种场景
- 运用满足简略
运用步骤
1、导入依靠
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.3.Final</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.3.Final</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2、编写两个完成类
@Data
public class DemoPO {
private String userName;
}
@Data
public class DemoVO {
private String userName;
}
3、编写转化器
@Mapper
public interface DemoConvert {
DemoConvert INSTANCE = Mappers.getMapper(DemoConvert.class);
DemoVO toVo(DemoPO po);
}
4、main 办法运行
public static void main(String[] args) {
DemoPO demoPO = new DemoPO();
demoPO.setUserName("小明");
DemoVO vo = DemoConvert.INSTANCE.toVo(demoPO);
System.out.println(vo);
}
杂乱场景映射
1、场景一:PO 和 VO 字段称号不一致
@Data
public class DemoPO {
private String userName;
}
@Data
public class DemoVO {
private String name;
}
@Mapper
public interface DemoConvert {
DemoConvert INSTANCE = Mappers.getMapper(DemoConvert.class);
@Mapping(target = "name", source = "userName")
DemoVO toVo(DemoPO po);
}
2、多层嵌套映射
@Data
public class DemoPO {
private String userName;
}
@Data
public class DemoVO {
private String name;
}
@Mapper
public interface DemoConvert {
DemoConvert INSTANCE = Mappers.getMapper(DemoConvert.class);
@Mapping(target = "name", source = "userName")
DemoVO toVo(DemoPO po);
List<DemoVO> toVoList(List<DemoPO> poList);
}
public class DemoMain {
public static void main(String[] args) {
DemoPO demoPO = new DemoPO();
demoPO.setUserName("小明");
List<DemoVO> voList = DemoConvert.INSTANCE.toVoList(Collections.singletonList(demoPO));
System.out.println(voList);
}
}
如果嵌套有三层、四层、五层,同样的原理
3、日期时间格式化
@Data
public class DemoPO {
private Date createDate;
}
@Data
public class DemoVO {
private String date;
}
@Mapper
public interface DemoConvert {
DemoConvert INSTANCE = Mappers.getMapper(DemoConvert.class);
@Mapping(target = "date", source = "createDate", dateFormat = "yyyy-MM-dd")
DemoVO toVo(DemoPO po);
}
4、数字格式化
@Data
public class DemoPO {
private Double num;
}
@Data
public class DemoVO {
private String num;
}
@Mapper
public interface DemoConvert {
DemoConvert INSTANCE = Mappers.getMapper(DemoConvert.class);
@Mapping(target = "num", source = "num", numberFormat = "#0.00")
DemoVO toVo(DemoPO po);
}
5、默认值
@Data
public class DemoPO {
private String def;
}
@Data
public class DemoVO {
private String def;
}
@Mapper
public interface DemoConvert {
DemoConvert INSTANCE = Mappers.getMapper(DemoConvert.class);
@Mapping(target = "def", defaultValue = "hello world")
DemoVO toVo(DemoPO po);
}
6、自定义转化
把目标转成 json 字符串
@Data
public class DemoPO {
private Map<String, String> map;
}
@Data
public class DemoVO {
private String map;
}
public class MapConvertUtil {
@Named("toJson")
public String toJson(Map<String, String> map){
return JSONUtil.toJsonStr(map);
}
}
@Mapper(uses = MapConvertUtil.class)
public interface DemoConvert {
DemoConvert INSTANCE = Mappers.getMapper(DemoConvert.class);
@Mapping(target = "map", source = "map", qualifiedByName="toJson")
DemoVO toVo(DemoPO po);
}
public class DemoMain {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("aaa", "bbb");
DemoPO demoPO = new DemoPO();
demoPO.setMap(map);
DemoVO vo = DemoConvert.INSTANCE.toVo(demoPO);
System.out.println(vo);
}
}
原理
MapStruct 的完成原理和 Lombok 类似,都是基于 JSR 269 标准,在源码编译期间生成字节码
JSR 269 它供给了一种机制,答应开发人员编写注解处理器来处理 Java 源代码中的注解,然后生成额定的 Java 代码。
其实便是 java 编译的过程中,会经过 jdk 的 ServiceLoader 这个类,扫描类途径下的META-INF/services/javax.annotation.processing.Processor
这个文件,取出里边的类名进行类加载和实例化,然后调用接口的 process 办法去生成对应的字节码
画图解释
java 程序编译运行阅历以下几个流程
源码编译成 class 文件其实是个比较杂乱的过程