/*
* RapidMiner
*
* Copyright (C) 2001-2014 by RapidMiner and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapidminer.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.example.set;
import java.util.Iterator;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.Attributes;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.SimpleAttributes;
import com.rapidminer.example.table.AttributeFactory;
import com.rapidminer.example.table.DoubleArrayDataRow;
import com.rapidminer.example.table.ExampleTable;
import com.rapidminer.example.table.NominalMapping;
import com.rapidminer.operator.Annotations;
import com.rapidminer.operator.similarity.ExampleSet2SimilarityExampleSet;
import com.rapidminer.tools.Ontology;
import com.rapidminer.tools.math.similarity.DistanceMeasure;
/**
* This similarity based example set is used for the operator
* {@link ExampleSet2SimilarityExampleSet}.
*
* @author Ingo Mierswa
*/
public class SimilarityExampleSet extends AbstractExampleSet {
private static final long serialVersionUID = 4757975818441794105L;
private static class IndexExampleReader extends AbstractExampleReader {
private int index = 0;
private ExampleSet exampleSet;
public IndexExampleReader(ExampleSet exampleSet) {
this.exampleSet = exampleSet;
}
public boolean hasNext() {
return index < exampleSet.size() - 1;
}
public Example next() {
Example example = exampleSet.getExample(index);
index++;
return example;
}
}
private ExampleSet parent;
private Attribute parentIdAttribute;
private Attributes attributes;
private DistanceMeasure measure;
public SimilarityExampleSet(ExampleSet parent, DistanceMeasure measure) {
this.parent = parent;
this.parentIdAttribute = parent.getAttributes().getId();
this.attributes = new SimpleAttributes();
Attribute firstIdAttribute = null;
Attribute secondIdAttribute = null;
firstIdAttribute = AttributeFactory.createAttribute("FIRST_ID", this.parentIdAttribute.getValueType());
secondIdAttribute = AttributeFactory.createAttribute("SECOND_ID", this.parentIdAttribute.getValueType());
this.attributes.addRegular(firstIdAttribute);
this.attributes.addRegular(secondIdAttribute);
firstIdAttribute.setTableIndex(0);
secondIdAttribute.setTableIndex(1);
// copying mapping of original id attribute
if (parentIdAttribute.isNominal()) {
NominalMapping mapping = parentIdAttribute.getMapping();
firstIdAttribute.setMapping((NominalMapping) mapping.clone());
secondIdAttribute.setMapping((NominalMapping) mapping.clone());
}
String name = "SIMILARITY";
if (measure.isDistance()) {
name = "DISTANCE";
}
Attribute similarityAttribute = AttributeFactory.createAttribute(name, Ontology.REAL);
this.attributes.addRegular(similarityAttribute);
similarityAttribute.setTableIndex(2);
this.measure = measure;
}
/** Clone constructor. */
public SimilarityExampleSet(SimilarityExampleSet exampleSet) {
this.parent = (ExampleSet)exampleSet.parent.clone();
this.parentIdAttribute = (Attribute) exampleSet.parentIdAttribute.clone();
this.attributes = (Attributes)exampleSet.attributes.clone();
this.measure = exampleSet.measure;
}
@Override
public boolean equals(Object o) {
if (!super.equals(o))
return false;
if (!(o instanceof SimilarityExampleSet))
return false;
SimilarityExampleSet other = (SimilarityExampleSet)o;
if (!this.measure.getClass().equals(other.measure.getClass()))
return false;
return true;
}
@Override
public int hashCode() {
return super.hashCode() ^ this.measure.getClass().hashCode();
}
@Override
public Attributes getAttributes() {
return this.attributes;
}
@Override
public Annotations getAnnotations() {
return parent.getAnnotations();
}
@Override
public Example getExample(int index) {
int firstIndex = index / this.parent.size();
int secondIndex = index % this.parent.size();
Example firstExample = this.parent.getExample(firstIndex);
Example secondExample = this.parent.getExample(secondIndex);
double[] data = new double[3];
data[0] = firstExample.getValue(parentIdAttribute);
data[1] = secondExample.getValue(parentIdAttribute);
if (measure.isDistance())
data[2] = measure.calculateDistance(firstExample, secondExample);
else
data[2] = measure.calculateSimilarity(firstExample, secondExample);
return new Example(new DoubleArrayDataRow(data), this);
}
@Override
public Iterator<Example> iterator() {
return new IndexExampleReader(this);
}
@Override
public ExampleTable getExampleTable() {
return null;//this.parent.getExampleTable();
}
@Override
public int size() {
return this.parent.size() * this.parent.size();
}
}