随机森林的特征 是放回抽样么_机器学习超详细实践攻略(10):随机森林算法详解及小白都能看懂的调参指南...

82437919064ddeee16b19ee1f01402e3.png

一、什么是随机森林

前面我们已经介绍了决策树的基本原理和使用。但是决策树有一个很大的缺陷:因为决策树会非常细致地划分样本,如果决策树分得太多细致,会导致其在训练集上出现过拟合,而如果决策树粗略地划分样本,又不能很好地拟合样本。

为了解决这个两难困境,聪明的专家们想出了这样的思路:既然我增加单棵树的深度会适得其反,那不如我不追求一个树有多高的精确度,而是训练多棵这样的树来一块预测,一棵树的力量再大,也是有限的,当他们聚成一个集体,它的力量可能是难以想象的,也就是我们常说的:“三个臭皮匠赛过诸葛亮”。这便是集成学习的思想。

这里多提一句,正是因为每棵树都能够用比较简单的方法细致地拟合样本,我们可以多用几棵树来搭建准确率更高的算法,后边要说到的一些工业级的算法,比如GBDT、XGBOOST、LGBM都是以决策树为积木搭建出来的。

所以在学习这些算法的过程中,我们也要把决策树算法看成一块块积木,学完了基本的积木算法之后,对于现在常用的那几个工业级的算法,只需要理清两个问题:

1)这个算法利用了哪个集成学习思想

2)这个算法具体怎么把这个思想实现出来的。

随机森林就是决策树们基于bagging集成学习思想搭建起来的。

随机森林的算法实现思路非常简单,只需要记住一句口诀:抽等量样本,选几个特征,构建多棵树。

下面,我们详细解释这个口诀的含义:

1)抽等量样本

随机森林训练每棵树之前,都会从训练集中随机抽出一部分样本来训练。所以说训练每棵树用到的样本其实都是有差别的,这样就保证了不同的树可以重点学习不同的样本。而为了达到抽等量样本的目的,抽样方式一般是有放回的抽样,也就是说,在训练某棵树的时候,这一次被抽到的样本会被放回数据集中,下一次还可能被抽到,因此,原训练集中有的样本会多次被抽出用来训练,而有的样本可能不会被使用到。

但是不用担心有的样本没有用到,只要训练的树的棵数足够多,大多数训练样本总会被取到的。有极少量的样本成为漏网之鱼也不用担心,后边我们会筛选他们出来用来测试模型。

2)选几个特征

在训练某棵树的时候,也不是将样本的所有特征都用来训练,而是会随机选择一部分特征用来训练。这样做的目的就是让不同的树重点关注不同的特征。在scikit-learn中,用“max_features”这个参数来控制训练每棵树选取的样本数。

3)构建多棵树。

通过1)、2)两个步骤,训练多棵树。鲁迅曾经说过:世界上本没有森林,长得树多了,就成了森林。正是一棵棵决策树构成了整个随机森林。具体构建树的数量,在scikit-learn中,用“n_estimators”这个参数来控制。

197444d4549011d18b95e4630186f316.png

那最终的预测结果怎么得到呢?随机森林是非常民主的算法,最终的结果由每棵决策树综合给出:如果是分类问题,那么对于每个测试集,树都会预测出一个类别进行投票,最终统计票数多的那个类别为最终类别。看看,这算法俨然是一个遵循:“少数服从多数”的原则的小型民主社会;如果是回归问题,那就更简单了,各个树得到的结果相加求得一个平均值为最终回归结果。

从上边的流程中可以看出,随机森林的随机性主要体现在两个方面:数据集的随机选取、每棵树所使用特征的随机选取。以上两个随机性使得随机森林中的决策树都能够彼此不同,提升系统的多样性,从而提升分类性能。

二、随机森林的特点

以上就是随机森林的构建原理,下面,我们说说随机森林算法的优缺点:

1、优点:

1)实现简单,泛化能力强,可以并行实现,因为训练时树与树之间是相互独立的;

2)相比单一决策树,能学习到特征之间的相互影响,且不容易过拟合;

3)能直接特征很多的高维数据,因为在训练过程中依旧会从这些特征中随机选取部分特征用来训练;

4)相比SVM,不是很怕特征缺失,因为待选特征也是随机选取;

5)训练完成后可以给出特征重要性。当然,这个优点主要来源于决策树。因为决策树在训练过程中会计算熵或者是基尼系数,越往树的根部,特征越重要。

2、缺点

1)在噪声过大的分类和处理回归问题时还是容易过拟合;

2)相比于单一决策树,它的随机性让我们难以对模型进行解释。

三、随机森林的使用

和决策树类似,随机森林同样可以分为分类森林(RandomForestClassifier )和回归森林(RandomForestRegressor),在scikit-lean中调用方式和决策树相同。

让我们在手写识别数据集上实现一个分类森林。

#导入必要的包
from sklearn.ensemble import RandomForestClassifier 
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split,GridSearchCV,cross_val_score
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
import numpy as np#导入数据集
data = load_digits()
x = data.data
y = data.target

用随机森林训练并进行交叉验证:

RF = RandomForestClassifier(random_state = 66)
score = cross_val_score(RF,x,y,cv=10).mean()
print('交叉验证得分: %.4f'%score)

输出:

交叉验证得分: 0.9278

四、随机森林调参

一)随机森林参数介绍

除了和决策树有的参数之外,对于随机森林,只需要掌握8个新增的参数即可,我将这8个参数分成三类:

1、用于调参的参数:

  • max_features(最大特征数): 这个参数用来训练每棵树时需要考虑的最大特征个数,超过限制个数的特征都会被舍弃,默认为auto。可填入的值有:int值,float(特征总数目的百分比),“auto”/“sqrt”(总特征个数开平方取整),“log2”(总特征个数取对数取整)。默认值为总特征个数开平方取整。值得一提的是,这个参数在决策树中也有但是不重要,因为其默认为None,即有多少特征用多少特征。为什么要设置这样一个参数呢?原因如下:考虑到训练模型会产生多棵树,如果在训练每棵树的时候都用到所有特征,以来导致运算量加大,二来每棵树训练出来也可能千篇一律,没有太多侧重,所以,设置这个参数,使训练每棵树的时候只随机用到部分特征,在减少整体运算的同时还可以让每棵树更注重自己选到的特征。
  • n_estimators:随机森林生成树的个数,默认为100。

2、控制样本抽样参数:

  • bootstrap:每次构建树是不是采用有放回样本的方式(bootstrap samples)抽取数据集。可选参数:True和False,默认为True。
  • oob_score:是否使用袋外数据来评估模型,默认为False。

boostrap和 oob_score两个参数一般要配合使用。如果boostrap是False,那么每次训练时都用整个数据集训练,如果boostrap是True,那么就会产生袋外数据。

先解释一下袋外数据的概念:

在一个含有n个样本的原始训练集中,我们每次随机取出一个样本并记录,并在抽取下一个样本之前将该样本放回原始训练集,即下次采样时这个样本依然可能被采集到,这样采集n次,最终得到一个和原始训练集一样大的子数据集。

由于是随机采样,这样每次的子数据集和原始数据集都不同,用这些子数据集来各自训练一棵树,这些树的参数自然也就各不相同了。

然而有放回抽样也会有自己的问题。由于是有放回,一些样本可能在同一个自助集中出现多次,而其他一些却可能被忽略,一般来说,每一次抽样,某个样本被抽到的概率是 1/n ,所以不被抽到的概率就是 1-1/n ,所以n个样本都不被抽到的概率就是:

用洛必达法则化简,可以得到这个概率收敛于(1/e),约等于0.37。

因此,如果数据量足够大的时候,会有约37%的训练数据被浪费掉,没有参与建模,这些数据被称为袋外数据(out of bag data,简写为oob)。

为了这些数据不被浪费,我们也可以把他们用来作为集成算法的测试集。也就是说,在使用随机森林时,我们可以不划分测试集和训练集,只需要用袋外数据来测试我们的模型即可。

当然,这需要样本数据n和分类器个数n_estimators都很大,如果数据集过少,很可能就没有数据掉落在袋外,自然也就无法使用oob数据来测试模型了。

当bootstrap参数取默认值True时,表示抽取数据集时采用这种有放回的随机抽样技术。如果希望用袋外数据来测试,则需要在实例化时就将oob_score这个参数调整为True,训练完毕之后,我们可以用随机森林的另一个重要属性:oob_score_来查看我们的在袋外数据上测试的结果,代码如下:

#训练一个模型,让oob_score=True
输出:0.9393433500278241

这个就是没有参与训练的数据集在模型上的测试得分。

3、不重要参数

  • max_samples:构建每棵树需要抽取的最大样本数据量,默认为None,即每次抽取样本数量和原数据量相同。
  • n_jobs::设定fit和predict阶段并列执行的CPU核数,如果设置为-1表示并行执行的任务数等于计算机核数。默认为None,即采用单核计算。
  • verbose:控制构建数过程的冗长度,默认为0。一般不需要管这个参数。
  • warm_start:当设置为True,重新使用之前的结构去拟合样例并且加入更多的估计器(estimators,在这里就是随机树)到组合器中。默认为 False

以上这几个参数只需要简单了解即可,大多数参数在使用过称重不用调整,只是需要注意一点,n_jobs默认为None,为了加快速度,可以把n_jobs设置为-1。

二)随机森林调参顺序

介绍完了这些参数,接下来就要介绍随机森林的调参顺序了,随机森林的调参顺序一般遵循先重要后次要、先粗放后精细的原则,即先确定需要多少棵树参与建模,再对每棵树做细致的调参,精益求精。

相对于xgboost等算法,随机森林的调参还是相对比较简单,因为各个参数之间互相影响的程度很小,只需要按步骤调整即可。

结合我们决策树文章中提到的参数以及今天所讲的两个参数,随机森林中主要用来调参的参数有6个:

  • n_estimators:
  • criterion
  • max_depth
  • min_samples_split
  • min_samples_leaf
  • max_features

调参顺序如下:

1)选择criterion参数(决策树划分标准)

和决策树一样,这个参数只有两个参数 'entropy'(熵) 和 'gini'(基尼系数)可选,默认为gini,这里简单测试一下就好

RF = RandomForestClassifier(random_state = 66)
score = cross_val_score(RF,x,y,cv=10).mean()
print('基尼系数得分: %.4f'%score)
RF = RandomForestClassifier(criterion = 'entropy',random_state = 66)
score = cross_val_score(RF,x,y,cv=10).mean()
print('熵得分: %.4f'%score)

输出:

基尼系数得分: 0.9278
熵得分: 0.9249

这里看到,依旧是选用gini系数模型效果更好。

2)探索n_estimators的最佳值。

接下来才是进入真正的调参环节。根据上述调参原则,我们先看看用几棵树模型的表现最好。一般来说,树的棵数越多,模型效果表现越好,但树的棵数达到一定的数量之后,模型精确度不再上升,训练这个模型的计算量却逐渐变大。这个时候,再加树的数量就没必要了。就好比你饿的时候每吃一个馒头就特别顶饱,但是吃到一定数量的馒头之后,再吃就要撑着了。

只要找到这个临界值,这个参数就调好了。为了观察得分随着树增多的变化,我们依然绘制决策树调参时的学习曲线。

###调n_estimators参数
ScoreAll = []
for i in range(10,200,10):DT = RandomForestClassifier(n_estimators = i,random_state = 66) #,criterion = 'entropy'score = cross_val_score(DT,data.data,data.target,cv=10).mean()ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])  
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.show()

输出:

最优参数以及最高得分: [120. 0.95560035]

fcb547239e3d2ec7836df831f2d7aa7b.png
调n_estimators参数

根据曲线,我们进一步缩小范围,搜索100~130之间的得分。(这里可以根据经验自己指定)

###进一步缩小范围,调n_estimators参数
ScoreAll = []
for i in range(100,130):DT = RandomForestClassifier(n_estimators = i,random_state = 66)   #criterion = 'entropy',score = cross_val_score(DT,data.data,data.target,cv=10).mean()ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])  
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.show()

输出:

最优参数以及最高得分: [117. 0.95727946]

e792712c663f85dbe34d4af1135599e0.png
调n_estimators参数


可以看到,117为得分最高点,我们暂定n_estimators为117,接着调下边的参数。

3)探索max_depth(树的最大深度)最佳参数

###粗调max_depth参数
ScoreAll = []
for i in range(10,30,3):DT = RandomForestClassifier(n_estimators = 117,random_state = 66,max_depth =i ) #,criterion = 'entropy'score = cross_val_score(DT,data.data,data.target,cv=10).mean()ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])  
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.show()

输出:

最优参数以及最高得分: [16. 0.95727946]

b6fb6e3478b30250bc0d9c0eab9482d1.png
max_depth参数

转折点在16,但是16之后一直没有变化,可以说明就算不限制,所有树的最大深度也就是16左右,因为我们以步长为3搜索的,所以还需要进一步搜索一下16附近的值。

精细搜索之后发现,16这个值就是转折点,所以暂定max_depth = 16。

4)探索min_samples_split(分割内部节点所需的最小样本数)最佳参数
min_samples_split最小值就是2,我们就从2开始调起。

###调min_samples_split参数
ScoreAll = []
for i in range(2,10):RF = RandomForestClassifier(n_estimators = 117,random_state = 66,max_depth =16,min_samples_split = i ) #,criterion = 'entropy'score = cross_val_score(RF,data.data,data.target,cv=10).mean()ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])  
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.show()

输出:

最优参数以及最高得分: [2. 0.95727946]

9fadff71cd149e4b25066863842ccb52.png
min_samples_split参数


可以看到,随着min_samples_split增大,模型得分下降,说明没有出现过拟合现象,min_samples_split暂定2。

5)探索min_samples_leaf(分割内部节点所需的最小样本数)最佳参数

###调min_samples_leaf参数
ScoreAll = []
for i in range(1,15,2):DT = RandomForestClassifier(n_estimators = 117,random_state = 66,max_depth =16,min_samples_leaf = i,min_samples_split = 2 ) score = cross_val_score(DT,data.data,data.target,cv=10).mean()ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])  
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.show()

输出:

最优参数以及最高得分: [1. 0.95727946]

5ad01980c068d83e8244149f35734f91.png
min_samples_leaf参数

5)对每棵树用到的最大特征数max_features调参:

正常来说,只要这个值不要设置得太小,所有特征都会被整个森林抽取到用来训练, 所以相对来说这个值对整个模型的影响不是太大。但这个值越大,单棵树需要考虑的特征越多,虽然模型的表现可能会更好,但是增加这个值会导致算法运行速度变慢,所以需要我们考虑去找一个平衡值。

#调max_features参数
param_grid = {'max_features':np.arange(0.1, 1)}rfc = RandomForestClassifier(random_state=66,n_estimators = 117,max_depth = 16,min_samples_leaf =1 ,min_samples_split =4 )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
print(GS.best_params_)
print(GS.best_score_)

输出:

{'max_features': 0.1}
0.9560335195530726

如果时间充裕,接下来也可以将min_samples_leaf和min_samples_split作为网格参数联调一下,因为这两个参数会相互影响,这里暂时省略这一步。

此时,我们得到的参数如下:

参数值n_estimators117max_depth16min_samples_leaf1min_samples_split2max_features0.1

6)在得到的最优参数附近进行小范围网格搜索

因为手动调参时,这些参数可能会相互影响,导致我们得到的参数还不是最优的。所以在最优参数附近进行小范围的网格搜索,排出相互影响的因素,尤其是在数据集量比较少时,小范围搜索一下可能会有意外收获。

import time
start = time.time()param_grid = {'n_estimators':np.arange(140, 150),'max_depth':np.arange(15, 18),'min_samples_leaf':np.arange(1, 8),'min_samples_split':np.arange(2, 5),'max_features':np.arange(0.1, 1)
}rfc = RandomForestClassifier(random_state=66)
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
end = time.time()
print("循环运行时间:%.2f秒"%(end-start))
print(GS.best_params_)
print(GS.best_score_)

输出如下:

循环运行时间:3052.67秒
{'max_depth': 16, 'max_features': 0.1, 'min_samples_leaf': 1, 'min_samples_split': 3, 'n_estimators': 143}
0.9599332220367279

可以看到,精确度又上升了一点,此时,我们得到的新旧参数对比如下:

参数旧值新值n_estimators117143max_depth1616min_samples_leaf11min_samples_split23max_features0.10.1

对比一下新旧参数,可以看到参数变化还是比较大的,尤其是树的棵数这个参数。当然,这里主要原因是我们用来做示例的这个预置的数据集只有1797条数据,导致参数的随机性太大,在实际使用中数据集数量都是十万百万级的,不会出现我们手动调整的参数和小范围网格搜索参数差别这么大的情况。

最后需要说明的一点是:随机森林相对于决策树来说运行较慢,在调参时可以将参数搜索范围设置得小一些。

当然,这只是我个人的调参顺序,仅用来参考,没必要这么固化。实际调参时可以根据实际情况做一些调整。还是那句话:正是调参过程充满的各种不确定性,才是调参的真正魅力所在。

五、本系列相关文章

  • 机器学习超详细实践攻略(1):盘点scikit-learn里那些有趣又有用的彩蛋级入门数据集
  • 机器学习超详细实践攻略(8):使用scikit-learn构建模型的通用模板【万字长文】
  • ​机器学习超详细实践攻略(9):决策树算法详解及小白都能看懂的调参指南
  • 机器学习超详细实践攻略(21):三板斧干掉样本不均衡问题之1——过(欠)采样
  • 机器学习超详细实践攻略(22):三板斧干掉样本不均衡问题之2——对正负样本设置不同权重
  • 机器学习超详细实践攻略(23):三板斧干掉样本不均衡问题之3——通过集成学习方法解决样本不均衡

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

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

相关文章

Java Code Geeks通过Twitter赠送了免费的Sublime Text Editor许可

正在与您的重量级编辑斗争? 然后,我们特别为您准备了一些东西! 我们正在举办比赛,免费赠送 kick-ass Sublime Text Editor 许可证 。 Sublime Text是用于代码,标记和散文的高级文本编辑器。 您会喜欢光滑的用户界面…

http端口_PhpStorm 修改默认端口号63342

PhpStorm 修改默认端口号63342​blog.csdn.net关键词PhpStorm phpStorm phpstorm 修改默认端口号63342 8080 80步骤1.打开Settings2. Build, Execution, Deployment→Deployment3.点击添加,选择In place起一个名字(可以随便起)在Web server U…

php根本自学不了,PHP开发自学还是培训?

员有两种,一种是会php的,一种是不会php的,今天我们不去说哪种开发语言好,哪种又不好,因为语言只是一种工具而已不管你是从IOS、.NET或其它语言进入这个行业,只要你在这个行业坚持多年,与php的感…

rds mysql 磁盘空间,RDS MySQL 空间问题的原因和解决

other_size- 系统文件和临时文件使用空间data_size- 数据文件使用空间binlog_size- Binlog 文件占用空间注:获取实例诊断报告的步骤请参考如何访问RDS 实例诊断报告。2. 解决RDS 实例支持单独升级磁盘空间,升级磁盘空间是解决空间问题的有效方式之一。下…

微信小程序 全局变量异步函数_微信小程序【生命周期】

小程序分为应用、页面和组件三个部分,所以小程序的生命周期涉及以下应用的生命周期页面的生命周期组件的声明周期应用的生命周期对页面生命周期的影响应用的生命周期App() 函数用来注册一个小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。…

oracle agile 性能,Oracle Agile PLM安全漏洞(CVE-2016-3554)

Oracle Agile PLM安全漏洞(CVE-2016-3554)发布日期:2016-07-21更新日期:2016-07-25受影响系统:Oracle Supply Chain Products Suite 9.3.5Oracle Supply Chain Products Suite 9.3.4描述:CVE(CAN) ID: CVE-2016-3554Oracle Agile产…

java 挥发注解_Java的挥发性修饰符

java 挥发注解不久前,我写了一个Java servlet过滤器,该过滤器在其init函数中加载配置(基于web.xml的参数)。 筛选器的配置缓存在私有字段中。 我在字段上设置了volatile修饰符。 后来,当我检查Sonar公司以查看是否在代…

python 线程锁_python多线程编程(3): 使用互斥锁同步线程

问题的提出 上一节的例子中,每个线程互相独立,相互之间没有任何关系。现在假设这样一个例子:有一个全局的计数num,每个线程获取这个全局的计数,根据num进行一些处理,然后将num加1。很容易写出这样的代码&am…

Comnnect oracle,RAC监听日志与CRS日志

RAC监听日志:tnsname.oraCRS日志:位置:Oracle集群涉及的日志主要位于“$ORA_CRS_HOME/log”和“$ORACLE_HOME/log”目录中目录结构:tree -d $ORA_CRS_HOME/logtree -d $ORACLE_HOME/log禁止Clusterware在系统重启后自动启动&#…

python全栈开发百度云_价值2400 2016年11月全栈开发Flask Python Web 网站编程

01-计算机基础常识.mp4 02-Python语言概览、安装与运行.mp4 03-Python 变量、数据类型及存储.mp4 04-Python 常用数据类型概览.mp4 05-数值与字符串.mp4 06-列表list.mp4 07-字典表dict 与元组 tuple.mp4 08-文件与类型汇总.mp4 09-语句、表达式与if分支.mp4 10-循环语句.mp4 1…

Java / Spring:如何快速生成整个数据库CRUD REST API

随着时间的流逝,Spring框架已成为Java中使用最广泛的Web开发框架之一,这一点已变得显而易见。 在接下来的十年之际,Spring最受欢迎的模块Spring Boot刚刚进行了重大更新。 新的Spring Boot版本“ 2.2.0”和年份“ 2020”几乎完美匹配。 因此…

如何在虚拟linux环境运行python_Conda(Python)虚拟环境不能从Windows移植到Linux

在我的Windows 10计算机上,我使用以下命令创建了一个虚拟环境:>conda env export > environment.yml 我尝试在Windows系统上使用yml文件重新创建虚拟环境,效果很好。然后我转学了环境.yml在我的Linux机器(Ubuntu16.04.1&…

oracle两个表合并 sql,如何创建从两个表(Oracle DBMS)生成“合并”数据集的Select SQL语句?...

我最后做了两个步骤:第一步填充事件表1中的数据,第二步合并目标(第一步中的数据集)和另一个源之间的数据。请原谅我,因为法律原因,我不得不混淆表名并省略下面代码中的一些列。下面是SQL:INSERT INTO EVENTS_TARGET (VEHICLE_ID,EVENT_TYPE_ID,CLIENT_ID,EVENT_DATE,CREATED_DA…

php毕业设计遇到的问题,常见问题_php毕业设计_php课程设计_php大作业_原创作品下载网...

一、我们怎么交易?答:本站采用在线支付的方式,每个产品页面都有一个付款按钮,亲在线付款后页面会显示一个“订单号”,根据这个订单号在本站的下载页面(见顶部菜单)下载相应程序,注意,亲要在30分…

git maven 发布_Maven Git发布

git maven 发布在开始这篇文章之前,我需要指出我在去年才开始认真地与Git合作 。 不幸的是,我从事的许多项目仍在使用SVN或CVS,但现在我终于开始使用Git了 。 在过去的几年中,我使用Maven Release Plugin完成了许多软件发行。 我…

python界面长什么样图片_python界面是什么样的

安装完Python,在命令行输入“python”之后,如果成功,会得到类似于下面的窗口:可以看到,结尾有3个>符号(>>>)。>>>被叫做Python命令提示符(prompt)&…

php static 访问,使用PHP访问Static方法的最佳方法

这是我的课堂财产private $my_paths array(imagemagick > E:\Server\_ImageOptimize\ImageMagick,pngcrush > E:\Server\_ImageOptimize\pngCrush\pngcrush.exe,jpegtran > E:\Server\_ImageOptimize\jpegtran\jpegtran.exe,gifsicle > E:\Server\_ImageOptimize\…

python表格控件_python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例...

PyQt5表格控件QTableView简介 在通常情况下,一个应用需要和一批数据进行交互,然后以表格的形式输出这些信息,这时就需要用到QTableView类了,在QTableView中可以使用自定义的数据模型来显示内容,通过setModel来绑定数据…

Java:Speedment 3.2的发布–现在启用轻量级数据库微服务

几种传统的ORM不能完全遵循Java模块封装(JPMS)。 这通常意味着在部署微服务时会使用很多不必要的文件和类。 最新的主要版本3.2的开源 Speedance通过引入模块系统支持来解决此问题,该模块支持对云应用程序进行有效部署并提供更严格的API。 …

Linux文件系统为,浅析Linux文件系统

原标题:浅析Linux文件系统一、文件系统层次分析由上而下主要分为用户层、VFS层、文件系统层、缓存层、块设备层、磁盘驱动层、磁盘物理层用户层最上面用户层就是我们日常使用的各种程序,需要的接口主要是文件的创建、删除、打开、关闭、写、读等。VFS层我…