【特征工程】变量编码方式


我们在用模型去解决机器学习问题的时候,要提前进行“特征工程”。而特征工程中很重要的就是对特征的预处理。分类变量是另一类常见的变量,用于表示类别或标记。与数值变量不同的是,分类变量的值是不能被排序的,所以也称无序变量。分类变量处理的核心是如何编码类别。最简单的方式就是使用正整数编码类别,但是这样就使得类别之间有了顺序,相当于是引入了额外的特征信息,是不允许的。

例如著名的Kaggle泰坦尼克生还预测这个比赛中,乘客从哪里上船(Embarked)这个变量就是类别型变量。这三个登船点两两之间的相关度应该是一样的,即S地区和C地区,与S地区与Q地区的相关度应该一样,这样就意味着如果我给Embarked变量用Embarked=1来表示乘客在S地区上船,Embarked=2表示乘客在Q地区上船,Embarked=3表示乘客在C地区上船,这样就会认为S与Q的“距离”比S和C之间的距离更近,所以这样编码是不合理的。

正因如此,我们引入了离散型变量的编码方式——one-hot(独热编码)dummy variable(哑变量)

one-hot encoding(独热编码)

one-hot编码(独热编码)用一个比特位表示一种可能的编码。一般每个变量只属于一个类别,所以只有一个比特位是1,这就是‘独热‘’这个词的由来。

独热编码的基本思想:将类别特征进行表示一个最好的办法就是使用一组比特位来表达。每一位代表一个可能的类别。 如果该变量不能一次成为多个类别,那么该组中只有一位可以是1。 这被称为独热编码, 每个位都是一个特征。 因此是一个绝对的具有k个可能类别的变量被编码为长度为k的特征向量。

我们以5个城市为例,我们想要使用one-hot对其进行编码,以下表示对五个城市进行编码:
在这里插入图片描述
独热编码的问题是,使用的比特位比实际所需多一位,因为所有位都为0这个编码没有被使用。

因为有且只有一个比特位是1,各比特位bn表示,则有b1+b2+…+bn=1。这是一个线性关系,而线性相关的特征有个缺点,会导致训练出的模型不唯一,特征的不同线性组合可以做出相同的预测。

dummy variable(哑变量)

哑变量编码直观的解释就是任意的将一个状态位去除。那对于以上五个城市的例子,我们可以只用4个状态位来表示5个变量。也就是说对于Hawaii这个城市,我们可以用全零来表示,即 [ 0 , 0 , 0 , 0 ] [0,0,0,0] [0,0,0,0]。只拿以上5个城市来说,如果不是前四个,那么就一定是Hawaii。

以下是对5个城市的哑变量表示:
在这里插入图片描述
哑变量编码没有了冗余,但是也损失了独热编码具有的直观性。直观和冗余有时候是矛盾。

### 特征工程中哑编码的实现方法 在机器学习数据预处理领域,哑编码(One-Hot Encoding)是一种常见的技术,用于将分类变量转换为可以提供给机器学习算法的形式。通过哑编码,每个类别都会被转化为一个新的二元列(0 或 1),表示该类别的存在与否。 #### 使用 `pandas` 实现哑编码 Python 的 `pandas` 库提供了简单易用的方法来进行哑编码操作。以下是具体的代码示例: ```python import pandas as pd # 创建一个简单的 DataFrame 示例 data = {'Gender': ['Male', 'Female', 'Female', 'Male'], 'City': ['New York', 'Los Angeles', 'New York', 'Chicago']} df = pd.DataFrame(data) # 使用 get_dummies 函数进行 One-Hot 编码 one_hot_encoded_df = pd.get_dummies(df, columns=['Gender', 'City']) print(one_hot_encoded_df) ``` 上述代码片段展示了如何利用 `pd.get_dummies()` 对分类变量进行哑编码[^5]。此函数会自动创建新的二元列,并删除原有的分类列。 #### 使用 `scikit-learn` 实现哑编码 除了 `pandas`,还可以使用 `scikit-learn` 提供的功能完成相同的操作。下面是基于 `ColumnTransformer` `OneHotEncoder` 的实现方式: ```python from sklearn.preprocessing import OneHotEncoder from sklearn.compose import ColumnTransformer import numpy as np import pandas as pd # 构造样本数据 data = {'Gender': ['Male', 'Female', 'Female', 'Male'], 'City': ['New York', 'Los Angeles', 'New York', 'Chicago']} df = pd.DataFrame(data) # 定义要应用 One-Hot Encoder 的列名 categorical_features = ['Gender', 'City'] # 初始化 ColumnTransformer 并指定 OneHotEncoder transformer = ColumnTransformer( transformers=[ ('onehot', OneHotEncoder(sparse=False), categorical_features) ], remainder='passthrough' # 不影响其他未指定的列 ) # 转换数据并查看结果 encoded_data = transformer.fit_transform(df) encoded_df = pd.DataFrame(encoded_data, columns=transformer.named_transformers_['onehot'].get_feature_names_out(categorical_features)) print(encoded_df) ``` 这段代码演示了如何借助 `scikit-learn` 的工具链执行更灵活的哑编码过程[^6]。特别适合于复杂场景下的流水线构建需求。 #### 哑编码的优点与局限性 优点包括但不限于能够有效减少模型对顺序假设的影响;而缺点则可能涉及维度爆炸问题,在某些情况下增加计算成本较高[^7]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值