KPCA降维_超参数_贝叶斯优化

使用kpca和贝叶斯优化进行特征降维


任务

在量化投资策略中给特征值进行降维时,类似PCA、ICA、LDA的线性降维算法比较常见。线性降维可保持特征值的全局结构,但不好处理局部关系和时间序列的非线性特点。此时非线性降维或许是更好的选择。

常用的非线性降维算法包括LLE、LE、TSNE、KPCA、SOM等。首先,算法需要能够处理无监督学习任务;其次,需要能够应用于测试集,即允许变换新数据,而并非只可用于训练;此外, 在处理时间序列任务时,数据是单条目滚动产生的,因此算法需要能够对单条目或者批量的新数据进行变换;最后,转换结果需要稳定,便于比较和校验。

根据上述目标,可以排除例如TSNE、SOM等降维方式。KPCA是较合适的方法之一。

贝叶斯优化不仅适用于有监督机器学习或深度学习,同样适用于无监督学习的聚类或降维。利用贝叶斯优化对KPCA中的超参数进行选择,提升降维表现和稳定。


一、数据加载

以sklearn中的红酒数据集作为案例进行说明。数据集包含178条样本,13个特征值,3个标签类。

from sklearn.datasets import load_wine
wine_dataset=load_wine()

二、数据预处理

数据集分割、标准化处理。

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(
    wine_dataset['data'],wine_dataset['target'],random_state=0)

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()  
X_train = scaler.fit_transform(X_train)  #标准化处理
X_test = scaler.transform(X_test)  #标准化处理  

三、核主成分分析KPCA

简单介绍一下KPCA原理。以下内容摘自基于sklearn的核主成分分析(KPCA)原理及其实现-CSDN博客

KPCA是PCA的一扩展形式,通过非线性映射将数据转换到高维空间中,然后在高维空间中进行PCA分析。KPCA可以在非线性数据上提取主成分,是一种有效的非线性降维方法。

KPCA的实现过程如下:

选择一个合适的核函数(如高斯核函数、多项式核函数等),将原始数据映射到高维空间中。

在高维空间中计算数据的协方差矩阵或者Gram矩阵,这个矩阵的维度通常很高。

对协方差矩阵或Gram矩阵进行特征值分解,得到每个特征向量和对应的特征值。

选取前k个特征向量,将原始数据映射到低维空间中。这些特征向量通常与原始数据的维度相同。
————————————————
以上为博主「清纯世纪」的原创文章,https://blog.csdn.net/qq_45100200/article/details/130020683

调用sklearn中的KernelPCA即可。利用fit_transform可直接对数据进行转换。做量化策略时,建议分开此过程。先用训练集fit数据,再在测试集上用transfomr转换。示例:

from sklearn.decomposition import KernelPCA

#建立kpca模型
model = KernelPCA(kernel='rbf', 
          n_components=2,
            fit_inverse_transform=True,
              random_state=0)

#训练集拟合
model.fit(X_train)
#测试集转换
model.transform(X_test)

四、贝叶斯优化——hyperopt

四、1  调优

首先尝试常用的贝叶斯优化算法库之一hyperopt。通过pip install hyperopt安装即可。hyperopt在计算效率、支持工具种类和可搜索空间具有优势。

需要注意的几点:

1.目标是最小化误差函数,可选择常用的几个之一或进行自定义。

2.n_components的最大值可选择为全部特征值数量。

3.保证结果可复现时,random_state传入‘rstate’参数进行设置。需要传入generator而非seed。

from sklearn.metrics import mean_squared_error
from sklearn.decomposition import KernelPCA
from hyperopt import fmin, tpe, hp

# 超参搜索空间
space = {
    'kernel': hp.choice('kernel', ['rbf', 'poly', 'cosine']), 
    'gamma': hp.uniform('gamma', 0.01, 0.9), 
    'n_components':hp.uniform('n_components', 1, 5) 
}

# 目标误差函数
def kpca_error(params):   
    kpca = KernelPCA(kernel=params['kernel'], gamma=params['gamma'],
                               n_components=int(params['n_components']), #整数化
                               fit_inverse_transform=True, 
                               random_state=0)
    transed_x = kpca.fit_transform(X_train)  #训练数据
    inversed_x = kpca.inverse_transform(transed_x)  #将训练结果逆变换

    return mean_squared_error(X_train,inversed_x)   #计算与真值的误差

# 贝叶斯优化
rstate = np.random.default_rng(0)  #设定随机种子,使结果可复现
best = fmin(kpca_error, space, algo=tpe.suggest, rstate=rstate, max_evals=30)
100%|██████████| 30/30 [00:00<00:00, 76.93trial/s, best loss: 0.1872761007179496] 

查看超参数优化的结果。注意若搜索空间中若有非数值型超参数,best的字典值中返回的是最优超参数在列表中的位置,而非原值。

best

{'gamma': 0.2365862168982712, 'kernel': 1, 'n_components': 4.54080206019777}

打印结果。

kernel_list = [ 'rbf', 'poly', 'cosine']
best_params = {'kernel':kernel_list[best['kernel']], #按位置索引
                'n_components': int(best['n_components']), #整数化
                 'gamma': best['gamma']}
best_error = kpca_error(best_params)
print("最佳参数:", best_params)
print("最小误差:", best_error)

最佳参数: {'kernel': 'poly', 'n_components': 4, 'gamma': 0.2365862168982712}
最小误差: 0.1872761007179496

四、2  可视化

根据最优超参建立KPCA模型,再对测试集数据进行转换。转换时需要逐条进行,而非一次喂入全部测试集数据。

#在最优参数中加入inverse_transform和random_state条件
best_params.update({'fit_inverse_transform':True,'random_state':0})

#建立模型并训练
hypo = KernelPCA(**best_params).fit(X_train)

检验下对单个条目或多个条目进行降维时,结果是否一致。(对多个条目进行降维的场景,适用于例如卷积或循环神经网络的模型。)

#测试集第一条数据
print(hypo.transform(X_test[0].reshape(1,-1)))
#测试集前10条数据
print(hypo.transform(X_test[0:10]))

[[ 2.37259716 -0.10926884  0.15115008 -0.14961992]]
[[ 2.37259716 -0.10926884  0.15115008 -0.14961992]
 [-3.64675841 -2.05933382  1.2071096   0.66484288]
 [ 0.73687104  1.80920838 -1.37414963 -1.59350468]
 [ 3.07627164 -0.30732876  0.82768742 -0.35732031]
 [-0.49235334  1.22296917 -0.69379776 -1.75557317]
 [ 0.8285484   1.15747042  2.59311594 -8.92095461]
 [ 2.62482353 -0.49293994 -0.00970395 -0.64279828]
 [-3.90039994 -2.15347714  0.73048196  0.89411751]
 [-0.32589994  1.80970648 -1.65273348 -1.01566239]
 [-0.70053125  1.68987254 -1.65613019 -1.21100263]]

以逐条进行转换为例。

#空列表
test_transed = []
#循环
for i in range(len(X_test)):
    test_transed.append(hypo.transform(X_test[i].reshape(1,-1)))
#去掉一层嵌套,三维变为二维
test_transed = [i[0] for i in test_transed]

降维后的特征数量为4个,以第一个特征为例,对其与其他特征之间关系进行可视化。

import matplotlib.pyplot as plt
colors = ['r', 'g', 'b']  #3个标签类,3种颜色
fig, axes = plt.subplots(2,2,figsize=(10,10)) #4个子图

#建立子图
axes_list = []
for i in range(axes.shape[0]):
    for j in range(axes.shape[1]):
        axes_list.append(axes[i, j])

for h in range(len(axes_list)): #在子图列表中循环
    for i in range(3): #在标签中循环
        points = np.array([test_transed[j] for j in range(len(test_transed)) 
                            if y_test[j] == i])  #找到每类标签对应的转换后的特征值     
        axes_list[h].scatter(points[:, 0], points[:, h], 
                                s=7, c=colors[i]) #对不同标签类上色
        axes_list[h].set_xlabel("transed_feature_"+str(0)) #横坐标均为第一个特征
        axes_list[h].set_ylabel("transed_feature_"+str(h))  #纵坐标为其余特征
             
plt.show()

五、贝叶斯优化——Bayes_opt

、1  调优

其次尝试Bayes_opt库。可通过pip install bayesian-optimization命令安装。Bayes_opt库在参数空间由大量连续型参数构成时表现较好。需要注意该库的超参搜索空间仅适用于数值型超参,对非数值型不适用。

需要注意的几点:

1.算法是最大化目标函数,因此需对误差函数取负。

2.需设置好核函数。根据之前的优化结果,设置为多项式核。

from bayes_opt import BayesianOptimization
from sklearn.metrics import mean_squared_error
from sklearn.decomposition import KernelPCA

def kpca_func(gamma,n_components):   

    kpca = KernelPCA(kernel='poly', gamma=gamma,
                               n_components=int(n_components),
                               fit_inverse_transform=True,
                               random_state=0)

    transed_x = kpca.fit_transform(X_train)
    inversed_x = kpca.inverse_transform(transed_x)

    return -mean_squared_error(X_train,inversed_x)  #x_data

params = {'gamma':(0.01, 0.9),  #搜索范围与之前相同
          'n_components':(1, 5)}  #搜索范围与之前相同

optimizer = BayesianOptimization(kpca_func,pbounds=params,random_state=0)
optimizer.maximize(init_points=1,  #执行随机搜索的步数
                    n_iter=30,   #执行贝叶斯优化的步数)
optimizer.max

|   iter    |  target   |   gamma   | n_comp... |
-------------------------------------------------
| 1         | -0.2997   | 0.4984    | 3.861     |
| 2         | -0.7741   | 0.01      | 1.0       |
| 3         | -0.2994   | 0.4932    | 3.857     |
| 4         | -0.6402   | 0.01      | 5.0       |
| 5         | -0.4416   | 0.9       | 2.969     |
| 6         | -0.6675   | 0.01      | 3.028     |
| 7         | -0.3133   | 0.9       | 3.588     |
| 8         | -0.207    | 0.9       | 4.678     |
| 9         | -0.207    | 0.896     | 4.989     |
| 10        | -0.6183   | 0.9       | 1.842     |
| 11        | -0.6512   | 0.01      | 4.054     |
| 12        | -0.207    | 0.9       | 4.246     |
| 13        | -0.2042   | 0.6525    | 4.876     |
| 14        | -0.2041   | 0.6463    | 4.474     |
| 15        | -0.6183   | 0.9       | 1.0       |
| 16        | -0.302    | 0.5385    | 3.455     |
| 17        | -0.2065   | 0.8406    | 4.452     |
| 18        | -0.205    | 0.7051    | 4.686     |
| 19        | -0.2051   | 0.7161    | 4.99      |
| 20        | -0.2051   | 0.7187    | 4.277     |
| 21        | -0.2062   | 0.8074    | 4.857     |
| 22        | -0.207    | 0.9       | 4.028     |
| 23        | -0.2063   | 0.8192    | 4.137     |
| 24        | -0.2018   | 0.5415    | 4.68      |
| 25        | -0.1403   | 0.5409    | 5.0       |
| 26        | -0.2063   | 0.8188    | 4.136     |
| 27        | -0.6969   | 0.01      | 2.069     |
| 28        | -0.1976   | 0.4197    | 4.982     |
| 29        | -0.2014   | 0.5259    | 4.979     |
| 30        | -0.437    | 0.6476    | 2.482     |
| 31        | -0.193    | 0.3369    | 4.458     |
=================================================

{'target': -0.14030320680092284,
 'params': {'gamma': 0.5409405966633758, 'n_components': 5.0}}

优化过程和最优结果如下。在相同的核函数下,两种算法对其他两个超参数的优化结果有所区别。Bayes_opt优化后的特征数量为5,特征转换后的误差比hyperopt的结果更小一些(去掉负号)。

五、2  可视化

采取相同的方式,对优化后的结果进行可视化。

params = optimizer.max['params']
params['n_components'] = params['n_components'].astype(int)
params.update({'fit_inverse_transform':True,'random_state':0})

byo = KernelPCA(**params).fit(X_train)

test_transed = []
for i in range(len(X_test)):
    test_transed.append(byo.transform(X_test[i].reshape(1,-1)))
#去掉一层嵌套,三维变为二维
test_transed = [i[0] for i in test_transed]
import matplotlib.pyplot as plt
colors = ['r', 'g', 'b']  #3个标签类,3种颜色
fig, axes = plt.subplots(2,3,figsize=(12,12)) #多一个特征,多一个子图

#建立子图
axes_list = []
for i in range(axes.shape[0]):
    for j in range(axes.shape[1]):
        axes_list.append(axes[i, j])

for h in range(len(axes_list)): #在子图列表中循环
    for i in range(3): #在标签中循环
        points = np.array([test_transed[j] for j in range(len(test_transed)) 
                            if y_test[j] == i])  #找到每类标签对应的转换后的特征值     
        axes_list[h].scatter(points[:, 0], points[:, h], 
                                s=7, c=colors[i]) #对不同标签类上色
        axes_list[h].set_xlabel("transed_feature_"+str(0)) #横坐标均为第一个特征
        axes_list[h].set_ylabel("transed_feature_"+str(h))  #纵坐标为其余特征
             
plt.show()


总结

任务完成。Bayes_opt库优化后的误差要更小,但不支持非数值型超参的调优。hyperopt库会更便捷和高效一些。实际做量化策略时,特征数量要比案例中大很多,建议考虑模型计算降维后数据的效率选择目标特征数量的最大值。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
核主元分析KPCA降维特征提取以及故障检测应用-Kernel Principal Component Analysis .zip 本帖最后由 iqiukp 于 2018-11-9 15:02 编辑      核主元分析(Kernel principal component analysis ,KPCA)在降维、特征提取以及故障检测中的应用。主要功能有:(1)训练数据和测试数据的非线性主元提取(降维、特征提取) (2)SPE和T2统计量及其控制限的计算 (3)故障检测 参考文献: Lee J M, Yoo C K, Choi S W, et al. Nonlinear process monitoring using kernel principal component analysis[J]. Chemical engineering science, 2004, 59: 223-234. 1. KPCA的建模过程(故障检测): (1)获取训练数据(工业过程数据需要进行标准化处理) (2)计算核矩阵 (3)核矩阵中心化 (4)特征值分解 (5)特征向量的标准化处理 (6)主元个数的选取 (7)计算非线性主成分(即降维结果或者特征提取结果) (8)SPE和T2统计量的控制限计算 function model = kpca_train % DESCRIPTION % Kernel principal component analysis % %       mappedX = kpca_train % % INPUT %   X            Training samples %                N: number of samples %                d: number of features %   options      Parameters setting % % OUTPUT %   model        KPCA model % % % Created on 9th November, 2018, by Kepeng Qiu. % number of training samples L = size; % Compute the kernel matrix K = computeKM; % Centralize the kernel matrix unit = ones/L; K_c = K-unit*K-K*unit unit*K*unit; % Solve the eigenvalue problem [V,D] = eigs; lambda = diag; % Normalize the eigenvalue V_s = V ./ sqrt'; % Compute the numbers of principal component % Extract the nonlinear component if options.type == 1 % fault detection     dims = find) >= 0.85,1, 'first'); else     dims = options.dims; end mappedX  = K_c* V_s ; % Store the results model.mappedX =  mappedX ; model.V_s = V_s; model.lambda = lambda; model.K_c = K_c; model.L = L; model.dims = dims; model.X = X; model.K = K; model.unit = unit; model.sigma = options.sigma; % Compute the threshold model.beta = options.beta;% corresponding probabilities [SPE_limit,T2_limit] = comtupeLimit; model.SPE_limit = SPE_limit; model.T2_limit = T2_limit; end复制代码2. KPCA的测试过程: (1)获取测试数据(工业过程数据需要利用训练数据的均值和标准差进行标准化处理) (2)计算核矩阵 (3)核矩阵中心化 (4)计算非线性主成分(即降维结果或者特征提取结果) (5)SPE和T2统计量的计算 function [SPE,T2,mappedY] = kpca_test % DESCRIPTION % Compute the T2 statistic, SPE statistic,and the nonlinear component of Y % %       [SPE,T2,mappedY] = kpca_test % % INPUT %   model       KPCA model %   Y           test data % % OUTPUT %   SPE         the SPE statistic %   T2          the T2 statistic %   mappedY     the nonlinear component of Y % % Created on 9th November, 2018, by Kepeng Qiu. % Compute Hotelling's T2 statistic % T2 = diag)*model.mappedX'); % the number of test samples L = size; % Compute the kernel matrix Kt = computeKM; % Centralize the kernel matrix unit = ones/model.L; Kt_c = Kt-unit*model.K-Kt*model.unit unit*model.K*model.unit; % Extract the nonlinear component mappedY = Kt_c*model.V_s; % Compute Hotelling's T2 statistic T2 = diag)*mappedY'); % Compute the squared prediction error SPE = sum.^2,2)-sum; end复制代码 3. demo1: 降维、特征提取 源代码 % Demo1: dimensionality reduction or feature extraction % ---------------------------------------------------------------------% clc clear all close all addpath) % 4 circles load circledata % X = circledata; for i = 1:4     scatter:250*i,1),X:250*i,2))     hold on end % Parameters setting options.sigma = 5;   % kernel width options.dims  = 2;   % output dimension options.type  = 0;   % 0:dimensionality reduction or feature extraction                      % 1:fault detection options.beta  = 0.9; % corresponding probabilities options.cpc  = 0.85; % Principal contribution rate % Train KPCA model model = kpca_train; figure for i = 1:4     scatter:250*i,1), ...         model.mappedX:250*i,2))     hold on end 复制代码(2)结果 (分别为原图和特征提取后的图) demo1-1.png demo1-2.png 4. demo2: 故障检测(需要调节核宽度、主元贡献率和置信度等参数来提高故障检测效果) (1)源代码 % Demo2: Fault detection % X: training samples % Y: test samples % Improve the performance of fault detection by adjusting parameters % 1. options.sigma = 16;   % kernel width % 2. options.beta          % corresponding probabilities % 3. options.cpc  ;        % principal contribution rate % ---------------------------------------------------------------------% clc clear all close all addpath) % X = rand; Y = rand; Y = rand 3; Y = rand*3; % Normalization % mu = mean; % st = std; % X = zscore; % Y = bsxfun,st); % Parameters setting options.sigma = 16;   % kernel width options.dims  = 2;   % output dimension options.type  = 1;   % 0:dimensionality reduction or feature extraction                      % 1:fault detection options.beta  = 0.9; % corresponding probabilities options.cpc  = 0.85; % principal contribution rate % Train KPCA model model = kpca_train; % Test a new sample Y [SPE,T2,mappedY] = kpca_test; % Plot the result plotResult; plotResult; 复制代码(2)结果(分别是SPE统计量和T2统计量的结果图) demo2-1.png demo2-2.png    附件是基于KPCA降维、特征提取和故障检测程序源代码。如有错误的地方请指出,谢谢。 Kernel Principal Component Analysis .zip KPCA

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值