Avatar billede CodingJoe Nybegynder
11. august 2013 - 15:41 Der er 9 kommentarer

Item rankerings algoritme til sortering og hotness markering af et item

Hejsa

Jeg har været lidt på nettet for at søge lidt på en algoritme, der kan rankere mine elementer.

Jeg har fx. et website med elementer af samme type, bare forskellige fabrikanter. En slutbruger kan review'e og rankere elementet / item ved at trykke på nogle stjerner. Der er fx. max 5 stjerner, slutbrugeren kan markere. Dvs fra 0-5, hvor 5 er det bedste.

Nu når man søger efter elementerne, så vil jeg gerne sortere efter denne rankering / hotness. Hvilken algoritme er bedst egnet til dette til at udregne denne rankering?

bayesian average eller elo ranking system? eller noget helt tredje?

Et eksempel vil være dejligt.
Avatar billede CodingJoe Nybegynder
11. august 2013 - 19:19 #1
Jeg er temmelig sikker på, at jeg skal bruge følgende fremgangsmåde.

Hvad synes I?
http://www.frontendjunkie.com/2011/02/using-bayesian-average-to-rank-content.html
Avatar billede arne_v Ekspert
19. august 2013 - 04:06 #2
Du har vel 2 spoergsmaal:
1) hvad er den bedste algoritme
2) hvordan implementeres den i C#

Svar #2 maa vaere trivielt naar du har svar #1.

Jeg tvivler paa at der er et objektivt bedste svar paa #1.

Kig paa hvad andre bruger.

Proev og lav nogle test data og anvend de forskellige algoritmer og se hvilken der giver det resultat som du oensker.
Avatar billede CodingJoe Nybegynder
19. august 2013 - 07:01 #3
Det er et par dage siden, jeg oprettede mit spørgsmål. I mellemtiden har jeg faktisk lavet et lille test eksempel, jeg gerne vil have review'et.

Jeg gør brug af bayesian average formlen, som tager udgangspunkt i
http://www.frontendjunkie.com/2011/02/using-bayesian-average-to-rank-content.html

Hvad synes du om denne fremgangsmåde?

public class Item
{
    public string Name { get; set; }
    public string Size { get; set; }
    public decimal Rank { get; set; }
    public decimal Votes { get; set; }
    public decimal Points { get; set; }
    public decimal Favorites { get; set; }
    public decimal Likes { get; set; }
    public decimal Followers { get; set; }
    public decimal AveragePoints { get; set; }
}

namespace BayesianAverageExample
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            var items = new List<Item>
                {
                    new Item
                    {
                        Name = "Item A", Size = "SizeA", Votes = 15, Points = 57, Likes = 55, Favorites = 14, Followers = 5
                    },

                    new Item
                    {
                        Name = "Item B", Size = "SizeB", Votes = 20, Points = 64, Likes = 45, Favorites = 24, Followers = 11
                    },

                    new Item
                    {
                        Name = "Item C", Size = "SizeC", Votes = 300, Points = 1015, Likes = 581, Favorites = 470, Followers = 531
                    },

                    new Item
                    {
                        Name = "Item D", Size = "SizeD", Votes = 250, Points = 938, Likes = 45, Favorites = 24, Followers = 11
                    },

                    new Item
                    {
                        Name = "Item E", Size = "SizeE", Votes = 400, Points = 1020, Likes = 450, Favorites = 350, Followers = 111
                    },

                    new Item
                    {
                        Name = "Item F", Size = "SizeF", Votes = 292, Points = 1188, Likes = 75, Favorites = 71, Followers = 91
                    },

                    new Item
                    {
                        Name = "Item G", Size = "SizeG", Votes = 35, Points = 147, Likes = 45, Favorites = 14, Followers = 10
                    },
                    new Item
                    {
                        Name = "Item H", Size = "SizeH", Votes = 100, Points = 300, Likes = 55, Favorites = 64, Followers = 71
                    },
                    new Item
                    {
                        Name = "Item I", Size = "SizeI", Votes = 2, Points = 8, Likes = 39, Favorites = 26, Followers = 31
                    }
                };

            var rankedItems = GetBayesianAverageList(items);
        }


        private static List<Item> GetBayesianAverageList(List<Item> items)
        {
            var totalVotes = items.Select(x => x.Votes).Sum();
            var totalPoints = items.Select(x => x.Points).Sum();

            var memberPopulation = 1500; // GetMembers();

            var totalFavorites = items.Select(x => x.Favorites).Sum();
            var totalLikes = items.Select(x => x.Likes).Sum();
            var totalFollowers = items.Select(x => x.Followers).Sum();

            foreach (var item in items)
            {
                item.AveragePoints = Math.Round(item.Points / item.Votes, 5);

                var bayesianPoints = BayesianAverage(totalVotes, totalPoints, item.Votes, item.Points);
                var bayesianFavorites = BayesianAverage(memberPopulation, totalFavorites, item.Favorites, item.Favorites);
                var bayesianLikes = BayesianAverage(memberPopulation, totalLikes, item.Likes, item.Likes);
                var bayesianFollowers = BayesianAverage(memberPopulation, totalFollowers, item.Followers, item.Followers);

                item.Rank = bayesianPoints + bayesianFavorites + bayesianLikes + bayesianFollowers;
            }

            return items.OrderByDescending(x => x.Rank).ToList();
        }

        private static decimal BayesianAverage(decimal a, decimal b, decimal c, decimal d)
        {
            // http://www.frontendjunkie.com/2011/02/using-bayesian-average-to-rank-content.html
            var bayesian = Math.Round(((a * (b / a)) + (c * d)) / (a + c), 5);
            return bayesian;
        }
    }
}
Avatar billede arne_v Ekspert
08. september 2013 - 05:22 #4
Hvis du har brugt formlen rigtigt, saa er der naeppe meget at sige til koden.
Avatar billede arne_v Ekspert
08. september 2013 - 05:22 #5
Jeg tror ikke at jeg ville have brugt decimal, men .........
Avatar billede CodingJoe Nybegynder
09. september 2013 - 16:19 #6
Hvad ville du bruge i stedet for decimal? :)
Avatar billede arne_v Ekspert
09. september 2013 - 16:25 #7
float eller double

decimal er til eksakte tak som f.eks. beloeb

float og double er til maalinger med en vis usikkerhed

hvis man siger 150.25 +/- 0.0001 krone saa faar bogholderen et lidt mystisk udtryk i ansigtet

hvis man siger at border et 150.25 cm +/- en hundrededel millimeter langt saa er det helt fint

efter min bedste mening er det OK at en ranking score er 150.25 +/- 0.0001 da det jo er et arbitraert valg af algoritme
Avatar billede CodingJoe Nybegynder
10. september 2013 - 10:18 #8
Nu har jeg brugt double, men når jeg laver en math.round...betyder valget af datatype så stadigvæk?
Avatar billede arne_v Ekspert
11. september 2013 - 03:37 #9
Math.Round aendrer vel ikke paa noget??
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester