降维相关的所有知识及相关python实现

一、降维和特征选择的区别

降低维度的意义:

    维数灾难:在给定精度下,准确地对某些变量的函数进行估计,所需样本量会随着样本维数的增加而呈指数形式增长。
    降维的意义:克服维数灾难,获取本质特征,节省存储空间,去除无用噪声,实现数据可视化,减少过拟合

之前没有详细了解之前,一直觉得降维和特征选择是一样的,因为他们的最终结果都是减少维度;但是这两者在本质上是不一样的。

  • By only keeping the most relevant variables from the original dataset (this technique is called feature selection)
  • By finding a smaller set of new variables, each being a combination of the input variables, containing basically the same information as the input variables (this technique is called dimensionality reduction)

1.1 特征选择:

特征选择就是单纯地从提取到的特征中选择部分特征作为训练特征,特征选择前后,特征的值并不改变,但维度会减少。例如,现在有一个1000维特征的数据,如果特征选择后500维,指的是在1000维特征中选取500维作为训练特征,舍弃另外500维的特征,但并不对特征的值进行改变。如果被选中的特征中某一value是9,则特征选择之后仍然是9.

常见的特征选择方法有:

  • Missing Value Ratio: If the dataset has too many missing values, we use this approach to reduce the number of variables. We can drop the variables having a large number of missing values in them
  • Low Variance filter: We apply this approach to identify and drop constant variables from the dataset. The target variable is not unduly affected by variables with low variance, and hence these variables can be safely dropped
  • High Correlation filter: A pair of variables having high correlation increases multicollinearity in the dataset. So, we can use this technique to find highly correlated features and drop them accordingly
  • Random Forest: This is one of the most commonly used techniques which tells us the importance of each feature present in the dataset. We can find the importance of each feature and keep the top most features, resulting in dimensionality reduction
  • Both Backward Feature Elimination and Forward Feature Selection techniques take a lot of computational time and are thus generally used on smaller datasets

具体的介绍:

1.缺失值比率(Missing Value Ratio)

在浏览数据的时候,如果我们发现其中包含不少缺失值,如果缺失值少,我们可以填补缺失值或者直接删除这个变量;当缺失值在数据集中的占比过高时,一般我会选择直接删除这个变量,因为它包含的信息太少了。具体删不删,怎么删需要视情况而定,我们可以设置一个阈值,如果缺失值占比高于阈值,删除它所在的列。阈值越高。降维方法越积极。
2.低方差滤波(Low Variance Filter)

如果一个数据集中,某一列的数值基本一致,也就是它的方差非常低,我们通常认为,低方差变量携带的信息也很少,所以可以把它直接删除,放到实践中,就是计算所有变量方差大小,然后删去其中最小的几个。

注意:方差与数据范围相关的,因此在采用该方法前需要对数据做归一化处理。
3.高相关滤波(High Correlation filter)

如果两个变量之间是高度相关的,这意味着他们具有相似的趋势并且可能携带类似的信息,同理,这类变量的存在会降低某些模型的性能(例如线性和逻辑回归模型)。为了解决此类问题,我们可以计算独立变量之间的相关性。如果相关系数超过某个阈值,就删除其中的一个变量。
4.随机森林(Random Forest)

RF是一种基于Bagging的集成学习方法,可以用来分来,在降维中我们可以用它进行特征选择

随机森林是一种广泛使用的特征选择算法,它会自动计算各个特征的重要性,所以无需单独编程。这有助于我们选择较小的特征子集。

随机森林的优点:

1、具有极高的准确率

2、随机性的引入,使得随机森林不容易过拟合

3、随机性的引入,使得随机森林有很好的抗噪声能力(能够更好的处理离群点)

4、能处理很高维度的数据,并且不用做特征选择

5、既能处理离散型数据,也能处理连续性数据,数据集无需规范化

6、训练速度快,可以得到变量重要性排序

7、容易实现并行化

随机森林的缺点:

1、当随机森林中的决策树个数很多时,训练需要的空间和时间会很大

2、随机森林的解释性很差
5.反向特征消除(Backward Feature Elimination)

主要步骤:

先获取数据集中的全部N个变量,然后用他们训练一个模型

计算模型的性能

在删除每个变量(n次)后计算模型的性能,即我们每次都去掉一个变量,用剩余的N-1个变量训练模型

确定对模型影响性最小的变量,把它删除

重复此过程直到不可以删除任何的变量
6.前向特征选择(Forward Feature Selection)

即为上述过程的一个逆过程

主要步骤:

选择一个特征,用每个特征训练模型N次,得到N个模型

选择模型性能最佳的变量作为初始变量

每次添加一个变量继续训练,重复上一过程,最后保留性能提升最大的变量

一直添加一直筛选,知道模型能不再有明显提高

注:前向特征选择和反向特征消除耗时较久,计算成本也都很高,所以只适用于输入变量较少的数据集。

1.2 降维:

降维本质是从一个维度空间映射到另一个维度空间,特征的多少并没有减少,但在映射过程中特征会发生相应的变化。例如原始的数据中有1000维的特征,经过一些降维手段之后变为500维,即是在找一个从1000维映射到500维的一个映射函数,原value是9,则降维之后可能是3.

常见的降维方法:

  • Factor Analysis: This technique is best suited for situations where we have highly correlated set of variables. It divides the variables based on their correlation into different groups, and represents each group with a factor
  • Principal Component Analysis: This is one of the most widely used techniques for dealing with linear data. It divides the data into a set of components which try to explain as much variance as possible
  • Independent Component Analysis: We can use ICA to transform the data into independent components which describe the data using less number of components
  • ISOMAP: We use this technique when the data is strongly non-linear
  • t-SNE: This technique also works well when the data is strongly non-linear. It works extremely well for visualizations as well
  • UMAP: This technique works well for high dimensional data. Its run-time is shorter as compared to t-SNE

具体的介绍:

7.因子分析(Factor Analysis)

因子分析是一个常见的统计方法,它能从多个变量中提取共性因子,并得到最优解。假设我们有两个变量:收入和教育。他们可能是高度相关的,因为从总体看来,学历很高的人一般收入也很高,所以他们之间可能存在一个潜在的共性因子,比如‘能力’。

在因子分析中,我们将变量按其相关性分组,即特定组内所有变量的相关性较高,组间变量的相关性较低。我们把每个组称为一个因子,它是多个变量的组合。和原始数据集的变量相比,这些因子在数量上更少,但携带的信息基本一致。
8.主成分分析(PCA)

PCA是一种很常用的降维方法,他可以通过对高维数据进行降维减少预测变量的个数,同时经过降维除去噪声,其中最直接的应用就是压缩数据,主要应用于:信号处理中的降噪,数据降维后可视化等。

数据特点:

1.维度灾难,简单来说就是变量的个数多,如果变量的个数增加,随之需要估计的参数的个数也在增加,在训练集保持不变得情况下待估参数的方差也会随机增加,导致参数估计的质量下降。

2.变量关系不一般,是指变量彼此之间常常存在一定程度的,有时甚至是相当高的相关性,这说明数据是有冗余的,或者说观测数据中的信息是有重叠的,这是我们利用PCA的前提条件。

在变量个数多,相互的相关性比较大的时候,我们会去寻找变量中的‘精华’,寻找个数相对较少的综合变量。

引用一个别人的例子:比如拿到一个汽车的样本,里面既有以“千米/每小时”度量的最大速度特征,也有“英里/小时”的最大速度特征,显然这两个特征有一个多余。

关于PCA的一些要点:

主成分是原始变量的线性组合

第一个主成分具有最大的方差值

第二主成分试图解释数据集中的剩余方差,并且与第一主成分不相关(正交)

第三主成分试图解释前两个主成分没有解释的方差
9.独立分量分析(ICA)

独立分量分析基于信息理论,是最广泛的降维技术之一。PCA和ICA的主要却别在于,PCA寻找不相关因素,而ICA寻找独立因素。

如果两个变量不相关,他们之间就没有线性关系。如果他们是独立的,他们就不依赖于其他变量。

以上方法的compare:

缺失值比率:如果数据集的缺失值太多,我们可以用这种方法减少变量数。

低方差滤波:该方法可以从数据集中识别和删除常量变量,方差小的变量对目标变量影响不大,所以可以放心删去。

高相关滤波:具有高相关性的一对变量会增加数据集中的多重共线性,所以用这种方法删去其中一个是有必要的。

随机森林:最常用的降维方法之一,他会明确算出数据集中每个特征的重要性。

前向特征选择和反向特征消除:这两种方法耗时很久,计算成本很高,所以只适用于变量较少的数据集。

因子分析:适用于数据集中存在高度相关的变量集的情况。

PCA:处理线性数据集最广泛使用的技术之一。

ICA:可以用ICA将数据转换为独立的分量,使用更少的分量来描述数据。

一些降维的python实现:

1)PCA的python实现:

 

具体python:

import numpy as np
import matplotlib.pyplot as plt
import time
from sklearn.datasets import load_digits

digits = load_digits(n_class=10)  # integer
X = digits.data
y = digits.target

# build plot_embedding
from matplotlib import offsetbox
def plot_embedding(X, title=None):
    x_min, x_max = np.min(X, 0), np.max(X, 0)
    X = (X - x_min) / (x_max - x_min)  # 正则化
    print(X)
    plt.figure(figsize=(10, 10))
    ax = plt.subplot(111)
    for i in range(X.shape[0]):
        plt.text(X[i, 0], X[i, 1], str(digits.target[i]),
                 color=plt.cm.Set1(y[i] / 10.),
                 fontdict={'weight': 'bold', 'size': 12})
    # 打印彩色字体
    if hasattr(offsetbox, 'AnnotationBbox'):
        # only print thumbnails with matplotlib > 1.0
        shown_images = np.array([[1., 1.]])  # just something big
        for i in range(digits.data.shape[0]):
            dist = np.sum((X[i] - shown_images) ** 2, 1)
            if np.min(dist) < 4e-3:
                # don't show points that are too close
                continue
            shown_images = np.r_[shown_images, [X[i]]]
            imagebox = offsetbox.AnnotationBbox(
                offsetbox.OffsetImage(digits.images[i], cmap=plt.cm.gray_r),
                X[i])
            ax.add_artist(imagebox)  # 输出图上输出图片
    plt.xticks([]), plt.yticks([])
    if title is not None:
        plt.title(title)

# 随机投影方法:

# random projecter(随机投影)
from sklearn import random_projection
rp = random_projection.SparseRandomProjection(n_components=2, random_state=42)  # 随机映射算法
start_time = time.time()
X_projected = rp.fit_transform(X)  # 随机投射
plot_embedding(X_projected, "Random Projection of the digits (time: %.3fs)" % (time.time() - start_time))
plt.show()

# 截断SVD(主成分投影)


# TruncatedSVD(截断SVD)
from sklearn import decomposition
X_pca = decomposition.TruncatedSVD(n_components=2).fit_transform(X)
start_time = time.time()
plot_embedding(X_pca, "Principal Components projection of the digits (time: %.3fs)" % (time.time() - start_time))
plt.show()

# t-SNE 降维


# t-SNE降维
from sklearn import manifold
# 降维
tsne = manifold.TSNE(n_components=2, init='pca', random_state=0)
start_time = time.time()
X_tsne = tsne.fit_transform(X)
# 绘图
plot_embedding(X_tsne,
               "t-SNE embedding of the digits (time: %.3fs)" % (time.time() - start_time))
plt.show()
# 这个非线性变换降维过后,仅仅2维的特征,就可以将原始数据的不同类别,在平面上很好地划分开。
# 不过t-SNE也有它的缺点,一般说来,相对于线性变换的降维,它需要更多的计算时间。

另外附上自己的另一个基于一家网贷公司的数据进行的lof异常检测,然后基于异常检测的结果进行tsne进行可视化。

# -*- coding:utf-8 -*
# 先进行异常检测后tsne降维可可视化分析。
from sklearn.neighbors import LocalOutlierFactor
from sklearn.manifold import TSNE
from scipy import stats
import matplotlib.pyplot as plt
import numpy as np
import xlrd
import math
import pandas as pd

rng = np.random.RandomState(42)

def excel2m(path, sheetnum):
    data = xlrd.open_workbook(path)
    table = data.sheet_by_index(sheetnum)
    nrows = table.nrows  # 行数
    ncols = table.ncols  # 列数
    datamatrix = np.zeros((nrows,ncols))
    for x in range(ncols):
        cols = table.col_values(x)
        minVals = min(cols)
        maxVals = max(cols)
        cols1 = np.matrix(cols)  # 把list转换成矩阵进行矩阵操作
        ranges = maxVals - minVals
        b = cols1 - minVals
        normcols = b / ranges   # 数据进行归一化处理
        datamatrix[:, x] = normcols  # 数据存储
    return datamatrix

# 对归一化后的数据进行去除nan值,该部分是因为整列是一个常量值。
def reprocess(path, sheetnum):
    datamatrix = excel2m(path, sheetnum)
    delete_lists = []
    feature_index = [i for i in range(30)]
    for i in range(datamatrix.shape[1]):
        a = datamatrix[0, i]
        if math.isnan(a):
            delete_lists.append(i)
    feature_index = np.delete(feature_index, delete_lists)
    datamatrix = np.delete(datamatrix, delete_lists, axis=1)
    return datamatrix, delete_lists, feature_index

matrix, delete_features, feature_index = reprocess("./data.xlsx", 8)  # (120,23)
n_samples, features_nums = matrix.shape[0], matrix.shape[1]  # 样本总数 ,特征数
outliers_fraction = 0.1      # 异常样本比例
print(n_samples, features_nums)

X_train = matrix
# fit the model
clf = LocalOutlierFactor(n_neighbors=35, contamination=outliers_fraction)
y_pred = clf.fit_predict(X_train)
print(y_pred)
scores_pred = clf.negative_outlier_factor_
print(len(scores_pred))
threshold = stats.scoreatpercentile(scores_pred, 100 * outliers_fraction)  # 根据异常样本比例,得到阈值,用于绘图
print(threshold)

outliernumbers = 0
for i in range(len(scores_pred)):
    a = scores_pred[i]
    if a < threshold:
        outliernumbers += 1
print(outliernumbers)

# 利用tsne进行features_nums的可视化.将2维的数据降低到2维特征数据。
X_tsne = TSNE(learning_rate=100).fit_transform(X_train)
plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y_pred)
plt.show()

                                

二、归一化和标准化的区别:

1,标准归一化。
将原始数据集归一化为均值为0、方差1的数据集,归一化公式如下:
其中为所有样本数据的均值,为所有样本数据的标准差。

2,最大最小归一化。
将原始数据线性化的方法转换到[0 1]的范围,归一化公式如下:
其中为样本数据的最大值,为样本数据的最小值。这种方法有个缺陷就是当有新数据加入时,可能导致和的变化,需要重新定义。
                   

 

1 概念
  归一化:1)把数据变成(0,1)或者(1,1)之间的小数。主要是为了数据处理方便提出来的,把数据映射到0~1范围之内处理,更加便捷快速。2)把有量纲表达式变成无量纲表达式,便于不同单位或量级的指标能够进行比较和加权。归一化是一种简化计算的方式,即将有量纲的表达式,经过变换,化为无量纲的表达式,成为纯量。
 标准化:在机器学习中,我们可能要处理不同种类的资料,例如,音讯和图片上的像素值,这些资料可能是高维度的,资料标准化后会使每个特征中的数值平均变为0(将每个特征的值都减掉原始资料中该特征的平均)、标准差变为1,这个方法被广泛的使用在许多机器学习算法中(例如:支持向量机、逻辑回归和类神经网络)。
  中心化:平均值为0,对标准差无要求
  归一化和标准化的区别:归一化是将样本的特征值转换到同一量纲下把数据映射到[0,1]或者[-1, 1]区间内,仅由变量的极值决定,因区间放缩法是归一化的一种。标准化是依照特征矩阵的列处理数据,其通过求z-score的方法,转换为标准正态分布,和整体样本分布相关,每个样本点都能对标准化产生影响。它们的相同点在于都能取消由于量纲不同引起的误差;都是一种线性变换,都是对向量X按照比例压缩再进行平移。
  标准化和中心化的区别:标准化是原始分数减去平均数然后除以标准差,中心化是原始分数减去平均数。 所以一般流程为先中心化再标准化。
  无量纲:我的理解就是通过某种方法能去掉实际过程中的单位,从而简化计算。

2 为什么要归一化/标准化?
  如前文所说,归一化/标准化实质是一种线性变换,线性变换有很多良好的性质,这些性质决定了对数据改变后不会造成“失效”,反而能提高数据的表现,这些性质是归一化/标准化的前提。比如有一个很重要的性质:线性变换不会改变原始数据的数值排序。
(1)某些模型求解需要
   1)在使用梯度下降的方法求解最优化问题时, 归一化/标准化后可以加快梯度下降的求解速度,即提升模型的收敛速度。如左图所示,未归一化/标准化时形成的等高线偏椭圆,迭代时很有可能走“之”字型路线(垂直长轴),从而导致迭代很多次才能收敛。而如右图对两个特征进行了归一化,对应的等高线就会变圆,在梯度下降进行求解时能较快的收敛。

     2)一些分类器需要计算样本之间的距离(如欧氏距离),例如KNN。如果一个特征值域范围非常大,那么距离计算就主要取决于这个特征,从而与实际情况相悖(比如这时实际情况是值域范围小的特征更重要)。

(2)无量纲化
  例如房子数量和收入,因为从业务层知道,这两者的重要性一样,所以把它们全部归一化。 这是从业务层面上作的处理。

(3)避免数值问题
  太大的数会引发数值问题。

3 数据预处理时
  3.1 归一化
  (1)Min-Max Normalization
   x' = (x - X_min) / (X_max - X_min)

  (2)平均归一化
   x' = (x - μ) / (MaxValue - MinValue)
  (1)和(2)有一个缺陷就是当有新数据加入时,可能导致max和min的变化,需要重新定义。

  (3)非线性归一化
    1)对数函数转换:y = log10(x)
    2)反余切函数转换:y = atan(x) * 2 / π
    3)经常用在数据分化比较大的场景,有些数值很大,有些很小。通过一些数学函数,将原始值进行映射。该方法包括 log、指数,正切等。需要根据数据分布的情况,决定非线性函数的曲线,比如log(V, 2)还是log(V, 10)等。

3.2 标准化
  (1)Z-score规范化(标准差标准化 / 零均值标准化)
  x' = (x - μ)/σ

3.3 中心化
  x' = x - μ

4 什么时候用归一化?什么时候用标准化?
  (1)如果对输出结果范围有要求,用归一化。
  (2)如果数据较为稳定,不存在极端的最大最小值,用归一化。
  (3)如果数据存在异常值和较多噪音,用标准化,可以间接通过中心化避免异常值和极端值的影响。
  某知乎答主的回答提到了他个人经验:一般来说,我个人建议优先使用标准哈。对于输出有要求时再尝试别的方法,如归一化或者更加复杂的方法。很多方法都可以将输出范围调整到[0, 1],如果我们对于数据的分布有假设的话,更加有效的方法是使用相对应的概率密度函数来转换。让我们以高斯分布为例,我们可以首先计算高斯误差函数(Gaussian Error Function),此处定为er fc(·),那么可以用下式进行转化:

                                                                


  这篇博客提到他的经验:1) 在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,第二种方法(Z-score standardization)表现更好。2) 在不涉及距离度量、协方差计算、数据不符合正太分布的时候,可以使用第一种方法或其他归一化方法。比如图像处理中,将RGB图像转换为灰度图像后将其值限定在[0 255]的范围。

 

5 哪些模型必须归一化/标准化?
(1)SVM
  不同的模型对特征的分布假设是不一样的。比如SVM 用高斯核的时候,所有维度共用一个方差,这不就假设特征分布是圆的么,输入椭圆的就坑了人家,所以简单的归一化都还不够好,来杯白化才有劲。比如用树的时候就是各个维度各算各的切分点,没所谓。

(2)KNN
  需要度量距离的模型,一般在特征值差距较大时,都会进行归一化/标准化。不然会出现“大数吃小数”。

(3)神经网络
  1)数值问题
  归一化/标准化可以避免一些不必要的数值问题。输入变量的数量级未致于会引起数值问题吧,但其实要引起也并不是那么困难。因为tansig(tanh)的非线性区间大约在[-1.7,1.7]。意味着要使神经元有效,tansig( w1x1 + w2x2 +b) 里的 w1x1 +w2x2 +b 数量级应该在 1 (1.7所在的数量级)左右。这时输入较大,就意味着权值必须较小,一个较大,一个较小,两者相乘,就引起数值问题了。
  假如你的输入是421,你也许认为,这并不是一个太大的数,但因为有效权值大概会在1/421左右,例如0.00243,那么,在matlab里输入 421·0.00243 == 0.421·2.43,会发现不相等,这就是一个数值问题。

  2)求解需要
  a. 初始化:在初始化时我们希望每个神经元初始化成有效的状态,tansig函数在[-1.7, 1.7]范围内有较好的非线性,所以我们希望函数的输入和神经元的初始化都能在合理的范围内使得每个神经元在初始时是有效的。(如果权值初始化在[-1,1]且输入没有归一化且过大,会使得神经元饱和)
  b. 梯度:以输入-隐层-输出这样的三层BP为例,我们知道对于输入-隐层权值的梯度有2ew(1-a^2)*x的形式(e是誤差,w是隐层到输出层的权重,a是隐层神经元的值,x是输入),若果输出层的数量级很大,会引起e的数量级很大,同理,w为了将隐层(数量级为1)映身到输出层,w也会很大,再加上x也很大的话,从梯度公式可以看出,三者相乘,梯度就非常大了。这时会给梯度的更新带来数值问题。
  c. 学习率:由(2)中,知道梯度非常大,学习率就必须非常小,因此,学习率(学习率初始值)的选择需要参考输入的范围,不如直接将数据归一化,这样学习率就不必再根据数据范围作调整。 隐层到输出层的权值梯度可以写成 2ea,而输入层到隐层的权值梯度为 2ew(1-a^2)x ,受 x 和 w 的影响,各个梯度的数量级不相同,因此,它们需要的学习率数量级也就不相同。对w1适合的学习率,可能相对于w2来说会太小,若果使用适合w1的学习率,会导致在w2方向上步进非常慢,会消耗非常多的时间,而使用适合w2的学习率,对w1来说又太大,搜索不到适合w1的解。如果使用固定学习率,而数据没归一化,则后果可想而知。
  d.搜索轨迹:已解释
  
(4)PCA

参考:
标准化和归一化什么区别? - 知乎:https://www.zhihu.com/question/20467170
R--数据标准化、归一化、中心化处理:https://zhuanlan.zhihu.com/p/33727799
特征工程中的[归一化]有什么作用? - 知乎:https://www.zhihu.com/question/20455227
神经网络为什么要归一化:http://nnetinfo.com/nninfo/showText.jsp?id=37

归一化 (Normalization)、标准化 (Standardization)和中心化/零均值化 (Zero-centered)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值