(Python) J'ai essayé d'analyser 1 million de mains ~ J'ai essayé d'estimer le nombre d'AA ~

Merci pour la navigation. Il est jaune pbird.

Cette fois, j'ai estimé le nombre d'apparitions AA à partir d'un million de mains. Plus précisément, nous estimons la probabilité et la quantité de AA qui apparaîtront pour une main de 2000 inconnue que vous jouerez dans le futur. La procédure d'estimation est la suivante.

① Agréger les mains et créer un histogramme ② Testez si les mains agrégées ont une normalité ③ Trouvez la valeur moyenne et la valeur de l'écart type ④ Estimer le nombre d'occurrences d'AA avec une précision de 95%

En ce qui concerne le contenu ci-dessus et les termes techniques qui apparaîtront par la suite, les livres suivants sont très faciles à comprendre, je les posterai donc. ・ "Statistiques d'introduction complètes pour l'auto-apprentissage Version Kindle" Hiroyuki Kojima (Auteur) https://amzn.to/3mSPpqf

Vous trouverez ci-dessous un histogramme qui résume les conclusions. Dans l'histogramme de cet article, l'axe vertical montre la valeur intégrée et l'axe horizontal montre le nombre de fois où AA est apparu dans 2000 mains.

スクリーンショット 2020-09-26 16.22.47.png

■ Qu'est-ce qu'un histogramme? Un histogramme est simplement un "graphique de données agrégées". Prenant la figure ci-dessus comme exemple ・ Le nombre d'apparitions AA toutes les 2000 mains était de 8 fois (axe horizontal), mais il était de 72 fois (axe vertical) dans 1 million de mains. ・ Le nombre de fois où AA est apparu toutes les 2000 mains était de deux fois (axe horizontal), mais une fois pour 1 million de mains (axe vertical). Etc.

■ Qu'est-ce que le test SW? Il existe différentes méthodes de test de normalité, mais cette fois, nous utiliserons le test SW. Le test SW est une méthode permettant de vérifier si les données agrégées ont une normalité dans le groupe de données d'origine (= population). Avec la normalité, diverses lois peuvent être utilisées. Et il est possible d'estimer le nombre d'occurrences d'AA en utilisant ces règles.

Dans le test SW, la valeur p est utilisée pour juger de la normalité. La valeur p est une valeur qui exprime la probabilité que les données soient distribuées comme des données agrégées lorsque les données sont sélectionnées au hasard dans la population et distribuées, en supposant que la population a une normalité. En général, si la probabilité de distribution est inférieure à 5%, elle est trop faible et on juge que la population n'a pas de règles de normalité en premier lieu (= la population n'a pas de normalité). .. Dans la figure ci-dessus, la valeur p (valeur P) est 0,08> 0,05 (= 5%), on peut donc dire qu'il existe une normalité marginale.

■ Valeur moyenne et valeur de l'écart type Dans la figure ci-dessus ・ Moyenne → moyenne (μ) ・ Écart → écart-type (σ) Est applicable.

■ Méthode d'estimation avec une précision de 95% Soit μ la valeur moyenne des données agrégées et σ la valeur de l'écart type. Il y a 95% de chances que le nombre d'occurrences AA soit compris entre «μ-1,96σ ≤ x ≤ μ + 1,96σ».

Donc ** "Si vous jouez 2000 mains, AA apparaîtra 3,37 fois ou plus et 15,29 fois ou moins avec une chance de 95%." ** Ce sera.

Puisque l'estimation est basée sur les données de 1 million de mains, il y a une erreur dans la valeur d'estimation ci-dessus. Au fur et à mesure que les données augmentent et que les valeurs moyennes et d'écart-type se rapprochent de la moyenne de la population et des valeurs de l'écart-type de la population, les valeurs estimées seront également exactes.

À propos, dans le cas de KK, c'est comme suit. Puisque la valeur P = 0,03 <0,05, l'hypothèse est rejetée et la population n'a aucune normalité. Dans ce cas, les données agrégées n'ont pas de normalité, il n'est donc pas possible d'estimer la précision à 95%.

スクリーンショット 2020-09-26 17.05.46.png

Cependant, si le nombre de mains augmente, la valeur de la valeur P augmentera et les données seront normales.

Dans le cas de QQ, il y a normalité ** "Si vous jouez 2000 mains, QQ apparaîtra 3,40 fois ou plus et 14,54 fois ou moins avec 95% de chances" **.

スクリーンショット 2020-09-26 17.05.26.png

Au fait, pourquoi KK n'est-il pas régulier? Quelle est la différence avec les histogrammes AA ou QQ! Je pense que certaines personnes disent cela.

···Je suis d'accord avec toi! !! !!

Il est mauvais que la valeur p soit estimée autour de la valeur numérique à la limite de la frontière. Ce problème peut être résolu en remplaçant toutes les 2000 mains par 1000 mains. Cependant, c'est un problème, et comme la valeur sur l'axe horizontal n'est que de 0 ou plus, il ne sera pas possible d'effectuer une analyse correcte ...

スクリーンショット 2020-09-27 0.23.56.png

スクリーンショット 2020-09-27 6.57.38.png

Le fait est qu'un million de mains, c'est trop peu lol

Cependant, c'est vraiment pratique car des calculs aussi compliqués peuvent être effectués en un instant avec Python. Je vais garder le code source, alors veuillez l'utiliser aussi !!

En fait, le contenu du test SW n'est pas très bien compris. En Python, vous pouvez calculer avec une seule ligne, donc même si vous savez quel type de valeur numérique vous pouvez obtenir, le processus de calcul est difficile à comprendre. Si vous avez des livres qui sont expliqués avec des exemples réels, je vous serais reconnaissant de bien vouloir me le faire savoir!

Voici le code source. Le programme est un débutant complet, donc si vous avez des idées sur la façon d'écrire un meilleur code, faites-le nous savoir! !!

pokermain.py


from holdcards import Holdcards 
from plotgraph import Plotgraph
import os
import glob
import re

path='Écrivez le chemin ici'
hand = "AA"  #Décrivez la main que vous souhaitez rechercher
count = 2000 #Décrivez chaque main que vous souhaitez vérifier


num = lambda val : int(re.sub("\\D", "", val))
filelist = sorted(glob.glob(os.path.join(path,"*.txt"),recursive=True),key = num)
totcards = []
graphdata = []
countdata = []
counthands = []
for item in filelist:
    print(item)
    with open(item) as f:
        data = f.readlines()
        card = Holdcards()
        h_cards = card.find_holdcards(data)
        totcards += h_cards

i = 0
while len(totcards[count*i:count*(i+1)]) == count:
    graphdata.append(totcards[count*i:count*(i+1)])
    i += 1

for item in graphdata:
    countdata.append(item.count(hand))

graph= Plotgraph()

graph.writehist(countdata,hand,count,len(graphdata)*count)  #Test SW-Normalisation

holdcards.py



class Holdcards:
       def __init__(self):
              self.trump={"A":"14","K":"13","Q":"12","J":"11","T":"10","9":"9","8":"8","7":"7","6":"6","5":"5","4":"4","3":"3","2":"2"}
              self.r_trump={"14":"A","13":"K","12":"Q","11":"J","10":"T","9":"9","8":"8","7":"7","6":"6","5":"5","4":"4","3":"3","2":"2"}
              self.hands = 0
              self.tothands = 0
              self.handlist = []


       def find_holdcards(self,data):
              holdcards = []
              for item in data:
                     if 'Dealt to' in item:
                            item = item[-7:-2]
                            if item[1] == item[4]:
                                   if int(self.trump.get(item[0])) > int(self.trump.get(item[3])):
                                          item = item[0] + item[3] + 's'
                                   else:
                                          item = item[3] + item[0] + 's'
                            else:
                                   if int(self.trump.get(item[0])) > int(self.trump.get(item[3])):
                                          item = item[0] + item[3] + 'o'
                                   elif item[0] == item[3]:
                                          item = item[0] + item[3]
                                   else:
                                          item = item[3] + item[0] + 'o'
                            
                            holdcards.append(item)
              return holdcards

plotgraph.py


import numpy as np
import pandas as pd
import scipy.stats as st
import math                        
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker 
import matplotlib.transforms as ts 

class Plotgraph:
       def __init__(self):
              pass

       def writehist(self,countdata,hand,count,tothands):#Moyenne mu, écart type sig, nombre de nombres aléatoires normaux n

              df = pd.DataFrame( {'p1':countdata} )
              target = 'p1'  #Colonnes à tracer dans le bloc de données
              # (1)Traitement statistique
              mu  = round(df[target].mean(),2)  #moyenne
              sig = round(df[target].std(ddof=0),2)#Écart type: ddof(Degré de liberté)=0
              print(f'■ Moyenne:{df[target].mean():.2f},écart-type:{df[target].std(ddof=0):.2f}')
              ci1, ci2 = (None, None)

              #Paramètres de dessin graphique
              x_min = round(mu - 3*sig)
              x_max = round(mu + 3*sig)  #Plage de score à tracer (limites inférieure et supérieure)
              j = 10                  #Taille de pas de l'axe Y (fréquence)
              k = 1                   #classe
              bins = int((x_max - x_min)/k)            #Nombre de sections(x_max-x_min)/k  (100-40)/5->12
              d = 0.001

              #Processus de dessin d'ici
              plt.figure(dpi=96)
              plt.xlim(x_min,x_max)
              hist_data = plt.hist(df[target], bins=bins, color='tab:cyan', range=(x_min, x_max), rwidth=0.9)
              n   = len(hist_data[0])    #Taille de l'échantillon
              plt.title("hand = "+hand+" , totalhands = "+str(tothands))

              # (2)Dessiner un histogramme
              plt.gca().set_xticks(np.arange(x_min,x_max-k+d, k))

              #Test de normalité (niveau de signification 5)%)
              _, p = st.shapiro(hist_data[0])
              print(hist_data[0])
              print(st.shapiro(hist_data[0]))
              if p >= 0.05 :
                     print(f'  - p={p:.2f} ( p>=0.05 )Et on peut dire que la population a la normalité')
                     U2 = df[target].var(ddof=1)  #Estimation de la variance de la population (variance sans biais)
                     print(U2)
                     DF = n-1                     #Degré de liberté
                     SE = math.sqrt(U2/n)         #Erreur standard
                     print(SE)
                     ci1,ci2 = st.t.interval( alpha=0.95, loc=mu, scale=SE, df=DF )
              else:
                     print(f'  ※ p={p:.2f} ( p<0.05 )Et on ne peut pas dire que la population est normale')


              # (3)Courbe approximative en supposant une distribution normale
              sig = df[target].std(ddof=1)  #Écart-type impartial: ddof(Degré de liberté)=1
              nx = np.linspace(x_min, x_max+d, 150) #150 divisions
              ny = st.norm.pdf(nx,mu,sig) * k * len(df[target])
              plt.plot( nx , ny, color='tab:blue', linewidth=1.5, linestyle='--')

              # (4)Réglage de l'échelle / étiquette de l'axe X
              plt.xlabel('total"'+str(hand)+'"/'+str(count)+'hands',fontsize=12)
              plt.gca().set_xticks(np.arange(x_min,x_max+d, k))
              # (5)Réglage de l'échelle / étiquette de l'axe Y
              y_max = max(hist_data[0].max(), st.norm.pdf(mu,mu,sig) * k * len(df[target]))
              y_max = int(((y_max//j)+1)*j) #Le plus petit multiple de j supérieur à la fréquence maximale
              plt.ylim(0,y_max)
              plt.gca().set_yticks( range(0,y_max+1,j) )
              plt.ylabel('Accumulation',fontsize=12)

              # (6)Sortie texte du score moyen et de l'écart type
              tx = 0.03 #Pour le réglage de la position de sortie des caractères
              ty = 0.91 #Pour le réglage de la position de sortie des caractères
              tt = 0.08 #Pour le réglage de la position de sortie des caractères
              tp = dict( horizontalalignment='left',verticalalignment='bottom',
                     transform=plt.gca().transAxes, fontsize=11 )
              plt.text( tx, ty, f'average {mu:.2f}', **tp)
              plt.text( tx, ty-tt, f'deviation {sig:.2f}', **tp)
              plt.text( tx, ty-tt-tt, f'P-value {p:.2f}', **tp)
              plt.vlines( mu, 0, y_max, color='black', linewidth=1 )


              plt.show()

Recommended Posts

(Python) J'ai essayé d'analyser 1 million de mains ~ J'ai essayé d'estimer le nombre d'AA ~
J'ai essayé de vérifier et d'analyser l'accélération de Python par Cython
J'ai essayé de résumer les opérations de chaîne de Python
J'ai essayé d'estimer la section.
J'ai essayé de trouver l'entropie de l'image avec python
[Python] J'ai essayé de visualiser la relation de suivi de Twitter
J'ai essayé d'estimer le rapport de circonférence π de manière probabiliste
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
J'ai essayé Web Scraping pour analyser les paroles.
J'ai essayé d'estimer la similitude de l'intention de la question en utilisant Doc2Vec de gensim
J'ai essayé de trouver le rapport de circonférence par 100 millions de chiffres
[Python] J'ai essayé d'analyser le lanceur qui n'a réussi aucun coup, aucune course
J'ai essayé de corriger la forme trapézoïdale de l'image
[Python] J'ai essayé de visualiser le prix en argent de "ONE PIECE" plus de 100 millions de caractères avec matplotlib.
J'ai essayé d'analyser la négativité de Nono Morikubo. [Comparer avec Posipa]
Qiita Job J'ai essayé d'analyser le travail
J'ai essayé de rationaliser le rôle standard des nouveaux employés avec Python
J'ai essayé d'obtenir les informations sur le film de l'API TMDb avec Python
J'ai essayé d'analyser la carte du Nouvel An par moi-même en utilisant python
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
J'ai essayé d'obtenir et d'analyser les données statistiques de la nouvelle Corona avec Python: données de l'Université John's Hopkins
[Python] J'ai essayé de juger l'image du membre du groupe d'idols en utilisant Keras
J'ai essayé de visualiser facilement les tweets de JAWS DAYS 2017 avec Python + ELK
J'ai essayé d'automatiser le dépôt de 100 yens des courses de chevaux Rakuten (python / sélénium)
J'ai essayé de refactoriser le code de Python débutant (lycéen)
J'ai essayé d'envoyer automatiquement la littérature du nouveau virus corona à LINE avec Python
J'ai essayé de représenter graphiquement les packages installés en Python
Comment obtenir le nombre de chiffres en Python
J'ai essayé de résumer comment utiliser matplotlib de python
J'ai essayé de résumer la forme de base de GPLVM
J'ai essayé de toucher un fichier CSV avec Python
J'ai essayé de résoudre Soma Cube avec python
Essayez d'estimer le nombre de likes sur Twitter
[Python] J'ai essayé de représenter graphiquement le top 10 des ombres à paupières
J'ai essayé de visualiser les informations spacha de VTuber
J'ai essayé d'effacer la partie négative de Meros
J'ai essayé de résoudre le problème avec Python Vol.1
[Python] J'ai essayé d'obtenir Json de squid ring 2
J'ai essayé de classer les voix des acteurs de la voix
J'ai essayé de résoudre la théorie des nombres entiers d'AOJ avec Python
[Python & SQLite] J'ai analysé la valeur attendue d'une course avec des chevaux dans la fourchette 1x win ①
Python pratique 100 coups J'ai essayé de visualiser l'arbre de décision du chapitre 5 en utilisant graphviz
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
Le 15e temps réel hors ligne, j'ai essayé de résoudre le problème de l'écriture avec python
[Courses de chevaux] J'ai essayé de quantifier la force du cheval de course
J'ai essayé la "correction gamma" de l'image avec Python + OpenCV
J'ai essayé de simuler la propagation de l'infection avec Python
J'ai essayé d'analyser les émotions de tout le roman "Weather Child" ☔️
J'ai essayé d'obtenir les informations de localisation du bus Odakyu
J'ai essayé d'implémenter la fonction d'envoi de courrier en Python
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
Je veux connaître la nature de Python et pip