看了论文《Deeply Exploiting Link Structure: Setting a Tougher Life for Spammers》,用Java和webgraph库实现了一下其中的算法CPV,即计算AVRank和HVRank。最终的结果没有做归一化处理,我用数据集试了一下,发现效果还不错。
代码实现如下:
package cn.edu.dlut.wisdom;
import it.unimi.dsi.webgraph.*;
public class Cpv {
private ImmutableGraph graph;
private ImmutableGraph igraph;
private double alpha = 0.5;
private double beta = 0.5;
private double dampening = 0.85;
private int numNodes;
private int m = 50;
public void setM(int m) {
this.m = m;
}
public void setAlpha(double alpha) {
this.alpha = alpha;
}
public void setBeta(double beta) {
this.beta = beta;
}
public void setDampening(double dampening) {
this.dampening = dampening;
}
public void setGraph(ImmutableGraph graph) {
this.graph = graph;
}
public void setIAVRank(double[] iAVRank) {
this.iAVRank = iAVRank;
}
public void setIgraph(ImmutableGraph igraph) {
this.igraph = igraph;
}
public void setIHVRank(double[] iHVRank) {
this.iHVRank = iHVRank;
}
private double[] iAVRank;
private double[] iHVRank;
private double[] aVRank;
private double[] hVRank;
public double[] getAVRank() {
return aVRank;
}
public double[] getHvRank() {
return hVRank;
}
public Cpv(ImmutableGraph graph, ImmutableGraph igraph, double [] iAVRank, double[] iHVRank, double alpha, double beta, double dampening, int m) {
this.iAVRank = iAVRank;
this.iHVRank = iHVRank;
this.alpha = alpha;
this.beta = beta;
this.dampening = dampening;
this.m = m;
this.graph = graph;
this.igraph = igraph;
numNodes = graph.numNodes();
}
public Cpv(ImmutableGraph graph, ImmutableGraph igraph) {
this.graph = graph;
this.igraph = igraph;
numNodes = graph.numNodes();
iAVRank = new double[numNodes];
iHVRank = new double[numNodes];
double temp = 1.0 / numNodes;
for(int i = 0; i < numNodes; i++) {
iAVRank[i] = temp;
iHVRank[i] = temp;
}
}
public Cpv(ImmutableGraph graph) {
this.graph = graph;
igraph = Transform.transpose(graph);
numNodes = graph.numNodes();
iAVRank = new double[numNodes];
iHVRank = new double[numNodes];
double temp = 1.0 / numNodes;
for(int i = 0; i < numNodes; i++) {
iAVRank[i] = temp;
iHVRank[i] = temp;
}
}
public void computeRank() {
// 初始化
aVRank = iAVRank.clone();
hVRank = iHVRank.clone();
int iter = m;
// 迭代
while(iter-- > 0) {
for(int i = 0; i < numNodes; i++) {
if(igraph.outdegree(i) > 0) {
aVRank[i] = 0;
for(int j : igraph.successorArray(i)) {
int outDegree = graph.outdegree(j);
aVRank[i] += alpha * aVRank[j] / outDegree + (1 - alpha) * hVRank[j] / outDegree;
}
}
}
for(int i = 0; i < numNodes; i++) {
if(graph.outdegree(i) > 0) {
hVRank[i] = 0;
for(int j : graph.successorArray(i)) {
int inDegree = igraph.outdegree(j);
hVRank[i] += beta * aVRank[j] / inDegree + (1 - beta) * hVRank[j] / inDegree;
}
}
}
for(int i = 0; i < numNodes; i++) {
aVRank[i] = dampening * aVRank[i] + (1 - dampening) * iAVRank[i];
hVRank[i] = dampening * hVRank[i] + (1 - dampening) * hVRank[i];
}
}
}
}