TupleListIterator expectedInput = (TupleListIterator)iterationData[0];
TupleListIterator actualInput = (TupleListIterator)iterationData[1];
Map<Object, Map<Object, Long>> confusionMatrix =
new HashMap<Object, Map<Object,Long>>();
SortedSet<Object> actualValues = new TreeSet<Object>();
Tuple expected;
while ((expected = (Tuple)expectedInput.nextValue()) != null)
{
Tuple actual = (Tuple)actualInput.nextValue();
if (actual == null)
{
throw new UnmatchedActivityInputsException(
new String[] {INPUT_EXPECTED, INPUT_PREDICTED},
new Object[] {expected, ControlBlock.NO_MORE_DATA});
}
// we're assuming there are no more than Integer.MAX_VALUE classes
Object predicted = actual.getObject(0);
Object exp = expected.getObject(0);
Map<Object, Long> map = confusionMatrix.get(exp);
actualValues.add(predicted);
if (map == null)
{
Map<Object, Long> counts = new HashMap<Object, Long>();
confusionMatrix.put(exp, counts);
counts.put(predicted, 1L);
}
else
{
Long count = map.get(predicted);
if (count == null)
{
map.put(predicted, 1L);
}
else
{
map.put(predicted, count+1);
}
}
}
Object obj = actualInput.nextValue();
if (obj != null)
{
throw new UnmatchedActivityInputsException(
new String[] {INPUT_EXPECTED, INPUT_PREDICTED},
new Object[] {ControlBlock.NO_MORE_DATA, obj});
}
List<ColumnMetadata> columns = new ArrayList<ColumnMetadata>();
columns.add(
new SimpleColumnMetadata(
"class",
TupleTypes._STRING,
0,
ColumnMetadata.COLUMN_NO_NULLS,
0));
for (Object object : actualValues)
{
columns.add(
new SimpleColumnMetadata(
object.toString(),
TupleTypes._LONG,
0,
ColumnMetadata.COLUMN_NO_NULLS,
0));
}
TupleMetadata metadata = new SimpleTupleMetadata(columns);
try
{
mOutput.write(ControlBlock.LIST_BEGIN);
mOutput.write(new MetadataWrapper(metadata));
for (Object key : confusionMatrix.keySet())
{
List<Object> elements = new ArrayList<Object>();
elements.add(key.toString());
Map<Object, Long> counts = confusionMatrix.get(key);
for (Object value : actualValues)
{
Long count = counts.get(value);
if (count == null)
{
elements.add(0L);
}
else
{
elements.add(count);
}
}
Tuple tuple = new SimpleTuple(elements);
mOutput.write(tuple);
}
mOutput.write(ControlBlock.LIST_END);
}