public kFoldThreadParameter(DataLoader loader, Methodology methodology, int fold, int nIteration) { this.loader = loader; this.methodology = methodology; this.fold = fold; this.nIteration = nIteration; }
// Primary Methods public void startPersonalizedPageRank(object parameterObject) { Stopwatch pageRankStopwatch = Stopwatch.StartNew(); // PageRank Environment Setting personalizedPageRankThreadParamters parameters = (personalizedPageRankThreadParamters)parameterObject; int nFold = parameters.kFold; int nIteration = parameters.nIteration; Methodology methodology = parameters.methodology; try { // Get ego user's ID and his like count long egoID = long.Parse(Path.GetFileNameWithoutExtension(this.dbPath)); // Final result to put the experimental result per fold together this.finalResult = new Dictionary <EvaluationMetric, double>(); // <'HIT(0)', double> or <'AVGPRECISION(1)', double> foreach (EvaluationMetric metric in Enum.GetValues(typeof(EvaluationMetric))) { this.finalResult.Add(metric, 0d); // Initialization } // Need to avoid the following error: "Collection was modified; enumeration operation may not execute" metrics = new List <EvaluationMetric>(this.finalResult.Keys); // K-Fold Cross Validation kFoldSemaphore = new Semaphore(nFold, nFold); List <Thread> kFoldThreadList = new List <Thread>(); // 'Thread': Standard Library Class for (int fold = 0; fold < 1; fold++) // One fold to One thread { // Load graph information from database and then configurate the graph DataLoader loader = new DataLoader(this.dbPath); loader.setEgoNetwork(); loader.setEgoTimeline(); loader.splitTimelineToKfolds(nFold); // |Friend| this.numOfFriend = loader.getNumOfFriend(); // Multi-Threading kFoldSemaphore.WaitOne(); // Wait until Semaphore released Thread thread = new Thread(new ParameterizedThreadStart(runKfoldCrossValidation)); kFoldThreadParameter kFoldparameters = new kFoldThreadParameter(loader, methodology, fold, nIteration); // 'ThreadParams': defined in 'Experiment.cs' thread.Start(kFoldparameters); kFoldThreadList.Add(thread); } // Synchronization: Wait until threads be terminated foreach (Thread thread in kFoldThreadList) { thread.Join(); } if (Program.isValidTrainSet == false) { return; } // Result: <Ego ID>\t<Experi Code>\t<N-fold>\t<iteration>\t<MAP>\t<Recall>\t<|LIKE|>\t<|HIT|>\t<|Friend|> pageRankStopwatch.Stop(); lock (Program.outFileLocker) { Program.logger.Write(egoID + "\t" + (int)methodology + "\t" + nFold + "\t" + nIteration); foreach (EvaluationMetric metric in metrics) { switch (metric) { case EvaluationMetric.MAP: Program.logger.Write("\t{0:F15}", (finalResult[metric] / 1)); break; case EvaluationMetric.RECALL: Program.logger.Write("\t{0:F15}", (finalResult[metric] / 1)); break; case EvaluationMetric.LIKE: Program.logger.Write("\t" + (finalResult[metric])); break; case EvaluationMetric.HIT: Program.logger.Write("\t" + (finalResult[metric])); break; } } // |Friend| Program.logger.Write("\t" + this.numOfFriend); // Output Execution Time Program.logger.WriteLine("\t" + Tools.getExecutionTime(pageRankStopwatch)); Program.logger.Flush(); // Console Output Console.WriteLine("|Friend|: " + this.numOfFriend); Console.WriteLine("Excution Time: " + Tools.getExecutionTime(pageRankStopwatch)); } } catch (Exception e) { Console.WriteLine(e.Message); } finally { Program.dbSemaphore.Release(); } }
private void runKfoldCrossValidation(object parameters) { try { // Setting environment for experiments kFoldThreadParameter p = (kFoldThreadParameter)parameters; DataLoader loader = p.loader; Methodology methodology = p.methodology; int fold = p.fold; int nIteration = p.nIteration; // #1 Core Part: 'EgoNetwork DB' --> 'Graph Strctures(Node, Edge)' loader.setTrainTestSet(fold); if (Program.isValidTrainSet == false) { return; } List <Feature> features = loader.getFeaturesOnMethodology(methodology); loader.setGraphConfiguration(features); // Graph Elements: Nodes and edges Dictionary <int, Node> nodes = loader.allNodes; Dictionary <int, List <ForwardLink> > edges = loader.allLinksFromNodes; // Incase: Mention Count(O), Friendship(X) if (methodology == Methodology.INCL_MENTIONCOUNT || methodology == Methodology.INCL_AUTHORSHIP_AND_MENTIONCOUNT || methodology == Methodology.INCL_FOLLOWSHIP_ON_THIRDPARTY_AND_MENTIONCOUNT || methodology == Methodology.EXCL_FRIENDSHIP) { foreach (List <ForwardLink> forwardLinks in edges.Values) { for (int i = 0; i < forwardLinks.Count; i++) { if (forwardLinks[i].type == EdgeType.FRIENDSHIP) { ForwardLink revisedForwardLink = forwardLinks[i]; revisedForwardLink.type = EdgeType.UNDEFINED; // FRIENDSHIP --> UNDEFINED forwardLinks[i] = revisedForwardLink; } } } } // #2 Core Part: 'Graph Strcture(Nodes, Edges)' --> 'PageRank Matrix(2D-ragged array)' Graph graph = new Graph(nodes, edges); graph.buildGraph(); // #3 Core Part: Recommendation list(Personalized PageRanking Algorithm) Recommender recommender = new Recommender(graph); var recommendation = recommender.Recommendation(0, 0.15f, nIteration); // '0': Ego Node's Index, '0.15f': Damping Factor // #4 Core Part: Validation - AP(Average Precision) DataSet testSet = loader.getTestSet(); HashSet <long> egoLikedTweets = testSet.getEgoLikedTweets(); int hit = 0, like = 0; double AP = 0.0, recall = 0.0; // Average Precision for (int i = 0; i < recommendation.Count; i++) { if (egoLikedTweets.Contains(((Tweet)recommendation[i]).ID)) { hit += 1; AP += (double)hit / (i + 1); } } // LIKE like = (int)egoLikedTweets.Count; // Average Precision & Recall if (hit != 0) { AP /= hit; recall = (double)hit / like; } else { AP = 0.0; recall = 0.0; } // Add current result to final one lock (kFoldLocker) { foreach (EvaluationMetric metric in this.metrics) { switch (metric) { case EvaluationMetric.MAP: this.finalResult[metric] += AP; break; case EvaluationMetric.RECALL: this.finalResult[metric] += recall; break; case EvaluationMetric.LIKE: this.finalResult[metric] += like; break; case EvaluationMetric.HIT: this.finalResult[metric] += hit; break; } } } } catch (FileNotFoundException e) { Console.WriteLine(e); } finally { kFoldSemaphore.Release(); } }
/*******************************************************************************/ /***************************** Primary Methods *********************************/ /*******************************************************************************/ public bool startPersonalizedPageRank(int nFold, int nIteration) { try { // Do experiments for each methodology foreach (Methodology methodology in Program.methodologies) { // Get ego user's ID and his like count long egoUser = long.Parse(Path.GetFileNameWithoutExtension(this.dbPath)); // Check if this experiment has ever been performed earlier int m = (int)methodology; if (Program.existingResults.ContainsKey(egoUser) && Program.existingResults[egoUser].Contains(m)) { lock (Program.locker) { Console.WriteLine("Ego network(" + egoUser + "): done on experiment #" + m); } return(false); } // Final result to put the experimental result per fold together this.finalResult = new Dictionary <EvaluationMetric, double>(); // <'HIT(0)', double> or <'AVGPRECISION(1)', double> foreach (EvaluationMetric metric in Enum.GetValues(typeof(EvaluationMetric))) { this.finalResult.Add(metric, 0d); // Initialization } // Need to avoid the following error: "Collection was modified; enumeration operation may not execute" metrics = new List <EvaluationMetric>(this.finalResult.Keys); // K-Fold Cross Validation List <Thread> threadList = new List <Thread>(); // 'Thread': Standard Library Class for (int fold = 0; fold < 1; fold++) // // One fold to One thread { // Load graph information from database and then configurate the graph DataLoader loader = new DataLoader(this.dbPath); loader.setEgoNetwork(); loader.setEgoTimeline(); loader.splitTimelineToKfolds(nFold); // |Friend| this.numOfFriend = loader.getNumOfFriend(); Thread thread = new Thread(new ParameterizedThreadStart(runKfoldCrossValidation)); // Core Part ThreadParams parameters = new ThreadParams(loader, methodology, fold, nIteration); // 'ThreadParams': defined in 'Experiment.cs' thread.Start(parameters); threadList.Add(thread); } // Synchronization: Wait until threads be terminated foreach (Thread thread in threadList) { thread.Join(); } // Result: <Ego ID>\t<Experi Code>\t<N-fold>\t<iteration>\t<MAP>\t<Recall>\t<|LIKE|>\t<|HIT|>\t<|Friend|> Program.logger.Write(egoUser + "\t" + (int)methodology + "\t" + nFold + "\t" + nIteration); foreach (EvaluationMetric metric in metrics) { switch (metric) { case EvaluationMetric.MAP: Program.logger.Write("\t{0:F15}", (finalResult[metric] / 1)); break; case EvaluationMetric.RECALL: Program.logger.Write("\t{0:F15}", (finalResult[metric] / 1)); break; case EvaluationMetric.LIKE: Program.logger.Write("\t" + (finalResult[metric])); break; case EvaluationMetric.HIT: Program.logger.Write("\t" + (finalResult[metric])); break; } } Program.logger.Write("\t" + this.numOfFriend); } } catch (Exception e) { Console.WriteLine(e.Message); } return(true); }
// Primary Methods public void startPersonalizedPageRank(object parameterObject) { Stopwatch pageRankStopwatch = Stopwatch.StartNew(); // PageRank Environment Setting personalizedPageRankThreadParamters parameters = (personalizedPageRankThreadParamters)parameterObject; int nFold = parameters.kFold; int nIteration = parameters.nIteration; Methodology methodology = parameters.methodology; try { // Get ego user's ID and his like count long egoID = long.Parse(Path.GetFileNameWithoutExtension(this.dbPath)); // Final result to put the experimental result per fold together this.finalResult = new Dictionary<EvaluationMetric, double>(); // <'HIT(0)', double> or <'AVGPRECISION(1)', double> foreach (EvaluationMetric metric in Enum.GetValues(typeof(EvaluationMetric))) this.finalResult.Add(metric, 0d); // Initialization // Need to avoid the following error: "Collection was modified; enumeration operation may not execute" metrics = new List<EvaluationMetric>(this.finalResult.Keys); // K-Fold Cross Validation kFoldSemaphore = new Semaphore(nFold, nFold); List<Thread> kFoldThreadList = new List<Thread>(); // 'Thread': Standard Library Class for (int fold = 0; fold < 1; fold++) // One fold to One thread { // Load graph information from database and then configurate the graph DataLoader loader = new DataLoader(this.dbPath); loader.setEgoNetwork(); loader.setEgoTimeline(); loader.splitTimelineToKfolds(nFold); // |Friend| this.numOfFriend = loader.getNumOfFriend(); // Multi-Threading kFoldSemaphore.WaitOne(); // Wait until Semaphore released Thread thread = new Thread(new ParameterizedThreadStart(runKfoldCrossValidation)); kFoldThreadParameter kFoldparameters = new kFoldThreadParameter(loader, methodology, fold, nIteration); // 'ThreadParams': defined in 'Experiment.cs' thread.Start(kFoldparameters); kFoldThreadList.Add(thread); } // Synchronization: Wait until threads be terminated foreach (Thread thread in kFoldThreadList) thread.Join(); if (Program.isValidTrainSet == false) return; // Result: <Ego ID>\t<Experi Code>\t<N-fold>\t<iteration>\t<MAP>\t<Recall>\t<|LIKE|>\t<|HIT|>\t<|Friend|> pageRankStopwatch.Stop(); lock(Program.outFileLocker) { Program.logger.Write(egoID + "\t" + (int)methodology + "\t" + nFold + "\t" + nIteration); foreach (EvaluationMetric metric in metrics) { switch (metric) { case EvaluationMetric.MAP: Program.logger.Write("\t{0:F15}", (finalResult[metric] / 1)); break; case EvaluationMetric.RECALL: Program.logger.Write("\t{0:F15}", (finalResult[metric] / 1)); break; case EvaluationMetric.LIKE: Program.logger.Write("\t" + (finalResult[metric])); break; case EvaluationMetric.HIT: Program.logger.Write("\t" + (finalResult[metric])); break; } } // |Friend| Program.logger.Write("\t" + this.numOfFriend); // Output Execution Time Program.logger.WriteLine("\t" + Tools.getExecutionTime(pageRankStopwatch)); Program.logger.Flush(); // Console Output Console.WriteLine("|Friend|: " + this.numOfFriend); Console.WriteLine("Excution Time: " + Tools.getExecutionTime(pageRankStopwatch)); } } catch (Exception e) { Console.WriteLine(e.Message); } finally { Program.dbSemaphore.Release(); } }
public static void runKFoldCrossValidation(object parameters) { try { Program.semaphore.WaitOne(); // Setting environment for experiments ThreadParams p = (ThreadParams)parameters; string dbFile = p.dbFile; int nFolds = p.nFolds; int nIterations = p.nIterations; // Check if the DB file exists if (!File.Exists(dbFile)) throw new FileNotFoundException(dbFile); // Do experiments for each methodology foreach (Methodology methodology in Program.methodologies) { // Get ego user's ID and his like count long egoUser = long.Parse(Path.GetFileNameWithoutExtension(dbFile)); int cntLikes = 0; // Check if this experiment has ever been performed earlier int m = (int)methodology; if (Program.existingResults.ContainsKey(egoUser) && Program.existingResults[egoUser].Contains(m)) { lock (Program.locker) { Console.WriteLine("Ego network(" + egoUser + "): done on experiment #" + m); } continue; } // Final result to put the experimental result per fold together var finalResult = new Dictionary<EvaluationMetric, double>(); foreach (EvaluationMetric metric in Enum.GetValues(typeof(EvaluationMetric))) finalResult.Add(metric, 0d); // Need to avoid the following error: "Collection was modified; enumeration operation may not execute" List<EvaluationMetric> metrics = new List<EvaluationMetric>(finalResult.Keys); // K-Fold Cross Validation for (int fold = 0; fold < nFolds; fold++) { // Load graph information from database and then configurate the graph DataLoader loader = new DataLoader(dbFile, nFolds); if (fold == 0) { if (loader.checkEgoNetworkValidation() == false) return; cntLikes = loader.cntLikesOfEgoUser; } loader.graphConfiguration(methodology, fold); // Nodes and edges of graph Dictionary<int, Node> nodes = loader.allNodes; Dictionary<int, List<ForwardLink>> edges = loader.allLinks; // Exeption: for the case that mention count is included when the friendship is none if (methodology == Methodology.INCL_MENTIONCOUNT || methodology == Methodology.EXCL_FRIENDSHIP || methodology == Methodology.INCL_FOLLOWSHIP_ON_THIRDPARTY_AND_MENTIONCOUNT) { foreach (List<ForwardLink> forwardLinks in edges.Values) { List<int> indFriendshipLinks = new List<int>(); for (int i = 0; i < forwardLinks.Count; i++) { if (forwardLinks[i].type == EdgeType.FRIENDSHIP) indFriendshipLinks.Add(i); } foreach (int i in indFriendshipLinks) { ForwardLink forwardLink = forwardLinks[i]; if (forwardLink.type == EdgeType.FRIENDSHIP) { forwardLink.type = EdgeType.UNDEFINED; forwardLinks[i] = forwardLink; } } } } // Make a graph structure to run Random Walk with Restart algorithm Graph graph = new Graph(nodes, edges); graph.buildGraph(); // Get recommendation list Recommender recommender = new Recommender(graph); var recommendation = recommender.Recommendation(0, 0.15f, nIterations); //// temp //lock (Program.locker) { // StreamWriter logger = new StreamWriter(Program.dirData + "rank.dat", true); // logger.WriteLine(methodology); // for (int i = 0; i < recommendation.Count; i++) // logger.WriteLine(recommendation[i].Key + ":\t" + recommendation[i].Value); // logger.Close(); //} // Get evaluation result int nHits = 0; double sumPrecision = 0; for (int i = 0; i < recommendation.Count; i++) { if (loader.testSet.Contains(recommendation[i].Key)) { nHits += 1; sumPrecision += (double)nHits / (i + 1); } } // Add current result to final one foreach (EvaluationMetric metric in metrics) { switch (metric) { case EvaluationMetric.HIT: finalResult[metric] += nHits; break; case EvaluationMetric.AVGPRECISION: finalResult[metric] += (nHits == 0) ? 0 : sumPrecision / nHits; break; } } } lock (Program.locker) { // Write the result of this ego network to file StreamWriter logger = new StreamWriter(Program.dirData + "result.dat", true); logger.Write(egoUser + "\t" + (int)methodology + "\t" + nFolds + "\t" + nIterations); foreach (EvaluationMetric metric in metrics) { switch (metric) { case EvaluationMetric.HIT: logger.Write("\t" + (int)finalResult[metric] + "\t" + cntLikes); break; case EvaluationMetric.AVGPRECISION: logger.Write("\t" + (finalResult[metric] / nFolds)); break; } } logger.WriteLine(); logger.Close(); } } } catch (FileNotFoundException e) { Console.WriteLine(e); } finally { Program.semaphore.Release(); } }
/*******************************************************************************/ /***************************** Primary Methods *********************************/ /*******************************************************************************/ public bool startPersonalizedPageRank(int nFold, int nIteration) { try { // Do experiments for each methodology foreach (Methodology methodology in Program.methodologies) { // Get ego user's ID and his like count long egoUser = long.Parse(Path.GetFileNameWithoutExtension(this.dbPath)); // Check if this experiment has ever been performed earlier int m = (int)methodology; if (Program.existingResults.ContainsKey(egoUser) && Program.existingResults[egoUser].Contains(m)) { lock (Program.locker) { Console.WriteLine("Ego network(" + egoUser + "): done on experiment #" + m); } return false; } // Final result to put the experimental result per fold together this.finalResult = new Dictionary<EvaluationMetric, double>(); // <'HIT(0)', double> or <'AVGPRECISION(1)', double> foreach (EvaluationMetric metric in Enum.GetValues(typeof(EvaluationMetric))) this.finalResult.Add(metric, 0d); // Initialization // Need to avoid the following error: "Collection was modified; enumeration operation may not execute" metrics = new List<EvaluationMetric>(this.finalResult.Keys); // K-Fold Cross Validation List<Thread> threadList = new List<Thread>(); // 'Thread': Standard Library Class for (int fold = 0; fold < 1; fold++) // // One fold to One thread { // Load graph information from database and then configurate the graph DataLoader loader = new DataLoader(this.dbPath); loader.setEgoNetwork(); loader.setEgoTimeline(); loader.splitTimelineToKfolds(nFold); // |Friend| this.numOfFriend = loader.getNumOfFriend(); Thread thread = new Thread(new ParameterizedThreadStart(runKfoldCrossValidation)); // Core Part ThreadParams parameters = new ThreadParams(loader, methodology, fold, nIteration); // 'ThreadParams': defined in 'Experiment.cs' thread.Start(parameters); threadList.Add(thread); } // Synchronization: Wait until threads be terminated foreach (Thread thread in threadList) thread.Join(); // Result: <Ego ID>\t<Experi Code>\t<N-fold>\t<iteration>\t<MAP>\t<Recall>\t<|LIKE|>\t<|HIT|>\t<|Friend|> Program.logger.Write(egoUser + "\t" + (int)methodology + "\t" + nFold + "\t" + nIteration); foreach (EvaluationMetric metric in metrics) { switch (metric) { case EvaluationMetric.MAP: Program.logger.Write("\t{0:F15}", (finalResult[metric] / 1)); break; case EvaluationMetric.RECALL: Program.logger.Write("\t{0:F15}", (finalResult[metric] / 1)); break; case EvaluationMetric.LIKE: Program.logger.Write("\t" + (finalResult[metric])); break; case EvaluationMetric.HIT: Program.logger.Write("\t" + (finalResult[metric])); break; } } Program.logger.Write("\t" + this.numOfFriend); } } catch (Exception e) { Console.WriteLine(e.Message); } return true; }