极端随机树(Extra Trees)是一种集成机器学习算法,它结合了许多决策树的预测结果。
它与广泛使用的随机森林算法相关。它通常可以获得与随机森林算法一样好甚至更好的性能,尽管它使用更简单的算法来构建用作集成成员的决策树。
由于其关键超参数较少且配置这些超参数的启发式方法合理,因此它也易于使用。
在本教程中,您将学习如何开发用于分类和回归的极端随机树集成模型。
完成本教程后,您将了解:
- 极端随机树集成模型是决策树的集成模型,与装袋法和随机森林相关。
- 如何使用 scikit-learn 对分类和回归问题使用极端随机树集成模型。
- 如何探索极端随机树模型超参数对模型性能的影响。
使用我的新书《使用 Python 的集成学习算法》启动您的项目,其中包括所有示例的分步教程和Python 源代码文件。
让我们开始吧。

如何使用 Python 开发额外树集成
图片由 Nicolas Raymond 拍摄,保留部分权利。
教程概述
本教程分为三个部分;它们是:
- 极端随机树算法
- 极端随机树 Scikit-Learn API
- 用于分类的极端随机树
- 用于回归的极端随机树
- 极端随机树超参数
- 探索树的数量
- 探索特征数量
- 探索每次分割的最小样本数
极端随机树算法
极端随机树,简称 Extra Trees,是一种集成机器学习算法。
具体来说,它是决策树的集成模型,与装袋法(bagging)和随机森林等其他决策树集成算法相关。
极端随机树算法通过从训练数据集中创建大量未修剪的决策树来工作。在回归的情况下,通过平均决策树的预测来进行预测;在分类的情况下,则通过多数投票进行预测。
- 回归:通过平均决策树的预测来做出预测。
- 分类:通过决策树的多数投票来做出预测。
树的预测结果会被聚合以产生最终预测,在分类问题中通过多数投票,在回归问题中通过算术平均。
— 《极端随机树》,2006年。
与装袋法和随机森林不同,后者从训练数据集的自助采样(bootstrap sample)中开发每个决策树,而极端随机树算法则在整个训练数据集上拟合每个决策树。
与随机森林类似,极端随机树算法会在决策树的每个分割点随机采样特征。与随机森林不同的是,随机森林使用贪婪算法选择最优分割点,而极端随机树算法则随机选择一个分割点。
Extra-Trees 算法根据经典的自顶向下过程构建了一个未修剪的决策树或回归树集成。它与其他基于树的集成方法有两个主要区别:它通过完全随机选择分割点来分割节点,并且使用整个学习样本(而不是自助复制样本)来生长树。
— 《极端随机树》,2006年。
因此,算法中有三个主要的超参数需要调整:集成中的决策树数量、随机选择并考虑用于每个分割点的输入特征数量,以及创建新分割点所需的节点中的最小样本数量。
它有两个参数:K,即每个节点随机选择的属性数量;nmin,即分割节点的最小样本量。[...] 我们将此集成的树数量表示为 M。
— 《极端随机树》,2006年。
分割点的随机选择使得集成中的决策树相关性较低,尽管这会增加算法的方差。这种方差的增加可以通过增加集成中使用的树的数量来抵消。
参数 K、nmin 和 M 具有不同的效果:K 决定属性选择过程的强度,nmin 决定平均输出噪声的强度,M 决定集成模型聚合的方差减少强度。
— 《极端随机树》,2006年。
想开始学习集成学习吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
极端随机树 Scikit-Learn API
极端随机树集成模型可以从头开始实现,尽管这对于初学者来说可能具有挑战性。
scikit-learn Python 机器学习库提供了极端随机树的机器学习实现。
它在库的最新版本中可用。
首先,通过运行以下脚本确认您正在使用该库的现代版本
1 2 3 |
# 检查 scikit-learn 版本 import sklearn print(sklearn.__version__) |
运行脚本将打印您的 scikit-learn 版本。
您的版本应该与此版本相同或更高。
如果不是,您必须升级您的 scikit-learn 库版本。
1 |
0.22.1 |
极端随机树通过 `ExtraTreesRegressor` 和 `ExtraTreesClassifier` 类提供。
这两个模型的操作方式相同,并接受影响决策树创建方式的相同参数。
模型构建中使用了随机性。这意味着每次在相同数据上运行算法时,它都会生成一个略有不同的模型。
在使用具有随机学习算法的机器学习算法时,通过对多次运行或重复交叉验证的性能进行平均来评估它们是一种很好的做法。在拟合最终模型时,可能需要增加树的数量,直到模型方差在重复评估中减少,或者拟合多个最终模型并平均它们的预测。
让我们看看如何为分类和回归开发极端随机树集成模型。
用于分类的极端随机树
在本节中,我们将探讨在分类问题中使用极端随机树。
首先,我们可以使用 make_classification() 函数 创建一个包含 1,000 个示例和 20 个输入特征的合成二元分类问题。
完整的示例如下所示。
1 2 3 4 5 6 |
# 测试分类数据集 from sklearn.datasets import make_classification # 定义数据集 X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=4) # 汇总数据集 print(X.shape, y.shape) |
运行示例会创建数据集并总结输入和输出组件的形状。
1 |
(1000, 20) (1000,) |
接下来,我们可以在此数据集上评估极端随机树算法。
我们将使用重复分层 k 折交叉验证来评估模型,其中重复 3 次,折叠 10 次。我们将报告模型在所有重复和折叠中的平均准确度和标准差。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 评估用于分类的极端随机树算法 from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold 从 sklearn.集成 导入 ExtraTreesClassifier # 定义数据集 X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=4) # 定义模型 model = ExtraTreesClassifier() # 评估模型 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise') # 报告表现 print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
运行示例报告了模型的平均准确度和标准差。
注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到默认超参数的极端随机树集成模型在此测试数据集上实现了大约 91% 的分类准确率。
1 |
准确率:0.910 (0.027) |
我们还可以将极端随机树模型用作最终模型并进行分类预测。
首先,极端随机树集成模型在所有可用数据上进行拟合,然后可以调用 `predict()` 函数对新数据进行预测。
以下示例在我们的二元分类数据集上演示了这一点。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 使用极端随机树进行分类预测 from sklearn.datasets import make_classification 从 sklearn.集成 导入 ExtraTreesClassifier # 定义数据集 X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=4) # 定义模型 model = ExtraTreesClassifier() # 在整个数据集上拟合模型 model.fit(X, y) # 进行单次预测 row = [[-3.52169364,4.00560592,2.94756812,-0.09755101,-0.98835896,1.81021933,-0.32657994,1.08451928,4.98150546,-2.53855736,3.43500614,1.64660497,-4.1557091,-1.55301045,-0.30690987,-1.47665577,6.818756,0.5132918,4.3598337,-4.31785495]] yhat = model.predict(row) print('Predicted Class: %d' % yhat[0]) |
运行示例将极端随机树集成模型拟合到整个数据集上,然后用于对新的数据行进行预测,就像我们在应用程序中使用模型时那样。
1 |
预测类别:0 |
既然我们熟悉了分类的极端随机树用法,接下来我们看看回归的 API。
用于回归的极端随机树
在本节中,我们将探讨在回归问题中使用极端随机树。
首先,我们可以使用 make_regression() 函数 创建一个包含 1,000 个示例和 20 个输入特征的合成回归问题。
完整的示例如下所示。
1 2 3 4 5 6 |
# 测试回归数据集 from sklearn.datasets import make_regression # 定义数据集 X, y = make_regression(n_samples=1000, n_features=20, n_informative=15, noise=0.1, random_state=3) # 汇总数据集 print(X.shape, y.shape) |
运行示例会创建数据集并总结输入和输出组件的形状。
1 |
(1000, 20) (1000,) |
接下来,我们可以在此数据集上评估极端随机树算法。
与上一节一样,我们将使用重复的 k 折交叉验证来评估模型,重复三次,每次 10 折。我们将报告模型在所有重复和折叠中的平均绝对误差 (MAE)。
scikit-learn 库将 MAE 设置为负数,以便将其最大化而不是最小化。这意味着负 MAE 越大越好,一个完美的模型 MAE 为 0。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 评估用于回归的极端随机树集成模型 from numpy import mean from numpy import std from sklearn.datasets import make_regression from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedKFold from sklearn.ensemble import ExtraTreesRegressor # 定义数据集 X, y = make_regression(n_samples=1000, n_features=20, n_informative=15, noise=0.1, random_state=3) # 定义模型 model = ExtraTreesRegressor() # 评估模型 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) n_scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1, error_score='raise') # 报告表现 print('MAE: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
运行示例报告了模型的平均准确度和标准差。
注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到默认超参数的极端随机树集成模型实现了大约 70 的 MAE。
1 |
MAE:-69.561 (5.616) |
我们还可以将极端随机树模型用作最终模型并进行回归预测。
首先,极端随机树集成模型在所有可用数据上进行拟合,然后可以调用 `predict()` 函数对新数据进行预测。
以下示例在我们的回归数据集上演示了这一点。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 极端随机树用于回归预测 from sklearn.datasets import make_regression from sklearn.ensemble import ExtraTreesRegressor # 定义数据集 X, y = make_regression(n_samples=1000, n_features=20, n_informative=15, noise=0.1, random_state=3) # 定义模型 model = ExtraTreesRegressor() # 在整个数据集上拟合模型 model.fit(X, y) # 进行单次预测 row = [[-0.56996683,0.80144889,2.77523539,1.32554027,-1.44494378,-0.80834175,-0.84142896,0.57710245,0.96235932,-0.66303907,-1.13994112,0.49887995,1.40752035,-0.2995842,-0.05708706,-2.08701456,1.17768469,0.13474234,0.09518152,-0.07603207]] yhat = model.predict(row) print('Prediction: %d' % yhat[0]) |
运行示例将极端随机树集成模型拟合到整个数据集上,然后用于对新的数据行进行预测,就像我们在应用程序中使用模型时那样。
1 |
预测:53 |
现在我们已经熟悉了如何使用 scikit-learn API 评估和使用极端随机树集成模型,接下来我们来看看如何配置模型。
极端随机树超参数
在本节中,我们将更深入地探讨您应该考虑为极端随机树集成模型调整的一些超参数及其对模型性能的影响。
探索树的数量
极端随机树算法的一个重要超参数是集成中使用的决策树数量。
通常,树的数量会一直增加,直到模型性能稳定下来。直觉可能会认为更多的树会导致过拟合,但情况并非如此。由于学习算法的随机性,装袋法、随机森林和极端随机树算法似乎对训练数据集的过拟合具有一定的免疫力。
树的数量可以通过“n_estimators”参数设置,默认为 100。
下面的示例探讨了树的数量在 10 到 5,000 之间对性能的影响。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# 探索极端随机树数量对性能的影响 from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.ensemble import ExtraTreesClassifier from matplotlib import pyplot # 获取数据集 定义 获取_数据集(): X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=4) 返回 X, y # 获取要评估的模型列表 定义 获取_模型(): models = dict() # 定义要考虑的树的数量 n_trees = [10, 50, 100, 500, 1000, 5000] for n in n_trees: models[str(n)] = ExtraTreesClassifier(n_estimators=n) 返回 模型 # 使用交叉验证评估给定模型 def evaluate_model(model, X, y): # 定义评估过程 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型并收集结果 scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1) 返回 分数 # 定义数据集 X, y = get_dataset() # 获取要评估的模型 模型 = 获取_模型() # 评估模型并存储结果 results, names = list(), list() for name, model in models.items(): # 评估模型 scores = evaluate_model(model, X, y) # 存储结果 results.append(scores) names.append(name) # 沿途总结性能 print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores))) # 绘制模型性能以供比较 pyplot.boxplot(results, labels=names, showmeans=True) pyplot.show() |
运行示例首先报告每个配置的决策树数量的平均准确率。
注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到性能在约 100 棵树之后上升并保持平稳。平均准确率分数在 100、500 和 1,000 棵树之间波动,这可能是统计噪声。
1 2 3 4 5 6 |
>10 0.860 (0.029) >50 0.904 (0.027) >100 0.908 (0.026) >500 0.910 (0.027) >1000 0.910 (0.026) >5000 0.912 (0.026) |
为每个配置的树数量创建了准确率分数的箱线图。
我们可以看到性能随着树的数量增加而普遍上升的趋势,可能在 100 棵树之后趋于平稳。

极端随机树集成模型大小与分类准确率的箱线图
探索特征数量
对于极端随机树,每个分割点随机采样的特征数量可能是最重要的配置特征,就像随机森林一样。
与随机森林类似,极端随机树算法对使用的具体值不敏感,尽管它是一个重要的超参数。
它通过 `max_features` 参数设置,默认为输入特征数量的平方根。对于我们的测试数据集,这将是 sqrt(20) 或大约四个特征。
下面的示例探讨了每个分割点随机选择的特征数量对模型准确率的影响。我们将尝试 1 到 20 的值,并期望根据启发式方法,大约四个的小值表现良好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# 探索极端随机树特征数量对性能的影响 from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.ensemble import ExtraTreesClassifier from matplotlib import pyplot # 获取数据集 定义 获取_数据集(): X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=4) 返回 X, y # 获取要评估的模型列表 定义 获取_模型(): models = dict() # 探索每个分割的特征数量从 1 到 20 for i in range(1, 21): models[str(i)] = ExtraTreesClassifier(max_features=i) 返回 模型 # 使用交叉验证评估给定模型 def evaluate_model(model, X, y): # 定义评估过程 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型并收集结果 scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1) 返回 分数 # 定义数据集 X, y = get_dataset() # 获取要评估的模型 模型 = 获取_模型() # 评估模型并存储结果 results, names = list(), list() for name, model in models.items(): # 评估模型 scores = evaluate_model(model, X, y) # 存储结果 results.append(scores) names.append(name) # 沿途总结性能 print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores))) # 绘制模型性能以供比较 pyplot.boxplot(results, labels=names, showmeans=True) pyplot.show() |
运行示例首先报告了每个特征集数量的平均准确率。
注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,结果表明 4 到 9 之间的值是合适的,这证实了该数据集上 4 的合理默认值。
考虑到分类准确率的平均值更大且标准差更小,9 的值甚至可能更好,尽管分数差异可能具有统计学意义,也可能不具有。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
>1 0.901 (0.028) >2 0.909 (0.028) >3 0.901 (0.026) >4 0.909 (0.030) >5 0.909 (0.028) >6 0.910 (0.025) >7 0.908 (0.030) >8 0.907 (0.025) >9 0.912 (0.024) >10 0.904 (0.029) >11 0.904 (0.025) >12 0.908 (0.026) >13 0.908 (0.026) >14 0.906 (0.030) >15 0.909 (0.024) >16 0.908 (0.023) >17 0.910 (0.021) >18 0.909 (0.023) >19 0.907 (0.025) >20 0.903 (0.025) |
为每个特征集数量的准确率分数分布创建了箱线图。
我们看到性能呈上升趋势,在 4 到 9 之间达到峰值,随着考虑更大的特征集大小而下降或保持平稳。

极端随机树特征集大小与分类准确率的箱线图
探索每次分割的最小样本数
最后一个有趣的超参数是在添加分割之前决策树节点中的样本数量。
只有当样本数量等于或超过此值时,才会向决策树添加新的分割。它通过“min_samples_split”参数设置,默认为两个样本(最小值)。较小的样本数量会导致更多的分割和更深、更专业的树。反过来,这可能意味着集成中树的预测之间的相关性较低,并可能提升性能。
下面的示例探讨了极端随机树在分割前最小样本数对模型性能的影响,测试值为 2 到 14。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# 探索极端随机树在分割前最小样本数对性能的影响 from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.ensemble import ExtraTreesClassifier from matplotlib import pyplot # 获取数据集 定义 获取_数据集(): X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=4) 返回 X, y # 获取要评估的模型列表 定义 获取_模型(): models = dict() # 探索每个分割的样本数量从 2 到 14 for i in range(2, 15): models[str(i)] = ExtraTreesClassifier(min_samples_split=i) 返回 模型 # 使用交叉验证评估给定模型 def evaluate_model(model, X, y): # 定义评估过程 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型并收集结果 scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1) 返回 分数 # 定义数据集 X, y = get_dataset() # 获取要评估的模型 模型 = 获取_模型() # 评估模型并存储结果 results, names = list(), list() for name, model in models.items(): # 评估模型 scores = evaluate_model(model, X, y) # 存储结果 results.append(scores) names.append(name) # 沿途总结性能 print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores))) # 绘制模型性能以供比较 pyplot.boxplot(results, labels=names, showmeans=True) pyplot.show() |
运行示例首先报告每个配置的最大树深度的平均准确度。
注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到较小的值会带来更好的性能,这证实了默认值2是合理的。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
>2 0.909 (0.025) >3 0.907 (0.026) >4 0.907 (0.026) >5 0.902 (0.028) >6 0.902 (0.027) >7 0.904 (0.024) >8 0.899 (0.026) >9 0.896 (0.029) >10 0.896 (0.027) >11 0.897 (0.028) >12 0.894 (0.026) >13 0.890 (0.026) >14 0.892 (0.027) |
为每个配置的最大树深度的准确度分数分布创建了一个箱线图。
在这种情况下,我们可以看到,在更少的最小样本进行分割时,性能有提高的趋势,正如我们所预期的那样。

Extra Trees 最小分割样本数与分类准确度箱线图
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
论文
- 极端随机树, 2006.
API
总结
在本教程中,您学习了如何开发用于分类和回归的 Extra Trees 集成模型。
具体来说,你学到了:
- 极端随机树集成模型是决策树的集成模型,与装袋法和随机森林相关。
- 如何使用 scikit-learn 对分类和回归问题使用极端随机树集成模型。
- 如何探索极端随机树模型超参数对模型性能的影响。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
这种算法或其他算法中是否有指定特征选择而不是随机选择的工具。让我解释得更清楚些。如果我有特征a,b,c,d,e,f,g,h,假设我认为a,b,c在预测能力方面逻辑上相关,而其他特征属于第二组。现在我可以创建两个模型,然后以某种方式汇集预测结果,但我想知道是否有模块可以在一个模型的操作下完成所有这些……谢谢
不。它选择能产生最佳性能模型的特征。
如果您愿意,可以将特征选择作为预处理步骤执行。
嗨 Jason,我想绘制从“探索特征数量”获得的准确度的混淆矩阵。每个特征显示不同的准确度,那么我应该如何拟合模型并使用“y-test”和“y-predict”绘制混淆矩阵呢?谢谢。
您可以选择一种配置,然后将数据集分成训练集和测试集,在训练集上拟合,预测测试集,并计算这些预测的混淆矩阵。
嗨 Jason,任何模型在优化超参数后表现不佳的可能原因是什么?在我的 Extra Tree 算法中,模型得分72%,但在优化超参数后,只能得分63%。请问您能告诉我原因吗?
也许您的测试工具方差很大?
尝试重复分层k折交叉验证,并进行多次重复,例如10次或30次。
我如何在我的博士论文中引用这个页面?
如果您喜欢,这会有所帮助
https://machinelearning.org.cn/faq/single-faq/how-do-i-reference-or-cite-a-book-or-blog-post
当我使用 BaggingClassiffier,例如
tree = DecisionTreeClassifier(max_depth = 1, splitter = “random”, max_features = “sqrt”)
extra_trees = BaggingClassifier(base_estimator = tree, n_estimators = 50,
bootstrap = False)
并且当我使用 ExtraTreesClassifier 时有相同的效果,例如
extra_trees2=ExtraTreesClassifier(n_estimators=50, max_features=”sqrt”)
除了明显的简单性之外,使用 ExtraTreesClassifier 而不是 BaggingClassifier 有什么好处?
只有当它能为您的特定预测任务带来更好的性能时,才真正有好处。
非常感谢您的时间和专业知识!我如何在代码中使用我自己的数据集(而不是使用“X, y = make_regression(n_samples=1000, n_features=20, n_informative=15, noise=0.1, random_state=3)”创建样本数据集)?我有一个包含45个预测特征的数据集,这些特征都是数值数据。谢谢!
像往常一样加载CSV,例如
https://machinelearning.org.cn/load-machine-learning-data-python/
非常感谢您,Brownlee博士,我只是不确定是否需要在加载自定义数据集的代码中定义其他方面。祝您周末愉快!😀
不客气。