/** * Write the clusterings out into a file. * * @param fileName the file to write out to * @param clustering the clusters to write out * @throws IOException occurs if there's an input or output error */ private static void writeOutputFile( String fileName, Clustering clustering, boolean adjustedEdgeWeights) throws IOException { BufferedWriter bufferedWriter; int i, nNodes; // get the information nNodes = clustering.getNNodes(); clustering.orderClustersByNNodes(); // writing to the .graph: final communities output if (adjustedEdgeWeights) { fileName = fileName + "-lm-performance" + "-rehoM" + ".graph"; } else { fileName = fileName + "-lm-performance" + "-maxM" + ".graph"; } bufferedWriter = new BufferedWriter(new FileWriter(fileName)); for (i = 0; i < nNodes; i++) { bufferedWriter.write(i + " " + Integer.toString(clustering.getCluster(i))); bufferedWriter.newLine(); } bufferedWriter.close(); }
/** * Resets the values of clusters that have been merged. * * @param clustering * @param i * @param j */ protected void updateScoreMatrix(Clustering clustering, int i, int j) { int size = clustering.getNumInstances(); int[] ci = clustering.getIndicesWithLabel(i); for (int ni = 0; ni < ci.length; ni++) { for (int nj = 0; nj < size; nj++) if (ci[ni] != nj) scoreCache.set(ci[ni], nj, 0.0); } int[] cj = clustering.getIndicesWithLabel(j); for (int ni = 0; ni < cj.length; ni++) { for (int nj = 0; nj < size; nj++) if (cj[ni] != nj) scoreCache.set(cj[ni], nj, 0.0); } }
/** * @param clustering * @param i * @param j * @return The score for merging these two clusters. */ protected double getScore(Clustering clustering, int i, int j) { if (scoreCache == null) scoreCache = new PairwiseMatrix(clustering.getNumInstances()); int[] ci = clustering.getIndicesWithLabel(i); int[] cj = clustering.getIndicesWithLabel(j); if (scoreCache.get(ci[0], cj[0]) == 0.0) { double val = evaluator.evaluate( new AgglomerativeNeighbor( clustering, ClusterUtils.copyAndMergeClusters(clustering, i, j), ci, cj)); for (int ni = 0; ni < ci.length; ni++) for (int nj = 0; nj < cj.length; nj++) scoreCache.set(ci[ni], cj[nj], val); } return scoreCache.get(ci[0], cj[0]); }
public static void testLoadingData(String[] args) { System.out.println("Loading point cloud from data: ex 0"); if (args.length < 1) { System.out.println("Usage: java ImageManipulation filename.dat"); System.exit(0); } // load point cloud PointCloud N; // N=PointCloud.randomPoints(10000, 3); N = Clustering.readFile(args[0]); Draw.draw2D(N, "original point cloud"); Draw.draw3D(N); }
/** * For each pair of clusters, calculate the score of the {@link * cc.mallet.cluster.neighbor_evaluator.Neighbor} that would result from merging the two clusters. * Choose the merge that obtains the highest score. If no merge improves score, return original * Clustering * * @param clustering * @return */ public Clustering improveClustering(Clustering clustering) { double bestScore = Double.NEGATIVE_INFINITY; int[] toMerge = new int[] {-1, -1}; for (int i = 0; i < clustering.getNumClusters(); i++) { for (int j = i + 1; j < clustering.getNumClusters(); j++) { double score = getScore(clustering, i, j); if (score > bestScore) { bestScore = score; toMerge[0] = i; toMerge[1] = j; } } } converged = (bestScore < stoppingThreshold); if (!(converged)) { progressLogger.info( "Merging " + toMerge[0] + "(" + clustering.size(toMerge[0]) + " nodes) and " + toMerge[1] + "(" + clustering.size(toMerge[1]) + " nodes) [" + bestScore + "] numClusters=" + clustering.getNumClusters()); updateScoreMatrix(clustering, toMerge[0], toMerge[1]); clustering = ClusterUtils.mergeClusters(clustering, toMerge[0], toMerge[1]); } else { progressLogger.info("Converged with score " + bestScore); } return clustering; }
/** * The main sequence. TODO * * @param args expects 9 arguments * @throws IOException occurs if there's an input or output error */ public static void main(String[] args) throws IOException { boolean printOutput, update, adjustedEdgeWeights = false; Clustering clustering; Console console; double performance, maxPerformance, resolution, resolution2, meaningfulMaxM, v_scalingParam; int i, j, nIterations, nRandomStarts; long beginTime, endTime, randomSeed; Network network; Random random; String inputFileName, outputFileName; VOSClusteringTechnique VOSClusteringTechnique; System.out.println("-------------------------------------"); System.out.println("Modularity Optimizer"); System.out.println("Version 1.3.0"); System.out.println("by Ludo Waltman and Nees Jan van Eck"); System.out.println("-------------------------------------"); // read in the arguments if (args.length == 9) { inputFileName = args[0]; outputFileName = args[1]; v_scalingParam = Double.parseDouble(args[2]); resolution = Double.parseDouble(args[3]); meaningfulMaxM = Double.parseDouble(args[4]); nRandomStarts = Integer.parseInt(args[5]); nIterations = Integer.parseInt(args[6]); randomSeed = Long.parseLong(args[7]); printOutput = (Integer.parseInt(args[8]) > 0); } else { console = System.console(); inputFileName = console.readLine("Input file path/name: "); outputFileName = console.readLine("Output file path/name (without file extension): "); v_scalingParam = Double.parseDouble( console.readLine( "Scaling parameter V (0 to 1; rates the" + " importance of the weight of inter-cluster edges," + " with respect to the weight of intra-cluster edges): ")); resolution = Double.parseDouble(console.readLine("Resolution parameter (e.g., 1.0): ")); meaningfulMaxM = Double.parseDouble(console.readLine("Meaningful maximum M of edge weights: ")); nRandomStarts = Integer.parseInt(console.readLine("Number of random starts (e.g., 10): ")); nIterations = Integer.parseInt(console.readLine("Number of iterations (e.g., 10): ")); randomSeed = Long.parseLong(console.readLine("Random seed (e.g., 0): ")); printOutput = (Integer.parseInt(console.readLine("Print output (0 = no; 1 = yes): ")) > 0); System.out.println(); } // read input file if (printOutput) System.out.println("Reading input file..."); network = readInputFile(inputFileName); if (printOutput) System.out.println("Finish reading input file."); // print network characteristics if (printOutput) { System.out.println(); System.out.format("Number of nodes: %d%n", network.getNNodes()); System.out.format("Number of edges: %d%n", network.getNEdges()); System.out.println("Running Louvain algorithm - performance"); System.out.println("Scaling parameter V: " + v_scalingParam); System.out.println("Meaningful maximum M: " + meaningfulMaxM); System.out.println(); } /** * Run the Louvain algorithm nRandomStarts times, beginning with a random node configuration * every time. After all the trials, return the trial that resulted in the best performance * score. */ beginTime = System.currentTimeMillis(); clustering = null; maxPerformance = Double.NEGATIVE_INFINITY; random = new Random(randomSeed); for (i = 0; i < nRandomStarts; i++) { if (printOutput && (nRandomStarts > 1)) { System.out.format("\tRandom start: %d%n", i + 1); } VOSClusteringTechnique = new VOSClusteringTechnique( v_scalingParam, meaningfulMaxM, network, resolution, outputFileName); j = 0; update = true; // Print performance of unaltered graph once if (i == 0) { System.out.println( "Performance of unaltered graph: " + VOSClusteringTechnique.calcPerformanceFunction()); } // run for nIterations times, or until there is no increase in performance do { if (printOutput && (nIterations > 0)) { System.out.format("\nIteration: %d%n", j + 1); update = VOSClusteringTechnique.runLouvainAlgorithm(random); } j++; performance = VOSClusteringTechnique.calcPerformanceFunction(); if (printOutput && (nIterations > 0)) System.out.format("\nIteration %d performance: %.4f%n", j, performance); } while ((j < nIterations) && update); // we have found our best clustering if (performance > maxPerformance) { clustering = VOSClusteringTechnique.getClustering(); maxPerformance = performance; } /* Print all clusterings to .tree file */ VOSClusteringTechnique.printClusteringsToTree(); /* Find the best clustering and print it */ VOSClusteringTechnique.bestOverallClustering(); /* Are we in the M = max or M = remove high outliers case? */ adjustedEdgeWeights = VOSClusteringTechnique.adjustedEdgeWeights; } endTime = System.currentTimeMillis(); // print end-of-algorithm information if (printOutput) { System.out.format( "\nMaximum performance in %d random starts: %.4f%n", nRandomStarts, maxPerformance); System.out.format("Number of communities: %d%n", clustering.getNClusters()); System.out.format("Elapsed time: %d seconds%n", Math.round((endTime - beginTime) / 1000.0)); System.out.println(); } // write to output file if (printOutput) System.out.println("Writing to non-optimized .graph..."); writeOutputFile(outputFileName, clustering, adjustedEdgeWeights); if (printOutput) System.out.println("Finish writing to non-optimized .graph."); }