特征选择及特征提取

特征

什么是特征:

举个例子:一个妹子很好看,好看的在哪里?腿长(特征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降维)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值