Giảm tác động của cử tri xuống với hệ thống xếp hạng


7

Tôi có một trang web trong đó người dùng đánh giá mọi thứ trong hệ thống 1-5 sao. Khi một mục đạt đến đỉnh của bảng xếp hạng, một số người dùng có xu hướng bắt đầu xếp hạng 1 sao mặc dù nó có phần lớn 4-5 sao để đạt được mục tiêu đó. Nó không lan man, tôi sẽ nói 10-20% số phiếu mới là 1. Rõ ràng họ đang cố gắng thao túng hệ thống xếp hạng, và tôi muốn ngăn chặn điều đó.

Cách hiện tại tôi đang làm là bằng cách có một "cửa sổ hợp lý" về những gì tôi coi là một cuộc bỏ phiếu hợp pháp.

Đối với các mục có ít hơn 10 phiếu; Tôi hiện không làm gì và có ý nghĩa như đánh giá của nó.

Khi một mục bắt đầu nhận được hơn 10 phiếu, tôi buộc chúng vào một cửa sổ có ý nghĩa. Cửa sổ này được định nghĩa là

Window = 4.5 - Log(TotalVotes, 10);

Vì vậy, một phạm vi bỏ phiếu hợp lý là sau đó (Mean - Window) thru (Mean + Window)

Khi phạm vi phiếu hợp lý được tìm thấy, "Xếp hạng" chỉ là giá trị trung bình của tất cả các phiếu hợp lý (những người nằm trong phạm vi hợp lý).

Điều này có nghĩa là một mục có ý nghĩa thực sự là 4.2 với 100 phiếu sẽ có một cửa sổ 4.5-Log(100,10) = 2.5, vì vậy nếu mục đó được bình chọn 1 sao, nó sẽ bị bỏ qua trong xếp hạng. Tuy nhiên, 1 sao vẫn sẽ ảnh hưởng đến giá trị trung bình cơ bản.

Điều này nói chung đã hoạt động tốt nhưng vấn đề là khi một mặt hàng Mean - Windowchỉ ở mức 1, ngay khi nó giảm xuống dưới 1, mỗi phiếu bầu 1 sao bây giờ được đưa vào xếp hạng và xếp hạng giảm đáng kể ngay cả chênh lệch trước và sau có thể vừa được thêm một đánh giá 1 sao.

Tôi cần một hệ thống / cách hoàn thành tốt hơn để lọc ra các xếp hạng 1 sao này, và không chỉ họ mà còn xử lý tình huống trong đó ai đó có thể khiến bạn bè của họ nâng cấp một mục 10 phiếu và cả 5 sao, trong đó xếp hạng thực sự của nó có thể nhiều hơn 3 sao.

Tìm kiếm bất kỳ đề xuất nào về cách xử lý các hệ thống xếp hạng do người dùng điều khiển và bình thường hóa các phiếu bầu ngoại lệ.


Bạn có thể cho phiếu bầu sau (tốt hoặc xấu) trọng lượng thấp hơn. Nhưng sau đó, một người nào đó được bạn bè bỏ phiếu sớm sẽ có trọng lượng cao hơn.
paparazzo

Có một sự tương tự tốt trong phân tích chuỗi thời gian này - việc làm mịn được thực hiện thông qua một cửa sổ chuyển động. Windows đã từng là các chức năng từng bước (giống như "cửa sổ" của bạn), nhưng hoạt động tốt hơn nhiều khi chúng là gaussian. Bạn nên biến cửa sổ của bạn thành một gaussian và cân nhắc số phiếu bằng giá trị của gaussian. Tôi sẽ cố gắng biến điều này thành một câu trả lời, nhưng bây giờ tôi thực sự bận rộn. Kiểm tra trung bình di chuyển theo cấp số nhân (EWMA) nhưng không di chuyển nó tức là EWA. Thật tuyệt vì mọi thứ trở nên suôn sẻ và bạn thoát khỏi những bước nhảy lượng tử từ việc đóng góp điểm số đến điểm số không đóng góp.
AN6U5

3
Điều gì nếu có một lý do cho điều đó? Nói trong Google Play Store, một phiên bản mới của một ứng dụng được tải lên. Và oops, nó bị hỏng. Tất nhiên rất nhiều người sẽ đưa ra đánh giá 1 sao sau đó, mà không hợp lý. Tôi sẽ tìm kiếm các chỉ số khác của thao túng.
Có QUIT - Anony-Mousse

Câu trả lời:


5

Bạn nên xem xét các ước tính khác của vị trí.

Những gì bạn muốn là một công cụ ước tính mạnh mẽ , với điểm phá vỡ cao .

Cách tiếp cận cực đoan sẽ là trung vị.

Nhưng bạn có thể nhận được kết quả thú vị hơn về mặt số với giá trị trung bình .

Bạn xác định một ngưỡng, nói 2%. Sau đó, bạn loại bỏ 2% số phiếu hàng đầu và 2% số phiếu dưới cùng và chỉ lấy trung bình của các mục còn lại. Một ứng dụng có 98% 5 sao vẫn sẽ nhận được 5.0

Nhưng để ngăn chặn thao túng, tôi sẽ xem xét các tín hiệu khác. Chẳng hạn như các phiếu bầu từ một khu vực, ví dụ.


Cảm ơn về khuyến nghị, vui mừng khi biết các điều khoản kỹ thuật của những gì tôi sau. Vấn đề với một ý nghĩa được cắt xén là trang phục không bao giờ xuất hiện trên trang đầu tiên hầu như không được 1 phiếu, trong khi những trang trên trang nhất nhận được 10% trở lên. Nếu tôi cắt 2% trên cùng và dưới cùng thì vấn đề vẫn còn đó đối với người chơi trước và nó làm tổn thương rất nhiều máy nhắn tin thứ hai. Để ngăn chặn thao túng, tôi xóa các phiếu có vẻ xa trung bình khi được nhóm theo IP và khu vực địa lý. Tuy nhiên đây là nhiệm vụ dọn dẹp mà tôi thực hiện vài tháng một lần, vấn đề được đặt ra ở đây là làm thế nào để xử lý nó một cách nhanh chóng
ParoX

2
Nếu bạn làm điều này một cách nhanh chóng như bạn đã thảo luận ở trên, bạn sẽ trở nên chậm hơn nhiều. Điều gì xảy ra nếu có một lý do khiến nhiều người bắt đầu cho điểm thấp (ví dụ: vì đã biết sản phẩm có vấn đề?)
Có QUIT - Anony-Mousse

1

Tôi thích câu trả lời của @ Anony-Mousse. Sử dụng công cụ ước tính mạnh mẽ là tốt.

Tôi muốn thêm một hướng khác để đối phó với vấn đề. Có vẻ như có một số người dùng "độc hại" bỏ những phiếu bầu này để bạn có thể muốn xác định chúng.

Tạo một bộ dữ liệu của người dùng và sử dụng " bỏ phiếu không chính đáng vào mục hàng đầu" làm nhãn. Bạn có thể sử dụng "bỏ phiếu bầu chọn cho mục hàng đầu" làm giá trị mặc định và sau đó sửa đổi chúng theo cách thủ công và làm cho quy tắc trở nên tinh tế hơn như "bỏ phiếu nhiều hơn hai lần vào mục hàng đầu sau khi mục đó đạt được các bảng xếp hạng hàng đầu" Tôi đoán rằng các tính năng như số phiếu thấp, số phiếu thấp cho các mục hàng đầu, v.v ... sẽ hữu ích.

Bây giờ bạn đang ở trong một khuôn khổ học tập có giám sát. Khi bạn xác định người dùng độc hại, hãy bỏ qua phiếu bầu của họ và tránh các thao tác.


1

Để củng cố công cụ ước tính của bạn, bạn có thể lập mô hình xếp hạng của mình dưới dạng mô hình hỗn hợp Gaussian (GMM) là hỗn hợp của hai Gaussian rvs: 1) xếp hạng đúng, 2) xếp hạng rác bằng một. Scikit-learn đã có bộ phân loại GMM đóng hộp: http://scikit-learn.org/ sóng / auto_examples / trộn / plot_gmm_ classifier.html # example-trộn-plot-gmm- classifier-py

Đi sâu hơn một chút, một cách tiếp cận đơn giản sẽ là để scikit-learn phân vùng xếp hạng của bạn thành hai gaussian. Nếu một trong các phân vùng kết thúc với giá trị trung bình gần một, thì chúng ta có thể loại bỏ các xếp hạng đó. Hoặc, thanh lịch hơn, chúng ta có thể lấy ý nghĩa của Gaussian khác, không gần một, như là đánh giá thực sự có nghĩa.

Đây là một chút mã cho một máy tính xách tay ipython thực hiện điều này:

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)

Đầu ra cho một lần chạy trông giống như:

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]

Chúng ta có thể mô phỏng cách thức hoạt động của nó với một vài thử nghiệm monte carlo:

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))

Đầu ra được dán bên dưới. Màu đỏ là xếp hạng trung bình và màu xanh là xếp hạng đề xuất. Bạn có thể điều chỉnh các tham số để có được các hành vi hơi khác nhau. nhập mô tả hình ảnh ở đây


0

Ghi lại tất cả các phiếu bầu

Tỷ lệ số 1 phiếu khi ở trang nhất so với không

Chỉ áp dụng một phần số phiếu bầu số 1 trong khi trên trang đầu tiên
Về cơ bản xóa toàn bộ xu hướng trang 1 dựa trên toàn bộ xu hướng trang 1

Áp dụng 1 phiếu = 1 phiếu bầu khi ở trang đầu tiên * (tổng số 1 trang thứ hai / 1 phiếu tổng trang đầu tiên)


0

Mặc dù về mặt kỹ thuật có lẽ là dễ nhất để thực hiện một trong những giải pháp trên, tôi nghĩ bạn cũng nên xem xét việc làm mất lòng các cử tri để hạ bệ. Ví dụ: nếu các lượt tải xuống đến từ một số ít người dùng rõ ràng đang lạm dụng hệ thống, thì các lượt tải xuống lặp đi lặp lại của họ sẽ được tính (phủ định) đối với danh tiếng của họ - như trang web này.


Tỷ lệ 1-5 không phải là một cuộc bỏ phiếu lên hay xuống. Bạn sẽ phạt một danh tiếng cho xếp hạng 1 (hàng đầu).
paparazzo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.