Autor Thema: Produktbewertungen: Auswertung und Übersicht  (Gelesen 160928 mal)

Quendan

  • Gast
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #75 am: 03 Jan 2018, 12:34:49 »
Gibt es dafür irgend eine mathematische Grundlage, die man sich dafür ansehen könnte?

Die gibt es vmtl irgendwo, aber ich wüsste nicht wo genau, sorry.

Loki

  • Korsaren
  • Hero Member
  • *
  • Beiträge: 3.036
  • Q: Sein v ¬Sein
    • Profil anzeigen
    • Google
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #76 am: 03 Jan 2018, 13:06:42 »
Also ich kenne das gewichtete Bewertungssystem von Bayes auch anders - ohne das Auffüllen mit Phantom-Stimmen. Ich meine, wir hätten damals einfach (durchschnittliche Stimmen * durchschnittliche Bewertung) + (Artikelstimmen * Artikelbewertung) / (durchschnittliche Stimmen + Artikelstimmen) gerechnet. Da wird der Durchschnitt halt dynamisch berechnet und nicht einfach angenommen, dass er bei 3,5 liegt (was die Ergebnisse in diesem Fall halt verfälscht, weil der Durchschnitt in der Realität viel besser ist). Eventuell habe ich aber auch irgendwo die Begründung überlesen, warum die 3,5 verwendet wird statt des tatsächlichen Durchschnitts. Dementsprechend ist die BoardGeek-Geekbewertung auch nicht identisch mit der gewichteten Bewertung nach Bayes, wie es aktuell im Splitterwikiartikel steht.

LG
« Letzte Änderung: 03 Jan 2018, 13:11:31 von Loki »
Who has seen the wind - Neither you nor I
But when the trees bow down their head, The wind is passing by

Yinan

  • Hero Member
  • *****
  • Beiträge: 5.291
  • U3BsaXR0ZXJtb25k
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #77 am: 03 Jan 2018, 13:52:52 »
Also ich kenne das gewichtete Bewertungssystem von Bayes auch anders - ohne das Auffüllen mit Phantom-Stimmen. Ich meine, wir hätten damals einfach (durchschnittliche Stimmen * durchschnittliche Bewertung) + (Artikelstimmen * Artikelbewertung) / (durchschnittliche Stimmen + Artikelstimmen) gerechnet.
Das ist das Gleiche.
"(durchschnittliche Stimmen * durchschnittliche Bewertung) + [..]" IST "Auffüllen mit Phantom-Stimmen". In dem Fall halt "durchschnittliche Stimmen" viele Phantomstimmen mit der Bewertung "durchschnittliche Bewertung".

Die Berechnung für Bayes ist ganz allgemein (zumindest, wenn man es für Ratings einsetzt. Bei anderen Einsatzgebieten wird es nochmal komplizierter und da bin ich dann auch noch nicht so hundert prozentig hinter gestiegen, weil es für den Fall aber auch nicht relevant ist):

(C*m + sum(B)) / (C + S)

S sind dabei die abgegebenen Stimmen, sum(B) ist dabei die Summe der Bewertungen.
C und m sind frei wählbare Werte, wobei C eine Konstante ist, welche gleichzusetzen ist mit S (C sind also "Stimmen") und m eine Bewertung.
Jetzt kann man halt verschiedene Möglichkeiten ansetzen wie man C und m bestimmt. Da kann man C entweder als echte Konstante nehmen, die sich wirklich niemals verändert, oder als Durchschnitt der Artikelstimmen oder sonst irgend ein anderer Wert. Und als m kann man die durchschnittlich mögliche Bewertung nehmen (also 3,5 bei 1 bis 6), als Durchschnitt der tatsächlichen Bewertung (wenn man also 3*1 und 2*4 hat wäre das 2,2) oder als irgend eine andere beliebige Wertung nehmen.

Wir haben halt derzeitig "Feste Anzahl Stimmen * Durchschnittlich mögliche Bewertung", also konkret "50 * 3,5", also "175" (was noch durch die Anzahl der Stimmen geteilt ist, wo die 50 Stimmen natürlich dazu kommen). Es geht halt auch anders. Man könnte z.B. auch einfach die schlechtmöglichste Bewertung nehmen, in diesem Fall also 6, was dann alles nach unten ziehen würde und einfach nur die Relation zueinander noch stärker heraus holen würde, ohne das jemals niedrigere Bewertungen einen "Boost" nach oben bekommen.

Wie gesagt, ich werde es vermutlich umändern in "durchschnittliche Anzahl Stimmen * durchschnittliche mögliche Bewertung" und das jeweils für die Kategorie (also die Spielhelfen werden da eine andere Stimmzahl bekommen als die Abenteuer etc.).
Wobei ich auch da ein Maximum reinsetzen werde (bei den Abenteuern vermutlich so um die 30, bei den Spielhilfen 50 etc.).
Wenn nicht anders gesagt, dann befassen sich meine Aussagen zu Regeln niemals mit Realismus oder Simulationismus, sondern nur mit Balancing.
----
Space is GOD DAMN TERRIFYING! Novas and Hypernovas are natures reminder that we can be wiped out instantly at any given time.

Xandila

  • Hero Member
  • *****
  • Beiträge: 974
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #78 am: 03 Jan 2018, 14:04:25 »
Mal kurz ein Einwurf zu einem anderen Thema, bevor ihr weiter über das Bewertungssystem diskutiert:

Was ist mit den Romanen? Da die ja auch nicht alle bei jedem gleich gut (oder schlecht) ankommen, wären da Bewertungen, die hier eingebunden sind, auch praktisch.
Und wenn es für sie keine Abstimmungen gibt oder geben soll, wäre es zumindest hilfreich, wenn die Diskussionsthreads zu ihnen oben verlinkt würden, dann findet man die schneller.

Loki

  • Korsaren
  • Hero Member
  • *
  • Beiträge: 3.036
  • Q: Sein v ¬Sein
    • Profil anzeigen
    • Google
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #79 am: 03 Jan 2018, 14:27:00 »
Ok, dann bin ich wohl nur über die Formulierung mit dem Auffüllen gestolpert.

Ich habe trotzdem den Satz von Bayes mal so angewendet, wie ich ihn kenne und das Ergebnis hochgeladen:

Sorry but you are not allowed to view spoiler contents.

Ich finde, man sieht da recht gut, dass die Platzierung der Produkte sich im Vergleich zur Speziellen Bewertung in der Splitterwiki bei weitem nicht so drastisch verändert und sich an der Platzierung allgemein nicht so wahnsinnig viel ändert.

LG

PS: Wobei ich gerade sehe, dass die Sortierung nicht hundertprozentig geklappt hat. Man sieht die Tendenz ja trotzdem.
Who has seen the wind - Neither you nor I
But when the trees bow down their head, The wind is passing by

Yinan

  • Hero Member
  • *****
  • Beiträge: 5.291
  • U3BsaXR0ZXJtb25k
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #80 am: 03 Jan 2018, 14:30:18 »
Interessant ist vor allen Dingen die Abenteuer. Weil da haben wir viele mit nur sehr wenig Stimmen dabei.
Wenn nicht anders gesagt, dann befassen sich meine Aussagen zu Regeln niemals mit Realismus oder Simulationismus, sondern nur mit Balancing.
----
Space is GOD DAMN TERRIFYING! Novas and Hypernovas are natures reminder that we can be wiped out instantly at any given time.

Jeong Jeong

  • Korsaren
  • Hero Member
  • *
  • Beiträge: 3.782
  • Autorin und Cosplayerin
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #81 am: 03 Jan 2018, 14:44:44 »
Ich finde die Idee ganz interessant, nur die Platzierung und nicht den Wert anzuzeigen. In einem Artikel wurde genau das für Bewertungsseiten empfohlen. Allerdings verringert es natürlich die Transparenz.

Loki

  • Korsaren
  • Hero Member
  • *
  • Beiträge: 3.036
  • Q: Sein v ¬Sein
    • Profil anzeigen
    • Google
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #82 am: 03 Jan 2018, 14:48:35 »
Der selbe Vergleich für Kaufabenteuer:

Sorry but you are not allowed to view spoiler contents.

Hier ist zwar mehr Bewegung drin, aber massive Veränderungen sehe ich hier auch eher nicht. Hängt aber wohl auch vom Maßstab ab: Einige Abenteuer verändern ihre Position schon stark, aber eben keine so drastische insgesamte Umwälzung.

Link zur LibreOffice-Datei, falls jemand selbst rumspielen will: Link.

LG
« Letzte Änderung: 03 Jan 2018, 14:55:54 von Loki »
Who has seen the wind - Neither you nor I
But when the trees bow down their head, The wind is passing by

Jeong Jeong

  • Korsaren
  • Hero Member
  • *
  • Beiträge: 3.782
  • Autorin und Cosplayerin
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #83 am: 03 Jan 2018, 15:08:09 »
Die Frage ist halt, wo man hin will. Bei dir ist Zügellose Zorn bspw. mit nur drei Bewertungen  immer noch im Spitzenfeld. Das kann mit Blick auf die niedrigen Stimmen bei Abenteuern sinnvoll sein, ist aber letztendlich eine Designentscheidung.

Loki

  • Korsaren
  • Hero Member
  • *
  • Beiträge: 3.036
  • Q: Sein v ¬Sein
    • Profil anzeigen
    • Google
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #84 am: 03 Jan 2018, 15:13:50 »
Einen Fall von Platz 1 auf Platz 10 finde ich schon signifikant, vor allem wenn es nur 40 betrachtete Abenteuer gibt. Das ist schon ein harter Sturz. Aber klar, hängt davon ab, was man erreichen will. Mir persönlich ist die Verzerrung aufgrund der angenommenen 3,5 Durchschnittsbewertung und 50 zusätzlichen Stimmen aber zu stark.

LG
Who has seen the wind - Neither you nor I
But when the trees bow down their head, The wind is passing by

Yinan

  • Hero Member
  • *****
  • Beiträge: 5.291
  • U3BsaXR0ZXJtb25k
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #85 am: 03 Jan 2018, 15:33:52 »
Einen Fall von Platz 1 auf Platz 10 finde ich schon signifikant, vor allem wenn es nur 40 betrachtete Abenteuer gibt. Das ist schon ein harter Sturz.
mMn aber ein berechtigter Sturz. Schließlich hat der 1. Platz nur 3 Stimmen, was dann viele andere übertrifft, die 20+ Stimmen haben, also knapp 7 mal so viele Stimmen.
Insofern finde ich die Bewertung von "Zügelloser Zorn" als ziemlich nichtssagend und sollte mit Vorsicht zu genießen sein, wohingegen z.B. "Ein Funke Mut" mit seinen 23 Stimmen schon wesentlich sicherer in seiner Bewertung ist. Insofern finde ich es sogar gut, wenn es so einen großen Umschwung gibt, wenn die Abenteuer nur so wenig Bewertungen haben.

Und hey, sobald da mehr Stimmen kommen, die auch so gut sind, wird es auch sehr schnell wieder nach oben steigen.
Wenn nicht anders gesagt, dann befassen sich meine Aussagen zu Regeln niemals mit Realismus oder Simulationismus, sondern nur mit Balancing.
----
Space is GOD DAMN TERRIFYING! Novas and Hypernovas are natures reminder that we can be wiped out instantly at any given time.

4 Port USB Hub

  • Hero Member
  • *****
  • Beiträge: 1.047
  • Jetzt mit USB 3.0 Ports
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #86 am: 04 Jan 2018, 02:26:03 »
Hui hab garnich gemerkt dass sich hier so viel getan hat.

Also letztendlich ein zweites Skript, dass etwas entsprechendes für die Splitterwiki ausgibt.
Weil ich glaube nicht, dass die Splitterwiki bbcode hat wie hier im Forum...
ich denke mit etwas Geduld kann man parser und formatter in zwei module unterteilen und dann einen wiki formatter einbinden. Gibts sicher schon einen.
Ja, ich kann bei Gelegenheit mal meine PY-Datei wieder nach GitHub hochladen.
Ja, das wäre super. Offener Quellcode ist immer der beste Weg um Hobbyprojekte vor dem Einschlafen zu bewahren. :)

Das Skript anzupassen sollte nicht so schwierig sein. Habe mir gerade mal n Fork erstellt und es mir angesehen und den letzten Fall kann man da ziemlich einfach mit einbauen (wären einfach nur 2 weitere Attribute die berechnet werden und bei der Ausgabe für den BBCode muss dann nurnoch die beiden Felder mit angegeben werden). Dann kann ich n Pull-Request machen und wenn 4 Port USB Hub das dann annimmt, ist es auch im Master-Branch drin.
gerne, deswegen steht es ja auf github.  :)
Für Fetzenstein! Nieder mit Knax!

Thallion

  • Moderator
  • Sr. Member
  • *****
  • Beiträge: 250
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #87 am: 06 Jan 2018, 09:17:29 »
#!/usr/bin/python
# coding=utf-8

import urllib.request
from statistics import StatisticsError, mean
from bs4 import BeautifulSoup
from collections import namedtuple, OrderedDict
from operator import attrgetter
from multiprocessing.dummy import Pool as ThreadPool

# Collection of Thread IDs in several categories
Produktthreads = OrderedDict([
    ('Spielhilfen', [
     1676, 1418, 2653, 3340, 3341, 3510, 4023, 4241, 4389, 4682, 4681, 5170, 4868, 5089, 5414, 5668, 5785]),
    ('Zubehör', [
     2361, 3345, 3158, 3344, 5115, 5550]),
    ('Kaufabenteuer', [
     2003, 2097, 2360, 2752, 3006, 3343, 3342, 3523, 3524, 3525, 2652, 2651, 3817, 4098, 4244, 4245, 4252, 4302, 4690, 4744, 4745, 5171, 5175, 5174, 5172, 5173, 5373, 5538, 5549, 5537, 5536, 5535, 5696, 5787, 5786]),
    ('Kostenlos verfügbare Abenteuer',
     [2097, 2098, 2099, 2100, 2101, 2652, 2651, 4253])
])

# maintain anthologies separately
Anthologien = OrderedDict([
                           ('Unter Wölfen',[
                                            3523, 3524, 3525]),
                           ('Zwischen den Welten',[
                                            5009, 5010, 5011]),
                           ('An den Küsten der Kristallsee',[
                                                             3828, 3827, 3817, 3826]),
                           ('Alter Friede, neuer Streit',[
                                            5173, 5174, 5175]),
                           ('Verwunschene Mauern',[
                                            5537, 5536, 5535])
                           ])


# Add anthologies to collection to avoid duplicates
for Anthologie in Anthologien:
    for threadid in Anthologien[Anthologie]:
        if threadid not in Produktthreads['Kaufabenteuer']:
            Produktthreads['Kaufabenteuer'].append(threadid)

# URL of a thread (%d will be thread_id)
baseurl = "http://forum.splittermond.de/index.php?topic=%d.0"

# Number of parallel threads (should be equal to number of CPU cores)
concurrent_parses = 4


def bbcode(tag, string, value=None):
    """Return a text(string) enclosed by the bbcode tags"""
    if value:
        return'[' + tag + '=' + value + ']' + string + '[/' + tag + ']'
    else:
        return'[' + tag + ']' + string + '[/' + tag + ']'


def bbcodeurl(urlstring, urlname):
    """Return an bbcode url format for given url and description"""
    return bbcode('url', urlname, urlstring)


def bbbold(text):
    """Return the text with a bbcode bold tag"""
    return bbcode(tag='b', string=text)


def bbtt(text):
    """Return the text with a bbcode tt tag"""
    return bbcode(tag='tt', string=text)


class bbtable():

    """creates the frame of a bbcode table"""

    def __init__(self, rows):
        """needs the rows as input for this table"""
        self.elements = rows

    def tablify(self, rows):
        """adds start and end tags for tables"""
        return str('[table]\r\n' + rows + '[/table]')

    def __str__(self):
        """prints table in bbcode format"""
        return(self.tablify(''.join(str(row) for row in self.elements)))


class tablerow(bbtable):

    """creates a bbcode table row with correct tags"""

    def cellify(self, rowfield):
        """encloses cells with correct tags"""
        return str('[td]' + str(rowfield) + '[/td]')

    def rowify(self, cells):
        """encloses rows with the correct tags"""
        return str('[tr]' + str(cells) + '[/tr]\r\n')

    def __str__(self):
        """adds cell and row tags to elements"""
        return(self.rowify(''.join(self.cellify(field) for field in self.elements)))


class tableheaderrow(tablerow):

    """adds a header row"""

    def cellify(self, rowfield):
        return str('[td]' + bbbold(rowfield) + bbtt('   ') + '[/td]')


class ProduktParser():

    def __init__(self, Produktthreads, Produkt = namedtuple('Produkt', 'name id url Stimmen Durchschnitt'), Produkte = [], Anthologien = [], baseurl = baseurl):
        """set base properties: URLs, thread ids, format"""
        self.Produkt = Produkt
        self.Produkte = Produkte
        self.baseurl = baseurl
        self.Produktthreads = Produktthreads
        self.Anthologien = Anthologien
        self.bewertungen = set(
            [item for sublist in self.Produktthreads.values() for item in sublist])
        self.pool = ThreadPool(concurrent_parses)
        self.pool.map(self.getProdukt, self.bewertungen)
        self.getAnthologie()

    def getProdukt(self, threadid):
        """collect information for selected thread id"""
        url = self.baseurl % threadid
        page = urllib.request.urlopen(url)
        soup = BeautifulSoup(page.read(), "html.parser")
        Produktname = soup.find('title').string.split('/')[0].strip()
        polls = soup.find('dl', {'class': 'options'})
        options = polls.findAll('dt', {'class': 'middletext'})
        votes = polls.findAll('span', {'class': 'percentage'})
        ergebnis = dict(zip([[int(s) for s in option.string.split() if s.isdigit()][
                        0] for option in options], [int(vote.string.split(' ')[0]) for vote in votes]))
        einzelvotes = [
            item for sublist in [[k] * v for k, v in ergebnis.items()] for item in sublist]
        try:
            durchschnitt = str(round(mean(einzelvotes), 2))
            stimmen = len(einzelvotes)
        except (ZeroDivisionError, StatisticsError) as e:
            durchschnitt = 'No votes yet'
            stimmen = 0
        self.Produkte.append(
            self.Produkt(Produktname, threadid, url, stimmen, durchschnitt))
       
    def getAnthologie(self):
        for Anthologie in self.Anthologien:
            Anthologiedurchschnittagg = 0
            Anthologiestimmen = 0
            for Spielhilfe in self.Produkte:
                if Spielhilfe.id in self.Anthologien[Anthologie]:
                    if  Spielhilfe.Durchschnitt != 'No votes yet':
                        Anthologiestimmen += Spielhilfe.Stimmen 
                        Anthologiedurchschnittagg += Spielhilfe.Stimmen * float(Spielhilfe.Durchschnitt)
            if Anthologiestimmen == 0:
                Anthologiedurchschnitt = 'No votes yet'
            else:
                Anthologiedurchschnitt = str(round(Anthologiedurchschnittagg/Anthologiestimmen, 2))
                         
            self.Produkte.append(
                self.Produkt(Anthologie, 0, 0, Anthologiestimmen, Anthologiedurchschnitt))
                   

    def generateTable(self, bewertungsthreads):
        """"generate a table for the threads"""
        return bbtable([tableheaderrow(['Platz', 'Bewertung', 'Stimmen', 'Produkt'])]
                       + [tablerow([index + 1, element.Durchschnitt, element.Stimmen, bbcodeurl(element.url, element.name)])
                          for index, element in enumerate(sorted(bewertungsthreads, key=attrgetter('Durchschnitt')))])

    def printProdukte(self):
        """"print the table"""
        for key, value in self.Produktthreads.items():
            print('\r\n' + bbbold(key))
            print(self.generateTable(
                [Spielhilfe for Spielhilfe in self.Produkte if Spielhilfe.id in value]))
           
        print('\r\n' + bbbold("Anthologien"))
        print(self.generateTable(
            [Spielhilfe for Spielhilfe in self.Produkte if Spielhilfe.name in [Anthologie for Anthologie in Anthologien]]))


if __name__ == '__main__':
    SplittermondParser = ProduktParser(Produktthreads=Produktthreads, Anthologien=Anthologien)
    print(
        'Hier die Sammlung aller Produktbewertungsthreads, inklusive Durchschnittsbewertung und Ranking.')
    print(
        'Das script ist verfügbar unter https://github.com/zaboron/Splittermond/blob/master/parsebewertungen.py')
    SplittermondParser.printProdukte()
« Letzte Änderung: 07 Jan 2018, 09:11:39 von Thallion »

ShadowAsgard

  • Sr. Member
  • ****
  • Beiträge: 257
    • Profil anzeigen
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #88 am: 08 Jan 2018, 07:21:11 »
Hallo Community,

wolln ma das kleine Weihnachtsszenario "Die Kunst zu backen" aufnehmen?

Ich habs noch nicht gefunden (vielleicht bin ich auch blind  :o)


JohnLackland

  • Beta-Tester
  • Hero Member
  • ***
  • Beiträge: 3.003
  • Nicht Beißen!
    • Profil anzeigen
    • Oh Kultes
Re: Produktbewertungen: Auswertung und Übersicht
« Antwort #89 am: 08 Jan 2018, 08:49:24 »
Hallo Community,

wolln ma das kleine Weihnachtsszenario "Die Kunst zu backen" aufnehmen?

Ich habs noch nicht gefunden (vielleicht bin ich auch blind  :o )


Es ist ein inoffizielle Mini-Szenario und damit kommt es nicht mit in den Pot soweit ich weiß, genausowenig wie die Fanabenteuer (obwohl sie als extra Kategorie vielleicht doch interessant sind,  ich glaube das viele gar nicht Wissen das es diese gibt)
« Letzte Änderung: 08 Jan 2018, 08:52:08 von JohnLackland »
Spielst du schon oder diskutierst du noch über die Regeln?