create_class_svmT_create_class_svmCreateClassSvmCreateClassSvmcreate_class_svm创建类支持向量机(算子)

名称

create_class_svmT_create_class_svmCreateClassSvmCreateClassSvmcreate_class_svm — 创建用于模式分类的支持向量机。

签名

create_class_svm( : : NumFeatures, KernelType, KernelParam, Nu, NumClasses, Mode, Preprocessing, NumComponents : SVMHandle)

Herror T_create_class_svm(const Htuple NumFeatures, const Htuple KernelType, const Htuple KernelParam, const Htuple Nu, const Htuple NumClasses, const Htuple Mode, const Htuple Preprocessing, const Htuple NumComponents, Htuple* SVMHandle)

void CreateClassSvm(const HTuple& NumFeatures, const HTuple& KernelType, const HTuple& KernelParam, const HTuple& Nu, const HTuple& NumClasses, const HTuple& Mode, const HTuple& Preprocessing, const HTuple& NumComponents, HTuple* SVMHandle)

void HClassSvm::HClassSvm(Hlong NumFeatures, const HString& KernelType, double KernelParam, double Nu, Hlong NumClasses, const HString& Mode, const HString& Preprocessing, Hlong NumComponents)

void HClassSvm::HClassSvm(Hlong NumFeatures, const char* KernelType, double KernelParam, double Nu, Hlong NumClasses, const char* Mode, const char* Preprocessing, Hlong NumComponents)

void HClassSvm::HClassSvm(Hlong NumFeatures, const wchar_t* KernelType, double KernelParam, double Nu, Hlong NumClasses, const wchar_t* Mode, const wchar_t* Preprocessing, Hlong NumComponents)   ( Windows only)

void HClassSvm::CreateClassSvm(Hlong NumFeatures, const HString& KernelType, double KernelParam, double Nu, Hlong NumClasses, const HString& Mode, const HString& Preprocessing, Hlong NumComponents)

void HClassSvm::CreateClassSvm(Hlong NumFeatures, const char* KernelType, double KernelParam, double Nu, Hlong NumClasses, const char* Mode, const char* Preprocessing, Hlong NumComponents)

void HClassSvm::CreateClassSvm(Hlong NumFeatures, const wchar_t* KernelType, double KernelParam, double Nu, Hlong NumClasses, const wchar_t* Mode, const wchar_t* Preprocessing, Hlong NumComponents)   ( Windows only)

static void HOperatorSet.CreateClassSvm(HTuple numFeatures, HTuple kernelType, HTuple kernelParam, HTuple nu, HTuple numClasses, HTuple mode, HTuple preprocessing, HTuple numComponents, out HTuple SVMHandle)

public HClassSvm(int numFeatures, string kernelType, double kernelParam, double nu, int numClasses, string mode, string preprocessing, int numComponents)

void HClassSvm.CreateClassSvm(int numFeatures, string kernelType, double kernelParam, double nu, int numClasses, string mode, string preprocessing, int numComponents)

def create_class_svm(num_features: int, kernel_type: str, kernel_param: float, nu: float, num_classes: int, mode: str, preprocessing: str, num_components: int) -> HHandle

描述

create_class_svmcreate_class_svmCreateClassSvmCreateClassSvmCreateClassSvmcreate_class_svm 创建一个支持向量机,可用于模式分类。待分类模式的维度由 NumFeaturesNumFeaturesNumFeaturesNumFeaturesnumFeaturesnum_features 指定,不同类别的数量由 NumClassesNumClassesNumClassesNumClassesnumClassesnum_classes 指定。

对于二元分类问题,当类之间可线性分离时,支持向量机算法会从训练集中选取数据向量,用于构造不同类之间最优的分离超平面。该超平面之所以最优,在于它使不同类凸包之间的间隔达到最大值。位于间隔处的训练样本定义了该超平面,这些样本被称为 support vectors(SV)支持向量。

特征向量 z 的分类采用以下公式进行: 此处, 为支持向量, 编码其类别归属( ), 为权重系数。超平面到原点的距离为 b。 和 b 是在训练过程中通过 train_class_svmtrain_class_svmTrainClassSvmTrainClassSvmTrainClassSvmtrain_class_svm 确定的。请注意,仅需原始训练集的一个子集( :支持向量数量)即可定义决策边界,因此非支持向量的数据向量将被舍弃。分类速度取决于支持向量与待分类特征向量之间点积的计算效率,因此与特征向量的长度及支持向量数量 相关。

对于类不可线性分离的分类问题,该算法通过两种方式进行扩展。首先,在训练过程中利用松弛变量补偿一定数量的错误(混淆)。这意味着支持向量 受到正则化常数的上限约束。为实现对训练错误数量的直观控制,采用 Nu-SVM 版本的训练算法。此处正则化参数 NuNuNuNununu 既是训练误差数量的渐近上界,也是支持向量数量的渐近下界。经验法则建议将 NuNuNuNununu 设为应用场景预期误差率的先验值,例如 0.01(对应最大训练误差 1%)。需注意:NuNuNuNununu 值过大可能导致训练问题不可行,即 SVM 无法正确训练(详见 train_class_svmtrain_class_svmTrainClassSvmTrainClassSvmTrainClassSvmtrain_class_svm)。由于该问题仅能在训练过程中发现,故只能在此处抛出异常。此时需创建 NuNuNuNununu 值更小的全新支持向量机。

其次,由于上述 SVM 仅计算特征向量间的点积,因此可在训练与测试算法中引入核函数。这意味着点积运算被核函数所替代,该函数在更高维特征空间中隐式执行点积运算。通过适当的核变换,原本不可线性分离的分类任务在更高维特征空间中便可实现线性分离。

可通过参数 KernelTypeKernelTypeKernelTypeKernelTypekernelTypekernel_type 选择不同的核函数。当 KernelTypeKernelTypeKernelTypeKernelTypekernelTypekernel_type = 'linear'"linear""linear""linear""linear""linear" 时,将按上述公式计算点积。该核函数仅适用于线性或近似线性可分的分类任务。此时参数 KernelParamKernelParamKernelParamKernelParamkernelParamkernel_param 将被忽略。

径向基函数(RBF)KernelTypeKernelTypeKernelTypeKernelTypekernelTypekernel_type = 'rbf'"rbf""rbf""rbf""rbf""rbf" 是核函数的最佳选择,因为它在许多分类任务中都能取得良好效果。其定义如下: 此处使用参数 KernelParamKernelParamKernelParamKernelParamkernelParamkernel_param 来选择 值。 的直观含义是支持向量对其周围区域的影响程度。当 值较大(对周围区域影响较小)时,意味着每个训练向量都成为支持向量。此时训练算法虽能“死记硬背”训练数据,却完全丧失泛化能力(过拟合)。此外,训练/分类耗时将显著增加。当 值过小(对周围区域影响较大),则导致仅有少量支持向量定义分类超平面(欠拟合)。典型策略是先选取较小的 -NuNuNuNununu 组合,在识别率持续提升时逐步增大参数值。

KernelTypeKernelTypeKernelTypeKernelTypekernelTypekernel_type = 'polynomial_homogeneous'"polynomial_homogeneous""polynomial_homogeneous""polynomial_homogeneous""polynomial_homogeneous""polynomial_homogeneous"'polynomial_inhomogeneous'"polynomial_inhomogeneous""polynomial_inhomogeneous""polynomial_inhomogeneous""polynomial_inhomogeneous""polynomial_inhomogeneous" 时,可选择多项式核函数。它们定义如下: 多项式核的次数必须通过 KernelParamKernelParamKernelParamKernelParamkernelParamkernel_param 参数设置。请注意,过高的次数(d > 10)可能导致数值计算问题。

经验法则表明,RBF 核适用于大多数分类问题,因此在绝大多数情况下都应优先选用。不过,线性核与多项式核在特定应用场景中可能表现更佳,可进行测试比较。请注意,新颖性检测 ModeModeModeModemodemodereduce_class_svmreduce_class_svmReduceClassSvmReduceClassSvmReduceClassSvmreduce_class_svm 算子仅支持 RBF 核。

ModeModeModeModemodemode 定义了分类任务的基本类型,包括如何将多类决策问题分解为二元子问题,或是否启用名为新颖性检测 'novelty-detection'"novelty-detection""novelty-detection""novelty-detection""novelty-detection""novelty-detection" 的特殊分类器模式。当 ModeModeModeModemodemode = 'one-versus-all'"one-versus-all""one-versus-all""one-versus-all""one-versus-all""one-versus-all"(一对多)时,系统创建的分类器会将每个类别与其余训练数据进行比较。测试阶段将选择输出值最大的类别(参见无符号分类公式)。 ModeModeModeModemodemode = 'one-versus-one'"one-versus-one""one-versus-one""one-versus-one""one-versus-one""one-versus-one"(一对一)则构建单类间二元分类器。测试时进行投票,多数票所属类别即为结果。多类分类的最优 ModeModeModeModemodemode 取决于类别数量。当存在 n 个类别时, 'one-versus-all'"one-versus-all""one-versus-all""one-versus-all""one-versus-all""one-versus-all" 模式会生成 n 个分类器,而 'one-versus-one'"one-versus-one""one-versus-one""one-versus-one""one-versus-one""one-versus-one" 模式仅生成 n(n-1)/2 个分类器。需注意:对于二元决策任务,'one-versus-one'"one-versus-one""one-versus-one""one-versus-one""one-versus-one""one-versus-one" 模式仅需创建一个分类器,而 'one-versus-all'"one-versus-all""one-versus-all""one-versus-all""one-versus-all""one-versus-all" 模式会多余地创建两个对称分类器。当类别较少(约 10 类以内)时,'one-versus-one'"one-versus-one""one-versus-one""one-versus-one""one-versus-one""one-versus-one" 模式在训练和测试阶段更高效,因为子分类器均由较少训练数据构成,从而产生更少的支持向量。当类别数量庞大时,'one-versus-all'"one-versus-all""one-versus-all""one-versus-all""one-versus-all""one-versus-all" 策略会产生数量惊人的子分类器(其数量随类别数目平方增长),此时 'one-versus-one'"one-versus-one""one-versus-one""one-versus-one""one-versus-one""one-versus-one" 策略更为可取。

分类的一个特例是 ModeModeModeModemodemode = 'novelty-detection'"novelty-detection""novelty-detection""novelty-detection""novelty-detection""novelty-detection",此时测试数据仅根据其是否属于训练数据进行分类,即 NumClassesNumClassesNumClassesNumClassesnumClassesnum_classes 必须设置为 1。分离超平面围绕训练数据分布,从而隐式地将训练数据与拒绝类分隔开来。其优势在于无需显式定义拒绝类——这在纹理分类等特定应用中难以实现。生成的支持向量均位于边界处。参数 NuNuNuNununu 用于指定训练数据集中异常值的比例。需注意,在 'novelty-detection'"novelty-detection""novelty-detection""novelty-detection""novelty-detection""novelty-detection" 模式下,训练数据的类别以索引 1 返回,拒绝类以索引 0 返回。因此首类即为拒绝类。而使用 MLP 分类器时,默认最后类别作为拒绝类。

参数 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessingNumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 可用于指定特征向量的预处理方式。当 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'none'"none""none""none""none""none" 时,特征向量将未经修改地传递给 SVM。此时 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 将被忽略。

对于 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing 的其他所有值,训练数据集在训练过程中以及后续分类阶段均用于计算特征向量的变换。

对于 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'normalization'"normalization""normalization""normalization""normalization""normalization" 的情况,特征向量将被归一化。若采用多项式核函数,则训练数据集的最小值与最大值将分别转换为 -1 和 +1。若采用 RBF 核,则通过从训练向量中减去均值,并将结果除以训练向量各成分的标准差来实现数据归一化。因此,转换后的特征向量具有均值为 0、标准差为 1 的特性。归一化操作不会改变特征向量的长度。此时 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 将被忽略。当特征向量的均值和标准差分别显著偏离 0 和 1 时,或特征向量各成分采用不同计量单位时(例如部分数据为灰度值特征而部分为区域特征,或区域特征本身存在混合类型,如圆度 'circularity'(单位:标量)与面积 'area'(单位:平方像素)),可采用此变换方法。通常应执行归一化转换,因为它能提升训练/测试过程中的数值稳定性。

对于 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'principal_components'"principal_components""principal_components""principal_components""principal_components""principal_components",将执行主成分分析(PCA)。首先对特征向量进行归一化处理(参见上文)。随后计算正交变换(即特征空间中的旋转),以消除训练向量间的关联性。变换后,训练向量的均值为 0,其协方差矩阵成为对角矩阵。该变换的选取原则是:将包含最大变异性的特征集中于变换后特征向量的前几个主成分。由此可省略特征向量末端主成分(通常主要受噪声影响)的变换特征,而不会丢失大量信息。参数 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 用于确定应采用多少个转换后的特征向量成分。最多可选取 NumFeaturesNumFeaturesNumFeaturesNumFeaturesnumFeaturesnum_features 个成分。算子 get_prep_info_class_svmget_prep_info_class_svmGetPrepInfoClassSvmGetPrepInfoClassSvmGetPrepInfoClassSvmget_prep_info_class_svm 可用于确定每个转换后的成分包含多少信息。从而辅助选择 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 的值。与数据归一化类似,当特征向量的均值和标准差分别显著偏离 0 和 1 时,或特征向量中数据成分采用不同计量单位时,均可采用此转换方式。此外,若特征间存在高度相关性,该转换同样具有实用价值。请注意,RBF 核对 PCA 进行的降维具有很强的稳健性,因此在加快分类速度时应优先选用。

PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'canonical_variates'"canonical_variates""canonical_variates""canonical_variates""canonical_variates""canonical_variates" 指定的转换首先对训练向量进行归一化,然后在所有类别上对训练向量进行平均去相关处理。该转换同时最大化分离各类别的均值。与 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'principal_components'"principal_components""principal_components""principal_components""principal_components""principal_components" 类似,转换后的成分按信息含量排序,因此可省略信息含量较低的转换成分。对于典型变量法,最多可选取 min(NumClassesNumClassesNumClassesNumClassesnumClassesnum_classes-1, NumFeaturesNumFeaturesNumFeaturesNumFeaturesnumFeaturesnum_features) 个成分。同样地,通过 get_prep_info_class_svmget_prep_info_class_svmGetPrepInfoClassSvmGetPrepInfoClassSvmGetPrepInfoClassSvmget_prep_info_class_svm 可确定转换后成分的信息含量。与主成分分析类似,典型变量法既能减少数据量而不丢失大量信息,又能优化降维后类别的可分离性。典型变量的计算也称为线性判别分析。

对于最后两种转换类型('principal_components'"principal_components""principal_components""principal_components""principal_components""principal_components"'canonical_variates'"canonical_variates""canonical_variates""canonical_variates""canonical_variates""canonical_variates"),SVM 输入数据的长度由 NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components 决定,而 NumFeaturesNumFeaturesNumFeaturesNumFeaturesnumFeaturesnum_features 则决定输入数据的维度(即未转换特征向量的长度)。因此,采用这两种变换中的任一种,可缩减支持 SVM 对于数据长度的规模,从而缩短 SVM 训练/分类时间。

使用 create_class_svmcreate_class_svmCreateClassSvmCreateClassSvmCreateClassSvmcreate_class_svm 创建 SVM 后,通常通过反复调用 add_sample_class_svmadd_sample_class_svmAddSampleClassSvmAddSampleClassSvmAddSampleClassSvmadd_sample_class_svmread_samples_class_svmread_samples_class_svmReadSamplesClassSvmReadSamplesClassSvmReadSamplesClassSvmread_samples_class_svm 向 SVM 添加训练样本。随后,通常使用 train_class_svmtrain_class_svmTrainClassSvmTrainClassSvmTrainClassSvmtrain_class_svm 对 SVM 进行训练。此后,可通过 write_class_svmwrite_class_svmWriteClassSvmWriteClassSvmWriteClassSvmwrite_class_svm 保存 SVM。或者,训练完成后可立即使用 classify_class_svmclassify_class_svmClassifyClassSvmClassifyClassSvmClassifyClassSvmclassify_class_svm 对数据进行分类。

SVM 与多层感知器(MLP)(参见 create_class_mlpcreate_class_mlpCreateClassMlpCreateClassMlpCreateClassMlpcreate_class_mlp)的对比通常表明:SVMs 在训练速度上普遍更胜一筹,尤其面对海量训练集时表现更为突出,且其识别率略优于 MLPs。而 MLP 在分类速度方面更具优势,因此在时间敏感型应用中应优先选用。请注意,此建议基于参数已进行最优调优的前提。

执行信息

此算子返回一个句柄。请注意,即使该句柄被用作特定算子的输入参数,这些算子仍可能改变此句柄类型的实例状态。

参数

NumFeaturesNumFeaturesNumFeaturesNumFeaturesnumFeaturesnum_features (输入控制)  integer HTupleintHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

SVM 的输入变量(特征)数量。

默认值: 10

建议值: 1, 2, 3, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100

限制: NumFeatures >= 1

KernelTypeKernelTypeKernelTypeKernelTypekernelTypekernel_type (输入控制)  string HTuplestrHTupleHtuple (string) (string) (HString) (char*)

内核类型。

默认值: 'rbf' "rbf" "rbf" "rbf" "rbf" "rbf"

值列表: 'linear'"linear""linear""linear""linear""linear", 'polynomial_homogeneous'"polynomial_homogeneous""polynomial_homogeneous""polynomial_homogeneous""polynomial_homogeneous""polynomial_homogeneous", 'polynomial_inhomogeneous'"polynomial_inhomogeneous""polynomial_inhomogeneous""polynomial_inhomogeneous""polynomial_inhomogeneous""polynomial_inhomogeneous", 'rbf'"rbf""rbf""rbf""rbf""rbf"

KernelParamKernelParamKernelParamKernelParamkernelParamkernel_param (输入控制)  real HTuplefloatHTupleHtuple (real) (double) (double) (double)

核函数的附加参数。对于 RBF 核,该参数对应 ;对于多项式核,则对应其次数。

默认值: 0.02

建议值: 0.01, 0.02, 0.05, 0.1, 0.5

NuNuNuNununu (输入控制)  real HTuplefloatHTupleHtuple (real) (double) (double) (double)

SVM 的正则化常数。

默认值: 0.05

建议值: 0.0001, 0.001, 0.01, 0.05, 0.1, 0.2, 0.3

限制: Nu > 0.0 && Nu < 1.0

NumClassesNumClassesNumClassesNumClassesnumClassesnum_classes (输入控制)  integer HTupleintHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

类别数量。

默认值: 5

建议值: 2, 3, 4, 5, 6, 7, 8, 9, 10

限制: NumClasses >= 1

ModeModeModeModemodemode (输入控制)  string HTuplestrHTupleHtuple (string) (string) (HString) (char*)

SVM 的模式。

默认值: 'one-versus-one' "one-versus-one" "one-versus-one" "one-versus-one" "one-versus-one" "one-versus-one"

值列表: 'novelty-detection'"novelty-detection""novelty-detection""novelty-detection""novelty-detection""novelty-detection", 'one-versus-all'"one-versus-all""one-versus-all""one-versus-all""one-versus-all""one-versus-all", 'one-versus-one'"one-versus-one""one-versus-one""one-versus-one""one-versus-one""one-versus-one"

PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing (输入控制)  string HTuplestrHTupleHtuple (string) (string) (HString) (char*)

用于转换特征向量的预处理类型。

默认值: 'normalization' "normalization" "normalization" "normalization" "normalization" "normalization"

值列表: 'canonical_variates'"canonical_variates""canonical_variates""canonical_variates""canonical_variates""canonical_variates", 'none'"none""none""none""none""none", 'normalization'"normalization""normalization""normalization""normalization""normalization", 'principal_components'"principal_components""principal_components""principal_components""principal_components""principal_components"

NumComponentsNumComponentsNumComponentsNumComponentsnumComponentsnum_components (输入控制)  integer HTupleintHTupleHtuple (integer) (int / long) (Hlong) (Hlong)

预处理参数:转换特征的数量(当 PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'none'"none""none""none""none""none"PreprocessingPreprocessingPreprocessingPreprocessingpreprocessingpreprocessing = 'normalization'"normalization""normalization""normalization""normalization""normalization" 时忽略此参数)。

默认值: 10

建议值: 1, 2, 3, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100

限制: NumComponents >= 1

SVMHandleSVMHandleSVMHandleSVMHandleSVMHandlesvmhandle (输出控制)  class_svm HClassSvm, HTupleHHandleHTupleHtuple (handle) (IntPtr) (HHandle) (handle)

SVM 句柄。

示例(HDevelop)

create_class_svm (NumFeatures, 'rbf', 0.01, 0.01, NumClasses,\
                  'one-versus-all', 'normalization', NumFeatures,\
                  SVMHandle)
* Generate and add the training data
for J := 0 to NumData-1 by 1
    * Generate training features and classes
    * Data = [...]
    * Class = ...
    add_sample_class_svm (SVMHandle, Data, Class)
endfor
* Train the SVM
train_class_svm (SVMHandle, 0.001, 'default')
* Use the SVM to classify unknown data
for J := 0 to N-1 by 1
    * Extract features
    * Features = [...]
    classify_class_svm (SVMHandle, Features, 1, Class)
endfor

结果

如果参数有效,算子 create_class_svmcreate_class_svmCreateClassSvmCreateClassSvmCreateClassSvmcreate_class_svm 返回值 2 (H_MSG_TRUE)。如有必要,则抛出异常。

可能的后继

add_sample_class_svmadd_sample_class_svmAddSampleClassSvmAddSampleClassSvmAddSampleClassSvmadd_sample_class_svm

替代

read_dl_classifierread_dl_classifierReadDlClassifierReadDlClassifierReadDlClassifierread_dl_classifier, create_class_mlpcreate_class_mlpCreateClassMlpCreateClassMlpCreateClassMlpcreate_class_mlp, create_class_gmmcreate_class_gmmCreateClassGmmCreateClassGmmCreateClassGmmcreate_class_gmm

另见

clear_class_svmclear_class_svmClearClassSvmClearClassSvmClearClassSvmclear_class_svm, train_class_svmtrain_class_svmTrainClassSvmTrainClassSvmTrainClassSvmtrain_class_svm, classify_class_svmclassify_class_svmClassifyClassSvmClassifyClassSvmClassifyClassSvmclassify_class_svm

参考文献

Bernhard Schölkopf, Alexander J.Smola: “Learning with Kernels”; MIT Press, London; 1999.
John Shawe-Taylor, Nello Cristianini: “Kernel Methods for Pattern Analysis”; Cambridge University Press, Cambridge; 2004.

模块

基础