模式识别——KNN K近邻法

模式识别——KNN K近邻法

题目描述

已知7个样本:X1=(1,0), X2=(0,1), X3=(0,-1), X4=(0,0), X5=(0,2), X6=(0,-2), X7=(-2,0), 其中前三个为ω1类,后四个为ω2类。 现有待分类样本X=(0.2,0.3)。

  1. 请使用自己熟悉的语言(如C/C++或Matlab,不能调用现成函数)编程实现k-NN算法,并分别计算当k=1,2,…,7时 上述问题中样本X的类别。
  2. 在上述问题中,当k取偶数时,可能出现两个类别中最近邻样本数相同的问题,请思考并给出此种情形下的解决方法。

1.代码

#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#define N 7
#define k 6
using namespace std;
struct Node {//代表每个样本特征向量
	float x;
	float y;
	int flag;//类别
	float dis;
	bool operator<(const Node& A)const {//
		return dis < A.dis;
	}
}Tree[100];
int loc;//静态数组中被使用的元素
void creat(float x,float y,int flag,Node*m) {//申请结点
	Tree[loc].x = x;
	Tree[loc].y = y;
	Tree[loc].flag = flag;
	Tree[loc].dis = sqrt(pow(m->x - Tree[loc].x,2) + pow(m->y - Tree[loc].y,2));
	loc++;
}
int main() {
	float x, y;
	int flag;
	while (cin >> x >> y) {
		Node* m = new Node;
		m->x = x;
		m->y = y;
		/*for (int i = 0; i < N; i++) {
			
			cin >> x >> y >> flag;
			creat(x, y, flag, m);
		}*/
		creat(1, 0, 1, m);
		creat(0, 1, 1, m);
		creat(0, -1, 1, m);
		creat(0, 0, 2, m);
		creat(0, 2, 2, m);
		creat(0, -2, 2, m);
		creat(-2, 0, 2, m);
		sort(Tree, Tree + N);
		int w1=0;
		int w2=0;
		float dis1=0;
		float dis2=0;
		for (int i = 0; i < k; i++) {
			if (Tree[i].flag == 1) {
				w1++;
							}
			else {
				w2++;
							}
		}
		if (w1 > w2) {
			cout << "该样本属于第一类" << endl;
		}
		else if (w1 < w2) {
			cout << "该样本属于第二类" << endl;
		}
		else if (w1 == w2) {
			cout << "两个类别中最近邻样本数相同" << endl;
			
		}
	}
	return 0;
}

2.答:我的方法:当两个类别中最近邻样本数相同时,就计算被测样本分别与最近的K个样本中的两类样本的总距离,比较总距离,距离哪个类的总距离更近就属于那个类。

#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#define N 7
#define k 6
using namespace std;
struct Node {//代表每个样本特征向量
	float x;
	float y;
	int flag;//类别
	float dis;
	bool operator<(const Node& A)const {//
		return dis < A.dis;
	}
}Tree[100];
int loc;//静态数组中被使用的元素
void creat(float x,float y,int flag,Node*m) {//申请结点
	Tree[loc].x = x;
	Tree[loc].y = y;
	Tree[loc].flag = flag;
	Tree[loc].dis = sqrt(pow(m->x - Tree[loc].x,2) + pow(m->y - Tree[loc].y,2));
	loc++;
}
int main() {
	float x, y;
	int flag;
	while (cin >> x >> y) {
		Node* m = new Node;
		m->x = x;
		m->y = y;
		/*for (int i = 0; i < N; i++) {
			
			cin >> x >> y >> flag;
			creat(x, y, flag, m);
		}*/
		creat(1, 0, 1, m);
		creat(0, 1, 1, m);
		creat(0, -1, 1, m);
		creat(0, 0, 2, m);
		creat(0, 2, 2, m);
		creat(0, -2, 2, m);
		creat(-2, 0, 2, m);
		sort(Tree, Tree + N);
		int w1=0;
		int w2=0;
		float dis1=0;
		float dis2=0;
		for (int i = 0; i < k; i++) {
			if (Tree[i].flag == 1) {
				w1++;
				dis1 += Tree[i].dis;
			}
			else {
				w2++;
				dis2 += Tree[i].dis;
			}
		}
		if (w1 > w2) {
			cout << "该样本属于第一类" << endl;
		}
		else if (w1 < w2) {
			cout << "该样本属于第二类" << endl;
		}
		else if (w1 == w2) {
			cout << "两个类别中最近邻样本数相同" << endl;
			if (dis1 > dis2) {
				cout << "但是新样本距离第二类样本的总距离更短,所以分为第二类" << endl;
			}
			else if (dis1 < dis2) {
				cout << "但是新样本距离第一类样本的总距离更短,所以分为第一类" << endl;
			}
		}
	}
	return 0;
}

发布了12 篇原创文章 · 获赞 12 · 访问量 169

猜你喜欢

转载自blog.csdn.net/xyzxyzxyz1999/article/details/105150947