Porté du langage R de "Sazae-san's Janken Data Analysis" vers Python

introduction

À l'origine, j'ai appris le langage R lorsque j'ai appris l'apprentissage automatique au Shizuoka Developers Study Group en 2013, mais après cela, j'ai appris «[Sazae-san's Janken Data Analysis]» (http: //yaju3d.hatenablog) une seule fois par an. .jp / entry / 2017/01/03/134420) ", je viens de démarrer R Studio, et j'ai l'impression de me souvenir de l'opération. L'année dernière, j'ai pu Préparer l'environnement de développement Python avec Visual Studio Code, j'ai donc essayé de le porter du langage R vers Python. J'ai fait. Cela dit, c'était la première fois pour moi de travailler sérieusement avec Python, donc j'ai eu du mal.

[PostScript 31/12/2018] Selon Livre blanc Sazae-san Janken édition hiver 2017, le premier (trimestre) cool (janvier, avril, juillet, octobre) ) Il est facile d'obtenir du choki, donc cette fois j'ai essayé de l'intégrer.

Environnement de développement

Installation

pip install beautifulsoup4
pip install pandasql

Grattage Web

C'était la première fois que je faisais du scraping Web avec Python, alors je l'ai recherché et l'ai trouvé sous le nom Télécharger les données Janken de Sazae (et Precure) Le script a été publié sur Git Hub, je l'ai donc utilisé comme référence. Cette fois, Pandas est utilisé pour la sortie dans un fichier CSV.

[PostScript du 01/01/2018] "Les études Janken de Sazae-san" a pris fin le 2017/06/25, donc après 2017/07 Les données ne peuvent pas être obtenues. Merci pour un long moment m (_ _) m Les données qui suivent sont ajoutées manuellement à partir des Résultats du jeu avec Sazae (annuel).

GetSazaeData.py


# -*- coding: utf-8 -*-

#get data from http://www.asahi-net.or.jp/~tk7m-ari/sazae_ichiran.html

'''
Acquisition des données de prévision Janken de Sazae
'''
import urllib.request
import datetime as dt
import bs4 as bs
import pandas as pd

def normalized_year(year):
    '''
Modifier l'année à 2 chiffres en année à 4 chiffres
    '''
    return int(year) + 2000 if year < 91 else int(year) + 1900

def read_data():
    '''
Acquisition de données par web scraping
    '''
    result = []
    response = urllib.request.urlopen('http://www.asahi-net.or.jp/~tk7m-ari/sazae_ichiran.html')
    soup = bs.BeautifulSoup(response, "lxml")

    for i in soup.body.contents[9].contents:
        if i.string and len(i.string.strip()) != 0:
            split = i.strip().split()
            seq = int(split[0][1:-1])
            year, month, day = map(int, split[1].split('.'))
            year = normalized_year(year)
            #the data contain illegal date: 91.11.31 -> 91.12.01
            if year == 1991 and month == 11 and day == 31:
                date = dt.date(year, month + 1, 1)
            else:
                date = dt.date(year, month, day)

            kind, idx = ('-', 9)
            hand = split[2]
            if hand == 'Goo':
                kind, idx = ('G', 1)
            if hand == 'Choki':
                kind, idx = ('C', 2)
            if hand == 'Par':
                kind, idx = ('P', 3)

            result.append((seq, year, date, kind, idx))
    result.reverse()

    return result

def main():
    '''
Principale
    '''
    df_data = pd.DataFrame(read_data(), columns=['seq', 'year', 'date', 'kind', 'idx'])
    df_data.to_csv('SazaeData.csv', index=False)

if __name__ == '__main__':
    main()

Prédiction Janken de Sazae

Algorithme de prédiction de la prochaine main

La sortie "SazaeData.csv" par GetSazaeData.py est lue et les résultats gagnants / perdants pour les 10 années de 2009 à 2018 sont affichés. Je ne semble pas m'habituer à la manipulation de données pandas, donc j'utilise "pandasql" pour manipuler les données en utilisant SQL. De plus, "pysqldf", qui est un fork de pandasql qui vous permet d'utiliser des fonctions définies par l'utilisateur, est également bon.

main.py


# -*- coding: utf-8 -*-
'''
Prédiction Janken de Sazae
'''
import datetime
import pandas as pd
from pandasql import sqldf

def get_guess(fstkind, sndkind, thrkind):
    '''
Prochaine prédiction
    '''

    guess = 'G'

    if fstkind == 'G':
        guess = 'C'
    elif fstkind == 'C':
        guess = 'G'
    elif fstkind == 'P':
        guess = 'G'

    #Quand il y a 2 front
    if sndkind != '':
        if sndkind != fstkind:
            #Combinaison différente: je m'attends à ce que les mains restantes sortent, alors je ferai le reste
            ptn = fstkind + sndkind
            if ptn in('GC', 'CG'):
                guess = 'C' #Faites-le C en attendant P
            elif ptn in('CP', 'PC'):
                guess = 'P' #Faire P avec l'attente de G
            elif ptn in('PG', 'GP'):
                guess = 'G' #Faire G avec l'attente de C
        else:
            #S'ils sont les mêmes, je m'attends à ce qu'ils soient égoïstes, alors je vais perdre
            if fstkind == 'G':
                guess = 'C' #Faites-le C en attendant P
            elif fstkind == 'C':
                guess = 'P' #Faire P avec l'attente de G
            elif fstkind == 'P':
                guess = 'G' #Faire G avec l'attente de C

        #Quand il y a 3 front
        if thrkind != '':
            #Combinaison différente: je m'attends à ce que les mains restantes sortent, alors je ferai le reste
            ptn = fstkind + sndkind
            if ptn in('GC', 'CG'):
                guess = 'C' #Puisque P sort, réglez-le sur C
            ptn = fstkind + sndkind + thrkind
            if ptn in('GCG', 'CGC'):
                guess = 'C' #Faites-le C en attendant P
            elif ptn in('CPC', 'PCP'):
                guess = 'P' #Faire P avec l'attente de G
            elif ptn in('PGP', 'GPG'):
                guess = 'G' #Faire G avec l'attente de C
            elif ptn in('GGC', 'CCG', 'GCC', 'CGG'):
                guess = 'C' #Faites-le C en attendant P
            elif ptn in('CCP', 'PPC', 'PCC', 'CPP'):
                guess = 'P' #Faire P avec l'attente de G
            elif ptn in('PPG', 'GGP', 'GPP', 'PGG'):
                guess = 'G' #Faire G avec l'attente de C

    return guess   #Valeur de retour

def get_fight(kind, guess):
    '''
Création de la fonction victoire / perte
    '''

    ptn = kind + guess
    if ptn in('GP', 'CG', 'PC'):
        result = 'win'
    elif kind == guess:
        result = 'draw'
    else:
        result = 'lose'

    return result   #Valeur de retour

def isFirstWeek(value):
    '''
    1,4,7,Jugement s'il s'agit de la première semaine de 10
    '''
    date = datetime.datetime.strptime(value, '%Y-%m-%d')
    if((date.month - 1) % 3 != 0):
       return False
      
    day = date.day

    weeks = 0
    while day > 0:
        weeks += 1
        day -= 7

    return (weeks == 1) 

def get_fight_result(df_data):
    '''
Gains / pertes avec données historiques par année
    '''
    result = []
    i = 0
    oldyear = 0
    row = len(df_data)
    while i < row:
        if oldyear != df_data.ix[i, 'year']:
            oldyear = df_data.ix[i, 'year']
            thrkind, sndkind, fstkind = ['', '', '']

        seq = df_data.ix[i, 'seq']
        year = df_data.ix[i, 'year']
        date = df_data.ix[i, 'date']
        kind = df_data.ix[i, 'kind']

        #Obtenez le prochain mouvement
        guess = get_guess(fstkind, sndkind, thrkind)
        #1,4,7,Il y a beaucoup de choki dans la première semaine de 10
        if(isFirstWeek(date)):
            guess = 'G'
        fight = get_fight(kind, guess)
        thrkind, sndkind, fstkind = [sndkind, fstkind, kind]

        result.append((seq, year, date, kind, guess, fight))
        i = i + 1

    return pd.DataFrame(result, columns=['seq', 'year', 'date', 'kind', 'guess', 'fight'])

def get_winning_percentage(df_data):
    '''
Calcul du taux de gain annuel
    '''
    result = []
    i = 0
    oldyear = 0
    row = len(df_data)
    while i < row:
        if oldyear != df_data.ix[i, 'year']:
            oldyear = df_data.ix[i, 'year']
            year = oldyear
            draw = df_data.ix[i, 'cnt']
            lose = df_data.ix[i+1, 'cnt']
            win = df_data.ix[i+2, 'cnt']
            rate = round(win / (win + lose), 3)
            result.append((year, win, lose, draw, rate))

        i = i + 1

    return pd.DataFrame(result, columns=['year', 'win', 'lose', 'draw', 'rate'])

def main():
    '''
Principale
    '''
    #Lire les données Janken de Sazae
    ytbl = pd.read_csv('SazaeData.csv')

    #Gain / perte avec les données passées pendant 10 ans
    pd.set_option("display.max_rows", 100)
    query = "SELECT seq, year, date, kind, idx FROM ytbl WHERE idx<>9 AND year BETWEEN 2009 AND 2018;"
    ytblptn = sqldf(query, locals())
    fighttbl = get_fight_result(ytblptn)
    print(fighttbl)

    #Calcul du taux de gain annuel pendant 10 ans
    query = "SELECT year,fight,COUNT(fight) AS cnt FROM fighttbl GROUP BY year,fight ORDER BY year;"
    fightcnt = sqldf(query, locals())
    ratetbl = get_winning_percentage(fightcnt)
    print(ratetbl)

if __name__ == '__main__':
    main()

Résultat de sortie

Parce que c'est long, la prédiction de la main de Sazae 2018 et le résultat de la victoire / défaite

seq year date kind guess fight
443 1364 2018 2018-01-07 C G win
444 1365 2018 2018-01-14 G G draw
445 1366 2018 2018-01-21 C C draw
446 1367 2018 2018-01-28 G C lose
447 1368 2018 2018-02-04 P C win
448 1369 2018 2018-02-11 G G draw
449 1370 2018 2018-02-18 C G win
450 1371 2018 2018-02-25 C C draw
451 1372 2018 2018-03-04 P C win
452 1373 2018 2018-03-11 G P win
453 1374 2018 2018-03-18 G G draw
454 1375 2018 2018-03-25 C G win
455 1376 2018 2018-04-01 C G win
456 1377 2018 2018-04-08 G C lose
457 1378 2018 2018-04-15 P C win
458 1379 2018 2018-04-22 P G lose
459 1380 2018 2018-04-29 C G win
460 1381 2018 2018-05-06 G P win
461 1382 2018 2018-05-13 C C draw
462 1383 2018 2018-05-20 P C win
463 1384 2018 2018-05-27 G P win
464 1385 2018 2018-06-03 C G win
465 1386 2018 2018-06-10 G C lose
466 1387 2018 2018-06-17 P C win
467 1388 2018 2018-06-24 P G lose
468 1389 2018 2018-07-01 C G win
469 1390 2018 2018-07-08 G P win
470 1391 2018 2018-07-15 P C win
471 1392 2018 2018-07-22 G G draw
472 1393 2018 2018-07-29 C G win
473 1394 2018 2018-08-05 C C draw
474 1395 2018 2018-08-12 P C win
475 1396 2018 2018-08-19 G P win
476 1397 2018 2018-08-26 G G draw
477 1398 2018 2018-09-02 P G lose
478 1399 2018 2018-09-09 C G win
479 1400 2018 2018-09-16 G P win
480 1401 2018 2018-09-23 C C draw
481 1402 2018 2018-09-30 P C win
482 1403 2018 2018-10-07 C G win
483 1404 2018 2018-10-14 G P win
484 1405 2018 2018-10-21 P C win
485 1406 2018 2018-11-04 P G lose
486 1407 2018 2018-11-11 C G win
487 1408 2018 2018-11-18 C P lose
488 1409 2018 2018-11-25 G P win
489 1410 2018 2018-12-02 G C lose
490 1411 2018 2018-12-09 P C win
491 1412 2018 2018-12-16 C G win

Résultats victoires / défaites pour 2009-2018

year win lose draw rate
0 2009 32 5 12 0.865
1 2010 27 6 14 0.818
2 2011 30 8 12 0.789
3 2012 27 12 10 0.692
4 2013 26 11 12 0.703
5 2014 32 8 11 0.800
6 2015 34 8 8 0.810
7 2016 26 12 12 0.684
8 2017 34 8 6 0.810
9 2018 30 9 10 0.769

finalement

Les trames de données en langage R pourraient également être facilement portées à l'aide des pandas de Python. sqldf pourrait également être remplacé par pandasql. Si quoi que ce soit, il était plus difficile de réduire les erreurs d'avertissement dans Pylint par Visual Studio Code. Même si je cherchais à partir du contenu de l'erreur, je ne pouvais pas accéder au site écrit en japonais, donc je l'ai corrigé tout en comprenant le texte anglais. Vous devez comprendre les conventions de dénomination de Python.

référence

Recommended Posts

Porté du langage R de "Sazae-san's Janken Data Analysis" vers Python
[Python] Flux du scraping Web à l'analyse des données
[Python] De l'analyse morphologique des données CSV à la sortie CSV et à l'affichage graphique [GiNZA]
Météorologie x Python ~ De l'acquisition de données météorologiques à l'analyse spectrale ~
Python pour passer d'une autre langue
Livres et sources recommandés de programmation d'analyse de données (Python ou R)
Comment éviter la duplication des données lors de la saisie de Python vers SQLite.
Introduction à l'analyse de données par Python P17-P26 [ch02 1.usa.gov données de bit.ly]
De l'introduction de JUMAN ++ à l'analyse morphologique du japonais avec Python
[Introduction au Data Scientist] Bases de Python ♬
Comparaison de R, Python, SAS, SPSS du point de vue des data scientists européens
Transférer des données en virgule flottante de Python vers JavaScript sans perte de chiffres
Analyse de données python
Porté un compilateur de langage homebrew naïf sur Python
[Python] Comment lire les données de CIFAR-10 et CIFAR-100
Environnement enregistré pour l'analyse des données avec Python
Analyse des données en Python Résumé des sources que les débutants devraient d'abord consulter
Organiser les outils Python pour accélérer le mouvement initial des compétitions d'analyse de données
Analyse de données avec python 2
Le mur lors du passage du service Django de Python 2.7 à la série Python 3
Résumé des outils nécessaires pour analyser les données en Python
Exemple d'application de Python à l'ingénierie: recherche de paramètres de formule de calcul approximative à partir de données réelles
[Python] [Word] [python-docx] Analyse simple des données de diff en utilisant python
[Pour les débutants] Comment étudier le test d'analyse de données Python3
Comment récupérer des données d'image de Flickr avec Python
Changements de Python 3.0 à Python 3.5
Changements de Python 2 à Python 3.0
Présentation de l'analyse de données python
[Mis à jour de temps en temps] Mémos Python souvent utilisés pour l'analyse des données [Division N, etc.]
[Chapitre 5] Introduction à Python avec 100 coups de traitement du langage
Note de lecture: Introduction à l'analyse de données avec Python
Introduction au langage Python
Comment utiliser Python Kivy ① ~ Bases du langage Kv ~
Défiez l'analyse des composants principaux des données textuelles avec Python
Envoyer des données de Python au traitement via une communication socket
[Impression] [Analyse de données à partir de zéro] Introduction à la science des données Python apprise dans des analyses de rentabilisation
Liste du code Python utilisé dans l'analyse de Big Data
[Chapitre 3] Introduction à Python avec 100 coups de traitement du langage
DataNitro, implémentation de la fonction de lecture des données de feuille
Modèle d'analyse de données Python
[Chapitre 2] Introduction à Python avec 100 coups de traitement du langage
Comprendre l'état de la perte de données - Python vs R
[Bases de la science des données] Collecte de données depuis RSS avec python
Analyse de données avec Python
[Livre technique] Introduction à l'analyse de données avec Python -1 Chapitre Introduction-
[Chapitre 4] Introduction à Python avec 100 coups de traitement du langage
Comment représenter la distribution de la composition bactérienne à partir des données d'analyse Qiime2 dans un diagramme de moustaches
Appeler des fonctions du langage C depuis Python pour échanger des tableaux multidimensionnels
SIGNATURE Quête ② De la création du modèle de ciblage à la création des données soumises
Traitement du langage 100 knocks-48: Extraction du chemin du nez à la racine
Je veux démarrer beaucoup de processus à partir de python
20200329_Introduction à l'analyse de données avec Python 2nd Edition Personal Summary
Lequel dois-je étudier, R ou Python, pour l'analyse des données?
[Python] Extrayez des données texte à partir de données XML de 10 Go ou plus.
L'histoire de la copie de données de S3 vers TeamDrive de Google
[Introduction to Data Scientists] Bases de Python ♬ Fonctions et classes
Appuyez sur REST en Python pour obtenir des données de New Relic
Comparaison de la gestion des trames de données en Python (pandas), R, Pig
Aller au langage pour voir et se souvenir de la partie 8 Appeler le langage GO à partir de Python