MATLAB 환경에서 K-Fold 교차 검정을 적용한 SVM 회귀 모델 최적화 및 예측 구현

데이터 예측 및 회귀 분석 분야에서 서포트 벡터 머신(SVM)은 뛰어난 일반화 성능을 발휘하는 알고리즘입니다. 특히 SVM의 성능은 패널티 파라미터(C)와 커널 파라미터(gamma)와 같은 하이퍼파라미터 설정에 크게 의존합니다. K-Fold 교차 검정을 결합하면 데이터의 분포를 더 정확하게 반영하며 과적합을 방지하고 최적의 파라미터를 안정적으로 도출할 수 있습니다. 본 글에서는 MATLAB와 LIBSVM 라이브러리를 활용하여 K-Fold 교차 검정 기반의 SVM 회귀 예측 모델을 구현하고 하이퍼파라미터를 최적화하는 과정을 다룹니다.

전체 아키텍처 및 프로세스

구현의 핵심은 그리드 서치(Grid Search)와 K-Fold 교차 검정을 결합하여 최적의 C와 gamma 값을 탐색하는 것입니다. 전체 프로세스는 데이터를 로드하고 특성과 타겟을 분리하는 메인 스크립트와, 실제 파라미터 탐색 및 모델 검증을 수행하는 함수로 구성됩니다. 최신 MATLAB 문법에 맞춰 데이터 I/O 방식을 개선하고, LIBSVM의 회귀 옵션을 명시적으로 지정하여 코드의 안정성을 높였습니다.

메인 스크립트 구현

메인 스크립트는 외부 데이터 세트를 불러오고, 특성과 타겟 변수를 정의한 후 파라미터 최적화 함수를 호출하는 역할을 합니다. 기존에 사용되던 xlsread 대신 더 효율적이고 권장되는 readmatrix 함수를 사용합니다.

% SVM 회귀 예측을 위한 메인 실행 스크립트
clear; clc; close all;

% 데이터 로드 (최신 MATLAB 함수 사용)
dataset = readmatrix('regression_dataset.xlsx');

% 특성 변수(X)와 타겟 변수(Y) 분리
predictors = dataset(:, 1:end-1);
responses = dataset(:, end);

% K-Fold 교차 검정 폴드 수 설정
kFolds = 5;

% 최적 파라미터 탐색 및 모델 평가 함수 호출
[optC, optGamma, minMSE] = findOptimalSVMParams(predictors, responses, kFolds);

% 최적화 결과 출력
fprintf('파라미터 탐색 완료\n');
fprintf('최적 패널티 파라미터 (C)    : %.4f\n', optC);
fprintf('최적 커널 파라미터 (gamma)  : %.4f\n', optGamma);
fprintf('최소 평균 제곱 오차 (MSE)   : %.4f\n', minMSE);

위 코드에서 readmatrix는 Excel 파일의 수치형 데이터를 매트릭스 형태로 빠르게 읽어옵니다. 데이터의 마지막 열을 종속 변수(responses)로, 나머지 열을 독립 변수(predictors)로 할당합니다. kFolds 변수를 통해 교차 검정의 분할 수를 정의하며, 일반적으로 5 또는 10으로 설정합니다.

하이퍼파라미터 최적화 및 교차 검정 함수

파라미터 탐색 함수는 로그 스케일의 검색 공간을 정의하고, 모든 파라미터 조합에 대해 K-Fold 검증을 수행하여 평균 제곱 오차(MSE)가 가장 낮은 조합을 선택합니다. LIBSVM의 svmtrain 함수에서 회귀 모델을 의미하는 -s 3 (epsilon-SVR) 옵션과 RBF 커널을 의미하는 -t 2 옵션을 명시합니다.

function [bestC, bestGamma, bestMSE] = findOptimalSVMParams(X, Y, folds)
    % 하이퍼파라미터 검색 공간 정의 (로그 스케일 그리드)
    cValues = logspace(-1, 3, 5);
    gammaValues = logspace(-3, 1, 5);
    
    % 파라미터 그리드 생성
    [CGrid, GammaGrid] = meshgrid(cValues, gammaValues);
    
    % 최적값 초기화
    bestMSE = inf;
    bestC = CGrid(1);
    bestGamma = GammaGrid(1);
    
    numSamples = size(X, 1);
    
    % K-Fold 인덱스 사전 생성 (모든 파라미터 조합에 동일한 폴드 적용)
    indices = crossvalind('Kfold', numSamples, folds);
    
    % 그리드 서치 반복문
    for idx = 1:numel(CGrid)
        currentC = CGrid(idx);
        currentGamma = GammaGrid(idx);
        
        foldMSE = zeros(folds, 1);
        
        for f = 1:folds
            % 훈련 세트와 검증 세트 인덱스 분리
            trainIdx = (indices ~= f);
            testIdx = (indices == f);
            
            % LIBSVM 옵션 설정 (회귀: -s 3, RBF 커널: -t 2, 조용히 실행: -q)
            options = sprintf('-s 3 -t 2 -c %f -g %f -q', currentC, currentGamma);
            
            % 모델 학습
            model = svmtrain(Y(trainIdx), X(trainIdx, :), options);
            
            % 검증 세트를 활용한 예측
            [predY, ~, ~] = svmpredict(Y(testIdx), X(testIdx, :), model, '-q');
            
            % 현재 폴드의 MSE 계산
            foldMSE(f) = mean((predY - Y(testIdx)).^2);
        end
        
        % 전체 폴드의 평균 MSE 도출
        avgMSE = mean(foldMSE);
        
        % 최소 MSE 및 최적 파라미터 업데이트
        if avgMSE < bestMSE
            bestMSE = avgMSE;
            bestC = currentC;
            bestGamma = currentGamma;
        end
    end
end

이 함수에서는 meshgrid를 사용하여 C와 gamma의 모든 조합을 매트릭스 형태로 생성한 후, 1차원 인덱싱으로 순회합니다. 또한 crossvalind를 반복문 외부에서 한 번만 호출하여, 모든 파라미터 조합이 동일한 데이터 분할을 기반으로 평가되도록 보장합니다. 이는 평가의 일관성을 유지하는 중요한 요소입니다.

LIBSVM 호출 시 -q 플래그를 추가하여 콘솔에 출력되는 불필요한 로그를 억제함으로써 대규모 그리드 서치 시 실행 속도와 가독성을 향상시켰습니다. 최종적으로 검증된 최적의 파라미터와 해당 파라미터에서의 평균 MSE를 메인 스크립트로 반환합니다.

태그: Matlab SVM Libsvm KFoldCrossValidation Regression

7월 13일 18:07에 게시됨