반응형
오늘 학교에서 머신러닝 과목으로 첫 인공지능을 배웠습니다!
K-최근접 이웃(K-Neighbors Classifier) 알고리즘은 여러 데이터에서 가장 가까운 k개의 이웃을 찾아 다수결로 분류하는 방식의 알고리즘입니다.(아마)
어쨋든!
학교에서 수업한 내용은 파이썬으로 되어있지만.. 파이썬은 여러 라이브러리를 통해 쉽게 할 수 있기 때문에.. 이해가 잘 안되는 것 들도 많았습니다..
그래서 최대한 이해하고자 라이브러리가 별로 없는 C++로 진행하고 싶어 만들어봤습니다!
일단 하기전에.. 원래는 그래프로 직접 보기 위해 Matplotlib C++를 가져올려 했으나.. 버전이 너무 오래 되어 불가능 했습니다.. 그래서 직접 만들고자 했지만.. 함수화 하는 과정에서 너무 어려워져 제쳐두었습니다. 위 사진은 시도한 흔적입니다.
아래 데이터셋을 이용!
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0,
31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0,
35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0,
500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0,
700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]
smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]
설명을 딱히 하긴 어렵지만.. 일단 구현이 안된건 score()입니다.. 어떤 식으로 구현해야할지 감이 안잡혀서.. 하하;;
어쨌든 아래 코드를 오늘 수업한 내용 과정 그대로 C++로 옮겨보았습니다! 2개의 데이터와 1개의 정답으로 벡터를 만들어 2개의 데이터와 예측 데이터로 유클리드 거리를 사용해서 거리 값을 구해 k개의 가까운 거리 값을 뽑아 어떤 것이 더 큰지 찾는 코드입니다!
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//거리 기준으로 오름차순 정렬을 하기 위한거
bool cmp(vector<double> x, vector<double> y) {
return x[3] < y[3];
}
int main() {
//데이터 정의
vector<double> bream_length = {
25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0,
31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0,
35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0
};
vector<double> bream_weight = {
242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0,
500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0,
700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0
};
vector<double> smelt_length = {
9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0
};
vector<double> smelt_weight = {
6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9
};
vector<double> length, weight;
//bream과 smelt 데이터를 나란히 이어 붙이는 코드
length.insert(length.end(), bream_length.begin(), bream_length.end());
length.insert(length.end(), smelt_length.begin(), smelt_length.end());
weight.insert(weight.end(), bream_weight.begin(), bream_weight.end());
weight.insert(weight.end(), smelt_weight.begin(), smelt_weight.end());
//length와 weight 데이터를 하나의 자료형에 때려 박는거
vector<vector<double>> fish_data;
for (int i = 0; i < length.size(); i++)
fish_data.push_back({ length[i], weight[i] });
//확인용
if(0)
for (int i = 0; i < length.size(); i++)
cout << fish_data[i][0] << "\t" << fish_data[i][1] << endl;
//정답 데이터 생성
vector<int> fish_target;
for (int i = 0; i < bream_length.size(); i++) fish_target.push_back(1);
for (int i = 0; i < smelt_length.size(); i++) fish_target.push_back(0);
//확인용
if (0)
for (int i = 0; i < fish_target.size(); i++)
cout << fish_target[i] << " ";
//kn 모델 정의(그냥 데이터와 정답데이터 붙이는거임)
int k = 5;
vector<vector<double>> kn;
for (int i = 0; i < fish_data.size(); i++)
kn.push_back({ fish_data[i][0], fish_data[i][1], double(fish_target[i]) });
//확인용
if (0)
for (int i = 0; i < length.size(); i++)
cout << kn[i][0] << "\t" << kn[i][1] << "\t" << kn[i][2] << endl;
//예측
//30, 600으로
double p1 = 30, p2 = 600;
//유클리드 거리 공식을 이용해서 거리를 구하고 kn벡터에 삽입하고 거리 기준으로 정렬하여 상위 k개를 뽑아서 누가 더 큰지 비교한다.
for (int i = 0; i < kn.size(); i++)
kn[i].push_back(sqrt(pow((kn[i][0] - p1), 2) + pow((kn[i][1] - p2),2)));
sort(kn.begin(), kn.end(), cmp);
//확인용
if (true)
for (int i = 0; i < length.size(); i++)
cout << kn[i][0] << "\t" << kn[i][1] << "\t" << kn[i][2] << "\t" << kn[i][3] << endl;
int bream_c = 0, smelt_c = 0;
for (int i = 0; i < k; i++) {
(kn[i][2] == 1 ? bream_c++ : smelt_c++);
}
cout << (bream_c > smelt_c ? "이건 bream임" : "이건 smelt임") << endl;
}
암튼 끝!
반응형