理解特征工程Part1-连续数值数据,读英文原文Understanding Feature Engineering (Part 1) — Continuous Numeric Data,用中文记录一些关键点。
总述
典型的机器学习pipeline
端到端的机器学习pipeline如下
获取原始数据(raw data)并且在这些数据之上直接构建模型(models)是鲁莽的因为我们不会拿到想要的结果或者表现,并且算法也不足够只能来自动从原始数据中提取有意义的特征(features)。
这里主要关注的是上图中的data preparation,我们使用各种方法论来从原始数据中提取有意义的属性或者特征,主要是Feature Extraction&Engineering部分。
Prof. Pedro Domingos在他的论文 “A Few Useful Things to Know about Machine Learning”中说:
“At the end of the day, some machine learning projects succeed and some fail. What makes the difference? Easily the most important factor is the features used.”
Understanding Features(理解特征)
feature一般是原始数据上的特定表示,它是一个独立的(individual)可衡量的(measurable)属性。一般被描述为数据集的一列。假设有一个二维数据集,每行描述了一个观察(observation),每列表示一个特征,形式如下:
典型的机器学习算法处理这些数值矩阵或张量(tensors),因此大部分特征工程技术主要是将原始数据转换为一些能被这些算法理解的数值表示。
基于数据集特征可以分为两类,原始特征(raw features)可以直接从数据集上获取而不需要额外的数据处理或工程。衍生特征(derived features)经常是从特征工程获取,我们需要从现有数据属性中提取。一个简单的例子是从一个员工包含生日“Birthdate”的数据集中通过拿当前日期减去生日创建新的特征“Age”。
也有不通的数据类型比如结构化数据和非结构化数据,本文主要讨论的是处理结构化数据的特征工程。
Feature Engineering on Numeric Data(数值数据特征工程)
这里的数值数据指的是连续数据而不是离散数据,数值数据也可以用值的向量来表示,其中向量中每个值表示一个特定的特征。int和float是最常用的表示连续数值数据的类型。虽然数值数据可以直接喂给机器学习模型,但是你可能根据场景,问题和领域的不通在构建模型前还是需要特征工程。
我们用python来看看一些数值数据的特征工程的策略:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as spstats
%matplotlib inline
Raw Measures(原始度量)
之前提到,原始数值数据经常可以直接喂给机器学习模型,raw measures就是不经过任何转换直接使用的数值变量,一般这些特征表示成值或者计数(counts),比如数据集Pokémon dataset中如下一段数据:
poke_df = pd.read_csv('datasets/Pokemon.csv', encoding='utf-8') poke_df.head()
这些数据集由各种特点的各种统计组成。
Values(数值)
来看一些数值数据
poke_df[['HP', 'Attack', 'Defense']].head()
包括HP,Attack等都是连续数值数据,这些数值可以直接作为特征,再看下这些数据的统计评估:
poke_df[['HP', 'Attack', 'Defense']].describe()
Counts(计数)
另外一个原始度量就是表示频率的特征,特定属性发生的计数,
看看表示大多数用户经常听的歌曲的频率的数据集millionsong dataset。
popsong_df = pd.read_csv('datasets/song_views.csv',
encoding='utf-8')
popsong_df.head(10)
上面截图中的listen_count就是统计计数值。
Binarization(二值化)
有时候原始计数可能和我们要构建的模型无关,比如当我在构建歌曲推荐系统的时候,为想知道一个人是否听过一个特定的歌曲,这就不需要该歌曲被听的次数因为为更关心用户是否听了,这是好用二值(比如0/1)就比count更合适,比如:
上面的watched就是用二值0/1表示是否看过。
Rounding(凑整)
经常我们处理像比例或者百分比这样连续数值属性的时候,我们可能不需要原始数值有很高的精度,因此舍去这些精度为数值int型就很合理了,这些int值然后可以直接用于做特征。我们尝试将这个概念用于虚拟数据集来描述items和相应流行比例。
items_popularity = pd.read_csv('datasets/item_popularity.csv',
encoding='utf-8')
items_popularity['popularity_scale_10'] = np.array(
np.round((items_popularity['pop_percent'] * 10)),