머신러닝으로 야구 득/실점 예측해보기 (2) string 정리하기

    목차
반응형

어떻게 하면 날짜 별로 나눌 수 있을까 생각해보았다.

저번 글을 보면 알 수 있지만

 

날짜

경기 시작시간

원정팀

스코어

홈팀

경기 장소

 

의 형식이 반복되고 있기 때문에 string의 처음~ 원정팀 전까지, 원정팀 ~ 홈팀 끝까지, 홈팀 이후~ 다음 원정팀 전까지 ... 로 자르면 어떨까 생각했다.

 

def cutst(st):
    teamlist = ["SK", "삼성", "LG", "롯데", "KIA", "한화", "넥센", "키움", "KT", "NC", "두산", "kt"]
    tmp = []

    while ("SK" in st) or ("삼성" in st) or ("LG" in st) or ("롯데" in st) or ("KIA" in st) \
            or ("한화" in st) or ("넥센" in st) or ("키움" in st) or ("KT" in st) or ("kt" in st) \
            or ("NC" in st) or ("두산" in st) :
        tmp2 = {}
        tmp3 = []
        for team in teamlist:
            pos = st.find(team)
            if pos == -1 :
                continue
            else :
                tmp2[team] = pos

        for k, v in tmp2.items():
            tmp3.append((v, k))
            tmp3 = sorted(tmp3)
        if len(tmp3) == 0 :
            break

        pos1 = tmp3[0][0]
        pos2 = tmp3[1][0]

        st1 = st[:pos1].strip()
        st2 = st[pos1:pos2+4].strip()


        tmp.append((st1, st2))
        st = st[pos2+3:].strip()

    return tmp
[('3.1 (토)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.2 (일)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.3 (월)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.4 (화)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.5 (수)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.6 (목)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.7 (금)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.8 (토)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.9 (일)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.10 (월)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.11 (화)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.12 (수)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.13 (목)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.14 (금)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.15 (토)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.16 (일)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.17 (월)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.18 (화)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.19 (수)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.20 (목)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.21 (금)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.22 (토)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.23 (일)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.24 (월)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.25 (화)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.26 (수)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.27 (목)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n3.28 (금)\n-\n프로야구 경기가 없습니다.\n\n\n\n\n\n\n\n\n\n\n\n\n3.29 (토)\n\n14:00', '롯데\n\n11:1\n\n한화'), ('대전\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n3.30 (일)\n\n13:30', '롯데\n\n9:8\n\n한화')]

빨리 등장하는 두 팀이 경기를 붙는다는 사실을 이용하여 첫 두 팀 앞뒤로 정리를 했다.

 

하지만 이렇게 하면 경기가 없는 날까지 처리가 되어버려서 finddate()라는 함수를 만들었다.

def finddate(st):
    pos = st.find("없습니다")

    if (pos >= 0):
        st = st[pos+5:].strip()
        return finddate(st)
    try :
        if len(st) == 0 :
            return st
        x = int(st[0])
        return st
    except :
        st = st[1:]
        return finddate(st)

"없습니다"라는 문구가 있다면 그 이후로 잘라서 문구가 없을 때까지 반복하며

string의 첫 글자가 숫자가 맞다면 날짜가 맞다라고 인식을 하여 그 스트링을 그대로 반환, 아니라면 다음 글자부터 다시 체크하는 방식으로 했다.

 

 

st1 = finddate(st1)을 cutst()의 tmp.append((st1, st2)) 위에 넣고 돌리면

[('3.29 (토)\n\n14:00', '롯데\n\n11:1\n\n한화'), ('3.30 (일)\n\n13:30', '롯데\n\n9:8\n\n한화')]

짠! 보기 좋게 정리가 되었다!

 

 

 

 

 

 

...

하지만 난관에 부딪힌다.

네이버 스포츠 기록실을 보면 201X년부터 중계방송사가 추가되고, 우천으로 인해 경기취소된 날이 같이 나오기 시작한다.

특히 중계방송사엔 SPOTV2 와 KBS 2TV 등의 숫자가 들어가서 finddate 하는 데 방해를 하는 요소가 있고

SKY SPORTS처럼 SK 구단으로 인식을 하여 팀 명을 찾는데 방해하는 요소가 생긴다.

이런 것들을 예외처리 해줘야 한다.

 

먼저 SPOTV2, KBS 2TV를 없애주자.

def finddate(st):
    pos1 = st.find("없습니다")
    pos2 = st.find("V2")
    pos3 = st.find("2TV")
    if (pos1 >= 0) or (pos2 >= 0) or (pos3 >= 0):
        pos = max(pos1, pos2, pos3)
        st = st[pos+5:].strip()
        return finddate(st)
    try :
        if len(st) == 0 :
            return st
        x = int(st[0])
        return st
    except :
        st = st[1:]
        return finddate(st)

 

 

 

이제는 SKY SPORTS를 없애주자.

def cutst(st):
    teamlist = ["SK ", "SK\n", "삼성", "LG", "롯데", "KIA", "한화", "넥센", "키움", "KT", "NC", "두산", "kt"]
    tmp = []

    while ("SK "in st) or ("SK\n" in st) or ("삼성" in st) or ("LG" in st) or ("롯데" in st) or ("KIA" in st) \
            or ("한화" in st) or ("넥센" in st) or ("키움" in st) or ("KT" in st) or ("kt" in st) \
            or ("NC" in st) or ("두산" in st) :
        tmp2 = {}
        tmp3 = []
        for team in teamlist:
            pos = st.find(team)
            if pos == -1 :
                continue
            else :
                tmp2[team] = pos

        for k, v in tmp2.items():
            tmp3.append((v, k))
            tmp3 = sorted(tmp3)
        if len(tmp3) == 0 :
            break

        pos1 = tmp3[0][0]
        pos2 = tmp3[1][0]

        st1 = st[:pos1].strip()
        st2 = st[pos1:pos2+4].strip()
        st1 = finddate(st1)

        pos3 = st2.find("SKY")
        if pos3 > 0 :
            st2 = st2[pos3+10:].strip()


        tmp.append((st1, st2))
        st = st[pos2+3:].strip()

        sky = st.find("SKY")

        if (sky > 0 ) and (sky < 30):
            st = st[sky+10:].strip()
    return tmp

SK면 OK, SKY면 NO 라는 걸 확인하고 싶었으나 잘 안 됐다.

그래서 어차피 구단명 뒤로 공백이 항상 들어간다는 걸 이용하여 SK 구단을 인식할 때 'SK'가 아닌 'SK ', 'SK\n'을 확인하도록 했다.

SKY는 언제나 방해되기 때문에 SKY가 들어가면 string을 자르는 것도 이용했다. (실제로 써먹어졌는지는 모르겠다.)

 

 

 

2015년 3월의 넥센 경기를 보면 SPOTV2, SKY SPORTS가 모두 들어있다. 이 때를 예시로 코드를 돌려보자.

(경기 취소는 나중에 정리하겠다.)

[('3.7 (토)\n\n13:00', 'kt\n\n0:5\n\n넥센'), ('3.8 (일)\n\n13:00', 'kt\n\n4:10\n\n넥센'), ('3.10 (화)\n\n13:00', '두산\n\nVS\n\n넥센\n경'), ('3.11 (수)\n\n13:00', '두산\n\nVS\n\n넥센\n경'), ('3.12 (목)\n\n13:00', 'KIA\n\n5:2\n\n넥센'), ('3.13 (금)\n\n13:00', 'KIA\n\n5:6\n\n넥센'), ('3.14 (토)\n\n13:00', '롯데\n\n5:3\n\n넥센'), ('3.15 (일)\n\n13:00', '롯데\n\n1:2\n\n넥센'), ('3.17 (화)\n\n13:00', '넥센\n\n10:8\n\n한화'), ('3.18 (수)\n\n13:00', '넥센\n\nVS\n\n한화\n경'), ('3.19 (목)\n\n13:00', 'LG\n\n10:2\n\n넥센'), ('3.20 (금)\n\n13:00', 'LG\n\n2:4\n\n넥센'), ('3.21 (토)\n\n13:00', '넥센\n\n1:1\n\nSK'), ('3.22 (일)\n\n13:00', '넥센\n\n1:1\n\nSK'), ('3.28 (토)\n\n14:00', '한화\n\n4:5\n\n넥센'), ('3.29 (일)\n\n14:00', '한화\n\n5:3\n\n넥센'), ('3.31 (화)\n\n18:30', '넥센\n\nVS\n\nNC\n경')]

프로야구 경기가 없는 날은 list에 저장이 안 되고 경기취소된 날은 추가된 모습을 확인할 수 있다.

 

 

 

(다음 글에 계속)

 

728x90
반응형