使用 fast.ai 库入门随机森林(程序员的机器学习——第1部分)

徐大白
1个月前 阅读 221 点赞 2

编程对于任何想要学习机器学习的人来说都是一个关键的必要条件。当然,有相当多的自动化工具在那里,但大多数仍然处于非常萌芽的阶段,且远远超出个人的预算。数据科学家的最佳结合点在于将编程和机器学习算法融合起来。

Fast.ai由Jeremy Howard和Rachel Thomas这一对最佳拍档联合创办。所以,当最近他们发布了他们的机器学习课程时,我迫不及待地想开始。

我个人喜欢这门课是自上而下的教学方法。您首先学习如何在Python中编写算法,然后转到理论方面。虽然不是一个独特的方法,它肯定有它的优势。

在去看这些视频的时候,我决定以一系列文章的形式在我们的优秀社区记录我的学习!因此,在第一篇文章中,我提供了前两个视频的综合总结(包括代码),其中Jeremy Howard教我们如何使用fast.ai库构建随机森林模型,以及如何调优不同的超参数可以显著地改变模型的精度。

您需要在Python中有一点经验来一起写代码。因此,如果您是机器学习的初学者,并且以前没有使用过Python和Jupyter Notebook,我建议您首先查看以下两个资源:

目录表

1.课程结构与材料

2.机器学习导论:第1课

  • 导入必要的库
  • 下载数据集
  • 读取文件
  • 随机森林概论
  • 数据预处理
  • 模型建立

3.机器学习导论:第2课

  • 创建验证集
  • 创建单一的树
  • Bagging介绍

4.话题延伸

1.课程结构与材料

视频讲座可在YouTube上进行,课程按以下结构分为十二堂课:

本课程假定你的电脑上安装了Jupyter Notebook。如果你不喜欢(也不喜欢安装),你可以选择以下任何一种(这些附带名义费用):

与每一节课程相关的所有笔记都可以在fast.ai的GitHub存储库上找到。您可以一次复制或下载整个存储库。可以在“安装”部分下找到完整的安装步骤

2.第一课:机器学习导论

准备好开始了吗?然后检查Jupyter Notebook和下面的视频

在本课中,我们将学习如何在Python中构建一个随机森林模型。由于本课程遵循自上而下的方法,我们将首先进行编码,同时理解代码如何工作。然后我们再研究随机森林算法的内部运作原理。

我们深入讨论一下这篇讲座的内容。

2.1 导入必要的库

%load ext_autoreload
%autoreload 2

当更新源代码时,上述两个命令将自动修改 Notebook。因此,使用 ext-autoreload 将自动且动态地在 Notebook 上进行更改。

%matplotlib inline

使用 %matplotlib inline,我们可以可视化笔记本内部的绘图。

from fastai.imports import*
from fastai.structured import *
from pandas_summary import DataFrameSummary
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from IPython.display import display
from sklearn import metrics

使用 import * 将导入fastai 库中的所有内容。为了读取数据框架摘要,创建用于计算RMSE(评估度量)的随机森林模型和度量,我们还导入了其他必要的库。

2.2 下载数据集

我们要使用的数据集是“Blue Book for Bulldozers”。以下是这次挑战的问题陈述:

其目的是根据某件重型设备的用途、设备类型和配置,预测其在拍卖会上的售价。数据来源于拍卖结果发布,包括使用和设备配置的信息。Fast Iron正在为推土机创造一本“蓝皮书”,让客户在拍卖中估价他们的重型设备车队的价值。

评价指标为RMSLE(均方根对数误差)。不要担心,如果你以前没有听说过,在撸代码的时候,我们会理解并处理它。假设您已经成功下载了数据集,让我们继续进行撸代码!

PATH = “data/bulldozers/”

此命令用于设置数据集的位置。我们现在将下载的数据集存储在数据文件夹内的名为 bulldozers 的文件夹中。要检查 PATH 中的文件是什么,可以键入:

!ls data/bulldozers/

或者:

!ls {PATH}

2.3 读取文件

我们提供的数据集为.csv格式。这是一个结构化数据集,其中列表示一系列内容,如ID、日期、状态、产品组等。对于处理结构化数据,Pandas是最重要的库。当我们早些时候使用 import* 命令时,我们已经输入Pandas (pd)。现在我们将使用Pandas 的 read_csv 函数读取数据:

df_raw = pd.read_csv(f'{PATH}Train.csv', low_memory=False, parse_dates=["saledate"])

让我们看看数据的前几行:

df_raw.head()

由于数据集很大,此命令不显示完整的列数据。相反,我们将看到一些不被显示的数据(如截图所示):

为了解决这个问题,我们将定义以下函数,其中将 max.rows max.columns 设置为1000。

def display_all(df):
    with pd.option_context("display.max_rows", 1000, "display.max_columns", 1000): 
        display(df)

现在我们可以使用这个新函数打印数据集的前面部分。我们已经用 transpose 使其视觉吸引力(我们看到列名称作为索引)。

display_all(df_raw.head().transpose())

记住,评估指标是RMSLE,它基本上是结果的日志值之间的RMSE。因此,我们将通过获取它的日志值来转换目标变量。这就是Numpy 库补救方式受欢迎的地方。

df_raw.SalePrice = np.log(df_raw.SalePrice)

2.4 随机森林概论

我们将在本课程的后面部分讨论随机森林模型从零开始工作的概念,但这里有一段关于Jeremy Howard的话的简短介绍:

  1. 随机森林是一种通用的机器学习技术。
  2. 它可以用于回归(目标是连续变量)或分类(目标是一个分类变量)问题。
  3. 它也适用于任何类型的列,如像素值、邮政编码、收入等。
  4. 一般来说,随机森林不会过拟合(很容易阻止它过度拟合)。
  5. 一般不需要单独的验证集。它可以告诉你它有多好,即使你只有一个数据集。
  6. 它很少(如果有的话)统计假设(它不假设“数据是正态分布的,数据是线性的”,或者你需要指定交互)。
  7. 需要很少的特征工程战术,所以这是一个很好的开始。对于许多不同类型的情况,不必使用数据日志或将交互相乘在一起。

听起来像是一种扣人心弦的技术,对吧?

Python中使用了RandomForestRegressor 函数和 RandomForestClassifier函数分别用于回归和分类问题。由于我们正在应对回归挑战,我们将坚持随机森林回归。

m = RandomForestRegressor(n_jobs=-1)
m.fit(df_raw.drop('SalePrice', axis=1), df_raw.SalePrice)

m.fit 函数有两个输入:

  • 独立变量
  • 依赖(目标)变量

这里的目标变量是 df_raw.SalePrice 。独立变量是除 SalePrice 以外的所有变量。在这里,我们使用df_raw.drop 抛出SalePrice 列(轴=1表示列)。这会产生如下错误:

ValueError: could not convert string to float: 'Conventional'

这表明该模型不能处理“常规”变量。大多数机器学习模型(包括随机森林)不能直接使用分类列。我们需要先把这些列转换成数字。因此,下一步自然是将所有的分类列转换成连续变量。

2.5 数据预处理

让我们逐一分类。首先,考虑 datetime 格式的 saledate 列。从日期列中,我们可以提取诸如–年、月、周、日、假期与否、周末或工作日,是否下雨等。

我们将利用 fast.ai 库中的 add_datepart 函数来为我们创建这些特征。该函数创建以下特征:

'Year', 'Month', 'Week', 'Day', 'Dayofweek',
'Dayofyear', 'Is_month_end', 'Is_month_start',
'Is_quarter_end', 'Is_quarter_start', 'Is_year_end',
'Is_year_start'

让我们运行函数并检查列:

add_datepart(df_raw, 'saledate')
df_raw.columns


Index(['SalesID', 'SalePrice', 'MachineID', 'ModelID', 'datasource',
       'auctioneerID', 'YearMade', 'MachineHoursCurrentMeter', 'UsageBand',
       'fiModelDesc', 'fiBaseModel', 'fiSecondaryDesc', 'fiModelSeries',
       'fiModelDescriptor', 'ProductSize', 'fiProductClassDesc', 'state',
       'ProductGroup', 'ProductGroupDesc', 'Drive_System', 'Enclosure',
       'Forks', 'Pad_Type', 'Ride_Control', 'Stick', 'Transmission',
       'Turbocharged', 'Blade_Extension', 'Blade_Width', 'Enclosure_Type',
       'Engine_Horsepower', 'Hydraulics', 'Pushblock', 'Ripper', 'Scarifier',
       'Tip_Control', 'Tire_Size', 'Coupler', 'Coupler_System',
       'Grouser_Tracks', 'Hydraulics_Flow', 'Track_Type',
       'Undercarriage_Pad_Width', 'Stick_Length', 'Thumb', 'Pattern_Changer',
       'Grouser_Type', 'Backhoe_Mounting', 'Blade_Type', 'Travel_Controls',
       'Differential_Type', 'Steering_Controls', 'saleYear', 'saleMonth',
       'saleWeek', 'saleDay', 'saleDayofweek', 'saleDayofyear',
       'saleIs_month_end', 'saleIs_month_start', 'saleIs_quarter_end',
       'saleIs_quarter_start', 'saleIs_year_end', 'saleIs_year_start',
       'saleElapsed'],
      dtype='object')

下一步是将分类变量转换成数字。我们可以使用fast.ai 的train_cats函数:

train_cats(df_raw)

在将分类转换为数字列时,我们必须考虑以下两个问题:

1.一些分类变量可以有它们之间的顺序(例如:High>Medium>Low)。我们可以使用set_categories 来设置顺序。

df_raw.UsageBand.cat.set_categories(['High', 'Medium', 'Low'], ordered=True, inplace=True)

2.如果一个类别在训练数据中得到一个特定的数字,那么它应该在测试数据中具有相同的值。例 如,如果训练数据高达3,测试数据有2,那么它将有两个不同的含义。我们可以使用 apply-cats 进行验证和测试数据集,以确保映射在不同的集合中是相同的。

虽然这不会对我们当前的情况产生很大影响,因为随机森林对数据集进行分割(稍后我们将详细了解随机森林是如何工作的),但是对于其他算法来说,知道这一点仍然很好。

缺失值处理

下一步是查看数据集中缺失值的数量,并了解如何处理它们。这在机器学习竞赛和现实工业问题上都是一个非常普遍的挑战。

display_all(df_raw.isnull().sum().sort_index()/len(df_raw))

我们使用 .innull() .sum() 来获取缺失值的总数,被数据集的长度除以确定缺失值的比率。

已经为创建模型准备好了数据集。数据清洗一直是一个繁琐和费时的过程。因此,请确保保存转换后的数据集,以便下次加载数据时,不必再次执行上述任务。

我们将以 feather 格式保存它,这可以让我们有效地访问数据:

#to save
os.makedirs('tmp', exist_ok=True)
df.to_feather('tmp/bulldozers-raw')

#to read
df_raw = pd.read_feather('tmp/bulldozers-raw')

我们必须对缺失值进行归类,并将数据存储为依赖和独立的部分。这是通过使用 fastai 的 proc_df函数 来完成的。该函数执行以下任务:

  1. 对于连续变量,它检查列是否存在缺失值;
  2. 如果列有缺失值,则创建另一列名为 columnname_na,1代表有缺失值,0代表没有缺失值;
  3. 同时,缺失值被列的中值所代替;
  4. 对于分类变量,Pandas 用-1替换缺失值。因此,proc_df 为分类变量的所有值增加了1。因此,我们0代表缺失值,而所有其他值都递增1。
df, y, nas = proc_df(df_raw, 'SalePrice')

2.6 模型建立

我们已经处理了分类列和日期值。我们也注意到了缺失值。现在,我们终于可以启动并建立我们一直向往的随机森林模型。

m = RandomForestRegressor(n_jobs=-1)
m.fit(df, y)
m.score(df,y)

n_job 设置为-1,以使用机器上所有可用的内核。这给我们一个分数(R^ 2)0.98,这是很好的。需要提醒的是我们在训练集上对模型进行了训练,并对结果进行了检验。很有可能这个模型在未被看到的数据(测试集,在我们的例子中)上不能很好地执行。

唯一的方法是创建一个验证集并检查模型上的性能。因此,让我们创建一个包含12000个数据点的验证集(并且训练集将包含其余的部分)。

def split_vals(a,n): 
    return a[:n].copy(), a[n:].copy()

n_valid = 12000  # same as Kaggle's test set size
n_trn = len(df)-n_valid
raw_train, raw_valid = split_vals(df_raw, n_trn)
X_train, X_valid = split_vals(df, n_trn)
y_train, y_valid = split_vals(y, n_trn)

X_train.shape, y_train.shape, X_valid.shape


((389125, 66), (389125,), (12000, 66))

这里,我们将在新的集合(原始集合的一个样本)上训练模型,并检查跨训练集和验证集的性能。

#define a function to check rmse value
def rmse(x,y): 
    return math.sqrt(((x-y)**2).mean())

为了将训练集与测试集的比分进行比较,下面的函数返回两个数据集的RMSE值和得分。

def print_score(m):
    res = [rmse(m.predict(X_train), y_train),
           rmse(m.predict(X_valid), y_valid),
           m.score(X_train, y_train), m.score(X_valid, y_valid)]
    if hasattr(m, 'oob_score_'): res.append(m.oob_score_)
    print(res)


m = RandomForestRegressor(n_jobs=-1)
%time m.fit(X_train, y_train)
print_score(m)

上述代码的结果如下所示。列车组的得分为0.98,而验证集的得分为0.88。有点下降,但总体上模型仍然表现良好。

CPU times: user 1min 3s, sys: 356 ms, total: 1min 3s
Wall time: 8.46 s
[0.09044244804386327, 0.2508166961122146, 0.98290459302099709, 0.88765316048270615]

3. 第二课:介绍机器学习

现在你知道如何用Python代码建立随机森林模型,理解它是如何在所有的代码工作的也是很重要的。随机森林有黑匣子模型,是时候跟这种误解说再见了。第二课视频

我们在第一节课中观察到,模型在训练数据(它以前见过的点)上表现得非常好,但是在验证集上测试时(数据点模型未被训练)会下降。让我们首先了解我们是如何创建验证集以及为什么它是如此重要的。

3.1 创建验证集

创建一个与测试集非常相似的良好验证集是机器学习中最重要的任务之一。验证分数代表我们的模型是如何在真实世界的数据上执行的,或者是在测试数据上执行的。

请记住,如果涉及到一个时间组件,那么最新的行应该包含在验证集中。因此,我们的验证集将具有与测试集相同的大小(从训练数据的最后12000行)。

def split_vals(a,n):
   return a[:n].copy(), a[n:].copy()

n_valid = 12000  
n_trn = len(df)-n_valid
raw_train, raw_valid = split_vals(df_raw, n_trn)
X_train, X_valid = split_vals(df, n_trn)
y_train, y_valid = split_vals(y, n_trn)

从0到(长度为12000)的数据点被存储为训练集(x_train,y_train)。使用训练集建立模型,并在训练集和验证集上对其性能进行测量。

m = RandomForestRegressor(n_jobs=-1)
%time m.fit(X_train, y_train)
print_score(m)


CPU times: user 1min 3s, sys: 356 ms, total: 1min 3s 
Wall time: 8.46 s 
[0.09044244804386327, 0.2508166961122146, 0.98290459302099709, 0.88765316048270615]

从上面的代码,我们得到的结果:

  • 训练集上的RMSE
  • 验证集上的RMSE
  • 训练集上的决定系数
  • 验证集上的决定系数

很明显,该模型在训练集上是过度拟合的。此外,它需要花费一分钟来进行训练。我们能减少训练时间吗?是的,我们可以!要做到这一点,我们将进一步采取原始数据集的子集:

df_trn, y_trn, nas = proc_df(df, 'SalePrice', subset=30000)
X_train, _ = split_vals(df_trn, 20000)
y_train, _ = split_vals(y_trn, 20000)

已经创建了30000个样本的子集,从中我们用20000个来训练随机森林模型。

3.2 建造单一的树

随机森林是一组被称为估计器的树。随机森林模型中的树数是由 n_estimators 定义的。我们首先来看一棵树(设置n_esitmators=1),最大深度为3。

m = RandomForestRegressor(n_estimators=1, max_depth=3, bootstrap=False, n_jobs=-1)
m.fit(X_train, y_train)
print_score(m)

绘制树:

[0.4965829795739235, 0.5246832258551836, 0.50149617735615859, 0.5083655198087873]


draw_tree(m.estimators_[0], df_trn, precision=3)

树是一组二元决策。观察第一个盒子,第一个分裂是在耦合器系统值上:小于等于0.5或大于0.5。分裂后,我们得到3185行coupler_system>0.5,剩下的16815行<0.5。类似地,下一个分裂是在EnclosureYearMade上进行的。

对于第一个盒子,只使用平均值(10.189)创建模型。这意味着所有行的预测值为10.189,对于这些预测的MSE(均方误差)为0.459。相反,如果我们基于coupler_system<0.5对行进行分割和分离,则满足条件(true)的样本的MSE减少到0.414,其余的样本的MSE减少到0.109。

那么,我们如何决定要分裂哪个变量呢?这个想法是把数据分成两组,尽可能不同。这可以通过检查每个变量的每个可能的分裂点来完成,然后计算出哪个变量给出了较低的MSE。为了做到这一点,我们可以采取分裂后的两个MSE值的加权平均。当它达到预先指定的Max深度值或当每个叶节点只有一个值时,分裂停止。

我们有一个基本的模型-一个单一树,但这不是一个很好的模型。我们需要一个更复杂的基于这个结构的东西。为了创建森林,我们将使用一种称为袋装的统计技术。

3.3 Bagging介绍

在Bagging技术中,我们创建多个模型,每个模型给出与另一个模型不相关的预测。然后我们从这些模型中预测平均值。随机森林是一种Bagging技术。

如果创建的所有树彼此相似,并且给出类似的预测,那么对这些预测进行平均将不会提高模型的性能。相反,我们可以在不同的数据子集上创建多个树,这样即使这些树过拟合,它们也会在不同的点集上这样做。这些样品是用替代品进行的。

简单地说,我们创建了多个性能差的模型,并对它们进行平均,以创建一个好的模型。个别模型必须尽可能预测,但在一起应该是不相关的。现在我们将增加随机森林中的估计数,并看结果。

m = RandomForestRegressor(n_jobs=-1)
m.fit(X_train, y_train)
print_score(m)

如果我们不给 n_estimators 进行参数赋值,则默认为10。我们将从这10棵树的每一棵树上得到预测。此外,np.stack 将被用于将预测连接到另一个。

preds = np.stack([t.predict(X_valid) for t in m.estimators_])


preds.shape

预测的维度为(10, 12000)。这意味着我们对验证集中的每一行都有10个预测。

现在,为了比较模型的结果与验证集,这里是一行预测、预测的平均值和来自验证集的实际值。

preds[:,0], np.mean(preds[:,0]), y_valid[0]

实际值是9.17,但我们的预测没有一个接近这个值。在我们所有预测的平均值上,我们得到9.07,这是比任何单个树更好的预测。

(array([ 9.21034,  8.9872 , 8.9872 , 8.9872 ,  8.9872 , 9.21034, 8.92266, 9.21034,  9.21034, 8.9872 ]),
9.0700003890739005,
9.1049798563183568)

尽可能多地可视化模型是一个好主意。这里是一个曲线图,显示了随着树数的增加,r^ 2值的变化。

plt.plot([metrics.r2_score(y_valid, np.mean(preds[:i+1], axis=0)) for i in range(10)]);

正如预期的那样,随着树数的增加,r^ 2变得更好。您可以尝试Ny估计值,看看R^ 2值如何随每次迭代而变化。你会注意到,在一定数量的树之后,r^ 2值趋于平稳。

3.3.1 Out-of-Bag(OOB)评分

为小数据集创建单独的验证集可能存在问题,因为它将导致更小的训练集。在这种情况下,我们可以使用树未被训练的数据点(或样本)。

为此,我们设置参数 oob_score=true 。

m = RandomForestRegressor(n_estimators=40, n_jobs=-1, oob_score=True)
m.fit(X_train, y_train)
print_score(m)

[0.10198464613020647, 0.2714485881623037, 0.9786192457999483, 0.86840992079038759, 0.84831537630038534]

oob_score 评分为0.84,接近验证集。让我们看看一些其他可以用来改进我们的模型的有趣的技术。

3.3.2 子采样

之前我们创建了一个30000行的子集,从这个子集随机选择训练集。作为另一种选择,我们可以每次创建一个不同的子集,以便模型对数据的较大部分进行训练。

df_trn, y_trn, nas = proc_df(df_raw, 'SalePrice')
X_train, X_valid = split_vals(df_trn, n_trn)
y_train, y_valid = split_vals(y_trn, n_trn)
set_rf_samples(20000)

我们使用 set_rf_sample 示例来指定样本大小。让我们检查一下模型的性能是否有所改进。

m = RandomForestRegressor(n_estimators=40, n_jobs=-1, oob_score=True)
m.fit(X_train, y_train)
print_score(m)

[0.2317315086850927, 0.26334275954117264, 0.89225792718146846, 0.87615150359885019, 0.88097587673696554]

我们得到了0.876的验证分数。到目前为止,我们已经研究了一个样本的子集。我们可以将这个模型应用到整个数据集(但是根据计算资源的好坏,运行它需要很长时间!).

reset_rf_samples()
m = RandomForestRegressor(n_estimators=40, n_jobs=-1, oob_score=True)
m.fit(X_train, y_train)
print_score(m)

[0.07843013746508616, 0.23879806957665775, 0.98490742269867626, 0.89816206196980131, 0.90838819297302553]

3.4 其他超参数实验和调谐

3.4.1 最小样叶

这可以被视为树的停止标准。当叶子节点中的样本数量少于指定时,树停止生长(或分裂)。

m = RandomForestRegressor(n_estimators=40, min_samples_leaf=3,n_jobs=-1, oob_score=True)
m.fit(X_train, y_train)
print_score(m)

[0.11595869956476182, 0.23427349924625201, 0.97209195463880227, 0.90198460308551043, 0.90843297242839738]

在这里,我们指定了 min_sample_leaf 为3。这意味着节点中的每个样本的最小数量应该是3。我们看到,r^2对验证集进行了改进,并在测试集上进行了缩减,从而得出结论,该模型在训练数据上不会过拟合。

3.4.2 Max feature

随机森林中的另一个重要参数是 max_feature 。我们以前已经讨论过,个体树必须尽可能不相关。同样,随机森林使用一行子集来训练每棵树。此外,我们还可以使用列的子集(features),而不是使用所有的festures。这是通过调整 max_feature 参数实现的。

m = RandomForestRegressor(n_estimators=40, min_samples_leaf=3, max_features=0.5, n_jobs=-1, oob_score=True) 
m.fit(X_train, y_train)
print_score(m)

[0.11926975747908228, 0.22869111042050522, 0.97026995966445684, 0.9066000722129437, 0.91144914977164715]

设置 max_feature 稍微提高了验证分数。这里,max_feature 被设置为0.5,这意味着每个分裂使用50%的特征。请记住,此参数也可以采用类似 Log2Sqrt 的值。

4.话题延伸

4.1 Jupyter Notebook中的提示和技巧

Jeremy Howard提到了一些Jupyter Notebook的导航提示与技巧,新手们会发现它非常有用。以下是一些亮点:

  • 若要找出函数所在的库,只需键入函数名并运行单元格(shift输入):
display

  • 要查看文档,请在函数之前使用问号:
?display

  • 若要查看函数的源代码,请在函数名称之前使用双问号:
??display

4.2 维灾

维灾是认为我们拥有更多维度,空间的边缘就会有更多的点。因此,如果列的数量越多,它就会产生越来越多的空白。理论上,这意味着点之间的距离远没有那么有意义。这不应该是真的,因为这些点仍然是彼此不同的距离。即使它们在边缘,我们仍然可以确定它们离彼此有多远。

4.3 连续、分类、序数变量

连续变量是具有整数或浮点值的变量。例如年龄、距离、体重、收入等

分类变量通常是字符串或表示名称或标签的值。例如性别、国家、邮政编码、等级等

序数变量是那些在它们之间有顺序的分类变量。例如秩(i,ii,iii)或注释(poor,good,excellent)有顺序。

4.4 过拟合与欠拟合


欠拟合:在列车数据和测试数据上表现不佳的模型。模型不能很好地推广。(左图)

过拟合:一种模型,它在列车数据上表现得非常好,但在测试数据上没有表现出类似的高性能。(正确情节)

4.5 均方根对数误差

我们的数据集的评价指标是RMSLE。这个公式是:

我们首先取对数值的平方差的平均值,然后取所得结果的平方根。这相当于计算值的对数的均方根误差(RMSE)。

4.6 决定系数

这里是决定系数的数学公式:

决定系数的值可以小于1。如果决定系数是负的,这意味着你的模型比预测平均值更差。

4.7 极随机树

scikit_learn 中,我们有另一种算法,即极端随机树分类器。不像随机森林,它不会为每个变量尝试每个分割点,而是为几个变量随机尝试几个分割点。

5. 小结

这篇文章是对 fast.ai 的机器学习课程的前两个视频的一个非常全面的总结。在第一节课中,我们学会了在 bulldozer 数据集上编码一个简单的随机森林模型。随机森林(和大多数ML算法)不适用于分类变量。在随机森林实现期间,我们遇到了类似的问题,并且我们看到了如何使用数据集中的日期列和其他分类列来创建模型。

在第二个视频中,引入了创建验证集的概念。然后,我们使用这个验证集来检查模型的性能,并调整一些基本的超参数来改进模型。这段视频中我最喜欢的部分是绘制和可视化我们建造的树。我相信你会通过这些视频学到很多东西。我不久将发表另一篇文章,内容包括接下来的两段视频。


原文链接An Introduction to Random Forest using the fastai Library (Machine Learning for Programmers – Part 1)

翻译:徐大白

| 2
登录后可评论,马上登录吧~
评论 ( 1 )
像徐大神学习
回复
4周前