MED 分类器

实现代码:

MED.h

#include <iostream>
#include <vector>
#include <valarray>
#include <assert.h>
typedef long double real;

template<size_t N>
class vec : public std::valarray<real> {
public:
	vec() {
		assert(N>0);
		resize(N);
	}
	vec(const std::pair<real, real> &p) {
		assert(N>0);
		resize(N);
		(*this)[0]=p.first;
		if(N>1)
			(*this)[1]=p.second;
	}
	real dot(const vec& rhs) const {
		assert(size()==rhs.size());
		real res=0;
		for(int i=size()-1; ~i; --i)
			res+=(*this)[i]*rhs[i];
		return res;
	}
	real len2() const {
		return dot(*this);
	}
	real len() const {
		return sqrtl(len2());
	}
	friend std::ostream& operator << (std::ostream& out, const vec<N> &v) {
		out<<"("<<v[0];
		for(int i=1; i<N; ++i)
			out<<","<<v[i];
		return out<<")";
	}
};

template<size_t N>
class Class {
protected:
	std::vector<vec<N> > spec;
	vec<N> sumvec;

public:
	void add(const vec<N>& obj) {
		spec.emplace_back(obj);
		sumvec+=obj;
	}
	vec<N> mu() const {
		vec<N> v=sumvec;
		for(int i=0, x=spec.size(); i<N; ++i)
			v[i]/=x;
		return v;
	}
	real dis(const vec<N>& obj) const {
		vec<N> now=mu();
		now-=obj;
		return now.len2();
	}
	friend std::ostream& operator << (std::ostream& out, const Class &c) {
		vec<N> m = c.mu();
		return out<<"mu = "<<m<<"\t,size = "<<c.spec.size();
	}
};

template<size_t M, size_t N>
class MED {
	std::vector<Class<N> > c;
public:
	MED() {
		assert(M>1);
		c.resize(M);
	}
	void add(int id, const vec<N>& obj) {
		assert(id<M);
		c[id].add(obj);
	}
	int classified(const vec<N>& obj) const {
		int minid=0;
		real minlen=c[0].dis(obj);
		for(int i=0; i<M; ++i) {
			real nowlen=c[i].dis(obj);
			std::cout<<"distance with Class "<<i<<":\t"<<sqrtl(nowlen)<<std::endl;
			if(nowlen<minlen) {
				minlen=nowlen;
				minid=i;
			}
		}
		return minid;
	}
	friend std::ostream& operator << (std::ostream& out, const MED &m) {
		for(int i=0; i<M; ++i)
			out<<"Class "<<i<<":\n\t"<<m.c[i]<<"\n";
		return out;
	}
};

测试代码:

test.cpp

#include <iostream>
#include <map>
#include "MED.h"

class Test {
	MED<2, 2> med;
public:
	Test() {
		load();
		std::cout<<med<<std::endl;
	}
	int classified(const vec<2>& v) {
		return med.classified(v);
	}
	void load() {
		std::map< std::pair<real, real> , int> train;
		
		train[std::make_pair(1, 4)]=1;
		train[std::make_pair(7, 0)]=1;
		train[std::make_pair(3.5, 1)]=1;
		train[std::make_pair(4.5, 3)]=1;
		
		train[std::make_pair(4, 4)]=0;
		train[std::make_pair(8, 5)]=0;
		train[std::make_pair(8, 3)]=0;
		train[std::make_pair(12, 4)]=0;
		
		for(auto [v, t] : train)
			med.add(t, v);
	}
}test;

int main() {
	vec<2> v=std::pair<real, real>(4, 5);
	int res = test.classified(v);
	std::cout<<"Belong to Class "<<res<<std::endl;
	return 0;
}

运行结果:

Class 0:

        mu = (8,4)      ,size = 4

Class 1:

        mu = (4,2)      ,size = 4



distance with Class 0:  4.12311

distance with Class 1:  3

Belong to Class 1
posted @ 2022-04-30 23:11  JustinRochester  阅读(105)  评论(0编辑  收藏  举报