머신러닝으로 야구 득/실점 예측해보기 (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에 저장이 안 되고 경기취소된 날은 추가된 모습을 확인할 수 있다.
(다음 글에 계속)
'데이터 분석 > 머신러닝' 카테고리의 다른 글
머신러닝과 기상 데이터를 이용해 홈런 갯수 예측해보기 (1) 소스 가져오기 (0) | 2020.05.10 |
---|---|
머신러닝으로 야구 득/실점 예측해보기 (5) 머신러닝 (0) | 2020.05.05 |
머신러닝으로 야구 득/실점 예측해보기 (4) 데이터 저장 (0) | 2020.05.05 |
머신러닝으로 야구 득/실점 예측해보기 (3) 스코어 뽑아내기 (0) | 2020.05.05 |
머신러닝으로 야구 득/실점 예측해보기 (1) 소스 가져오기 (0) | 2020.05.05 |