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.anomaly.evaluation;
018
019import org.tribuo.anomaly.AnomalyFactory;
020import org.tribuo.anomaly.Event;
021import org.tribuo.evaluation.metrics.MetricTarget;
022
023import java.util.function.ToDoubleBiFunction;
024
025/**
026 * Default metrics for evaluating anomaly detection.
027 */
028public enum AnomalyMetrics {
029    //
030    // cast to doubles here because AbstractEvaluator assumes all metric results are doubles.
031    /**
032     * The number of true positives.
033     */
034    TP((t, c) -> (double) c.getTruePositive()),
035    /**
036     * The number of false positives.
037     */
038    FP((t, c) -> (double) c.getFalsePositive()),
039    /**
040     * The number of true negatives.
041     */
042    TN((t, c) -> (double) c.getTrueNegative()),
043    /**
044     * The number of false negatives.
045     */
046    FN((t, c) -> (double) c.getFalseNegative()),
047    /**
048     * The precision, i.e., the true positives divided by the predicted positives.
049     */
050    PRECISION((t,c) -> ((double) c.getTruePositive()) / (c.getTruePositive() + c.getFalsePositive())),
051    /**
052     * The recall, i.e., the true positives divided by the ground truth positives.
053     */
054    RECALL((t,c) -> ((double) c.getTruePositive()) / (c.getTruePositive() + c.getFalseNegative())),
055    /**
056     * The F_1 score, i.e., the harmonic mean of the precision and the recall.
057     */
058    F1((t,c) -> (2.0 * c.getTruePositive()) / ((2.0 * c.getTruePositive()) + c.getFalseNegative() + c.getFalsePositive()));
059
060    private final ToDoubleBiFunction<MetricTarget<Event>, AnomalyMetric.Context> impl;
061
062    private final AnomalyMetric metric;
063
064    AnomalyMetrics(ToDoubleBiFunction<MetricTarget<Event>, AnomalyMetric.Context> impl) {
065        this.impl = impl;
066        this.metric = new AnomalyMetric(new MetricTarget<>(AnomalyFactory.ANOMALOUS_EVENT),this.name(),this.impl);
067    }
068
069    AnomalyMetric asMetric() {
070        return metric;
071    }
072}