[LibSVM] libsvm을 이용한 2-class classifier (3) - Optimal parameter를 찾고 자동으로 학습하자!
전공관련/기타 etc. 2014. 2. 14. 15:54지난 두편에서 SVM 의 개념과 exe 파일을 이용한 학습방법을 살펴 보았다.
[LibSVM] libsvm을 이용한 2-class classifier (1) - SVM이란 무엇인가.
[LibSVM] libsvm을 이용한 2-class classifier (2) - Training/Test (exe파일 이용)
이번에는 svm 학습시에 사용되는 파라미터의 최적값을 찾기위한 python script [ grid.py ] 와 [ easy.py] 사용법에 대하여 알아보자
이 방법은 svm의 기본값인 C-SVM 과 RBF 커널 에 대해서 사용가능하고 다른 커널이나 svm 모드에 대하여는 모르겠다! ㅋ
grid.py 스크립트는 최적의 파라미터를 반환해주는 스크립트고 easy.py는 최적의 파라미터를 찾고 트레이닝까지 다 해주는
스크립터이다.
나는 한번 입력으로 model 까지 만들어 주는 easy.py 을 주로 사용한다.
사용할때 가장 해멘 부분이 실행만 하면 자꾸 exe 파일이 없다는 경고와 함께 실행이 불가능한 부분이었다.
Google 검색 중에 해당 스크립트의 파이선 소스코드를 발견했다.
그중에 문제가 되는 부분이 아래 부분인듯 하다.
- is_win32 = (sys.platform == 'win32')
- if not is_win32:
- svmscale_exe = "../svm-scale"
- svmtrain_exe = "../svm-train"
- svmpredict_exe = "../svm-predict"
- grid_py = "./grid.py"
- gnuplot_exe = "/usr/bin/gnuplot"
- else:
- # example for windows
- svmscale_exe = r"..\windows\svm-scale.exe"
- svmtrain_exe = r"..\windows\svm-train.exe"
- svmpredict_exe = r"..\windows\svm-predict.exe"
- gnuplot_exe = r"c:\tmp\gnuplot\binary\pgnuplot.exe"
- grid_py = r".\grid.py"
내 PC의 OS 는 64bit 를 사용중인지라 exe 파일의 경로가 아래 else 항 대로 설정이 되어야 하는 듯 하다.
python script 를 수정 할 방법이 있다면 경로를 수정하면 좋겠지만 나는 그러한 방법을 모르기에 해당 경로에
파일을 옮겨 주기로 한다.
상위폴더에 windows 폴더를 만들고 svm 파일들 넣어주고.. c에 tmp 이하 경로를 설정하고.. exe 파일을 복사 해준다.
경로 설정을 해주니 실행이 가능하다. 이게 문제였어.. ㅋ
아무튼 easy.py의 실행 방법은 svm 과 마찬가지로 명령프롬프트 창에서 수행한다.
easy.py 스크립트가 위치한 폴더로 이동후에
파일경로>easy.py [training_data] [test_data]
이때 주의할 점은 training data 와 test data 는 scaling 되지 않은 데이터를 넣어 줘야한다는 것이다.
이유는 해당 스크립트에서 먼저 스케일링을 수행하고 5 fold cross validation 을 수행하여 최적의 파라미터를 찾기 때문이다.
뭐 스케일된거 넣으면 그냥 같은 결과가 나오겠지....
아무튼 수행하면 gnuplot으로 트레이닝 양상을 시각화 하여 보여준다.
원래 이렇게 오래 걸리는 건지 모르겠지만 본인의 경우에는 하나의 파일을 트레이닝 하는데 24시간이 넘어 걸렸다.
feature 960 차원 / data_set 10000 개 기준으로 26시간 정도 걸리는거 같다.. 시간을 줄일수 있는 방법 아시는분 알려줘요..
뭐 켜놓고 다른일 하다 퇴근하고 다음날 오면 되있을테니..
아무튼 학습이 끝나면 Best 파라미터와 해당 파라미터를 이용한 Cross Validation 결과를 보여준다.
또한 해당 파라미터로 학습한 모델을 이용하여 같이 입력한 테스트 파일에 대한 테스트 결과도
이어서 보여주므로 학습 데이터가 아닌 unknown 데이터에 대한 대략적인 인식률도 미리 확인 가능하다.
학습 시에 최적 파라미터를 이용하는것과 기본 파라미터를 이용하는 것은 최종 인식률에서 큰 차이가 나타나므로
grid/easy.py 를 이용하여 반드시 최적 파라미터를 확인하고 학습 하도록 하자.
'전공관련 > 기타 etc.' 카테고리의 다른 글
해시 / MD5 / SHA / 무결성검사 에 관한 정리 (0) | 2017.07.18 |
---|---|
HOG Feature / Descriptor (1) | 2014.12.10 |
[LibSVM] libsvm을 이용한 2-class classifier (3) - Optimal parameter를 찾고 자동으로 학습하자! (14) | 2014.02.14 |
[LibSVM] libsvm을 이용한 2-class classifier (2) - Training/Test (exe파일 이용) (14) | 2014.02.13 |
[LibSVM] libsvm을 이용한 2-class classifier (1) - SVM이란 무엇인가. (5) | 2014.02.12 |
[자료구조] 여러가지 Sorting 기법을 시각/청각적으로 표현 (0) | 2014.01.26 |
댓글을 달아 주세요
안녕하세요? 보행자 검출 연구를 하고 있는 사람입니다. 매직블럭 님의 게시물을 잘 보고 있습니다. 좋은 자료 감사합니다.
다름아니라 제가 이렇게 쓴 댓글을 쓴 이유는 LibSvm으로 predict를 시킬 때 exe 파일로 한 거와 easy.py를 실행한 후 나오는 accuracy 가 크게 차이가 나서 혹시 어떤 이유에서 많이 나는지 알고 계신지 여쭤보려고 댓글을 쓰게 되었습니다.
만약 다르게 나오는 것이 맞다면 어느 부분에 신뢰성을 더 두어야 하는지 그것도 알고 싶습니다.
혹시 wjddms7392@naver.com 이쪽으로 답변을 해주실 수 있으시면 이쪽으로 답변을 해주시면 정말 감사드리겠습니다.
메일 드렸습니다.
안녕하세요. 배터리의 잔존 수명 혹은 용량을 예측하는 연구를 하려고 합니다. SVM을 사용할때 클래스를 2개 이상 나눠야 한다고 나오더라구요 그런데 예측하고자 하는 데이터가 진행된 싸이클숫자에 대한 용량 즉, 곡선형태인데 클래스를 어떻게 나눠야 하는건가요? 홀수번 데이터는 0 짝수번 데이터는 1 이런식으로 클래스를 나누면 모든 데이터를 지나가는 벡터를 그릴 수 있는건가요?
그리고 predict를 통해 얻어진 데이터를 그래프화 시키는 것이 가능한가요? 윈도우에서 .predit 데이터를 text로 읽어들이면 0과 1로만 이루어진 데이터가 나옵니다. 그런데 클래스를 나눌때 사용되어진 벡터를 어떻게 그릴 수 있는지 궁금합니다. 클래스를 나눌때 만들어진 곡선이 있을텐데 말이죠.
세번째는, 트래이닝 데이터와 테스트 데이터의 차이점을 알고싶습니다. 트래이닝 데이터를 통해 학습되어진 SVM을 통해 테스트 데이터를 테스트 해 보는건가요?? 그렇다면 트래이닝 데이터와 테스트 데이터의 차이를 모르겠습니다. 제상황으로 놓고 볼때는 동일 조건으로 만들어지 배터리의 용량 데이터를 테스트 데이터로 사용하면 되는건가요? 아니면 트래이닝 데이터 다른 데이터들을 더 집어넣어서 정확도를 높이는게 더 좋은건가요? 그리고 트래이닝 데이터를 그대로 테스트 데이터로 사용하여도 되는지 궁금합니다. SVM을 처음 접해보는데 하면 할 수록 어렵내요 ㅠㅠ 두서 없이 물어봤는데 답변 주시면 정말 감사하겠습니다.
제가 맞게 이해 한건진 모르겠지만 일단 진행하시는 연구에 대해서는 classification 문제가 아닌 regression 문제로 푸셔야 한 것 아닌가 하는 생각이 드네요. 두번째 질문에 대해서는 libsvm에서는 prediction 된 class 결과가 아닌 score를 출력하는 방법이 있는 것으로 알고 있습니다. 이에 대해서는 libsvm 사이트에서 찾아 보시는게 가장 빠를 것 같습니다. ( https://www.csie.ntu.edu.tw/~cjlin/libsvm/ ).
마지막 질문에 대한 답변은 테스트 데이터는 말 그대로 학습 된 모델의 성능을 평가하기 위한 테스트 데이터 셋입니다. 데이터 자체에 차이가 있는 것은 아닙니다. 수집된 데이터 중에서 1/10을 테스트 데이터로 사용 하는 방법이나 일반적으로 흔히 사용하는 n-fold cross validation 방법을 사용하여 성능을 평가 할 수 있습니다. 트레이닝 데이터를 그대로 테스트셋으로 사용할 경우는 이미 답안지를 보고 공부를 한것과 같은 것이기에 테스트 성능은 잘 나오지만 그것이 학습되지 않은 unknown 정보에 대해서도 동일한 성능을 보인다고 기대할 수 없습니다. 즉, training/test dataset은 완벽히 분리 해 주시고 테스트셋을 학습에 절대 사용하시면 안됩니다.
쥔장님 블로그 글 덕분에 svm의 실전 사용법까지 익히게 되었습니다.프로그래밍자체에 문외한이라 cmd에서 27피쳐,1800개 데이터를 가진 주가정보를 가지고 두부류로 구분하고 있는데 (30개선택,1770개 탈락)ㅡsvm홈피에서 피쳐가 구분자보다 훨씬 많은경우 선형분석을 하는것이 낫다고 하여 밤새가며 수동으로 돌렸는데 테스트셋에서 거의 안맞더군요.근데 파이썬에서 자동으로 찾는 법이 있다니 너무 반가운 나머지 댓글을 남깁니다.혹 파이썬의 소스코드정보와 사용법을 알려주실 수 없는지요?
수개월간 정말 어렵게 이까지 왔는데 ㅠ힘드네요
감사합니다.즐건 주말 되세요
자동으로 옵티멀 파라미터 찾고 학습까지 수행하는 스크립터가 easy.py 입니다. SVM 설치하시면 기본으로 포함되어있고 얘는 내부적으로 grid.py 파일을호출하여 사용합니다.
먼저 easy.py 파일의 아래부분에 경로를 맞게 설정 해 주시고
is_win32 = (sys.platform == 'win32')
if not is_win32:
svmscale_exe = "..\windows\svm-scale.exe"
svmtrain_exe = "..\windows\svm-train.exe"
svmpredict_exe = "..\windows\svm-predict.exe"
gnuplot_exe = "c:\Program Files (x86)\gnuplot\bin\pgnuplot"
grid_py = ".\grid.py"
else:
# example for windows
svmscale_exe = r"..\windows\svm-scale.exe"
svmtrain_exe = r"..\windows\svm-train.exe"
svmpredict_exe = r"..\windows\svm-predict.exe"
gnuplot_exe = r"C:\Program Files (x86)\gnuplot\bin\gnuplot.exe"
grid_py = r".\grid.py"
그다음 grid.py파일에서
self.c_begin, self.c_end, self.c_step = -1, 5, 2
self.g_begin, self.g_end, self.g_step = -5, -9, -2
이 부분을 수정하셔서 검사 범위를 제한하시는게 좋을것 같습니다.
검사 범위는 옵션이지만 전체를 다 탐색 할경우 시간이 너무 오래걸려서 저는 범위를 줄여서 사용하고 있습니다. 정확히 기억은 안나지만 아마 저 파라미터가 제가 줄여서 사용했던 수정된 파라미터 일 겁니다.
이 두군데만 수정하시고
파일경로>easy.py [training_data] [test_data]
이와같이 실행하시면 알아서 파라미터 찾고 학습까지 진행 해 줍니다.
친절한 설명 너무감사드립니다.말씀한신대로 해보니 그래프 그리는 프로그램을 안깔았는데 파일없다고 해서 파이썬 깔고 소스부분의 gnuplot 부분을 다 삭제하고 진행했습니다.다행히 데이터가 작아서 그런지 결과가 빨리 나오더군요. 근데 테스트셋의 결과가 백개의 데이터중 10개만 구분하는건데 정작구분해야될 데이터는 모두 분류를 못하네요. 다른 좋은 방법이 없을까요?감사합니다.
윗 댓글로 짐작컨데 리니어 커널 사용중이시지 않을까 합니다. 가장 쉽게 바꿔볼수 있는게 RBF 커널로 바꿔서 사용해 보심이 어떠할까 합니다. 기본적으로 RBF커널이 기본값이고 이녀석은 비선형 커널이라 다른 성능을 낼 수도 있지 않을까 합니다.
(참고)
-t kernel_type : set type of kernel function (default 2)
0 -- linear: u'*v
1 -- polynomial: (gamma*u'*v + coef0)^degree
2 -- radial basis function: exp(-gamma*|u-v|^2)
3 -- sigmoid: tanh(gamma*u'*v + coef0)
본문에 기술하신것 처럼 easy py 로 자동최적화 결과를 만들고 난 값이라...기본 c svm 에 rbf 커널아닌가요? 리니어커널은 수동으로 할때 지정해 봤었구요.지금은 easy py로 하고 있는데도 테스트셋 결과가 안좋네요.혹 grid py 에서 커널 옵션변경이 되나요?감사합니다.
easy.py 파일에
cmd = '{0} -c {1} -g {2} "{3}" "{4}"'.format(svmtrain_exe,c,g,scaled_file,model_file)
해당 구문 수정하시면 옵션 모두 사용 가능하십니다.
이런저런 시도 해 보셔도 성능이 정 안좋다면 데이터 자체가 svm으로 classification 이 안되는 형태의 데이터인지도 점검이 필요할 듯 합니다.
cmd 라인을 보니 svm종류 c값 감마값 훈련셋 훈련모델인데 커널은 임의로 삽입하니 -t {0} 작동에 변함이 없네요ㅠ 어찌 수정해야 될까요?번거롭게 해드려 죄송함다.홈피에보니 liblinear 도 있던데 요런것도 easy py 가 되려나요?정 두클래스로 구분이 안된다면 확률분석을 해도 괜찮을듯 한데....회귀로 풀면 될런지...감사합니다.
비밀댓글입니다
안녕하세요, 이번에 SVM을 이용해서 차종분류 하는 프로젝트를 맡게되어 SVM을 공부하다가 들르게 되었습니다. 좋은 설명 감사합니다. 이해하는데 많은 도움이 되었습니다.