in src/main/java/com/twitter/sbf/core/MHAlgorithm.java [775:837]
public static PredictionStat getPredictionStatVertexSampling(
Graph graph,
SparseBinaryMatrix matrix,
ExecutorService executor,
int[] evalVertexIds) {
Range[] ranges = Util.chunkArray(evalVertexIds.length, 1000);
ObjectList<Future<PredictionStat>> futures = new ObjectArrayList<>(ranges.length);
for (Range range : ranges) {
Future<PredictionStat> future = executor.submit(() -> {
PredictionStat myStat = new PredictionStat();
for (int i = range.start; i < range.end; i++) {
int vertex1 = evalVertexIds[i];
int truePosForVertex = 0;
for (int vertex2 = 0; vertex2 < graph.getNumVertices(); vertex2++) {
if (vertex1 == vertex2) {
continue;
}
float edgeWeight = graph.getWeightOfEdge(vertex1, vertex2);
boolean isEdge = edgeWeight > 0;
boolean predictEdge =
Util.hasCommonElement(matrix.getRow(vertex1), matrix.getRow(vertex2));
if (isEdge) {
myStat.incActualPositive();
truePosForVertex++;
myStat.incWeightActualPositive(edgeWeight);
}
if (predictEdge) {
myStat.incPredictedPositive();
// what should this be set to?
// Let's set this to be the average weight across the two nodes incident on this edge.
double add =
(graph.getWeightedOutDegree(vertex1) + graph.getWeightedOutDegree(vertex2))
/ (graph.getDegree(vertex1) + graph.getDegree(vertex2));
myStat.incWeightPredictedPositive(add);
}
if (isEdge && predictEdge) {
myStat.incTruePositive();
myStat.incWeightTruePositive(edgeWeight);
}
if (!isEdge && !predictEdge) {
myStat.incTrueNegative();
}
}
myStat.incEval(graph.getNumVertices() - 1);
myStat.incEvalVertices();
if (truePosForVertex == 0) {
myStat.incEvalVerticesWithZeroTruePos();
}
}
return myStat;
});
futures.add(future);
}
PredictionStat stat = new PredictionStat();
for (Future<PredictionStat> future : futures) {
try {
stat.add(future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return stat;
}