6
votes

Image moyenne pondérée: valeur en fonction de la valeur

Quelques fond pour expliquer cette question difficile d'abord:

J'ai une base de données qui estime la fiabilité des utilisateurs en comparant les valeurs qu'ils ont soumises à une moyenne globale. Les valeurs varient entre 0 et 1. Donc, où: p>

  • Fiabilité de cet utilisateur particulier = r code> li>
  • moyenne de ces valeurs soumises d'un utilisateur particulier = A code> li>
  • global, "convenu" moyen = g code> li> ul>

    fiabilité: p> xxx pré>

    Voici comment la fiabilité de chaque utilisateur est calculée. Maintenant, le Global, "convenu" moyen g code> est calculé à l'aide d'une moyenne pondérée, où la pondération est le r code> et la valeur est a code >. S'il y a 3 utilisateurs au total: p> xxx pré>

    Le problème est que, une fois que les utilisateurs ont une fiabilité élevée, ils ont un monopole complet et aucune nouvelle valeur ne peut changer cela. Prenant un exemple: P>

    --Creating 3 new users
    INSERT INTO Users
    (UserID, Reliability)
    values 
    (1, 0.5),
    (2, 0.5),
    (3, 0.5)
    GO
    
    --Creating a new GlobalSubmission
    INSERT INTO GlobalSubmission
    (GlobalSubmissionID, NAME, GlobalAverage)
    values (1, 'BOILER2B' , 0.5)
    GO
    
    --First, we will submit values of 1 for two users:
    INSERT INTO UserSubmission values (1.0, 1, 1); -- Value: 1.0, User 1, Submission 1
    GO
    INSERT INTO UserSubmission values (1.0, 1, 2); -- Value: 1.0, User 2, Submission 1
    GO
    INSERT INTO UserSubmission values (1.0, 1, 1); -- Value: 1.0, User 1, Submission 1
    GO
    INSERT INTO UserSubmission values (1.0, 1, 2); -- Value: 1.0, User 2, Submission 1
    GO
    
    
    --Now, we will submit values of 0 for the third user:
    INSERT INTO UserSubmission values (0.0, 1, 3); -- Value: 0.0, User 3, Submission 1
    GO
    INSERT INTO UserSubmission values (0.0, 1, 3); -- Value: 0.0, User 3, Submission 1
    GO
    
    SELECT * FROM Users -- This results in 0% reliability for the last user.
    
    --If we create new users and add them, the reliability won't budge:
    INSERT INTO Users
    (UserID, Reliability)
    values 
    (4, 0.5),
    (5, 0.5),
    (6, 0.5),
    (7, 0.5),
    (8, 0.5)
    GO
    
    
    INSERT INTO UserSubmission values (0, 1, 4); -- Value: 0, User 4, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 5); -- Value: 0, User 5, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 6); -- Value: 0, User 6, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 7); -- Value: 0, User 7, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 8); -- Value: 0, User 8, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 4); -- Value: 0, User 4, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 5); -- Value: 0, User 5, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 6); -- Value: 0, User 6, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 7); -- Value: 0, User 7, Submission 1
    GO
    INSERT INTO UserSubmission values (0, 1, 8); -- Value: 0, User 8, Submission 1
    GO
    
    
    SELECT * FROM Users -- Even though we've added loads of new users suggesting 0 as value, the final value
    -- is remaining 1.0, because when a new value (0) is submitted, it varies too much from the global average
    --(1), causing the reliability of that user to go down, and that user ends up making no influence on the
    -- global average!
    


8 commentaires

@ Guillermorenéramírez, je ne pense pas qu'il obtient des erreurs, en soi. Il cherche plus d'aide algorithmique.


@Davidkiger a cloué.


Désolé, lisez "impasse" et a immédiatement essayé de trouver des serrures en conflit.


Vous avez bien expliqué le problème, mais sans connaître la réponse que vous souhaitez recevoir (par opposition à votre réponse actuelle que vous jugez incorrecte) Comment pouvons-nous aider? Qu'en est-il de calculer uniquement la fiabilité après que toutes les soumissions de l'utilisateur ont été effectuées, si une majorité d'utilisateurs soumettez et de valeur incorrecte vos notes de fiabilité seront également incorrectes.


Que diriez-vous uniquement de calculer la fiabilité après que toutes les soumissions utilisateur ont été faites? c'est très difficile. Il s'agit d'un système de crowdsourded, la nature est que les soumissions seront envoyées au hasard par différents utilisateurs. Vous avez raison, mais la majorité n'est pas souvent fausse. Cela s'appelle "sagesse de la foule". Eh bien, la réponse que je voudrais recevoir serait de préférence changer l'algorithme afin que les nouveaux utilisateurs soumettant des valeurs auraient un impact sur la moyenne globale.


Avez-vous envisagé d'utiliser quelque chose comme une moyenne mobile, de sorte que les soumissions plus anciennes n'ont pas d'impact sur la cote de fiabilité (actuelle) autant que des soumissions plus récentes?


@Jakep aucune idée de la manière dont je peux mettre en œuvre cela, cependant.


David, comme ce que @mcdowella décrit dans sa réponse.


3 Réponses :


0
votes

première suggestion, éliminez les différences absolues. Ils rendent les maths plus difficiles qu'il ne devrait l'être. Utilisez la différence carrée pour garder des choses simples.

Gardez une trace de la somme et du nombre de la valeur soumise de chaque utilisateur.

g = (Sum1 * R1 + Sum2 * R2 + Sum3 * R3) / (Nombre1 * R1 + Nombre2 * R2 + Nombre3 * R3)

Initialise les sommes à 0,5, comptez sur 1 et R à 1,0.

Chaque fois que vous recevez une note, la somme de mise à jour et comptez pour cet utilisateur, GLAZ G et fiabilité pour chaque utilisateur utilisant:

r = 1- (g - somme / compte) ^ 2.

Essentiellement, vous gardez une trace des cotes avec un «préalable». Si vous initialisez le nombre de comptes à un grand nombre, l'algorithme est résistant aux valeurs soumises errantes, mais prend plus de temps pour converger. Le contraire exact est vrai si vous réduisez le nombre initial (cas extrême à 0).


8 commentaires

Qu'est-ce que somme (x) et compte (x) représente s'il vous plaît?


@David Somme est la somme de toutes les valeurs reçues d'un utilisateur particulier. Vous recevez plusieurs valeurs d'un utilisateur, non?


Ahh Ok, je l'ai eu maintenant. Oui.


Je ne peux pas vraiment initialiser les sommes et les comptes. Ils sont tirés de la base de données. Je vais initialiser R à 1.0 cependant, et peut-être que je pourrais ajouter une constante à compter?


Vient d'essayer le vôtre. Voici le code de fiabilité avec votre algorithme: Sélectionnez-nous.userid, 1- (@g -power (Somme (US.Subvalue) / Compte (US.SUBValue), 2)) Fiabilité de l'usermission US Joindre les utilisateurs U ON u.userid = userid where where.globalsubmissionid = 520 groupe par nous.subvalue, us.userid cette partie, au moins se comporte beaucoup comme la mienne. Lorsque g = 1.0, utilisateur1 (moyenne) = 1, user2 (a) = 1 et user3 (a) = 0, le résultat est: user3 (r) = 0, user2 (r) = 1.0 et user1 (R) = 1.0


@David Vous pouvez essayer la puissance ((somme (US.Subvalue) +0.5) / (comptage (US.Subvalue) +1), 2) Si vous souhaitez lisser vos résultats avec un peu avant


Non, c'est la même chose qu'auparavant, car il n'est pas possible de modifier les valeurs des sommes et de compter. C'est probablement parce que l'algorithme est géré plusieurs centaines de fois: chaque fois qu'il y a une nouvelle soumission, tout est recalculé.


@David d'accord. Essayez-le avec le préalable (puissance ((somme (US.Subvalue) +0.5) / (comptage (US.SUBValue) +1), 2)). Essayez également d'ajouter différentes valeurs à la somme et au nombre (5.0 et 10 peut-être).



1
votes

Voici une estimation alternative qui est toujours un peu ad hoc mais ne produit jamais de poids 0.

1) Pour chaque utilisateur, produisent une estimation de manière exponentielle d'erreur carrée. Commencez par une estimation arbitraire correctrice accordable K. Ensuite, chaque fois que l'utilisateur produit une valeur a et la moyenne du groupe est G produisant une erreur carrée E = (A - G) * (A - G) et modifier l'estimation de l'erreur carrée d'avant à Après = avant * x + e * (1 - x) où X est une autre constante accordable entre 0 et 1 qui a changé la carrette des bêches anciennes rapides. Cette estimation ne peut jamais se gâter tout à zéro, mais à cause de la prochaine étape, il pourrait être aussi bien de l'arrêter de diminuer sous une certaine valeur accordable.

2) Pour obtenir une nouvelle estimation globale, utilisez une moyenne pondérée comme avant, mais faites pondre la réciproque de l'estimation actuelle de l'erreur carrée pour cet utilisateur.

Si tous les utilisateurs étaient impartiaux, les estimations de décomposition exponentielle peuvent se retrouver comme des estimations décentes de l'erreur carrée moyenne pour chaque utilisateur, puis les poids constitueraient la combinaison linéaire des estimations qui minimisent l'erreur carrée attendue de l'estimation globale. Vérifiez: Si les différents utilisateurs que j'ai soumis des moyennes de Ni estimations de la même source, l'erreur carrée moyenne des estimations de chaque utilisateur serait 1 / ni multiplication par la réciprocité de cela transformerait leurs moyennes dans la somme d'origine des estimations produites par chacun L'utilisateur et l'estimation pondérée finiraient par mettre en commun des estimations.


10 commentaires

Quelques exemples (pas même en attendant du code, mais des exemples mathématiques) aideraient vraiment. Par exemple, travailler la valeur de E, estimation globale, etc. Lorsque deux utilisateurs soumettent 1.0 et un utilisateur soumet 0,0 par la suite.


Son été un moment, mais la formule de la moyenne mobile doit-elle être E * X + avant * (1 - x)?


avant est la valeur "actuelle" d'un?


Oups, un peu lent aujourd'hui, n'aimable pas si c'est E * X ou avant * x. @David, je crois que "avant" est l'ancienne valeur "fiabilité". Cette formule décrit un Moyenne mobile exponentielle de l'erreur carrée.


Putain, essayant de mettre en œuvre cela avec SQL et c'est vraiment déroutant. Je vais lui donner un autre coup demain, la pensée de pensée est inversement proportionnelle aux heures après minuit: p


Oui, avant la vieille valeur avant de voir A pour un utilisateur particulier, une fois la valeur nouvellement calculée, ce qui est en effet une moyenne mobile exponentielle de l'erreur carrée.


@mcdowella donc, après = avant * x + e * (1 - x) laisser avant = 1,0, x = 0,5, e = 0. après = 1 * 0.5 + 0 * (1-0.5) après = 0.5. Donc, la fiabilité descendait de moitié lorsque l'erreur = 0? Peut-être que c'est mon erreur.


Ce que nous calculons ici diminue en effet avec 0 erreur. Ce n'est plus une mesure de fiabilité, mais une mesure d'une erreur carrée, vous pouvez donc vous attendre à ce que cela descendra ici. Cela a du sens parce que vous avez des estimations de poids par la réciprocité de cela, une erreur carrée inférieure signifie un poids plus important - de 1 / 1,0 = 1 à 1 / 0,5 = 2,0. Si vous souhaitez annoncer une fiabilité, une erreur pas au carré, vous pouvez annoncer le poids.


@mcdowella ok! Pensez que je suis presque là-bas, bien que si j'essaie de trouver la réciprocité de E quand E est 0, je vais avoir l'infini (1/0). Pour l'instant, j'utilise une sorte de hack (si E = 0 retourne Sumofvalues ​​/ Countofvalues). Cela serait-il correct?


En théorie, e ne devrait jamais aller à 0, car il commence non-zéro et le plus bas à chaque étape doit être ex, ex ^ 2, ex ^ 3 ... aucun qui est égal à zéro. En pratique, bien sûr, cela pourrait éventuellement devenir si petit pour être zéro. Je suggère que vous ajoutez E.g. E = max (e, trèssmall) où vessirs est un paramètre corrigé, il ne devient donc jamais ci-dessous. Selon l'endroit où les valeurs proviennent de là peut y avoir une valeur plausible pour cela - si tous les numéros soumis sont des nombres entiers, vous pouvez définir E = 0,25, car 0.5 est une erreur minimale plausible et 0,25 est ceci carré.



0
votes

Ne mettez pas à jour la fiabilité de l'utilisateur qu'après que la nouvelle moyenne globale est calculée.

user1 a is submitted, 1.0
g = (0.5)*(1.0)/(0.5) = 1.0
user1 reliability = 1 - ABS (1 -1) = 1
user2 a is submitted, 1.0
g = ((1.0)*(1.0) + (0.5)*(1.0))/(1 + 0.5) = 1.0
user1 reliability = 1 - ABS (1 -1) = 1
user2 reliability = 1 - ABS (1 -1) = 1
user3 a is submitted, 0.0
g = ((1.0)*(1.0) + (1.0)*(1.0) + (0.5)*(0))/(1 + 1 + 0.5) = 0.8
user1 reliability = 1 - ABS (0.8 -1) = 0.8
user2 reliability = 1 - ABS (0.8 -1) = 0.8
user3 reliability = 1 - ABS (0.8 - 0.0) = 0.2


3 commentaires

Des milliers de soumissions sont envoyées. L'ordre n'a pas d'importance. J'ai essayé, je reçois de bons résultats au début, mais comme étant davantage soumis, il finit très rapidement de zéro.


@David - Si vous obtenez des milliers de 1 de 1, et seulement quelques 0, vous vous attendriez aux personnes qui ont voté 0 pour obtenir une fiabilité de 0. La partie importante est que si les votes se transfèrent plus tard vers une division 50-50, que La fiabilité des personnes qui ont voté 0 monte.


Oui, mais si les votes passent à 50-50 plus tard, la fiabilité ne change pas, c'est la chose!