1、什么是分类变量?
通常来说,分类变量是用来表示某一属性的类别或标识的。例如:一年中的四季,月份,OS,brand,行业(银行、保险、券商、科技......),地区等等;大型分类变量例如:IP地址,用户ID,语料库的词汇表等等
一般的,分类变量有个显而易见的特点:数量有限且无序,不具有数值型数据大小的含义。因此在很多涉及到数值度量的模型中,如:LR,SVM等,我们不能像处理数值型变量那样来处理分类变量。
一般来说,类别数量小的分类变量的常见处理方式有:one-hot编码,虚拟编码和效果编码。
示例数据:
1.1 one-hot编码
示例数据中,“brand”特征有apple,huawei, xiaomi 三种值,可以简单地为其标注为0,1,2.但是这样做的结果是使类别彼此之间有了顺序和大小关系。更好地方法是,使用一组比特位,每个比特位表示一种可能的类别,因此k个类别的分类变量就可以编码为长度为k的特征向量。one-hot encoding可以用scikit-learn中的sklearn.proprocessing.LabelBinarizer来实现,也可以用pandas.get_dummies实现。
# pandas.get_dummies实现
pd.get_dummies(df,columns=['brand'])
# 利用sklearn中的LabelBinarizer实现onehot效果
# encoder= LabelBinarizer()
# brand_1hot=encoder.fit_transform(df['brand'])
# feature=pd.concat([df,pd.DataFrame(brand_1hot,columns=['brand_apple','brand_huawei','brand_xiaomi'])],axis=1)
1.1.2 LabelEncoder
把这些文本标签转换为数字:
encoder_Label=LabelEncoder()
brand_label_encoded=encoder_Label.fit_transform(df['brand'])
brand_label_encoded
标注为0,1,2, 这样做的结果是使类别彼此之间有了顺序和大小关系。这样的做法只在有些有包含关系或等级关系的类别中比较合适。
1.2虚拟编码(dummy encoding)
在one-hot编码的方式亦可以利用其中一列作为参照系。
一般分类变量有k个类别,就用了长度为k的特征向量来表示。而在虚拟编码中,只使用长度为(k-1)的特征向量来表示,被去掉的特征被一个全零向量所替代,它被称为参照类。
如下:
1.3Effect编码
分类变量编码的另一种变体称为Effect编码。 Effect编码与虚拟编码非常相似,区别在于参考类别现在由所有-1的向量表示。
# 先进行虚拟编码
dummy_df = pd.get_dummies(df, columns=["brand"], drop_first=True)
effect_df=dummy_df.copy()
effect_df[['brand_huawei','brand_xiaomi']]=effect_df[['brand_huawei','brand_xiaomi']].astype('int8')
# 虚拟编码转为效果编码的函数
effect_df.loc[(dummyDF['brand_huawei']==0)&(dummyDF['brand_xiaomi']==0),['brand_huawei','brand_xiaomi']]=-1
effect_df
类别变量的优点和缺点
独热编码是多余的,它允许多个有效模型一样的问题。 非唯一性有时候对解释有问题。该优点是每个特征都明显对应于一个类别。 此外,失踪数据可以编码为全零矢量,输出应该是整体目标变量的平均值。
虚拟编码和效果编码不是多余的。 他们产生独特和可解释的模型。 虚拟编码的缺点是它不能轻易处理缺少数据,因为全零矢量已经映射到参考类别。它还编码每个类别相对于参考类别的影响,其中看起来很奇怪。 效果编码通过使用不同的代码来避免此问题参考类别。 但是,所有-1的矢量都是一个密集的矢量,对于存储和计算来说都很昂贵。
因此,Pandas和Scikit Learn等流行的ML软件包选择了虚拟编码或独热编码,而不是效应编码。当类别数量变得非常多时,所有三种编码技术都会失效大。 需要不同的策略来处理非常大的分类变量。
2.分箱计数的方法来处理大型分类变量
独热编码、虚拟编码和效果编码,这三种编码在面对类别数量特别大的情况下就会生成一个大型的、稀疏的、二值的特征向量空间,这对于模型训练而言是不合理的。因此我们通常会选择分箱计数的方法来处理大型分类变量。
简单来说,分箱计数就是要找到一个与类别本身以及目标变量相关的统计量来替代该类别特征,使特征转换为一个小巧的、密集的、实数型的特征向量。
如何找到这么一个相关统计量来替代类别本身?
(1)将分类变量的条件概率作为相关统计量,也即每个类别的响应率:
响应率公式:
(2)优势比:
实例如下:
| 点击(次) | 没有点击(次) | 总计 |
小明 | 50 | 1200 | 1250 |
非小明 | 9950 | 188800 | 198750 |
总计 | 10000 | 190000 | 200000 |
所以,优势比的值为:
在这个例子中,优势比就是“小明点击广告的概率在多大程度上高于她不点击广告的概率”和“其他人点击广告的概率在多大程度上高于他们不点击广告的概率”这两个问题的比值。
(3)将优势比考虑的简单点,即只考虑原公式的分子部分,也适用于具有多个值的大型分类变量。
(4)在实际使用过程中,类似优势比的概率比值很容易特别小或者特别大(例如有人会从不点击广告,有人却非常频繁地点击广告)。这时就需要考虑使用对数变换,生成对数优势比。
参考:
1. https://zhuanlan.zhihu.com/p/130766002 了解特征工程——小型分类变量的常见处理
2. 特征工程之特征哈希/标准化缩放