Re: Confusion Matrix
In article
<42ed46a0-c810-4267-8f63-0767f7350985@l32g2000vbp.googlegroups.com>,
Simon <choonching5u@gmail.com> wrote:
What is the best way to do a confusion matrix in [J]ava programming,
the size of the matrix must [be] dynamic? I failed to do it with
HashMap as folowing. For example,
pas, per, urd, ara
pas [0, 6, 24, 10]
per [0, 6, 24, 10]
urd [0, 6, 24, 10]
ara [0, 6, 24, 10]
I've never used one larger than second order. I'm not sure why you'd use
a HashMap for a matrix; just use an array of arrays, e.g. int[][]. A Map
associates keys with objects for quick retrieval. You might use a Map to
access values by name rather than index:
<http://en.wikipedia.org/wiki/Confusion_matrix>
<console>
cat dog rab
cat 5 2 0
dog 3 3 2
rab 0 1 11
cat: 8 actual, 7 predicted
dog: 6 actual, 8 predicted
rab: 13 actual, 12 predicted
</console>
<code>
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** @author John B. Matthews, distribution per GPL, v2 or later */
public class CMTest {
public static void main(String[] args) {
final List<String> list = new ArrayList<String>(
Arrays.asList("cat", "dog", "rab"));
final CMatrixModel model = new CMatrixModel(list);
model.setRow(list.get(0), 5, 2, 0);
model.setRow(list.get(1), 3, 3, 2);
model.setRow(list.get(2), 0, 1, 11);
System.out.println(model);
for (String s : list) {
System.out.println(s + ": "
+ model.actual(s) + " actual, "
+ model.predicted(s) + " predicted ");
}
}
}
class CMatrixModel extends Object {
private List<String> names;
private Map<String, Integer> map =
new HashMap<String, Integer>();
private int order;
private int[][] data;
CMatrixModel(List<String> names) {
this.names = names;
this.order = names.size();
this.data = new int[order][order];
int i = 0;
for (String name : names) {
map.put(name, i++);
}
}
public void set(String actual, String predicted, int value) {
int row = map.get(predicted);
int col = map.get(actual);
data[row][col] = value;
}
public int get(String actual, String predicted) {
int row = map.get(predicted);
int col = map.get(actual);
return data[row][col];
}
public void setRow(String predicted, int... actuals) {
int row = map.get(predicted);
int col = 0;
for (int v : actuals) {
data[row][col++] = v;
}
}
public int actual(String actual) {
int sumActual = 0;
for (String s : names) {
sumActual += this.get(actual, s);
}
return sumActual;
}
public int predicted(String predicted) {
int sumPredicted = 0;
for (String s : names) {
sumPredicted += this.get(s, predicted);
}
return sumPredicted;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (String name : names) {
sb.append(name);
sb.append(" ");
}
sb.append("\n");
int i = 0;
for (int[] row : data) {
sb.append(names.get(i++));
sb.append(" ");
for (int col : row) {
sb.append(col);
sb.append(" ");
}
sb.append("\n");
}
return sb.toString();
}
}
</code>
[Compiled; error checking omitted.]
--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>