[Python] MFCC를 통한 SVM 구현


앞서 추출한 MFCC를 통해 SVM 모델을 학습시켜 보자.

SVM에 대한 개념적 이해는 이 포스팅에서 다루지 않겠다. 필요시 글을 새로 작성할 계획.

먼저, 구글링을 열심히 하며 겪은 시행착오들..


음성 감정 인식에 대한 정보가 많이 없어 처음 코드를 작성할 때 많은 벽을 느꼈다.. 구글링을 열심히 하며 논문등을 찾아 읽어보고 부분 부분 코드를 보며 이해해서 짜맞추고.. 이 포스팅을 보는 다른 사람이 조금이나마 도움을 얻길 바라며 🐤

참고로 필자는 머신러닝에 대해 제대로 배운적이 없기 때문에 이 포스팅은 정확한 지식 전달이 목적이 아닌 이해를 돕기 위한 포스팅에 불과하다.

➰➰➰

음성 데이터를 학습 시킬 경우, 그 길이가 다 다르기 때문에 크기를 맞춰줘야 한다. data.shape을 통해 학습시킬 데이터(x_train, x_test)들의 크기와 정답 데이터(Y_train, Y_test)의 크기를 동일하게 맞춰주자. 나는 처음에는 모든 음성 데이터들을 1초 단위로 잘라서 사용했지만 정확도를 높히기 위해 4초로 길이를 수정했다.

머신러닝을 배웠던 사람들에게는 당연할 수도 있겠지만 따로 머신러닝을 배우지 않고 관련 지식이 없던 나에게는 이런 당연한 사실조차 삽질을 해가며 깨우쳤다.. 😂

또한 정답 데이터(Y_train, Y_test)에는 x에 들어있는 파일에 대한 정답(감정 인식의 경우, 해당 파일이 어떤 감정인지)를 알려줘야 하며, 이것 또한 shape이 동일해야 한다.

문자열로 이루어진 감정 라벨들을 인코딩을 통해 숫자로 바꾸어 준다.

크게 어려움을 겪었던 부분은 이정도이다. 이제 코드를 보며 svm 모델을 완성시켜 보자!

🌝 데이터 로드 및 MFCC 추출


이 부분은 이전 포스팅에서 자세하게 다뤘으니 필요시 참고하자.

1

코드를 보면 먼저 학습시킬 데이터가 들어있는 폴더의 경로를 지정한다. 다음으로 dataset에는 MFCC를 통해 추출한 특징 벡터, label에는 음성 파일의 이름에서 감정을 나타내는 부분(anger, happy 등)을 추출해서 저장한다.

_

모든 음성 데이터의 이름이 위와 같이 저장되어있어서 split함수를 통해 필요한 부분을 잘라내어 사용했다.

따라서 dataset과 label에는 하나의 음성 데이터에 대한 특징 벡터(학습 시킬 데이터, x)와 그에 대한 정답(Y)이 같은 인덱스를 가지고 저장된다.

🔖 라벨 인코딩


위의 label 배열에 담아둔 감정을 라벨 인코딩 과정을 통해 수치형 데이터로 바꿔주자. sklearn.preprocessingLabelEncoder를 사용했다.

2

🎢 모델 학습시키기


3

먼저 학습 데이터와 훈련 데이터를 나누고, 커널을 설정한다.

이때, 데이터 전처리 과정을 통해 보다 성능을 높일 수 있다. 데이터가 매우 크거나, 값이 일정한 범위 내에 있지 않는 경우 스케일링 조정이 필수다!

스케일러는 StandardScaler, MinMaxScaler, QuantileTransformer등이 있으며, 여러가지를 모두 테스트한 결과 MinMaxScaler가 가장 성능이 좋아서 이걸 사용했다.

커널을 결정한 뒤에 C와 gamma값을 조절해 최적화를 해주어야 하는데, 간단하게 설명하자면, C와 gamma 값이 커질수록 결정 경계가 굴곡지고(over fitting의 가능성) 작아질수록 결정 경계는 직선에 가까워진다(under fittin의 가능성). 이 두개의 파라미터를 적절하게 조절해 성능을 높여야 한다.

GridSearchCV등을 사용해 최적화 된 인자를 찾는 방법도 있으며, 필자는 C=10, gamma는 default를 사용했다.

5

오랜 시간의 시행착오와 삽질 끝에 정확도 약 82%를 얻어냈다😍 (데이터 전처리도 없이, 음성 길이 1,2 초 정도로 돌렸을 때는 60% 정도 나왔었다.)

학습된 모델 저장하고 내보내기 - using pickle 🥒

4

pickle을 사용해서 학습된 모델을 pkl 파일로 내보낸 뒤 사용할 수 있다.




# 카테고리