维度规约(特征的提取和组合)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了维度规约(特征的提取和组合)相关的知识,希望对你有一定的参考价值。

参考技术A

介绍
第一部分 参数方法——类密度模型参数估计
第二部分 监督学习——分类(基于似然的方法)
第三部分 监督学习——分类(基于判别式的方法)(参数方法——判别式参数估计)
第四部分 监督学习——回归
第五部分 监督学习——关联规则
第六部分 维度规约(特征的提取和组合)
第七部分 半参数方法
第八部分 非监督学习——聚类
第九部分 非参数方法——密度估计
第十部分 非参数方法——决策树实现的判别式
第十一部分 多层感知器——非参数估计器
第十二部分 局部模型
第十三部分 支持向量机与核机器
第十四部分 隐马尔科夫模型
第十五部分 参数的贝叶斯估计
第十六部分 集成学习——组合多学习器
第十七部分 增强学习
第十八部分 机器学习实验
第十九部分 特征工程与数据预处理

任何分类和回归方法的复杂度都依赖于输入的数量。我们需要输入数据含有可供决策的信息。理想情况下,不需要将特征选择或特征提取作为一个单独的过程。并且有效的方法,应该能够利用任何必要的特征,并丢弃不相关的特征。

但将降维作为一个单独的预处理步骤,有如下一些原因:

1、在大多数机器学习算法中,复杂度依赖于输入的维度d及样本规模N。为了减少存储及计算时间,需要考虑降低维度。同时降低d也降低了检验算法的复杂度。

2、去除不必要的采集数据,

3、更简单的模型可以在小数据集上更鲁棒。(《 监督学习——分类(基于判别式的方法)(参数方法——判别式参数估计) 》多元情况部分中,提到过高维输入x可能存在奇异的协方差矩阵估计)

4、当数据可以用较少的特征解释时,有利于理解数据背后的过程,并提取知识,利于解释。



降低维度主要有两类方法:特征选择、特征提取。

特征选择 ——从d个维中找到 提供最多信息的k个维度,丢弃其他(d-k)个维度的数据。

特征提取 ——找到k个维度的新集合,这k个维度是原来d个维度的组合。这些方法可以是监督的或者非监督的。如同为 线性投影方法 主成分分析(PCA) 线性判别分析(LDA) 分别是非监督的和监督的。线性维度归约以外,还有非线性维度归约方法,如 等距特征映射(Isomap) 局部线性嵌入(LLE) 拉普拉斯特征映射

1、主成分计算

在投影方法中,我们要找到的是从原d维输入空间到新的 维空间的、具有最小信息损失的映射。

x在方向\\omega 上的投影为 。

PCA是一种非监督方法,其最大化的准则是方差,主成分是这样的 ,样本投影在 上后最分散。同时为了保证解唯一,要求 。

如果 且 ,则 。寻找 使得 在约束 下最大化。写成拉格朗日问题,有:

关于 求导并令它等于0,有 ,也就是 。 是 的特征向量, 是对应的特征值。因为我们想最大化方差 ,特征值就等于方差,所以选择最大化特征值的特征向量。

因此,主成分是输入样本协方差矩阵的具有最大特征值的特征向量。

第二个主成分 也应该最大化方差 ,具有单位长度,并且与 正交(也就是与 不相关)。则对第二个主成分有:

关于 求导并令它等于0,有 。左乘 ,得 。

其中 。

于是得 , 。表明 是 得具有第二大特征值的特征向量。类似地,其他维可由递减特征值的特征向量给出。并且,因为 是对称的,所以对于任意两个不同的特征值,对应的特征向量是正交的。

最后有降维后的数据 ,其中W的k列是\\Sigma 的估计S的k个主特征向量。 投影前从 x 中减去样本均值 m ,将数据原点中心化

等同地,我们想找到一个矩阵W,使得 (不失一般性,x已经中心化), ,其中D是对角矩阵,既我们希望得到不相关的z_i。令S是D的估计, 矩阵C的第 i 列是S的规范化特征向量 ,则 。且有

其中D是对角矩阵,对角元素是特征值\\lambda_i。这称为S的谱分解。C是正交的,有 。所以可以令 , 是对角矩阵。

2、 选取主成分

得到了各主成分 ,根据特征值大小,可统计方差比例 ,取贡献了一定比例以上的前k个主成分。或可通过忽略小于平均输入方差的特征值对应的特征向量,来得到k个主成分。

PCA解释方差,但对离群点很敏感。少量离群点会明显影响方差,从而对特征向量产生很大影响。一般会通过计算数据点的马氏距离,丢弃孤立的离群点,保证估计的鲁棒性。


因子分析(FA)同PCA一样时非监督的。假设存在不可观测的潜在因子集合 ,它们组合成样本实例 。与PCA方法相反,FA的目的时通过较少的因子 z 刻画观测变量 x 之间的依赖性。也就是相较于PCA的 ,FA试图找到 z 使得其构成 x : 。

在PCA中,挑选大特征值的特征向量构成W,损失了没有被选中的特征值对应的方差。但FA虽也在一个更小的维空间重构数据,但没有丢失信息。


X是 的样本数据矩阵,协方差矩阵是 的。如果X已中心化,具有零均值,则协方差矩阵等于 。PCA使用 的特征向量,谱分解是 ,C的各列是 的特征向量,D是对应特征值构成的 对角矩阵。

如果我们想将维度归约到 ,在PCA中,假定W中的特征向量按特征值大小排序,取W的前k列( 具有最大特征值的k个特征向量),我们记这些特征向量为 ,对应特征值为 。从原始输入空间映射到新的k维空间:

对任意 ,有

因此, 是 的具有特征值 的特征向量。注意, 是 的,而 是 的。

其谱分解为 ,其中 是 的, 的列是 的特征向量 (单位化后的), 是对应特征值构成的对角矩阵。 的N维特征向量是新的特征嵌入(FE)空间的坐标。

求得了 ,可直接得到 (PCA所做的):

通常 ,这是使用PCA来计算 更简单。而有时 ,则计算 容易一些。

对于PCA,得到的是投影向量,可通过取x与特征向量的点积,将任意一个x投影到新的k维空间。但线性嵌入没有学习得到投影映射的模型,每当有一个新的数据加入,都需要重新进行计算。


假设N个点,知道每对点间距离 (不需知道这些点的坐标,维度,也不必知道如何计算这些距离)。多维定位(MDS)是把这些点映射到低维空间的方法,使它们在低维空间重得欧式距离 尽可能接近原始空间中的给定距离 。

可以使用MDS进行维度归约,通过d维 x 空间的逐对欧氏距离,将距离作为MDS的输入。如有样本 ,其中 ,在运用MDS方法时,不需知道 x 的具体坐标。对每两个点 r 和 s。它们之间的平方欧氏距离为

,其中 。

将数据中心化并假定 。由此有 。

并记 ,得到

由上述各等式可得:

故通过已知的 ,计算得到了 ,也就是得到了 。也就是线性嵌入的结果。通过B的特征向量得到各实例在新空间中的坐标。

PCA、FA与MDS做了同样的事情,当d<N时,PCA代价更低。在相关性矩阵上而不是协方差矩阵上做PCA等价于用标准欧氏距离来做MDS,其中每个变量都有单位方差。而MDS

上面介绍的MDS用线性映射的方法,将原空间上的数据,线性地映射到新空间:

MDS中也可以使用非线性的映射,这被称为Sammon映射。映射中的标准化误差称为Sammon应力:

可对g使用任何回归方法,训练 最小化训练数据 X 上的Sammon应力。

对于分类的情况,可在距离的定义中包含类信息,如 ,其中 是r和s所属类之间的距离。应该主观地提供这个类间距离, 用交叉验证优化。


线性判别分析(LDA)是一种用于分类问题的维度归约的 监督 方法。

两类问题 ,考虑两个类 , 的样本,希望找到由向量 定义的方向,使得当数据投影到 上时,来自两个类的样本尽可能分开。

是 到 上的投影。 和 是 类样本在投影前和投影后的均值。注意这里 ,而 。设样本 ,对 有 , 有 。

, 。

来自两个类的样本投影后在均值周围的散布是

, 。

投影后,为了使各类尽可能地分开,则希望均值金尽可能远离,并且类实例散布在尽可能小的范围里。既, 大, 小。费希尔线性判别式是这样的 ,最大化 。其中

其中 是类间散度矩阵, 是类内散布的和。从而

,关于 求 的导数,并令其为0,得

其中 是常数,有 ,c是常数。这里关注的是 的方向,故c取1。

对于 K>2 个类,我们希望找到矩阵W,使得 ,其中z是k维的,矩阵W是 矩阵。 的类内散布矩阵是

,其中对 有 ,否则为0。

总的类内散布矩阵是 。

类间散布矩阵是 ,其中 。

投影后类间散布矩阵为 ,类内散布矩阵是 ,都是 矩阵。

同样地,我们希望类间散布更大,类内散布更小,故最大化 ,其解为 的最大的特征向量。注意, 是K个秩为1的矩阵 的和,并且可知它们之中最多只有K-1个是独立,因此S_B的秩最大只有K-1。同2类一样,数据在 上的投影自然是降维的。

为了使用LDA,需要类内散布矩阵 可逆。如果不可逆,可先用PCA消除奇异性,在运用LDA。同时,应该确保PCA 没有把维度降得太低,使得LDA没有多少事可做。

相比于PCA只注重总体的方差,LDA的监督性注重类间散布 。


前面所介绍的方法,都需要数据落在一个线性子空间中。但这一前提并不总是成立。等距特征映射(Isomap)与下面的局部线性嵌入和拉普拉斯特征映射,不同于上面的方法,考虑的是 流形(mainfold) 上的输入数据,且为 非监督方法 。关注的局部数据的逐对距离,而不是全局相似性。

Isomap使用所有数据点对之间的测地距离(沿流形的距离)。对输入空间中靠近的邻近点,可以使用欧氏距离。对距离远的点,用沿流形的各点之间的距离和来近似。

视两个点 r 和 s 是连接的,如果 或 s 是 r 的n个最近邻之一,则其rs边长是 。对任意两个节点 r 和s, 是它们之间最短路径的长度。然后在 可上应用MDS。

与使用MDS一样,由于使用了线性嵌入来将N个数据放到一个低维空间,所以没有学习一个从原空间到低维空间的映射函数。

局部线性嵌入(LLE)从局部线性拟合来发现全局非线性结构。其基本思想是,流形的每个局部可以线性地近似。每个点可通过其邻近点的线性加权和给出。

原数据 和它的近邻 可使用最小二乘法找到重构权重 。其最小化误差 ,

且满足 。

LLE试图用重构权重 反应数据的固有几何性质,期望这种性质在映射后的新空间中也能保持。因此,LLE方法下一步保持 固定,来取新坐标 z 的值。

与Isomap一样,LLE的解是N个点的新坐标,不学习映射。对此有两种解决方案:

1、使用相同的思想,对新元素 ,在原始 d 维空间中找出 的n个近邻(原数据集中的实例,已映射到新空间),并且首先学习最小化 的重构权重 。然后使用它们在新的k维空间中重构 。

2、使用映射后的结果 作为训练集,可训练任意回归器 。例如多层感知器,作为从 到 映射的近似。

Isomap和LLE中,全局非线性组织 通过整合部分重叠的局部线性约束而得到。

考虑数据实例 和它们的投影 。假定实例点对之间相似度为 , 可在原始空间中计算。r和s相等时 取最大值,并且它是对称的 。

这里的目标函数是 ,意义在于 相似的实例应该放在新空间中的邻近位置,而不相似的实例在新空间中的位置相对不关心。

计算 ,MDS方法中使用点积 。但在拉普拉斯特征映射中,同Isomap和LLE一样,只关注局部相似性。通过r 和s 之间的某个最大 距离,或者通过k最近邻来定义邻域,邻域之外,设置 。邻域之内,对于用户指定的某个 值,使用高斯核把欧氏距离转换为相似度:

定义了 后,最小化目标函数

简写为 ,其中D是 的 对角矩阵,B是 构成的 矩阵。

定义 图拉普拉斯(graph Laplacian) 。目标最小化 。约束 。与特征嵌入一样,得到新空间中的坐标 z。其解是L的特征向量,又因为我们要最小化 ,所以选则最小特征值的特征向量作为解(注意忽略0特征值)。

拉普拉斯特征映射是一种特征嵌入方法。也就是直接在新空间中得到坐标,而没有可用于新实例的映射模型。

拉普拉斯特征映射使用特征嵌入的思想,并保持逐对相似性。相同的思想也用于核机器,核机器中逐对相似性由核函数给出。


核机器的运用,将非线性空间的问题变为新的线性空间上的问题。具体对核方法的介绍见《 支持向量机与核机器 》一节。

对于维度规约方法,也可以运用核方法。对于处理线性子空间的方法,不能直接运用在流形问题上。核版本的方法可以解决这个问题,核机器内在地将原问题映射到新的线性子空间中,再在线空间上采用线性方法。核PCA使用核矩阵的特征向量核特征值,这对应于在基函数映射后的 的空间上做线性维度规约。而在MDS中,核值则作为相似度值。`

如何使用 scikit-learn 组合具有不同维度输出的特征

【中文标题】如何使用 scikit-learn 组合具有不同维度输出的特征【英文标题】:How to combine features with different dimensions output using scikit-learn 【发布时间】:2018-10-30 06:32:59 【问题描述】:

我正在使用 scikit-learn 与 Pipeline 和 FeatureUnion 从不同的输入中提取特征。我的数据集中的每个样本(实例)都引用了不同长度的文档。我的目标是独立计算每个文档的顶部 tfidf,但我不断收到此错误消息:

ValueError: blocks[0,:] 的行尺寸不兼容。得到 blocks[0,1].shape[0] == 1,预计 2000 年。

2000 是训练数据的大小。 这是主要代码:

book_summary= Pipeline([
   ('selector', ItemSelector(key='book')),
   ('tfidf', TfidfVectorizer(analyzer='word', ngram_range(1,3), min_df=1, lowercase=True, stop_words=my_stopword_list, sublinear_tf=True))
])

book_contents= Pipeline([('selector3', book_content_count())]) 

ppl = Pipeline([
    ('feats', FeatureUnion([
         ('book_summary', book_summary),
         ('book_contents', book_contents)])),
    ('clf', SVC(kernel='linear', class_weight='balanced') ) # classifier with cross fold 5
]) 

我编写了两个类来处理每个管道函数。我的问题是 book_contents 管道,它主要处理每个样本并独立返回每本书的 TFidf 矩阵。

class book_content_count(): 
  def count_contents2(self, bookid):
        book = open('C:/TheCorpus/'+str(int(bookid))+'_book.csv', 'r')       
        book_data = pd.read_csv(book, header=0, delimiter=',', encoding='latin1',error_bad_lines=False,dtype=str)
                      corpus=(str([user_data['text']]).strip('[]')) 
        return corpus

    def transform(self, data_dict, y=None):
        data_dict['bookid'] #from here take the name 
        text=data_dict['bookid'].apply(self.count_contents2)
        vec_pipe= Pipeline([('vec', TfidfVectorizer(min_df = 1,lowercase = False, ngram_range = (1,1), use_idf = True, stop_words='english'))])
        Xtr = vec_pipe.fit_transform(text)
        return Xtr

    def fit(self, x, y=None):
        return self

数据样本(示例):

title                         Summary                          bookid
The beauty and the beast      is a traditional fairy tale...    10
ocean at the end of the lane  is a 2013 novel by British        11

那么每个id都会引用一个包含这些书籍实际内容的文本文件

我尝试过toarrayreshape 函数,但没有成功。任何想法如何解决这个问题。 谢谢

【问题讨论】:

能否提供一些示例数据? 我添加了数据示例 理想情况下,您将提供一个最小的工作示例来重现您的错误。目前你指的是book_content_count(),我无法从你的代码中识别出来。 这不能在 FeatureUnion 中完成。它在内部使用numpy.hstack,这要求所有部分的行数相等。第一部分'book_summary' 将处理整个训练数据并返回一个包含 2000 行的矩阵。但是您的第二部分 'book_contents' 将只返回一行。您将如何组合这些数据? 只是古玩,您找到解决方案了吗?请注意,“每个文档独立的 tfidf”等价于 countvectorizer。 【参考方案1】:

您可以将Neuraxle's Feature Union 与需要自己编码的自定义连接器一起使用。 joiner 是一个传递给 Neuraxle 的 FeatureUnion 的类,用于以您期望的方式将结果合并在一起。

1。导入 Neuraxle 的类。

from neuraxle.base import NonFittableMixin, BaseStep
from neuraxle.pipeline import Pipeline
from neuraxle.steps.sklearn import SKLearnWrapper
from neuraxle.union import FeatureUnion

2。通过继承 BaseStep 来定义您的自定义类:

class BookContentCount(BaseStep): 

    def transform(self, data_dict, y=None):
        transformed = do_things(...)  # be sure to use SKLearnWrapper if you wrap sklearn items.
        return transformed

    def fit(self, x, y=None):
        return self

3。创建一个加入者,以您希望的方式加入特征联合的结果:

class CustomJoiner(NonFittableMixin, BaseStep):
    def __init__(self):
        BaseStep.__init__(self)
        NonFittableMixin.__init__(self)

    # def fit: is inherited from `NonFittableMixin` and simply returns self.

    def transform(self, data_inputs):
        # TODO: insert your own concatenation method here.
        result = np.concatenate(data_inputs, axis=-1)
        return result

4。最后通过将连接器传递给 FeatureUnion 来创建您的管道:

book_summary= Pipeline([
    ItemSelector(key='book'),
    TfidfVectorizer(analyzer='word', ngram_range(1,3), min_df=1, lowercase=True, stop_words=my_stopword_list, sublinear_tf=True)
])

p = Pipeline([
    FeatureUnion([
        book_summary,
        BookContentCount()
    ], 
        joiner=CustomJoiner()
    ),
    SVC(kernel='linear', class_weight='balanced')
]) 

注意:如果您希望您的 Neuraxle 管道恢复为 scikit-learn 管道,您可以执行 p = p.tosklearn()

要了解有关 Neuraxle 的更多信息: https://github.com/Neuraxio/Neuraxle

文档中的更多示例: https://www.neuraxle.org/stable/examples/index.html

【讨论】:

以上是关于维度规约(特征的提取和组合)的主要内容,如果未能解决你的问题,请参考以下文章

文本挖掘中特征选择(附python实现)

文本挖掘之三种特征选择(python 实现)

大数据项目3(数据规约)

ABP官方文档翻译 3.5 规约

ABP官方文档翻译 3.5 规约

ABP框架 - 规约