独热码

独热码,在英文文献中称做 one-hot code,直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。例如,有6个状态的独热码状态编码为:000001,000010,000100,001000,010000,100000。

问题

最近在做一个根据一个人的信息预测此人人品的机器学习项目:
https://github.com/Root-lee/ML_micro_loan
在项目中,数据中有上千维的特征,大部分是数值型特征,但是也有93个分类特征,在训练模型时需要将这些分类特征用OneHot编码,使得模型能正确理解这些分类特征。
所幸,著名机器学习包已经提供了独热码的编码器:preprocessing.OneHotEncoder()
我们只需要直接调用就可以了,于是我写了如下代码编码分类特征:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd
#对分类类型的数据进行ONEHOT编码
feature_type = pd.read_csv('G:/Redhat_share/ML_micro/features_type.csv')
category_feature = list(feature_type[feature_type.type=='category'].feature)
test = pd.read_csv('G:/Redhat_share/ML_micro/test_x.csv')
test = test[['uid']+category_feature]
train = pd.read_csv('G:/Redhat_share/ML_micro/train_x.csv')
train = train[['uid']+category_feature]

from sklearn import preprocessing
enc = preprocessing.OneHotEncoder()
enc.fit(train)
train= enc.transform(train).toarray()
train_after_oh = pd.DataFrame(train)
train_after_oh['uid']=uid

但是运行程序时却出现了错误:
error_info
OneHot编码出现ValueError: X needs to contain only non-negative integers.
错误出现在 enc.fit(train) 这一句代码上,根据报错信息,原来scikit-learn库中的onehot编码器要求分类特征是非负整数,但是我们的数据train中的分类特征的值中含有负数,所以会出现错误。

解决办法

在调用onehot编码器之前我们需要先对分类特征数据进行一点处理,将所有的值都变为非负数,可以使用如下代码实现目的:

1
2
3
4
5
6
7
8
#OneHot编码要求特征是非负整数
#先把训练数据特征的值变为非负数
uid = train.uid
train = train.drop('uid',axis=1)
features = list(train.columns)
for feature in features:
max_ = train[feature].max()
train[feature] = (train[feature] - max_) * (-1)

把上面这段代码放在onehot编码之前,再次运行程序错误即可消失。