/** * CrowdTransEval, a toolkit for evaluating machine translation * system by using crowdsourcing. * Copyright (C) 2012 Alejandro Navarro Fulleda <anf5@alu.ua.es> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package es.ua.alex952.cf_helpers.result_helpers; import java.util.ArrayList; /** * * @author alex952 */ public class KappaRaters { private static Integer N_RATES = 6; private Integer raterA; private Integer raterB; public Integer getRaterA() { return raterA; } public Integer getRaterB() { return raterB; } private int[][] flucencyRates; private int[][] adecuacyRates; /** * Main constructor. * * @param raterA First part of the couple of raters (order matters) * @param raterB Last part of the couple of raters (order matters) */ public KappaRaters(Integer raterA, Integer raterB) { this.raterA = raterA; this.raterB = raterB; this.flucencyRates = new int[N_RATES][N_RATES]; this.adecuacyRates = new int[N_RATES][N_RATES]; } /** * Add one more judgment to fluency rate table. * * @param rateA What first has rated. * @param rateB What last has rated. */ public void addFluency(Integer rateA, Integer rateB) { this.flucencyRates[rateA][rateB]++; } /** * Add one more judgment to fluency rate table. * * @param rateA rateA What first has rated. * @param rateB rateB What last has rated. */ public void addAdequacy(Integer rateA, Integer rateB) { this.adecuacyRates[rateA][rateB]++; } /** * Get the numer of rates of a given combination. * * @param rateA * @param rateB * @return */ public Integer getFluencyRate(Integer rateA, Integer rateB) { return this.flucencyRates[rateA][rateB]; } /** * Get the numer of rates of a given combination. * * @param rateA * @param rateB * @return */ public Integer getAdequacyRate(Integer rateA, Integer rateB) { return this.adecuacyRates[rateA][rateB]; } /** * Gets the kappa factor from the raters' matrix * * @param ratesTable The rater's matrix * @return Kappa factor derived from the table */ private Double getKappa(int [][] ratesTable) { //Total sum of table Integer total = 0; //Stores the rows' sums ArrayList<Double> pe1 = new ArrayList<Double>(); //Stores the cols' sums ArrayList<Double> pe2 = new ArrayList<Double>(); //Used to collect total sum and row sum for (int i = 0; i < ratesTable.length; i++) { int row = 0; for (int j = 0; j < ratesTable[i].length; j++) { total += ratesTable[i][j]; row += ratesTable[i][j]; } pe1.add(new Double(row)); row = 0; } //Calculus of P(a) Double pa = 0.0; for(int i = 0; i < ratesTable.length; i++) { pa += ratesTable[i][i]; } pa /= total; //Used to collect columns' sum for (int i = 0; i < ratesTable.length; i++) { int col = 0; for (int j = 0; j < ratesTable[i].length; j++) { col += ratesTable[j][i]; } pe2.add(new Double(col)); col = 0; } //Calculus of P(e) Double pe = 0.0; for (int i = 0; i < pe1.size(); i++) { pe += pe1.get(i) / total * pe2.get(i) / total; } //Return the real Kappa P(a) - P(e) / 1.0 - P(e) return (pa - pe) / (1.0 - pe); } /** * Returns the Kappa factor for the Fluency feature. * * @return Fluency's Kappa factor */ public Double getFluencyKappa() { return this.getKappa(this.flucencyRates); } /** * Returns the Kappa factor for the Adequacy feature. * * @return Fluency's Kappa factor */ public Double getAdequacyKappa() { return this.getKappa(this.flucencyRates); } private Integer getRatings(int[] ratings) { Integer res = 0; for (Integer rate: ratings) { res += rate; } return res; } /** * Getter for the fluency ratings answered by one rater * * @param score The score that we want to know * @return Total score given by the rater A */ public Integer getRatingsFluencyA(int score) { return this.getRatings(this.flucencyRates[score]); } /** * Getter for the adequacy ratings answered by one rater * * @param score The score that we want to know * @return Total score given by the rater A */ public Integer getRatingsAdequacyA(int score) { return this.getRatings(this.adecuacyRates[score]); } /** * Getter for the fluency ratings answered by one rater * * @param score The score that we want to know * @return Total score given by the rater B */ public Integer getRatingsFluencyB(int score) { int[] column = new int[this.flucencyRates.length]; for (int i = 0; i < flucencyRates.length; i++) { column[i] = this.flucencyRates[i][score]; } return this.getRatings(column); } /** * Getter for the adequacy ratings answered by one rater * * @param score The score that we want to know * @return Total score given by the rater B */ public Integer getRatingsAdequacyB(int score) { int[] column = new int[this.adecuacyRates.length]; for (int i = 0; i < adecuacyRates.length; i++) { column[i] = this.adecuacyRates[i][score]; } return this.getRatings(column); } }