K近邻算法
K近邻算法简单概述
K近邻算法采用测量不同特征值之间的距离方法进行分类
该方法的思路是:如果一个样本在特征空间中与k个实例最为相似(即特征空间中最邻近),那么这k个实例中大多数属于哪个类别,则该样本也属于这个类别。
其中,计算样本与其他实例的相似性一般采用距离衡量法。离得越近越相似,离得越远越不相似。
- 优点:精度高,异常值不敏感,无数据输入假定
- 缺点:计算复杂度高,空间复杂度高
- 适用数据范围:数值型和标称型
K近邻简述:遍历计算测试集的每个子集与训练集的距离,然后取距离最近的前K个值,再通过这K个值对应的训练集的标签(多数赞同)来决定这个子集的标签
K近邻算法机器学习实战源码(缺点:参数只能测试集的一个数据与欧氏距离的计算)
def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] # 训练集数据个数4个 diffMat = tile(inX, (dataSetSize, 1)) - dataSet # np.tile函数 # 瓦铺函数 # 将inX的shape为(1,1)的拉伸为(4,2) sqDiffMat = diffMat ** 2 # x^2,y^2 sqDistance = sqDiffMat.sum(axis=1) # x^2+y^2 distances = sqDistance ** 0.5 # 开根 sortedDistIndicies = distances.argsort() # 返回其排序好的索引,索引的取值是由小到大的 classCount = {} # 创建分类字典 for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 相当于 classCount[voteIlabel] = classCount[voteIlabel] +1 # 使用get 是为了键不存在时取值为0而不是None sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) # 最后一步:根据字典的值最多的返回其键 # 字典无序,需要遍历 ,此行代码封装的好,但易读性弱,不建议使用 return sortedClassCount[0][0]
K近邻自改源码(缺点:参数只能为测试集的单一数据)
def classify1(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] # 训练集数据个数 distances = [] for i in range(0,dataSetSize): d = linalg.norm(inX-dataSet[i],ord=2) distances.append(d) distances = array(distances) sortedDistIndicies = distances.argsort() classCount = {} # 创建分类字典 for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 相当于 classCount[voteIlabel] = classCount[voteIlabel] +1 # 使用get 是为了键不存在时取值为0而不是None sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) # 最后一步:根据字典的值最多的返回其键 # 字典无序,需要遍历 ,此行代码封装的好,但易读性弱,不建议使用 return sortedClassCount[0][0]
K近邻自改可适用于一个测试数据集,返回为预测结果
class KNearestNeighbor: def __init__(self): pass def train(self,X,y): self.X_train = X self.y_train = y def predict(self, X, k=1): # 计算L2距离 num_test = X.shape[0] #测试样本个数 num_train = self.X_train.shape[0] #训练样本个数 # because(X - X_train)*(X - X_train) = -2X*X_train + X*X + X_train*X_train, so d1 = -2 * np.dot(X, self.X_train.T) # shape (num_test, num_train) d2 = np.sum(np.square(X), axis=1, keepdims=True) # shape (num_test, 1) d3 = np.sum(np.square(self.X_train), axis=1) # shape (1, num_train) dist = np.sqrt(d1 + d2 + d3) # 根据K值,选择最可能属于的类别 y_pred = np.zeros(num_test) for i in range(num_test): dist_k_min = np.argsort(dist[i])[:k] # dist[i]根据每个测试集i, # 取每个测试集与所有训练集的欧氏距离,返回k个训练集上的索引 # 最近邻k个实例位置 y_kclose = self.y_train[dist_k_min] # 最近邻k个实例对应的标签 y_pred[i] = np.argmax(np.bincount(y_kclose.tolist())) # 找出k个标签中从属类别最多的作为预测类别 return y_pred