数据挖掘06--特征变换(二)

目录

5. 特征离散化

无监督离散化

1. pd.cut(等宽分箱)和pd.qcut(等频分箱)

2. 不等距分箱

3. Sklearn中KBinsDiscretizer类分箱

​编辑

 项目案例:

6. 数据规范化

标准化:

区间化

归一化

一、数据标准化 / 归一化的作用

二、标准差标准化 StandardScaler

三、极差标准化 / 归一化 MinMaxScaler

四、稳健标准化 RobustScaler


5. 特征离散化

基础知识 前面提到了“离散型”和“连续型”这两种类型的特征。·

  • 离散型∶在任意两个值之间具有可计数的值。

  • 连续型∶在任意两个值之间具有无限个值。

  • 算法要求:机器学习中的一些算法,比如决策树、朴素贝叶斯、对数概率回归(logistic回归)等算法,都要求变量必须是离散化的。

  • 离散后数据好处:对于连续型特征,在离散化之后,能够降低对离群数据的影响,例如将表示年龄的特征离散化,大于50的是1,否则为0。如果此特征中出现了年龄为500的离群值,在离散化后,该离群值对特征的影响就被消除了。

  • 相对于连续型特征,离散型特征在计算速度、表达能力、模型稳定性等方面都具有优势。

  • 那么,如何实施特征离散化?

  • 通常使用的离散化方法可以划分为“有监督的”和“无监督的”两类。离散化也可以称为“分箱”。

无监督离散化

无监督离散化就是不依据数据集的标签(有的数据集也没有标签),对特征实施离散化操作。

比如,考试结果等级评定规则是∶≥90分为A,80~<90分为B,60~<80分为C,<60分为D。 将学生百分制的卷面成绩依据规则转化为相应的等级,这样就实现了分数的离散化。在这个离散化过程中,没有根据学生的其他某种标签,这样的特征离散化就是无监督离散化。

import pandas as pd
ages = pd.DataFrame({'years':[10, 14, 30, 53, 67, 32, 45], 'name':['A', 'B', 'C', 'D', 'E', 'F', 'G']})
ages

1. pd.cut(等宽分箱)和pd.qcut(等频分箱)

#如果对特征“years”离散化,可以使用Pandas提供的函数cut。
pd.cut(ages['years'],3)

  • cut 函数的第2个参数3,表示将 ages【years】划分为等宽的3个区间。
  • 输出的“{(9.943,29.0]<(29.0,48.0]<(48.0,67.0]]”,表示每个区间的范围,依据每个样本的数值,将该样本标记为在相应的区间中。

因为离散化的别称是“分箱”,上面的操作称为“等宽分箱法”。

用pd.qcut函数实现。

pd.qcut(ages['years'],3)

输出对比:

  • pd.cut(ages['years'],3)
  • Categories (3, interval[float64]): [(9.943, 29.0] < (29.0, 48.0] < (48.0, 67.0]] 29-9.943=19.057 48-29=19 48.0-29=19 67-48=19
  • pd.qcut(ages['years'],3)
  • Categories (3, interval[float64]): [(9.999, 30.0] < (30.0, 45.0] < (45.0, 67.0]] 30-10=20 45-30=15 67-45=32

pd.qcut函数,按照数据出现频率百分比划分,比如要把数据分为四份,则四段分别是数据的0-25%,25%-50%,50%-75%,75%-100%

  • pd.cut() 将指定序列 x,按指定数量等间距的划分(根据值本身而不是这些值的频率选择均匀分布的bins),或按照指定间距划分
  • pd.qcut() 将指定序列 x,划分为 q 个区间,使落在每个区间的记录数一致
#重新指定value的标签
klass = pd.cut(ages['years'], 3, labels=[0, 1, 2])    # ①
ages['label'] = klass
ages

 

2. 不等距分箱

#另外解决方案,指定分割点,避免了离群值的影响。
ages2 = pd.DataFrame({'years':[10, 14, 30, 53, 300, 32, 45], 'name':['A', 'B', 'C', 'D', 'E', 'F', 'G']})
klass2 = pd.cut(ages2['years'], bins=[9, 30, 50, 300], labels=['Young', 'Middle', 'Senior'])    # ③
ages2['label'] = klass2
ages2

3. Sklearn中KBinsDiscretizer类分箱

KBinsDiscretizer实现等宽分箱法的特征离散化,创建离散化模型,其中,

  • n_bins表示所划分的区间个数(整数)或者划分区间的分割点(类数组对象),④的n_bins=3表示将特征数据划分为三部分。
  • encode 表示离散化之后的结果保存方式(编码方式),可以选择三个值(onehot、onehot-dense、ordinal),默认值是onehot。这三个值的含义分别如下。
    • onehot∶离散化之后再进行OneHot编码,并且返回一个稀疏矩阵。
    • onehot-dense∶离散化之后再进行OneHot编码,并且返回数组。
    • ordinal∶离散化之后,以整数数值标记相应的记录。
  • strategy表示离散化所采用的策略。
    • uniform∶每个分区的宽度相同。
    • quantile∶默认值。每个分区的样本数量相同。
    • kmeans∶根据k-means聚类算法设置分区。

⑤则使用所创建的模型对特征“years”的值进行转换,并用⑥合并到原有数据集中,比较特征"label"和"kbd"(忽略浮点数和整数的差异),会发现前面的操作的操作等效。

KBinsDiscretizer类的参数strategy的三个取值,代表了无监督离散化的三个常用方法。

#继续使用成的数据ages,用KBinsDiscretizer实现等宽分箱法的特征离散化
from sklearn.preprocessing import KBinsDiscretizer
kbd = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')   # ④
trans = kbd.fit_transform(ages[['years']])    # ⑤
print(type(trans))
ages['kbd'] = trans[:, 0]    # ⑥
ages

 项目案例:

import numpy as np 
from sklearn.datasets import load_iris
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
iris = load_iris()
#鸢尾花数据集中的各特征是连续值(花瓣、花萼的长度和宽度测量值),
#要求用此数据集训练机器学习的分类算法,并比较在离散化与原始值两种状态下的分类效果。

#鸢尾花数据集有4个特征
iris.feature_names

#简化问题,只选两个特征
X = iris.data
y = iris.target
X = X[:, [2, 3]]
%matplotlib inline
import matplotlib.pyplot as plt
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.3,  cmap=plt.cm.RdYlBu, edgecolor='black')

#离散化后的数据分布
Xd = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='uniform').fit_transform(X)
plt.scatter(Xd[:, 0], Xd[:, 1], c=y, cmap=plt.cm.RdYlBu, edgecolor='black')

 离散化后的数据更泾渭分明,有利于分类算法应用。下面将以上两种数据用于决策树分类算法,比较优劣:

dtc = DecisionTreeClassifier(random_state=0)    # ⑦
score1 = cross_val_score(dtc, X, y, cv=5)    # ⑧
score2 = cross_val_score(dtc, X, y, cv=5)    # ⑨

np.mean(score1), np.std(score1)
(0.9466666666666667, 0.039999999999999994)
np.mean(score2), np.std(score2)
(0.9466666666666667, 0.039999999999999994)

分别计算了X(未离散化)和Xd(已离散化)两个数据集在决策树模型中的评估得分,并分别计算了相应的平均值和标准差。从结果可以看出,在实施特征离散化之后,对优化模型的性能还是有价值的。 继续使用KBinsDiscretizer类对鸢尾花数据离散化,这次使用k-means方法

km = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='kmeans').fit_transform(X)    # ⑩
s = cross_val_score(dtc, km, y, cv=5)
np.mean(s), np.std(s)
#模型的性能得到进一步提高。
(0.9733333333333334, 0.02494438257849294)

6. 数据规范化

标准化:

from sklearn import datasets
from sklearn.preprocessing import StandardScaler 
iris = datasets.load_iris()
#print(iris)
iris_std = StandardScaler().fit_transform(iris.data)    # ①

使用了鸢尾花数据,①用StandardScaler类创建的标准化实例,并将数据标准化

iris['data'][:5]
#显示的是鸢尾花数据集中原有的前5个样本的数值,
>>>
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2]])
iris_std[:5]
#显示的是这5个样本经过标准化变换之后的Z分数。
>>>
array([[-0.90068117,  1.01900435, -1.34022653, -1.3154443 ],
       [-1.14301691, -0.13197948, -1.34022653, -1.3154443 ],
       [-1.38535265,  0.32841405, -1.39706395, -1.3154443 ],
       [-1.50652052,  0.09821729, -1.2833891 , -1.3154443 ],
       [-1.02184904,  1.24920112, -1.34022653, -1.3154443 ]])
#经过标准化变换之后的数据集,各特征的平均值应该为0,标准差是1。
import numpy as np
np.mean(iris_std, axis=0)
>>>
array([-1.69031455e-15, -1.84297022e-15, -1.69864123e-15, -1.40924309e-15])

区间化

所谓区间化,是指特征的值经过变换后被限定在指定的区间。通常,会将特征的值限定在0~1的范围之内,为此要使用特征的最大值和最小值。

于是将某特征的值区间化到0与1之间的变换称为“Min-Max标准化”,公式:

(原始值-最小值) / (最大值 -最小值)

从上面公式不难看出,经过此类区间化的值,也去掉了原有的量纲,并表示了每个数值与最小值的相对距离。

●不适用场景:原始数据存在小部分很大/很小的数据时,会造成大部分数据规范化后接近于0/1,区分度不大

from sklearn.preprocessing import MinMaxScaler
iris_mm = MinMaxScaler().fit_transform(iris.data)    # ②
iris_mm[:5]
#代码实现了对鸢尾花数据集的"Min-Max标准化"操作,显示了前5条样本的结果,这些数值分布在0与1之间,得到的“标准差标准化”的结果进行对比
>>>
array([[0.22222222, 0.625     , 0.06779661, 0.04166667],
       [0.16666667, 0.41666667, 0.06779661, 0.04166667],
       [0.11111111, 0.5       , 0.05084746, 0.04166667],
       [0.08333333, 0.45833333, 0.08474576, 0.04166667],
       [0.19444444, 0.66666667, 0.06779661, 0.04166667]])

np.concatenate 是numpy中对array进行拼接的函数

#对比缩放的效果
import numpy as np
import pandas as pd
X = pd.DataFrame({
    'x1': np.concatenate([np.random.normal(20, 1, 1000), np.random.normal(1, 1, 25)]),
    'x2': np.concatenate([np.random.normal(30, 1, 1000), np.random.normal(50, 1, 25)]),
})
X.sample(10)
#concatencate是对于数组的拼接函数  在numpy库内可以查询

#对X数据集分别用类RobustScaler和MinMaxScaler进行区间化
from sklearn.preprocessing import RobustScaler, MinMaxScaler
robust = RobustScaler()
robust_scaled = robust.fit_transform(X)
robust_scaled = pd.DataFrame(robust_scaled, columns=['x1', 'x2'])

minmax = MinMaxScaler()
minmax_scaled = minmax.fit_transform(X)
minmax_scaled = pd.DataFrame(minmax_scaled, columns=['x1', 'x2'])
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns

fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(9, 5))

ax1.set_title('Before Scaling')
sns.kdeplot(X['x1'], ax=ax1)
sns.kdeplot(X['x2'], ax=ax1)

ax2.set_title('After Robust Scaling')
sns.kdeplot(robust_scaled['x1'], ax=ax2)
sns.kdeplot(robust_scaled['x2'], ax=ax2)

ax3.set_title('After Min-Max Scaling')
sns.kdeplot(minmax_scaled['x1'], ax=ax3)
sns.kdeplot(minmax_scaled['x2'], ax=ax3)

归一化

#L2范数
from sklearn.preprocessing import Normalizer 
norma = Normalizer()    # ③
norma.fit_transform([[3, 4]])
>>>
array([[0.6, 0.8]])


#L1范数
norma1 = Normalizer(norm='l1')
norma1.fit_transform([[3, 4]])
>>>
array([[0.42857143, 0.57142857]])


#依据最大值进行归一
norma_max = Normalizer(norm='max')
norma_max.fit_transform([[3, 4]])
>>>
array([[0.75, 1.  ]])
from mpl_toolkits.mplot3d import Axes3D

df = pd.DataFrame({
    'x1': np.random.randint(-100, 100, 1000).astype(float),
    'y1': np.random.randint(-80, 80, 1000).astype(float),
    'z1': np.random.randint(-150, 150, 1000).astype(float),
})

scaler = Normalizer()
scaled_df = scaler.fit_transform(df)
scaled_df = pd.DataFrame(scaled_df, columns=df.columns)

fig = plt.figure(figsize=(9, 5))
ax1 = fig.add_subplot(121, projection='3d')
ax2 = fig.add_subplot(122, projection='3d')
ax1.scatter(df['x1'], df['y1'], df['z1'])
ax2.scatter(scaled_df['x1'], scaled_df['y1'], scaled_df['z1'])

一、数据标准化 / 归一化的作用


提升模型精度:标准化 / 归一化使不同维度的特征在数值上更具比较性,提高分类器的准确性。
提升收敛速度:对于线性模型,数据归一化使梯度下降过程更加平缓,更易正确的收敛到最优解


二、标准差标准化 StandardScaler


from sklearn.preprocessing import StandardScaler
使用均值与方差,对服从正态分布的数据处理,得到符合标准正态分布的数据

处理方法:标准化数据减去均值,然后除以标准差,经过处理后数据符合标准正态分布,即均值为0,标准差为1;
转化函数:x = (x-mean) / std;
适用性:适用于本身服从正态分布的数据;
Outlier 的影响:基本可用于有outlier的情况,但在计算方差和均值时outliers仍然会影响计算。
参数包括:with_mean, with_std, copy

with_mean:布尔型,默认为 True,表示在缩放前将数据居中,当尝试在稀疏矩阵上时,这不起作用(并且会引发异常),因为将它们居中需要构建一个密集矩阵,在常见的用例中,该矩阵可能太大而无法容纳在内存中;
with_std:布尔型,默认为True,表示将数据换算成单位方差(或等效的单位标准差);
copy : 布尔值,默认为True,可选参数,表示拷贝一份数据以避免在原数据上进行操作,若设置为 False 执行插入行规范化并避免复制。
属性包括:mean_, scale_, var_, n_samples_seen_

mean_:训练集中每个特征的平均值,当_mean=False时,为None;
scale_:每个特征数据的相对缩放;
var_:训练集中每个特征的方差,用于计算比例,当_ std =False时,为None;
n_samples_seen_:每个特征处理的样本数。如没有丢失的样本,n_samples_seen_是一个整数,否则是一个数组,并将被重置或递增。


三、极差标准化 / 归一化 MinMaxScaler


from sklearn.preprocessing import MinMaxScaler
区间缩放,基于最大最小值,将数据转换到0,1区间上的

处理方法:将特征缩放到给定的最小值和最大值之间,也可以将每个特征的最大绝对值转换至单位大小。这种方法是对原始数据的线性变换,将数据归一到[0,1]中间;
转换函数:x = (x-min) / (max-min);
适用性:适用于分布范围较稳定的数据,当新数据的加入导致max/min变化,则需重新定义;
Outlier 的影响:因为outlier会影响最大值或最小值,因此对outlier非常敏感。
参数包括:min, max, copy

min:默认为0,指定区间的下限;
max:默认为1,指定区间的上限;
copy : 布尔值,默认为True,可选参数,表示拷贝一份数据以避免在原数据上进行操作,若设置为 False 执行插入行规范化并避免复制。
属性包括:min_, scale_, data_min_, data_max_

min_:每个功能调整为最小;
scale_:每个特征数据的相对缩放;
data_min_:每个特征在数据中出现的最小值;
data_max_:每个特征在数据中心出现的最大值。


四、稳健标准化 RobustScaler


from sklearn.preprocessing import RobustScaler
使用具有鲁棒性的统计量缩放带有异常值(离群值)的数据

处理方法:该缩放器删除中位数,并根据百分位数范围(默认值为IQR:四分位间距)缩放数据;
IQR:是第1个四分位数(25%)和第3个四分位数(75%)之间的范围;
适用性:适用于包含许多异常值的数据;
Outlier 的影响:RobustScaler 利用IQR进行缩放来弱化 outlier 的影响。
参数包括:with_centering, with_scaling, quantile_range, copy

with_centering:布尔值,默认为 True,表示在缩放之前将数据居中。若使用稀疏矩阵时,这将导致转换引发异常,因为将它们居中需要建立一个密集的矩阵,在通常的使用情况下,该矩阵可能太大而无法容纳在内存中;
with_scaling : 布尔值,默认为True,表示将数据缩放到四分位数范围;
quantile_range : 元组,默认值为(25.0, 75.0)即 IQR,表示用于计算 scale_的分位数范围;
copy : 布尔值,默认为True,可选参数,表示拷贝一份数据以避免在原数据上进行操作,若设置为 False 执行插入行规范化并避免复制。
属性包括:center_, scale_

center_ :训练集中每个属性的中位数;
scale_ :训练集中每个属性的四分位间距。
五、总结
在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,StandardScaler表现更好(避免不同量纲对方差、协方差计算的影响);
在不涉及距离度量、协方差、数据不符合正态分布、异常值较少的时候,可使用MinMaxScaler。(eg:图像处理中,将RGB图像转换为灰度图像后将其值限定在 [0, 255] 的范围);
在带有的离群值较多的数据时,推荐使用RobustScaler。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据挖掘是指从大量数据中发掘出有用的信息和知识的过程,而特征工程则是在数据挖掘中的一个关键步骤。特征工程是指通过对原始数据进行预处理、特征选择、特征变换等方法,提取出适合用于数据挖掘算法建模的特征。 在数据挖掘任务中,特征工程非常重要。一个好的特征工程可以帮助我们更好地发现模型中的规律和关联。而在特征工程中,CSDN(中国最大的IT社区)提供了大量的资源和教程,可以帮助我们理解和应用各种特征工程的方法和技巧。 在CSDN中,我们可以找到关于特征选择、特征提取、特征构造等方面的技术文章和教程。这些文章和教程详细介绍了各种常用的特征工程方法和算法,如主成分分析、线性判别分析、信息增益、互信息等。同时,CSDN还提供了一些常用的特征工程工具,如sklearn、pandas等,方便我们在实际应用中进行特征工程处理。 通过CSDN的学习和实践,我们可以更好地了解特征工程的重要性,学习到各种特征工程的方法和技巧,并能够灵活应用到实际的数据挖掘任务中。在实践中,我们可以根据不同的数据集和任务需求,选择合适的特征工程方法,处理原始数据,提取有用的特征,为后续的模型构建和分析做好准备。 总之,CSDN为我们提供了丰富的特征工程资源和技术支持,通过学习和应用这些资源,我们可以在数据挖掘中更好地进行特征工程,提高模型的准确性和效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值