特征工程-特征选择--过滤法、包裹法、嵌入法/特征提取-PCA、LDA、SVD
数据分析的流程:
1 特征选择
2 模型、算法
3 评价指标
怎么做整理:一是从项目中,做一个项目总结一个方法;二是平常最常用的。
会飞的蜗牛:
6.22特征选择sklearn.feature_selection
首先根据客户需求(市场监督管理局),整理出一些指标。
1. 过滤法
1.1方差选择
方差表示离散程度,方差小表示特征值很稳定,没有太大变化,故可以选择方差大的特征来分析。
先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。使用feature_selection库的VarianceThreshold类来选择特征。
from sklearn.feature_selection import VarianceThreshold
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
sel.fit_transform(X) ##方差选择法,返回值为特征选择后的数据
def var():
var=VarianceThreshold(threshold=1.0)
data=var.fit_transform([[0,2,0,3],[0,1,4,3],[0,1,1,3]])
print(data)
return None
var()
1.2单变量特征选择
原理:分别单独的计算每个变量的某个统计指标,根据该指标来判断哪些指标重要,剔除那些不重要的指标。
A.分类(y离散):卡方检验、F检验、互信息
B.回归(y连续):相关系数、互信息
互信息:一个随机变量包含的关于另一个随机变量的信息量
或者说一个随机变量由于已知另一个随机变量而减少的不确定性。
SelectKBest 移除得分前 k 名以外的所有特征(取top k)
SelectPercentile 移除得分在用户指定百分比以后的特征(取top k%)
(1)卡方检验:
经典的卡方检验是检验定性自变量对定性因变量的相关性.
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
iris = load_iris()
X, y = iris.data, iris.target
X.shape
X_new = SelectKBest(chi2, k=2).fit_transform(X, y) ##选择了前2个特征
X_new.shape
(2)相关系数(距离相关系数)
Pearson相关系数的一个明显缺陷是,作为特征排序机制,他只对线性关系敏感。如果关系是非线性的,即便两个变量具有一一对应的关系,Pearson相关性也可能会接近0。
import numpy as np
from scipy.stats import pearsonr
np.random.seed(0)
size = 300
x = np.random.normal(0,1,size)
# pearsonr(x, y)的输入为特征矩阵和目标向量
print("Lower noise", pearsonr(x, x + np.random.normal(0, 1, size)))
print("Higher noise", pearsonr(x, x + np.random.normal(0, 10, size)))
(3)互信息及最大相关系数(MINE库安装失败)
互信息直接用于特征选择其实不是太方便(不太适用于连续变量,在不同数据集上无法比较),用最大信息系数去改进,它首先寻找一种最优的离散化方式,然后把互信息取值转换成一种度量方式,取值区间在[0,1]。
from minepy import MINE
m = MINE()
x = np.random.uniform(-1, 1, 10000)
m.compute_score(x, x**2)
print(m.mic())
(4)基于模型的特征排序
可以采用决策树、随机森林、SVM、LogisticRegression的方法,得到特征排序的重要性。
##波士顿房价数据 随机森林
from sklearn.model_selection import cross_val_score, ShuffleSplit
from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor
import numpy as np
# Load boston housing dataset as an example
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]
rf = RandomForestRegressor(n_estimators=20, max_depth=4)
scores = []
# 单独采用每个特征进行建模,并进行交叉验证
for i in range(X.shape[1]):
score = cross_val_score(rf, X[:, i:i+1], Y, scoring="r2",cv=ShuffleSplit(len(X), 3, .3))
# 注意X[:, i]shape(1,m)和X[:, i:i+1]的区别hape(m,1)
scores.append((format(np.mean(score), '.3f'), names[i]))
print(sorted(scores, reverse=True))
2.Wrapper(包裹法) 递归特征消除 (Recursive Feature Elimination)
递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,移除若干权值系数的特征,再基于新的特征集进行下一轮训练。
sklearn官方解释:对特征含有权重的预测模型(例如,线性模型对应参数coefficients),RFE通过递归减少考察的特征集规模来选择特征。首先,预测模型在原始特征上训练,每个特征指定一个权重。之后,那些拥有最小绝对值权重的特征被踢出特征集。如此往复递归,直至剩余的特征数量达到所需的特征数量。
RFECV 通过交叉验证的方式执行RFE,以此来选择最佳数量的特征:对于一个数量为d的feature的集合,他的所有的子集的个数是2的d次方减1(包含空集)。指定一个外部的学习算法,比如SVM之类的。通过该算法计算所有子集的validation error。选择error最小的那个子集作为所挑选的特征
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
iris = load_iris()
#递归特征消除法,返回特征选择后的数据
#递归特征消除法
#递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。使用feature_selection库的RFE类来选择特征的代码如下:
#参数estimator为基模型
#参数n_features_to_select为选择的特征个数7
#print(iris.data[0:5])
print(iris.data[0:5])
print(iris.target[0:5])
print("-----------------------------------")
selector = RFE(estimator=LogisticRegression(), n_features_to_select=2).fit(iris.data, iris.target)
data = selector.transform(iris.data)
print(data[0:5])
print("-----------------------------------")
print(selector.ranking_)
3 Embedding(嵌入法)
3.1使用SelectFromModel选择特征 (Feature selection using SelectFromModel)
基于机器学习模型的方法。有些机器学习方法本身就具有对特征进行打分的机制,或者很容易将其运用到特征选择任务中,例如回归模型,SVM,决策树,随机森林等等。其实Pearson相关系数等价于线性回归里的标准化回归系数。
3.1.1 基于L1的特征选择 (L1-based feature selection)
使用L1范数作为惩罚项的线性模型(Linear models)会得到稀疏解:大部分特征对应的系数为0。当你希望减少特征的维度以用于其它分类器时,可以通过 feature_selection.SelectFromModel 来选择不为0的系数。特别指出,常用于此目的的稀疏预测模型有 linear_model.Lasso(lasso回归), linear_model.LogisticRegression(逻辑回归)和 svm.LinearSVC(SVM支持向量机)
##对于SVM和逻辑回归,参数C控制稀疏性:C越小,被选中的特征越少。对于Lasso,参数alpha越大,被选中的特征越少。
from sklearn.svm import LinearSVC ##SVM
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
X.shape
# (150, 4)
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y)
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
X_new.shape
#(150, 3)
3.1.2 随机稀疏模型 (Randomized sparse models)
基于L1的稀疏模型的局限在于,当面对一组互相关的特征时,它们只会选择其中一项特征。为了减轻该问题的影响可以使用随机化技术,通过_多次重新估计稀疏模型来扰乱设计矩阵_,或通过_多次下采样数据来统计一个给定的回归量被选中的次数_。
RandomizedLasso实现了使用这项策略的Lasso,RandomizedLogisticRegression 使用逻辑回归,适用于分类任务。要得到整个迭代过程的稳定分数,你可以使用 lasso_stability_path
3.1.3基于树的特征选择
基于树的预测模型(见 sklearn.tree 模块,森林见 sklearn.ensemble 模块)能够用来计算特征的重要程度,因此能用来去除不相关的特征(结合 sklearn.feature_selection.SelectFromModel):
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
X.shape # (150, 4)
clf = ExtraTreesClassifier()
clf = clf.fit(X, y)
clf.feature_importances_
#array([ 0.04..., 0.05..., 0.4..., 0.4...])
model = SelectFromModel(clf, prefit=True)
X_new = model.transform(X)
X_new.shape #(150, 2)
4.Embedding将特征选择过程融入pipeline (Feature selection as part of a pipeline)
特征选择常常被当作学习之前的一项预处理。在scikit-learn中推荐使用sklearn.pipeline.Pipeline:
clf = Pipeline([
('feature_selection', SelectFromModel(LinearSVC(penalty="l1"))),
('classification', RandomForestClassifier())
])
clf.fit(X, y)
在此代码片段中,将 sklearn.svm.LinearSVC 和 sklearn.feature_selection.SelectFromModel 结合来评估特征的重要性,并选择最相关的特征。之后 sklearn.ensemble.RandomForestClassifier 模型使用转换后的输出训练,即只使用被选出的相关特征。你可以选择其它特征选择方法,或是其它提供特征重要性评估的分类器。更多详情见 sklearn.pipeline.Pipeline 相关示例。
二、特征提取方法--PCA、LDA、SVD
PCA和LDA都是用来降维的,适用于高斯分布的数据
LDA:https://www.cnblogs.com/simon-c/p/5023726.html
https://blog.csdn.net/weixin_41637300/article/details/84591348
https://blog.csdn.net/z962013489/article/details/79918758?utm_source=blogxgwz9
https://blog.csdn.net/u013719780/article/details/78312165
https://blog.csdn.net/qq_41398808/article/details/92440569
https://blog.csdn.net/z962013489/article/details/79871789?utm_source=blogxgwz5
https://nbviewer.jupyter.org/github/csuldw/MachineLearning/blob/master/LDA/lda.ipynb
SVD:https://www.cnblogs.com/endlesscoding/p/10033527.html