// loop through all instances
for (int ii = 0; ii < trainingList.size(); ii++) {
Instance inst = trainingList.get(ii);
Labeling labeling = inst.getLabeling ();
FeatureVector fv = (FeatureVector) inst.getData();
int fvisize = fv.numLocations();
int correctIndex = labeling.getBestIndex();
Arrays.fill(results, 0);
// compute dot(x, wi) for each class i
for(int lpos = 0; lpos < numLabels; lpos++) {
for(int fvi = 0; fvi < fvisize; fvi++) {
int fi = fv.indexAtLocation(fvi);
double vi = fv.valueAtLocation(fvi);
results[lpos] += vi * m_weights[lpos][fi];
}
// This extra value comes from the extra
// "feature" present in all examples
results[lpos] += m_weights[lpos][numFeats];
}
// Get indices of the classes with the 2 highest dot products
int predictedIndex = 0;
int secondHighestIndex = 0;
double max = Double.MIN_VALUE;
double secondMax = Double.MIN_VALUE;
for (int i = 0; i < numLabels; i++) {
if (results[i] > max) {
secondMax = max;
max = results[i];
secondHighestIndex = predictedIndex;
predictedIndex = i;
}
else if (results[i] > secondMax) {
secondMax = results[i];
secondHighestIndex = i;
}
}
// Adjust weights if this example is mispredicted
// or just barely correct
if (predictedIndex != correctIndex) {
for (int fvi = 0; fvi < fvisize; fvi++) {
int fi = fv.indexAtLocation(fvi);
m_weights[predictedIndex][fi] *= (1 - epsilon);
m_weights[correctIndex][fi] *= (1 + epsilon);
}
m_weights[predictedIndex][numFeats] *= (1 - epsilon);
m_weights[correctIndex][numFeats] *= (1 + epsilon);
}
else if (max/secondMax - 1 < m_delta) {
for (int fvi = 0; fvi < fvisize; fvi++) {
int fi = fv.indexAtLocation(fvi);
m_weights[secondHighestIndex][fi] *= (1 - epsilon);
m_weights[correctIndex][fi] *= (1 + epsilon);
}
m_weights[secondHighestIndex][numFeats] *= (1 - epsilon);
m_weights[correctIndex][numFeats] *= (1 + epsilon);