在机器学习项目中,经常会遇到数值型和分类型数据。由于机器学习算法仅能理解数值,因此在将数据输入算法之前,需要将分类变量转换为数值变量。有时,还需要对数值特征进行编码。尽管数值特征对算法来说是友好的,但在某些情况下,对数值特征进行编码可以更好地洞察数据。例如,在分析Google Play商店的数据时,需要分析各种应用的下载次数。由于并非所有应用对用户都同样有用,只有一些受欢迎的应用才是有用的。因此,这类数据通常是偏斜的,无法直接从这类数据中获得任何好的洞察。这就是需要对数值列进行编码以获得更好数据洞察的原因。本文将讨论“分箱”或“离散化”技术来编码数值变量。
离散化:这是将连续变量转换为分类变量的过程,通过创建一组连续的区间来覆盖变量值的范围。它也被称为“分箱”,其中“箱”是区间的类似名称。
1. 更好地处理异常值。 2. 提高值的分布。 3. 最小化小观察误差的影响。
无监督分箱: (a) 等宽分箱:也称为“均匀分箱”,因为所有区间的宽度相同。算法将数据分成N个区间,每个区间的大小相等。区间的宽度是:w=(max-min)/N。因此,区间边界是:[min+w], [min+2w], [min+3w], ——————————, [min+(N-1)w],其中min和max分别是数据中的最小值和最大值。 (b) 等频分箱:也称为“分位数分箱”。算法将数据分成N组,每组包含大约相同数量的值。假设想要10个箱子,即每个区间包含总观察值的10%。这里区间的宽度不一定相等。 (c) K均值分箱:这种技术使用聚类算法,即“K均值算法”。当数据以聚类形式存在时,通常使用这种技术。
自定义分箱:也称为“领域”基础分箱。在这种技术中,对业务问题陈述有领域知识,并且需要使用知识进行自定义分箱。例如,有一个年龄属性,其值如下:10, 11, 13, 14, 17, 19, 30, 31, 32, 38, 40, 42, 70, 72, 73, 75。分箱后,数据变为:属性年龄-1、年龄-2、年龄-3,10, 11, 13, 14, 17, 19;30, 31, 32, 38, 40, 42;70, 72, 73, 75。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.compose import ColumnTransformer
# 读取和加载数据集
df=pd.read_csv('titanic.csv',usecols=['Age','Fare','Survived'])
print(df.head())
# 删除任何缺失值所在的行
df.dropna(inplace=True)
print(df.shape)
# 分离因变量和自变量
X=df.iloc[:,1:]
y=df.iloc[:,0]
# 将数据集拆分为训练和测试子集
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=109)
print(X_train.head(2))
# 拟合决策树分类器
clf=DecisionTreeClassifier(criterion='gini')
clf.fit(X_train,y_train)
# 在测试数据集上找到模型的准确性
y_pred=clf.predict(X_test)
print(accuracy_score(y_test,y_pred))
# 形成KBinsDiscretizer类的实例
Kbin_age=KBinsDiscretizer(n_bins=15,encode='ordinal',strategy='quantile')
Kbin_fare=KBinsDiscretizer(n_bins=15,encode='ordinal',strategy='quantile')
# 使用列转换器转换列
trf=ColumnTransformer([('first',Kbin_age,[0]),('second',Kbin_fare,[1])])
X_train_trf=trf.fit_transform(X_train)
X_test_trf=trf.transform(X_test)
# 打印“年龄”列的箱数和区间点
print(trf.named_transformers_['first'].n_bins_)
print(trf.named_transformers_['first'].bin_edges_)
# 打印“票价”列的箱数和区间点
print(trf.named_transformers_['second'].n_bins_)
print(trf.named_transformers_['second'].bin_edges_)
# 再次拟合决策树分类器并检查准确性
clf.fit(X_train_trf,y_train)
y_pred2=clf.predict(X_test_trf)
print(accuracy_score(y_test,y_pred2))