All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ciir.umass.edu.metric.BestAtKScorer Maven / Gradle / Ivy

There is a newer version: 2.10.1
Show newest version
/*===============================================================================
 * Copyright (c) 2010-2012 University of Massachusetts.  All Rights Reserved.
 *
 * Use of the RankLib package is subject to the terms of the software license set
 * forth in the LICENSE file included with this software, and also available at
 * http://people.cs.umass.edu/~vdang/ranklib_license.html
 *===============================================================================
 */

package ciir.umass.edu.metric;

import java.util.Arrays;

import ciir.umass.edu.learning.RankList;

/**
 * @author vdang
 */
public class BestAtKScorer extends MetricScorer {

    public BestAtKScorer() {
        this.k = 10;
    }

    public BestAtKScorer(final int k) {
        this.k = k;
    }

    @Override
    public double score(final RankList rl) {
        return rl.get(maxToK(rl, k - 1)).getLabel();
    }

    @Override
    public MetricScorer copy() {
        return new BestAtKScorer();
    }

    /**
     * Return the position of the best object (e.g. docs with highest degree of relevance) among objects in the range [0..k]
     * NOTE: If you want best-at-k (i.e. best among top-k), you need maxToK(rl, k-1)
     * @param rl The rank list.
     * @param k The last position of the range.
     * @return The index of the best object in the specified range.
     */
    public int maxToK(final RankList rl, final int k) {
        int size = k;
        if (size < 0 || size > rl.size() - 1) {
            size = rl.size() - 1;
        }

        double max = -1.0;
        int max_i = 0;
        for (int i = 0; i <= size; i++) {
            if (max < rl.get(i).getLabel()) {
                max = rl.get(i).getLabel();
                max_i = i;
            }
        }
        return max_i;
    }

    @Override
    public String name() {
        return "Best@" + k;
    }

    @Override
    public double[][] swapChange(final RankList rl) {
        //FIXME: not sure if this implementation is correct!
        final int[] labels = new int[rl.size()];
        final int[] best = new int[rl.size()];
        int max = -1;
        int maxVal = -1;
        int secondMaxVal = -1;//within top-K
        int maxCount = 0;//within top-K
        for (int i = 0; i < rl.size(); i++) {
            final int v = (int) rl.get(i).getLabel();
            labels[i] = v;
            if (maxVal < v) {
                if (i < k) {
                    secondMaxVal = maxVal;
                    maxCount = 0;
                }
                maxVal = v;
                max = i;
            } else if (maxVal == v && i < k) {
                maxCount++;
            }
            best[i] = max;
        }
        if (secondMaxVal == -1) {
            secondMaxVal = 0;
        }

        final double[][] changes = new double[rl.size()][];
        for (int i = 0; i < rl.size(); i++) {
            changes[i] = new double[rl.size()];
            Arrays.fill(changes[i], 0);
        }
        //FIXME: THIS IS VERY *INEFFICIENT*
        for (int i = 0; i < rl.size() - 1; i++) {
            for (int j = i + 1; j < rl.size(); j++) {
                double change = 0;
                if (j < k || i >= k) {
                    change = 0;
                } else if (labels[i] == labels[j] || labels[j] == labels[best[k - 1]]) {
                    change = 0;
                } else if (labels[j] > labels[best[k - 1]]) {
                    change = labels[j] - labels[best[i]];
                } else if (labels[i] < labels[best[k - 1]] || maxCount > 1) {
                    change = 0;
                } else {
                    change = maxVal - Math.max(secondMaxVal, labels[j]);
                }
                changes[i][j] = changes[j][i] = change;
            }
        }
        return changes;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy