【自学笔记】处理类别数据、独热编码和降维(主成分分析)

类别数据

  与数值特征不同,类别数据往往更难被计算机理解,主要分为序数标称
  序数具有顺序,比如衣服尺码中有XL>L>M等
  标称不含任何顺序,特征之间相互独立。

处理序数特征

  为了让算法正确解读序数特征,我们需要用整数来表示。我们可以定义映射关系,训练后再反向映射,比如:

import pandas as pd

df = pd.DataFrame([['green', 'M', 10.1, 'class2'],
                   ['red', 'L', 13.5, 'class1'],
                   ['blue', 'XL', 15.3, 'class2']])
df.columns = ['color', 'size', 'price', 'classlabel']

size_mapping = {
   'XL': 3,
                'L': 2,
                'M': 1}
df['size'] = df['size'].map(size_mapping)

在这里插入图片描述
在这里插入图片描述

  查看映射关系:

inv_size_mapping = {
   v: k for k, v in size_mapping.items()}
df['size'].map(inv_size_mapping)

在这里插入图片描述

处理标称数据

  与上述不同的是,标称数据没有顺序,所以可以更方便地自动获取映射:

# 获取这列数据,用unique去除重复,再为每种数据映射到数字
class_mapping = {
   label: idx for idx, label in enumerate(np.unique(df['classlabel']))}
df['classlabel'] = df['classlabel'].map(class_mapping)

# 反向映射
inv_class_mapping = {
   v: k for k, v in class_mapping.items()}
df['classlabel'] = df['classlabel'].map(inv_class_mapping)

在这里插入图片描述

  在ski-learn中也可以直接调用LabelEncoder类来实现:

from sklearn.preprocessing import LabelEncoder

class_le = LabelEncoder()
y = class_le.fit_transform(df['classlabel'].values)
# y = array([1, 0, 1])

# 反向映射
class_le.inverse_transform(y)
# >> array(['class2', 'class1', 'class2'], dtype=object)

独热编码

  虽然我们将标称数据映射成了整数,并声称其没有顺序,但机器学习算法会认为1大于0,2大于1,从而影响算法的偏好。

  解决这个问题的常用方案是独热编码。我们将每一个特征映射成同样大小的向量。比如:

array = [1, 0, 1, 2]

  将会变成:

array2 = [ [0, 1, 0],
      [1, 0, 0],
      [0, 1, 0],
      [0, 0, 1]]

注意

   使用独热编码要小心多重共线性,即所有的特征呈现出了一个相关性(如果n种取值中前n-1个都预测为0,那第n个一定是1)。如果发生了特征高度相关,会导致矩阵求逆是很难的,且会降低数据稳定性。

在这里插入图片描述
   所以,我们可以简单粗暴地删除一个特征列,不用担心丢失信息。

代码实现

   最方便的是pandas:

pd.get_dummies(df[['price', 'color', 'size']], drop_first=True)

   或者用sklearn中的OneHotEncoder:

from sklearn.preprocessing import OneHotEncoder

X = df[['color', 'size', 'price']].values
color_ohe = OneHotEncoder()

# 此处只转换单列
color_ohe.fit_transform(X[:, 0].reshape(-1, 1)).toarray()

  如果想转化多列,ColumnTransformer支持同时对不同列使用不同的转化策略。

# 导入ColumnTransformer类,它允许对数据集的不同列应用不同的转换器
from sklearn.compose import ColumnTransformer

# 从数据帧df中选择'color', 'size', 'price'三列,并将它们转换为NumPy数组赋值给X
X = df[['color', 'size', 'price']].values

# 定义ColumnTransformer实例c_transf
c_transf = ColumnTransformer([

    # 定义第一个转换器:对第0列('color'列)进行独热编码
    ('onehot', OneHotEncoder(), [0]),

    # 定义第二个转换器:对于第1列和第2列('size'和'price'列)不进行任何转换,直接保留原数据
    # 'nothing'是转换器的名称,'passthrough'是一个特殊的转换器,表示这些列的数据将被直接传递,不做任何修改
    ('nothing', 'passthrough', [1, 2])
])

# 使用X数据拟合c_transf,并对其进行转换
# fit_transform()方法首先会根据X数据拟合转换器,然后应用这些转换器对X数据进行转换
c_transf.fit_transform(X).astype(float)

降维

  数据的维度直接决定了训练模型的难度和时间成本,维度过高也有过拟合的风险。主要有两种降维技术:特征选择特征提取

序列特征选择算法

  经典的序列特征选择算法是序列后向选择(SBS),使用贪心的思想,每次选择一个性能损失最小的特征并删除,直到新的特征子空间包含了需要的特征数量。

  (1)假设 d d d为特征空间 X d X_{d} Xd的维数
  (2)找到影响最小的特征 x − ∈ X d x^{-}\in{X_{d}} xXd, x − = a r g m a x J ( X d − x ) x^{-}=argmaxJ(X_{d}-x) x=argmaxJ(Xdx) ------max指找到最大值,arg指找到对应使J最大的 x x x
  (3)从特征集中去除特征 x − x^{-} x X d − 1 = X d − x − X_{d-1}=X_{d}-x^{-} Xd1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值