Le livre "Programmation probabiliste en Python: inférence bayésienne et algorithmes"

image Salut, habrozhiteli! Les méthodes bayésiennes font peur aux formules de nombreux informaticiens, mais vous ne pouvez plus vous passer d’analyse des statistiques et des probabilités. Cameron Davidson-Pylon parle de la méthode bayésienne du point de vue d'un programmeur pratique travaillant avec le langage multifonctionnel PyMC et les bibliothèques NumPy, SciPy et Matplotlib. Révélant le rôle des conclusions bayésiennes dans les tests A / B, identifiant la fraude et d'autres tâches urgentes, vous comprendrez non seulement facilement ce sujet non trivial, mais vous commencerez également à appliquer les connaissances acquises pour atteindre vos objectifs.

Extrait: 4.3.3. Exemple: tri des commentaires sur Reddit


Peut-être n'êtes-vous pas d'accord que la loi des grands nombres est appliquée par tous, bien qu'implicitement, dans la prise de décision inconsciente. Prenons l'exemple des évaluations de produits en ligne. Faites-vous souvent confiance à une note moyenne de cinq points sur la base d'un seul avis? Deux critiques? Trois avis? Vous comprenez inconsciemment qu'avec un si petit nombre d'avis, la note moyenne ne reflète pas bien à quel point le produit est bon ou mauvais.


En conséquence, il y a des omissions lors du tri des marchandises et généralement lors de leur comparaison. Pour de nombreux acheteurs, il est clair que trier les résultats d'une recherche interactive par note n'est pas très objectif, peu importe si nous parlons de livres, de vidéos ou de commentaires sur Internet. Souvent, les films ou commentaires en premier lieu obtiennent des notes élevées uniquement en raison d'un petit nombre de fans enthousiastes, et de très bons films ou commentaires sont cachés sur les pages suivantes avec des notes supposément imparfaites d'environ 4,8. Que faire à ce sujet?

Considérez le site populaire Reddit (je ne fournis pas délibérément de liens vers celui-ci, car Reddit est connu pour attirer les utilisateurs, et je crains que vous ne reveniez jamais à mon livre). Sur ce site, il existe de nombreux liens vers différentes histoires et images, et les commentaires sur ces liens sont également très populaires. Les utilisateurs du site (qui est généralement appelé le mot redditor1) peuvent voter pour ou contre chaque commentaire (les soi-disant votes positifs et négatifs). Reddit trie les commentaires par défaut dans l'ordre décroissant. Comment déterminer quels commentaires sont les meilleurs? Ils se concentrent généralement sur les différents indicateurs suivants.

1. Popularité . Un commentaire est considéré comme bon si beaucoup de votes sont exprimés. Les problèmes lors de l'utilisation de ce modèle commencent dans le cas d'un commentaire avec des centaines de votes pour et des milliers de contre. Bien que très populaire, ce commentaire semble trop ambigu pour être considéré comme "le meilleur".

2. La différence . Vous pouvez profiter de la différence entre le nombre de votes pour et contre. Cela résout le problème qui se pose lors de l'utilisation de la métrique de «popularité», mais ne prend pas en compte le caractère temporaire des commentaires. Les commentaires peuvent être envoyés plusieurs heures après la publication du lien d'origine. Dans le même temps, un biais apparaît, en raison duquel la note la plus élevée n'est pas du tout reçue par les meilleurs commentaires, mais les plus anciens, qui ont réussi à accumuler plus de votes pour que les plus récents.

3. Correction du temps . Considérons une méthode dans laquelle la différence entre le pour et le contre est divisée par l'âge du commentaire et une fréquence est obtenue, par exemple, la différence en par seconde ou par minute. Un contre-exemple vient immédiatement à l'esprit: lorsque vous utilisez l'option «par seconde», un commentaire laissé il y a une seconde avec un vote «oui» sera meilleur que laissé il y a 100 secondes avec 99 votes «oui». Ce problème peut être évité si vous ne considérez que les commentaires laissés il y a au moins t secondes. Mais comment choisir une bonne valeur de t? Est-ce à dire que tous les commentaires postés il y a moins de t secondes sont mauvais? Le cas se terminera par une comparaison des valeurs instables avec stable (commentaires nouveaux et anciens).

4. Valeur . Classement des commentaires sur le rapport entre le nombre de voix pour et le nombre total de voix pour et contre. Cette approche élimine le problème de la nature temporelle des commentaires, de sorte que les commentaires récemment publiés avec de bonnes notes recevront une note élevée avec la même probabilité que ceux laissés il y a longtemps, à condition qu'ils aient un ratio de votes relativement élevé par rapport au nombre total de votes. Le problème avec cette méthode est qu’un commentaire avec un vote pour (ratio = 1.0) sera meilleur qu’un commentaire avec 999 votes pour et un contre (ratio = 0.999), bien qu’il soit évident que le second de ces commentaires sera probablement le meilleur.

J'ai écrit «plutôt» pour une raison. Il peut s'avérer que le premier commentaire avec un seul vote oui est vraiment meilleur que le second, avec 999 votes oui. Il est difficile de souscrire à cette déclaration, car nous ne savons pas quels pourraient être les 999 prochains votes potentiels pour le premier commentaire. Disons, il pourrait obtenir à la suite de 999 autres votes pour et pas un seul vote contre et être meilleur que le second, bien qu'un tel scénario ne soit pas très probable.

En fait, nous devons évaluer le rapport réel des votes favorables. Je constate que ce n'est pas du tout la même que la corrélation observée des votes pour; le rapport réel des votes est caché, on observe seulement le nombre de votes pour par rapport aux votes contre (le rapport réel des votes peut être considéré comme la probabilité que ce commentaire reçoive un vote oui, pas contre). Grâce à la loi des grands nombres, on peut dire avec certitude que dans un commentaire avec 999 voix pour et une contre, le ratio réel des voix sera probablement proche de 1. Par contre, nous sommes beaucoup moins sûrs de ce que Le ratio réel de votes pour le commentaire avec un vote en faveur. Cela semble être un problème bayésien.

Une façon de déterminer la répartition a priori des votes affirmatifs est d'étudier l'historique de la répartition des votes affirmatifs. Cela peut être fait en grattant les commentaires Reddit, puis en définissant la distribution. Cependant, cette méthode présente plusieurs inconvénients.

1. Données asymétriques . La majorité absolue des commentaires a un très petit nombre de votes, ce qui fait que les ratios de nombreux commentaires seront proches de l'extrême (voir le graphique «triangulaire» dans l'exemple avec le jeu de données Kaggle dans la figure 4.4) et la distribution sera fortement «biaisée». Vous pouvez essayer de ne considérer que les commentaires dont le nombre de votes dépasse une certaine valeur seuil. Mais ici surgissent des difficultés. Il faut rechercher un équilibre entre le nombre de commentaires disponibles, d'une part, et une valeur de seuil plus élevée avec la précision correspondante du rapport, d'autre part.

2. Données biaisées (contenant des erreurs systématiques) . Reddit est composé de nombreux sous-forums (subreddits). Deux exemples: r / aww avec des photos d'animaux drôles et r / politique. Il est plus que probable que le comportement des utilisateurs lors de commentaires sur ces deux sous-forums Reddit sera radicalement différent: dans le premier d'entre eux, les visiteurs sont le plus susceptibles d'être touchés et de se comporter de manière amicale, ce qui conduira à un plus grand nombre de votes en faveur, par rapport au second, où les opinions dans les commentaires sont susceptibles de diverger.

À la lumière de ce qui précède, il me semble qu'il est judicieux d'utiliser une distribution uniforme a priori.

Maintenant, nous pouvons calculer la distribution postérieure du rapport réel des votes en faveur. Le script comments_for_top_reddit_pic.py est utilisé pour supprimer les commentaires de l'image Reddit la plus populaire. Dans le code suivant, nous avons gratté les commentaires Reddit liés à l'image [3]: http://i.imgur.com/OYsHKlH.jpg.

from IPython.core.display import Image #       %run #   i-   . %run top_pic_comments.py 2 

 [Output]: Title of submission: Frozen mining truck http://i.imgur.com/OYsHKlH.jpg 

 """ Contents:       Votes:   NumPy  ""  ""    """ n_comments = len(contents) comments = np.random.randint(n_comments, size=4) print "  (    %d) \n -----------"%n_comments for i in comments: print '"' + contents[i] + '"' print " ""/"": ",votes[i,:] print 

 [Output]:   (   77) ----------- "Do these trucks remind anyone else of Sly Cooper?"  ""/"": [2 0] "Dammit Elsa I told you not to drink and drive."  ""/"": [7 0] "I've seen this picture before in a Duratray (the dump box supplier) brochure..."  ""/"": [2 0] "Actually it does not look frozen just covered in a layer of wind packed snow."  ""/"": [120 18] 

Avec N votes et un ratio de votes réel donné "pour" p, le nombre de votes "pour" ressemble à une variable aléatoire binomiale avec les paramètres p et N (le fait est que le ratio réel de votes pour "est équivalent à la probabilité de voter pour" par rapport au vote " contre "avec N votes / procès possibles). Nous créons une fonction pour la dérivation bayésienne de p par rapport à l'ensemble des votes «pour» / «contre» un commentaire particulier.

 import pymc as pm def posterior_upvote_ratio(upvotes, downvotes, samples=20000): """         ""  "",   ,    ,    . ,    . """ N = upvotes + downvotes upvote_ratio = pm.Uniform("upvote_ratio", 0, 1) observations = pm.Binomial("obs", N, upvote_ratio, value=upvotes, observed=True) # ;    MAP,     #       . map_ = pm.MAP([upvote_ratio, observations]).fit() mcmc = pm.MCMC([upvote_ratio, observations]) mcmc.sample(samples, samples/4) return mcmc.trace("upvote_ratio")[:] 

Voici les distributions postérieures résultantes.

 figsize(11., 8) posteriors = [] colors = ["#348ABD", "#A60628", "#7A68A6", "#467821", "#CF4457"] for i in range(len(comments)): j = comments[i] label = u'(%d :%d )\n%s...'%(votes[j, 0], votes[j,1], contents[j][:50]) posteriors.append(posterior_upvote_ratio(votes[j, 0], votes[j,1])) plt.hist(posteriors[i], bins=18, normed=True, alpha=.9, histtype="step", color=colors[i%5], lw=3, label=label) plt.hist(posteriors[i], bins=18, normed=True, alpha=.2, histtype="stepfilled", color=colors[i], lw=3) plt.legend(loc="upper left") plt.xlim(0, 1) plt.ylabel(u"") plt.xlabel(u"  ''") plt.title(u"    '' \   "); 

 [Output]: [****************100%******************] 20000 of 20000 complete 

Comme on peut le voir sur la fig. 4.5, certaines distributions sont fortement «pressées», tandis que d'autres ont des «queues» relativement longues, exprimant que nous ne savons pas exactement à quoi sert le ratio réel des votes.

image

4.3.4. Tri


Jusqu'à présent, nous avons ignoré l'objectif principal de notre exemple: trier les commentaires du meilleur au pire. Bien sûr, il est impossible de trier les distributions; trier les valeurs scalaires nécessaires. Il existe de nombreuses façons d'extraire l'essence de la distribution sous la forme d'un scalaire; par exemple, l'essence d'une distribution peut être exprimée en termes d'espérance mathématique ou de valeur moyenne. Cependant, la valeur moyenne pour cela n'est pas appropriée, car cet indicateur ne prend pas en compte l'incertitude des distributions.

Je recommanderais d'utiliser la valeur la moins plausible à 95%, qui est définie comme une valeur avec seulement 5% de probabilité que la valeur réelle du paramètre soit inférieure à celle-ci (cf. la borne inférieure de l'intervalle de confiance bayésien). Ensuite, nous traçons les distributions postérieures avec la valeur la moins probable indiquée à 95% (Fig. 4.6).

image

 N = posteriors[0].shape[0] lower_limits = [] for i in range(len(comments)): j = comments[i] label = '(%d :%d )\n%s…'%(votes[j, 0], votes[j,1], contents[j][:50]) plt.hist(posteriors[i], bins=20, normed=True, alpha=.9, histtype="step", color=colors[i], lw=3, label=label) plt.hist(posteriors[i], bins=20, normed=True, alpha=.2, histtype="stepfilled", color=colors[i], lw=3) v = np.sort(posteriors[i])[int(0.05*N)] plt.vlines(v, 0, 10 , color=colors[i], linestyles="—", linewidths=3) lower_limits.append(v) plt.legend(loc="upper left") plt.ylabel(u"") plt.xlabel(u"  ''") plt.title(u"    '' \   "); order = np.argsort(-np.array(lower_limits)) print order, lower_limits 

 [Output]: [3 1 2 0] [0.36980613417267094, 0.68407203257290061, 0.37551825562169117, 0.8177566237850703] 

Selon notre procédure, les meilleurs seront les commentaires pour lesquels la plus forte probabilité de recevoir un pourcentage élevé de votes oui. Visuellement, il s'agit des commentaires dont la valeur la moins plausible est 95% la plus proche de l'unité. Dans la fig. 4.6 La valeur la moins plausible à 95% est représentée à l'aide de lignes verticales.

Pourquoi le tri basé sur cette métrique est-il une si bonne idée? Le tri selon la valeur la moins plausible à 95% signifie une prudence maximale dans la déclaration des commentaires comme étant les meilleurs. Autrement dit, même dans le pire des cas, si nous surestimons fortement le rapport des votes en faveur, il est garanti que les meilleurs commentaires seront au top. Avec cette commande, les propriétés très naturelles suivantes sont fournies.

1. Des deux commentaires avec le même ratio de votes «pour» observé, le commentaire avec le plus grand nombre de votes sera reconnu comme le meilleur (puisque la confiance est plus élevée pour le ratio le plus élevé).

2. Des deux commentaires avec le même nombre de votes, le meilleur est considéré comme le commentaire avec le plus grand nombre de votes pour.

»Plus d'informations sur le livre sont disponibles sur le site Web de l'éditeur
» Contenu
» Extrait

25% de réduction sur les colporteurs - JavaScript

Lors du paiement de la version papier du livre, un livre électronique est envoyé par e-mail.

Source: https://habr.com/ru/post/fr456562/


All Articles