Disclaimer: Todos os cenários, descrições, e situações deste projeto são fictícios e não representam qualquer relação com alguma empresa real. Portanto, os processos, resultados, recomendações, ou qualquer outra informação presente neste projeto possuem a única intenção de descrever minhas habilidades em ciência de dados. Os dados utilizados neste projeto foram coletados de um domínio público do website Kaggle. Esta base de dados está em domínio público e sua utilização respeita todos os termo e condições do website.

0.0 INTRODUÇÃO

0.1 Contexto do projeto

A empresa

GoalForce Analytics é uma empresa que avalia jovens jogadores de futebol, visando detectar indicadores que demonstrem potencial de sucesso dos mesmos.

0.2 Problema de negócio

O CEO da GoalForce Analytics requisitou a equipe de cientistas de dados uma solução do tipo insights que orientasse qual posição de atuação no clube o jogador deveria investir, visando retorno financeiro para um jovem jogador de futebol.

0.3 Planejamento da Solução

Para entregar o produto final, solicitado pelo CEO da empresa, existem algum passos que o cientista de dados deve percorrer, que incluem:

  • Estabelecimento do problema a ser resolvido;
  • Entendimento do negócio e mapeamento das premissas;
  • Coleta, processamento, e analise dos dados;
  • Implementação de análise detalhada, e avaliação dos resultados;
  • Apresentar um relatório simples e eficiente, onde os stakeholders poderão tomas suas decisões baseado em dados.

Ferramentas utilizadas

A justificativa para utilização da linguagem R se deu pelo planejamento para os próximos ciclos deste projeto. Para o primeiro ciclo, a abordagem do projeto será do tipo insights. Para o ciclo 2 em diante, será feita uma abordagem de rergessão, utilizando modelagem linear mista. A linguagem R já possui ferramentas desenvolvidas para realizar tais técnicas. Além disso, devido ao planejamento dos ciclos, optei por já iniciar o projeto no R, uma vez que o mesmo também possui boas ferramentas de manipulação e visualização de dados.

  • Linguagem de programação R
  • Bibliotecas de manipulação e visualização de dados

1.0 PREMISSAS

Após estudo detalhado do pedido do CEO, algumas premissas devem ser levadas em consideração. Abaixo encontra - se as premissas consideradas para este projeto:

Mindmap
Mindmap

1.1 Desenvolvimento da solução

1.2. Coleta de dados

Os dados para esse projeto foram coletados no site Kaggle. As informações de jogadores de futebol profissionais de oito temporadas estão cadastrados no jogo FIFA do estúdio EA Sports. Os dados utilizados se referem a um histórico dos jogadores no período, e apresentam características da aptidão física e abordagem técnico-tática dos mesmos. Embora se tratem de dados sintéticos, os atributos podem ser coletados em jogares no mundo real e os métodos de ciência de dados aqui implementados, podem ser aplicados no mundo real. Os dados podem ser baixados aqui.

A página do Kaggle disponibiliza os dados em links individuais, e os arquivos estão em formato .csv, formatados como tabelas e disponíveis para download. O autor dos conjuntos de dados afirma que os dados são oriundos de procedimento de webscraping, o que sugere que possíveis vieses seriam oriundos dos códigos utilizados na coleta de dados.

Os dados utilizados respeitam os termos de utilização do Kaggle. Os dados foram armazenados em maquina local e protegidos por senha. Após download, eu realizei rápida inspeção visual, procurando por problemas visíveis, para preparar os dados para processamento e análise. Este cuidado inicial dom os dados visa ampliar a qualidade das análises e interpretação dos resultados.

1.2.1. Bibliotecas

Para carregar os dados no ambiente de trabalho bem como desenvolver todos os procedimentos do projeto, será necessário carregar algumas bibliotecas que não são nativas no R.

library( readxl )
library( dplyr )
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library( ggplot2 )
library( reshape2 )
library( psych )
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library( knitr )
library( pander )
library( kableExtra )
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
library( stringr )

1.2.2. Carregando os dados

Os dados deste projeto foram disponibilizados em arquivos separados (possivelmente, devido ao tamanho de cada arquivo. Também, arquivos separados facilitam a análise de diferentes temporadas sem a necessidade de linhas de código adicionais).

Para carregar os dados, primeiro eu listei todos os arquivos .csv no ambiente de trabalho:

csv_files <- list.files( pattern = "*.csv" )

Então, carreguei e nomeei cada arquivo de acordo com a temporada que o mesmo representa:

data_list <- list()

for ( file in csv_files ){
  #extract the file name without the extension
  file_name <- gsub( "\\.csv", "", file, ignore.case=TRUE )
  
  # Load csv into data frame
  df <- read.csv( file, header=TRUE )
  
  #  assign the data frame to an object with the same name
  assign( file_name, df )
  
  #add the data frame to the list
  data_list[[file_name]] <- df
}

Em seguida, criei uma lista com todos os data frames do ambiente, realizei pequena correção nos tipos de dados nas variáveis “lw” e “rw” para poder concatenar todos os data frames em um único arquivo. o último bloco de códigos na célula abaixo removou aqueles arquivos que não serão mais utilizados, visando liberar recursos do computador local:

# get a list of all data frames in the environment
df_list <- Filter( is.data.frame,mget( ls() ) )

# fix data types for concatenation
fifa_17$lw <- as.character( fifa_17$lw )
fifa_18$lw <- as.character( fifa_18$lw )
fifa_21$lw <- as.character( fifa_21$lw )
fifa_22$lw <- as.character( fifa_22$lw )

fifa_17$rw <- as.character( fifa_17$rw )
fifa_21$rw <- as.character( fifa_21$rw )
fifa_22$rw <- as.character( fifa_22$rw )

# concatenate all data frames into single data frame
fifa_15to20 <- bind_rows( fifa_15,fifa_16,fifa_17,fifa_18,fifa_19,fifa_20 )
fifa_rest <- bind_rows( fifa_15to20,fifa_21 )

fifas <- bind_rows( fifa_rest,fifa_22 )

# remove unused data
rm( fifa_15,fifa_16,fifa_17,fifa_18,fifa_19,fifa_20,fifa_21,fifa_22,fifa_15to20,fifa_rest, fifa_rkd, data_list, df, df_list, file, file_name, csv_files )

1.2.2.1 Análise descritiva

Neste passo, serão feitas descrição dos atributos do conjunto de dados, verificação da dimensão do data frame com as oito temporadas, verificados os tipos de variáveis, se existem dados faltantes, e realizar uma análise estatística descritiva.

Tabela 1. Descrição dos atributos do data frame original.

var_name description
sofifa_id unique player ID on sofifa
player_url URL of the scraped player
short_name player short name
long_name player long name
player_positions player preferred positions
overall player current overall attribute
potential player potential overall attribute
value_eur player value (in EUR)
wage_eur player weekly wage (in EUR)
age player age
dob player date of birth
height_cm player height (in cm)
weight_kg player weight (in kg)
club_team_id club team_id on sofifa where the player plays
club_name club name where the player plays
league_name league name of the club
league_level league rank of the club (e.g. English Premier League is 1, English League Championship is 2, etc.)
club_position player position in the club (e.g. SUB means substitute, RES means reserve)
club_jersey_number player jersey number in the club
club_loaned_from club loaning out the player - if applicable
club_joined date when the player joined his current club
club_contract_valid_until player contract expiration date
nationality_id player nationality id on sofifa
nationality_name player nationality name
nation_team_id national team_id on sofifa where the player plays
nation_position player position in the national team
nation_jersey_number player jersey number in the national team
preferred_foot player preferred foot
weak_foot player weak foot attribute
skill_moves player skill moves attribute
international_reputation player international reputation attribute
work_rate player work rate attributes (attacking / defensive)
body_type player body type
real_face player real face
release_clause_eur player release clause (in EUR) - if applicable
player_tags player tags
player_traits player traits
pace player pace attribute
shooting player shooting attribute
passing player passing attribute
dribbling player dribbling attribute
defending player defending attribute
physic player physic attribute
attacking_crossing player crossing attribute
attacking_finishing player finishing attribute
attacking_heading_accuracy player heading accuracy attribute
attacking_short_passing player short passing attribute
attacking_volleys player volleys attribute
skill_dribbling player dribbling attribute
skill_curve player curve attribute
skill_fk_accuracy player free-kick accuracy attribute
skill_long_passing player long passing attribute
skill_ball_control player ball control attribute
movement_acceleration player acceleration attribute
movement_sprint_speed player sprint speed attribute
movement_agility player agility attribute
movement_reactions player reactions attribute
movement_balance player balance attribute
power_shot_power player shot power attribute
power_jumping player jumping attribute
power_stamina player stamina attribute
power_strength player strength attribute
power_long_shots player long shots attribute
mentality_aggression player aggression attribute
mentality_interceptions player interceptions attribute
mentality_positioning player positioning attribute
mentality_vision player vision attribute
mentality_penalties player penalties attribute
mentality_composure player composure attribute
defending_marking_awareness player marking awareness attribute
defending_standing_tackle player standing tackle attribute
defending_sliding_tackle player sliding tackle attribute
goalkeeping_diving player GK diving attribute
goalkeeping_handling player GK handling attribute
goalkeeping_kicking player GK kicking attribute
goalkeeping_positioning player GK positioning attribute
goalkeeping_reflexes player GK reflexes attribute
goalkeeping_speed player GK speed attribute
ls player attribute playing as LS – left striker
st player attribute playing as ST – striker, or centre forward
rs player attribute playing as RS – right striker
lw player attribute playing as LW – left winger
lf player attribute playing as LF – left forward
cf player attribute playing as CF – centre forward or central forward
rf player attribute playing as RF – right forward
rw player attribute playing as RW – right winger winger
lam player attribute playing as LAM – left attacking midfielder
cam player attribute playing as CAM – central attacking midfielder
ram player attribute playing as RAM – right attacking midfielder
lm player attribute playing as LM – left midfielder
lcm player attribute playing as LCM – left central midfielder
cm player attribute playing as CM – central midfielder
rcm player attribute playing as RCM – right central midfielder
rm player attribute playing as RM – right midfielder
lwb player attribute playing as LWB – left wing back
ldm player attribute playing as LDM - left defensive midfielder
cdm player attribute playing as CDM – central defensive midfielder
rdm player attribute playing as RDM – right defensive midfielder
rwb player attribute playing as RWB – right wing back
lb player attribute playing as LB – left back
lcb player attribute playing as LCB – left central back
cb player attribute playing as CB – central back
rcb player attribute playing as RCB – right central back
rb player attribute playing as RB – right back
gk player attribute playing as GK – goalkeeper
player_face_url URL of the player face
club_logo_url URL of the club logo
club_flag_url URL of the club nationality flag
nation_logo_url URL of the national team logo
nation_flag_url URL of the national flag

**Um ponto bastante interessante e importante deste projeto experimental é que os dados sintéticos aqui apresentados podem ser coletados no mundo real. Basta verificar alguns dos atributos que serão utilizados com maiores detalhes. Veja as descrições aqui.

Para este projeto, apenas alguns atributos serão utilizados para a elaboração do produto de dados final. Portanto, as variáveis abaixo serão removidas do conjunto de dados visando melhorar a clareza, bem como, a o desempenho geral do computador utilizado.

fifas <- subset(fifas, select = -c( sofifa_id                 , player_url           ,   
                                    club_team_id              , club_name            ,   
                                    league_name               , league_level         ,   
                                    club_loaned_from          , club_joined          ,   
                                    club_contract_valid_until , nationality_id       ,   
                                    nationality_name          , nation_team_id       ,   
                                    nation_position           , nation_jersey_number ,   
                                    real_face                 , release_clause_eur   ,   
                                    player_tags               , player_traits        ,   
                                    player_face_url           , club_logo_url        ,   
                                    club_flag_url             , nation_logo_url      ,   
                                    nation_flag_url           , international_reputation,
                                    mentality_aggression      , mentality_interceptions,
                                    mentality_positioning     , mentality_vision,
                                    mentality_penalties       , mentality_composure,
                                    goalkeeping_speed         , club_jersey_number,
                                    work_rate                 , body_type,
                                    ls                        , st,
                                    rs                        , lw,
                                    lf                        , cf,
                                    rf                        , rw,
                                    lam                       , cam,
                                    ram                       , lm, 
                                    lcm                       , cm,
                                    rcm                       , rm,
                                    lwb                       , ldm,
                                    cdm                       , rdm,
                                    rwb                       , lb,
                                    lcb                       , cb,
                                    rcb                       , rb,
                                    gk
                                    ))

1.2.3. Dimensão dos dados

Aqui, verifiquei a dimensão do data frame após concatenar todas as temporadas.

## A base de dados contém: 142079  linhas e  50 colunas.

1.2.4. Limpeza dos dados

A limpeza de dados compreende algumas etapas abrangentes para garantir a qualidade dos dados quando chegarmos à fase de modelagem. Estes são descritos abaixo:

1.2.4.1. Tipos de dados

# Create a data frame with column index, name, and data type
column_info <- data.frame(
  Column_Index = 1:length(names(fifas)),
  Data_Type = sapply(fifas, typeof),
  stringsAsFactors = FALSE
)

# Print the table using kableExtra for styling
kable(column_info, align = "c") %>%
  kable_styling(full_width = FALSE, bootstrap_options = "striped", font_size = 14) %>%
  add_header_above(c(" " = 1, "Column Index" = 1, "Data Type" = 1), bold = TRUE) %>%
  row_spec(0, background = "white",color = "black") %>% 
  column_spec(1:3, color = "black")
Column Index
Data Type
Column_Index Data_Type
short_name 1 character
long_name 2 character
player_positions 3 character
overall 4 integer
potential 5 integer
value_eur 6 integer
wage_eur 7 integer
age 8 integer
dob 9 character
height_cm 10 integer
weight_kg 11 integer
club_position 12 character
preferred_foot 13 character
weak_foot 14 integer
skill_moves 15 integer
pace 16 integer
shooting 17 integer
passing 18 integer
dribbling 19 integer
defending 20 integer
physic 21 integer
attacking_crossing 22 integer
attacking_finishing 23 integer
attacking_heading_accuracy 24 integer
attacking_short_passing 25 integer
attacking_volleys 26 integer
skill_dribbling 27 integer
skill_curve 28 integer
skill_fk_accuracy 29 integer
skill_long_passing 30 integer
skill_ball_control 31 integer
movement_acceleration 32 integer
movement_sprint_speed 33 integer
movement_agility 34 integer
movement_reactions 35 integer
movement_balance 36 integer
power_shot_power 37 integer
power_jumping 38 integer
power_stamina 39 integer
power_strength 40 integer
power_long_shots 41 integer
defending_marking_awareness 42 integer
defending_standing_tackle 43 integer
defending_sliding_tackle 44 integer
goalkeeping_diving 45 integer
goalkeeping_handling 46 integer
goalkeeping_kicking 47 integer
goalkeeping_positioning 48 integer
goalkeeping_reflexes 49 integer
year 50 integer

1.2.4.2. Checagem de dados faltantes (NA’s)

# Remove rows from club_position empty cells
fifass <- subset(fifas, club_position != "")
fifas <- fifass
rm(fifass)

na_count <- sapply(fifas, function(x) sum(is.na(x)))

# Create a list with variable name - value format
na_count_list <- paste(names(na_count), na_count, sep = ": ")

# Print the list
print(na_count_list)
##  [1] "short_name: 0"                  "long_name: 0"                  
##  [3] "player_positions: 0"            "overall: 0"                    
##  [5] "potential: 0"                   "value_eur: 275"                
##  [7] "wage_eur: 0"                    "age: 0"                        
##  [9] "dob: 0"                         "height_cm: 0"                  
## [11] "weight_kg: 0"                   "club_position: 0"              
## [13] "preferred_foot: 0"              "weak_foot: 0"                  
## [15] "skill_moves: 0"                 "pace: 15543"                   
## [17] "shooting: 15543"                "passing: 15543"                
## [19] "dribbling: 15543"               "defending: 15543"              
## [21] "physic: 15543"                  "attacking_crossing: 0"         
## [23] "attacking_finishing: 0"         "attacking_heading_accuracy: 0" 
## [25] "attacking_short_passing: 0"     "attacking_volleys: 0"          
## [27] "skill_dribbling: 0"             "skill_curve: 0"                
## [29] "skill_fk_accuracy: 0"           "skill_long_passing: 0"         
## [31] "skill_ball_control: 0"          "movement_acceleration: 0"      
## [33] "movement_sprint_speed: 0"       "movement_agility: 0"           
## [35] "movement_reactions: 0"          "movement_balance: 0"           
## [37] "power_shot_power: 0"            "power_jumping: 0"              
## [39] "power_stamina: 0"               "power_strength: 0"             
## [41] "power_long_shots: 0"            "defending_marking_awareness: 0"
## [43] "defending_standing_tackle: 0"   "defending_sliding_tackle: 0"   
## [45] "goalkeeping_diving: 0"          "goalkeeping_handling: 0"       
## [47] "goalkeeping_kicking: 0"         "goalkeeping_positioning: 0"    
## [49] "goalkeeping_reflexes: 0"        "year: 0"

A variável resposta do projeto é a “value_eur”, que apresenta 275 dados faltantes. Dentro do contexto deste projeto, decidi remover os dados faltantes, uma vez que se trata de um primeiro ciclo, com dados experimentais.

cat("O conjunto de dados original contém", dim(fifas)[1], " linhas e", dim(fifas)[2], "colunas.")
## O conjunto de dados original contém 140449  linhas e 50 colunas.
fifas <- fifas[complete.cases(fifas$value_eur), ]

cat("Após remoção dos dados faltantes da variável resposta, o conjunto de dados agora tem", dim(fifas)[1], " linhas e", dim(fifas)[2], "colunas.")
## Após remoção dos dados faltantes da variável resposta, o conjunto de dados agora tem 140174  linhas e 50 colunas.

Ainda, as variáveis “pace”, “shooting”, “passing”, “dribbling”, “defending”, e “physic” apresentam 15791 dados faltantes. Estes também serão removidos. Vale ressaltar que todos os dados faltantes são correspondentes nas linhas. Portanto, remover os dados faltantes da variável “pace” automaticamente removerá o restante.

fifas <- fifas[complete.cases(fifas$pace), ]

cat('Após remoção dos dados faltantes das variáveis "pace", "shooting", "passing", "dribbling", "defending", e "physic", o conjunto de dados agora tem', dim(fifas)[1], " linhas e", dim(fifas)[2], "colunas.")
## Após remoção dos dados faltantes das variáveis "pace", "shooting", "passing", "dribbling", "defending", e "physic", o conjunto de dados agora tem 124631  linhas e 50 colunas.

1.2.4.3. Nova contagem de NA’s e visualização da nova estrutura do conjunto de dados

na_count <- sapply(fifas, function(x) sum(is.na(x)))

# Create a list with variable name - value format
na_count_list <- paste(names(na_count), na_count, sep = ": ")

# Print the list
print(na_count_list)
##  [1] "short_name: 0"                  "long_name: 0"                  
##  [3] "player_positions: 0"            "overall: 0"                    
##  [5] "potential: 0"                   "value_eur: 0"                  
##  [7] "wage_eur: 0"                    "age: 0"                        
##  [9] "dob: 0"                         "height_cm: 0"                  
## [11] "weight_kg: 0"                   "club_position: 0"              
## [13] "preferred_foot: 0"              "weak_foot: 0"                  
## [15] "skill_moves: 0"                 "pace: 0"                       
## [17] "shooting: 0"                    "passing: 0"                    
## [19] "dribbling: 0"                   "defending: 0"                  
## [21] "physic: 0"                      "attacking_crossing: 0"         
## [23] "attacking_finishing: 0"         "attacking_heading_accuracy: 0" 
## [25] "attacking_short_passing: 0"     "attacking_volleys: 0"          
## [27] "skill_dribbling: 0"             "skill_curve: 0"                
## [29] "skill_fk_accuracy: 0"           "skill_long_passing: 0"         
## [31] "skill_ball_control: 0"          "movement_acceleration: 0"      
## [33] "movement_sprint_speed: 0"       "movement_agility: 0"           
## [35] "movement_reactions: 0"          "movement_balance: 0"           
## [37] "power_shot_power: 0"            "power_jumping: 0"              
## [39] "power_stamina: 0"               "power_strength: 0"             
## [41] "power_long_shots: 0"            "defending_marking_awareness: 0"
## [43] "defending_standing_tackle: 0"   "defending_sliding_tackle: 0"   
## [45] "goalkeeping_diving: 0"          "goalkeeping_handling: 0"       
## [47] "goalkeeping_kicking: 0"         "goalkeeping_positioning: 0"    
## [49] "goalkeeping_reflexes: 0"        "year: 0"
cat('A nova dimensão do conjunto de dados contém', dim(fifas)[1], "linhas e", dim(fifas)[2], "colunas.")
## A nova dimensão do conjunto de dados contém 124631 linhas e 50 colunas.
cat('')

1.2.4.4. Formatação dos tipos de dados

Uma característica interessante na linguagem R é que ao chamar a função “head” para verificar as primeiras linhas do conjunto de dados, também é apresentado o tipo de variável. Tal característica auxilia na formatação do tipo de variável.

Abaixo, segue a formatação das variáveis.

fifas$dob <- as.Date(fifas$dob, format = "%Y-%m-%d")
head(fifas,3)
##          short_name                           long_name player_positions
## 1          L. Messi      Lionel Andrés Messi Cuccittini               CF
## 2 Cristiano Ronaldo Cristiano Ronaldo dos Santos Aveiro           LW, LM
## 3         A. Robben                        Arjen Robben       RM, LM, RW
##   overall potential value_eur wage_eur age        dob height_cm weight_kg
## 1      93        95 100500000   550000  27 1987-06-24       169        67
## 2      92        92  79000000   375000  29 1985-02-05       185        80
## 3      90        90  54500000   275000  30 1984-01-23       180        80
##   club_position preferred_foot weak_foot skill_moves pace shooting passing
## 1            CF           Left         3           4   93       89      86
## 2            LW          Right         4           5   93       93      81
## 3           SUB           Left         2           4   93       86      83
##   dribbling defending physic attacking_crossing attacking_finishing
## 1        96        27     63                 84                  94
## 2        91        32     79                 83                  95
## 3        92        32     64                 80                  85
##   attacking_heading_accuracy attacking_short_passing attacking_volleys
## 1                         71                      89                85
## 2                         86                      82                87
## 3                         50                      86                86
##   skill_dribbling skill_curve skill_fk_accuracy skill_long_passing
## 1              96          89                90                 76
## 2              93          88                79                 72
## 3              93          85                83                 76
##   skill_ball_control movement_acceleration movement_sprint_speed
## 1                 96                    96                    90
## 2                 92                    91                    94
## 3                 90                    93                    93
##   movement_agility movement_reactions movement_balance power_shot_power
## 1               94                 94               95               80
## 2               93                 90               63               94
## 3               93                 89               91               86
##   power_jumping power_stamina power_strength power_long_shots
## 1            73            77             60               88
## 2            94            89             79               93
## 3            61            78             65               90
##   defending_marking_awareness defending_standing_tackle
## 1                          25                        21
## 2                          22                        31
## 3                          29                        26
##   defending_sliding_tackle goalkeeping_diving goalkeeping_handling
## 1                       20                  6                   11
## 2                       23                  7                   11
## 3                       26                 10                    8
##   goalkeeping_kicking goalkeeping_positioning goalkeeping_reflexes year
## 1                  15                      14                    8 2015
## 2                  15                      14                   11 2015
## 3                  11                       5                   15 2015

1.2.5. Estatística Descritiva

Para a realização da estatística descritiva geral, os dados serão separados em numéricos e não-numéricos.

1.2.5.1. Atributos Numéricos

No código abaixo, os dados numéricos serão separados dos não-numéricos:

options(scipen = 999)
df_num <- fifas[,sapply(fifas, is.numeric)]
round(t(describe(df_num)),2)
##            overall potential    value_eur  wage_eur       age height_cm
## vars          1.00      2.00         3.00      4.00      5.00      6.00
## n        124631.00 124631.00    124631.00 124631.00 124631.00 124631.00
## mean         65.86     70.92   2345896.36  11468.05     24.93    180.34
## sd            6.97      6.22   5850102.49  22705.80      4.49      6.44
## median       66.00     71.00    725000.00   4000.00     25.00    180.00
## trimmed      65.86     70.79   1147032.19   6530.99     24.73    180.35
## mad           7.41      5.93    733887.00   4447.80      4.45      7.41
## min          40.00     46.00      1000.00    500.00     16.00    154.00
## max          94.00     95.00 194000000.00 575000.00     39.00    204.00
## range        54.00     49.00 193999000.00 574500.00     23.00     50.00
## skew          0.04      0.18         8.35      6.49      0.35     -0.02
## kurtosis      0.03      0.04       111.43     75.96     -0.60     -0.21
## se            0.02      0.02     16571.07     64.32      0.01      0.02
##          weight_kg weak_foot skill_moves      pace  shooting   passing
## vars          7.00      8.00        9.00     10.00     11.00     12.00
## n        124631.00 124631.00   124631.00 124631.00 124631.00 124631.00
## mean         74.40      3.00        2.49     68.03     52.19     56.87
## sd            6.63      0.64        0.62     11.08     13.93     10.55
## median       74.00      3.00        2.00     69.00     54.00     58.00
## trimmed      74.28      2.98        2.41     68.53     52.66     57.16
## mad           5.93      0.00        0.00     10.38     14.83     10.38
## min          49.00      1.00        1.00     21.00     14.00     20.00
## max         110.00      5.00        5.00     97.00     94.00     93.00
## range        61.00      4.00        4.00     76.00     80.00     73.00
## skew          0.20      0.25        0.94     -0.53     -0.28     -0.23
## kurtosis      0.13      0.63        0.18      0.58     -0.75     -0.14
## se            0.02      0.00        0.00      0.03      0.04      0.03
##          dribbling defending    physic attacking_crossing attacking_finishing
## vars         13.00     14.00     15.00              16.00               17.00
## n        124631.00 124631.00 124631.00          124631.00           124631.00
## mean         62.03     50.98     64.81              53.97               49.55
## sd           10.39     16.69      9.74              14.04               16.30
## median       63.00     55.00     66.00              56.00               52.00
## trimmed      62.65     51.54     65.32              54.58               49.96
## mad           8.90     17.79     10.38              14.83               19.27
## min          22.00     14.00     27.00              11.00               10.00
## max          96.00     91.00     92.00              94.00               95.00
## range        74.00     77.00     65.00              83.00               85.00
## skew         -0.56     -0.31     -0.46              -0.37               -0.22
## kurtosis      0.34     -1.12     -0.15              -0.55               -0.94
## se            0.03      0.05      0.03               0.04                0.05
##          attacking_heading_accuracy attacking_short_passing attacking_volleys
## vars                          18.00                   19.00             20.00
## n                         124631.00               124631.00         124631.00
## mean                          56.87                   62.18             46.74
## sd                            11.63                   10.03             14.73
## median                        57.00                   63.00             47.00
## trimmed                       57.00                   62.75             46.57
## mad                           11.86                    8.90             17.79
## min                           12.00                   20.00             10.00
## max                           95.00                   95.00             93.00
## range                         83.00                   75.00             83.00
## skew                          -0.10                   -0.59              0.08
## kurtosis                      -0.34                    0.74             -0.77
## se                             0.03                    0.03              0.04
##          skill_dribbling skill_curve skill_fk_accuracy skill_long_passing
## vars               21.00       22.00             23.00              24.00
## n              124631.00   124631.00         124631.00          124631.00
## mean               60.18       51.20             46.48              55.80
## sd                 12.59       15.03             14.99              12.48
## median             62.00       51.00             44.00              58.00
## trimmed            61.21       51.19             45.85              56.48
## mad                10.38       17.79             17.79              11.86
## min                12.00       11.00             10.00              15.00
## max                97.00       94.00             95.00              95.00
## range              85.00       83.00             85.00              80.00
## skew               -0.75        0.00              0.33              -0.46
## kurtosis            0.55       -0.78             -0.77              -0.19
## se                  0.04        0.04              0.04               0.04
##          skill_ball_control movement_acceleration movement_sprint_speed
## vars                  25.00                 26.00                 27.00
## n                 124631.00             124631.00             124631.00
## mean                  62.92                 67.93                 68.09
## sd                    10.14                 11.62                 11.33
## median                64.00                 69.00                 69.00
## trimmed               63.48                 68.49                 68.63
## mad                    8.90                 10.38                 10.38
## min                   16.00                 20.00                 21.00
## max                   96.00                 97.00                 97.00
## range                 80.00                 77.00                 76.00
## skew                  -0.58                 -0.57                 -0.58
## kurtosis               0.74                  0.60                  0.70
## se                     0.03                  0.03                  0.03
##          movement_agility movement_reactions movement_balance power_shot_power
## vars                28.00              29.00            30.00            31.00
## n               124631.00          124631.00        124631.00        124631.00
## mean                66.26              61.90            66.45            59.60
## sd                  12.35               9.00            12.15            13.33
## median              67.00              62.00            67.00            61.00
## trimmed             66.86              61.93            67.03            60.37
## mad                 11.86               8.90            11.86            13.34
## min                 21.00              24.00            17.00            11.00
## max                 96.00              96.00            97.00            96.00
## range               75.00              72.00            80.00            85.00
## skew                -0.47              -0.04            -0.49            -0.50
## kurtosis             0.14              -0.09             0.30            -0.15
## se                   0.03               0.03             0.03             0.04
##          power_jumping power_stamina power_strength power_long_shots
## vars             32.00         33.00          34.00            35.00
## n            124631.00     124631.00      124631.00        124631.00
## mean             65.84         67.16          65.68            51.33
## sd               11.64         11.26          12.66            15.72
## median           67.00         68.00          67.00            54.00
## trimmed          66.30         67.53          66.35            51.99
## mad              10.38         10.38          11.86            16.31
## min              23.00         20.00          19.00            11.00
## max              97.00         97.00          98.00            94.00
## range            74.00         77.00          79.00            83.00
## skew             -0.42         -0.41          -0.47            -0.35
## kurtosis          0.29          0.38           0.06            -0.72
## se                0.03          0.03           0.04             0.04
##          defending_marking_awareness defending_standing_tackle
## vars                           36.00                     37.00
## n                          124631.00                 124631.00
## mean                           49.39                     51.58
## sd                             18.32                     19.07
## median                         54.00                     58.00
## trimmed                        50.16                     52.64
## mad                            19.27                     17.79
## min                             7.00                     10.00
## max                            94.00                     94.00
## range                          87.00                     84.00
## skew                           -0.36                     -0.47
## kurtosis                       -1.05                     -1.03
## se                              0.05                      0.05
##          defending_sliding_tackle goalkeeping_diving goalkeeping_handling
## vars                        38.00              39.00                40.00
## n                       124631.00          124631.00            124631.00
## mean                        49.39              10.45                10.51
## sd                          19.02               3.24                 3.21
## median                      55.00              10.00                10.00
## trimmed                     50.26              10.43                10.50
## mad                         19.27               4.45                 4.45
## min                         10.00               1.00                 1.00
## max                         95.00              75.00                75.00
## range                       85.00              74.00                74.00
## skew                        -0.41               1.30                 1.11
## kurtosis                    -1.10              19.26                16.67
## se                           0.05               0.01                 0.01
##          goalkeeping_kicking goalkeeping_positioning goalkeeping_reflexes
## vars                   41.00                   42.00                43.00
## n                  124631.00               124631.00            124631.00
## mean                   10.51                   10.47                10.46
## sd                      3.28                    3.21                 3.25
## median                 10.00                   10.00                10.00
## trimmed                10.48                   10.45                10.44
## mad                     4.45                    4.45                 4.45
## min                     1.00                    1.00                 1.00
## max                    75.00                   71.00                74.00
## range                  74.00                   70.00                73.00
## skew                    1.48                    1.11                 1.35
## kurtosis               21.00                   15.59                20.29
## se                      0.01                    0.01                 0.01
##               year
## vars         44.00
## n        124631.00
## mean       2018.65
## sd            2.28
## median     2019.00
## trimmed    2018.69
## mad           2.97
## min        2015.00
## max        2022.00
## range         7.00
## skew         -0.08
## kurtosis     -1.21
## se            0.01

1.2.5.2. Criando visualizações para verificar a distribuição dos dados numéricos

df_num1 <- df_num[,1:22]
df_num2 <- df_num[,23:44]

# Melt the data frame to long format for plotting
df_num_melt1 <- melt(df_num1)
## No id variables; using all as measure variables
# Create a grid of histograms using ggplot2
ggplot(df_num_melt1, aes(x = value)) +
  geom_histogram() +
  facet_wrap(~ variable, nrow = 5, ncol = 5, scales = "free") +
  labs(x = "Value", y = "Count")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

df_num1 <- df_num[,1:22]
df_num2 <- df_num[,23:44]

# Melt the data frame to long format for plotting
df_num_melt2 <- melt(df_num2)
## No id variables; using all as measure variables
# Create a grid of histograms using ggplot2
ggplot(df_num_melt2, aes(x = value)) +
  geom_histogram() +
  facet_wrap(~ variable, nrow = 5, ncol = 5, scales = "free") +
  labs(x = "Value", y = "Count")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

df_num4 <- df_num[,1:11]
df_num5 <- df_num[,12:23]
df_num6 <- df_num[,24:35]
df_num7 <- df_num[,35:44]

# Melt the data frame to long format for plotting
df_num_melt4 <- melt(df_num4)
## No id variables; using all as measure variables
df_num_melt5 <- melt(df_num5)
## No id variables; using all as measure variables
df_num_melt6 <- melt(df_num6)
## No id variables; using all as measure variables
df_num_melt7 <- melt(df_num7)
## No id variables; using all as measure variables
ggplot(df_num_melt4, aes(sample = value)) +
  geom_qq() +
  facet_wrap(~ variable, nrow = 3, ncol = 5, scales = "free") +
  labs(x = "Theoretical Quantiles", y = "Sample Quantiles")

ggplot(df_num_melt5, aes(sample = value)) +
  geom_qq() +
  facet_wrap(~ variable, nrow = 3, ncol = 5, scales = "free") +
  labs(x = "Theoretical Quantiles", y = "Sample Quantiles")

ggplot(df_num_melt6, aes(sample = value)) +
  geom_qq() +
  facet_wrap(~ variable, nrow = 3, ncol = 5, scales = "free") +
  labs(x = "Theoretical Quantiles", y = "Sample Quantiles")

ggplot(df_num_melt7, aes(sample = value)) +
  geom_qq() +
  facet_wrap(~ variable, nrow = 3, ncol = 5, scales = "free") +
  labs(x = "Theoretical Quantiles", y = "Sample Quantiles")

# Removing unnecessary files
rm(df_num,df_num1,df_num2,df_num3,df_num4,df_num5,df_num6,df_num7,df_num_melt1,df_num_melt2,df_num_melt3,df_num_melt4,df_num_melt5,df_num_melt6,df_num_melt7, column_info)
## Warning in rm(df_num, df_num1, df_num2, df_num3, df_num4, df_num5, df_num6, :
## object 'df_num3' not found
## Warning in rm(df_num, df_num1, df_num2, df_num3, df_num4, df_num5, df_num6, :
## object 'df_num_melt3' not found

1.2.5.3. Atributos Categóricos

O conjunto de dados também possui algumas variáveis categoricas, que foram separadas das variáveis numéricas para análise de pré-processamento e limpeza.

# Separate the non-numerical attributes of the original data frame.
df_cat <- fifas[,!sapply(fifas, is.numeric)]

# Show the first few rows for initial visual inspection.
head(df_cat)
##          short_name                           long_name player_positions
## 1          L. Messi      Lionel Andrés Messi Cuccittini               CF
## 2 Cristiano Ronaldo Cristiano Ronaldo dos Santos Aveiro           LW, LM
## 3         A. Robben                        Arjen Robben       RM, LM, RW
## 4    Z. Ibrahimović                  Zlatan Ibrahimović               ST
## 6           Iniesta                Andrés Iniesta Luján           CM, LW
## 7         L. Suárez            Luis Alberto Suárez Díaz           ST, CF
##          dob club_position preferred_foot
## 1 1987-06-24            CF           Left
## 2 1985-02-05            LW          Right
## 3 1984-01-23           SUB           Left
## 4 1981-10-03            ST          Right
## 6 1984-05-11           LCM          Right
## 7 1987-01-24           RES          Right

Note que as variáveis categóricas são apenas 6 (eu um universo de 51 variáveis).

2.0. FEATURE ENGINEERING

A base de dado possui uma variável chamada “player_positions”, que apresenta quais posições em campo o jogador pode atuar. Por exemplo, o jogador Luis Alberto Suárez Díaz pode atuar em duas posições: ST, CF. Por outro lado, existem jogadores que atuam em uma posição, ao passo que outros, em duas ou três. Portanto, criei uma variável que apresenta a contagem das possibilidades de posições em que o jogador pode participar para verificar o impacto desta versatilidade no valor final do jogador.

# CREATE A PLAYING POSITION COUNTING VARIABLE. THIS ONE WILL SHOW IN HOW MANY POSITIONS A PLAYER PLAYS.

fifas$p_position_count <- str_count(fifas$player_positions, ",") + 1

2.1. Mapa de hipóteses

Este projeto visa estimar o valor de mercado de um jogador de futebol a partir de características facilmente quantificáveis. A base de dados disponível permite criar algumas hipóteses que serão ou não validadas para a elaboração do modelo de predição.

Pitch playing position
Pitch playing position

2.2. Criando Hipoteses

H1. Valor médio do jogador depende da posição que o mesmo atua; H2. Jogadores apresentam características distintas, de acordo com a posição que atuam; H3. Jogadores versáteis são mais valiosos; H4. Jogadores versáteis, dentro de sua faixa de atuação, são mais valiosos.

3.0. VARIABLE FILTERING

A filtragem de variáveis também faz parte da limpeza de dados. Algumas restrições que o negócio apresenta podem dificultar a implantação do modelo em produção. Portanto, filtrar as variáveis não apenas moldará os dados de acordo com a questão de negócio, mas também ajudará a escolher as variáveis mais relevantes para a modelagem.

4.0. ANALISE EXPLORATORIA DE DADOS (EDA)

Depois de um minucioso processo de limpeza que usou etapas específicas para preparar os dados, é hora de verificar como e a força do impacto dessas variáveis sobre os fenômenos que estou investigando. Nesta fase, é possível detectar nuances nos dados que possam influenciar a modelagem do aprendizado de máquina nas próximas etapas. Essa abordagem diminui substancialmente a tentativa e erro. Aqui, eu expandiria a experiência de negócios e seria capaz de gerar insights, seja trazendo novas informações para a mesa ou contrastando algo que se acreditava ser verdade. Finalmente, a EDA pode revelar variáveis importantes no modelo.

H1. Valor médio do jogador depende da posição que o mesmo atua:
CORRETO - Jogadores possuem valor médio de mercado distinto, de acordo com sua posição de atuação em campo.

Aqui, primeiro criei um data frame com os agrupamentos e ordenamentos necessários para verificar as H1.

# Specify the name of your dataframe
df_num_cp <- fifas %>%
  select(where(is.numeric), club_position)

df_num_cp$long_name <- NULL

# Calculate mean by grouping variables
mean_by_group <- aggregate(. ~ club_position, data = df_num_cp, FUN = mean, na.rm = TRUE)

# Sort from value_eur
mean_by_group <- mean_by_group %>% 
  arrange(desc(value_eur))

mean_by_group <- subset(mean_by_group, select = c("club_position", "value_eur"))

# Calculate SD by grouping variables
sd_by_group <- aggregate(. ~ club_position, data = df_num_cp, FUN = sd, na.rm = TRUE)

# Sort from value_eur
sd_by_group <- sd_by_group %>% 
  arrange(desc(value_eur))

sd_by_group <- subset(sd_by_group, select = c("club_position", "value_eur"))

# Merge mean and sd data
mean_val_eur <- merge(mean_by_group, sd_by_group, by = "club_position")
mean_val_eur <- mean_val_eur %>% 
  arrange(desc(value_eur.x))

mean_val_eur$cv <- (mean_val_eur$value_eur.y/mean_val_eur$value_eur.x) * 100

colnames(mean_val_eur) <- c("club_position", "value_eur_avg", "value_eur_sd", "value_eur_cv")

# View the resulting data frame using kableExtra for styling
kable(mean_val_eur, align = "c") %>%
  kable_styling(full_width = FALSE, bootstrap_options = "striped", font_size = 14) %>%
  add_header_above(c("Club Position" = 1, "Valor Mercado (média)" = 1, "Valor Mercado (desvio-padrão)" = 1, "Coeficiente de variacao(%)" = 1), bold = TRUE, color = "black") %>%
  row_spec(1, background = "white",color = "black") %>% 
  column_spec(1:4, color = "black")
Club Position
Valor Mercado (média)
Valor Mercado (desvio-padrão)
Coeficiente de variacao(%)
club_position value_eur_avg value_eur_sd value_eur_cv
CF 10557555.6 19256219 182.3928
LW 6532372.7 15723222 240.6969
RW 6119948.2 13313717 217.5462
LF 4746666.7 8051763 169.6298
ST 4728807.7 10550463 223.1104
CAM 4564981.5 8851036 193.8899
RAM 4437762.6 6819246 153.6641
CDM 4190715.1 8895817 212.2744
RF 4165277.8 7504344 180.1643
LS 4037059.5 9255610 229.2661
LAM 4005068.2 6267030 156.4775
RCM 3816270.1 8942462 234.3247
LCM 3800055.7 8194705 215.6470
RS 3679727.5 8499348 230.9776
LM 3535750.2 7341573 207.6383
RM 3403197.6 6769326 198.9108
RDM 3216514.2 7142487 222.0568
LDM 3132473.4 6396972 204.2147
CM 3072530.1 5827588 189.6674
RCB 2951151.9 6159733 208.7230
CB 2890418.3 5814931 201.1796
LCB 2818676.2 6305563 223.7065
LB 2449315.9 5501541 224.6154
RB 2381714.7 5132908 215.5132
RWB 2370266.3 4492949 189.5546
LWB 2054492.8 3673914 178.8234
SUB 1834380.5 4052681 220.9291
RES 784039.3 1734567 221.2348
~AVG Pay by playing position
~AVG Pay by playing position

H2. Jogadores apresentam características distintas, de acordo com a posição que atuam:
CORRETO - Jogadores apresentam características específicas que otimizam a função que cumprem.

# Specify the name of your dataframe
df_h2 <- fifas %>%
  select(where(is.numeric), club_position)

df_h2$long_name <- NULL

# Calculate mean by grouping variables
h2_mean_by_group <- aggregate(. ~ club_position, data = df_h2, FUN = mean, na.rm = TRUE)

# Sort from value_eur
h2_mean_by_group <- h2_mean_by_group %>% 
  arrange(desc(value_eur))

# Remove the 'club_position' column from the data frame
h2_df_without_cp <- h2_mean_by_group[, !(names(h2_mean_by_group) %in% "club_position")]

# Iterate over each column and create a bar chart
for (column in names(h2_df_without_cp)) {
  p <- ggplot(h2_mean_by_group, aes(x = reorder(club_position, .data[[column]]), y = .data[[column]])) +
    geom_col(fill = "blue") +
    labs(x = "Club Position", y = column) +
    ggtitle(paste("Column Chart -", column)) +
    coord_flip()
  
  print(p)
}

H3. Jogadores versáteis são mais valiosos:

# Format scatterplot
p <- ggplot(fifas, aes(x = p_position_count, y = value_eur)) +
  geom_point() +
  labs(x = "Versatilidade", y = "Valor de Mercado")
# Print the plot
print(p)

5.0. CONCLUSOES

6.0 PRÓXIMOS PASSOS

Para o próximo ciclo de análise, será realizado uma análize, utilizando modelagem linear mista (linear mixed modelling), uma vez que os dados utilizados apresentam característica hierárquica, bem como fere premissas de modelos de regressão linear. Por fim, será criado um dashboard dinâmino na aplicação R Shiny, onde os stakeholders poderão acessar de qualquer equipamento com acesso a internet e tomas suas decisãoes, baseado nos dados apresentados.