Lesson 9.1 集成学习的三大关键领域、Bagging 方法的基本思想和 RandomForestRegressor 的实现

news2024/11/15 8:14:47

文章目录

  • 一、 集成学习的三大关键领域
  • 二、Bagging 方法的基本思想
  • 三、RandomForestRegressor 的实现

  • 在开始学习之前,先导入我们需要的库,并查看库的版本。
import numpy as np
import pandas as pd
import sklearn
import matplotlib as mlp
import seaborn as sns
import re, pip, conda

for package in [sklearn,mlp,np,pd,sns,pip,conda]:
    print(re.findall("([^']*)",str(package))[2],package.__version__)
#sklearn 1.0.1
#matplotlib 3.4.3
#numpy 1.20.3
#pandas 1.3.4
#seaborn 0.11.2
#pip 21.3.1
#conda 4.10.3
  • 如果有缺少的库或者库的版本比较落后可以采用如下的代码进行下载更新。
#下载
pip install --upgrade scikit-learn
#更新
conda update scikit-learn

一、 集成学习的三大关键领域

  • 集成学习(Ensemble learning)是机器学习中最先进、最有效、最具研究价值的领域之一,这类方法会训练多个弱评估器(base estimators)、并将它们输出的结果以某种方式结合起来解决一个问题。
  • 在过去十年中,人工智能相关产业蓬勃发展,计算机视觉、自然语言处理、语音识别等领域不断推陈出新、硕果累累,但热闹是深度学习的,机器学习好似什么也没有。2012 年之后,传统机器学习占据的搜索、推荐、翻译、各类预测领域都被深度学习替代或入侵,在招聘岗位中,69% 的岗位明确要求深度学习技能,传统机器学习算法在这一场轰轰烈烈的人工智能热潮当中似乎有些被冷落了。
  • 在人工智能大热的背后,集成学习就如同裂缝中的一道阳光,凭借其先进的思想、优异的性能杀出了一条血路,成为当代机器学习领域中最受学术界和产业界青睐的领域。
  • 从今天的眼光来看,集成学习是:
  • (1) 当代工业应用中,唯一能与深度学习算法分庭抗礼的算法;
  • (2) 数据竞赛高分榜统治者,KDDcup、Kaggle、天池、DC 冠军队御用算法;
  • (3) 在搜索、推荐、广告等众多领域,事实上的工业标准和基准模型;
  • (4) 任何机器学习/深度学习工作者都必须掌握其原理、熟读其思想的领域。
  • 在集成学习的发展历程中,集成的思想以及方法启发了众多深度学习和机器学习方面的工作,在学术界和工业界都取得了巨大的成功。今天,集成学习可以被分为三个主要研究领域:
    -(1) 模型融合。
    模型融合在最初的时候被称为分类器结合,这个领域主要关注强评估器,试图设计出强大的规则来融合强分类器的结果、以获取更好的融合结果。这个领域的手段主要包括了投票法 Voting、堆叠法 Stacking、混合法 Blending等,且被融合的模型需要是强分类器。
    模型融合技巧是机器学习/深度学习竞赛中最为可靠的提分手段之一,常言道:当你做了一切尝试都无效,试试模型融合。
  • (2) 弱分类器集成。
  • 弱分类器集成主要专注于对传统机器学习算法的集成,这个领域覆盖了大部分我们熟悉的集成算法和集成手段,如装袋法 bagging,提升法 boosting。这个领域试图设计强大的集成算法、来将多个弱学习器提升成为强学习器。
  • (3) 混合专家模型(mixture of experts)。
  • 混合专家模型常常出现在深度学习(神经网络)的领域。在其他集成领域当中,不同的学习器是针对同一任务、甚至在同一数据上进行训练。
  • 但在混合专家模型中,我们将一个复杂的任务拆解成几个相对简单且更小的子任务,然后针对不同的子任务训练个体学习器(专家),然后再结合这些个体学习器的结果得出最终的输出。

二、Bagging 方法的基本思想

  • Bagging又称为装袋法,它是所有集成学习方法当中最为著名、最为简单、也最为有效的操作之一。
  • 在 Bagging 集成当中,我们并行建立多个弱评估器(通常是决策树,也可以是其他非线性算法),并综合多个弱评估器的结果进行输出。
  • 当集成算法目标是回归任务时,集成算法的输出结果是弱评估器输出的结果的平均值,当集成算法的目标是分类任务时,集成算法的输出结果是弱评估器输出的结果少数服从多数。
  • 举例来说,假设现在一个 bagging 集成算法当中有 7 个弱评估器,对任意一个样本而言,输出的结果如下:
#分类的情况:输出7个弱评估器上的分类结果(0,1,2)
r_clf = np.array([0,2,1,1,2,1,0])

b_result_clf = np.argmax(np.bincount(r_clf))

b_result_clf #集成算法在现在的样本上应该输出的类别
#1
  • bincount 会先将 array 由小到大进行排序,然后对每个数值进行计数,并返回计数结果的函数。需要注意的是,bincount 函数不能接受负数输入。
  • argmax 是找到 array 中最大值,并返回最大值索引的函数。
np.bincount(r_clf) #0类2个,1类3个,2类2个
#array([2, 3, 2], dtype=int64)

np.bincount([3,0,2,1,1,2,1,0]) #0类2个,1类3个,2类2个,3类1个
#array([2, 3, 2, 1], dtype=int64)

np.argmax(np.array([2, 3, 2]))
#不难发现,其返回的就是少数服从多数后数量最多的类别
#1

#如果是二分类,涉及到有一些负数类别的,可以使用如下代码
r_clf = np.array([1,1,1,-1,-1,-1,-1])
(r_clf == 1).sum() #整个集成算法当中,输出为1的弱分类器的数量
#3

(r_clf == -1).sum()
#4

b_result_clf = 1 if (r_clf == 1).sum() > (r_clf != 1).sum() else -1
b_result_clf
#-1

#如果评估器的数量是偶数,而少数和多数刚好一致怎么办?
r_clf = np.array([1,1,1,0,0,0,2,2])
  • 从数量一致的类别中随机返回一个类别(需要进行随机设置)。
  • 从数量一致的类别中,返回编码数字更小的类别(如果使用 argmax 函数)。
#回归的情况:输出7个弱评估器上的回归结果
r_reg = np.array([-2.082, -0.601, -1.686, -1.001, -2.037, 0.1284, 0.8500])
b_result_reg = r_reg.mean()
b_result_reg
#-0.9183714285714285
  • 在 sklearn 当中,我们可以接触到两个 Bagging 集成算法,一个是随机森林(RandomForest),另一个是极端随机树(ExtraTrees),他们都是以决策树为弱评估器的有监督算法,可以被用于分类、回归、排序等各种任务。
  • 同时,我们还可以使用 bagging 的思路对其他算法进行集成,比如使用装袋法分类的类 BaggingClassifier 对支持向量机或逻辑回归进行集成。在课程当中,我们将重点介绍随机森林的原理与用法。
Bagging算法集成类
随机森林分类RandmForestClassifier
随机森林回归RandomForestRegressor
极端随机树分类ExtraTreesClassifier
极端随机树回归ExtraTreesRegressor
装袋法分类BaggingClassifier
装袋法回归BaggingRegressor

三、RandomForestRegressor 的实现

  • 随机森林是机器学习领域最常用的算法之一,其算法构筑过程非常简单:从提供的数据中随机抽样出不同的子集,用于建立多棵不同的决策树,并按照 Bagging 的规则对单棵决策树的结果进行集成(回归则平均,分类则少数服从多数)。
  • 只要你充分掌握了决策树的各项属性和参数,随机森林的大部分内容都相当容易理解。
  • 虽然原理上很简单,但随机森林的学习能力异常强大、算法复杂度高、又具备一定的抗过拟合能力,是从根本上来说比单棵决策树更优越的算法。
  • 即便在深入了解机器学习的各种技巧之后,它依然是我们能够使用的最强大的算法之一。原理如此简单、还如此强大的算法在机器学习的世界中是不常见的。在机器学习竞赛当中,随机森林往往是我们在中小型数据上会尝试的第一个算法。
  • 在 sklearn 中,随机森林可以实现回归也可以实现分类。随机森林回归器由类 sklearn.ensemble.RandomForestRegressor 实现,随机森林分类器则有类 sklearn.ensemble.RandomForestClassifier 实现。
  • 我们可以像调用逻辑回归、决策树等其他 sklearn 中的算法一样,使用“实例化、fit、predict/score”三部曲来使用随机森林,同时我们也可以使用 sklearn 中的交叉验证方法来实现随机森林。其中回归森林的默认评估指标为 R2,分类森林的默认评估指标为准确率。
  • 随机森林回归器实现模板如下:
class sklearn.ensemble.RandomForestRegressor(n_estimators=100, *, criterion='squared_error', max_depth=None, min_samples_split=2,
min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, 
bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, ccp_alpha=0.0, max_samples=None)
  • 随机森林分类器实现模板如下:
class sklearn.ensemble.RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2,
min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0,
bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None, ccp_alpha=0.0, 
max_samples=None)
  • 不难发现,随机森林回归器和分类器的参数高度一致,因此我们只需要讲解其中一个类即可。任意集成算法在发源时都是回归类算法,因此我们的重点将会放在回归类算法上。
  • 随机森林有大量的参数,幸运的是,随机森林中所有参数都有默认值,因此即便我们不学习任何参数,也可以调用随机森林算法。我们先来建一片森林看看吧:
  • 先导入必要的库。
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestRegressor as RFR
from sklearn.tree import DecisionTreeRegressor as DTR
from sklearn.model_selection import cross_validate, KFold
  • 这里有几点需要注意:
  • (1) 这里我们不再使用 cross_val_score,转而使用能够输出训练集分数的 cross_validate;
  • (2) 决策树本身就是非常容易过拟合的算法,而集成模型的参数量/复杂度很难支持大规模网格搜索,因此对于随机森林来说,一定要关注算法的过拟合情况。
  • 首先,我们先读入待操作的数据集,并通过 head() 函数读取其中的前五行数据。
data = pd.read_csv(r"D:\Pythonwork\2021ML\PART 2 Ensembles\datasets\House Price\train_encode.csv",index_col=0)
data.head()
#Id	住宅类型	住宅区域	街道接触面积(英尺)	住宅面积	街道路面状况	巷子路面状况	住宅形状(大概)	住宅现状	水电气	...	泳池面积	泳池质量	篱笆质量	其他配置	其他配置的价值	销售月份	销售年份	销售类型	销售状态	SalePrice
#0	0.0	5.0	3.0	36.0	327.0	1.0	0.0	3.0	3.0	0.0	...	0.0	0.0	0.0	0.0	0.0	1.0	2.0	8.0	4.0	208500
#1	1.0	0.0	3.0	51.0	498.0	1.0	0.0	3.0	3.0	0.0	...	0.0	0.0	0.0	0.0	0.0	4.0	1.0	8.0	4.0	181500
#2	2.0	5.0	3.0	39.0	702.0	1.0	0.0	0.0	3.0	0.0	...	0.0	0.0	0.0	0.0	0.0	8.0	2.0	8.0	4.0	223500
#3	3.0	6.0	3.0	31.0	489.0	1.0	0.0	0.0	3.0	0.0	...	0.0	0.0	0.0	0.0	0.0	1.0	0.0	8.0	0.0	140000
#4	4.0	5.0	3.0	55.0	925.0	1.0	0.0	0.0	3.0	0.0	...	0.0	0.0	0.0	0.0	0.0	11.0	2.0	8.0	4.0	250000
#5 rows × 81 columns
  • 可以通过 shape 函数得到数据的行列数量信息。
data.shape
#(1460, 81)
  • 随后对 X 和 y 进行设定,并操作。
X = data.iloc[:,:-1]
y = data.iloc[:,-1]

y #注意,y的类型是整数型,并且y的均值很大,可想而知整体的MSE一定会很大
#0       208500
#1       181500
#2       223500
#3       140000
#4       250000
#         ...  
#1455    175000
#1456    210000
#1457    266500
#1458    142125
#1459    147500
#Name: SalePrice, Length: 1460, dtype: int64

y.mean()
#180921.19589041095

X.shape
#(1460, 80)

X.columns.tolist()
#['Id',
# '住宅类型',
# '住宅区域',
# '街道接触面积(英尺)',
# '住宅面积',
# '街道路面状况',
# '巷子路面状况',
# '住宅形状(大概)',
# '住宅现状',
# '水电气',
# '住宅配置',
# '住宅视野',
# '社区',
# '住宅周边1',
# '住宅周边2',
# '适用家庭',
# '住宅房型',
# '装修质量',
# '整体质量',
# '建造年份',
# '法律拆除年份',
# '天花板类型',
# '天花板材料',
# '户外装饰1',
# '户外装饰2',
# '砖墙类型',
# '砖墙面积',
# '户外材料质量',
# '户外装修质量',
# '地下室类型',
# '地下室深度',
# '地下室质量',
# '花园外墙',
# '地下室现状1',
# '地下室一层标准面积',
# '地下室现状2',
# '地下室二层标准面积',
# '地下室建造现状',
# '整体地下室面积',
# '暖气类型',
# '暖气质量',
# '中央空调',
# '电力系统',
# '二楼面积',
# '三楼面积',
# '全低质量面积',
# '户外活动空间面积',
# '全卫地下室',
# '半卫地下室',
# '全卫及以上',
# '半卫及以上',
# '卧室及以上',
# '厨房及以上',
# '厨房质量',
# '总房间量',
# '住宅性能',
# '壁炉数量',
# '壁炉质量',
# '车库类型',
# '车库建造时间',
# '车库装修现状',
# '车位数量',
# '车库面积',
# '车库质量',
# '车库现状',
# '石板路',
# '木板面积',
# '开放式门廊面积',
# '关闭式门廊面积',
# '三季门廊面积',
# '半开放式门廊面积',
# '泳池面积',
# '泳池质量',
# '篱笆质量',
# '其他配置',
# '其他配置的价值',
# '销售月份',
# '销售年份',
# '销售类型',
# '销售状态']

reg_f = RFR() #实例化随机森林
reg_t = DTR() #实例化决策树
cv = KFold(n_splits=5,shuffle=True,random_state=1412) #实例化交叉验证方式
  • 与 sklearn 中其他回归算法一样,随机森林的默认评估指标是 R2,但在机器学习竞赛、甚至实际使用时,我们很少使用损失以外的指标对回归类算法进行评估。对回归类算法而言,最常见的损失就是 MSE。
cross_validate参数
n_jobs允许该程序调用的线程数
verbose是否打印进度
result_t = cross_validate(reg_t #要进行交叉验证的评估器
                          ,X,y #数据
                          ,cv=cv #交叉验证模式
                          ,scoring="neg_mean_squared_error" #评估指标
                          ,return_train_score=True #是否返回训练分数
                          ,verbose=True #是否打印进程
                          ,n_jobs=-1 #线程数
                         )
#[Parallel(n_jobs=-1)]: Using backend LokyBackend with 16 concurrent workers.
#[Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:    1.2s finished
  • 你知道如何查看自己计算机的线程数吗?
result_f = cross_validate(reg_f,X,y,cv=cv,scoring="neg_mean_squared_error"
                          ,return_train_score=True
                          ,verbose=True
                          ,n_jobs=-1)
#[Parallel(n_jobs=-1)]: Using backend LokyBackend with 16 concurrent workers.
#[Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:    2.1s finished

result_t #超级过拟合
#{'fit_time': array([0.0220046 , 0.0220046 , 0.0220046 , 0.02100563, 0.02100468]),
# 'score_time': array([0.00199962, 0.00199938, 0.00199938, 0.00199914, 0.00200129]),
# 'test_score': array([-1.13534182e+09, -3.41485921e+09, -1.67088861e+09, -1.67895115e+09,
#        -1.59034213e+09]),
# 'train_score': array([-0., -0., -0., -0., -0.])}

result_f #训练集和测试在交叉验证上的分数差异更小,因此森林的过拟合程度没有决策树高
#{'fit_time': array([1.31684232, 1.19581604, 1.27883458, 1.29583764, 1.21081877]),
# 'score_time': array([0.01100278, 0.01100206, 0.01100206, 0.01100278, 0.0110023 ]),
# 'test_score': array([-7.66379839e+08, -2.01798504e+09, -7.66327398e+08, -4.90163166e+08,
#        -9.88309425e+08]),
# 'train_score': array([-1.27164348e+08, -1.09165780e+08, -1.34679785e+08, -1.39727005e+08,
#        -1.19699899e+08])}
  • 在集成学习中,我们衡量回归类算法的指标一般是 RMSE(根均方误差),也就是 MSE 开根号后的结果。现实数据的标签往往数字巨大、数据量庞杂,MSE 作为平方结果会放大现实数据上的误差(例如随机森林结果中得到的,7∗108 等结果。
  • ,因此我们会对平房结果开根号,让回归类算法的评估指标在数值上不要过于夸张。同样的,方差作为平方结果,在现实数据上也会太大,因此如果可以,我们使用标准差进行模型稳定性的衡量。
trainRMSE_f = abs(result_f["train_score"])**0.5
testRMSE_f = abs(result_f["test_score"])**0.5
trainRMSE_t = abs(result_t["train_score"])**0.5
testRMSE_t = abs(result_t["test_score"])**0.5
trainRMSE_f.mean()
#11218.296933940535
testRMSE_f.mean()
#30773.03828921106

trainRMSE_f.std() #方差数额太大,使用标准差
#487.0084587022606

#默认值下随机森林的RMSE与标准差std
xaxis = range(1,6)
plt.figure(figsize=(8,6),dpi=80)
#RMSE
plt.plot(xaxis,trainRMSE_f,color="green",label = "RandomForestTrain")
plt.plot(xaxis,testRMSE_f,color="green",linestyle="--",label = "RandomForestTest")
plt.plot(xaxis,trainRMSE_t,color="orange",label = "DecisionTreeTrain")
plt.plot(xaxis,testRMSE_t,color="orange",linestyle="--",label = "DecisionTreeTest")
plt.xticks([1,2,3,4,5])
plt.xlabel("CVcounts",fontsize=16)
plt.ylabel("RMSE",fontsize=16)
plt.legend()
plt.show()

在这里插入图片描述

  • 其中,横坐标表示交叉验证次数,纵坐标表示 RMSE 数值。
  • 从图像来看,森林与决策树都处于过拟合状态,不过森林的过拟合程度较轻,决策树的过拟合程度较强。两个算法在训练集上的结果都比较优秀,决策树的可以完美学习训练集上的内容,达到 RMSE=0 的程度。
  • 而随机森林在训练集上的 RMSE 大约在 1w 上下徘徊,测试集上的结果则是随机森林更占优。可见,与填写的参数无关,随机森林天生就是比决策树更不容易过拟合、泛化能力更强的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/400965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink学习-单词统计WordCount

WordCount(流处理)通过socket数据源,去请求一个socket服务(9999),得到数据流然后统计数据流中出现的单词及其个数1.创建一个编程入口,生成环境StreamExecutionEnvironment streamEnv StreamExecutionEnvir…

嵌入式Linux驱动开发(二)LED驱动

1. Linux下LED驱动原理 与裸机区别在于,编写驱动要符合linux驱动框架规范。裸机直接对寄存器物理地址进行读写,linux下需要经过MMU。 1.1 地址映射相关概念 1)MMU(Memory Manage Unit - 内存管理单元): …

新星计划·第四季·Python赛道报名入口 -〖你就是下一个新星〗

↓↓↓报名方式:(下滑到本页面底部)重要提醒:这里是新星计划第四季Python赛道报名入口,一经报名,不可更换。报名入口点击此处跳转 一、新星计划 新星计划是一个以发掘潜力新人、培养优质博主为目标的创作…

css3动画属性

边框弧度 border-radius:value // 四角 border-radius:value value // 左上右下 右上左下 border-radius:value value value value // 左上 右上 右下 左下 text-shadow:value value value color; // 水平 垂直 模糊度 颜色 线性渐变:background-image:linear-…

oracle的时间戳获取不含中文内容的方式

背景: 在做oracle的数据库同步时发现,创建的行级触发器获取表的时间戳数据时含有中文,导致入库时转义乱码,条件匹配失败。 调试过程: 写了一个declare脚本测试: declare --类型定义 cursor c_job IS sele…

java反射机制及其详解

反射反射机制反射调用优化有时候我们做项目的时候不免需要用到大量配置文件,就拿框架举例,通过这些外部文件配置,在不修改的源码的情况下,来控制文件,就要用到我们的反射来解决 假设有一个Cat对象 public class Cat …

堆的应用(topk问题)

文章目录1.堆排序1.1代码实现2. TOP-K问题2.1原理2.2实例分析1.堆排序 堆排序即利用堆的思想来进行排序,总共分为两个步骤: 1.建堆 升序:大堆 降序:小堆 2.利用堆删除思想来排序 1.1代码实现 void Heapsort(int* a, int n) {f…

C#中通过HttpClient发送Post请求

C#中HttpClient进行各种类型的传输我们可以看到, 尽管PostAsync有四个重载函数, 但是接受的都是HttpContent, 而查看源码可以看到, HttpContent是一个抽象类那我们就不可能直接创建HttpContent的实例, 而需要去找他的实现类, 经过一番研究, 发现了, 如下四个:MultipartFormData…

系列一、AliyunOSS开通及使用

一、对象存储OSS服务开通及配置 1.1、开通OSS 1.2、进入管理控制台 1.3、控制台使用 1.3.1、创建Bucket 命名:20230309-oss 读写权限:公共读 1.3.2、上传默认头像 创建文件夹 avater,上传默认的用户头像 1.4、使用RAM子用户 1.4.1、添加…

设计模式3——结构型模式

结构型模式描述如何将类或对象按某种布局组成更大的结构,它分为类结构型和对象结构型模式,前者采用继承机制来组织接口和类,后者采用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”&…

哈希表的实现

哈希表概念 二叉搜索树具有对数时间的表现,但这样的表现建立在一个假设上:输入的数据有足够的随机性。哈希表又名散列表,在插入、删除、搜索等操作上具有「常数平均时间」的表现,而且这种表现是以统计为基础,不需依赖…

CMU15-445 Project.4总结

在线测试 Project #4 - Concurrency Control 以下是Project #4的网址,2022FALL的Project #4是实现并发控制,可以分为以下三个任务: 我们首先需要实现一个锁管理器,能够支持 READ_UNCOMMITED、READ_COMMITTED、REPEATABLE_READ…

layui表格合并

先看一下最终合并之后的效果,能对单选、复选框进行按照某一列的合并 最开始的解决方案来自于这篇博客介绍的方法:https://blog.csdn.net/guishifoxin/article/details/81480136 但是还是存在没能解决的问题。 在完善之后达到的效果: 一&…

移动硬盘格式化?想要恢复硬盘那就看这里!

案例:移动硬盘无法打开,提示格式化? “怎么办啊!!!今天下午给同学重装系统,插上自己的移动硬盘,却发现读不出来,提示需要格式化!里面有很多东西,…

第十四章 opengl之高级OpenGL(深度测试)

OpenGL深度测试深度测试函数深度值精度深度缓冲的可视化深度冲突防止深度冲突深度测试 前面我们渲染一个3D图片中运用了深度缓冲:防止被阻挡的面渲染到其他面的前面。 深度缓冲就像颜色缓冲(Color Buffer)(储存所有的片段颜色:视觉输出&…

JAVA开发(JAVA中的异常)

在java开发与代码运行过程中,我们经常会遇到需要处理异常的时候。有时候是在用编辑器写代码,点击保存的时候,编辑器就提示我们某块代码有异常,强制需要处理。有时候是我们启动,运行JAVA代码的时候的,日志里…

案例06-没有复用思想的接口和sql--mybatis,spring

目录一、背景二、思路&方案问题1优化问题2优化三、总结四、升华一、背景 写这篇文章的目的是通过对没有复用思想接口的代码例子优化告诉大家,没有复用思想的代码不要写,用这种思维方式和习惯来指导我们写代码。 项目中有两处没有复用思想代码&#…

R语言基础(三):运算

接前文 R语言基础(一):注释、变量 R语言基础(二):常用函数 4.运算 4.1 数学运算 R语言中支持加减乘除四则运算、乘方运算、求余数(取模)运算: 符号含义示例加法11 结果是2-减法2-1 结果是1*乘法4*5 结果是20/除法4/5 结果是0.8%/%整除(只要…

MySQL 事务隔离

MySQL 事务隔离事务隔离实现事务的启动ACID : 原子(Atomicity)、一致(Consistency)、隔离(Isolation)、永久(Durability) 多个事务可能出现问题 : 脏读 (dirty read) , 不可重复读 (non-repeatable read) , 幻读 (phantom read) 事务隔离级别 : 读未提交 (read uncommitted)…

一篇学习ES

文章目录ES简介1.什么是ElasticSearch2.ElasticSearch的使用案例3.ElasticSearch对比SolrElasticSearch环境搭建1. 下载ES压缩包2. 安装ES服务3. 启动ES服务3. 安装ES的图形化界面插件ES术语1.概述2.索引 index3.类型 type4.字段Field5.映射 mapping6.文档 document7. 接近实时…