#2-3 사람들은 경마 예측을 잘 할까요

목차

    2017. 10. 14. 07:14



    경마장에 가면 다양한 경마 정보지를 판매하고 있습니다.

    그리고 많은 사람들이 이 정보지를 가지고 경마 경기를 분석예측합니다.


    그럼 사람들이 이렇게 예측하는 정보는 얼마나 정확할까요? 그리고 얼마나 돈을 벌거나 잃을까요?



    이를 알기 전에 배당에 대해서 조금 알아보겠습니다.


    경마는 사람들이 베팅한 금액을 적중한 사람들에게 나눠줍니다. 

    나눠줄 때는 각종 세금과 비용을 떼고, 나머지를 지급합니다. 

    적중했을 때 돌려주는 비율을 환급율이라고 합니다.

    정확히는 단승식과 연승식은 환급률이 80%,

    그 외에 나머지 승식은 환급률이 73%입니다. 

    다시 설명드리면, 마사회에서 20~27%에 해당하는 금액을 세금과 기타 비용 등으로 떼고 지급합니다. 


    ( 참고로 승식은 단승식, 연승식, 복승식, 쌍승식이 있습니다. 

      단승은 1등하는 말을, 연승은 3등 안으로(3등 포함) 들어오는 말을, 

      복승식은 순서와 상관없이 1,2등 또는 1,2,3등을

      쌍승식은 순서대로 1,2등 또는 1,2,3등을 맞추는 베팅 방식입니다.)


    경마 결과나 경기 중에 표기되는 배당률은

    각종 세금과 비용을 떼고 실제 지급되는 돈이 표기됩니다.

    그래서 배당이 1.1이면 110%가 지급됩니다.


    맞힌 사람들에게 베팅된 돈을 나눠주다 보니, 많은 사람들이 맞추면 배당 금액은 낮아지게 됩니다. 

    반대로 맞춘 사람들이 적으면 배당 금액은 많아지게 됩니다.

    실제로 연승식의 경우 배당이 1.0인 경우도 많은데, 배당이 1.0이면 원금을 돌려받게 됩니다.

    리스크를 감수하고 베팅했는데도, 돌려받는 돈은 원금이라니 베팅한 의미가 없네요.




    (출처: 17년 7월 29일 서울 첫 번째 경주)


    연승은 맞추기 쉬운 만큼 배당이 낮습니다. 1등한 말의 연승 배당이 1.1로 굉장히 낮네요.



    그래서 배당이 적은 말의 경우는 많은 사람들이 1등할 것이라고 예상한 말로 볼 수 있습니다.

    단승식으로 배당이 가장 적은 말이 얼마나 많이 1위로 도착하느냐를 산출해보면,

    많은 사람들이 1등할 것이라고 예상하는 말이 얼마나 잘 적중하는지를 알 수 있을 것입니다.



    # coding=utf-8

    import sqlite3
    import pandas as pd

    if __name__ == "__main__":

    con = sqlite3.connect("./data/race.db")
    cur = con.cursor()
    query = cur.execute("SELECT * From total_hn_bu")
    cols = [column[0] for column in query.description]
    race = pd.DataFrame.from_records(data=query.fetchall(), columns=cols)
    con.close()


    전에 설명드린 것처럼, encoding 및 패키지 import를 하고 DB를 불러옵니다.



    먼저 단승식이 숫자 형태로 되어 있는지 확인해 보겠습니다.


    In[3]: print(race["단승"].dtypes) object


    Object로 정의되어 있는 것을 확인할 수 있습니다. float 형식으로 변환하겠습니다.




    In[3]: race["단승"]=race["단승"].astype(float) ValueError: could not convert string to float: '----'


    여기서도 에러가  발생하네요. "----"을 float로 변환할 수 없다고 합니다.

    출전취소 등이 발생하는 경우, 해당 말에 대한 배당값이 없을 수 있습니다. 


    이런 데이터를 삭제하고 다시 float 형식으로 바꾸니 작동이 됩니다.

    자세한 설명은 이전 글에서 했으므로 생략하겠습니다.


    race=race[race["단승"]!="----"]
    race["단승"] = race["단승"].astype(float)



    이제 경기별로 배당이 적은 말에 랭킹을 부여하기 위해, groupby와 rank라는 함수를 쓰겠습니다.


    groupby는 그룹별로 계산을 하겠다는 이야기이고요. rank는 순서대로 번호를 부여하겠다는 함수입니다.


    race["pred_rank"] = race.groupby(["date", "no", "location"])["단승"].rank(method="min")
    race = race.reset_index(drop=True)


    groupby에는 총 세 개의 변수를 넣었는데, 이렇게 해야 각각의 경기를 구분할 수 있습니다. 

    날짜, 경기번호, 경기지역입니다. 그리고 "단승" 변수값을 기준으로 랭킹을 부여하는데, 

    방법은 최소값부터 차례로 부여합니다. 그리고 부여된 값은 "pred_rank"라는 변수에 저장됩니다.



    그리고 코드를 실행하다보면 warning이 나올 수 가 있는데요. 

    dataframe에서 일부 행을 삭제하거나 추가하게 되면 i

    ndex에 비는 값들이 생기면서 warning이 발생하게 됩니다. 


    예를 들면, 1,2,3행에서 2행을 삭제합니다. 그러면 index가 1,3이렇게 이어지게 되는데, 


    이런 경우  warning이 발생합니다. 대게는 별 문제가 되지 않지만,

    for문을 돌리거나 할 때 문제가 될 수 있습니다. 


    reset_index문을 이용해서 index를 재지정하면 해결됩니다.



    ix문을 이용해서, 얼마나 1위 적중했는지 비교해 보겠습니다.


    race["is_right"]=0
    race.ix[(race["순위"]==race["pred_rank"]) & (race["순위"]==1),"is_right"]=1


    먼저 is_right라는 변수에 0값이 넣습니다.

    그리고 ix 문을 이용해서, 실제 순위("순위" 변수)와 단승을 기준으로 예측한 순위가 같고 

    그 순위가 1위라면  is_right의 값을 1로 바꿔 줍니다.



    여기서 잘 동작하지 않는 것을 알 수 있는데, 


    순위의 datatype이 object라 모든 값이 다르다고 나오는 것을 알 수 있습니다.

    그래서 순위 변수도 int형으로 바꾸고 다시 실행합니다.



    result=race.groupby(["date","no","location"])["is_right"].sum()
    print(result.groupby("is_right").size())



    이제 각각의 경기별로 is_right를 더해 봅니다.


    어차피 한 경기에서 1등하는 말은 1마리이기 때문에 최대값은 1일 것입니다. 

    그 result를 groupby에서 count를 하면 1등을 적중한 경기수가 나올 것입니다. 

    groupby를 하면서 type이 dataframe에서 series로 바뀌었기 때문에

    다시 dataframe으로 바꾸고 실행하였습니다.


    result=race.groupby(["date","no","location"])["is_right"].sum()
    result=pd.DataFrame(result)
    print(result.groupby("is_right").size()) is_right 0 6301 1 4316 dtype: int64


    전체 10,617 경기중에 4,316 경기를 적중해서 적중률이 무려 40%나 됩니다. 

    실제로 모델을 돌려서 이 40%를 넘기란 정말 어렵습니다. 


    경마 정보지를 가지고 분석하는 많은 경마인들이 상당히 정확한 예측을 하고 있었습니다.


    그럼 이렇게 투자하면 돈을 벌 수 있을까요? 단승 배당값을 적용해 보았습니다.


    right = race[race["is_right"]==1]
    right["단승"].sum() Out[31]: 8641.400000000012


    race에서 맞은 말들만 골라서, 배당값을 더해보았습니다.

    8,641.4라는 값이 나왔습니다. 4,316경기에 대한 배당값이니 2배 정도 되네요. 

    그런데 저희가 맞는 경기만 베팅할 수 있는 것은 아니므로,

    전체 경기(10,617) 기준으로 수익률을 산정하면 81.4% 가 나옵니다. 


    결국 적중율은 높았지만

    배당이 적기 때문에 마이너스인 것을 알 수 있었습니다.

    실제로 경마를 해 보니 적중하는 것도 중요하지만, 

    그보다 배당이 더 중요하다는 것을 알 수 있습니다.

    가끔 대박 경기가 나오는데

    그런 경기는 많은 사람들이 꼴지로 들어올 거라고 예상한 말이

    1등을 하는 경우입니다. 

    맞춘 사람들이 한 두명 밖에 되지 않으니 

    배당금이 어마어마 합니다. 

    2만배가 넘는 배당이 나올 때도 있으니, 

    천원 베팅 기준으로 2천만원 되겠네요.

    이렇게 남들은 다 안 된다고 예상했는데

    내가 맞추어야 수익이 더 커집니다.



    그럼 다음 편에는 또 다른 주제로 경마를 알아보도록 하겠습니다.


    감사합니다.