Exemple #1
0
        public PairRankedItems previous; // automatically construct linked list

        #endregion Fields

        #region Constructors

        public PairRankedItems(RankedItem r1, RankedItem r2)
        {
            item1 = r1;
            item2 = r2;
            previous = mostRecent;
            mostRecent = this;
        }
Exemple #2
0
        /// <summary>
        /// Find every pair, compute alpha, and store the pair in pairRankedItems.  Items are assumed already ranked.
        /// In fact the convex version (limited to [0,1]) is equivalent to the non-convex version (allowing infinite steps)
        /// (just rescale by 1/(1-alpha)).  However the latter is useful because (1) we can easily control step size and (2)
        /// the old weights are left unchanged.
        /// </summary>
        /// <param name="rankedItems"></param>
        /// <param name="convex"></param>
        /// <param name="maxStep">max step to use for non-convex version.</param>
        /// <param name="ctr"></param>
        /// <returns></returns>
        public static PairRankedItems FillPairRankedItems(RankedItem[] rankedItems, bool convex, bool alphaPos, double maxStep, ref int ctr)
        {
            PairRankedItems pri = null;
            for(int i = 0; i < rankedItems.Length - 1; ++i)
            {
                RankedItem x = rankedItems[i];
                for(int j = i + 1; j < rankedItems.Length; ++j)
                {
                    RankedItem y = rankedItems[j];

                    // See boostingNotes.docx.
                    if(convex)
                    {
                        // The convex combination version: (1-alpha)*score1 + alpha*score2.  Disadvantage: previously computed weights
                        // keep changing.
                        if(x.score2 - x.score1 + y.score1 - y.score2 != 0)
                        {
                            // Note ranks go inversely with score
                            double alpha = ( y.score1 - x.score1 ) / ( x.score2 - x.score1 + y.score1 - y.score2 );
                            if(alpha >= 0.0 && alpha <= 1.0)
                            {
                                pri = new PairRankedItems(x, y);
                                pri.alpha = alpha;
                            }
                        }
                    }
                    else
                    {
                        // The score1 + alpha*score2 version.  Advantage: leaves previously computed weights the same.
                        if(x.score2 != y.score2)
                        {
                            double alpha = ( x.score1 - y.score1 ) / ( y.score2 - x.score2 );
                            // alpha=0 corresponds to original rank order for both convex and non-convex combinations
                            if( (alphaPos && alpha >= 0.0 && alpha <= maxStep) ||
                                (!alphaPos && alpha <= 0.0 && alpha >= -maxStep) )
                            {
                                pri = new PairRankedItems(x, y);
                                pri.alpha = alpha;
                            }
                        }
                    }

                }
            }

            return pri;
        }
Exemple #3
0
        /// <summary>
        /// Loop through every alpha.  If both labels are the same, just swap ranks (and no change to NDCG).
        /// If not, still swap ranks, and compute cumulative delta NDCG.  Keep track of that alpha that gave the
        /// best NDCG.  Also treat as a special case alpha=0 (which may give the best result, and which may not
        /// be one of the listed alphas, since those always correspond to swapping points).
        /// </summary>
        /// <param name="pairRankedItems">Assumed sorted by alpha, with the value closest to zero first. WARNING: SIDE EFFECTS on RankedItems.</param>
        /// <param name="dcg"></param>
        /// <param name="bestAlpha"></param>
        /// <param name="bestNDCGGain"></param>
        void FindBestAlpha(PairRankedItems[] pairRankedItems, DCGScorer scorer, int nQueries, out double bestAlpha, out double bestMeanNDCGGain)
        {
            bestAlpha = 0.0;
            double bestNDCGGain = 0.0;
            int bestIndex = 0;
            double NDCGGain = 0.0; // This really is a gain in a gain (again)
            double[] markups = DCGScorer.discounts; // Position dependent part of NDCG

            // Rely on jittering to take care of degeneracy.
            int loopLength = pairRankedItems.Length;
            //int degCtr = 0;
            //while (loopLength != 0)
            //{
            for (int i = 0; i < loopLength; ++i)
            {
                PairRankedItems pairRankedItem = pairRankedItems[i];
                RankedItem x = pairRankedItem.item1;
                RankedItem y = pairRankedItem.item2;
                int rankx = x.rank;
                int ranky = y.rank;
                if (rankx != ranky + 1 && rankx != ranky - 1)
                {
                    throw new Exception("FindBestAlpha: degenerate scores encountered.");
                    //pairRankedItems[degCtr++] = pairRankedItem;
                    //Console.WriteLine("Warning: we've hit a degenerate pair: QueryID {0}", x.QueryID);
                    //Console.WriteLine("QueryID: {0} s1_1 {1} s1_2 {2} s2_1 {3} s2_2 {4} rank1 {5} rank2 {6} crossing error...", x.QueryID, x.score1, y.score1, x.score2, y.score2, rankx, ranky);
                }
                else
                {
                    if (x.label != y.label)
                    {
                        double ndcgx = x.ndcgWt;
                        double ndcgy = y.ndcgWt;
                        double markupx = markups[rankx];
                        double markupy = markups[ranky];
                        NDCGGain += (ndcgx - ndcgy) * (markupy - markupx);
                        if (NDCGGain > bestNDCGGain)
                        {
                            bestNDCGGain = NDCGGain;
                            bestIndex = i;
                        }
                    }

                    // Positions swap only if in the open interval (not at the edges), otherwise could get a spurious gain
                    if ((convex && pairRankedItem.alpha != 0.0 && pairRankedItem.alpha != 1.0) ||
                         (!convex && pairRankedItem.alpha != 0.0 && pairRankedItem.alpha < maxStep && pairRankedItem.alpha > -maxStep))
                    {
                        x.rank = ranky;
                        y.rank = rankx;
                    }
                }
            }

            //				if(degCtr > 0)
            //					Console.WriteLine("Num degenerates = {0}", degCtr);
            //				loopLength = degCtr;
            //				degCtr = 0;
            //			}

            // Put the best alpha half way between that found (which is on the border) and the next, unless it's the last.
            if(bestIndex < pairRankedItems.Length - 1)
                bestAlpha = 0.5 * ( pairRankedItems[bestIndex].alpha + pairRankedItems[bestIndex + 1].alpha );
            else if(bestIndex == pairRankedItems.Length - 1)
                bestAlpha = pairRankedItems[bestIndex].alpha;
            else // The passed pairRankedItems array could be empty.
                bestAlpha = 0.0;

            bestMeanNDCGGain = bestNDCGGain / (double)nQueries;
        }
Exemple #4
0
        public static PairRankedItems[] PRI_ListToArray()
        {
            int ctr = 0;
            PairRankedItems priPtr = PairRankedItems.mostRecent;
            while(priPtr != null)
            {
                ++ctr;
                priPtr = priPtr.previous;
            }

            PairRankedItems[] pairRankedItems = new PairRankedItems[ctr];

            ctr = 0;
            priPtr = PairRankedItems.mostRecent;
            while(priPtr != null)
            {
                pairRankedItems[ctr++] = priPtr;
                priPtr = priPtr.previous;
            }

            return pairRankedItems;
        }
Exemple #5
0
 public int CompareTo(PairRankedItems other)
 {
     return alpha > other.alpha ? 1 : ( alpha < other.alpha ? -1 : 0 );
 }
Exemple #6
0
 public static void Reset()
 {
     mostRecent = null;
 }