数值输入变量可能具有高度偏斜或非标准分布。
这可能是由数据中的异常值、多峰分布、高度指数分布等引起的。
许多机器学习算法在数值输入变量具有标准概率分布时更喜欢或表现更好。
离散化变换提供了一种自动更改数值输入变量以具有不同数据分布的方法,这反过来又可用作预测模型的输入。
在本教程中,您将了解如何使用离散化变换将数值映射到离散类别,以进行机器学习。
完成本教程后,您将了解:
- 许多机器学习算法在将具有非标准概率分布的数值离散化时更喜欢或表现更好。
- 离散化变换是一种将数值输入或输出变量转换为具有离散顺序标签的技术。
- 如何使用 KBinsDiscretizer 更改数值变量的结构和分布,以提高预测模型的性能。
启动您的项目,阅读我的新书《机器学习数据准备》,其中包含分步教程和所有示例的Python源代码文件。
让我们开始吧。

如何在机器学习中使用离散化变换
照片来自 Kate Russell,部分权利保留。
教程概述
本教程分为六个部分;它们是:
- 更改数据分布
- 离散化变换
- 声纳数据集
- 均匀离散化变换
- K-means 离散化变换
- 分位数离散化变换
更改数据分布
某些机器学习算法可能偏好或需要分类或顺序输入变量,例如某些决策树和基于规则的算法。
一些分类和聚类算法仅处理标称属性,无法处理在数值尺度上测量的属性。
— 第 296 页,《数据挖掘:实际机器学习工具和技术》,第四版,2016 年。
此外,许多机器学习算法的性能会因具有非标准概率分布的变量而下降。
这适用于分类和回归任务中的实值输入变量,以及回归任务中的实值目标变量。
某些输入变量可能具有高度偏斜的分布,例如指数分布,其中最常见的观测值聚集在一起。某些输入变量可能有异常值,导致分布高度分散。
这些和其他问题,例如非标准分布和多模态分布,可能会使数据集难以使用各种机器学习模型进行建模。
因此,通常需要将每个输入变量转换为标准概率分布。
一种方法是使用数值变量的变换来获得离散概率分布,其中每个数值都被分配一个标签,并且标签具有有序(顺序)关系。
这被称为分箱或离散化变换,可以通过使数值输入变量的概率分布离散化来提高某些机器学习模型在数据集上的性能。
想开始学习数据准备吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
离散化变换
离散化变换会将数值变量映射到离散值。
分箱,也称为分类或离散化,是将定量变量转换为一组两个或多个定性桶(即类别)的过程。
— 第 129 页,《特征工程与选择》,2019 年。
变量的值被分组到离散的箱中,每个箱都分配一个唯一的整数,从而保留了箱之间的顺序关系。
箱的使用通常被称为分箱或k-分箱,其中k表示将数值变量映射到的组数。
该映射提供了值的排序,可以平滑观测值之间的关系。该变换可以应用于训练数据集中的每个数值输入变量,然后作为输入提供给机器学习模型来学习预测建模任务。
箱的确定必须包含在重采样过程中。
— 第 132 页,《特征工程与选择》,2019 年。
可以使用不同的方法将值分组为 k 个离散箱;常见技术包括:
- 均匀:每个箱在变量的可能值范围内具有相同的宽度。
- 分位数:每个箱具有相同数量的值,根据百分位数进行划分。
- 聚类:识别聚类并将示例分配给每个组。
离散化变换可在 scikit-learn Python 机器学习库中通过 KBinsDiscretizer 类获得。
“strategy”参数控制输入变量的划分方式,可以是“uniform”、“quantile”或“kmeans”。
“n_bins”参数控制将创建的箱的数量,必须根据策略的选择来设置。例如,“uniform”是灵活的,“quantile”必须有一个“n_bins”小于观测值的数量或合理的百分位数,而“kmeans”必须使用一个可以合理找到的簇数量。
“encode”参数控制变换是将每个值映射到整数值(通过设置“ordinal”或独热编码“onehot”)。顺序编码几乎总是首选,尽管独热编码可能允许模型学习组之间的非顺序关系,例如在k-means 聚类策略的情况下。
我们可以通过一个小型实际示例来演示 KBinsDiscretizer。我们可以生成一个样本 高斯随机数。然后可以使用 KBinsDiscretizer 将浮点值转换为固定数量的离散类别,并具有排序的顺序关系。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 离散化变换演示 from numpy.random import randn from sklearn.preprocessing import KBinsDiscretizer from matplotlib import pyplot # 生成高斯数据样本 data = randn(1000) # 原始数据的直方图 pyplot.hist(data, bins=25) pyplot.show() # 将数据重塑为行和列 data = data.reshape((len(data),1)) # 离散化变换原始数据 kbins = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='uniform') data_trans = kbins.fit_transform(data) # 总结前几行 print(data_trans[:10, :]) # 变换后数据的直方图 pyplot.hist(data_trans, bins=10) pyplot.show() |
运行该示例,首先创建 1,000 个高斯随机浮点值样本,并将数据绘制成直方图。

具有高斯分布的数据直方图
接下来,使用 KBinsDiscretizer 将数值映射到分类值。我们将变换配置为创建 10 个类别(0 到 9),以顺序格式(整数)输出结果,并均匀划分输入数据的范围。
将打印转换后的数据样本,清楚地显示了数据预期的整数格式。
1 2 3 4 5 6 7 8 9 10 |
[[5.] [3.] [2.] [6.] [7.] [5.] [3.] [4.] [4.] [2.]] |
最后,创建直方图,显示 10 个离散类别以及观测值在这些组中的分布情况,遵循与具有高斯形状的原始数据相同的模式。

离散类别转换后的数据直方图
在接下来的部分,我们将仔细研究如何在实际数据集上使用离散化变换。
接下来,我们介绍数据集。
声纳数据集
声纳数据集是用于二元分类的标准机器学习数据集。
它涉及 60 个实值输入和一个二类目标变量。数据集中有 208 个示例,并且类别相当平衡。
使用重复分层的 10 折交叉验证,基线分类算法可以达到大约 53.4% 的分类准确率。最高性能数据集使用重复分层的 10 折交叉验证,大约为 88%。
数据集描述了岩石或模拟地雷的雷达回波。
您可以从这里了解更多关于数据集的信息
无需下载数据集;我们将从我们的示例中自动下载它。
首先,让我们加载并总结数据集。完整的示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 加载并总结声纳数据集 from pandas import read_csv from pandas.plotting import scatter_matrix from matplotlib import pyplot # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) # 总结数据集的形状 print(dataset.shape) # 总结每个变量 print(dataset.describe()) # 变量的直方图 dataset.hist() pyplot.show() |
运行示例首先总结加载数据集的形状。
这证实了 60 个输入变量、一个输出变量和 208 行数据。
提供了输入变量的统计摘要,显示值是数值,大约在 0 到 1 之间。
1 2 3 4 5 6 7 8 9 10 11 12 |
(208, 61) 0 1 2 ... 57 58 59 count 208.000000 208.000000 208.000000 ... 208.000000 208.000000 208.000000 mean 0.029164 0.038437 0.043832 ... 0.007949 0.007941 0.006507 std 0.022991 0.032960 0.038428 ... 0.006470 0.006181 0.005031 min 0.001500 0.000600 0.001500 ... 0.000300 0.000100 0.000600 25% 0.013350 0.016450 0.018950 ... 0.003600 0.003675 0.003100 50% 0.022800 0.030800 0.034300 ... 0.005800 0.006400 0.005300 75% 0.035550 0.047950 0.057950 ... 0.010350 0.010325 0.008525 max 0.137100 0.233900 0.305900 ... 0.044000 0.036400 0.043900 [8 rows x 60 columns] |
最后,为每个输入变量创建了一个直方图。
如果我们忽略图表的杂乱,只关注直方图本身,我们可以看到许多变量具有偏斜分布。

声纳二元分类数据集输入变量的直方图图
接下来,让我们在原始数据集上拟合和评估一个机器学习模型。
我们将使用 k-近邻算法,并使用默认超参数,通过 重复分层 k 折交叉验证进行评估。
完整的示例如下所示。
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 |
# 在原始声纳数据集上评估 knn from numpy import mean from numpy import std from pandas import read_csv from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import LabelEncoder from matplotlib import pyplot # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) data = dataset.values # 分割为输入和输出列 X, y = data[:, :-1], data[:, -1] # 确保输入是浮点数,输出是整数标签 X = X.astype('float32') y = LabelEncoder().fit_transform(y.astype('str')) # 定义和配置模型 model = KNeighborsClassifier() # 评估模型 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))) |
运行示例评估 KNN 模型在原始声纳数据集上的性能。
注意:您的结果可能因算法或评估程序的随机性,或数值精度差异而有所不同。请尝试运行示例几次并比较平均结果。
我们可以看到,该模型实现了大约 79.7% 的平均分类准确率,这表明它具有技能(优于 53.4%),并且接近良好性能(88%)。
1 |
准确率:0.797 (0.073) |
接下来,让我们探索对数据集进行均匀离散化变换。
均匀离散化变换
均匀离散化变换将保留每个输入变量的概率分布,但会将其离散化为指定的顺序组或标签数量。
我们可以使用 KBinsDiscretizer 类并设置“strategy”参数为“uniform”来应用均匀离散化变换。我们还必须设置“n_bins”参数指定的所需 bin 数量;在本例中,我们将使用 10。
定义后,我们可以调用 fit_transform() 函数并将我们的数据集传递给它,以创建数据集的分位数变换版本。
1 2 3 4 |
... # 对数据集执行均匀离散化变换 trans = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='uniform') data = trans.fit_transform(data) |
让我们在声纳数据集上尝试一下。
创建声纳数据集的均匀离散化变换并绘制结果直方图的完整示例如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 可视化声纳数据集的均匀顺序离散化变换 from pandas import read_csv from pandas import DataFrame from pandas.plotting import scatter_matrix from sklearn.preprocessing import KBinsDiscretizer from matplotlib import pyplot # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) # 仅检索数字输入值 data = dataset.values[:, :-1] # 对数据集执行均匀离散化变换 trans = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='uniform') data = trans.fit_transform(data) # 将数组转换回数据框 dataset = DataFrame(data) # 变量的直方图 dataset.hist() pyplot.show() |
运行该示例会转换数据集并绘制每个输入变量的直方图。
我们可以看到,直方图的形状通常与原始数据集的形状匹配,尽管在这种情况下,每个变量都有固定的 10 个值或顺序组。

声纳数据集均匀离散化变换输入变量的直方图
接下来,让我们评估与上一节相同的 KNN 模型,但在此情况下,是在数据集的均匀离散化变换上。
完整的示例如下所示。
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 |
# 使用均匀顺序离散化变换评估声纳数据集上的 KNN from numpy import mean from numpy import std from pandas import read_csv from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import KBinsDiscretizer from sklearn.pipeline import Pipeline from matplotlib import pyplot # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) data = dataset.values # 分割为输入和输出列 X, y = data[:, :-1], data[:, -1] # 确保输入是浮点数,输出是整数标签 X = X.astype('float32') y = LabelEncoder().fit_transform(y.astype('str')) # 定义管道 trans = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='uniform') model = KNeighborsClassifier() pipeline = Pipeline(steps=[('t', trans), ('m', model)]) # 评估管道 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) n_scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise') # 报告管道性能 print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
注意:您的结果可能因算法或评估程序的随机性,或数值精度差异而有所不同。请尝试运行示例几次并比较平均结果。
运行示例,我们可以看到均匀离散化变换将性能从没有变换时的 79.7% 准确率提升到变换后的约 82.7%。
1 |
准确率:0.827 (0.082) |
接下来,让我们仔细看看 k-means 离散化变换。
K-means 离散化变换
K-means 离散化变换将尝试为每个输入变量拟合 k 个簇,然后将每个观测值分配给一个簇。
除非变量的经验分布复杂,否则簇的数量可能很小,例如 3-5 个。
我们可以使用 KBinsDiscretizer 类并设置“strategy”参数为“kmeans”来应用 K-means 离散化变换。我们还必须设置“n_bins”参数指定的所需 bin 数量;在本例中,我们将使用三个。
定义后,我们可以调用 fit_transform() 函数并将其传递给我们的数据集,以创建我们数据集的量化转换版本。
1 2 3 4 |
... # 对数据集执行 k-means 离散化变换 trans = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='kmeans') data = trans.fit_transform(data) |
让我们在声纳数据集上尝试一下。
创建声纳数据集的 K-means 离散化变换并绘制结果直方图的完整示例如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 可视化声纳数据集的 k-means 顺序离散化变换 from pandas import read_csv from pandas import DataFrame from pandas.plotting import scatter_matrix from sklearn.preprocessing import KBinsDiscretizer from matplotlib import pyplot # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) # 仅检索数字输入值 data = dataset.values[:, :-1] # 对数据集执行 k-means 离散化变换 trans = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='kmeans') data = trans.fit_transform(data) # 将数组转换回数据框 dataset = DataFrame(data) # 变量的直方图 dataset.hist() pyplot.show() |
运行该示例会转换数据集并绘制每个输入变量的直方图。
我们可以看到,每个输入变量的观测值被组织到三个组之一中,其中一些组的观测值似乎相当均匀,而另一些则不那么均匀。

声纳数据集 k-means 离散化变换输入变量的直方图
接下来,让我们评估与上一节相同的 KNN 模型,但在此情况下,是在数据集的 K-means 离散化变换上。
完整的示例如下所示。
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 |
# 使用 k-means 顺序离散化变换评估声纳数据集上的 KNN from numpy import mean from numpy import std from pandas import read_csv from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import KBinsDiscretizer from sklearn.pipeline import Pipeline from matplotlib import pyplot # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) data = dataset.values # 分割为输入和输出列 X, y = data[:, :-1], data[:, -1] # 确保输入是浮点数,输出是整数标签 X = X.astype('float32') y = LabelEncoder().fit_transform(y.astype('str')) # 定义管道 trans = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='kmeans') model = KNeighborsClassifier() pipeline = Pipeline(steps=[('t', trans), ('m', model)]) # 评估管道 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) n_scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise') # 报告管道性能 print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
注意:您的结果可能因算法或评估程序的随机性,或数值精度差异而有所不同。请尝试运行示例几次并比较平均结果。
运行示例,我们可以看到 K-means 离散化变换将性能从没有变换时的 79.7% 准确率提升到变换后的约 81.4%,尽管略低于上一节中的均匀分布。
1 |
准确率:0.814 (0.088) |
接下来,让我们仔细看看分位数离散化变换。
分位数离散化变换
分位数离散化变换将尝试将每个输入变量的观测值分割为 k 个组,其中分配给每个组的观测值数量大致相等。
除非有大量观测值或复杂的经验分布,否则 bin 的数量必须保持较小,例如 5-10。
我们可以使用 KBinsDiscretizer 类并设置“strategy”参数为“quantile”来应用分位数离散化变换。我们还必须设置“n_bins”参数指定的所需 bin 数量;在本例中,我们将使用 10。
1 2 3 4 |
... # 对数据集执行分位数离散化变换 trans = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='quantile') data = trans.fit_transform(data) |
以下示例应用分位数离散化变换并为每个变换后的变量创建直方图。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 可视化声纳数据集的分位数顺序离散化变换 from pandas import read_csv from pandas import DataFrame from pandas.plotting import scatter_matrix from sklearn.preprocessing import KBinsDiscretizer from matplotlib import pyplot # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) # 仅检索数字输入值 data = dataset.values[:, :-1] # 对数据集执行分位数离散化变换 trans = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='quantile') data = trans.fit_transform(data) # 将数组转换回数据框 dataset = DataFrame(data) # 变量的直方图 dataset.hist() pyplot.show() |
运行该示例会转换数据集并绘制每个输入变量的直方图。
我们可以看到,所有直方图都显示了每个输入变量的均匀概率分布,其中 10 个组中的每个组都具有相同数量的观测值。

声纳数据集分位数离散化变换输入变量的直方图
接下来,让我们评估与上一节相同的 KNN 模型,但在此情况下,是在原始数据集的分位数离散化变换上。
完整的示例如下所示。
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 |
# 使用分位数顺序离散化变换评估声纳数据集上的 KNN from numpy import mean from numpy import std from pandas import read_csv from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import KBinsDiscretizer from sklearn.pipeline import Pipeline from matplotlib import pyplot # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) data = dataset.values # 分割为输入和输出列 X, y = data[:, :-1], data[:, -1] # 确保输入是浮点数,输出是整数标签 X = X.astype('float32') y = LabelEncoder().fit_transform(y.astype('str')) # 定义管道 trans = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='quantile') model = KNeighborsClassifier() pipeline = Pipeline(steps=[('t', trans), ('m', model)]) # 评估管道 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) n_scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise') # 报告管道性能 print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
注意:您的结果可能因算法或评估程序的随机性,或数值精度差异而有所不同。请尝试运行示例几次并比较平均结果。
运行示例,我们可以看到均匀变换将性能从没有变换时的 79.7% 准确率提升到变换后的约 84.0%,优于上一节中的均匀和 K-means 方法。
1 |
准确率:0.840 (0.072) |
我们将 bin 数量选择为一个任意数字,本例中为 10。
可以调整此超参数以探索变换分辨率对模型结果技能的影响。
以下示例执行了此实验,并绘制了从 2 到 10 的不同“n_bins”值的平均准确率。
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 49 50 51 52 53 54 55 |
# 探索离散 bin 数量对分类准确率的影响 from numpy import mean from numpy import std from pandas import read_csv from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import KBinsDiscretizer from sklearn.preprocessing import LabelEncoder from sklearn.pipeline import Pipeline from matplotlib import pyplot # 获取数据集 定义 获取_数据集(): # 加载数据集 url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/sonar.csv" dataset = read_csv(url, header=None) data = dataset.values # 分离输入和输出列 X, y = data[:, :-1], data[:, -1] # 确保输入为浮点数,输出为整数标签 X = X.astype('float32') y = LabelEncoder().fit_transform(y.astype('str')) 返回 X, y # 获取要评估的模型列表 定义 获取_模型(): models = dict() for i in range(2,11): # 定义管道 trans = KBinsDiscretizer(n_bins=i, encode='ordinal', strategy='quantile') model = KNeighborsClassifier() models[str(i)] = Pipeline(steps=[('t', trans), ('m', model)]) 返回 模型 # 使用交叉验证评估给定模型 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, error_score='raise') 返回 分数 # 获取数据集 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() |
运行示例会报告每个“n_bins”参数值的平均分类准确率。
注意:您的结果可能因算法或评估程序的随机性,或数值精度差异而有所不同。请尝试运行示例几次并比较平均结果。
我们可以看到,令人惊讶的是,较小的值导致了更高的准确率,例如三个值达到了约 86.7% 的准确率。
1 2 3 4 5 6 7 8 9 |
>2 0.806 (0.080) >3 0.867 (0.070) >4 0.835 (0.083) >5 0.838 (0.070) >6 0.836 (0.071) >7 0.854 (0.071) >8 0.837 (0.077) >9 0.841 (0.069) >10 0.840 (0.072) |
创建箱线图是为了总结数据集中每个离散分箱的数量的分类准确度分数。
我们可以看到在三个分箱时准确度有一个小幅提升,而分箱数量增加时,分数下降并保持平坦。
结果突出表明,探索所选方法中不同数量的离散分箱,以查看是否能获得更好的性能,很可能会带来一些好处。

离散分箱数量与 KNN 在 Sonar 数据集上的分类准确度箱线图
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
教程
书籍
- 数据挖掘:实用机器学习工具与技术,第四版,2016。
- 特征工程与选择, 2019.
数据集 (Dataset)
API
文章
总结
在本教程中,您将了解如何使用离散化转换将数值映射到离散类别,以用于机器学习。
具体来说,你学到了:
- 许多机器学习算法在将具有非标准概率分布的数值离散化时更喜欢或表现更好。
- 离散化变换是一种将数值输入或输出变量转换为具有离散顺序标签的技术。
- 如何使用 KBinsDiscretizer 更改数值变量的结构和分布,以提高预测模型的性能。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
嗨,Jason,
感谢您的本教程。
我想使用分位数离散化变换,并为随机森林模型调整分箱数量。
您能提供一个在 R 中使用随机森林模型的示例吗?
您对此有什么建议吗?
在此先感谢,
Juan
抱歉,我没有这方面的 R 语言示例。
嗨,Jason,
感谢这篇非常棒的文章。运行代码并看到进展总是一种乐趣。我通过这篇文章理解了在运行任何机器学习算法之前进行离散化的必要性。
我将上面的图与使用“StandarScaler”进行数据预处理的 Sonar 数据集的神经网络实现进行了比较,我达到了 87% 和 88% 的准确率,或者使用 Dropout (87,95%)。(在您的书籍《Python 深度学习》中)
我的理解是,当运行 {k-近邻算法和重复分层 k-折分层 + 离散化} 或 {神经网络模型 + StandarScaler + Dropout} 的组合时,我们处于相似的准确率范围内。
那么我的问题是:您对这两种机器学习算法有什么推荐吗?(在基于实例的 kNN 和神经网络 MLP 之间)
谢谢,
诚挚的问候
Dominique
谢谢。
没有,始终测试一系列算法和数据预处理方法、整个建模流程,以发现最适合您数据集的方法。
你好 Jason,
非常感谢您分享您的知识。我读到了一种可以帮助我们离散化目标变量的算法。我真的很想听听您对此的看法。
https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5148156/
不客气。
抱歉,我不熟悉这项工作。
你好 Jason,
谢谢。我有一个问题,在进行分位数离散化变换时,是否应该对整个数据集进行?
还是应该先分割训练集和测试集,然后只在训练集上进行?
该变换必须在训练集上拟合,然后应用于训练集和测试集。
当使用交叉验证时,您可以通过管道自动完成此操作。
非常感谢您提供信息。离散化变换解释得非常好。我真的很感谢您分享了所有内容并附带了示例。
不客气。
这是一个非常有启发性的教程!我还想知道是否有任何方法可以量化在进行离散化变换时丢失的信息。
谢谢!
好问题,我没亲自做过。也许可以查阅文献,寻找衡量信息变化的常用方法,或者可以从类似散度度量的方法开始。
https://machinelearning.org.cn/divergence-between-probability-distributions/
这非常有意思,Jason。感谢分享。
进行离散化后,我们如何查看不同的分箱?阈值呢?
谢谢。
好问题!请查看您的 KBinsDiscretizer 实例上的“n_bins_”和“bin_edges_”属性。
更多细节在此
https://scikit-learn.cn/stable/modules/generated/sklearn.preprocessing.KBinsDiscretizer.html
嗨,Jason,
非常感谢您分享无监督离散化方法!包括管道在内的代码示例非常有帮助。使用管道可以避免数据泄露。
这里我有一个问题。您如何看待有监督离散化方法,例如 DecisionTreeDiscretiser?
我正在处理 Kaggle 的泰坦尼克号比赛,并计划对年龄和费用变量进行离散化。
尝试一下,看看它是否能提高您项目的性能。
为什么对所有列应用相同的策略?当数据包含数值、类别和有序列时,如何处理?
仅作为演示。
嗨,Jason,
我有一个简单的问题,
我们如何确定分箱的数量?
也就是说,是否有任何数值方法来选择要使用的“k 个离散分箱”的数量?
没有,对一系列值进行网格搜索,并使用适合您数据集和所选模型的值或最佳配置。
谢谢你
不客气。
嗨 Jason
假设我们有“年龄”和“收入”作为特征,我们想对它们进行分组,例如
年龄 1-12:年龄组 A
年龄 13-30:年龄组 B
年龄 31-40:年龄组 C,等等
收入 1-100:收入组 A
收入 101-150:收入组 B
收入 151-250:收入组 C,等等
每个组可能有不同的范围,是否有办法“搜索”每个组的年龄和收入范围,以便在使用 Y 目标(可能是情感分析)时,每个组的年龄和收入范围对 Y 目标都是最优的?
谢谢
Mike
可能您想做一些启发式搜索来找到最优解。例如,模拟退火。
你好,感谢您的教程。我有一个问题,由于 KNN 使用欧氏距离技术,我们如何在该算法中使用有序变量?
Mehdi 你好… 感谢你的反馈!请详细说明你对 KNN 和有序变量的目标,以便我们能更好地帮助你。