数据预处理

数据预处理

数据分析大致步骤:(偏业务)

  1. 需求分析 demand analysis
  2. 维度分析 dimensional analysis
  3. 数据收集 data collection
  4. 数据预处理 data pre-processing
    1. 数据清洗 data cleaning
      1. 重复值 duplicate values
      2. 缺失值 missing values
      3. 异常值 outliers
    2. 特征工程 feature engineering
      1. 数据标准化 data normalization
      2. 类别特征数值化 Category feature numeralization
  5. 数据分析 data analysis
    1. 统计学分析 Presentation data analysis
    2. 探索性分析 Exploratory Data Analysis
  6. 出报告

在这里插入图片描述

1. 数据清洗

1.1 检测与处理重复值

a) 检查重复值

duplicated(subset=None, keep=‘first’)

参数名说明
subset接收string或sequence。表示进行去重的列。默认为None,表示全部列
keep接收特定string。表示重复时保留第几个数据。
first:不显示第一个。last:不显示最后一个。false:所有重复的行都显示。默认为first。
# 创建演示用DF
df = pd.DataFrame({'name':['苹果','梨','草莓','梨','苹果','梨'], 
                   'price':[7,8,9,8,8,8], 
                   'cnt':[3,4,5,4,4,4]})
            """
            	name	price	cnt
            0	苹果	7		3
            1	梨		8		4
            2	草莓	9		5
            3	梨		8		4
            4	苹果	8		4
            5	梨		8		4
            """
# 默认形式显示重复的行, 如果全部字段数据相同则判断为重复, 不显示重复数据的第一行 
df.duplicated()
            """
            0    False
            1    False
            2    False
            3     True
            4    False
            5     True
            """
# 判断name字段的重复值, 显示所有的重复行
df.duplicated(subset='name', keep=False)
b) 删除重复值

pandas提供了一个名为drop_duplicates()的去重方法。
该方法只对DataFrame或者Series类型有效。这种方法不会改变数据原始排列,并且兼具代码简洁和运行稳定的特点。
该方法不仅支持单一特征的数据去重,还能够依据DataFrame的其中一个或者几个特征进行去重操作。

参数名说明
subset接收string或sequence。表示进行去重的列。默认为None,表示全部列。
keep接收特定string。表示重复时保留第几个数据。
first:保留第一个。last:保留最后一个。false:只要有重复都不保留。默认为first。
inplace接收boolean。表示是否在原表上进行操作。默认为False。

示例:

import pandas as pd

# 创建演示用DF
data=pd.DataFrame({'A':[1,1,2,2,2],'B':['a','b','a','b','b'],'C':['s1','s2','s3','s4','s4']})
print(data)
                """
                    A	B	C
                0	1	a	s1
                1	1	b	s2
                2	2	a	s3
                3	2	b	s4
                4	2	b	s4
                """

# 删除3列都重复的值
da = data.drop_duplicates(subset=None, keep='first')
print(da)
                """
                    A	B	C
                0	1	a	s1
                1	1	b	s2
                2	2	a	s3
                3	2	b	s4		# 只删除了第五行
                """
# 删除A列重复的值
da = data.drop_duplicates(subset='A', keep='first')
print(da)
                """
                	A	B	C
                0	1	a	s1
                2	2	a	s3		# 删除第二,三,四行
                """

1.2 检测与处理缺失值

数据中的某个或某些特征的值是不完整的,这些值称为缺失值。
pandas提供了识别缺失值的方法isnull以及识别非缺失值的方法notnull,这两种方法在使用时返回的都是布尔值True和False。
结合sum函数和isnull、notnull函数,可以检测数据中缺失值的分布以及数据中一共含有多少缺失值。
isnull和notnull之间结果正好相反,因此使用其中任意一个都可以判断出数据中缺失值的位置。

# 用掩码可以查看哪些行有缺失值
df[df.isnull().values==True]
a) 删除法

删除法分为删除观测记录(删除行) 和 删除特征(删除列) 两种
pandas中提供了简便的删除缺失值的方法dropna(),该方法既可以删除观测记录,亦可以删除特征。

参数名说明
axis接收0或1。表示轴向,0为删除记录(行),1为删除特征(列)。默认为0。
how接收特定string。表示删除的形式。any表示只要有缺失值存在就执行删除操作。all表示当且仅当全部为缺失值时执行删除操作。默认为any。
subset接收类array数据。表示进行去重的列∕行。默认为None,表示所有列/行。
inplace接收boolean。表示是否在原表上进行操作。默认为False。

示例:

# 创建演示用数据
data=pd.DataFrame({'A':[1,1,np.NaN,2,np.NaN],
                   'B':['a','b','a','b',np.NaN],
                   'C':['s1','s2','s3','s4','s4']})
print(data)
                """
                	A		B		C
                0	1.0		a		s1
                1	1.0		b		s2
                2	NaN		a		s3
                3	2.0		b		s4
                4	NaN		NaN		s4
                """
# 通过isnull()方法或notnull()方法可用得到一个布尔值的DF
data.isnull()
data,notnull()
                """ isnull()方法输出:				notnull()方法输出:
                    A		B		C					A		B		C
                0	False	False	False			0	True	True	True
                1	False	False	False			1	True	True	True
                2	True	False	False			2	False	True	True
                3	False	False	False			3	True	True	True
                4	True	True	False			4	False	False	True
                """
    
# 观察isnull().sum()以及isnull().sum(axis=1)的输出数据
data.isnull().sum()
data.isnull().sum(axis=1)
                """isnull().sum()输出:				isnull().sum(axis=1)输出:
                A    2									0    0
                B    1									1    0
                C    0									2    1
                dtype: int64							3    0
														4    2
														dtype: int64
                """
# 用dropna()删除NaN的数据, 删除有NaN的行
data.dropna()		"""
                    	A		B		C
                    0	1.0		a		s1
                    1	1.0		b		s2
                    3	2.0		b		s4
                    """

# 用dropna(axis=1)删除NaN的数据, 删除有NaN的列
data.dropna(axis=1)			"""
                            C
                            0	s1
                            1	s2
                            2	s3
                            3	s4
                            4	s4
                            """
b) 替换法

替换法是指用一个特定的值替换缺失值。
特征可分为离散型和连续型,两者出现缺失值时的处理方法也是不同的。

  • 缺失值所在特征为连续型时,通常利用其均值、中位数和众数等描述其集中趋势的统计量来代替缺失值。
  • 缺失值所在特征为离散型时,则经常选择使用众数来替换缺失值。
方法方法描述
均值/中位数/众数插补根据属性值的类型用该属性取值的平均数/中位数/众数进行插补
使用固定值将缺失的属性值用一个常量替换。
最近插补在记录中找到与缺失样本最接近的样本的该属性值插补
回归方法对带有缺失值的变量,根据已有数据和与其有关的其他变量(因变量)的数据建立拟合模型来预测缺失的属性值

pandas库中提供了缺失值替换的方法名为fillna()

参数名说明
value接收scalar,dict,Series或者DataFrame。表示用来替换缺失的值。无默认。
method接收特定string。默认为None。
backfill 或 bfill 表示使用下一个非缺失值填补缺失值。
pad 或 ffill 表示使用上一个非缺失值填补缺失值。
axis接收0或1。表示轴向。默认为1。
inplace接收boolean。表示是否在原表上进行操作。默认为False。
limit接收int。表示填补缺失值个数上限,超过则不进行填补。默认为None。

示例:

# 创建df用于演示
dates = pd.date_range('20130101', periods=6)		# 创建6个从2013-01-01开始的连续日期
df = pd.DataFrame(np.arange(24).reshape((6,4)),		# 创建从0开始的24个连续数值,换维为6行4列的多维数组
                  index=dates, 						# 以dates作为index
                  columns=['A','B','C','D'])		# 命名列名

# 将指点单元格数据替换为NaN
df.iloc[0,1] = np.nan
df.iloc[1,2] = np.nan
print(df)
                """
                    		A		B		C		D
                2013-01-01	0		NaN		2.0		3
                2013-01-02	4		5.0		NaN		7
                2013-01-03	8		9.0		10.0	11
                2013-01-04	12		13.0	14.0	15
                2013-01-05	16		17.0	18.0	19
                2013-01-06	20		21.0	22.0	23
                """

# 以每列的平均数为值,向缺失的数据填充
for i in df.columns:								# 循环遍历得到每列的列名
    df[i].fillna(value=df[i].mean(), inplace=True)	# 得到每列的平均值,并填入空值
print(df0)
                """
                			A     	B     	C   	D
                2013-01-01   0  	13.0   	2.0   	3
                2013-01-02   4   	5.0  	13.2   	7
                2013-01-03   8   	9.0  	10.0  	11
                2013-01-04  12  	13.0  	14.0  	15
                2013-01-05  16  	17.0  	18.0  	19
                2013-01-06  20  	21.0  	22.0  	23
                """

# 由缺失值的右边数值向缺失值填充
df1 = df.fillna(method='bfill', axis=1)
print(df1)
                """
                			A		B		C		D
                2013-01-01	0.0		2.0		2.0		3
                2013-01-02	4.0		5.0		7.0		7
                2013-01-03	8.0		9.0		10.0	11
                2013-01-04	12.0	13.0	14.0	15
                2013-01-05	16.0	17.0	18.0	19
                2013-01-06	20.0	21.0	22.0	23
                """
c) 插值法

删除法简单易行,但是会引起数据结构变动,样本减少;替换法使用难度较低,但是会影响数据的标准差,导致信息量变动。在面对数据缺失问题时,除了这两种方法之外,还有一种常用的方法—插值法。

scipy提供了插值算法可以通过一组散点得到一个符合一定规律插值器函数。这样当我们给插值器函数更多未知x,插值函数将会返回相应的y用于填补缺失值。

import scipy.interpolate as si
func = si.interp1d(离散x坐标, 
                   离散y坐标,
                   kind=插值算法(默认为线性插值))

示例:

import scipy.interpolate as si
import pandas as pd

data = {'A': np.arange(10), 'B': np.arange(100,110)}
df = pd.DataFrame(data)
df.iloc[4,1]=np.nan
print(df)
                """
                    A	B
                0	1	100.0
                1	2	101.0
                2	3	102.0
                3	4	103.0
                4	5	NaN				# 可以明显的看出来, 两列数据是线性关系, 缺失值应该是104
                5	6	105.0
                6	7	106.0
                7	8	107.0
                8	9	108.0
                9	10	109.0
                """
    
df1 = df.dropna()							# 在使用si.interp1d()函数进行线性回归时, 必须是无缺失值的
func = si.interp1d(x=df1['A'],y=df1['B'])	# 用si.interp1d()函数得到的是一个函数
func(5)										# 输入x的值, 得到y的值为104, 符合预期

1.3 检测与处理异常值

  1. 简单统计量分析

    • 先对变量做一个描述性统计,找出哪些数据是不合理的,最常用的统计量是求最大值和最小值,判断变量是否在这个区间。
  2. 3σ原则

    • 3σ原则又称为拉依达法则。该法则就是先假设一组检测数据只含有随机误差,对原始数据进行计算处理得到标准差,然后按一定的概率确定一个区间,认为误差超过这个区间的就属于异常值。
    • 这种判别处理方法仅适用于对正态或近似正态分布的样本数据进行处理。
    • 如果不符合正态分布,可以用远离平均值的多少倍标准差来表示。
  3. 箱线图分析

    • 箱线图提供了识别异常值的一个标准,即异常值通常被定义为小于QL-1.5IQR或大于QU+1.5IQR的值。
    • QL称为下四分位数,表示全部观察值中有四分之一的数据取值比它小。
    • QU称为上四分位数,表示全部观察值中有四分之一的数据取值比它大。
    • IQR称为四分位数间距,是上四分位数QU与下四分位数QL之差,其间包含了全部观察值的一半。

异常值的处理方法

异常值处理方法方法描述
删除含有异常值的记录直接删除含有异常值的记录
视为缺失值将异常值视为缺失值,按照缺失值方法处理。
平均值修正用前后两个观测值的均值进行修正。
不处理直接在含有异常值的数据集上进行数据建模。

2. 数据的特征工程

# 数据预处理相关库
import sklearn.preprocessing as sp

2.1 数据标准化

data normalization

​ 为了消除数据特征之间的量纲影响,我们需要对特征进行归一化处理,使得不同指标之间具有可比性。例如,分析一个人的身高和体重对健康的影响,如果使用米(m)和千克(kg)作为单位,那么身高特征会在1.6~1.8m的数值范围内,体重特征会在50~100kg的范围内,分析出来的结果显然会倾向于数值差别比较大的体重特征。想要得到更为准确的结果,就需要进行特征归一化(Normalization)处理,使各指标处于同一数值量级,以便进行分析

a) 均值移除

由于一个样本的不同特征值差异较大,不利于使用现有机器学习算法进行样本处理。
均值移除可以让样本矩阵中的每一列的平均值为0,标准差为1。

用scale()方法对数据进行标准化

import sklearn.preprocessing as sp

# scale函数用于对函数进行预处理,实现均值移除, array为原数组,返回A为均值移除后的结果。
A = sp. (array)

示例:

# 创建一个有5个数的series数组
data = pd.Series(np.arange(5))

# 对数组进行均值移除
A = sp.scale(data)
print(A)	# 输出: array([-1.41421356, -0.70710678,  0.0,  0.70710678,  1.41421356])
b) 范围缩放

线性函数归一化

将样本矩阵中的每一列的最小值和最大值设定为相同的区间,统一各列特征值的范围。一般情况下会把特征值缩放至[0, 1]区间

用 MinMaxScaler() 和 fit_transform() 函数 (必须使用二维的数据类型)

# 创建MinMax缩放器
mms = sp.MinMaxScaler(feature_range=(0, 1))

# 调用mms对象的fit_transform或transform方法执行缩放操作, 返回缩放过后的结果
result = mms.fit_transform(原始样本矩阵)

# 调用mms对象的inverse_transform方法可以将缩放后的数据返还回原本的数据
data = mms.inverse_transform(缩放后的数据)

示例:

# 创建DF数据
raw_samples = pd.DataFrame([[17., 100., 4000],
                            [20., 80., 5000],
                            [23., 75., 5500]])
print(raw_samples)
                        """
                            0      1     2
                        0  17.0  100.0  4000
                        1  20.0   80.0  5000
                        2  23.0   75.0  5500
                        """
# 对DF的所有数据进行范围缩放
mms = sp.MinMaxScaler(feature_range=(0, 1))		# 创建缩放对象, 指明最大最小值
mms_samples = mms.fit_transform(raw_samples)	# 对数据进行缩放, 必须是DF型数据
print(pd.DataFrame(mms_samples))
                        """
                             0    1         2		# 是按照列为单位进行范围缩放的
                        0  0.0  1.0  0.000000
                        1  0.5  0.2  0.666667
                        2  1.0  0.0  1.000000
                        """
import sklearn.preprocessing as sp
import pandas as pd

raw_samples = pd.DataFrame([[17., 100., 4000],
                            [20., 80., 5000],
                            [23., 75., 5500]])
# 只将数据的第一列做归一化
data = raw_samples.iloc[:,1:2]

mms = sp.MinMaxScaler(feature_range=(0, 1))		# 创建处理对象, 将数据缩放到0~1的范围
result1 = mms.fit_transform(data)				# 数据缩放
result1				"""
                    array([[0. ],
                           [0.5],
                           [1. ]])
                    """

result2 = mms.inverse_transform(result1)		# 数据还原
result2				"""
                    array([[17.],
                           [20.],
                           [23.]])
                    """
c) 归一化

有些情况每个样本的每个特征值具体的值并不重要,但是每个样本特征值的占比更加重要。
所以归一化即是用每个样本的每个特征值除以该样本各个特征值绝对值的总和。变换后的样本矩阵,每个样本的特征值绝对值之和为1。
这样可知每个样本在总样本中的占比

用normalize() 方法对样本进行归一化 (必须使用二维的数据类型) (会对行进行归一化)

sp.normalize(array, norm='l1')
# array 原始样本矩阵
# norm  范数
#    l1范数,向量中每个元素绝对值之和
#    l2范数,向量中每个元素平方之和
# 返回归一化预处理后的样本矩阵

示例1:

# 创建DF对象
raw_samples = pd.DataFrame([
    [17., 100., 4000],
    [20., 80., 5000],
    [23., 75., 5500]])

print(raw_samples)
                """
                      0      1     2
                0  17.0  100.0  4000
                1  20.0   80.0  5000
                2  23.0   75.0  5500
                """
# 对DF进行归一化
sample = sp.normalize(raw_samples.T, norm='l1')		# 会对行进行归一化, 所以必须先反转数据 (T属性)
nor = pd.DataFrame(sample.T)						# 再次将归一后的数据反转回来
print(nor)
                """
                          0         1         2
                0  0.283333  0.392157  0.275862
                1  0.333333  0.313725  0.344828
                2  0.383333  0.294118  0.379310
                """

示例2:

raw_samples = pd.DataFrame([
    [17., 100., 4000],
    [20., 80., 5000],
    [23., 75., 5500]])

print(raw_samples)
				"""
                      0      1     2
                0  17.0  100.0  4000
                1  20.0   80.0  5000
                2  23.0   75.0  5500
                """
                
sample = sp.normalize(raw_samples.iloc[:,1:2].T, norm='l1').T
print(pd.DataFrame(sample))
                """
                        0
                0	0.392157
                1	0.313725
                2	0.294118
                """
d) 二值化

有些业务并不需要分析矩阵的详细完整数据(比如图像边缘识别只需要分析出图像边缘即可)
可以根据一个事先给定的阈值,用0和1表示特征值表示不高于或高于阈值。
二值化后的数组中每个元素非0即1,达到简化数学模型的目的。

用Binarizer() 方法和 transform() 方法进行二值化 (会对行进行归一化)

# 给出阈值, 获取二值化器对象
bin = sp.Binarizer(threshold=阈值)
# 调用transform方法对原始样本矩阵进行二值化预处理操作
result = bin.transform(原始样本矩阵)

示例:

# 创建DF对象
raw_samples = pd.DataFrame([[17., 100., 4000],
                            [20., 80., 5000],
                            [23., 75., 5500]])
print(raw_samples)
                """
                      0      1     2
                0  17.0  100.0  4000
                1  20.0   80.0  5000
                2  23.0   75.0  5500
                """
# 二值化
# 给出阈值, 获取二值化器对象
bin = sp.Binarizer(threshold=80)
# 调用transform方法对原始样本矩阵进行二值化预处理操作
result = bin.transform(raw_samples)
print(pd.DataFrame(result, dtype='int'))
                """
                   0  1  2
                0  0  1  1
                1  0  0  1
                2  0  0  1
                """

类别型特征( Categorical Feature ) 主要是指性别(男、女)、血型( A 、B 、AB 、0 ) 等只在有限选项内取值的特征。类别型特征原始输入通常是字符串形式,除决策树等少数模型能直接处理字符串形式的输入, 对于逻辑回归、支持向量机等模型来说,类别型特征必须经过处理转换成数值型特征才能正确工作

2.2 类别特征数值化

Data Categorical Feature

​ 类别型特征(Categorical Feature)主要是指性别(男、女)、血型(A、B、AB、O)等只在有限选项内取值的特征。类别型特征原始输入通常是字符串形式,除了决策树等少数模型能直接处理字符串形式的输入,对于逻辑回归、支持向量机等模型来说,类别型特征必须经过处理转换成数值型特征才能正确工作

a) 独热编码 (onehot)

​ 独热编码通常用于处理类别间不具有大小关系的特征。例如血型,一共有4 个值( A 型血、B 型血、AB 型血、0 型血) ,独热编码会把血型变成一个4 维稀疏向量, A 型血表示为( 1, 0, 0, 0 ) , B 型血表示为( 0, I , 0, 0 ) , AB 型表示为( 0, 0, I, 0 ) , 0 型血表示为( 0, 0,
0, I )

  • **优点:**解决了分类器不好处理分类数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。
  • 缺点:当类别的数量很多时,特征空间会变得非常大,容易造成维度灾难

为样本特征的每个值建立一个由一个1和若干个0组成的序列,用该序列对所有的特征值进行编码。 如下:

		导演		演员		上映地点	类型
战狼1		吴京     余男      内地       战争
钢铁侠1   钢哥	  铁蛋      美国	   科幻
战狼2     吴京     吴京      内地		战争
        10		100			10		10
        01		010			01		01
		10		001			10		10

        101001010
        010100101
		100011010 

对于类别取值较多的情况下使用独热编码需要注意以下问题:

  1. 使用稀疏向量来节省空间。在独热编码下3 特征向量只有某一维取值为1 ,真他位置取值均为0 。因此可以利用向量的稀疏表示有效地节省空间,并且目前大部分的算法均接受稀疏向量形式的输入。
  2. 配合特征选择采降低维度。高维度特征会带来几方面的问题:
    1. 在K 近邻算法中,高维空间下两点之间的距离很难得到高效的衡量;
    2. 在逻辑回归模型中,参数的数量会随着维度的增高而增加,容易引起过拟合问题;
    3. 通常只高部分维度是对分类、预测有帮助,因此可以考虑配合特征选择来降低维度。

用 OneHotEncoder() 函数 和 fit_transform() 函数转换为热独编码

# 创建一个独热编码器
# sparse: 是否使用紧缩格式(稀疏矩阵)
# dtyle:  数据类型
ohe = sp.OneHotEncoder(sparse=是否采用紧缩格式, dtype=数据类型)
# 对原始样本矩阵进行处理,返回独热编码后的样本矩阵。
result = ohe.fit_transform(原始样本矩阵)

示例1:

import numpy as np
import sklearn.preprocessing as sp

raw_samples = np.array([[1., 100., 5000],
                        [1., 80., 5000],
                        [1., 75., 5500]])

# 创建独热编码器
ohe = sp.OneHotEncoder(sparse=False, dtype=int)
# 用独特编码器对原始样本矩阵做独热编码
ohe_samples2 = ohe.fit_transform(raw_samples)
print(ohe_samples2)
"""
[[1 0 0 1 1 0]
 [1 0 1 0 1 0]
 [1 1 0 0 0 1]]
"""

示例2:

import numpy as np
import pandas as pd

raw_samples = pd.DataFrame([[1., 100., 5000],
                            [1., 80., 5000],
                            [1., 80., 5500]])
raw_samples.iloc[:,1]	
                                """
                                    1
                                0	100.0
                                1	80.0
                                2	80.0
                                """
import sklearn.preprocessing as sp

# 创建独热编码器
ohe = sp.OneHotEncoder(sparse=False, dtype=int)

# 将数据转为独热编码
transformed_data = ohe.fit_transform(raw_samples.iloc[:,1:2])
transformed_data
                                """
                                array([[0, 1],
                                       [1, 0],
                                       [1, 0]])
                                """
# 将独热编码转为数据
row_data = ohe.inverse_transform(transformed_data)
row_data
                                """
                                array([[100.],
                                       [ 80.],
                                       [ 80.]])
                                """
b) 标签编码

​ 标签编码又叫序号编码 (sklearn的LabelEncoder可以对于数字类进行大小排序功能, 但是字符串的话不行), 序号编码通常用于处理类别间具有大小关系的数据。例如成绩,可以分为低、中、高三档,并且存在“高>中>低”的排序关系。序号编码会按照大小关系对类别型特征赋予一个数值ID,例如高表示为3、中表示为2、低表示为1,转换后依然保留了大小关系

根据字符串形式的特征值在特征序列中的位置,为其指定一个数字标签,用于提供给基于数值算法的学习模型。将字符串转为数字

  • **优点:**解决了分类编码的问题,可以自由定义量化数字。但其实也是缺点,因为数值本身没有任何含义,只是排序。如大中小编码为123,也可以编码为321,即数值没有意义。
  • **缺点:**可解释性比较差。比如有[dog,cat,dog,mouse,cat],我们把其转换为[1,2,1,3,2],这里就产生了一个奇怪的现象:dog和mouse的平均值是cat。因此,Label encoding编码其实并没有很宽的应用场景。

用 LabelEncoder() 方法创建编码器对象
用 fit_transform() 方法进行编码
用 inverse_transform() 方法进行解码

# 获取标签编码器
lbe = sp.LabelEncoder()
# 调用标签编码器的fit_transform方法训练并且为原始样本矩阵进行标签编码
result = lbe.fit_transform(原始样本数组)		# 放入1为数组
# 根据标签编码的结果矩阵反查字典 得到原始数据矩阵
samples = lbe.inverse_transform(result)

# 用map()方法对字符串进行排序

示例1: (sklearn标签编码器)

import sklearn.preprocessing as sp
import pandas as pd

raw_samples = pd.Series(['audi', 'ford', 'audi', 'toyota',
                         'ford', 'bmw', 'toyota', 'ford', 'audi'])

# 获取标签编码器
lbe = sp.LabelEncoder()

# 调用标签编码器的fit_transform方法训练并且为原始样本矩阵进行标签编码
result = lbe.fit_transform(raw_samples)
print(result)		# [0 2 0 3 2 1 3 2 0]

# 根据标签编码的结果矩阵反查字典 得到原始数据矩阵
samples = lb.inverse_transform(result)
print(samples)		# ['audi' 'ford' 'audi' 'toyota' 'ford' 'bmw' 'toyota' 'ford' 'audi']

示例2: (map函数)

import numpy as np
import pandas as pd

raw_samples = pd.DataFrame([[1., '大', 5000],
                            [1., '中', 5000],
                            [1., '小', 5500]])

classMap = {'小':1,'中':2,'大':3}
transformed_data = raw_samples.iloc[:,1].map(classMap)
print(transformed_data)
                    """
                    0    3
                    1    2
                    2    1
                    Name: 1, dtype: int64
                    """

classMap = {1:'小',2:'中',3:'大'}
row_data = transformed_data.map(classMap)
print(row_data)
                    """
                    0    大
                    1    中
                    2    小
                    Name: 1, dtype: object
                    """
c) 独热编码 vs 标签编码

特征数据类型

  • **对于定类类型的数据,建议使用one-hot encoding。**定类类型就是纯分类,不排序,没有逻辑关系。比如性别分男和女,男女不存在任何逻辑关系,我们不能说男就比女好,或者相反。再者,中国各省市分类也可以用独热编码,同样各省不存在逻辑关系,这时候使用one-hot encoding会合适些。但注意,一般会舍去一个变量,比如男的对立面肯定是女,那么女就是重复信息,所以保留其中一个变量即可。
  • **对于定序类型的数据,建议使用label encoding。**定序类型也是分类,但有排序逻辑关系,等级上高于定类。比如,学历分小学,初中,高中,本科,研究生,各个类别之间存在一定的逻辑,显然研究生学历是最高的,小学最低。这时候使用Label encoding会显得更合适,因为自定义的数字顺序可以不破坏原有逻辑,并与这个逻辑相对应。

所使用的模型

  • 对数值大小敏感的模型必须使用one-hot encoding。典型的例子就是LR和**SVM。**二者的损失函数对数值大小是敏感的,并且变量间的数值大小是有比较意义的。而Label encoding的数字编码没有数值大小的含义,只是一种排序,因此对于这些模型都使用one-hot encoding。
  • **对数值大小不敏感的模型(如树模型)不建议使用one-hot encoding。**一般这类模型为树模型。如果分类类别特别多,那么one-hot encoding会分裂出很多特征变量。这时候,如果我们限制了树模型的深度而不能向下分裂的话,一些特征变量可能就因为模型无法继续分裂而被舍弃损失掉了。因此,此种情况下可以考虑使用Label encoding。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值