피파온라인4 기록 기반으로 23TOTY 명단 가상 선정하기(2)

khkwon_0712·2023년 2월 17일
0

1. 선수별 출전 빈도 차이 분석

합산 결과를 1차적으로 저장하였지만, 내가 보고 싶은 데이터는 경기 당 스텟이다. 전체 합산으로 해도 무방했겠지만, 선수별로 쓰인 빈도 편차가 너무나도 커서 경기 당 기록을 새로 만들어 열 추가하였다.
(예를 들어 손흥민이 10경기 5골 3도움이면 경기 당 0.5골, 0.3도움인 것이다)

각 포지션별 출전 경기 수이다. 편차가 심하다는 것을 한 눈에 봐도 확인할 수 있다. 경기 당 기록으로 평점을 매기지 않는 경우 평점도 마찬가지로 기형적으로 차이가 나게 되고, 평점의 신뢰성을 잃게 된다고 판단하였다. 누구는 도합 10000골을 득점했는데, 누구는 100골만 득점했다면, 당연히 10000골 넣은 선수의 평점이 100골 넣은 선수보다 기형적으로 높아질 수 밖에 없다. 평균적으로 한 경기당 선수의 전반적인 경기 기여도를 평가하고 싶어 경기 당 기록을 가져오게 되었고, 다만 표본이 너무 적은 것도 문제라고 생각하여 1000경기 이하 뛴 선수들의 기록은 추후 TOTY 명단 선정 시 제외하였다.

2. 경기 당 기록 열 추가하기

기존의 데이터를 csv로 저장한 결과이다. 출전 경기 수 및 누적 기록들을 다음과 같이 확인할 수 있다. 경기 당 기록을 열 추가하는 법은 간단하다. 누적된 기록을 출전 경기 수로 나누면 된다. 100경기 출전한 선수가 40골을 득점하였다면 경기 당 0.4골, 드리블 횟수가 84회라면 경기 당 0.84회의 드리블을 한 것이다.
아래의 코드가 바로 경기 당 기록을 계산하여 데이터프레임에 열 추가한 코드이다.

# FW_groupby = 1차적으로 선수 이름으로 groupby하여 저장한 데이터프레임
FW_goal = FW_groupby['득점'].values.tolist()
FW_assist = FW_groupby['도움'].values.tolist()
FW_shot = FW_groupby['일반 슈팅'].values.tolist()
FW_shot_target = FW_groupby['유효 슈팅'].values.tolist()
FW_pass = FW_groupby['전체 패스 횟수'].values.tolist()
FW_dribble = FW_groupby['전체 드리블 횟수'].values.tolist()
FW_header = FW_groupby['전체 공중볼 경합 횟수'].values.tolist()
FW_intercept = FW_groupby['가로채기'].values.tolist()
FW_tackle = FW_groupby['전체 태클 횟수'].values.tolist()
FW_block = FW_groupby['전체 차단 횟수'].values.tolist()
FW_save = FW_groupby['선방(골 차단)'].values.tolist()

FW_total_shot=[]
for shot,shot_target in zip(FW_shot,FW_shot_target): # 일반 슈팅 + 유효 슈팅
    total = shot+shot_target
    FW_total_shot.append(total)
    
FW_groupby['전체 슈팅']=FW_total_shot


x1=[]
for game,goal in zip(FW_games,FW_goal):
    x = goal/game
    x1.append(x)    
FW_groupby['경기 당 골 횟수']=x1

x2=[]
for game,assist in zip(FW_games,FW_assist):
    x = assist/game
    x2.append(x)    
FW_groupby['경기 당 도움 횟수']=x2
    
x3=[]
for game,shot in zip(FW_games,FW_total_shot):
    x = shot/game
    x3.append(x)    
FW_groupby['경기 당 슈팅 횟수']=x3

x4=[]
for game,passes in zip(FW_games,FW_pass):
    x = passes/game
    x4.append(x)    
FW_groupby['경기 당 패스 횟수']=x4

x5=[]
for game,dribble in zip(FW_games,FW_dribble):
    x = dribble/game
    x5.append(x)    
FW_groupby['경기 당 드리블 횟수']=x5

x6=[]
for game,header in zip(FW_games,FW_header):
    x = header/game
    x6.append(x)    
FW_groupby['경기 당 공중볼 경합 횟수']=x6

x7=[]
for game,intercept in zip(FW_games,FW_intercept):
    x = intercept/game
    x7.append(x)    
FW_groupby['경기 당 가로채기 횟수']=x7

x8=[]
for game,tackle in zip(FW_games,FW_tackle):
    x = tackle/game
    x8.append(x)    
FW_groupby['경기 당 태클 횟수']=x8

x9=[]
for game,block in zip(FW_games,FW_block):
    x = block/game
    x9.append(x)    
FW_groupby['경기 당 차단 횟수']=x9

x10=[]
for game,save in zip(FW_games,FW_save):
    x = save/game
    x10.append(x)    
FW_groupby['경기 당 클리어링 횟수']=x10

FW_groupby.head()

기존에는 패스 성공률, 드리블 성공률, 공중볼 경합 성공률의 데이터도 추가하였으나, 추후 평점 연산 관련 논문을 읽어본 결과 필요없는 데이터라는 것을 알게 되었고, TOTY 선정 시에는 활용하지 않았다. 그러므로 이에 관한 것은 설명하지 않고 넘어간다.
(방식은 패스 성공 횟수를 전체 패스 횟수로 나누는 그런 방식으로 하였다. 결국엔 쓰지 않았지만...🤣🤣)

골키퍼 포지션에 관한 기록은 너무 없어서 따로 하지 않았고, 단순히 경기 당 선방 기록으로 최우수 선수를 선정하기로 하였다.

3. MySQL에 저장하기

필요한 데이터를 필요 시마다 불러와서 활용할 수 있도록 MySQL에 저장한다.

FW_list = FW_groupby.values.tolist()

conn = MySQLdb.connect(user='root',passwd='password',host='localhost',db='toty_db')
cursor = conn.cursor()
cursor.execute("drop table if exists forward")
cursor.execute("create table forward(name VARCHAR(30),total_game int,goal int,assist int,shot_target int,shot int,pass_success int,pass_total int,dribble_success int,dribble_total int,header_success int,header_total int,intercept int,tackle_success int,tackle_total int,block_success int,block_total int,save int,pass_rate float,dribble_rate float,header_rate float,tackle_rate float,block_rate float,total_shot int,goal_per float,assist_per float,shot_per float,pass_per float,dribble_per float,header_per float,intercept_per float,tackle_per float,block_per float,save_per float)")
for k in range(len(FW_list)):
    data = list(FW_groupby.iloc[k])
    cursor.execute(f"INSERT INTO forward VALUES(\"{data[0]}\",\"{data[1]}\",\"{data[2]}\",\"{data[3]}\",\"{data[4]}\",\"{data[5]}\",\"{data[6]}\",\"{data[7]}\",\"{data[8]}\",\"{data[9]}\",\"{data[10]}\",\"{data[11]}\",\"{data[12]}\",\"{data[13]}\",\"{data[14]}\",\"{data[15]}\",\"{data[16]}\",\"{data[17]}\",\"{data[18]}\",\"{data[19]}\",\"{data[20]}\",\"{data[21]}\",\"{data[22]}\",\"{data[23]}\",\"{data[24]}\",\"{data[25]}\",\"{data[26]}\",\"{data[27]}\",\"{data[28]}\",\"{data[29]}\",\"{data[30]}\",\"{data[31]}\",\"{data[32]}\",\"{data[33]}\")")
conn.commit()
conn.close()

MySQLdb 라이브러리를 불러와 데이터를 저장하였다. 데이터 저장 시 선수의 이름은 VARCHAR, 누적 기록은 int, 그리고 경기 당 기록은 float로 잘 지정해서 저장하였다. 이거 엉망으로 하면 추후 데이터를 불러와서 활용할 때 커다란 곤욕을 치를 수도 있으니 이 부분은 꼭 신경써야 한다. 포지션별로 table을 따로따로 저장하였고, Forward 말고 이외의 포지션들도 위의 코드와 똑같이 저장하였다.

다음 포스팅에는 내가 평점을 매겼던 방식, 그리고 그 방식에서 중요하게 작용한 가중치에 대한 간략한 설명을 할 예정이다(논문 등장 예정)

profile
꾸준하게 😊

0개의 댓글

관련 채용 정보