数据的变换(一)

数据变换就是通过标准化、离散化与分层化让数据变得更加一致,将数据转换或统一成更适合机器训练或数据分析的形式。数据变换即对数据进行规范化处理,以便于后续的信息挖掘。常见的数据变换包括:特征二值化、特征归一化、连续特征变化,定性特征哑编码等。

 

一、二值化:

特征二值化的核心在于设定一个阈值,将特征与该阈值比较后,转话为0或1(只考虑某个特征出现与否,不考虑出现次数,程度),它的目的是将连续数值细粒度的度量转化为粗粒度的度量。

二值化的函数

from sklearn.preprocessing import Binarizer
data = [[1,2,4],
        [1,2,6],
        [3,2,2],
        [4,3,8]]
binar = Binarizer(threshold=3) #设置阈值为3,<=3标记为0,>3标记为1
print(binar.fit_transform(data))

#注意:fit_transform(X)中的参数X只能是矩阵

[[0 0 1]

 [0 0 1]

 [0 0 0]

 [1 0 1]]

如果需要将数据转变为3值或者更多值,需要自己进行编程,如:

def guifan(data):

    m,n = len(data),len(data[0]) #m,n分别表示行和列

    A = [[0] * n for i in range(m)] #生成(m,n)的空数组

    for i in range(m):

        for j in range(n):

            if data[i][j]>0 and data[i][j]<2:

                A[i][j] = 0

            elif data[i][j]>=2 and data[i][j]<5:

                A[i][j] = 1

            else:

                A[i][j] = 2

    return A

data = [[1,2,4],

        [1,2,6],

        [3,2,2],

        [4,3,8]]

print(guifan(data))

 

二、特征归一化

特征归一化也叫做数据无量纲化,主要包括:总和标准化、标准差标准化、极大值标准化、极差标准化。这里需要说明的是,基于树的方法是不需要进行特征归一化的,例如GBDT,bagging、boosting等等,而基于参数的模型或基于距离的模型,则都需要进行特征归一化。

(一)、总和标准化

总和标准化处理后的数据介于(0,1)之间,并且它们的和为1。总和标准化的步骤和公式也非常简单:分别求出各聚类要素所定义的数据的总和,以各要素的数据除以该要素的数据总和,即:

 

经过总和标准化处理后所得的新数据满足:

 

(二)、标准差标准化

标准差标准化公式如下:

 

其中

 

标准差标准化处理后所得到的新数据,各要素(指标)的平均值0,标准差为1。

 

(三)、极大值标准化

结果极大值标准化的公式如下所示:

 

极大值标准化后的新数据,各要素的最大值为1,其余各项都小于1。

对稀疏数据进行中心化会破坏稀疏数据的结构,这样做没有什么意义,但可以对稀疏数据标准化,极大值标准化就是为稀疏数据设计的,同时这也是一种常用的方法,Python中极大值标准化为MaxAbsScaler(),如果要使用Python中标准差标准化(StandardScaler)则需要设置with_centering = False,否则将破坏数据稀疏性。

 

(四)、极差标准化(区间放缩法,0-1标准化)

极差标准化的计算公式如下:

 

经过极差标准化处理后的新数据,各要素的极大值为1,极小值为0,其余数值均在0与1之间。这里的min{x_ij}和max{x_ij}指的是和x_ij同一列的最小值和最大值。

如果数据中有离群点,对数据进行均值和方差的标准化效果并不好,这时候可以使用robust_scale和RobustScaler作为代替,它们有对数据中心化和数据的缩放鲁棒性更强的参数。

 

示例:

import pandas as pd
import numpy as np
a = [47,83,81,18,72,41]
b = [56,96,84,21,87,67]
data = np.array([a,b]).T
dfab = pd.DataFrame(data,columns = ['A','B'])
print('极差规范化:\n',(dfab-dfab.min())/dfab.max()-dfab.min())
print('零均值规范化:\n',(dfab-dfab.mean())/dfab.std())
print('最大值规范化:\n',dfab/dfab.max())
print('总和规范化:\n',dfab/dfab.sum())

 

极差规范化:

            A          B

0 -17.650602 -20.635417

1 -17.216867 -20.218750

2 -17.240964 -20.343750

3 -18.000000 -21.000000

4 -17.349398 -20.312500

5 -17.722892 -20.520833

零均值规范化:

           A         B

0 -0.386103 -0.456223

1  1.003868  1.003690

2  0.926648  0.565716

3 -1.505803 -1.733646

4  0.579155  0.675209

5 -0.617765 -0.054747

最大值规范化:

           A         B

0  0.566265  0.583333

1  1.000000  1.000000

2  0.975904  0.875000

3  0.216867  0.218750

4  0.867470  0.906250

5  0.493976  0.697917

总和规范化:

           A         B

0  0.137427  0.136253

1  0.242690  0.233577

2  0.236842  0.204380

3  0.052632  0.051095

4  0.210526  0.211679

5  0.119883  0.163017

 

 

三、连续特征变换

 

连续特征变换的常用方法有三种:基于多项式的数据变换、基于指数函数的数据变换、基于对数函数的数据变换。连续特征变换能够增加数据的非线性特征捕获特征之间的关系,有效提高模型的复杂度。

 

生成多项式特征与自定义函数(如:log等)

 

在输入特征中增加非线性特征可以有效提高模型的复杂度,其中最常用的是多项式特征

 

matrix =

 

[[0 1 2]

 

 [3 4 5]

 

 [6 7 8]]

 

当degree = 2时,以第二行为例:

 

[1 3 4 5 3*3 3*4 3*5 4*4 4*5 5*5]

 

当degree = 3时,以第二行为例::

 

[1 3 4 5 3*3 3*4 3*5 4*4 4*5 5*5 3*3*3 3*3*4 3*3*5 4*4*3 4*3*5 5*5*3 4*4*4 4*4*5 4*5*5 5*5*5]

 

"""

 

import numpy as np

 

from sklearn.preprocessing import PolynomialFeatures

 

from sklearn.preprocessing import FunctionTransformer

 

"""生成多项式"""

 

X = np.arange(9).reshape(3,3)

 

print(X)

 

ploy = PolynomialFeatures(2)

 

print(ploy.fit_transform(X))

 

ploy = PolynomialFeatures(3)

 

print(ploy.fit_transform(X))

 

 

 

"""自定义转换器"""

 

X = np.array([[0,1],[2,3]])

 

transformer = FunctionTransformer(np.log1p) #括号内的就是自定义函数

 

print(transformer.fit_transform(X))

 

transformer = FunctionTransformer(np.exp)

 

print(transformer.fit_transform(X))

 

 

 

四、数据离散化

 

数据离散化的方法与数据清理与数据规约的方法有重合之处。毕竟在数据预处理中,很多理念是相通的,数据离散化中较常用的方法有如下几个:

 

(1)通过分箱离散化

 

分箱是一种基于指定的箱个数的自顶向下的分裂技术。例如使用等宽或等频分箱,然后用箱均值或中位数替换箱中的每个值,可以将属性值离散化。分箱对用户指定的箱个数很敏感,也易受离群点的影响。

 

 

(2)通过直方图离散化

 

直方图把属性A的值划分为不相交的区间,称作桶或箱。可以使用各种划分规则定义直方图。如在等宽直方图中,将值分成相等分区或区间。直方图分析算法可以递归地用于每个分区,自动地产生多级概念分层,直到达到一个预先设定的概念层数,过程终止。

 

 

(3)通过聚类、决策树和相关分析离散化

 

 

 

定性特征哑编码:One-hot编码

 

one-hot编码又称为独热码,即一位代表一种状态,及其信息中,对于离散特征,有多少个状态就有多少个位,且只有该状态所在位为1,其他位都为0。

 

举例来说:

 

天气有:{多云、下雨、晴天}三种情况,如果我们将“多云”表达为0,“下雨”表达为1,“晴天”表达为2,这样会有什么问题呢?

 

我们发现不同状态对应的数值是不同的,那么在训练的过程中就会影响模型的训练效果,明明是同一个特征在样本中的权重却会发生了变化。

 

 

 

那么,如何对这三个值进行one-hot编码呢?这时候我们就使用到one-hot编码,

 

即对于:

 

天气:{多云、下雨、晴天}

 

湿度:{偏高、正常、偏低}

 

当输入{天气:多云,湿度:偏低}时进行独热编码,天气状态编码可以得到{100},湿度状态编码可以得到{001},那么二者连起来就是最后的独热编码{100001}。此时{0,2}转换后的长度就是6 = 3+3,即{100001}。

 

sklearn中有封装好的独热编码:OneHotEncoder

 

 

 

from sklearn.preprocessing import OneHotEncoder

 

data = [[1,0,3],[1,1,0],[0,2,1],[1,0,2]]

 

oneHotEn = OneHotEncoder()

 

print(oneHotEn.fit(data))

 

print(oneHotEn.transform([[1,2,2]]).toarray())

 

print(oneHotEn.n_values_) #不同特征对应的值有几种

 

print(oneHotEn.feature_indices_) #不同特征对应的索引号

 

输出:

代码分析:

data是一个矩阵,一列代表一个特征,可知矩阵有3个特征,且第一个特征有2个特征值(0,1),第二个特征有3个特征值(0,1,2),第三个特征有4个特征值(0,1,2,3)。当输入[1,2,2]时,相当于第一个特征,特征值为1的位标记为1,第二个特征,特征值为2的位标记为1,第三个特征,特征值为2的位标记为1。

 

 

 

将离散特征进行one-hot编码后,距离计算就会更加合理。

 

 

 

类别型数据的哑变量处理

 

类别型数据是数据分析中十分常见的特征变量,但是在进行建模时,Python不能像R那样去直接处理非数值型的变量,因此往往需要对这些类别变量进行一系列转换,如哑变量。

 

哑变量(Dummy Variables)用以反映质的属性的一个人工变量,是量化了的自变量,通常取值为0或1。Python中利用pandas库中的get_dummies函数对类别型特征进行哑变量处理。

 

 

 

df = pd.DataFrame([['green','M',10.1,'class1'],

 

                   ['red','L',13.5,'class2'],

 

                   ['blue','XL',14.3,'class1']])

 

df.columns = ['color','size','prize','class label']

 

print(df)

 

pd.get_dummies(df)

 

   color size  prize class label

 

# 0  green    M   10.1      class1

 

# 1    red    L   13.5      class2

 

# 2   blue   XL   14.3      class1

 

 

对于连续变量的离散化,见参考文献

 

 

https://blog.csdn.net/sysstc/article/details/84532396

 

https://blog.csdn.net/YYIverson/article/details/100160544

 

https://blog.csdn.net/shi_jiaye/article/details/119388320

 

posted @   萧六弟  阅读(1042)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示