Open ronecharles opened 4 years ago
Oi, @ronecharles você pode dar mais detalhes de qual algoritmo/notebook você está tentando rodar?
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...
Ó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.