当前位置:   article > 正文

sklearn的特征抽取和特征筛选_sklearn实现特征筛选

sklearn实现特征筛选

数据分析过程中,往往需要处理很多类型的数据,数值型和非数值型,无论是在回归问题还是分类问题中,特征工程都是重中之重。
我们都知道,特征值和特征向量在高等数学和线性代数中极为关键,特征工程,从表面上来说,就是从大大小小的数据中,筛选出有意义或者有用的条目,进而转换成一种数学表达,让机器和算法能够理解其中的意义。好比一个班上的每个学生,都有性别、年龄、身高、体重、成绩、性格特点等等特征,年龄、身高、体重、成绩属于数值型的特征,可以直接为我们所用,性别、性格特点属于非数值型特征,需要通过转换才能被算法理解。
python的sklearn包,包含了特征工程常用的工具和api,主要有以下几个方面:

特征抽取

sklearn.feature_extraction:包含了常用的用于特征抽取的api

  • DictVectorizer(dtype=<class ‘numpy.float64’>, separator=’=’, sparse=True, sort=True)
    通过字典传入抽取特征,用于将标签型或非数值型数据的抽取和转换,sparse参数表示是否转换为稀疏矩阵
    >>> from sklearn.feature_extraction import DictVectorizer
    >>> v = DictVectorizer(sparse=False)
    >>> D = [{'foo': 1, 'bar': 2}, {'foo': 3, 'baz': 1}]
    >>> X = v.fit_transform(D)
    >>> X
    array([[2., 0., 1.],
           [0., 1., 3.]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • FeatureHasher(n_features=1048576, input_type=’dict’, dtype=<class ‘numpy.float64’>, alternate_sign=True)
    将输入转换为hash矩阵,n_features为特征的列数,也就是特征维数,input_type为输入的python数据类型,通常用于处理特征的维度较大的问题。
    >>> from sklearn.feature_extraction import FeatureHasher
    >>> h = FeatureHasher(n_features=10)
    >>> D = [{'dog': 1, 'cat':2, 'elephant':4},{'dog': 2, 'run': 5}]
    >>> f = h.transform(D)
    >>> f.toarray()
    array([[ 0.,  0., -4., -1.,  0.,  0.,  0.,  0.,  0.,  2.],
           [ 0.,  0.,  0., -2., -5.,  0.,  0.,  0.,  0.,  0.]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • image
    从图像中直接抽取特征
    • image.extract_patches_2d(image, patch_size, max_patches=None, random_state=None)
      从二维图像中抽取特征,patch_size为输出的色块或图像块的维度,是一个二维元祖,max_patches表示最大的色块维度,random_state表示当max_patches不为none时,是否采用随机数采样填充色块的值。输出的每个图像块均为一个RGB三通道构成
    	>>> from sklearn.datasets import load_sample_image
    	>>> from sklearn.feature_extraction import image
    	>>> # Use the array data from the first image in this dataset:
    	>>> one_image = load_sample_image("china.jpg")
    	>>> print('Image shape: {}'.format(one_image.shape))
    	Image shape: (427, 640, 3)
    	>>> patches = image.extract_patches_2d(one_image, (2, 2))
    	>>> print('Patches shape: {}'.format(patches.shape))
    	Patches shape: (272214, 2, 2, 3)
    	>>> # Here are just two of these patches:
    	>>> print(patches[1]) 
    	[[[174 201 231]
    	  [174 201 231]]
    	 [[173 200 230]
    	  [173 200 230]]]
    	>>> print(patches[800])
    	[[[187 214 243]
    	  [188 215 244]]
    	 [[187 214 243]
    	  [188 215 244]]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • image.grid_to_graph(n_x, n_y, n_z=1, mask=None, return_as=<class ‘scipy.sparse.coo.coo_matrix’>, dtype=<class ‘int’>)
    • image.img_to_graph(img, mask=None, return_as=<class ‘scipy.sparse.coo.coo_matrix’>, dtype=None)
      图像转换为连通图矩阵
    • image.reconstruct_from_patches_2d(patches, image_size)
      用图像块矩阵构造图片
    • image.PatchExtractor(patch_size=None, max_patches=None, random_state=None)
      同extract_patches_2d,用法不同
      >>> from sklearn.datasets import load_sample_images
      >>> from sklearn.feature_extraction import image
      >>> # Use the array data from the second image in this dataset:
      >>> X = load_sample_images().images[1]
      >>> print('Image shape: {}'.format(X.shape))
      Image shape: (427, 640, 3)
      >>> pe = image.PatchExtractor(patch_size=(2, 2))
      >>> pe_fit = pe.fit(X)
      >>> pe_trans = pe.transform(X)
      >>> print('Patches shape: {}'.format(pe_trans.shape))
      Patches shape: (545706, 2, 2)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
  • text
    • text.CountVectorizer(input=’content’, encoding=’utf-8’, decode_error=’strict’, strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, stop_words=None, token_pattern=’(?u)\b\w\w+\b’, ngram_range=(1, 1), analyzer=’word’, max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False, dtype=<class ‘numpy.int64’>)
      根据词典,矢量词频统计
    	>>> from sklearn.feature_extraction.text import CountVectorizer
    	>>> corpus = [
    	...     'This is the first document.',
    	...     'This document is the second document.',
    	...     'And this is the third one.',
    	...     'Is this the first document?',
    	... ]
    	>>> vectorizer = CountVectorizer()
    	>>> X = vectorizer.fit_transform(corpus)
    	>>> print(vectorizer.get_feature_names())
    	['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
    	>>> print(X.toarray())  
    	[[0 1 1 1 0 0 1 0 1]
    	 [0 2 0 1 0 1 1 0 1]
    	 [1 0 0 1 1 0 1 1 1]
    	 [0 1 1 1 0 0 1 0 1]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • text.HashingVectorizer(input=’content’, encoding=’utf-8’, decode_error=’strict’, strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, stop_words=None, token_pattern=’(?u)\b\w\w+\b’, ngram_range=(1, 1), analyzer=’word’, n_features=1048576, binary=False, norm=’l2’, alternate_sign=True, dtype=<class ‘numpy.float64’>)
      矢量词频统计,词典自动生成
    	>>> from sklearn.feature_extraction.text import HashingVectorizer
    	>>> corpus = [
    	...     'This is the first document.',
    	...     'This document is the second document.',
    	...     'And this is the third one.',
    	...     'Is this the first document?',
    	... ]
    	>>> vectorizer = HashingVectorizer(n_features=2**4)
    	>>> X = vectorizer.fit_transform(corpus)
    	>>> print(X.shape)
    	(4, 16)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • text.TfidfTransformer(norm=’l2’, use_idf=True, smooth_idf=True, sublinear_tf=False)

    • text.TfidfVectorizer(input=’content’, encoding=’utf-8’, decode_error=’strict’, strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, analyzer=’word’, stop_words=None, token_pattern=’(?u)\b\w\w+\b’, ngram_range=(1, 1), max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False, dtype=<class ‘numpy.float64’>, norm=’l2’, use_idf=True, smooth_idf=True, sublinear_tf=False)

特征筛选

sklearn.feature_selection,包含了特征筛选所用的api

  • GenericUnivariateSelect(score_func=, mode=’percentile’, param=1e-05)
    单变量筛选器,score_func为评价函数,mode为筛选策略,主要有{‘percentile’, ‘k_best’, ‘fpr’, ‘fdr’, ‘fwe’}几种,具体有什么意义见下文。param筛选策略的参数。

    >>> from sklearn.datasets import load_breast_cancer
    >>> from sklearn.feature_selection import GenericUnivariateSelect, chi2
    >>> X, y = load_breast_cancer(return_X_y=True)
    >>> X.shape
    (569, 30)
    >>> transformer = GenericUnivariateSelect(chi2, 'k_best', param=20)
    >>> X_new = transformer.fit_transform(X, y)
    >>> X_new.shape
    (569, 20)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    评价函数分为以下几种:

    • f_classif
      方差分析中f值,也就是通常说的F检验,主要用于判断两个样本之间方差是否存在明显差异,主要用于特征对类别(标记)的分类任务中
    • mutual_info_classif
      变量和目标值之间的互信息,用于分类任务,计算公式如下。互信息是一种有用的信息度量,它可以看成是一个随机变量中包含的关于另一个随机变量的信息量,或者说是一个随机变量由于已知另一个随机变量而减少的不肯定性。
      在这里插入图片描述
    • chi2
      卡方检验,主要用于分类任务中
    • f_regression
      特征和类别(标记)的F值,主要用于回归分析
    • mutual_info_regression
      互信息,用于目标值为连续变量(非标记或类别)的分类任务。
  • SelectPercentile(score_func=, percentile=10)
    基于评价函数结果的百分位数来筛选特征,score_func为评价函数,percentile是百分比。例如选择卡方检验,选择10百分数,则输出结果会筛选出卡方检验值的前10%的特征作出输出特征。

    >>> from sklearn.datasets import load_digits
    >>> from sklearn.feature_selection import SelectPercentile, chi2
    >>> X, y = load_digits(return_X_y=True)
    >>> X.shape
    (1797, 64)
    >>> X_new = SelectPercentile(chi2, percentile=10).fit_transform(X, y)
    >>> X_new.shape
    (1797, 7)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • SelectKBest(score_func=, k=10)
    基于评价函数结果筛选出最高的前K个特征

  • SelectFpr(score_func=, alpha=0.05)
    基于特征的假正率测试,筛选特征。假正率=被模型预测为正的负样本/(被模型预测为正的负样本+被模型预测为负的负样本),具体如下,主要用于二分类任务。score_func为评价函数,默认为f_classif,alpha评价函数的p值的上限值。


    预正预负
    实正真正(TP)假负(FN)
    实负假正(FP)正负(TN))
    • True Positive Rate(真正率 , TPR)或灵敏度(sensitivity)
      TPR = TP /(TP + FN)
      正样本预测结果数 / 正样本实际数
    • True Negative Rate(真负率 , TNR)或特指度(specificity)
      TNR = TN /(TN + FP)
      负样本预测结果数 / 负样本实际数
    • False Positive Rate (假正率, FPR)
      FPR = FP /(FP + TN)
      被预测为正的负样本结果数 /负样本实际数
    • False Negative Rate(假负率 , FNR)
      FNR = FN /(TP + FN)
      被预测为负的正样本结果数 / 正样本实际数
  • SelectFdr(score_func=, alpha=0.05)
    基于错误发现率(fdr)进行特征筛选,定义是错误拒绝(拒绝真的原假设)的个数占所有被拒绝的原假设个数的比例的期望值。通俗一点理解,就是实际为负的那部分样本中,通过特征计算得出的为负的样本所占的比例。alpha为p值的上限值。同样用于二分类任务

  • SelectFwe(score_func=, alpha=0.05)
    基于总Ⅰ型错误率筛选特征,关于FDR和FWE的知识,可参考链接

  • SelectFromModel(estimator, threshold=None, prefit=False, norm_order=1, max_features=None)
    基于模型选择特征,简单理解就是先采用模型对每个特征进行一次分类或回归任务,通过错误率或者误差筛选特征,estimator为评价器,也就是回归或分类模型,必须带有特征权重feature_importances_或者系数coef_;threshold为阈值,特征的权重大于或等于阈值的将会保留,否则就会被剔除;prefit是否直接fit筛选器;norm_order:规定的系数的个数;max_features=最大筛选特征量。

  • RFE(estimator, n_features_to_select=None, step=1, verbose=0)
    递归筛选特征,给定一个带权重或系数的评价器,RFE会对权重进行排序,首先对所有特征进行评价计算,进行迭代计算,每次迭代计算筛选出step个权重或系数最小的特征,直到剩余的特征数等于n_features_to_select。verbose用于是否输出过程。

    >>> from sklearn.datasets import make_friedman1
    >>> from sklearn.feature_selection import RFE
    >>> from sklearn.svm import SVR
    >>> X, y = make_friedman1(n_samples=50, n_features=10, random_state=0)
    >>> estimator = SVR(kernel="linear")
    >>> selector = RFE(estimator, 5, step=1)
    >>> selector = selector.fit(X, y)
    >>> selector.support_ 
    array([ True,  True,  True,  True,  True, False, False, False, False,
           False])
    >>> selector.ranking_
    array([1, 1, 1, 1, 1, 6, 4, 3, 2, 5])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • RFECV(estimator, step=1, min_features_to_select=1, cv=’warn’, scoring=None, verbose=0, n_jobs=None)
    同RFE,加入了交叉验证的过程。

  • VarianceThreshold(threshold=0.0)
    方差阈值筛选,threshold是方差的阈值

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/988815
推荐阅读
  

闽ICP备14008679号