diff --git a/html/relnotes.html b/html/relnotes.html index 46e2a61ee2f756e7c757d665eebd30f7b0833830..03a706ee0735ac875a93b834ce36b1d3c5ff9745 100644 --- a/html/relnotes.html +++ b/html/relnotes.html @@ -74,6 +74,7 @@ The development of 4 versions continue. <li>Added <tt>InstanceBasedMatrixMeasure</tt> for instance based alignments (impl)</li> <li>Added a <tt>getResult()</tt> method to <tt>Evaluator</tt> (api)</li> <li>Added a <tt>DiffAlign( al1, al2 )</tt> evaluator (impl)</li> +<li>Added an <tt>aggr.ConsensusAggregator</tt> for merging several alignments (impl)</li> <li>Implemented online evaluation and diff (server)</li> <li>Added the possibility to drop a number of correspondences in <tt>ONetworkWeakener</tt> (util)</li> <li>Added a google chart API display of plots <tt>GenPlot -t html</tt> (util)</li> @@ -81,7 +82,7 @@ The development of 4 versions continue. can be empty (edoal)</li> <li>Upgraded to <span style="color: green">Pellet 2.1</span> (but Pellet is not anymore distributed <a href="lib.html">due to license restrictions</a>)</li> -<li>Upgraded to <span style="color: green">OntoSim 2.0</span> (lib)</li> +<li>Upgraded to <span style="color: green">OntoSim 2.1</span> (lib)</li> <li>Added <a href="tutorial/tutorial4/index.html">tutorial 4</a> Pellet action (tutorial)</li> <li>Added <a href="tutorial/tutorial5/index.html">tutorial 5</a> about exposing matchers as web services (tutorial)</li> <li>Fixed path errors in tutorials (tutorial)</li> diff --git a/src/fr/inrialpes/exmo/align/impl/aggr/ConsensusAggregator.java b/src/fr/inrialpes/exmo/align/impl/aggr/ConsensusAggregator.java new file mode 100644 index 0000000000000000000000000000000000000000..bd6dc837f4431bf62032e1a83a1ec13c6cf802f8 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/impl/aggr/ConsensusAggregator.java @@ -0,0 +1,155 @@ +/* + * $Id$ + * + * Copyright (C) INRIA, 2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package fr.inrialpes.exmo.align.impl.aggr; + +import java.util.Hashtable; +import java.util.Set; +import java.util.HashSet; + +import org.semanticweb.owl.align.Alignment; +import org.semanticweb.owl.align.AlignmentException; +import org.semanticweb.owl.align.Cell; +import org.semanticweb.owl.align.Relation; + +import fr.inrialpes.exmo.align.impl.BasicAlignment; + +/** + * + * @author Jérôme Euzenat + * @version $Id$ + * + * This class is a generalisation of a consensus aggregation. + * It is fed by "ingesting" various alignments, i.e., collecting and counting their correspondences + * Then the extraction of an alignement is made by extracting an alignment + * So the aggregator works with the following interface: + * aggr = new ConsensusAggregator(); + * aggr.ingest( Alignment ); + * aggr.ingest( Alignment ); + * ... + * aggr.extract( double, boolean ) + * or + * aggr.extract( int, boolean ) + * for the interpretation of these two primitives, see the definition of extract. + * + * There could be also a possibility to introduce a hook depending on the entities to be compared. + * For instance, in multilingual matching, if the labels are one word, then n=5, if they are more than one word, n=2 + */ + +public class ConsensusAggregator extends BasicAlignment { + + int nbAlignments = 0; + Hashtable<Cell, CountCell> count; + + /** Creation **/ + public ConsensusAggregator() { + // Initialising the hash table + count = new Hashtable<Cell, CountCell>(); + } + + + /** + * Extract the alignment from consensus + */ + public void ingest( Alignment al ) throws AlignmentException { + nbAlignments++; + for ( Cell c : al ) { + Cell newc = isAlreadyThere( c ); + if ( newc == null ) { + newc = addAlignCell( c.getObject1(), c.getObject2(), c.getRelation().toString(), 1. ); + count.put( newc, new CountCell() ); + } + count.get( newc ).incr( c.getStrength() ); + } + } + + /** + * Extract the alignment from consensus + * If absolute, then retain correspondences found in more than n alignments + * Otherwise, retain those found in more than n% of alignments + */ + public void extract( int minVal, boolean absolute ) throws AlignmentException { + // Check that this is between 0. and 1. + double threshold = (double)minVal; + if ( !absolute ) threshold = minVal*(double)nbAlignments; + Set<Cell> todelete = new HashSet<Cell>(); + for ( Cell c : this ) { + // if it is not more than X time, then return 0 + if ( count.get( c ).getOccurences() >= threshold ) { + c.setStrength( (double)count.get( c ).getOccurences() / (double)nbAlignments ); + } else { + todelete.add( c ); + } + } + for ( Cell c : todelete ) { + try { remCell( c ); } catch (Exception ex ) {}; + } + + } + + /** + * Extract the alignment from consensus + * If absolute, then retain correspondences scoring more than n + * Otherwise, retain those scoring more than n in average, i.e., n*nbAlignments + */ + public void extract( double minVal, boolean absolute ) throws AlignmentException { + double threshold = minVal; + if ( !absolute ) threshold = minVal*(double)nbAlignments; // Check that this is between 0. and 1. + Set<Cell> todelete = new HashSet<Cell>(); + for ( Cell c : this ) { + if ( count.get( c ).getValue() >= minVal ) { + c.setStrength( count.get( c ).getValue() / (double)nbAlignments ); + } else { + todelete.add( c ); + } + } + for ( Cell c : todelete ) { + try { remCell( c ); } catch (Exception ex ) {}; + } + + } + + public Cell isAlreadyThere( Cell c ){ + try { + Set<Cell> possible = getAlignCells1( c.getObject1() ); + Object ob2 = c.getObject2(); + Relation r = c.getRelation(); + if ( possible!= null ) { + for ( Cell c2 : possible ) { + if ( ob2.equals( c2.getObject2() ) && r.equals( c2.getRelation() ) ) return c2; + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + private class CountCell { + private int occ; + private double number; + public CountCell() { number = 0.; occ = 0; } + public CountCell( double i, int j ) { number = i; occ = j; } + public void incr( double d ) { number += d; occ++; } + public double getValue() { return number; } + public int getOccurences() { return occ; } + } + +}