作者:linxdcn
转载请注明出处:http://blog.csdn.net/linxdcn/article/details/80866745
最近看完一本写特征工程的书,概念清晰,内容全面,所以总结如下读书笔记,书名:Feature Engineering Made Easy,可免费试用在线阅读。
1、特征认识(Feature understanding)
- 结构化数据:可分解为观测记录和属性的数据,如表格数据,行为观测,列为属性
- 非结构化数据:数据形式随意,不遵循特定规则,如一堆数据(log文件),博客信息,或者只有一个特征的数据
- 定量数据:有明确数值的数据
- 定性数据:类别数据
1.1 探索性数据分析(Exploratory data analysis)&描述性分析(Descriptive analysis)
常用的函数有(调用pandas包):head()、info()、describe()、isnull()、corr()等
1.2 四种数据级别
- 名义级别(The nominal level):全部为定性数据,不能进行加减乘除数学运算,但可以做计数(count)统计,如血型数据,可采用饼图、直方图可视化
- 序列级别(The ordinal level):与名义级别基本一致,但数据可自然排序,为类别(category)数据,数学上数据可比较(compare),如大学成绩A、B、C、D,可采用Box-plot可视化
- 间隔级别(The interval level):除了名义级别和序列级别的特性,间隔级别数据还可进行加减运算,如温度
- 比例级别(The ratio level):除了上述级别的特性,比例级别可进行乘除运算(拥有0物理含义),如重量,钱,100块是50块的2倍
2、特征改进(Feature improvement)
2.1 缺失值处理
- 删除缺失值记录:调用pandas包的dropna()
- (定量数据)填充均值或中值:(pandas包)data.fillna(value),(sklearn包)Imputer().fit_transform(data)
- (定性数据)填充众数:(pandas包)data.fillna(data.value_counts().index[0])
注意:缺失值的填补应该在划分训练集和测试集之后,即用训练集的某一特征均值代入测试集的缺失值。
2.2 标准化和正态化(Standardization and Normalization)
3、特征构建(Feature Construction)
在做数据变换时,sklearn实现了一种名为Pipelines的流水线处理模式,使得在尝试模型参数进行交叉检验时,多个处理步骤可集成一体,在具体可参考官网sklearn.pipeline.Pipeline的说明。以定性数据的缺失值处理为例:
from sklearn.base import TransformerMixin class CustomCategoryImputer(TransformerMixin): def __init__(self, cols=None): self.cols = cols def transform(self, df): X = df.copy() for col in self.cols: X[col].fillna(X[col].value_counts().index[0], inplace=True) return X def fit(self, *_): return self cci = CustomCategoryImputer(cols=['col1', 'col2']) imputer = Pipeline([('category', cci), ('xxx', xxx)]) imputer.fit_transform(X)
3.1 类别数据编码(Encoding categorical variables)
- 名义级别编码:将类别数据转换为哑变量(Dummy Variable),如(性别:男or女)=> (男:0 or 1;女:0 or 1)(注意这个例子中其实(女:0 or 1)为多余的),类似于One-hot编码,在pandas中可调用get_dummies()
- 序列级别编码:可采用标签编码(Label Encoder),将序列按0~(n-1)编码
- 数值特征组合:有时也可将数值特征按多项式组合,生成新的特征,可调用sklearn包的PolynomialFeatures()
3.2 文字特征编码
文字特征的处理常采用bag-of-words的方法,基本思想是采用单词出现的频率来表示一段文字,一般都如下三个步骤:
- 标记(Tokenizing):将一段文字(英文)按标点符号和空格进行分割,获取标记单词
- 计数(Counting):统计标记出现的频率
- 标准化(Normalizing):消除文字长度对标记重要性的影响
具体可调用sklearn包的CountVectorizer()和CountVectorizer()
4、特征选择
4.1 模型性能评估指标
特征选择的依据是模型性能的好坏,下面首先介绍分类模型的评估指标:
- 精确率(precision):TP / (TP+FP)
- 召回率(recall):TP / (TP+FN)
- 准确率(accuracy,ACC):(TP + TN) / (TP + TN + FP + FN)
- F1 Score:精准率和召回率的调和均值,2 / F1 = 1 / P + 1 / R
- True Positive Rate: TPR = TP / (TP+FN) → 将正例分对的概率
- Fales Positive Rate: FPR = FP / (FP+TN) → 将负例错分为正例的概率
- ROC曲线:在ROC空间中,每个点的横坐标是FPR,纵坐标是TPR,ROC曲线越靠近左上角,模型越好。ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变,解决类不平衡(class imbalance)的问题
- AUC:ROC曲线下的面积,AUC越接近1模型越好
对于回归问题的评估指标,常用的有:
- R2
- 平均绝对误差MAE(Mean Absolute Error):L1范数损失
- 平均平方误差MSE(Mean Squared Error):L2范数损失
除此以外,一些其他因素也值得考虑,如:
- 数据训练时间
- 数据预测时间
- 所需的计算机内存等
4.2 特征选择方法
(1)基于概率统计理论的特征选择
根据特征与预测目标的相关性系数挑选
from sklearn.base import TransformerMixin, BaseEstimator class CustomCorrelationChooser(TransformerMixin, BaseEstimator): def __init__(self, response, cols_to_keep=[], threshold=None): self.response = response self.threshold = threshold self.cols_to_keep = cols_to_keep def transform(self, X): return X[self.cols_to_keep] def fit(self, X, *_): df = pd.concat([X, self.response], axis=1) self.cols_to_keep = df.columns[df.corr()[df.columns[-1]].abs() > self.threshold] self.cols_to_keep = [c for c in self.cols_to_keep if c in X.columns] return self
采用不同假设检验方法挑选特征,如ANOVA、Chi2检验等
from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import f_classif k_best = SelectKBest(f_classif, k=5) k_best.fit_transform(X, y) p_values = pd.DataFrame({'column': X.columns, 'p_value': k_best.pvalues_}).sort_values('p_value') p_values[p_values['p_value'] < .05]
(2)基于机器学习模型的特征选择
一般的,基于概率统计理论的特征选择,在特征数量特别多的时候效果不是很好。
根据决策树一类模型的特征选择
from sklearn.feature_selection import SelectFromModel select_from_model = SelectFromModel(DecisionTreeClassifier(), threshold=.05) selected_X = select_from_model.fit_transform(X, y)
根据线性模型的特征选择,如线性回归、逻辑回归、支持向量机等,引入正则项能防止过拟合,提高模型泛化能力
- L1正则(lasso正则)
- L2正则(ridge正则)
from sklearn.feature_selection import SelectFromModel logistic_selector = SelectFromModel(LogisticRegression(penalty=l1), threshold=.05) selected_X = logistic_selector.fit_transform(X, y)
4.3 特征选择经验
如果大部分特征为类别特征,可采用Chi2检验或者决策树之类的模型进行选择
如果大部分特征为数值特征,可采用线性模型进行选择
如果为二分类问题,采用SelectFromModel()函数和支持向量机模型
有些情况下,也可进行探索性数据分析,手工选择特征,或根据专业知识选择特征
5、特征变换(Feature Transformation)
主成分分析(principal components analysis):sklearn包的PCA类
线性判别分析(linear discriminant analysis):sklearn包的LinearDiscriminantAnalysis类
PCA是从特征的协方差角度,希望主成分方向携带尽量多的信息量;而LDA则是在已知样本的类标注, 希望投影到新的基后使得不同的类别之间的数据点的距离更大,同一类别的数据点更紧凑。
6、特征学习(Feature Learning)
特征变换和特征学习均数据特征提起范畴,特征变换的PCA和LDA方法只能处理线性变换,且新的特征数量受限于输入特征数量;而特征学习则采用深度学习的方法,可以提取更复杂的特征。
受限玻尔兹曼机(Restricted Boltzmann Machine,RBM):包含两层的神经网络,可见层(visible layer)和隐藏层(hidden layer),可见层神经元数量等于输入的特征数,隐藏层神经元数量等于希望提取的特征数量,sklearn包的BernoulliRBM类
6.1 文字特征学习
Word2Vec
GloVe
转载请注明出处:http://blog.csdn.net/linxdcn/article/details/80866745