2024年大数据最全Lesson 9(1)

w

w。

  • 不过,这里存在一个问题:虽然原来的树没有变化,但增量学习看起来并没有增加新的树——事实上,对于随机森林而言,我们需要手动增加新的树:
model2.estimators_ #属性,反映训练完毕的模型的一些特点、一些客观存在的性质

#调用模型的参数,可以通过这种方式修改模型的参数,而不需要重新实例化模型
model2.n_estimators += 2 #增加2棵树,用于增量学习
model2
#RandomForestRegressor(n\_estimators=5, warm\_start=True)

model2.fit(X.iloc[:,:8],y)
#RandomForestRegressor(n\_estimators=5, warm\_start=True)

model2.estimators_ #原来的树还是没有变化,新增的树是基于新输入的数据进行训练的
#[DecisionTreeRegressor(max\_features='auto', random\_state=338470642),
# DecisionTreeRegressor(max\_features='auto', random\_state=1545812511),
# DecisionTreeRegressor(max\_features='auto', random\_state=740599321),
# DecisionTreeRegressor(max\_features='auto', random\_state=1633155700),
# DecisionTreeRegressor(max\_features='auto', random\_state=623929223)]

2. 增量学习在 Kaggle 数据上的应用

2.1 实际应用
  • 现在我们使用一个 385MB 的 csv 文件作为例子,进行巨量数据的导入和训练(当然,在实际中 csv 文件往往是 5G 以上,基本不可能使用 excel 打开进行简单分析或观察)。
  • 该数据是来自 Kaggle 的五大人格心理特质回归数据集。五大人格心理特质是心理学当中常见的人格分类法,也称为 FFM 模型或 OCEAN 模型。这种人格分类法是通过给与被调查者一些描述性格方面的句子,让被调查者选择自己符合的项目,例如:
  • (1) 考试前我总是提前准备好一切,尽全力避免出错。
  • (2) 考试前我会花几天时间准备。
  • (3) 我在考试前临时抱佛脚。
  • (4) 我考试前从不准备。
  • (5) 我不在意考试,甚至不记得考试的时间。
  • 你从中选择最像你的选项,和最不像你的选项,选择结果最终被用于性格分类。该数据集通过收集 100w 人群在大约 80 个问题当中的选项,得出最终性格分数和分类。
  • 训练集大约有一百万样本,测试集则有 2w 样本,更详细的状况可以查看:https://www.kaggle.com/tunguz/big-five-personality-test
  • 在面对大型数据时,我们采用循环模式分批读取巨大 csv 或数据库文件中的内容,并将数据分批进行预处理、再增量学习到一个模型当中。
  • 现在,我们在干净的数据上来看看增量学习具体的步骤:
  • (1) 定义训练和测试数据地址
trainpath = r"D:\Pythonwork\2021ML\PART 2 Ensembles\datasets\Big data\bigdata\_train.csv"
testpath = r"D:\Pythonwork\2021ML\PART 2 Ensembles\datasets\Big data\bigdata\_test.csv"

  • (2) 设法找出 csv 中的总数据量
  • 我们决定使用增量学习时,数据应该是巨大到不可能直接打开查看、不可能直接训练、甚至不可能直接导入的(比如,超过 20 个 G)。但如果我们需要对数据进行循环导入,就必须知道真实的数据量大概有多少,因此我们可以从以下途径获得无法打开的 csv 中的数据量:
  • 如果是比赛数据集,一般可以在比赛页面找到相应的说明。
  • 如果是数据库数据集,则可以在数据库中进行统计。
  • 如果无法找到相应的说明,可以使用 deque 库导入 csv 文件的最后几行,查看索引。
  • 如果数据没有索引,就只能够靠 pandas 尝试找出大致的数据范围了。
#使用deque与StringIO辅助,导入csv文件最后的n行
from collections import deque #deque:双向队列
from io import StringIO

with open(trainpath, 'r') as data:
    q = deque(data, 5)

q

pd.read_csv(StringIO(''.join(q)), header=None)

  • 可以看到最后一行的索引是 995033,因此训练集中有 99w 条数据。
  • 如果数据没有索引,则使用 pandas 中的 skiprows 与 nrows 进行尝试。
  • skiprows 表示本次导入跳过前 skiprows 行。
  • nrows 表示本次导入只导入 nrows 行。
  • 例如,当 skiprows=1000, nrows=1000 时,pandas 会导入 1001~2000 行。
  • 但是当 skiprows 超出数据量时,就会报空值错误 EmptyDataError。
for i in range(0,10\*\*7,100000):
    df = pd.read_csv(trainpath,skiprows=i, nrows=1)
    print(i)

  • 可以看到 90w 顺利导入了,但是 100w 报错了,所以数据量在 90-100w 之间。如果我们想,我们可以继续精确数据量的具体范围,但通常来说我们只要确认 10w 以内的区域就可以了。
  • (3) 确认数据量后,准备循环范围
[\*range(0,10\*\*6,50000)]

looprange = range(0,10\*\*6,50000)

  • (4) 建立增量学习使用的模型,定义测试集
reg = RFR(n_estimators=10
          ,random_state=1412
          ,warm_start=True
          ,verbose=True #增量学习的过程总是很漫长的,你可以选择展示学习过程
          ,n_jobs=-1 #调用你全部的资源进行训练
         )

#定义测试集
test = pd.read_csv(testpath,header="infer",index_col=0)
Xtest = test.iloc[:,:-1]
Ytest = test.iloc[:,-1]

Xtest.head()

  • (5) 开始循环导入与增量学习
  • 当 skiprows 与 nrows 之和超出数据量的时候,会发生什么?
trainsubset = pd.read_csv(trainpath, header=None, index_col=0
                          , skiprows=950000
                          , nrows=50000)

trainsubset.tail(5) #会导出全部剩下的数据,即便不足200w

trainsubset.shape 
#(45035, 110)

for line in looprange:
    if line == 0:
        #首次读取时,保留列名,并且不增加树的数量
        header = "infer"
        newtree = 0
    else:
        #非首次读取时,不要列名,每次增加10棵树
        header = None
        newtree = 10
    
    trainsubset = pd.read_csv(trainpath, header = header, index_col=0, skiprows=line, nrows=50000)
    Xtrain = trainsubset.iloc[:,:-1]
    Ytrain = trainsubset.iloc[:,-1]
    reg.n_estimators += newtree
    reg = reg.fit(Xtrain,Ytrain)
    print("DONE",line+50000)
        
    #当训练集的数据量小于50000时,打断循环
    if Xtrain.shape[0] < 50000:
        break

  • 现在,全部的 99w 数据都已经训练完毕了,我们可以在测试集上进行测试:
reg.score(Xtest,Ytest) #R2 99%,这可能与测试集上的数据太少有关
#0.9903482355083931

  • 当使用增量学习时,如果需要调参,我们则需要将增量学习循环打包成一个评估器或函数,以便在调参过程中不断调用,这个过程所需的计算量是异常大的,不过至少我们拥有了在 CPU 上训练巨大数据的方法。

二、Bagging 方法 6 大面试热点问题

  • 本节,我们总结关于随机森林和 bagging 的几个重点面试问题,深入地探讨一下 Bagging 算法背后相关的原理,这对于我们理解后续模型融合中的 Voting 与 Averaging 方法有重要的意义。本节一共包括6个问题:

Q1:为什么 Bagging 算法的效果比单个评估器更好?

  • 该问题其实是在考察 Bagging 方法降低模型泛化误差的基本原理。
  • 泛化误差是模型在未知数据集上的误差,更低的泛化误差是所有机器学习/深度学习建模的根本目标。在机器学习当中,泛化误差一般被认为由偏差、方差和噪音构成。
  • 其中偏差是预测值与真实值之间的差异,衡量模型的精度。方差是模型在不同数据集上输出的结果的方差,衡量模型稳定性。噪音是数据收集过程当中不可避免的、与数据真实分布无关的信息。
  • 当算法是回归算法、且模型衡量指标是 MSE 时,模型的泛化误差可以有如下定义:

泛化误差

=

2

方差

2

=

b

i

a

s

2

v

a

r

i

a

n

c

e

n

o

i

s

e

2

\begin{aligned} 泛化误差 &= 偏差^2 + 方差 + 噪音^2 \ &= bias^2 + variance + noise^2 \end{aligned}

泛化误差​=偏差2+方差+噪音2=bias2+variance+noise2​

(该公式可以通过泛化误差、偏差、方差与噪音的定义推导而得)

  • Bagging 的基本思想是借助弱评估器之间的独立性来降低方差,从而降低整体的泛化误差。这个思想可以被推广到任意并行使用弱分类器的算法或融合方式上,极大程度地左右了并行融合方式的实际使用结果。
  • 其中,降低方差指的是 Bagging 算法输出结果的方差一定小于弱评估器输出结果的方差,因此在相同数据上,随机森林往往比单棵决策树更加稳定,也因此随机森林的泛化能力往往比单棵决策树更强。

Q2:为什么 Bagging 可以降低方差?

  • 以随机森林为例,假设现在随机森林中含有

n

n

n 个弱评估器(

n

n

n 棵树),任意弱评估器上的输出结果是

X

i

X_i

Xi​,则所有这些弱评估器输出结果的方差可以被表示为 Var(

X

i

X_i

Xi​)。

  • 假设现在我们执行回归任务,则森林的输出结果等于森林中所有树输出结果的平均值,因此森林的输出可以被表示为

X

ˉ

=

X

i

n

\bar{X} = \frac{\sum{X_i}}{n}

Xˉ=n∑Xi​​,因此随机森林输出结果的方差可以被表示为Var(

X

ˉ

\bar{X}

Xˉ),也可以写作 Var(

X

i

n

\frac{\sum{X_i}}{n}

n∑Xi​​)。

  • 在数学上我们很容易证明:

当森林中的树互相独立时,Var(

X

ˉ

\boldsymbol{\bar{X}}

Xˉ) 永远小于 Var(

X

i

\boldsymbol{X_i}

Xi​)

  • 为了完成这个证明,我们需要几个定理:
  • Var(A + B) = Var(A) + Var(B),其中 A 和 B 是相互独立的随机变量。
  • Var(aB) = a

2

^2

2Var(B),其中 a 是任意常数。

  • 假设任意树输出的方差 Var(

X

i

X_i

Xi​) =

σ

2

\sigma^2

σ2,则有:

V

a

r

(

X

ˉ

)

=

V

a

r

(

1

n

i

=

1

n

X

i

)

=

1

n

2

V

a

r

(

i

=

1

n

X

i

)

=

1

n

2

(

V

a

r

(

X

1

)

V

a

r

(

X

2

)

.

.

.

V

a

r

(

X

n

)

)

=

1

n

2

n

σ

2

=

σ

2

n

\begin{aligned} Var(\bar{X}) &= Var\left(\frac{1}{n}\sum_{i=1}^{n}X_i\right)\ &= \frac{1}{n2}Var\left(\sum_{i=1}{n}X_i\right)\ &= \frac{1}{n^2} \left( Var(X_1) + Var(X_2) + … + Var(X_n) \right)\ &= \frac{1}{n2}n\sigma2\ &= \frac{\sigma^2}{n} \end{aligned}

Var(Xˉ)​=Var(n1​i=1∑n​Xi​)=n21​Var(i=1∑n​Xi​)=n21​(Var(X1​)+Var(X2​)+…+Var(Xn​))=n21​nσ2=nσ2​​

n

n

n 为正整数、且弱评估器之间相互独立时,必然有 Var(

X

ˉ

\bar{X}

Xˉ) 永远小于 Var(

X

i

X_i

Xi​),这是随机森林的泛化能力总是强于单一决策树的根本原因。

r = np.array([-1,-1,-1, 1, 1, 1, 1]) #-1,1

(r == 1).sum()
#4

(r == -1).sum()
#3

  • 按少数服从多数结果,随机森林的输出应该是 1。这个过程可以很容易使用函数来替代,只要我们对所有树的结果的均值套上 sigmoid 函数,再以 0.5 为阈值就可以。
r = np.array([-1,-1,-1, 1, 1, 1, 1])

r.mean()
#0.14285714285714285

def sigmoid(z):
    return 1/(1+np.e\*\*(-z))

sigmoid(r.mean())
#0.5356536708339716

  • sigmoid 函数的结果大于 0.5,因此最终输出的类别为 1。当模型效果足够好时,sigmoid 函数的结果一般与少数服从多数相一致。
  • 因此,当弱评估器的方差是
    Var(

X

i

X_i

Xi​)时,随机森林分类器的方差可以写作 Var(

f

(

X

ˉ

)

f(\bar{X})

f(Xˉ)),其中

f

(

z

)

f(z)

f(z) 就是 sigmoid 函数,

X

ˉ

\bar{X}

Xˉ 是所有弱评估器的分类结果的均值。在数学上我们也很容易证明:

当森林中的树互相独立,且

f

(

x

)

f(x)

f(x)为sigmoid函数时,Var(

f

(

X

ˉ

)

\boldsymbol{f(\bar{X})}

f(Xˉ))永远小于Var(

X

i

\boldsymbol{X_i}

Xi​)

f

(

x

)

f(x)

f(x) 为二阶可导函数时,根据泰勒展开我们可以有:

  • Var[f(A)]

\approx

≈ (f’E[A]))

2

^2 *

2∗Var[A]

  • 其中 A 为任意随机变量,f’ 为函数

f

(

x

)

f(x)

f(x) 的一阶导数。

  • 假设任意树输出的方差 Var(

X

i

X_i

Xi​) =

σ

2

\sigma^2

σ2,则有:

V

a

r

(

f

(

X

ˉ

)

)

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

当森林中的树互相独立,且

f

(

x

)

f(x)

f(x)为sigmoid函数时,Var(

f

(

X

ˉ

)

\boldsymbol{f(\bar{X})}

f(Xˉ))永远小于Var(

X

i

\boldsymbol{X_i}

Xi​)

f

(

x

)

f(x)

f(x) 为二阶可导函数时,根据泰勒展开我们可以有:

  • Var[f(A)]

\approx

≈ (f’E[A]))

2

^2 *

2∗Var[A]

  • 其中 A 为任意随机变量,f’ 为函数

f

(

x

)

f(x)

f(x) 的一阶导数。

  • 假设任意树输出的方差 Var(

X

i

X_i

Xi​) =

σ

2

\sigma^2

σ2,则有:

V

a

r

(

f

(

X

ˉ

)

)

[外链图片转存中…(img-XyLCUB0m-1714642588730)]
[外链图片转存中…(img-9BF7EC5w-1714642588730)]
[外链图片转存中…(img-1F9SHBAG-1714642588731)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

  • 20
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值