# 전용준 :: 리비젼컨설팅 :: 02-415-7650 :: revision.co.kr :: xyxonxyxon@empal.com
#==================================================
# 랜덤 포리스트 Random Forest 를 사용한 간단한 예측 모델링 적용 예제를
# kbo data set에 응용하는 사례 ( http://blog.daum.net/revisioncrm/201 도 참조 )
k3 <- read.table("kbo_batterbox.txt", header=TRUE, sep=",")
# 이전에 사용하던 데이터를 그대로 활용
# 참고 : [kbo data set ] 자료와 의미 ==> http://blog.daum.net/revisioncrm/171
# 임시로 target 변수로 사용할 항목을 하나 생성
# 장타율 rlong 값이 median에 해당하는 0.403 을 넘으면 장거리 포 타자라고 간주하기로 함
# 장거리와 단거리 두가지로만 구분된 binary 변수 생성
# instead of use if else if structure u can use variable creation straightforwardly
k3$isLH[ k3$rlong >0.403 ] <- 'LH' # designating long range hitter
k3$isLH[ k3$rlong <=0.403 ] <- 'sH' # others are short range hitter
# 필요없는 일부 항목을 data frame 에서 제거.
k3$rlong <- NULL
k3$palyer <- NULL # data frame을 만들면서 typo로 player를 palyer라고 명명했음
# 데이터 셋 수정이 필요한 대목. 여하간 사용하지는 않을 것임 (선수 이름)
# 48명 선수만 들어있는 데이터 이므로 20명은 테스트용으로 나머지 28명은 모델 학습용
test = k3[ c(1:20), ]
train = k3[ c(21:48), ]
attach(train)
# 데이터 타입이 올바른지 잠시 확인
is.numeric(train$robase)
# 랜덤포리스트 패키지 호출
require(randomForest)
r = randomForest(isLH ~., data=train, importance=TRUE, do.trace=5)
# 에러가 발생되면서 r 오브젝트는 생성되지 않음. 에러메시지는...
### error :: Can not handle categorical predictors with more than 32 categories.
# [검토] random forest를 사용하는 것이 아니라고 해도 tree 모델을 만들면서
# 다수의 카테고리로 구성된 변수를 사용하는 것은 통상적이지 않은 방법
# 그러나 여기서의 이슈는 의도하지도 반영하지도 않은 category 변수가 사용된다는 점
print(r)
# 아래 중에서 뒤에 works 라는 표시가 붙은 부분은 정상 수행됨. 나머지는 같은 오류 발생
r = randomForest(isLH ~ games +atbat, data=train, importance=TRUE, do.trace=5,
ntree=5)
r = randomForest(isLH ~ position , data=train, importance=TRUE )
r = randomForest(hr ~ games , data=train ) # works
r = randomForest(position ~ games , data=train ) # works
r = randomForest(position ~ games + team, data=train, importance=TRUE,
do.trace=5, ntree=20) # works
print(r)
[ info:: 데이터사이언티스트의 현재와 미래 컨퍼런스 2014년 10월 8일 ]
http://www.itdaily.kr/news/articleView.html?idxno=55924
# the issue is in the target variable isLH which was created during
# the data prep session
# target 변수를 isLH 대신 hr 이나 position 같은 다른 변수로 바꿔 보면 정상 실행됨
# hr은 홈런수로 수치형 변수. position은 character 변수. 결국 문제는 targe variable인
# isLH에 있는 것으로 추측됨
# to check if NA/NaN/Inf related issue
# 에러메시지에 나오듯이 세가지중의 무언가로 값이 잘못 들어간 것이 있는지 확인중
# 콘솔 출력후 눈으로는 확인되지 않아서 with 함수를 사용해봄
with(train, train == Inf)
with(train, train == NA)
with(train, train == NaN)
# only isLH shows different value FALSE from the last command line
# all others show NA
# Inf와 NA에서는 특별한 점이 나타나지 않았으나 NaN 을 적용했을때 특이한 현상 나타남.
# isLH에 대한 결과값이 FALSE로 나타남 (다른 모든 값은 NA )
# 레벨의 수 즉 카테고리의 수를 확인하기 위해 unique 함수로 체크
# 동일한 듯 보여도 position은 레벨이 표시되지만 새로이 생성한 derived variable 인 isLH 는
# 레벨이 표시되지 않음. 생성된 변수에 대해서 더블쿼우트 쌍따옴표가 붙는 것이 문제를
# 일으켰을 가능성을 의심해봄
unique(position)
[1] cat cf lf 2b 3b 1b rf ss
Levels: 1b 2b 3b cat cf lf rf ss
unique(isLH) [1] "LH" "sH"
# 테스트를 위해서 처음 읽어들인 데이터에 isLH 변수 생성후 물리적인 파일로 export한 후
# 다시 import 하는 트릭을 시도해봄
k3 <- read.table("kbo_batterbox.txt", header=TRUE, sep=",")
k3$isLH[ k3$rlong >0.403 ] <- 'LH' # designating long range hitter
k3$isLH[ k3$rlong <=0.403 ] <- 'sH' # others are short range hitter
write.table(k3, "kbo_batterbox01.txt", sep=",")
k3 <- read.table("kbo_batterbox01.txt", header=TRUE, sep=",")
k3$rlong <- NULL
k3$palyer <- NULL
test = k3[ c(1:20), ]
train = k3[ c(21:48), ]
attach(train)
# require(randomForest)
# 이번에는 isLH에 FALSE 값이 또 나오는지 다시 체크 해봄. 모두 NA로 나옴
# 문제가 해결되었다는 이야기임
with(train, train == NaN)
# 당연히 모델 생성도 정상적으로 됨
# randomForest 에서는 input과 target 양쪽의 변수로 numeric, category 모두 사용 가능
r = randomForest(isLH ~ games + team, data=train, importance=TRUE, do.trace=5,
ntree=20) # works
r = randomForest(isLH ~ position + games + atbat + run + double + steal + SO +
rhit + robase, data=train, importance=TRUE, do.trace=5, ntree=100) # works
print(r)
# 테스트 데이터를 가지고 예측값 생성
k3.predict = predict(r, test)
k3.predict
t = table(observed=test[,'isLH'], predict=k3.predict)
t
prop.table(t, 1)
# 정상적으로 실행되었음. 결국 여기서 문제를 일으킨 부분은 중간에 파생변수 생성한 부분.
# 코딩 과정에서 잘못한 것은 아니라 할 수 있음. R 자체의 문제라고 봐야 할 듯.
# 어쩔 수 없이 트릭을 사용해서 문제를 해결해야 하는 번거러움을 감수해야함
# 참고로 정상적으로 32개 카테고리를 넘는 카테고리 변수역시 사용할 수 없기 때문에
# 이 경우에는 매트릭스 같은 다른 데이터 타입으로 변환이 필요함
# compare the results from the cases when ntree=20 and ntree=100
# 함수 사용에 특별한 복잡한 파라미터는 없고 그저 생성할 트리 갯수 정도만 지정하면되므로
# 트리 갯수에 서로 다른 옵션을 준 경우에 얼마나 예측의 정확성이 차이나는지 확인해봄
# 20을 주었을 경우와 100을 주었을 경우. 물론 컴퓨팅 리소스를 더 쓰는 것은 당연하겠지만
# 정확도는 상당히 증가함을 confusion matrix를 비교하여 볼 수 있음.
# 왜 random forest를 많이들 사용하는지를 간단하게 보여줌
# 다만 다수의 트리의 ensemble 이다 보니 어느 변수가 더 중요했는지에 대한 직관적인 정보를
# 확인하기 위해서는 별도의 작업이 필요
# in case of ntree=20
predict
observed LH sH
LH 0.5000000 0.5000000
sH 0.3333333 0.6666667
# in case of ntree=100
predict
observed LH sH
LH 0.6428571 0.3571429
sH 0.3333333 0.6666667
# 모델 평가를 위한 플롯 ----------------------------------
# [참고] http://stats.stackexchange.com/questions/2344/best-way-to-present-a-random-forest-in-a-publication
# 트리 수의 증가에 따른 오차율 변화 플롯
plot(r, log="y")
# 변수 중요도를 나타내는 플롯
varImpPlot(r)
# 모델에 대한 사후 분석 결과를 보면
# 1. 트리의 수를 50 이상으로 설정한다면 이 문제에서 오차가 더 줄어들지 않는다
# 결국 트리의 수는 50으로 설정한다면 충분하다
# 2. 거포 즉, 장타율이 높은 타자인가 (isLH)를 구별하는데는 타율(rhit)과 2루타(double), 출루율(robase)이 중요한 변수임
# 3. 의외로 장타율 계산에 직접 사용되지는 않는 도루의 수와 포지션도 영향력이 있는 변수임
# [Tip] 단순히 모델을 만들고 예측치를 계산하는 것에 멈춘다면 데이터 분석의 가치를
# 100% 활용할 수 없음. 사후 분석이나 결과값에 대한 Profiling을 통해서
# Data와 문제 자체에 대한 background knowledge와 insight 를 얻어내는 것이 필수
# 파악된 중요 변수에 대한 목표 변수와의 관계 플롯 [ -> 추가적 EDA 탐색적 분석]
require(ggplot2) # ggplot2 패키지의 플롯을 사용해서 간단한 탐색위한 시각화 시도
qplot( rhit, isLH, data = k3, color = position, size = robase )
# Y축에 장타율이 높은가하는 binary class 변수( 예측 모델링의 목표 변수)를 두고
# 주요변수인 타율, 출루율, 그리고 의외였던 포지션 (색상으로) 간의 관계를
# 하나의 플롯에서 확인
# 플롯이 보여주는 내용은 [해석] 타율이 장거리포인 타자들이 전반적으로 높다는 점
# 출루율 역시 장거리포들이 더 높다는 점... 어쩌면 볼넷을 얻기 좋아서?
# 투수들이 피하고자 한다면 그럴 수도 있을 듯
# 포지션의 경우 9개 카테고리가 되므로 48개 뿐인 데이터로는 패턴이 나타난다해도
# 신뢰하기는 곤란할 것 같다는 판단이 됨
# 질문사항은 ==>
# 댓글에 남기거나, xyxonxyxon@empas.com 으로도 연락 가능
'R 데이터 분석' 카테고리의 다른 글
twitter access tmp (0) | 2013.08.29 |
---|---|
[R 분석 연습] 2차원 플롯 : 밀집 영역 플로팅 (0) | 2013.06.14 |
랜덤 포리스트 random forest [R 마이닝] (0) | 2013.06.04 |
[빅 데이터, 그리고] 데이터 사이언스와 데이터 마이닝 - Using R <강좌 예고> (0) | 2013.05.09 |
[R 분석] searchtwitter 한글 오류 검토 (0) | 2013.04.12 |