上一篇展示了数据,这里会继续深入了解数据,由数据列的描述信息,知道里面含有哪些数值型特征,哪些为枚举型特征。具体内容如下面脚本所示,
String labelColName = "click";
String[] selectedColNames = new String[] {
"C1", "banner_pos", "site_category", "app_domain",
"app_category", "device_type", "device_conn_type",
"C14", "C15", "C16", "C17", "C18", "C19", "C20", "C21",
"site_id", "site_domain", "device_id", "device_model"};
String[] categoryColNames = new String[] {
"C1", "banner_pos", "site_category", "app_domain",
"app_category", "device_type", "device_conn_type",
"site_id", "site_domain", "device_id", "device_model"};
String[] numericalColNames = new String[] {
"C14", "C15", "C16", "C17", "C18", "C19", "C20", "C21"};
“click“列标明了是否被点击,是分类问题的标签列。对于数值型特征,各特征的取值范围差异很大,一般需要进行标准化、归一化等操作;枚举类型的特征不能直接应用到FTRL模型,需要进行枚举值到向量值的映射,后面还需将各列的变换结果合成到一个向量,即是后面模型训练的特征向量。
我们的示例里,选择对数值类型进行标准化操作,并使用了FeatureHash算法组件,在其参数设置中,需要指定处理的各列名称,并需要标明,哪些是枚举类型,那么没被标明的列就是数值类型。FeatureHash操作会将这些特征通过hasn的方式,映射到一个稀疏向量中,向量的维度可以设置,我们这里设置为30000。每个数值列都会被hash到一个向量项,该列的数值就会付给对应的向量项;而对每个枚举特征的不同枚举值,也会被hash到向量项,并被赋值为1。其实,FeatureHash同时完成了枚举类型的映射及汇总为特征向量的工作。因为使用了hash的方式,会存在不同内容hash到同一项的风险,但是由于该组件使用起来比较简便 ,在示例中使用,或者作为实验开始时的组件,快速得到baseline指标,FeatureHash还是很适合的。相关脚本如下所示:
// result column name of feature enginerring
String vecColName = "vec";
int numHashFeatures = 30000;
// setup feature enginerring pipeline
Pipeline feature_pipeline = new Pipeline()
.add(
new StandardScaler()
.setSelectedCols(numericalColNames)
)
.add(
new FeatureHasher()
.setSelectedCols(selectedColNames)
.setCategoricalCols(categoryColNames)
.setOutputCol(vecColName)
.setNumFeatures(numHashFeatures)
);
我们定义特征工程处理pipeline(管道),其中包括了StandardScaler和FeatureHasher,对批式训练数据trainBatchData执行fit方法,及进行训练,得到PipelineModel(管道模型)。该管道模型可以作用在批式数据,也可以应用在流式数据,生成特征向量。我们先把这个特征工程处理模型保存到本地,设置文件路径为 /Users/yangxu/alink/data/temp/feature_pipe_model.csv
// fit and save feature pipeline model
String FEATURE_PIPELINE_MODEL_FILE = "/Users/yangxu/alink/data/temp/feature_pipe_model.csv";
feature_pipeline.fit(trainBatchData).save(FEATURE_PIPELINE_MODEL_FILE);
BatchOperator.execute();