Esempio n. 1
0
        /****************************** Constructor **********************************/
        // Personalized PageRank Algorithm: All node do random jump to Ego node
        public Model(Graph graph, double dampingFactor, int targetNode)
        {
            this.linkMatrix = graph.matrix;
            this.nNodes = graph.getCntAllNodes();
            this.dampingFactor = dampingFactor;
            this.egoNode = targetNode;

            rank = new double[nNodes];
            nextRank = new double[nNodes];

            for (int i = 0; i < nNodes; i++)
            {
                // Initialize rank score of each node
                rank[i] = (i == targetNode) ? nNodes : 0;
                nextRank[i] = 0;
            }
        }
        public Model(Graph graph, double dampingFactor, int targetNode)
        {
            this.graph = graph;
            this.nNodes = graph.getCntAllNodes();
            this.dampingFactor = dampingFactor;

            rank = new double[nNodes];
            nextRank = new double[nNodes];
            restart = new double[nNodes];

            for (int i = 0; i < nNodes; i++)
            {
                // Initialize rank score of each node
                rank[i] = (i == targetNode) ? nNodes : 0;
                nextRank[i] = 0;

                // Make restart weight
                restart[i] = (i == targetNode) ? 1d : 0; // [1, 0, 0, 0, 0, ... , 0, 0, 0]: Personalized PageRank
            }
        }
 public Recommender(Graph graph) 
 {
     this.graph = graph;
 }
        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();
            }
        }
Esempio n. 5
0
        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();
            }
        }