weka.core.metrics
Class KL

java.lang.Object
  extended byweka.core.metrics.Metric
      extended byweka.core.metrics.LearnableMetric
          extended byweka.core.metrics.KL
All Implemented Interfaces:
java.lang.Cloneable, InstanceConverter, OptionHandler, java.io.Serializable

public class KL
extends LearnableMetric
implements InstanceConverter, OptionHandler

KL class Implements weighted Kullback-Leibler divergence

See Also:
Serialized Form

Field Summary
static int CONVERSION_EXPONENTIAL
           
static int CONVERSION_LAPLACIAN
          We can have different ways of converting from distance to similarity
static int CONVERSION_UNIT
           
 double LOG2
           
protected  double m_alpha
           
protected  double m_alphaDecayRate
           
protected  int m_conversionType
          The method of converting, by default laplacian
protected  double m_currAlpha
           
protected  HashMapVector m_datasetFrequencies
          Frequencies over the entire dataset used for smoothing
protected  java.util.HashMap m_instanceConstraintMap
          A hashmap that maps every instance to a set of instances with which JS has been computed
protected  java.util.HashMap m_instanceNormHash
          We hash sum(p log(p)) terms for the input instances to speed up computation
protected  double m_lambdaJM
          The lambda value for the Jelinek-Mercer smoothing
protected  MetricLearner m_metricLearner
          A metric learner responsible for training the parameters of the metric
protected  int m_numTotalTokens
          Total number of tokens in the dataset
protected  double m_pseudoCountDirichlet
          The pseudocount value for the Dirichlet smoothing
protected  int m_smoothingType
          The smoothing method
protected  boolean m_useDITCSmoothing
          Even with unsmoothed data, DITC-type smoothing can be used
protected  boolean m_useIDivergence
          We can switch between regular KL divergence and I-divergence
static int SMOOTHING_DIRICHLET
           
static int SMOOTHING_JELINEK_MERCER
           
static int SMOOTHING_UNSMOOTHED
          Different smoothing methods for obtaining probability distributions from frequencies
static Tag[] TAGS_CONVERSION
           
static Tag[] TAGS_SMOOTHING
           
 
Fields inherited from class weka.core.metrics.LearnableMetric
m_attrWeights, m_classifier, m_classifierClassName, m_classifierRequiresNominalClass, m_numPosDiffInstances, m_posNegDiffInstanceRatio, m_trainable
 
Fields inherited from class weka.core.metrics.Metric
m_attrIdxs, m_classIndex, m_numAttributes
 
Constructor Summary
KL()
          Create a default new metric
KL(int numAttributes)
          Create a new metric.
KL(int[] _attrIdxs)
          Creates a new metric which takes specified attributes.
 
Method Summary
 void buildMetric(Instances data)
          Create a new metric for operating on specified instances
 void buildMetric(int numAttributes)
          Generates a new Metric.
 void buildMetric(int numAttributes, java.lang.String[] options)
          Generates a new Metric.
 java.lang.Object clone()
          Create a copy of this metric
protected  double convertFrequency(double freq, double numTotalTokens, java.lang.String token)
          Given a frequency of a given token in a document, convert it to a probability value for that document's distribution
 Instance convertInstance(Instance instance)
          Take an instance and convert it for use by the metric
 Instance createDiffInstance(Instance instance1, Instance instance2)
          Create an instance with features corresponding to dot-product components of the two given instances
 Instance createDiffInstanceJS(Instance instance1, Instance instance2)
          Create an instance with features corresponding to JS components
protected  Instance createDiffInstanceJSNonSparse(Instance instance1, Instance instance2)
          Create a nonsparse instance with features corresponding to dot-product components of the two given instances
protected  SparseInstance createDiffInstanceJSSparse(SparseInstance instance1, SparseInstance instance2)
          Create a sparse instance with features corresponding to dot-product components of the two given instances
protected  Instance createDiffInstanceJSSparseNonSparse(SparseInstance instance1, Instance instance2)
          Create an instance with features corresponding to dot-product components of the two given instances
protected  Instance createDiffInstanceNonSparse(Instance instance1, Instance instance2)
          Create a nonsparse instance with features corresponding to dot-product components of the two given instances
protected  SparseInstance createDiffInstanceSparse(SparseInstance instance1, SparseInstance instance2)
          Create a sparse instance with features corresponding to dot-product components of the two given instances
protected  Instance createDiffInstanceSparseNonSparse(SparseInstance instance1, Instance instance2)
          Create an instance with features corresponding to dot-product components of the two given instances
 double distance(Instance instance1, Instance instance2)
          Returns a distance value between two instances.
 double distanceInternal(Instance instance1, Instance instance2)
          Returns a distance value between two instances.
 double distanceJS(Instance instance1, Instance instance2)
          Returns Jensen-Shannon distance value between two instances.
 double distanceJSNonSparse(Instance instance1, Instance instance2)
          Returns Jensen-Shannon distance between non-sparse instances without using the weights
 double distanceJSSparse(SparseInstance instance1, SparseInstance instance2)
          Returns Jensen-Shannon distance between two sparse instances.
 double distanceJSSparseNonSparse(SparseInstance instance1, Instance instance2)
          Returns Jensen-Shannon distance between a non-sparse instance and a sparse instance
 double distanceNonSparse(Instance instance1, Instance instance2)
          Returns a distance value between non-sparse instances without using the weights
 double distanceNonWeighted(Instance instance1, Instance instance2)
          Returns distance between two instances without using the weights.
 double distanceSparse(SparseInstance instance1, SparseInstance instance2)
          Returns a distance value between two sparse instances.
 double distanceSparseNonSparse(SparseInstance instance1, Instance instance2)
          Returns a distance value between a non-sparse instance and a sparse instance
 double getAlpha()
          Get the initial value of the smoothing parameter alpha in DITC smoothing
 double getAlphaDecayRate()
          Get the initial value of the the decay rate of alpha in DITC smoothing
 Instance getCentroidInstance(Instances instances, boolean fastMode, boolean normalized)
          Given a cluster of instances, return the centroid of that cluster
 SelectedTag getConversionType()
          return the type of distance to similarity conversion
 double getCurrAlpha()
          Get the current value of the smoothing parameter alpha in DITC smoothing
 double[] getGradients(Instance instance1, Instance instance2)
          Get the values of the partial derivates for the metric components for a particular instance pair
 double getLambdaJM()
          Get the lambda parameter for Jelinek-Mercer smoothing
 MetricLearner getMetricLearner()
          Get the distance metric learner
protected  java.lang.String getMetricLearnerSpec()
          Gets the classifier specification string, which contains the class name of the classifier and any options to the classifier
 java.lang.String[] getOptions()
          Gets the current settings of KLP.
 double getPseudoCountDirichlet()
          Get the pseudo-count value for Dirichlet smoothing
 SelectedTag getSmoothingType()
          return the type of smoothing
 boolean getUseDITCSmoothing()
          Check whether DITC smoothing is used
 boolean getUseIDivergence()
          Check whether regular KL divergence or I-divergence is used
 boolean isDistanceBased()
          The computation of a metric can be either based on distance, or on similarity
 void learnMetric(Instances data)
          Train the metric
 java.util.Enumeration listOptions()
          Returns an enumeration describing the available options.
static void main(java.lang.String[] args)
           
 void resetMetric()
          Reset all values that have been learned
 void setAlpha(double alpha)
          Set the initial value of the smoothing parameter alpha in DITC smoothing
 void setAlphaDecayRate(double alphaDecayRate)
          Set the initial value of the smoothing parameter alphaDecayRate in DITC smoothing
 void setConversionType(SelectedTag conversionType)
          Set the type of distance to similarity conversion.
 void setLambdaJM(double lambdaJM)
          Set the lambda parameter for Jelinek-Mercer smoothing
 void setMetricLearner(MetricLearner metricLearner)
          Set the distance metric learner
 void setOptions(java.lang.String[] options)
          Parses a given list of options.
 void setPseudoCountDirichlet(double pseudoCountDirichlet)
          Set the pseudo-count value for Dirichlet smoothing
 void setSmoothingType(SelectedTag smoothingType)
          Set the type of smoothing
 void setUseDITCSmoothing(boolean useDITC)
          Switch between using and not using DITC smoothing
 void setUseIDivergence(boolean useID)
          Switch between regular KL divergence and I-divergence
 double similarity(Instance instance1, Instance instance2)
          Returns a similarity estimate between two instances.
 double similarityNonWeighted(Instance instance1, Instance instance2)
          Returns a similarity estimate between two instances without using the weights.
 void updateAlpha()
          Update the current value of alpha by the decay rate
 
Methods inherited from class weka.core.metrics.LearnableMetric
getExternal, getNumPosDiffInstances, getPosNegDiffInstanceRatio, getTrainable, getWeights, meanOrMode, normalizeInstanceWeighted, setExternal, setNumPosDiffInstances, setPosNegDiffInstanceRatio, setTrainable, setWeights, useClassifier, useNoClassifier, usesClassifier
 
Methods inherited from class weka.core.metrics.Metric
forName, getAttrIdxs, getAttrIdxsWithoutLastClass, getAttrIndxs, getClassIndex, getNumAttributes, length, normalizeInstance, setAttrIdxs, setAttrIdxs, setClassIndex
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

LOG2

public final double LOG2

m_useIDivergence

protected boolean m_useIDivergence
We can switch between regular KL divergence and I-divergence


m_datasetFrequencies

protected HashMapVector m_datasetFrequencies
Frequencies over the entire dataset used for smoothing


m_instanceNormHash

protected java.util.HashMap m_instanceNormHash
We hash sum(p log(p)) terms for the input instances to speed up computation


m_numTotalTokens

protected int m_numTotalTokens
Total number of tokens in the dataset


SMOOTHING_UNSMOOTHED

public static final int SMOOTHING_UNSMOOTHED
Different smoothing methods for obtaining probability distributions from frequencies

See Also:
Constant Field Values

SMOOTHING_DIRICHLET

public static final int SMOOTHING_DIRICHLET
See Also:
Constant Field Values

SMOOTHING_JELINEK_MERCER

public static final int SMOOTHING_JELINEK_MERCER
See Also:
Constant Field Values

TAGS_SMOOTHING

public static final Tag[] TAGS_SMOOTHING

m_smoothingType

protected int m_smoothingType
The smoothing method


m_useDITCSmoothing

protected boolean m_useDITCSmoothing
Even with unsmoothed data, DITC-type smoothing can be used


m_alpha

protected double m_alpha

m_alphaDecayRate

protected double m_alphaDecayRate

m_currAlpha

protected double m_currAlpha

m_pseudoCountDirichlet

protected double m_pseudoCountDirichlet
The pseudocount value for the Dirichlet smoothing


m_lambdaJM

protected double m_lambdaJM
The lambda value for the Jelinek-Mercer smoothing


CONVERSION_LAPLACIAN

public static final int CONVERSION_LAPLACIAN
We can have different ways of converting from distance to similarity

See Also:
Constant Field Values

CONVERSION_UNIT

public static final int CONVERSION_UNIT
See Also:
Constant Field Values

CONVERSION_EXPONENTIAL

public static final int CONVERSION_EXPONENTIAL
See Also:
Constant Field Values

TAGS_CONVERSION

public static final Tag[] TAGS_CONVERSION

m_conversionType

protected int m_conversionType
The method of converting, by default laplacian


m_metricLearner

protected MetricLearner m_metricLearner
A metric learner responsible for training the parameters of the metric


m_instanceConstraintMap

protected java.util.HashMap m_instanceConstraintMap
A hashmap that maps every instance to a set of instances with which JS has been computed

Constructor Detail

KL

public KL(int numAttributes)
   throws java.lang.Exception
Create a new metric.

Parameters:
numAttributes - the number of attributes that the metric will work on

KL

public KL()
Create a default new metric


KL

public KL(int[] _attrIdxs)
   throws java.lang.Exception
Creates a new metric which takes specified attributes.

Parameters:
_attrIdxs - An array containing attribute indeces that will be used in the metric
Method Detail

resetMetric

public void resetMetric()
                 throws java.lang.Exception
Reset all values that have been learned

Specified by:
resetMetric in class LearnableMetric
Throws:
java.lang.Exception

buildMetric

public void buildMetric(int numAttributes)
                 throws java.lang.Exception
Generates a new Metric. Has to initialize all fields of the metric with default values.

Specified by:
buildMetric in class Metric
Parameters:
numAttributes - the number of attributes that the metric will work on
Throws:
java.lang.Exception - if the distance metric has not been generated successfully.

buildMetric

public void buildMetric(int numAttributes,
                        java.lang.String[] options)
                 throws java.lang.Exception
Generates a new Metric. Has to initialize all fields of the metric with default values

Specified by:
buildMetric in class Metric
Parameters:
options - an array of options suitable for passing to setOptions. May be null.
numAttributes - the number of attributes that the metric will work on
Throws:
java.lang.Exception - if the distance metric has not been generated successfully.

buildMetric

public void buildMetric(Instances data)
                 throws java.lang.Exception
Create a new metric for operating on specified instances

Specified by:
buildMetric in class Metric
Parameters:
data - instances that the metric will be used on
Throws:
java.lang.Exception

convertInstance

public Instance convertInstance(Instance instance)
Description copied from interface: InstanceConverter
Take an instance and convert it for use by the metric

Specified by:
convertInstance in interface InstanceConverter

convertFrequency

protected double convertFrequency(double freq,
                                  double numTotalTokens,
                                  java.lang.String token)
Given a frequency of a given token in a document, convert it to a probability value for that document's distribution

Parameters:
freq - frequency of a token
token - the token

distance

public double distance(Instance instance1,
                       Instance instance2)
                throws java.lang.Exception
Returns a distance value between two instances.

Specified by:
distance in class Metric
Parameters:
instance1 - First instance.
instance2 - Second instance.
Throws:
java.lang.Exception - if distance could not be estimated.

distanceInternal

public double distanceInternal(Instance instance1,
                               Instance instance2)
                        throws java.lang.Exception
Returns a distance value between two instances.

Parameters:
instance1 - First instance.
instance2 - Second instance.
Throws:
java.lang.Exception - if distance could not be estimated.

distanceSparse

public double distanceSparse(SparseInstance instance1,
                             SparseInstance instance2)
                      throws java.lang.Exception
Returns a distance value between two sparse instances.

Parameters:
instance1 - First sparse instance.
instance2 - Second sparse instance.
Throws:
java.lang.Exception - if distance could not be estimated.

distanceSparseNonSparse

public double distanceSparseNonSparse(SparseInstance instance1,
                                      Instance instance2)
                               throws java.lang.Exception
Returns a distance value between a non-sparse instance and a sparse instance

Parameters:
instance1 - sparse instance.
instance2 - sparse instance.
Throws:
java.lang.Exception - if distance could not be estimated.

distanceNonSparse

public double distanceNonSparse(Instance instance1,
                                Instance instance2)
                         throws java.lang.Exception
Returns a distance value between non-sparse instances without using the weights

Parameters:
instance1 - non-sparse instance.
instance2 - non-sparse instance.
Throws:
java.lang.Exception - if distance could not be estimated.

distanceJS

public double distanceJS(Instance instance1,
                         Instance instance2)
                  throws java.lang.Exception
Returns Jensen-Shannon distance value between two instances.

Parameters:
instance1 - First instance.
instance2 - Second instance.
Throws:
java.lang.Exception - if distanceJS could not be estimated.

distanceJSSparse

public double distanceJSSparse(SparseInstance instance1,
                               SparseInstance instance2)
                        throws java.lang.Exception
Returns Jensen-Shannon distance between two sparse instances.

Parameters:
instance1 - First sparse instance.
instance2 - Second sparse instance.
Throws:
java.lang.Exception - if distanceJS could not be estimated.

distanceJSSparseNonSparse

public double distanceJSSparseNonSparse(SparseInstance instance1,
                                        Instance instance2)
                                 throws java.lang.Exception
Returns Jensen-Shannon distance between a non-sparse instance and a sparse instance

Parameters:
instance1 - sparse instance.
instance2 - sparse instance.
Throws:
java.lang.Exception - if distanceJS could not be estimated.

distanceJSNonSparse

public double distanceJSNonSparse(Instance instance1,
                                  Instance instance2)
                           throws java.lang.Exception
Returns Jensen-Shannon distance between non-sparse instances without using the weights

Parameters:
instance1 - non-sparse instance.
instance2 - non-sparse instance.
Throws:
java.lang.Exception - if distanceJS could not be estimated.

similarity

public double similarity(Instance instance1,
                         Instance instance2)
                  throws java.lang.Exception
Returns a similarity estimate between two instances. Similarity is obtained by inverting the distance value using one of three methods: CONVERSION_LAPLACIAN, CONVERSION_EXPONENTIAL, CONVERSION_UNIT.

Specified by:
similarity in class Metric
Parameters:
instance1 - First instance.
instance2 - Second instance.
Throws:
java.lang.Exception - if similarity could not be estimated.

distanceNonWeighted

public double distanceNonWeighted(Instance instance1,
                                  Instance instance2)
                           throws java.lang.Exception
Returns distance between two instances without using the weights.

Specified by:
distanceNonWeighted in class Metric
Parameters:
instance1 - First instance.
instance2 - Second instance.
Throws:
java.lang.Exception - if similarity could not be estimated.

similarityNonWeighted

public double similarityNonWeighted(Instance instance1,
                                    Instance instance2)
                             throws java.lang.Exception
Returns a similarity estimate between two instances without using the weights.

Specified by:
similarityNonWeighted in class Metric
Parameters:
instance1 - First instance.
instance2 - Second instance.
Throws:
java.lang.Exception - if similarity could not be estimated.

getGradients

public double[] getGradients(Instance instance1,
                             Instance instance2)
                      throws java.lang.Exception
Get the values of the partial derivates for the metric components for a particular instance pair

Specified by:
getGradients in class LearnableMetric
Parameters:
instance1 - the first instance
instance2 - the first instance
Throws:
java.lang.Exception

learnMetric

public void learnMetric(Instances data)
                 throws java.lang.Exception
Train the metric

Specified by:
learnMetric in class LearnableMetric
Throws:
java.lang.Exception

setMetricLearner

public void setMetricLearner(MetricLearner metricLearner)
Set the distance metric learner

Parameters:
metricLearner - the metric learner

getMetricLearner

public MetricLearner getMetricLearner()
Get the distance metric learner


createDiffInstance

public Instance createDiffInstance(Instance instance1,
                                   Instance instance2)
Create an instance with features corresponding to dot-product components of the two given instances

Specified by:
createDiffInstance in class LearnableMetric
Parameters:
instance1 - first instance
instance2 - second instance

createDiffInstanceSparse

protected SparseInstance createDiffInstanceSparse(SparseInstance instance1,
                                                  SparseInstance instance2)
Create a sparse instance with features corresponding to dot-product components of the two given instances

Parameters:
instance1 - first sparse instance
instance2 - second sparse instance

createDiffInstanceSparseNonSparse

protected Instance createDiffInstanceSparseNonSparse(SparseInstance instance1,
                                                     Instance instance2)
Create an instance with features corresponding to dot-product components of the two given instances

Parameters:
instance1 - first sparse instance
instance2 - second non-sparse instance

createDiffInstanceNonSparse

protected Instance createDiffInstanceNonSparse(Instance instance1,
                                               Instance instance2)
Create a nonsparse instance with features corresponding to dot-product components of the two given instances

Parameters:
instance1 - first nonsparse instance
instance2 - second nonsparse instance

createDiffInstanceJS

public Instance createDiffInstanceJS(Instance instance1,
                                     Instance instance2)
Create an instance with features corresponding to JS components

Parameters:
instance1 - first instance
instance2 - second instance

createDiffInstanceJSSparse

protected SparseInstance createDiffInstanceJSSparse(SparseInstance instance1,
                                                    SparseInstance instance2)
Create a sparse instance with features corresponding to dot-product components of the two given instances

Parameters:
instance1 - first sparse instance
instance2 - second sparse instance

createDiffInstanceJSSparseNonSparse

protected Instance createDiffInstanceJSSparseNonSparse(SparseInstance instance1,
                                                       Instance instance2)
Create an instance with features corresponding to dot-product components of the two given instances

Parameters:
instance1 - first sparse instance
instance2 - second non-sparse instance

createDiffInstanceJSNonSparse

protected Instance createDiffInstanceJSNonSparse(Instance instance1,
                                                 Instance instance2)
Create a nonsparse instance with features corresponding to dot-product components of the two given instances

Parameters:
instance1 - first nonsparse instance
instance2 - second nonsparse instance

setConversionType

public void setConversionType(SelectedTag conversionType)
Set the type of distance to similarity conversion. Values other than CONVERSION_LAPLACIAN, CONVERSION_UNIT, or CONVERSION_EXPONENTIAL will be ignored


getConversionType

public SelectedTag getConversionType()
return the type of distance to similarity conversion

Returns:
one of CONVERSION_LAPLACIAN, CONVERSION_UNIT, or CONVERSION_EXPONENTIAL

setSmoothingType

public void setSmoothingType(SelectedTag smoothingType)
Set the type of smoothing


getSmoothingType

public SelectedTag getSmoothingType()
return the type of smoothing

Returns:
one of SMOOTHING_UNSMOOTHED, SMOOTHING_DIRICHLET, SMOOTHING_JELINEK_MERCER

setPseudoCountDirichlet

public void setPseudoCountDirichlet(double pseudoCountDirichlet)
Set the pseudo-count value for Dirichlet smoothing

Parameters:
pseudoCountDirichlet - the pseudocount value

getPseudoCountDirichlet

public double getPseudoCountDirichlet()
Get the pseudo-count value for Dirichlet smoothing

Returns:
the pseudocount value

setLambdaJM

public void setLambdaJM(double lambdaJM)
Set the lambda parameter for Jelinek-Mercer smoothing


getLambdaJM

public double getLambdaJM()
Get the lambda parameter for Jelinek-Mercer smoothing

Returns:
lambda

isDistanceBased

public boolean isDistanceBased()
The computation of a metric can be either based on distance, or on similarity

Specified by:
isDistanceBased in class Metric

setUseIDivergence

public void setUseIDivergence(boolean useID)
Switch between regular KL divergence and I-divergence


getUseIDivergence

public boolean getUseIDivergence()
Check whether regular KL divergence or I-divergence is used


setUseDITCSmoothing

public void setUseDITCSmoothing(boolean useDITC)
Switch between using and not using DITC smoothing


getUseDITCSmoothing

public boolean getUseDITCSmoothing()
Check whether DITC smoothing is used


setAlpha

public void setAlpha(double alpha)
Set the initial value of the smoothing parameter alpha in DITC smoothing


getAlpha

public double getAlpha()
Get the initial value of the smoothing parameter alpha in DITC smoothing


getCurrAlpha

public double getCurrAlpha()
Get the current value of the smoothing parameter alpha in DITC smoothing


setAlphaDecayRate

public void setAlphaDecayRate(double alphaDecayRate)
Set the initial value of the smoothing parameter alphaDecayRate in DITC smoothing


getAlphaDecayRate

public double getAlphaDecayRate()
Get the initial value of the the decay rate of alpha in DITC smoothing


updateAlpha

public void updateAlpha()
Update the current value of alpha by the decay rate


getCentroidInstance

public Instance getCentroidInstance(Instances instances,
                                    boolean fastMode,
                                    boolean normalized)
Given a cluster of instances, return the centroid of that cluster

Specified by:
getCentroidInstance in class LearnableMetric
Parameters:
instances - objects belonging to a cluster
fastMode - whether fast mode should be used for SparseInstances
normalized - normalize centroids for SPKMeans
Returns:
a centroid instance for the given cluster

setOptions

public void setOptions(java.lang.String[] options)
                throws java.lang.Exception
Parses a given list of options. Valid options are:

-N
Normalize the euclidean distance by vectors lengths -E
Use exponential conversion from distance to similarity (default laplacian conversion)

-U
Use unit conversion from similarity to distance (dist=1-sim) (default laplacian conversion)

-R
The metric is trainable and will be trained using the current MetricLearner (default non-trainable)

Specified by:
setOptions in interface OptionHandler
Parameters:
options - the list of options as an array of strings
Throws:
java.lang.Exception - if an option is not supported

getMetricLearnerSpec

protected java.lang.String getMetricLearnerSpec()
Gets the classifier specification string, which contains the class name of the classifier and any options to the classifier

Returns:
the classifier string.

listOptions

public java.util.Enumeration listOptions()
Returns an enumeration describing the available options.

Specified by:
listOptions in interface OptionHandler
Returns:
an enumeration of all the available options.

getOptions

public java.lang.String[] getOptions()
Gets the current settings of KLP.

Specified by:
getOptions in interface OptionHandler
Returns:
an array of strings suitable for passing to setOptions()

clone

public java.lang.Object clone()
Create a copy of this metric

Overrides:
clone in class LearnableMetric

main

public static void main(java.lang.String[] args)