001/* 002 * Copyright (c) 2015-2020, Oracle and/or its affiliates. All rights reserved. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.tribuo.classification.sgd.kernel; 018 019import com.oracle.labs.mlrg.olcut.config.ArgumentException; 020import com.oracle.labs.mlrg.olcut.config.Option; 021import org.tribuo.Trainer; 022import org.tribuo.classification.ClassificationOptions; 023import org.tribuo.math.kernel.Kernel; 024import org.tribuo.math.kernel.Linear; 025import org.tribuo.math.kernel.Polynomial; 026import org.tribuo.math.kernel.RBF; 027import org.tribuo.math.kernel.Sigmoid; 028 029import java.util.logging.Logger; 030 031/** 032 * Options for using the KernelSVMTrainer. 033 * <p> 034 * See: 035 * <pre> 036 * Shalev-Shwartz S, Singer Y, Srebro N, Cotter A 037 * "Pegasos: Primal Estimated Sub-Gradient Solver for SVM" 038 * Mathematical Programming, 2011. 039 * </pre> 040 */ 041public class KernelSVMOptions implements ClassificationOptions<KernelSVMTrainer> { 042 private static final Logger logger = Logger.getLogger(KernelSVMOptions.class.getName()); 043 044 /** 045 * The kernel types. 046 */ 047 public enum KernelEnum { 048 /** 049 * Uses a {@link Linear} kernel. 050 */ 051 LINEAR, 052 /** 053 * Uses a {@link Polynomial} kernel. 054 */ 055 POLYNOMIAL, 056 /** 057 * Uses a {@link Sigmoid} kernel. 058 */ 059 SIGMOID, 060 /** 061 * Uses an {@link RBF} kernel. 062 */ 063 RBF 064 } 065 066 /** 067 * Intercept in kernel function. Defaults to 1.0. 068 */ 069 @Option(longName = "kernel-intercept", usage = "Intercept in kernel function. Defaults to 1.0.") 070 public double kernelIntercept = 1.0; 071 /** 072 * Degree in polynomial kernel function. Defaults to 1.0. 073 */ 074 @Option(longName = "kernel-degree", usage = "Degree in polynomial kernel function. Defaults to 1.0.") 075 public double kernelDegree = 1.0; 076 /** 077 * Gamma value in kernel function. Defaults to 1.0. 078 */ 079 @Option(longName = "kernel-gamma", usage = "Gamma value in kernel function. Defaults to 1.0.") 080 public double kernelGamma = 1.0; 081 /** 082 * Number of SGD epochs. Defaults to 5. 083 */ 084 @Option(longName = "kernel-epochs", usage = "Number of SGD epochs. Defaults to 5.") 085 public int kernelEpochs = 5; 086 /** 087 * Kernel function. Defaults to LINEAR. 088 */ 089 @Option(longName = "kernel-kernel", usage = "Kernel function. Defaults to LINEAR.") 090 public KernelEnum kernelKernel = KernelEnum.LINEAR; //TODO should the default be KernelEnum.RBF? 091 /** 092 * Lambda value in gradient optimisation. Defaults to 0.01. 093 */ 094 @Option(longName = "kernel-lambda", usage = "Lambda value in gradient optimisation. Defaults to 0.01.") 095 public double kernelLambda = 0.01; 096 /** 097 * Log the objective after n examples. Defaults to 100. 098 */ 099 @Option(longName = "kernel-logging-interval", usage = "Log the objective after <int> examples. Defaults to 100.") 100 public int kernelLoggingInterval = 100; 101 /** 102 * Sets the random seed for the Kernel SVM. 103 */ 104 @Option(longName = "kernel-seed", usage = "Sets the random seed for the Kernel SVM.") 105 public long kernelSeed = Trainer.DEFAULT_SEED; 106 107 @Override 108 public KernelSVMTrainer getTrainer() { 109 logger.info("Configuring Kernel SVM Trainer"); 110 Kernel kernelObj = null; 111 switch (kernelKernel) { 112 case LINEAR: 113 logger.info("Using a linear kernel"); 114 kernelObj = new Linear(); 115 break; 116 case POLYNOMIAL: 117 logger.info("Using a Polynomial kernel with gamma " + kernelGamma + ", intercept " + kernelIntercept + ", and degree " + kernelDegree); 118 kernelObj = new Polynomial(kernelGamma, kernelIntercept, kernelDegree); 119 break; 120 case RBF: 121 logger.info("Using an RBF kernel with gamma " + kernelGamma); 122 kernelObj = new RBF(kernelGamma); 123 break; 124 case SIGMOID: 125 logger.info("Using a tanh kernel with gamma " + kernelGamma + ", and intercept " + kernelIntercept); 126 kernelObj = new Sigmoid(kernelGamma, kernelIntercept); 127 break; 128 default: 129 logger.warning("Unknown kernel function " + kernelKernel); 130 throw new ArgumentException("kernel-kernel", "Unknown kernel function " + kernelKernel); 131 } 132 logger.info(String.format("Set logging interval to %d", kernelLoggingInterval)); 133 return new KernelSVMTrainer(kernelObj, kernelLambda, kernelEpochs, kernelLoggingInterval, kernelSeed); 134 } 135}