Wie ähnlich sind unsere Geschmäcker?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Wie ähnlich sind unsere Geschmäcker?

    Hi!

    Ich möchte basierend auf zwei unterschiedlichen Datensätzen von Bewertungen (0 bis 10 Punkte) die Geschmäcker zweier User vergleichen.

    ich habe in der Datenbank die Spalten 'rating_id', 'user_id', 'identifier' und 'rating'.
    Anhand des Identifier finde ich heraus, welche Bewertungen der beiden User zusammen gehören.
    Ein grober Entwurf schaut so aus (Ich schreibe hier die Ergebnisser aus der Datenbank als Mengen):
    1. A = 'SELECT * from ratingstable WHERE userid = a';
      B = 'SELECT * from ratingstable WHERE userid = b';
    2. vergleichbar = Durchschnitt (A, B);
      (Es werden nur Bewertungen vergleichen, die beide User getätigt haben.)
    Und hier kommt der Trick bei der Sache:
    Wie berechne ich die Ähnlichkeit der Gesamtbewertungen?
    Ich habe da zwei Ideen:
    • Setzte die Bewertungen in einer von 'identifier' vorgegeben Reihenfolge als String zusammen.
      Berechne den Abstand der Strings.
    • Berechne von den Bewertungen der beiden User (A1, A2, ... An) und (B1, B2, ... Bn) folgenden Abstand:
      Abstand = Summe i von 1 bis n [ Betrag( Ai - Bi ) ];
      Ähnlichkeit = Abstand / n;
      wobei Abstand dann aus der Menge [0, 10] ist.
    Ich denke mir, dass vor allem die zweite Variante die Effizientere ist (Rechenzeit O(n) ), da Stringvergleiche auf Ähnlichkeit ja zwischen O(log n) und O(n^3) haben können.

    Nun meine eigentlichen Fragen:
    Fällt jemand eine bessere Berechnung der Ähnlichkeit ein, als mein zweiter Algorithmus?
    Kann ich in der Datenbankabfrage schon dafür sorgen, dass nur Datensätze gewählt werden, die bei beiden Usern vorhanden sind? Die übereinstimmenden Datensätze per PHP herauszufiltern wäre auch wieder ein Zeitfaktor von O(n), denke ich.
    Ich denke dabei an eine Abfrage in der Art (Achtung: Pseudoabfrage) "SELECT * from ratingstable WHERE userid = a AND (userid = b AND identifier_exists(this.identifier))". :P

    Gruß,
    Max123
    Die Japaner glauben jetzt auch, sie könnten den Superrechner verkaufen. Das wäre
    so, als würde man einen Jumbo-Jet nehmen, vorne und hinten die Spitzen absägen,
    davon 10 Stück zusammenschweißen und als ultimativen Super-Jet verkaufen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Herbi ()

  • Die Datenbankverbindung ist ja immer schon das Nadelöhr, deswegen stört hier auch nicht der aufwendige JOIN, wenn du dafür einen 2ten Verbindungsaufbau einsparst.

    Quellcode

    1. SELECT A.rating AS arating,
    2. B.rating AS brating
    3. FROM ratingstable A
    4. JOIN ratingstable B ON A.identifier = B.identifier
    5. WHERE A.userID = 'a' AND b.userID = 'b';


    Bei deiner Berechnung benutzt du die Summe... dabei kommt es doch eigentlich immer auf den Unterschied für einen einzigen Identifier an.
    • Person PA wertet identifier IA mit 5
    • Person PB wertet identifier IA mit 1
    • Person PA wertet identifier IB mit 1
    • Person PB wertet identifier IB mit 5

    In der Summe sind sie gleich. Individuell verglichen sind sie das aber gar nicht.

    Etwas weiter gedacht reicht vielleicht auch ein SELECT:

    Quellcode

    1. SELECT SUM(ABS(A.rating-B.rating))
    2. FROM ratingstable A
    3. JOIN ratingstable B ON A.identifier = B.identifier
    4. GROUP BY A.identifier, B.identifier
    5. WHERE A.userID = 'a' AND b.userID = 'b';


    Bin mir nicht hunderprozentig sicher, ob die Summe korrekt ist, wenn du nach 2 Kriterien gruppierst. Probiers mal aus und berichte.
  • Beide SQL Abfragen funktionieren.

    Allerdings hat sich in deine zweite ein Fehler eingeschlichen, so ist es richtig:

    Quellcode

    1. SELECT SUM(ABS(A.rating-B.rating))
    2. FROM ratingstable A
    3. JOIN ratingstable B ON A.identifier = B.identifier
    4. WHERE A.userID = 'a' AND B.userID = 'b'
    5. GROUP BYA.identifier, B.identifier;
    Die Japaner glauben jetzt auch, sie könnten den Superrechner verkaufen. Das wäre
    so, als würde man einen Jumbo-Jet nehmen, vorne und hinten die Spitzen absägen,
    davon 10 Stück zusammenschweißen und als ultimativen Super-Jet verkaufen.