特征
 
什么是特征:
 
举个例子:一个妹子很好看,好看的在哪里?腿长(特征1),白(特征2),性格开朗(特征3)
 
那么可以概括为好看妹子的特征是[腿长,白,性格开朗]
 
特征类型:
 
 
 •  
 相关特征:对于学习任务(例如分类问题)有帮助,可以提升学习算法的效果 
 
  比如:腿长,白 
 
 
 •  
 无关特征:对于我们的算法没有任何帮助,不会给算法的效果带来任何提升 
 
 
 比如:性格好(性格好的妹子不一定好看,好看的妹子不一定性格好) 
 
 
 •  
 冗余特征:不会对我们的算法带来新的信息,或者这种特征的信息可以由其他的特征推断出 
 
 比如:腿长可以推导出身高高
 
为什么要进行特征提取:
 
 
 •  
 降维  
 
 
 •  
 降低学习任务的难度  
 
 
 •  
 提升模型的效率 
 
 
什么是特征选择:
 
 
 从N个特征中选择其中M(M<=N)个子特征,并且在M个子特征中,准则函数可以达到最优解。  
 
 
 特征选择想要做的是:选择尽可能少的子特征,模型的效果不会显著下降,并且 
 结果的类别分布尽可能的接近真实的类别分布。 
 
 
 
 怎么做特征选择:
 
  
  1. 生成过程:生成候选的特征子集;  
 
 
  
  2. 评价函数:评价特征子集的好坏;  
 
 
  
  3. 停止条件:决定什么时候该停止;  
 
 
  
  4. 验证过程:特征子集是否有效; 
 
 
  
  
  特征选择生成过程:
 
   
   生成过程是一个搜索过程,这个过程主要有以下三个策略:  
  
 
   
   1. 完全搜索 
   :根据评价函数做完全搜索。完全搜索主要有两种:穷举搜索和非穷举搜索;  
  
 
   
   2. 启发式搜索 
   :根据一些启发式规则在每次迭代时,决定剩下的特征是应该被选择还是被拒绝。这种方法很简单并且速度很快。  
  
 
   
   3. 随机搜索 
   :每次迭代时会设置一些参数,参数的选择会影响特征选择的效果。由于会设置一些参数(例如最大迭代次数)。 
  
 
   
   
  
特征选择停止条件:
 
 
 停止条件用来决定迭代过程什么时候停止,生成过程和评价函数可能会对于怎么选择停止条件产生影响。停止条件有以下四种选择:  
 
 
 1. 达到预定义的最大迭代次数;  
 
 
 2. 达到预定义的最大特征数;  
 
 
 3. 增加(删除)任何特征不会产生更好的特征子集;  
 
 
 4. 根据评价函数,产生最优特征子集; 
 
 
 特征选择评价函数:
 
  
  评价函数主要用来评价选出的特征子集的好坏, 
  一个特征子集是最优的往往指相对于特定的评价函 
  数来说的 
  。评价函数主要用来度量一个特征(或者特征子集)可以区分不同类别的能力。根据具体的评价方法主要有三类:  
 
 
  
  •  
  过滤式( 
  filter):  
  先进行特征选择,然后去训练学习器,所以特征选择的过程与学习器无关。相当于先对于特征进行过滤操作,然后用特征子集来训练分类器。对每一维的特征“打分”,即给每一维的特征赋予权重,这样的权重就代表着该维特征的重要性,然后依据权重排序。  
 
 
  
  •  
  包裹式( 
  wrapper): 
  直接把最后要使用的分类器作为特征选择的评价函数,对于特定的分类器选择最优的特征子集。将子集的选择看作是一个搜索寻优问题,生成不同的组合,对组合进行评  
 
 
  
  价,再与其他的组合进行比较。这样就将子集的选择看作是一个优化问题,  
 
 
  
  •  
  Filter和Wrapper组合式算法: 
  先使用Filter进行特征选择,去掉不相关的特征,降低特征维度;然后利用Wrapper进行特征选择。  
 
 
  
  •  
  嵌入式( 
  embedding): 
  把特征选择的过程与分类器学习的过程融合一起,在学习的过程中进行特征选择。 
 
 
  
  其主要思想是:在模型既定的情况下学习出对提高模型准确性最好的属性。是讲在确定模型的过程中,挑选出那些对模型的训练有重要意义的属性。 
 
 
 特征选择评价函数:
 
  
  1. 距离度量:如果 X 在不同类别中能产生比 Y 大的差异,那么就说明 X 要好于 Y;  
 
 
  
  2. 信息度量:主要是计算一个特征的信息增益(度量先验不确定性和期望, 后验不确定性之间的差异);  
 
 
  
  3. 依赖度量:主要用来度量从一个变量的值预测另一个变量值的能力。最常见的是相关系数: 
 
 
  
  用来发现一个特征和一个类别的相关性。如果 X 和类别的相关性高于 Y与类别的相关性,那么X优于Y。对相关系数做一点改变,用来计算两个特征之间的依赖性,值代表着两个特征之间的冗余度。  
 
 
  
  4. 一致性度量:对于两个样本,如果它们的类别不同,但是特征值是相同的,那么它们是不一致的;否则是一致的。找到与全集具有同样区分能力的最小子集。严重依赖于特定的训练集和最小特征偏见(Min-Feature bias)的用法;找到满足可接受的不一致率(用户指定的参数)的最小规模的特征子集。  
 
 
  
  5. 误分类率度量:主要用于Wrapper式的评价方法中。使用特定的分类器,利用选择的特征子集来预测测试集的类别,用分类器的准确率来作为指标。这种方法准确率很高,但是计算开销较大。 
 
 
  
  特征选择算法:
 
  完全搜索:
 
   
   广度优先搜索( 
   Breadth First Search): 
   主要采用完全搜索策略和距离度量评价函数。 使用广度优先算法遍历所有可能的特征子集,选择出最优的特征子集。 
   主要采用完全搜索和距离度量。 
   B&B从所有的特征上开始搜索,每次迭代从中去掉一个特征,每次给评价函数的值一个限制条件。因为评价函数满足单调性原理(一个特征子集不会好于所有包含这个特征子集的更大的特征子集),所以如果一个特征使得评价函数的值小于这个限制,那么就删除这个特征。类似于在穷举搜索中进行剪枝。  
  
 
   
   
   定向搜索( 
   Beam Search): 
   主要采用完全搜索策略和误分类率作为评价函数。选择得分最高的特征作为特征子集,把它加入到一个有长度限制的队列中,从头到尾依次是性能最优到最差的特征子集。每次从队列总取得分最高的子集,然后穷举向该子集中加入一个特征后所有的特征集,按照得分把这些子集加入到队列中。  
  
 
   
   
   最优优先搜索( 
   Best First Search): 
   和定位搜索类似,不同点在于不限制队列的长度 
   。 
  
 
   
  启发式搜索:
 
   
   序列前向选择( 
   SFS , Sequential Forward Selection) 
   :使用误分类率作为评价函数。从空集开始搜索,每次把一个特征加入到这个特征子集中,使得评价函数达到最优值。如果候选的特征子集不如上一轮的特征子集,那么停止迭代,并将上一轮的特征子集作为最优的特征选择结果。  
  
 
   
   
   广义序列前向选择( 
   GSFS ,Generalized Sequential Forward Selection): 
   该方法是SFS算法的加速算法,它可以一次性向特征集合中加入r个特征。在候选特征中选择一个规模为r的特征子集,使得评价函数取得最优值。  
  
 
   
   
   序列后向选择( 
   SBS , Sequential Backward Selection): 
   把误分类率作为评价函数。从特征的全集开始搜索,每次从特征子集中去掉一个特征,使得评价函数达到最优值。  
  
 
   
   
   广义序列后向选择( 
   GSBS,Generalized Sequential Backward Selection): 
   该方法是SBS的加速,可以一次性的从特征子集中去除一定数量的特征。是实际应用中的快速特征选择算法,性能相对较好。但是有可能消除操作太快,去除掉重要的信息,导致很难找到最优特征子集。  
  
 
   
   
   双向搜索( 
   BDS , Bi-directional Search): 
   分别使用SFS和SBS同时进行搜索,只有当两者达到一个相同的特征子集时才停止搜索。为了保证能够达到一个相同的特征子集,需要满足两个条件:  
  
 
   
   被SFS选中的特征不能被SBS去除;  
  
 
   
   被SBS去除的特征就不能SFS选择; 
  
 
   
    
    
    增L去R选择算法( 
    LRS , Plus L Minus R Selection):  
   
 
    
    采用误分类率作为评价函数。允许特征选择的过程中进行回溯,这种算法主要有两种形式:  
   
 
    
    当L>R时,是一种自下而上的方法,从空集开始搜索,每次使用SFS增加L个特征,然后用SBS从中去掉R个特征;  
   
 
    
    当L<R时,是一种自上而下的算法,从特征的全集开始搜索,每次使用SBS去除其中的R个特征,使用SFS增加L个特征;  
   
 
    
    
    序列浮动选择( 
    Sequential Floating Selection): 
    和增L去R算法类似,只不过序列浮动算法的L和R不是固定的,每次会产生变化,这种算法有两种形式:  
   
 
    
    
    序列浮动前向选择( 
    SFFS , Sequential Floating Forward Selection): 
    从空集开始搜索,每次选择一个特征子集,使得评价函数可以达到最优,然后在选择一个特征子集的子集,把它去掉使得评价函数达到最优;  
   
 
    
    
    序列浮动后向选择( 
    SFBS , Sequential Floating Backward Selection: 
    从特征全集开始搜索,每次先去除一个子集,然后在加入一个特征子集。  
   
 
    
    
    决策树算法(DTM , Decision Tree Method) 
    :采用信息增益作为评价函数。在训练集中使用C4.5算法,等到决策树充分增长,利用评价函数对决策树进行剪枝。最后,出现在任意一个叶子  
   
 
    
    节点的路径上的所有特征子集的并集就是特征选择的结果。 
   
 
    
   随机搜索:
 
   LVF(Las Vegas Filter):使用一致性度量作为评价函数。使用拉斯维加斯算法随机搜索子集空间,这样可以很快达到最优解。对于每一个候选子集,计算它的不一致性,如果大于阈值,则去 除这个子集。否则,如果这个候选子集中的特征数量小于之前最优子集的数量,则该子集作为最优子集。这个方法在有噪声的数据集达到最优解,它是很简单被实现而且保证产生比较好的特征 子集。但是在一些特定问题上,它会花费比启发式搜索更多的时间,因为它没有利用到先验知识。
 
    
    遗传算法:
 
     
     
     使用误分类率作为评价函数。随机产生一批特征子集,然后使用评价函数对于子集进行评分,通过选择、交叉、突变操作产生下一代特征子集,并且得分越高的子集被选中产生下一代的几率越高。经过N代迭代之后,种群中就会形成评价函数值最高的特征子集。它比较依赖于随机性,因为选择、交叉、突变都由一定的几率控制,所以很难复现结果。遗传算法的过程如下:  
    
 
     
     1. 随机产生初始种群;  
    
 
     
     2. 在非支配排序后,通过遗传算法的三个算子(选择算子,交叉算子,变异算子)进行变更操作得到第一代种群;  
    
 
     
     3. 将父代种群与子代种群合并得到大小为N的初始化种群;  
    
 
     
     4. 对包括N个个体的种群进行快速非支配排序;  
    
 
     
     5. 对每个非支配层中的个体进行拥挤度计算;  
    
 
     
     6. 根据非支配关系及个体的拥挤度选取合适的个体组成新的父代种群;  
    
 
     
     7. 通过遗传算法的基本变更操作产生新的子代种群;  
    
 
     
     8. 重复 3 到 7 直到满足程序结束的条件(即遗传进化代数); 
    
 
     
     
     特征提取:
 
     特征是什么:
 
      
      常见的特征有边缘、角、区域等。  
     
 
      
     特征提取:
 
      
      是通过属性间的关系,如组合不同的属性得到新的属性,这样就改变了原来的  
     
 
      
      特征空间。  
     
 
     特征选择:
 
      
      是从原始特征数据集中选择出子集,是一种包含的关系,没有更改原始的特征空间。  
     
 
      
      目前图像特征的提取主要有两种方法:传统图像特征提取方法 和 深度学习方法。  
     
 
      
      1. 传统的特征提取方法:基于图像本身的特征进行提取;  
     
 
      
      2. 深度学习方法:基于样本自动训练出区分图像的特征分类器;  
     
 
      
      
      特征选择(feature selection)和特征提取(Feature extraction)都属于降维(Dimension reduction) 
     
 
      
      特征提取:
 
       
       特征提取的主要方法: 
      
 
       
       主要目的是为了排除信息量小的特征,减少计算量等: 
      
 
       
       
        
        主成分分析( 
        PCA) 
       
 
        
         
         将数据从原始的空间中转换到新的特征空间中,例如原始的空间是三维的(x,y,z),x、y、z分别是原始空间的三个基,我们可以通过某种方法,用新的坐标系(a,b,c)来表示原始的数据,那么a、b、c就是新的基,它们组成新的特征空间。在新的特征空间中,可能所有的数据在c上的投影都接近于0,即可以忽略,那么我们就可以直接用(a,b)来表示数据,这样数据就从三维的(x,y,z)降到了二维的(a,b)。  
        
 
         
         
         问题是如何求新的基(a,b,c)?  
        
 
         
         一般步骤是这样的:  
        
 
         
         1. 对原始数据零均值化(中心化),  
        
 
         
         2. 求协方差矩阵,  
        
 
         
         3. 对协方差矩阵求特征向量和特征值,这些特征向量组成了新的特征空间。 
        
 
         
         
         PCA--零均值化(中心化):
 
          
          中心化即是指变量减去它的均值,使均值为0。  
         
 
          
          其实就是一个平移的过程,平移后使得所有数据的中心是(0,0) 
         
 
          
          
          只有中心化数据之后,计算得到的方向才能比较好的“概括”原来的数据。  
         
 
          
          此图形象的表述了,中心化的几何意义,就是将样本集的中心平移到坐标系的原点O上。 
         
 
          
 
          PCA降维的几何意义:
 
          
          如果它在某一坐标轴上的方差越大,说明坐标点越分散,该属性能够比较好的反映源数据。 
         
 
          
          
 
          
          PCA算法的优化目标就是 
          :  
         
 
          
          ① 降维后同一维度的方差最大  
         
 
          
          ② 不同维度之间的相关性为0 
         
 
          
          PCA--协方差
 
           
           协方差就是一种用来度量两个随机变量关系的统计量。  
          
 
           
           同一元素的协方差就表示该元素的方差,不同元素之间的协方差就表示它们的相关性。 
          
 
           
           
 
 
           
 
 
           
 
 
           
 
 
          对协方差矩阵求特征值、特征矩阵 
 
          
 
           
 
 
          对协方差矩阵求特征值、特征矩阵
 
          对特征值进行排序
 
          评价模型的好坏,K值的确定
 
          
 
          累了吧(不累?反正我累了),上代码!
 
          import cv2
 import numpy as np
 # 1. 对原始数据零均值化(中心化),
 # 2. 求协方差矩阵,
 # 3. 对协方差矩阵求特征向量和特征值,这些特征向量组成了新的特征空间。
 class PCA:
 # 求均值
 def centralization(array):
 return np.array([np.mean(attr) for attr in array.T])
 # 中心化矩阵
 def getCentralizationMatrix(array):
 mean = PCA.centralization(array)
 print("均值:" , mean)
 return array - mean
 # 协方差矩阵
 def getCov(array):
 centerMatrix = PCA.getCentralizationMatrix(array)
 length = len(centerMatrix)
 print("中心矩阵:" , centerMatrix)
 return np.dot(centerMatrix.T , centerMatrix) / (length - 1)
 # 获取特征值
 def getEigenValue(array):
 # length = len(array)
 # identityMatrix = PCA.initIdentityMatrix(length)
 cov = PCA.getCov(array)
 print("协方差矩阵:" , cov)
 a, b = np.linalg.eig(cov)
 print("特征值:" , a)
 print("特征值向量" , b)
 return a , b
 def getEigenArray(array , size):
 value , eArray = PCA.getEigenValue(array)
 length = len(np.sort(value))
 # 取前几行(自定义)
 newArray = np.array([eArray[:,i] for i in range(size)])
 return newArray.T
 # 获取降维矩阵
 def dimensionalityReductionMatrix(array , size):
 eArray = PCA.getEigenArray(array , size)
 print("特征矩阵" , eArray)
 return np.dot(array , eArray)
 # # 创建单位矩阵
 # def initIdentityMatrix(length):
 # array = [[0] * length] * length
 # for i in range(length):
 # for j in range(length):
 # if(i == j):
 # array[i][j] = 1
 # else:
 # continue
 # return array
 def getImageArray(filePath):
 image = cv2.imread(filePath, 1)
 # 长,宽,通道
 originArray = image.shape[1]
 def mainFunction(filePath , size):
 # imageArray = PCA.getImageArray(filePath)
 # 每行就是一个样本,每列就是样本的某一个属性
 imageArray = np.array([[10, 15, 29],
 [15, 46, 13],
 [23, 21, 30],
 [11, 9, 35],
 [42, 45, 11],
 [9, 48, 5],
 [11, 21, 14],
 [8, 5, 15],
 [11, 12, 21],
 [21, 20, 25]])
 finalArray = PCA.dimensionalityReductionMatrix(imageArray , size)
 print("降维矩阵:" , finalArray)
 PCA.mainFunction("111" , 2)
 
          关于sklearn可以参看下面的文章
 
          (机器学习)sklearn降维算法PCA(用几个小案例详解PCA降维)