Reduzierung der Wirkung von Down-Wählern mit Bewertungssystem

7

Ich habe eine Seite, auf der Benutzer Dinge in einem 1-5-Sterne-System bewerten. Sobald ein Gegenstand die Spitze der Charts erreicht, neigen einige Benutzer dazu, ihn mit 1 Stern zu bewerten, obwohl er eine Mehrheit von 4-5 Sternen hat, um dorthin zu gelangen, wo er sich befindet. Es ist nicht weit verbreitet, ich würde sagen, 10-20% der neuen Stimmen sind 1. Offensichtlich versuchen sie, das Bewertungssystem zu manipulieren, und das möchte ich verhindern.

Die derzeitige Art und Weise, wie ich das tue, besteht darin, ein "angemessenes Fenster" dessen zu haben, was ich für eine legitime Abstimmung halte.

Für Artikel mit weniger als 10 Stimmen; Ich mache momentan nichts und nehme den Mittelwert als Bewertung.

Sobald ein Gegenstand mehr als 10 Stimmen erhält, binde ich ihn an ein Fenster seines Mittelwerts. Dieses Fenster ist definiert als

Window = 4.5 - Log(TotalVotes, 10);

Ein angemessener Abstimmungsbereich ist dann also (Mean - Window) thru (Mean + Window)

Sobald der angemessene Abstimmungsbereich gefunden wurde, ist die "Bewertung" nur der Mittelwert aller angemessenen Stimmen (diejenigen, die in den angemessenen Abstimmungsbereich fallen).

Dies bedeutet, dass ein Artikel mit einem realen Mittelwert von 4,2 mit 100 Stimmen ein Fenster von 4.5-Log(100,10) = 2.5hat. Wenn dieser Artikel also eine 1-Stern-Stimme erhält, wird er in der Bewertung ignoriert. Der 1-Stern wirkt sich jedoch weiterhin auf den zugrunde liegenden Mittelwert aus.

Dies hat im Allgemeinen gut funktioniert, aber das Problem ist, wenn ein Artikel Mean - Windowgerade am Rande von 1,0 steht, sobald er unter 1,0 fällt, ist jetzt jede 1-Stern-Stimme in der Bewertung enthalten und die Bewertung sinkt sogar die Differenz vor und nach Mai erheblich Ich habe gerade noch eine 1-Sterne-Bewertung erhalten.

Ich brauche ein besseres System / eine bessere Methode, um diese 1-Sterne-Bewertungen herauszufiltern, und nicht nur sie, sondern auch die Situation, in der jemand seine Freunde dazu bringt, einen Punkt mit 10 Stimmen und alle 5 Sterne zu bewerten, wobei seine wahre Bewertung möglicherweise höher ist 3 Sterne.

Suchen Sie nach Empfehlungen zum Umgang mit benutzergesteuerten Bewertungssystemen und zur Normalisierung von Ausreißerstimmen.

ParoX
quelle
Sie könnten späteren Stimmen (gut oder schlecht) ein geringeres Gewicht geben. Aber dann bekommt jemand, der einen Freund dazu bringt, früh abzustimmen, ein höheres Gewicht.
Paparazzo
In der Zeitreihenanalyse gibt es ein gutes Analogon dazu: Die Glättung erfolgt über ein sich bewegendes Fenster. Windows waren einst Schrittfunktionen (genau wie Ihr "Fenster"), aber sie sind viel besser, wenn sie Gaußsche sind. Sie sollten Ihr Fenster in einen Gaußschen Wert verwandeln und die Stimmen mit dem Wert des Gaußschen gewichten. Ich werde versuchen, daraus eine Antwort zu machen, bin aber jetzt sehr beschäftigt. Überprüfen Sie den exponentiell gewichteten gleitenden Durchschnitt (EWMA), aber bewegen Sie ihn nicht, dh EWA. Es ist schön, da alles glatt wird und Sie sich von den Quantensprüngen von beitragenden Punktzahlen zu nicht beitragenden Punktzahlen entfernen.
AN6U5
3
Was ist, wenn es dafür einen Grund gibt? Angenommen, im Google Play Store wird eine neue Version einer App hochgeladen. Und hoppla, es ist kaputt. Natürlich geben viele Leute dann eine 1-Sterne-Bewertung, ohne vernünftig zu sein. Ich würde nach anderen Manipulationsindikatoren suchen.
Hat aufgehört - Anony-Mousse

Antworten:

5

Sie sollten sich andere Standortschätzer ansehen.

Was Sie wollen, ist ein robuster Schätzer mit einem hohen Ausfallpunkt .

Der extreme Ansatz wäre der Median.

Möglicherweise erhalten Sie jedoch numerisch interessantere Ergebnisse mit einem getrimmten Mittelwert .

Sie definieren einen Schwellenwert, z. B. 2%. Dann entfernen Sie die oberen 2% der Stimmen und die unteren 2% der Stimmen und nehmen nur den Mittelwert der verbleibenden Einträge. Eine App mit 98% 5 Sternen erhält weiterhin eine 5.0

Aber um Manipulationen zu verhindern, würde ich andere Signale untersuchen. Zum Beispiel gruppierte Stimmen aus einer einzelnen Region.

Hat aufgehört - Anony-Mousse
quelle
Vielen Dank für die Empfehlung, ich bin froh, die technischen Begriffe zu kennen, nach denen ich suche. Das Problem mit einem reduzierten Mittelwert ist, dass Outfits, die nie auf der ersten Seite erscheinen, fast keine 1-Stimmen erhalten, während diejenigen auf der Titelseite 10% oder mehr erhalten. Wenn ich die oberen und unteren 2% beschneide, ist das Problem für Front-Pager immer noch da und es tut Second-Pagern sehr weh. Um Manipulationen zu verhindern, lösche ich Stimmen, die nach IP und geografischer Region weit vom Mittelwert entfernt zu sein scheinen. Dies ist jedoch eine Aufräumaufgabe, die ich alle paar Monate ausführe. Hier geht es darum, wie man sie im
laufenden Betrieb handhabt
2
Wenn Sie dies wie oben beschrieben im laufenden Betrieb tun, werden Sie viel langsamer. Was ist, wenn es einen Grund gibt, warum viele Leute anfangen, schlechte Noten zu geben (z. B. weil bekannt geworden ist, dass das Produkt ein Problem hat?)
Hat aufgehört - Anony-Mousse
1

Ich mag die Antwort von @ Anony-Mousse. Die Verwendung robuster Schätzer ist gut.

Ich möchte eine andere Richtung hinzufügen, um das Problem zu lösen. Es scheint, dass es einige "böswillige" Benutzer gibt, die diese Abstimmungen abgeben, sodass Sie sie möglicherweise identifizieren möchten.

Erstellen Sie einen Datensatz der Benutzer und verwenden Sie " ungerechtfertigt gegossen" führenden Elements" als Bezeichnung. Sie können als Standardwert "Abgestimmte Abstimmung über führendes Element" verwenden und diese dann manuell ändern und die Regel empfindlicher gestalten, z. B. "Mehr als zweimal über das führende Element abstimmen, nachdem das Element die oberen Diagramme erreicht hat" Die Anzahl der niedrigen Stimmen, die Anzahl der niedrigen Stimmen für führende Elemente usw. ist nützlich.

Jetzt befinden Sie sich in einem überwachten Lernrahmen. Wenn Sie böswillige Benutzer identifiziert haben, ignorieren Sie deren Stimmen und vermeiden Sie Manipulationen.

DaL
quelle
1

Um Ihren Schätzer zu stabilisieren, können Sie Ihre Bewertungen als Gaußsches Mischungsmodell (GMM) modellieren, das eine Mischung aus zwei Gaußschen RVs ist: 1) echte Bewertungen, 2) Junk-Bewertung, die gleich eins ist. Scikit-learn hat bereits einen vordefinierten GMM-Klassifizierer: http://scikit-learn.org/stable/auto_examples/mixture/plot_gmm_classifier.html#example-mixture-plot-gmm-classifier-py

Ein einfacher Ansatz wäre, Scikit-Learn Ihre Bewertungen in zwei Gaußsche Werte aufteilen zu lassen. Wenn eine der Partitionen einen Mittelwert nahe eins hat, können wir diese Bewertungen verwerfen. Oder eleganter können wir den Mittelwert des anderen, nicht nahe beieinander liegenden Gaußschen als den wahren Bewertungsmittelwert nehmen.

Hier ist ein bisschen Code für ein ipython-Notebook, das dies tut:

from sklearn.mixture import GMM
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import collections

def make_ratings(mean,std,rating_cnt):
    rating_sample = np.random.randn(rating_cnt)*std + mean
    return np.clip(rating_sample,1,5).astype(int)

def make_collection(true_mean,true_std,true_cnt,junk_count):
    true_ratings = make_ratings(true_mean,true_std,true_cnt)
    junk_ratings = make_ratings(1,0,junk_count)
    return np.hstack([true_ratings,junk_ratings])[:,np.newaxis]

def robust_mean(X, th = 2.5, agg_th=2.5, default_agg=np.mean):
    classifier = GMM(n_components=2)
    classifier.fit(X)
    if np.min(classifier.means_) > th or default_agg(X)<agg_th:
        return default_agg(X)
    else:
        return np.max(classifier.means_)

r_mean = 4.2
X = make_collection(r_mean,2,40,10)
plt.hist(X,5)
classifier = GMM(n_components=2)
classifier.fit(X)
plt.show()
print "vars =",classifier.covars_.flatten()
print "means = ",classifier.means_.flatten()
print "mean = ",np.mean(X)
print "median = ",np.median(X)
print "robust mean = ", robust_mean(X)
print "true mean = ", r_mean
print "prob(rating=1|class) = ",classifier.predict_proba(1).flatten()
print "prob(rating=true_mean|class) = ",classifier.predict_proba(r_mean).flatten()
print "prediction: ", classifier.predict(X)

Die Ausgabe für einen Lauf sieht folgendermaßen aus:

vars = [ 0.22386589  0.56931527]
means =  [ 1.32310978  4.00603523]
mean =  2.9
median =  3.0
robust mean =  4.00603523034
true mean =  4.2
prob(rating=1|class) =  [  9.99596493e-01   4.03507425e-04]
prob(rating=true_mean|class) =  [  1.08366762e-08   9.99999989e-01]
prediction:  [1 0 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 1 0 1 0 1 1 0
 1 1 1 0 0 0 0 0 0 0 0 0 0]

Wir können simulieren, wie dies mit ein paar Monte-Carlo-Versuchen funktionieren wird:

true_means = np.arange(1.5,4.5,.2)
true_ratings = 40
junk_ratings = 10
true_std = 1
m_out = []
m_in = []
m_reg = []
runs = 40
for m in true_means:
    Xs = [make_collection(m,true_std,true_ratings,junk_ratings) for x in range(runs)]
    m_in.append([[m]*runs])
    m_out.append([[robust_mean(X, th = 2.5, agg_th=2,default_agg=np.mean) for X in Xs]])
    m_reg.append([[np.mean(X) for X in Xs]])

m_in = np.array(m_in).T[:,0,:]
m_out = np.array(m_out).T[:,0,:]
m_reg = np.array(m_reg).T[:,0,:]

plt.plot(m_in,m_out,'b.',alpha=.25)
plt.plot(m_in,m_reg,'r.',alpha=.25)
plt.plot(np.arange(0,5,.1),np.arange(0,5,.1),'k.')
plt.xlim([0,5])
plt.ylim([0,5])
plt.xlabel('true mean')
plt.ylabel('predicted mean')
plt.title("true_ratings=" + str(true_ratings)
          + "; junk_ratings=" + str(junk_ratings)
         + "; std="+str(true_std))

Die Ausgabe wird unten eingefügt. Das Rot ist die mittlere Bewertung und das Blau ist die vorgeschlagene Bewertung. Sie können die Parameter anpassen, um leicht unterschiedliche Verhaltensweisen zu erzielen. Geben Sie hier die Bildbeschreibung ein

Bob Baxley
quelle
0

Notiere alle Stimmen

Verhältniszahl von 1 Stimmen auf der Titelseite im Vergleich zu nicht

Wenden Sie nur einen Bruchteil der Stimmen der Nummer 1 an, während Sie sich auf der ersten Seite befinden.
Entfernen Sie grundsätzlich die Verzerrung von Seite 1 basierend auf der Verzerrung von Seite 1 als Ganzes

1 abgegebene Stimme = 1 Stimmenpunkt auf der ersten Seite * (1 Stimmen zweite Seite insgesamt / 1 Stimmen erste Seite insgesamt)

Paparazzo
quelle
0

Obwohl es technisch wahrscheinlich am einfachsten ist, eine der oben genannten Lösungen zu implementieren, sollten Sie meines Erachtens auch in Betracht ziehen, die Wähler nicht dazu zu bewegen, ihre Stimme abzustimmen. Wenn die Downvotes beispielsweise von einer Minderheit von Benutzern stammen, die das System eindeutig missbrauchen, sollten ihre wiederholten Downvotes (wie diese Website) (negativ) für ihren Ruf zählen.

KrisP
quelle
Rate 1-5 ist weder eine Aufwärts- noch eine Abwärtsabstimmung. Sie würden einen Ruf für eine 1 (Top) Bewertung bestrafen.
Paparazzo