机器学习特征工程中的Encoding(One-Hot、Target、Ordinal)

目录

  1. Target Encoding
  2. Ordinal Encoding
  3. One-Hot Encoding

简介

在很多机器学习任务中,特征并不总是连续值,而有可能是分类值。

离散特征的编码分为两种情况:

1、离散特征的取值之间没有大小的意义,比如color:[red,blue],那么就使用one-hot编码

2、离散特征的取值有大小的意义,比如size:[X,XL,XXL],那么就使用数值的映射{X:1,XL:2,XXL:3}

One-Hot和Ordinal两种比较常见,接下来着重讲的是 目标编码(target encoding)是特征工程中一种非常强大的技术,在机器学习竞赛中广泛应用并取得了良好的效果。近年来,出现了多种目标编码的方法和变体。本文将探讨并实现一种常见的目标编码方法,即k-fold目标编码。

数据地址

1Target Encoding

目标编码(Target Encoding)是一种用于处理分类特征的技术,它将类别特征映射为目标变量的相关性。在目标编码中,每个类别的特征值被替换为该类别在目标变量上的统计指标,通常是平均值、频率或其他相关性度量。

具体的话是将下面转变成按照类别分类,填为target的平均值

1具体步骤

  • 代码
  • 首先的话使用model_selection.KFold,分成5个fold,再把kfold值写回去,通过kfold值划分xtrain和xvalid,通过groupby(col)将含objec的列的里面值分组然后计算xtrain的target的平均值,最后将值转为字典通过map将xvalid[col]的object值转换target的平均值,test集的话是将5个fold的值加起来然后取平均。
py 复制代码
#这里用把fold填进去是为了方便查看
kf = model_selection.KFold(n_splits=5,shuffle = True,random_state= 42)
for fold,(train_indicies,valid_indicies) in enumerate(kf.split(X=df_train)):
    df_train.loc[valid_indicies,"kfold"] = fold
    
    
#object_cols 含有object的列
for col in object_cols:
    temp_df = []
    temp_test_feat = None
    #这里的话是有5个fold
    for fold in range(5):
        xtrain = df[df.kfold != fold].reset_index(drop=True)
        xvalid = df[df.kfold == fold].reset_index(drop=True)
        #这里的话是根据col列的值分组 比如A一组,B一组,然后计算每一组的平均值
        feat = xtrain.groupby(col)['target'].agg("mean")
        #转为字典
        feat = feat.to_dict()
        #将原值转为平均值
        xvalid[col] = xvalid[col].map(feat)
        temp_df.append(xvalid)
        if temp_test_feat is None:
            temp_test_feat = df_test[col].map(feat)
        else:
            temp_test_feat += df_test[col].map(feat)
    temp_test_feat /= 5
    df_test.loc[col] = temp_test_feat
    df = pd.concat(temp_df)
    
  • groupby()功能查看
py 复制代码
for key,values in df.groupby(col):
    print(pd.DataFrame([values[col],values['target']]).T)
css 复制代码
       cat9    target
31        A  6.847814
32        A  8.023149
33        A  6.975083
34        A  5.858966
48        A  7.732898
...     ...       ...
299835    A   7.65375
299894    A  8.060798
299909    A  6.427984
299925    A  4.821355
299974    A  7.584323

[13408 rows x 2 columns]
       cat9    target
5         B  7.060652
35        B  8.563246
97        B  7.691082
239       B    8.3303
277       B   7.18416
...     ...       ...
299748    B  6.823052
299773    B  6.975738
299848    B  8.113872
299935    B  5.561943
299979    B  8.342594

2对比原数据和修改数据

py 复制代码
df2 = df1.groupby('kfold')['cat0'].unique()
df3 = df.groupby('kfold')['cat0'].unique()#原数据
df4 = pd.merge(df3,df2,on = 'kfold',how = 'left')
df4

左边是原有的数据值,右边是转换成的target平均值

kfold cat0(原本) cat0(target encoding之后)
0 [A, B] [7.468670297726988, 7.270407090697891]
1 [A, B] [7.469791725132474, 7.269712615159259]
2 [B, A] [7.271782291227367, 7.468671480124456]
3 [A, B] [7.46870305956268, 7.26862208495064]
4 [A, B] [7.467050068804046, 7.265260691611668]

3最终效果

2 Ordinal Encoding

使用sklearn导包,并查看原本是Object的数据

py 复制代码
#找出有object的列,也可以用DataFrame.select_dtypes(include=None, exclude=None)找出来

object_cols = [col for col in useful_features if col.startswith("cat")]
df[object_cols]

使用 Ordinal Encoding

py 复制代码
from sklearn.preprocessing import OrdinalEncoder

# Apply ordinal encoder
ordinal_encoder = OrdinalEncoder()
df[object_cols] = ordinal_encoder.fit_transform(df[object_cols])

3 One-Hot Encoding

单热编码创建新列,指示原始数据中每个可能值的存在(或不存在)。

方法 1pandas 的独热编码

py 复制代码
df = pd.get_dummies(df)
  • 查看结果
  • 数据太多,单独查看有object的列查看
py 复制代码
df1 = df[object_cols]
df1 = pd.get_dummies(df1)
  • 原数据
  • 查看新列名列表,下面是结果
py 复制代码
df1.columns
py 复制代码
Index(['cat0_A', 'cat0_B', 'cat1_A', 'cat1_B', 'cat2_A', 'cat2_B', 'cat3_A',
       'cat3_B', 'cat3_C', 'cat3_D', 'cat4_A', 'cat4_B', 'cat4_C', 'cat4_D',
       'cat5_A', 'cat5_B', 'cat5_C', 'cat5_D', 'cat6_A', 'cat6_B', 'cat6_C',
       'cat6_D', 'cat6_E', 'cat6_G', 'cat6_H', 'cat6_I', 'cat7_A', 'cat7_B',
       'cat7_C', 'cat7_D', 'cat7_E', 'cat7_F', 'cat7_G', 'cat7_I', 'cat8_A',
       'cat8_B', 'cat8_C', 'cat8_D', 'cat8_E', 'cat8_F', 'cat8_G', 'cat9_A',
       'cat9_B', 'cat9_C', 'cat9_D', 'cat9_E', 'cat9_F', 'cat9_G', 'cat9_H',
       'cat9_I', 'cat9_J', 'cat9_K', 'cat9_L', 'cat9_M', 'cat9_N', 'cat9_O'],
      dtype='object')

方法2使用sklearn

  • 具体步骤就是创造OneHotEncoder,然后fit_transform,有object的列,然后通过pd.concat,再将原数据drop掉了有object的列,再拼接独热编码好的列,如OH_cols_train
py 复制代码
# Apply one-hot encoder to each column with categorical data
OH_encoder = OneHotEncoder(handle_unknown='ignore', sparse=False)
OH_cols_train = pd.DataFrame(OH_encoder.fit_transform(X_train[low_cardinality_cols]))
OH_cols_valid = pd.DataFrame(OH_encoder.transform(X_valid[low_cardinality_cols]))

# One-hot encoding removed index; put it back
OH_cols_train.index = X_train.index
OH_cols_valid.index = X_valid.index

# Remove categorical columns (will replace with one-hot encoding)
num_X_train = X_train.drop(object_cols, axis=1)
num_X_valid = X_valid.drop(object_cols, axis=1)

# Add one-hot encoded columns to numerical features
OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1)
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1)

# Ensure all columns have string type
OH_X_train.columns = OH_X_train.columns.astype(str)
OH_X_valid.columns = OH_X_valid.columns.astype(str)
相关推荐
古希腊掌管学习的神2 小时前
[机器学习]XGBoost(3)——确定树的结构
人工智能·机器学习
海棠AI实验室4 小时前
AI的进阶之路:从机器学习到深度学习的演变(一)
人工智能·深度学习·机器学习
IT古董5 小时前
【机器学习】机器学习的基本分类-强化学习-策略梯度(Policy Gradient,PG)
人工智能·机器学习·分类
睡觉狂魔er5 小时前
自动驾驶控制与规划——Project 3: LQR车辆横向控制
人工智能·机器学习·自动驾驶
scan7246 小时前
LILAC采样算法
人工智能·算法·机器学习
菌菌的快乐生活6 小时前
理解支持向量机
算法·机器学习·支持向量机
爱喝热水的呀哈喽6 小时前
《机器学习》支持向量机
人工智能·决策树·机器学习
大山同学6 小时前
第三章线性判别函数(二)
线性代数·算法·机器学习
苏言の狗6 小时前
Pytorch中关于Tensor的操作
人工智能·pytorch·python·深度学习·机器学习
bastgia7 小时前
Tokenformer: 下一代Transformer架构
人工智能·机器学习·llm