Ejemplo n.º 1
0
        public void CalcuatePageRank(List <string> query)
        {
            //det gøres på helt samme måde som vi gjorde det på papir.
            //blot hvor i stedet for at betragte hver document og dermed
            //hver row og col i P matricen, så betragter vi her blot
            //kun de documenter som matchede querien og dermed kun
            //de row og col i P matricen som svarer til id'erne for de dokumenter.

            this.termsInQuery = query;
            List <int> idOfDocsMatchingQuery = new List <int>();

            //we are only interested in the documents matching a query
            //ved faktisk ikke om man burde gøre det for alle documents.
            //men lige pt udregner vi også kun tfidf-values for de docs som matcher
            //queryen. De andre har vil bare en tfidf-value på 0.
            foreach (string term in termsInQuery)
            {
                //retrieve postings for term.
                List <Tuple <int, int> > postings = new List <Tuple <int, int> >();
                try
                {
                    postings = indexer.indexCreator.index[term];
                }
                catch (Exception)
                {
                    //så hvis der ikke er nogle dokumenter som indeholder termen.
                    //så får vi en fejl og vi prøver blot med næste term
                    continue;
                }

                foreach (Tuple <int, int> docTfPair in postings)
                {
                    //hvis det er første gang vi støder på documentet.
                    if (!idOfDocsMatchingQuery.Contains(docTfPair.Item1))
                    {
                        idOfDocsMatchingQuery.Add(docTfPair.Item1);
                    }
                }
            }


            int numberOfPages = pageDB.GetNumOfCrawledPages();

            //NOTE: Hvis du ikke forstår hvorfor alt er foreach
            //så er det blot fordi vi kun kigger på de docs som matchede querien
            //så istedet for at udregne pagerank for alle pages.
            //så laver vi stadig en P matrix og en q som om vi gjorde det.
            //men vi tilgår bare kun de indgange for de id's af de documenter som
            //matchede querien. Så meget af P matricen er ikke blevet initialiseret.
            //og det samme med q. Man kunne også bare have udregnet det for alle
            //og så nede i udregning af total score så bare kun gøre det for dem
            //som havde matchede querien, men så har vi jo udregnet pagerank for
            //nogle unødvendige, så vi gør dette i stedet.

            //make list of all links
            Dictionary <int, List <string> > idToLinks = new Dictionary <int, List <string> >();

            foreach (int i in idOfDocsMatchingQuery)
            {
                string        iUrl     = pageDB.IdToUrl[i];
                string        iWebpage = pageDB.UrlToWebpage[iUrl];
                List <string> iLinks   = urlFilter.FindLinks(iWebpage, iUrl);
                idToLinks.Add(i, iLinks);
            }

            //calculate normal P-matrix
            //since we only consider all the ids of the pages that
            //matches many indexes in this matrix are never used.
            double[,] P = new double[numberOfPages, numberOfPages];
            foreach (int row in idOfDocsMatchingQuery)
            {
                List <string> iLinks = idToLinks[row];
                foreach (int col in idOfDocsMatchingQuery)
                {
                    string jUrl = pageDB.IdToUrl[col];
                    if (iLinks.Contains(jUrl))
                    {
                        P[row, col] = 1;
                    }
                    else
                    {
                        P[row, col] = 0;
                    }
                }
            }
            //normalize each entry
            Dictionary <int, double> sumOfEachRow = new Dictionary <int, double>();

            foreach (int row in idOfDocsMatchingQuery)
            {
                double sum = 0;
                foreach (int col in idOfDocsMatchingQuery)
                {
                    sum += P[row, col];
                }
                //for hver row gemmer vi dens sum
                sumOfEachRow.Add(row, sum);
            }


            foreach (int row in idOfDocsMatchingQuery)
            {
                foreach (int col in idOfDocsMatchingQuery)
                {
                    if (P[row, col] == 1)
                    {
                        P[row, col] = P[row, col] / sumOfEachRow[row];
                    }
                }
            }

            //tilføj alt det med alpha osv
            double alpha        = 0.1;
            double teleportProb = 1.0 / (double)numberOfPages;

            //udregner PPagerank
            foreach (int row in idOfDocsMatchingQuery)
            {
                foreach (int col in idOfDocsMatchingQuery)
                {
                    double temp  = (1 - alpha) * P[row, col];
                    double temp1 = (alpha * teleportProb);
                    P[row, col] = ((1 - alpha) * P[row, col]) + (alpha * teleportProb);
                }
            }

            //assume we start on page 0
            double[] q = new double[numberOfPages];
            foreach (int i in idOfDocsMatchingQuery)
            {
                q[i] = 0;
            }

            q[idOfDocsMatchingQuery[0]] = 1;


            //calculating new q

            //ineffective iteration over arrays
            //loop hvor man udregner qi indtil den ikke afviger særlig meget
            int iterations = 20; //ifølge slides kunne man også nøjes med mindre (slide 47)

            for (int i = 0; i < iterations; i++)
            {
                foreach (int col in idOfDocsMatchingQuery)
                {
                    double sum = 0;
                    foreach (int row in idOfDocsMatchingQuery)
                    {
                        sum += P[row, col] * q[row];
                    }

                    q[col] = sum;
                }
            }

            //add pagerank værdier til dictionary.
            foreach (int i in idOfDocsMatchingQuery)
            {
                pagerank.Add(i, q[i]);
            }
        }