Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Algoritmo 2020 #74

Open
ronecharles opened this issue Sep 5, 2020 · 2 comments
Open

Algoritmo 2020 #74

ronecharles opened this issue Sep 5, 2020 · 2 comments

Comments

@ronecharles
Copy link

Ótimo trabalho, show esse algoritmo.

Ao rodar a rodada 1 a 7 2020, tentando o solver para rodada 8
a array de dados está retornando números infinitos, gerando o erro NAN no python.

O mesmo código usado em 2019 funciona perfeitamente.

Tentei substituir os NAN por 0,dai ele roda... mas ele não encontra resposta para o problema, ou seja a sugestão de escalaçao.

@arnaldog12
Copy link
Collaborator

Oi, @ronecharles
você pode dar mais detalhes de qual algoritmo/notebook você está tentando rodar?

@ronecharles
Copy link
Author

ronecharles commented Sep 8, 2020

Bom dia. @arnaldog12

/////////////////////////////////////////////

import pandas as pd

ano = '2020'
url = 'https://raw.githubusercontent.com/henriquepgomide/caRtola/master/data/'+ano+'/'+ano+'-medias-jogadores.csv'
medias = pd.read_csv(url)
medias.head()
medias.shape
medias.columns

qtd_atletas = len(medias['player_id'].unique())
print(qtd_atletas)

posicoes = medias['player_position'].unique()

medias['Rank'] = None
for posicao in posicoes:
rank = medias[medias['player_position'] == posicao].player_id.rank(method='min')
rank = rank - 1
medias.iloc[rank.index,-1] = rank

colunas_unicos = ['Rank','player_id','player_position']
atletas = medias[colunas_unicos].drop_duplicates()

atletas.head()
atletas.shape

partidas = pd.read_csv(r'https://raw.githubusercontent.com/henriquepgomide/caRtola/master/data/'+ano+'/'+ano+'_partidas.csv')
partidas['home_score_norm'] = partidas['home_score'] / max(partidas['home_score'])
partidas['away_score_norm'] = partidas['away_score'] / max(partidas['away_score'])
partidas.head()
partidas.shape

rodada_atual = 7
df_partidas = pd.DataFrame()
for rodada in range(1,rodada_atual):
df_rodada = pd.read_csv(f'https://raw.githubusercontent.com/henriquepgomide/caRtola/master/data/2020/rodada-{rodada}.csv')
df_rodada['round'] = rodada
df_partidas =df_partidas.append(df_rodada,sort=False)

df_partidas.shape
df_partidas = df_partidas[df_partidas['atletas.posicao_id'] != 'tec']
df_partidas = df_partidas.set_index('atletas.atleta_id').join(atletas.set_index('player_id'))

df_partidas.head()
df_partidas['Rank']
df_partidas.drop(df_partidas[df_partidas['Rank'].isnull()].index, inplace=True)
df_partidas['Rank'] = df_partidas['Rank'].astype(int)

import numpy as np

posicao = 'ata'
qtd_atletas = len(atletas[atletas.player_position == posicao])
M = np.zeros((qtd_atletas,qtd_atletas))

M

M.shape

df_partidas_posicao = df_partidas[df_partidas['atletas.posicao_id'] == posicao].copy()

for partida in range(len(partidas)-1): #Vamos deixar a última partida de fora para testes
df_rodada = df_partidas_posicao[df_partidas_posicao['round'] == partidas['round'][partida]]
jogadores_casa = df_rodada[df_rodada['atletas.clube_id'] == partidas['home_team'][partida]]
jogadores_visitantes = df_rodada[df_rodada['atletas.clube_id'] == partidas['away_team'][partida]]

for j_casa in range(len(jogadores_casa)):
    for j_visitante in range(len(jogadores_visitantes)):
        score_casa = 0
        score_visitante = 0
        
        pontos_j_casa = jogadores_casa['atletas.pontos_num'].iloc[j_casa]
        pontos_j_visitante = jogadores_visitantes['atletas.pontos_num'].iloc[j_visitante]
        
        soma =  pontos_j_casa + pontos_j_visitante 
        if soma != 0:
            score_casa = pontos_j_casa / soma
            score_visitante = pontos_j_visitante / soma
        
        j1 = jogadores_casa['Rank'].iloc[j_casa]
        j2 = jogadores_visitantes['Rank'].iloc[j_visitante]
            
        M[j1,j1] = M[j1,j1] + partidas['home_score_norm'][partida] + score_casa
        M[j1,j2] = M[j1,j2] + partidas['away_score_norm'][partida] + score_visitante
        M[j2,j1] = M[j2,j1] + partidas['home_score_norm'][partida] + score_casa
        M[j2,j2] = M[j2,j2] + partidas['away_score_norm'][partida] + score_visitante

M

M = np.nan_to_num(M)
M = M / np.sum(M,axis=1)

evals, evecs = np.linalg.eig(M.T)
evec1 = evecs[:,np.isclose(evals, 1)]

evec1 = evec1[:,0]
stationary = evec1 / evec1.sum()
stationary = stationary.real

stationary

medias[medias.player_position == posicao][list(stationary > 0.015)]

stationaries = {}

for posicao in posicoes:
qtd_atletas = len(atletas[atletas.player_position == posicao])
M = np.zeros((qtd_atletas,qtd_atletas))

df_partidas_posicao = df_partidas[df_partidas['atletas.posicao_id'] == posicao].copy()

for partida in range(len(partidas)-1): #Vamos deixar a última partida de fora para testes
    df_rodada = df_partidas_posicao[df_partidas_posicao['round'] == partidas['round'][partida]]
    jogadores_casa = df_rodada[df_rodada['atletas.clube_id'] == partidas['home_team'][partida]]
    jogadores_visitantes = df_rodada[df_rodada['atletas.clube_id'] == partidas['away_team'][partida]]

    for j_casa in range(len(jogadores_casa)):
        for j_visitante in range(len(jogadores_visitantes)):
            score_casa = 0
            score_visitante = 0

            pontos_j_casa = jogadores_casa['atletas.pontos_num'].iloc[j_casa]
            pontos_j_visitante = jogadores_visitantes['atletas.pontos_num'].iloc[j_visitante]

            soma =  pontos_j_casa + pontos_j_visitante 
            if soma != 0:
                score_casa = pontos_j_casa / soma
                score_visitante = pontos_j_visitante / soma

            def_n_vazada_casa = 0 if partidas['away_score_norm'][partida] > 0 else 1
            def_n_vazada_visitante = 0 if partidas['home_score_norm'][partida] > 0 else 1
            
            if posicao == 'ata':
                pontos_casa = partidas['home_score_norm'][partida] + score_casa
                pontos_visitante = partidas['away_score_norm'][partida] + score_visitante
            elif posicao == 'mei':
                pontos_casa = partidas['home_score_norm'][partida] + def_n_vazada_casa + score_casa
                pontos_visitante = partidas['away_score_norm'][partida] + def_n_vazada_visitante + score_visitante
            else:
                pontos_casa = def_n_vazada_casa + score_casa
                pontos_visitante = def_n_vazada_visitante + score_visitante                  
                
            j1 = jogadores_casa['Rank'].iloc[j_casa]
            j2 = jogadores_visitantes['Rank'].iloc[j_visitante]               

            M[j1,j1] = M[j1,j1] + pontos_casa
            M[j1,j2] = M[j1,j2] + pontos_visitante
            M[j2,j1] = M[j2,j1] + pontos_casa
            M[j2,j2] = M[j2,j2] + pontos_visitante

M = np.nan_to_num(M)
M = M / np.sum(M,axis=1)

evals, evecs = np.linalg.eig(M.T)
evec1 = evecs[:,np.isclose(evals, 1)]

evec1 = evec1[:,0]
stationary = evec1 / evec1.sum()
stationary = stationary.real

stationaries[posicao] = stationary

rodada = 38

df_rodada = df_partidas[df_partidas['round'] == rodada].copy()
df_rodada['Rank'] = df_rodada['Rank'].astype(int)
df_rodada['probs'] = 0

for jogador in range(len(df_rodada)):
posicao = df_rodada.iloc[jogador]['player_position']
rank = df_rodada.iloc[jogador]['Rank']
if rank:
df_rodada.iloc[jogador,-1] = stationaries[posicao][rank]

df_rodada = df_rodada[df_rodada['atletas.status_id'] == 'Provável'].copy()

df_rodada.head()

formacao = {
'ata': 3,
'mei': 3,
'lat': 2,
'zag': 2,
'gol':1
}

cartoletas = 140

df_rodada.set_index('atletas.slug',inplace=True)
z = df_rodada['probs'].to_dict()
c = df_rodada['atletas.preco_num'].to_dict()

dummies_posicao = pd.get_dummies(df_rodada['atletas.posicao_id'])
dummies_posicao = dummies_posicao.to_dict()

from pulp import LpMaximize, LpProblem, lpSum, LpVariable

prob = LpProblem("Melhor_Escalacao", LpMaximize)
y = LpVariable.dicts("Atl",df_rodada.index,0,1,cat='Binary')
prob += lpSum([z[i] * y[i] for i in y])

prob += lpSum([c[i] * y[i] for i in y]) <= cartoletas, "Limite de Cartoletas"
prob += lpSum([dummies_posicao['ata'][i] * y[i] for i in y]) == formacao['ata'], "Quantidade Atacantes"
prob += lpSum([dummies_posicao['lat'][i] * y[i] for i in y]) == formacao['lat'], "Quantidade Laterais"
prob += lpSum([dummies_posicao['mei'][i] * y[i] for i in y]) == formacao['mei'], "Quantidade Meio"
prob += lpSum([dummies_posicao['zag'][i] * y[i] for i in y]) == formacao['zag'], "Quantidade Zagueiros"
prob += lpSum([dummies_posicao['gol'][i] * y[i] for i in y]) == formacao['gol'], "Quantidade Goleiro"

prob.solve()

escalados = []
for v in prob.variables():
if v.varValue == 1:
atleta = v.name.replace('Atl_','').replace('_','-')
escalados.append(atleta)
print(atleta, "=", v.varValue)

colunas = ['atletas.posicao_id','atletas.clube.id.full.name','atletas.pontos_num','atletas.preco_num']
df_rodada.loc[escalados][colunas]

df_rodada.loc[escalados]['atletas.pontos_num'].sum()

df_rodada.loc[escalados]['atletas.preco_num'].sum()

jogar_em_casa = 5

times = {
'Internacional':3,
'Fortaleza':2
}

times_casa = partidas[partidas['round'] == rodada]['home_team']
df_rodada.loc[df_rodada['atletas.clube_id'].isin(times_casa),'probs'] = df_rodada.loc[
df_rodada['atletas.clube_id'].isin(times_casa),'probs'] * (jogar_em_casa / 10 + 1)

for time in times:
df_rodada.loc[df_rodada['atletas.clube.id.full.name'] == time,'probs'] = df_rodada.loc[
df_rodada['atletas.clube.id.full.name'] == time,'probs'] * (times[time] / 10 + 1)

z = df_rodada['probs'].to_dict()

prob = LpProblem("Melhor_Escalacao", LpMaximize)
y = LpVariable.dicts("Atl",df_rodada.index,0,1,cat='Binary')
prob += lpSum([z[i] * y[i] for i in y])

prob += lpSum([c[i] * y[i] for i in y]) <= cartoletas, "Limite de Cartoletas"
prob += lpSum([dummies_posicao['ata'][i] * y[i] for i in y]) == formacao['ata'], "Quantidade Atacantes"
prob += lpSum([dummies_posicao['lat'][i] * y[i] for i in y]) == formacao['lat'], "Quantidade Laterais"
prob += lpSum([dummies_posicao['mei'][i] * y[i] for i in y]) == formacao['mei'], "Quantidade Meio"
prob += lpSum([dummies_posicao['zag'][i] * y[i] for i in y]) == formacao['zag'], "Quantidade Zagueiros"
prob += lpSum([dummies_posicao['gol'][i] * y[i] for i in y]) == formacao['gol'], "Quantidade Goleiro"

prob.solve()

escalados = []
for v in prob.variables():
if v.varValue == 1:
atleta = v.name.replace('Atl_','').replace('_','-')
escalados.append(atleta)
print(atleta, "=", v.varValue)

colunas = ['atletas.posicao_id','atletas.clube.id.full.name','atletas.pontos_num','atletas.preco_num']
df_rodada.loc[escalados][colunas]

df_rodada.loc[escalados]['atletas.pontos_num'].sum()

df_rodada.loc[escalados]['atletas.preco_num'].sum()

/////////////////////////////////////////////

Estou rodando o algoritmo base do repositório, adequado para os dados de 2020 e rodada 8

Uso Python 3, no Windows. Este mesmo algoritmo base 2019, rodada 38, faz a escalação perfeitamente, como no exemplo.

Parece que ao trazer os dados 2020 algo muda...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants