特征工程

归一化:

减去均值,然后归一化

X -= np.mean(X, axis = 0) # 减去均值,使得以0为中心
X /= np.std(X, axis = 0) # 归一化

这样归一化以后数据X就被归一化到-1到1的范围内。

归一化注意事项:

第一,样本归一化。FFM默认是进行样本数据的归一化,即  为真;若此参数设置为假,很容易造成数据inf溢出,进而引起梯度计算的nan错误。因此,样本层面的数据是推荐进行归一化的。

第二,特征归一化。CTR/CVR模型采用了多种类型的源特征,包括数值型和categorical类型等。但是,categorical类编码后的特征取值只有0或1,较大的数值型特征会造成样本归一化后categorical类生成特征的值非常小,没有区分性。例如,一条用户-商品记录,用户为“男”性,商品的销量是5000个(假设其它特征的值为零),那么归一化后特征“sex=male”(性别为男)的值略小于0.0002,而“volume”(销量)的值近似为1。特征“sex=male”在这个样本中的作用几乎可以忽略不计,这是相当不合理的。因此,将源数值型特征的值归一化到  是非常必要的。

第三,省略零值特征。从FFM模型的表达式可以看出,零值特征对模型完全没有贡献。包含零值特征的一次项和组合项均为零,对于训练模型参数或者目标值预估是没有作用的。因此,可以省去零值特征,提高FFM模型训练和预测的速度,这也是稀疏样本采用FFM的显著优势。

离散特征编码分两种,特征具有大小意义,特征不具有大小意义。

1、特征不具备大小意义的直接独热编码

2、特征有大小意义的采用映射编码

import pandas as pd   
df = pd.DataFrame([    
            ['green', 'M', 10.1, 'label1'],     
            ['red', 'L', 13.5, 'label2'],     
            ['blue', 'XL', 15.3, 'label2']])    
# color、label不具备大小含义,size具有大小意义  
df.columns = ['color', 'size', 'length', 'label']    
df 
size_mapping = {    
           'XL': 3,    
           'L': 2,    
           'M': 1}    
df['size'] = df['size'].map(size_mapping)    
    
label_mapping = {lab:idx for idx,lab in enumerate(set(df['label']))}    
df['label'] = df['label'].map(label_mapping)    
df  

直接使用函数进行独热编码

并不会区分是否具有大小含义

get_dummies()用法:

import pandas as pd  
s = pd.Series(list('abca'))  
pd.get_dummies(s)  

对于较大数据量推荐这样的方法处理:

先用LabelEncoder对离散特征编码,因为onehotencoder只能处理数值;然后使用OneHotEncoder编码,生成稀疏表示的特征;再使用sparse.hstack连接连续特征和稀疏特征。

pd.get_dummy直接生成的稠密矩阵,内存开销太大。

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
from scipy import sparse

for feature in cate_feature + con_feature:
    data[feature] = LabelEncoder().fit_transform(data[feature].values)
enc = OneHotEncoder()
train_x=train[numeric_feature]
test_x=test[numeric_feature]
for feature in cate_feature+con_feature:
    enc.fit(data[feature].values.reshape(-1, 1))
    train_a=enc.transform(train[feature].values.reshape(-1, 1))
    test_a = enc.transform(test[feature].values.reshape(-1, 1))
    train_x= sparse.hstack((train_x, train_a))
    test_x = sparse.hstack((test_x, test_a))

# 文本one hot
from sklearn.feature_extraction.text import CountVectorizer
# 每行用空格join起来
data['corpus']=data['corpus'].apply(lambda x:' '.join(x.split(';')))
#如果corpus里面是数字,可能会提示empty vocabulary; perhaps the documents only contain stop words
#改成这样就行了CountVectorizer(token_pattern='(?u)\b\w+\b')
property_feature = CountVectorizer().fit_transform(data['corpus'])
train_x=sparse.hstack((train_property_feature,train_x))
原文地址:https://www.cnblogs.com/ylHe/p/9017837.html