OpenCV3를 사용한 Random Trees

기계학습계에서 활발한 랜덤숲은 일반적으로 R, scikit-learn에 설치되지만, 다음과 같은 이유로 오픈CV3에서 사용하기로 했다.
• C++에서 다른 모듈과 협업
・ 이미지 데이터를 학습하고 OpenCV를 통해 처리
• 다른 C++ 라이브러리도 있지만 가져오기 환경이 번거롭다
그러나 OpenCV3 버전의 랜덤 숲 랜덤트리스에 대한 일본어 정보는 거의 없고, 참고 자료도 설치와 무엇이 다릅니까(Rtrees: Param은 존재하지 않습니까?)힘들기 때문에 총결산의 메모가 되었다.
데이터 준비(ml:TrainData)
우선 데이터의 준비 작업이다.데이터 클래스로 사용되는 TrainData는 RandomTrees뿐만 아니라 다른 ml 모듈에도 사용할 수 있습니다.
csv 파일에서 읽기
csv 파일에서 학습 데이터를 TrainData 클래스로 읽습니다.csv 파일은 다음과 같이 각 샘플의 특징량 벡터 배열 형식입니다.여기는 첫 번째 열을 라벨로 하지만, 임의의 열일 수도 있습니다.

다음 loadFromcSV를 사용하여 읽습니다.
Ptr<TrainData> loadFromCSV(const String& filename, int headerLineCount, int responseStartIdx=-1, int responseEndIdx=-1, const String& varTypeSpec=String(), char delimiter=',', char missch='?')
  • filename: csv 파일 경로
  • headerLinkeCount: 머리글을 무시할 행 수를 지정합니다. #시작할 때 자동으로 무시된다.
  • responseStartIdx: 태그의 색인을 지정합니다.기본적으로 마지막 항목은 태그입니다.
  • responseEndIdx: 태그의 끝 색인을 지정합니다.기본값은 1 변수의 레이블입니다.
  • varTypeSpec: 변수가 연속값인지 카테고리인지 지정합니다.
  • 탭 변수를 분류하고 연속값으로 설정하면 회귀 문제가 된다.
  • 기본적으로 태그가 1 변수인 경우 정수 문자열의 경우 분류(범주), 그렇지 않으면 회귀(연속값)입니다.
  • "ord"로 지정하면 모두 연속값으로 읽습니다.
  • "cat"으로 지정하면 모두 클래스로 읽습니다.
  • 연속값, 종류를 혼합하고 지정하는 상황에서'ord[0,3-4],cat[1-2]'처럼 각 인덱스를 지정한다.
  • delimiter:csv 파일의 구분자입니다.기본값은, 로 구분됩니다.
    (※ 반각 공백이 있으면 강제로 구분되기 때문에 1변수의 표시에는 반각 공백이 필요하지 않습니다.)
  • 상기 csv 데이터는 다음과 같이 읽습니다.태그가 첫 번째 열이므로 responseStartIdx=0으로 설정합니다.
    string filename = "sample.csv";
    Ptr<TrainData> data = TrainData::loadFromCSV(filename, 0, 0, -1);
    
    메모리에서 읽기
    이미지 그룹에서 특징을 추출하고 메모리에서 데이터 집합을 생성할 때create로TrainData를 만들 수 있습니다.
    Ptr<TrainData> create(InputArray samples, int layout, InputArray responses, InputArray varIdx=noArray(), InputArray sampleIdx=noArray(), InputArray sampleWeights=noArray(), InputArray varType=noArray())
    
  • samples: 변수 벡터(특징량)를 입력하는flat형 데이터 배열.상기 csv 데이터의 라벨을 제외하고는
  • layout: 샘플 방향.csv 데이터가 같으면 ROWSAMPLE로 지정하면 각 행에서 샘플을 읽습니다.줄을 서고 싶으면 콜.SAMPLE.
  • responses: 출력 변수(라벨)의 데이터 배열.ROW_SAMPLE의 경우 샘플 수×1로 나열됩니다.flat형이면 연속값(회귀 문제)이 기본값입니다.
  • varIdx: 학습에 사용되는 변수의 인덱스입니다.다 쓰면 무시해.
  • sampleIdx: 학습에 사용되는 샘플 인덱스.다 쓰면 무시해.
  • varType: 변수가 연속값인지 카테고리인지 여부를 지정합니다.특징 변수의 수량>+<라벨의 수량>의 uchar형 열을 배열합니다.연속값 변수의 인덱스에 0을 지정하고, 분류에 1을 지정합니다.
  • 데이터 방향과 분류에 주의를 기울여도 복귀는 문제없다.
    학습, 테스트 데이터 분할
    setTrainTest SplitRatio를 사용하면 TrainData 내에서 학습용과 테스트용을 분리하여 평가할 수 있습니다.
    void TrainData::setTrainTestSplitRatio(double ratio, bool shuffle=true)
  • ratio: 학습용에 분배되는 비율.총 데이터 수×ratio가 학습 데이터 수가 되다.
  • ratio가 0일 때는 할당할 수 없습니다.1.0에서 오류가 발생할 수 있습니다. 주의하십시오.
  • shuffle: 기본적으로 무작위로 분배를 혼란시킵니다.
  • Random Trees(ml::RTrees)
    데이터가 준비되면 공부를 시작합시다.
    초기화
    Rtrees의create 함수로 초기화합니다.Ptr<RTrees> rtrees = RTrees::create();매개변수 설정
    학습 매개 변수를 설정하는 중입니다.
    rtrees->setMaxDepth(5);
    rtrees->setMinSampleCount(2);
    rtrees->setCalculateVarImportance(true);
    rtrees->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 100, 0.1));
    
  • setMaxDepth: 나무의 최대 깊이는 말할 것도 없이
  • setMinsampleCount: 잎 노드의 최소 샘플 수
  • setCalcVarImportance: 변수의 중요성을 계산하는 데 사용되는 플래그입니다.를 연 후 변수를 분석할 수 있습니다.(랜덤 수박)
  • setTermcriteria: 합성기 트리의 정지 조건.
  • MAX_ITER: 트리의 최대 개수
  • EPS: OOB 오류 임계값
  • 다른 매개 변수도 많지만 기본적으로 제어하면 좋지 않아요.
    배우다
    데이터가 준비된 TrainData를 매개 변수로 학습을 시작합니다.
    rtrees->train(data);
    
    평점
    TrainData로 setTrainTest SplitRatio를 설정하면 학습, 테스트 데이터를 각각 평가할 수 있습니다.
    calcError 함수에TrainData와 로고(학습:가짜, 테스트:진짜)를 첨가하여 평가합니다.
    printf("train error: %f\n", rtrees->calcError(data, false, noArray()));
    printf("test error: %f\n\n", rtrees->calcError(data, true, noArray()));
    
    분류 문제 중 오류율(%)은 회귀 문제에서 RMS가 평가한다.
    저장 및 읽기
    공부가 끝난 후 save 함수로 저장하세요.
    rtrees->save("rtree_model.xml");
    
    마찬가지로load 함수로 읽을 수 있습니다.
    Ptr<RTrees> rtrees = RTrees::load<RTrees>("rtree_model.xml");
    
    어림잡다
    마지막으로 추측입니다.
    이번 예에서 ROW 배열에서 추정하고자 하는 특징 벡터를predict 함수에 저장하면 추측 결과를 되돌려줍니다.
    아래의 예에서 TrainData의 샘플을 얻어 각 샘플을 추측 처리한다.
    Mat samples = data->getSamples();
    
    for (int i = 0; i < samples.rows; i++) {
        Mat sample = samples.row(i);
    
        float result = rtrees->predict(sample);
    
        cout << "index:" << i << ", predict:" << result <<endl;
    }
    
    여러 견본을 총괄적으로 평가할 수 있지만, 두 번째 파라미터에서 결과를 받는 그룹을 지정해야 한다.
    Mat results;
    float result = rtrees->predict(samples, results);
    
    이곳의 반환 값은 최초의 견본의 평가 결과일 뿐이기 때문에 특별한 의미가 없다.
    보충: 공부할 때의 오류
    샘플의 학습 데이터를 이용하여 실험을 진행할 때 입력 변수와 출력 변수(라벨)를 분류하면 오류가 발생할 수 있습니다.

    학습 트리의 서브집합에서 출력 변수에 대해 최소한 견본이 하나도 없으면 예외가 발생하는 것 같다.
    즉, 라벨이 A, B 두 개면 서브집합 안의 모든 샘플이 A 라벨이면 오류가 발생한다.
    OpenCV의 규격이라 어쩔 수 없지만, 서브집합의 샘플 수가 적으면 쉽게 발생할 수 있으므로 데이터 양을 늘리는 것이 좋으며, 입력 변수인지 출력 변수인지 실제 수치로 설정하는 것이 좋다.
    말하자면 이미지 데이터로 학습하면 특징량은 실수이고 CV로도 괜찮겠지...(그래도 입력 변수에서 분류가 허용될 때 이상하게 느껴질 수 있다)
    데이터 발굴성 이용은 R과 scikit-learn이 좋아요?

    좋은 웹페이지 즐겨찾기