类型数据
特征里经常会有非数值类型的,比如某个用户去看电影,他留下的非数值特征可能有:星期几去的,几月份,几点,是不是节假日,当天天气等.这些数据属于类型数据(categorical data),比如:
星期几:一二三四五六七
月份:一到十二月
当天天气:晴,雨,阴,雪.
以前一直以为在构建特征时碰到这种类型数据,用一位数字表示就好,比如某个样本的特征是(2, 12 , 22 , 0, 1)表示星期二,十二月,22点,非节假日,晴天.但最近看书才知道不是这样,应该用一种称作二元编码的方法.
二元编码
首先统计某个类型数据一共有几类,比如星期几共有7种类型.二元编码就是只再对应的位置上为1,其它全是0.比如星期一对应(1,0,0,0,0,0,0).不过不是非要按照顺序来,比如星期三不一定是(0,0,1,0,0,0,0).每种特征按照这种方式转换,最后拼起来.
想了想这么做确实有道理,参数多了,对每个特征的每种情况都训练了一个或者多个参数.如果写成(2, 12 , 22 , 0, 1)参数就太少.
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
def get_mapping(dataset, idx): '''dataset是所有数据,统计各维特征并编号 ''' featset = set() for data in dataset: featset.add(data[idx]) return dict(zip(featset, range(0, len(featset))))
mappings = [get_mapping(dataset, idx) for idx in range(0, 3)]
feature_len = sum(map(len, mappings))
def get_one_hot_feature(data, mappings, feature_len): '''data是一条数据 ''' feature_vec = np.zeros(feature_len) idx = 0 step = 0 for feature in data: feature_vec[step + mappings[idx][feature]] = 1.0 step += len(mappings[idx]) idx += 1 return feature_vec
all_one_hot_feature = map(lambda data: get_one_hot_feature(data, mappings, feature_len), dataset)
|