引言
最小距离分类器:它将各类训练样本划分成若干子类,并在每个子类中确定代表点。未知样本的类别则以其与这些代表点距离最近做决策。该方法的缺点是所选择的代表点并不一定能很好地代表各类,其后果将使错误率增加
最近邻法
- 最近邻分类器(nearest neighborhood classifier, nnc): 最小距离分类器的一种极端的情况,以全部训练样本作为代表点,计算测试样本与所有样本的距离,并以最近邻者的类别作为决策。
- 最初的近邻法是由Cover和Hart于1968年提出的,随后得到理论上深入的分析与研究,是非参数法中最重要的方法之一。
- 最近邻法,将与测试样本最近邻样本的类别作为决策的结果
k-近邻法
- k-近邻法:最近邻法的扩展其基本规则是,在所有N个样本中找到与测试样本的k个最近邻者,其中各类别所占个数表示成ki,i=1,...,c.定义判别函数为gi(x)=ki,i=1,2,..,c
- k-近邻一般采用k为奇数,跟投票表决一样,避免因两种票数相等而难以决策
- 决策规则为各个类别所占个数最大的作为决策结果
改进的近邻法
近邻法的一个严重问题是需要存储全部的训练样本,以及繁重的距离计算量。
两种改进的方法:
- 一种是对样本集进行组织与整理,分群分层,尽可能将计算压缩到在接近测试样本邻域的小范围内,避免盲目地训练样本集中每个样本进行距离计算
- 另一种则是在原有样本集中挑选出对分类计算有效的样本,使样本总数合理地减少,以同时达到即减少计算量,又减少存储量的双重效果
快速搜索近邻法
快速搜索近邻法,包括两个阶段:
- 样本集的分级分解
- 搜索
其基本思想是将样本集按邻近关系分解成组,给出每组的质心所在,以及组内样本至该质心的最大距离。这些组又可形成层次结构,即组又分子组,因而待识别样本可将搜索近邻的范围从某一大组,逐渐深入到其中的子组,直至树的叶节点所代表的组,确定其相邻关系。这种方法着眼于只解决减少计算量,但没有达到减少存储量的要求。
import numpy as np
X = np.random.randn(200,2)
X[:100] *= 2
X[:100] += 5
X[100:] -= 6
y = np.zeros(200)
y[100:] = 1
index_random = np.random.permutation(200)
X = X[index_random]
y = y[index_random]
X_tr = X[:160]
y_tr = y[:160]
X_te = X[160:]
y_te = y[160:]
class NearestNeighbor(object):
def __init__(self):
pass
def train(self, X, y):
self.Xtr = X
self.ytr = y
def predict(self, X):
N = X.shape[0]
D_tr = self.Xtr.shape[0]
Ypred = np.zeros(N, dtype=self.ytr.dtype)
dists = np.zeros((N, D_tr))
for i in range(N):
for j in range(D_tr):
dists[i,j] = np.sum(np.abs(self.Xtr[j,:]-X[i,:]))
# 欧式距离的一层循环计算
for i in range(N):
dists[i] = np.sum(np.abs(self.Xtr - X[i]), axis=1)
# 欧式距离的无循环计算
dists = np.sqrt(-2 * np.dot(X, self.Xtr.T) + np.sum(np.square(self.Xtr), axis=1)
+ np.transpose([np.sum(np.square(X), axis=1)]))
min_index = np.argmin(dists, axis=1)
Ypred = self.ytr[min_index]
return Ypred
nn = NearestNeighbor()
nn.train(X_tr, y_tr)
Ypred = nn.predict(X_te)
p = sum(y_te == Ypred)/float(y_te.shape[0])
print(p)