类别变量类型:
- Nominal: 红,黄,蓝
- Ordinal,高,中,低
连续变量:1.1,2.1,1.3,1.4
类别变量问题的一些挑战
- 类别数量很多,但是每个类别的样本不多,例如“城市”
- 一些机器学习模型,例如回归或者SVM 需要输入是数值型的,类别需要先转化成数值才能应用这些算法
- 对于机器来说,不一定能轻松理解一些人理解的信息,例如 北京,上海,杭州三个城市,人可以知道上海到杭州更近点,但是对于模型来说,仅仅代表三个不同的level,所以需要增加一些额外的信息。
几种处理方法:
- one-hot encoding
[2] 中提到直接用pandas中的get_dummies 函数就可以做处理,方便点;当然,sklearn中也有支持的,具体见文章吧
import pandas as pd
data=pd.DataFrame({
"x":["黄瓜","黄瓜","南瓜","冬瓜"],
"y":["红","蓝","白","黑"]
})
df=pd.get_dummies(data,prefix="蔬菜",columns=["x"])
print(df)
# 输出
y 蔬菜_冬瓜 蔬菜_南瓜 蔬菜_黄瓜
0 红 0 0 1
1 蓝 0 0 1
2 白 0 1 0
3 黑 1 0 0
针对回归模型,对one-hot编码后的特征,需要删除第1列或者最后一列,需要满足自由度为N-1的要求,说白了,是共线性的问题!对于SVM,神经网络和一些聚类算法也是如此操作。
但是在树模型中,我们需要用到N个one-hot编码后的特征
- label encoding
用1...N 表示类别,例如,逾期,正常还款用 1,2 来表示 ; 这个编码会有个问题,实际上类别之间是没有关系的,但机器会认为他们有关系。
df1=data.copy()
df1.loc[:,"x_encode"] =pd.factorize(df1["x"])[0].reshape(-1,1)
print(df1)
# 输出
x y x_encode
0 黄瓜 红 0
1 黄瓜 蓝 0
2 南瓜 白 1
3 冬瓜 黑 2
- binary encoding
需要经历两个步骤:
1.类别变量首先需要转化为数值有序变量,比如1,2,3,4 这种 ,这里的有序仅仅是数字上的有序
2.将上一步的结果转为为二进制,比如 4,转化为 100 ,1 转为为 001
import category_encoders as ce
bencoder=ce.BinaryEncoder(cols=["x","y"])
dfbin=bencoder.fit_transform(data)
print(dfbin)
# 输出
x_0 x_1 x_2 y_0 y_1 y_2
0 0 0 1 0 0 1
1 0 0 1 0 1 0
2 0 1 0 0 1 1
3 0 1 1 1 0 0
其他常见的方法还有WOE,均值,频度等,这里就不介绍,具体可以参见如下的refer
refer:
[1] https://hub.packtpub.com/how-to-handle-categorical-data-for-machine-learning-algorithms/
[2] https://towardsdatascience.com/all-about-categorical-variable-encoding-305f3361fd02
[3] https://www.datacamp.com/community/tutorials/categorical-data