数据挖掘-特征工程

特征工程,看图说话:

1.数据预处理

使用鸢尾花的数据集:

#coding=gbk
#特征工程
#IRIS数据集由Fisher在1936年整理,包含4个特征
# (Sepal.Length(花萼长度)、Sepal.Width(花萼宽度)、Petal.Length(花瓣长度)、Petal.Width(花瓣宽度)),
# 特征值都为正浮点数,单位为厘米。
# 目标值为鸢尾花的分类(Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾),Iris Virginica(维吉尼亚鸢尾))
import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
print(iris.data.shape)#(150, 4)
print(iris.target[:5])  # [0 0 0 0 0]
print(iris.target[49:52])# [0 1 1]
print(iris.data[:5])
# [[5.1 3.5 1.4 0.2]
#  [4.9 3.  1.4 0.2]
#  [4.7 3.2 1.3 0.2]
#  [4.6 3.1 1.5 0.2]
#  [5.  3.6 1.4 0.2]]

1.1无量纲化:

无量纲化使不同规格的数据转换到同一规格。常见的无量纲化方法有标准化和区间缩放法。标准化的前提是特征值服从正态分布,标准化后,其转换成标准正态分布。区间缩放法利用了边界值信息,将特征的取值区间缩放到某个特点的范围,例如[0, 1]等。

标准化,计算特征数值得方差和均值:

from sklearn.preprocessing import StandardScaler
iris_standard = StandardScaler().fit_transform(iris.data)
print(iris_standard[:5])
# [[-0.90068117  1.03205722 -1.3412724  -1.31297673]
#  [-1.14301691 -0.1249576  -1.3412724  -1.31297673]
#  [-1.38535265  0.33784833 -1.39813811 -1.31297673]
#  [-1.50652052  0.10644536 -1.2844067  -1.31297673]
#  [-1.02184904  1.26346019 -1.3412724  -1.31297673]]

最小值最大值规范化:

from sklearn.preprocessing import MinMaxScaler
iris_minmax = MinMaxScaler().fit_transform(iris.data)
print(iris_minmax[:5])
# [[0.22222222 0.625      0.06779661 0.04166667]
#  [0.16666667 0.41666667 0.06779661 0.04166667]
#  [0.11111111 0.5        0.05084746 0.04166667]
#  [0.08333333 0.45833333 0.08474576 0.04166667]
#  [0.19444444 0.66666667 0.06779661 0.04166667]]

正则化 Normalizer类:

from sklearn.preprocessing import Normalizer
iris_normalizer = Normalizer().fit_transform(iris.data)
print(iris_normalizer[:5])
# [[0.80377277 0.55160877 0.22064351 0.0315205 ]
#  [0.82813287 0.50702013 0.23660939 0.03380134]
#  [0.80533308 0.54831188 0.2227517  0.03426949]
#  [0.80003025 0.53915082 0.26087943 0.03478392]
#  [0.790965   0.5694948  0.2214702  0.0316386 ]]

scale 和 Normalizer类,StandardScaler

import numpy as np
from sklearn.preprocessing import StandardScaler, scale, Normalizer, normalize
X = np.array([[ 1., -1.,  2.],[ 2.,  0.,  0.],[ 0.,  1., -1.]])
print(X)
print(np.mean(X, axis=0)) #计算每列的平均值
print(np.std(X, axis=0))
# [1.         0.         0.33333333]
# [0.81649658 0.81649658 1.24721913]

scale_X = scale(X)
print(scale_X)
print(np.mean(scale_X, axis=0)) #scale 类将每列的数转换为方差为1, 均值为0 的标准正态分布
print(np.std(scale_X, axis=0))
# [0. 0. 0.]
# [1. 1. 1.]

stand_X = StandardScaler().fit_transform(X)
print(stand_X)
print(np.mean(stand_X, axis=0))
print(np.std(stand_X, axis=0))
print(np.var(stand_X, axis=0))
# [0. 0. 0.]
# [1. 1. 1.]

nor_X = Normalizer(norm='l1').fit_transform(X)  #正则化,只能按行进行操作
print(X)
# [[ 1. -1.  2.]
#  [ 2.  0.  0.]
#  [ 0.  1. -1.]]
print(nor_X)
# [[ 0.25 -0.25  0.5 ]
#  [ 1.    0.    0.  ]
#  [ 0.    0.5  -0.5 ]]

nor_x = normalize(X, norm='l1', axis=1)   #按行进行操作
print(nor_x)
# [[ 0.25 -0.25  0.5 ]
#  [ 1.    0.    0.  ]
#  [ 0.    0.5  -0.5 ]]
nor_y = normalize(X, norm='l1', axis=0) #按列进行操作
print(nor_y)
# [[ 0.33333333 -0.5         0.66666667]
#  [ 0.66666667  0.          0.        ]
#  [ 0.          0.5        -0.33333333]]

 l1计算:x^* = \frac{x_i}{\sum_{i=1}^{n}\left | x_i \right |}

l2计算:x^* = \frac{x_i}{\sqrt{\sum_{i=1}^{n}\left | x_i \right |^2}}

1.2对定量特征二值化;

#对定量特征二值化,将数值型特征转换成类别型特征,大于阈值的为1
from sklearn.preprocessing import Binarizer
iris_binarizer = Binarizer(threshold=3).fit_transform(iris.data)
print(iris_binarizer[:5])#设置阈值为3
# [[1. 1. 0. 0.]
#  [1. 0. 0. 0.]
#  [1. 1. 0. 0.]
#  [1. 1. 0. 0.]
#  [1. 1. 0. 0.]]

对定性特征进行哑变量编码,由于其输入需要是2为数组,所以需要reshape

from sklearn.preprocessing import OneHotEncoder
iris_onehot = OneHotEncoder(sparse=False).fit_transform(iris.target.reshape((-1,1)))
print(iris_onehot[:5])
# [[1. 0. 0.]
#  [1. 0. 0.]
#  [1. 0. 0.]
#  [1. 0. 0.]
#  [1. 0. 0.]]

缺失值处理:


from numpy import array, vstack, NaN
from sklearn.preprocessing import Imputer
nan = array([NaN]*4)
new_iris_data = vstack((iris.data, nan))
print(new_iris_data[-1]) #[nan nan nan nan]
iris_imputer = Imputer(strategy='mean').fit_transform(new_iris_data)
# strategies: ['mean', 'median', 'most_frequent']只有3种选择均值,中位数,众数
print(iris_imputer[-1])#[5.84333333 3.054      3.75866667 1.19866667]默认对空值变为均值

 

x* = (x - μ ) / σ

其中μ为所有样本数据的均值,σ为所有样本数据的标准差。

z-score 标准化:z-score标准化方法适用于属性A的最大值和最小值未知的情况,或有超出取值范围的离群数据的情况。该种标准化方式要求原始数据的分布可以近似为高斯分布,否则效果会变得很糟糕。

1、在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,(Z-score standardization)表现更好。

2、在不涉及距离度量、协方差计算、数据不符合正态分布的时候,可以使用最大最小值规范化方法或其他归一化方法。比如图像处理中,将RGB图像转换为灰度图像后将其值限定在[0 255]的范围。
原因是使用第一种方法(线性变换后),其协方差产生了倍数值的缩放,因此这种方式无法消除量纲对方差、协方差的影响,对PCA分析影响巨大;同时,由于量纲的存在,使用不同的量纲、距离的计算结果会不同。而在第二种归一化方式中,新的数据由于对方差进行了归一化,这时候每个维度的量纲其实已经等价了,每个维度都服从均值为0、方差1的正态分布,在计算距离的时候,每个维度都是去量纲化的,避免了不同量纲的选取对距离计算产生的巨大影响。

log函数转换

通过以10为底的log函数转换的方法同样可以实现归一下,具体方法如下:

看了下网上很多介绍都是x*=log10(x),其实是有问题的,这个结果并非一定落到[0,1]区间上,应该还要除以log10(max),max为样本数据最大值,并且所有的数据都要大于等于1。

from:https://blog.csdn.net/pipisorry/article/details/52247379

 

功能说明
StandardScaler无量纲化标准化,基于特征矩阵的列,将特征值转换至服从标准正态分布
MinMaxScaler无量纲化区间缩放,基于最大最小值,将特征值转换到[0, 1]区间上
Normalizer归一化基于特征矩阵的行,将样本向量转换为“单位向量”
Binarizer二值化基于给定阈值,将定量特征按阈值划分
OneHotEncoder哑编码将定性数据编码为定量数据
Imputer缺失值计算计算缺失值,缺失值可填充为均值等
PolynomialFeatures多项式数据转换多项式数据转换
FunctionTransformer自定义单元数据转换使用单变元的函数来转换数据

2.特征选择

当数据预处理完成后,我们需要选择有意义的特征输入机器学习的算法和模型进行训练。通常来说,从两个方面考虑来选择特征:

  • 特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。
  • 特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优选选择。

  根据特征选择的形式又可以将特征选择方法分为3种:

  • Filter:过滤法,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征。
  • Wrapper:包装法,根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。
  • Embedded:嵌入法,先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。类似于Filter方法,但是是通过训练来确定特征的优劣。

from:http://www.cnblogs.com/jasonfreak/p/5448385.html

1.过滤法:

方差选择法:

from sklearn.feature_selection import VarianceThreshold
#返回的是选择后的特征数据,阈值是方差值
iris_data = VarianceThreshold(threshold=1)
iris_variance = iris_data.fit_transform(iris.data)
print(iris_data.variances_) #[0.68112222 0.18675067 3.09242489 0.57853156]打印出4种特征的方差
print(iris_variance.shape) #(150, 1) 可以看出,当方差阈值为1时,只选择第3个特征

相关系数法:

#相关系数:计算每个特征与目标特征的相关系数及其p值,依据皮尔森系数
from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr
print(iris.data.shape)#(150, 4)
def multivariate_pearsonr(X, y):
    scores, p_values = [], []
    for column in range(iris.data.shape[1]):
        score, p_value = pearsonr(X[:, column], y)
        scores.append(score)
        p_values.append(p_value)
    return np.array(scores), np.array(p_values)

transform = SelectKBest(score_func=multivariate_pearsonr,k=2)
iris_per = transform.fit_transform(iris.data, iris.target)
print(transform.scores_) #[ 0.78256123 -0.4194462   0.94904254  0.95646382]打印出评分,选择了后2个特征
print(iris_per[:3])
# [[1.4 0.2]
#  [1.4 0.2]
#  [1.3 0.2]]

卡方检验法:

#依据卡方检验,chi2
from sklearn.feature_selection import SelectKBest, chi2
transform_chi = SelectKBest(chi2, k=2)
iris_chi = transform_chi.fit_transform(iris.data, iris.target)
print(transform_chi.scores_)#[ 10.81782088   3.59449902 116.16984746  67.24482759]
print(iris_chi[:3])#同样得到最后2列对目标函数的相关性比较大
# [[1.4 0.2]
#  [1.4 0.2]
#  [1.3 0.2]]

2、Wrapper包装法

递归特征消除法,递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。
#和方差选择法一样, 可能使用RFE 后, 会造成模型的性能下降,预测精度也随之降低,需要谨慎使用

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
transform_rfe = RFE(estimator=LogisticRegression(), n_features_to_select =2)
iris_rfe = transform_rfe.fit_transform(iris.data, iris.target)
print(iris_rfe[:3])
# [[3.5 0.2]#与上述的chi2, 和personr都不同
#  [3.  0.2]
#  [3.2 0.2]]
#一些参数
print("N_features %s" % transform_rfe.n_features_) # 保留的特征数 N_features 2
print("Support is %s" % transform_rfe.support_) # 是否保留 Support is [False  True False  True]
print("Ranking %s" % transform_rfe.ranking_) # 重要程度排名  Ranking [3 1 2 1]
  • RFECV通过交叉验证来找到最优的特征数量。如果减少特征会造成性能损失,那么将不会去除任何特征。这个方法用以选取单模型特征相当不错,但是有两个缺陷,一,计算量大。二,随着学习器(评估器)的改变,最佳特征组合也会改变,有些时候会造成不利影响。

使用交叉验证来保留最佳性能的特征。不过这里的交叉验证的数据集切割对象不再是 行数据(样本),而是列数据(特征),同时学习器本身不变,最终得到不同特征对于score的重要程度,然后保留最佳的特征组合。其分割方式类似于随机森林中的列上子采样。

from sklearn.feature_selection import RFECV
transform_cv = RFECV(estimator=LogisticRegression(), cv=3) #step : 整数时,每次去除的特征个数,小于1时,每次去除权重最小的特征,cv表示几折
iris_cv = transform_cv.fit_transform(iris.data, iris.target)
print("N_features %s" % transform_cv.n_features_) # 保留的特征数 N_features 3
print("Support is %s" % transform_cv.support_) # 是否保留 Support is [False  True  True  True]
print("Ranking %s" % transform_cv.ranking_) # 重要程度排名  Ranking [2 1 1 1]
print(transform_cv.grid_scores_)#[0.85457516 0.90727124 0.95424837 0.94689542]

 3 Embedded 嵌入法

使用SelectFromModel选择特征 (Feature selection using SelectFromModel)

  单变量特征选择方法独立的衡量每个特征与响应变量之间的关系,另一种主流的特征选择方法是基于机器学习模型的方法。有些机器学习方法本身就具有对特征进行打分的机制,或者很容易将其运用到特征选择任务中,例如回归模型,SVM,决策树,随机森林等等。其实Pearson相关系数等价于线性回归里的标准化回归系数。

  SelectFromModel 作为meta-transformer,能够用于拟合后任何拥有coef_feature_importances_ 属性的预测模型。 如果特征对应的coef_ 或 feature_importances_ 值低于设定的阈值threshold,那么这些特征将被移除。除了手动设置阈值,也可通过字符串参数调用内置的启发式算法(heuristics)来设置阈值,包括:平均值(“mean”), 中位数(“median”)以及他们与浮点数的乘积,如”0.1*mean”。

1.基于L1的特征选择:

#3.1 基于惩罚项的特征选择法
#使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。
# 使用feature_selection库的SelectFromModel类结合带L1惩罚项的逻辑回归模型,来选择特征
#基于L1的特征选择
from sklearn.svm import LinearSVC
from sklearn.feature_selection import SelectFromModel
iris_l1 = SelectFromModel(LinearSVC(C=0.01, penalty='l1', dual=False)).fit_transform(iris.data, iris.target)
print(iris_l1[:3])
# [[5.1 3.5 1.4]
#  [4.9 3.  1.4]
#  [4.7 3.2 1.3]]

# 对于SVM和逻辑回归,参数C控制稀疏性:C越小,被选中的特征越少。对于Lasso,参数alpha越大,被选中的特征越少。

 2基于树模型的特征选择法,使用树模型中GBDT模型作为特征选择:

from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier
iris_gb = SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
print(iris_gb[:3])
# [[1.4 0.2]# 选择后2个特征
#  [1.4 0.2]
#  [1.3 0.2]]

3.降维

PCA和LDA有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样:PCA是为了让映射后的样本具有最大的发散性;而LDA是为了让映射后的样本有最好的分类性能。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。

降维:当特征选择完成后,可以直接训练模型了,但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。


主成分分析法PCA:


from sklearn.decomposition import PCA
iris_pca = PCA(n_components=2).fit_transform(iris.data)#参数为主成分的数目
print(iris_pca[:3])
# [[-2.68420713  0.32660731]
#  [-2.71539062 -0.16955685]
#  [-2.88981954 -0.13734561]]

线性判别分析法(LDA)


from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
iris_lda = LDA(n_components=2).fit_transform(iris.data, iris.target)
print(iris_lda[:3])
# [[-8.0849532   0.32845422]
#  [-7.1471629  -0.75547326]
#  [-7.51137789 -0.23807832]]

连续特征的离散化处理
        1.常用的方法是根据阈值进行分组:如设置0-0.3为低,0.3-0.7为中,0.7-1为高
        2.高级的方法,比如使用GBDT,先将连续值转换成离散值,然后使用独热编码。

print('test gbdt')
# 对于一个矩阵而言,若数值为零的元素远远多于非零元素的个数,且非零元素分布没有规律时,这样的矩阵被称作稀疏矩阵;
# 与之相反,若非零元素数目占据绝大多数时,这样的矩阵被称作稠密矩阵。
#使用GDBT 把连续值转换成离散值
from sklearn.datasets import make_classification
from sklearn.preprocessing import OneHotEncoder
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
X, y = make_classification(n_samples=10)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)
# print(X_train)
one_hot = OneHotEncoder()
gbc = GradientBoostingClassifier(n_estimators=2)
gbc.fit(X_train, y_train)
X_train_new = one_hot.fit_transform(gbc.apply(X_train)[:, :, 0])
print(X_train_new)
#   (0, 3)    1.0
#   (0, 1)    1.0
#   (1, 3)    1.0
#   (1, 1)    1.0
#   (2, 2)    1.0
#   (2, 0)    1.0
#   (3, 2)    1.0
#   (3, 0)    1.0
#   (4, 3)    1.0
#   (4, 1)    1.0
print(X_train_new.todense())
# [[0. 1. 0. 1.]
#  [0. 1. 0. 1.]
#  [1. 0. 1. 0.]
#  [1. 0. 1. 0.]
#  [0. 1. 0. 1.]]

print('测试稀疏矩阵')
# .CSR(Compressed Sparse Row):稀疏矩阵用非零值的三个一维数组、行的范围和列索引表示;
# 通过调用csr_matrix()函数,可以使用CSR表示将存储在Numpy数组中的稠密矩阵转换为稀疏矩阵。
from scipy.sparse import csr_matrix
A = np.array([[1,0,0,1,0,0], [0,0,2,0,0,1], [0,0,0,2,0,0]])
print(A)
# [[1 0 0 1 0 0]
#  [0 0 2 0 0 1]
#  [0 0 0 2 0 0]]
s = csr_matrix(A)
print(s)
#   (0, 0)    1
#   (0, 3)    1
#   (1, 2)    2
#   (1, 5)    1
#   (2, 3)    2
B = s.todense()
# 调用todense()函数将其转换回密集数组。
print(B)
# [[1 0 0 1 0 0]
#  [0 0 2 0 0 1]
#  [0 0 0 2 0 0]]

参考:http://www.cnblogs.com/jasonfreak/p/5448385.html

           http://scikit-learn.org/stable/modules/feature_selection.html

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据挖掘是指从大量数据中发掘出有用的信息和知识的过程,而特征工程则是在数据挖掘中的一个关键步骤。特征工程是指通过对原始数据进行预处理、特征选择、特征变换等方法,提取出适合用于数据挖掘算法建模的特征。 在数据挖掘任务中,特征工程非常重要。一个好的特征工程可以帮助我们更好地发现模型中的规律和关联。而在特征工程中,CSDN(中国最大的IT社区)提供了大量的资源和教程,可以帮助我们理解和应用各种特征工程的方法和技巧。 在CSDN中,我们可以找到关于特征选择、特征提取、特征构造等方面的技术文章和教程。这些文章和教程详细介绍了各种常用的特征工程方法和算法,如主成分分析、线性判别分析、信息增益、互信息等。同时,CSDN还提供了一些常用的特征工程工具,如sklearn、pandas等,方便我们在实际应用中进行特征工程处理。 通过CSDN的学习和实践,我们可以更好地了解特征工程的重要性,学习到各种特征工程的方法和技巧,并能够灵活应用到实际的数据挖掘任务中。在实践中,我们可以根据不同的数据集和任务需求,选择合适的特征工程方法,处理原始数据,提取有用的特征,为后续的模型构建和分析做好准备。 总之,CSDN为我们提供了丰富的特征工程资源和技术支持,通过学习和应用这些资源,我们可以在数据挖掘中更好地进行特征工程,提高模型的准确性和效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值