предисловие
本文从2个方面讲解knn算法的实战。
<1>完全自己coding代码
<2>通过sklearn这个扩展包
Код, полностью написанный вами
import numpy as np
import operator
# 读取已知类别的数据集合
def createDataSet():
# dataset - 数据集合,只有2个特征
# 列表形式-->数组形式
dataset = np.array( [ [1,101],
[5,89],
[108,5],
[115,8] ] )
# 标签
labels = ['爱情片','爱情片','动作片','动作片']
return dataset, labels
def classify(input_data, dataset, labels, k):
# input_data - 待分类数据,只包含特征数据,没有标签
# dataset - 已知类别的数据集合的特征值
# labes - 已知类别的数据集合的类别
# k - kNN算法参数,选择距离最小的k个点,人为规定k值
dataset_size = dataset.shape[0] # 得到数据集合的行数
diffMat = np.tile(input_data, (dataset_size, 1)) - dataset 把待分类数据,复制成和数据集合相同行数的array,然后2个array相减,
sqDiffMat = diffMat**2 # 二维特征相减后平方
sqDistances = sqDiffMat.sum(axis=1) # sum()所有元素相加,sum(0)列相加,sum(1)行相加
distances = sqDistances**0.5 # 开根号
# 返回distances中元素从小到大排序后的索引值
# 及对距离进行升序排序
sortedDistIndices = distances.argsort()
# 定义一个空字典
# 对最近邻中的各条基准数据的类型进行统计
classCount = dict()
for i in range(k):
# 取出前k个元素的类别
voteIlabel = labels[ sortedDistIndices[i] ]
# 计算类别出现的次数
# 如果没有出现过,就是1,如果已经出现过,就是在原来的基础上加1
classCount[voteIlabel] = classCount.get(voteIlabel,1) + 1
# 字典排序
# 从大到小排序
sortedClassCount = sorted(classCount.items(),
key=operator.itemgetter(1),
reverse=True)
# 返回次数最多的类别,即所要分类的类别
# 第0个kv对的k,就是待预测数据的标签label
return sortedClassCount[0][0]
if __name__ == '__main__':
# 创建数据集
dataset, labels = createDataSet()
# 测试集
test = [101,20] # 待分类的数据
# kNN分类
test_class = classify0(test, dataset, labels, 3) # 从就最小的前3个类别中
# 打印分类结果
print(test_class)
Используйте пакет расширения sklearn
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
np.random.seed(0)
# 加载数据
iris = datasets.load_iris()
# 特征数据
# 样本数据150*4二维数据,代表150个样本,每个样本4个属性分别为花瓣和花萼的长、宽
iris_x= iris.data
# 标签数据
# 长150的以为数组,样本数据的标签
iris_y = iris.target
# 打乱顺序
# permutation()接收一个数作为参数(150),产生一个0-149一维数组,只不过是随机打乱的,
# 当然她也可以接收一个一维数组作为参数,结果是直接对这个数组打乱
indices = np.random.permutation(len(iris_x))
# 划分训练集合和测试集合
# 前140条数据是训练数据,后10条数据是测试数据
iris_x_train = iris_x[indices[:-10]]
iris_y_train = iris_y[indices[:-10]]
iris_x_test = iris_x[indices[-10:]]
iris_y_test = iris_y[indices[-10:]]
# 初始化一个knn分类器对象
# 在KNeighborsClassifier类的初始化的时候,有几个参数可以指定,
n_neighbors=5
int 型参数,
knn算法中指定以最近的几个最近邻样本具有投票权,默认参数为5
weights='uniform'
str参数,即每个拥有投票权的样本是按什么比重投票,
'uniform'表示等比重投票,
'distance'表示按距离反比投票,及距离越小,权重越大,及话语权越大。这个是对于数据分布不均衡的情况的
默认参数为‘uniform’
knn = KNeighborsClassifier()
# 用训练数据进行模型的训练
knn.fit(iris_x_train, iris_y_train)
# 用测试数据进行测试
# predict()方法直接给出最后的类别
iris_y_predict = knn.predict(iris_x_test)
# predict_proba()方法给出属于各个类别的概率
iris_y_predict_proba = knn.predict_proba(iris_x_test)
# kneighbors()函数是对真实的待预测数据进行预测
neighborpoint = knn.kneighbors(iris_x_test[-1],5,False)
#计算与最后一个测试样本距离在最近的5个点,返回的是这些样本的序号组成的数组
# score()函数,计算出准确率
# 其实这一步就是模型的泛化能力
score = knn.score(iris_x_test,iris_y_test,sample_weight=None)
print('测试 ',iris_y_predict)
# 输出测试的结果
print('iris_y_test = ')
print(iris_y_test)
#输出原始测试数据集的正确标签,以方便对比
print('Accuracy:',score)
# 输出准确率计算结果
print('neighborpoint of last test sample:',neighborpoint)
print('probility:',iris_y_predict_proba)
# 结果输出:
iris_y_predict =
[1 2 1 0 0 0 2 1 2 0]
iris_y_test =
[1 1 1 0 0 0 2 1 2 0]
Accuracy: 0.9
neighborpoint of last test sample: [[ 75 41 96 78 123]]
probility: [[ 0. 1. 0. ]
[ 0. 0.4 0.6]
[ 0. 1. 0. ]
[ 1. 0. 0. ]
[ 1. 0. 0. ]
[ 1. 0. 0. ]
[ 0. 0. 1. ]
[ 0. 1. 0. ]
[ 0. 0. 1. ]
[ 1. 0. 0. ]]