1、分箱(Binning)
分箱是将连续的数值型特征分成一系列的区间的过程。这种方法有助于减少数值型特征的复杂性,使模型更容易捕捉到特征与目标变量之间的关系。分箱可以是等宽的(每个箱子的范围宽度相同)或等深的(每个箱子包含相同数量的观测值)。在 scikit-learn 中,可以使用 KBinsDiscretizer
类来实现分箱。常用参数如下,
参数 | 描述与默认值 |
---|---|
n_bins | 类型:int 或一系列的 int 。默认值: 5 。指定区间的数量。单一整数时,所有特征使用相同数量的区间; 一系列整数时,为每个特征指定不同数量的区间。 |
encode | 类型:{'onehot', 'onehot-dense', 'ordinal'} 。默认值: 'onehot' 。离散化后的输出编码格式。'onehot' 返回稀疏矩阵,'onehot-dense' 返回密集数组, 'ordinal' 返回序号。 |
strategy | 类型:{'uniform', 'quantile', 'kmeans'} 。默认值: 'quantile' 。定义如何计算区间的策略。'uniform' 每个区间宽度相同,'quantile' 每个区间样本数相同,'kmeans' 基于K-均值聚类确定区间边界。 |
import numpy as np from sklearn.preprocessing import KBinsDiscretizer # 创建数据集 X = np.array([[2], [4], [6], [8], [10], [12], [14], [16], [18], [20]]).astype(float) # 应用 KBinsDiscretizer,尝试不同的 encode 和 strategy 参数 # 使用 quantile 策略和 ordinal 编码 est_quantile_ordinal = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='quantile') Xt_quantile_ordinal = est_quantile_ordinal.fit_transform(X) print("Quantile strategy with ordinal encoding:\n", Xt_quantile_ordinal) # 使用 uniform 策略和 onehot-dense 编码 est_uniform_onehot = KBinsDiscretizer(n_bins=3, encode='onehot-dense', strategy='uniform') Xt_uniform_onehot = est_uniform_onehot.fit_transform(X) print("Uniform strategy with onehot-dense encoding:\n", Xt_uniform_onehot) # 使用 kmeans 策略和 onehot 编码 est_kmeans_onehot = KBinsDiscretizer(n_bins=3, encode='onehot', strategy='kmeans') Xt_kmeans_onehot = est_kmeans_onehot.fit_transform(X) print("KMeans strategy with onehot encoding:\n", Xt_kmeans_onehot.toarray())
2、数值型特征的离散化
特征提取是机器学习预处理过程中的一个重要步骤,尤其是将数值型特征离散化,可以帮助改善模型的性能,特别是对于决策树模型。离散化(也称为分箱或分段)是将连续特征的值范围划分为一系列区间,并将这些区间转换为离散的值。离散化有多种方法,包括等宽分箱、等频分箱、基于聚类的分箱等。在Python中,使用pandas和scikit-learn库可以方便地进行特征的离散化处理。
import pandas as pd from sklearn.preprocessing import KBinsDiscretizer # 创建示例数据 data = pd.DataFrame({ 'feature': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }) # 等宽分箱 # 等宽分箱将特征的值域分成具有相同宽度的区间。可以使用 pandas的cut函数实现 data['feature_eq_width'] = pd.cut(data['feature'], bins=3, labels=False) # 等频分箱 # 等频分箱将特征的值域分成具有相同数据点数量的区间。可以使用pandas的qcut函数实现 data['feature_eq_freq'] = pd.qcut(data['feature'], q=3, labels=False) # 基于聚类的分箱 # 基于聚类的分箱是根据特征值的聚类结果来进行分箱的。 X = data[['feature']].values est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='kmeans') data['feature_kmeans'] = est.fit_transform(X) print(data)
3、标准化 (Standardization)
标准化是将所有特征缩放到相同的尺度,使它们的均值为0,方差为1。这对于许多机器学习算法是非常重要的,尤其是那些基于距离计算的算法。不过,对于决策树来说,由于其模型结构的特点,标准化不是必需的。可以使用sklearn.preprocessing.StandardScaler
来实现标准化,常用参数如下,
参数 | 详细说明 |
copy | 类型: bool, 默认值: True, 如果为 True,则会对数据进行复制, 然后进行标准化处理。如果为 False, 则直接在原数据上进行操作, 这样可以节省内存空间, 但原数据会被改变。 |
with_mean | 类型: bool, 默认值: True, 如果为 True,则会在标准化过程中中心化数据, 即减去均值使数据的均值为0。 对于稀疏矩阵,中心化会改变矩阵的稀疏结构, 因此可能需要将此参数设置为 False。 |
with_std | 类型: bool, 默认值: True, 如果为 True,则会在标准化过程中缩放数据, 即除以数据的标准差使得数据的标准差为1。 这样做可以保证所有特征的尺度一致。 |
使用代码,
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score # 加载数据集 data = load_iris() X = data.data y = data.target # 分割数据集为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 创建 StandardScaler 对象 # 使用 copy=True 以确保原始数据不被修改 # 设置 with_mean=True 和 with_std=True 来启用数据的中心化和缩放 scaler = StandardScaler(copy=True, with_mean=True, with_std=True) X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # 训练决策树分类器 clf = DecisionTreeClassifier(random_state=42) clf.fit(X_train_scaled, y_train) # 预测测试集 y_pred = clf.predict(X_test_scaled) # 评估模型性能 accuracy = accuracy_score(y_test, y_pred) print(f"模型准确率: {accuracy:.2f}")
4、归一化 (Normalization)
归一化是将特征缩放到一个指定的最小和最大值(通常是0到1)之间,以便在相同的尺度上比较不同的特征。与标准化一样,归一化对于决策树模型来说不是必需的,但在某些情况下对于其他模型可能会有帮助。可以使用sklearn.preprocessing.MinMaxScaler
来实现归一化,常用参数如下,
参数名 | 描述 |
feature_range | 类型: 元组 (min, max), 默认值为 (0, 1)。 指定缩放后数据的范围, 默认情况下, 特征会被缩放到 0 和 1 之间。 可以修改此参数以缩放到不同的范围。 |
copy | 类型: 布尔值,True 或 False, 默认为 True。如果为 True, 则会创建原始数据的副本然后进行缩放。 如果为 False, 则直接在原始数据上进行缩放。 |
clip | 类型: 布尔值,True 或 False, 默认为 False。如果为 True,则将 transform 方法应用到数据时, 缩放后的数据会被裁剪到 feature_range 指定的范围内。 |
使用代码,
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import accuracy_score # 加载iris数据集 iris = load_iris() X, y = iris.data, iris.target # 将数据集分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 使用MinMaxScaler进行数据预处理 scaler = MinMaxScaler(feature_range=(0, 1)) X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # 创建决策树模型 clf = DecisionTreeClassifier(random_state=42) # 使用缩放后的训练数据训练模型 clf.fit(X_train_scaled, y_train) # 使用缩放后的测试数据评估模型 y_pred = clf.predict(X_test_scaled) # 打印模型准确率 print("Accuracy:", accuracy_score(y_test, y_pred))