KNN
在机器学习中,我们通过训练数据来学习出一个模型,通常我们是先设计模型(Model),通过学习得到模型最优参数。根据有无参数我们可以将模型分为有参数模型和无参数模型。
最近邻算法
基本思想就是看那个已知事物和你未知事物最像就是认为属于该类别,那么计算机是如何判断这里像或者是相似。在接下里介绍 KNN 上计算机通过计算样本的特性间的距离来判断是否相似。那么这就是把 KNN 能够解决的问题进行限制了。首先 KNN 能够解决问题是样本的特征间差异可以用距离来进行衡量。
KNN(K-Nearest Neighbours)K值邻近算法是一个非常简单的算法,这里简单到即使没有任何数据基础也能够很容容易理解KNN算法,常被用于解决分类问题的, 也可以用于解决回归问题。KNN 是非参数的,基于实例的算法。
在统计学中,参数模型通常是假设总体服从某个分布,这个分布可以由一些参数确定,如正态分布由均值和标准差确定,在此基础上构建的模型称为参数模型
常见的参数机器学习模型有:
1、逻辑回归(logistic regression)
2、线性成分分析(linear regression)
3、感知机(perceptron)
非参数模型对于总体的分布不做任何假设或者说是数据分布假设自由,只知道其分布是存在的,所以就无法得到其分布的相关参数,只能通过非参数统计的方法进行推断。
常见的非参数机器学习模型有:
1、决策树
2、朴素贝叶斯
3、支持向量机
4、神经网络

对于星型数据按离其距离来取 k 最近点,然后根据这些点那个类别占比例多来进行判断。
K 必须取奇数
k 是否可以取偶数,当 K 为偶数时,如果 K 样本数据两个不同类别的样本点各占一半,不是无法对新样板点所属类别进行推测了吗。其实可以通过这些样本到新样本的距离作为辨别条件,来进一步推测样本点类别。
K 取值的技巧
如果 k 取 1 在训练集模型会记住每一个样本,就发生过拟合。如果 K 选取无穷大,那么就变成哪个点多就把任何测试样本分为哪个样本数据多的类别。

任何两个点之间连接连线,中点做垂线可以将整个区域划分若干个小块,每一小块属于整个点领地,只要数据落在其领域就是和该数据同样的类别。扩展到多维空间,就不再是中线而是中间的垂直的面作为分隔面。
KNN 可以解决回归问题
k 近邻可以解决回归问题,这里通过一个实例给大家解释KNN 是如何解决回归问题,我们要估计班级上一个同学的成绩,通常可以通过他的好朋友的成绩加权取平均值来得到这位同学的成绩。也就是我们可以通过临近点的均值或者带有按离推测样本点距离作为权重来计算该样本点的值。
其中最常见的计算各点之间的方法是欧氏距离(Euclidean Distance)。欧氏距离就是计算 N 维空间中两点之间的距离。
KNN 间距
那么在 KNN 中距离需要满足下面的条件
- 距离需要满足对称关系,也就是 d(A,B) = d(B,A) 也就是 A 到 B 的距离等于 B 到 A 的距离
- d(A,A) = 0 样本点到自己本身的距离为 0 也就是自己和自己是最相似的。
- d(A,B) = 0 iff A = B 还要满足只有和自己的距离才为 0 ,到其他点距离都不是 0
- 距离需要满足三角不等式 d(A,B) <= d(A,C) + d(B,C)
只有距离满足以上条件的,我们才可以用 KNN 进行计算
距离(模)
距离公式开起来有点数据,其实就是向量的模
- 欧氏距离(L_2)
- 曼哈顿距离(L_1)
所谓曼哈顿距离,有许多街区是沿着街区进行移动从 A 到 B 点,也就是分别求 x 和 y 距离进行相加
- 切比雪夫距离(L_r)
这几个公式满足上面计算距离的条件
- 汉明距离(hamming distance)
通过异或运算,来判断两个二进制数据间的距离 - consine similarity
from sklearn.datasets import *
boston = load_boston()
boston.keys()
dict_keys(['data', 'target', 'feature_names', 'DESCR', 'filename'])
查看数据
import pandas as pd
bos = pd.DataFrame(boston['data'])
bos.columns = boston['feature_names']
bos['Price'] = boston['target']
bos.head()

price 是我们要估计的特征值
from sklearn.neighbors import KNeighborsRegressor
train_x = boston['data'][:500]
train_y = boston['target'][:500]
KNR = KNeighborsRegressor(20)
KNR.fit(train_x,train_y)
import numpy as np
test = np.array(boston['data'][501])
test1 = test.reshape(1,-1)
test1
bos.ix[500:]

/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning:
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing
See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated
"""Entry point for launching an IPython kernel.
KNR.predict(test1)
array([24.175])
import matplotlib.pyplot as plt
data_dir = 'data/'
def load_data(data_dir,train_row):
train = pd.read_csv(data_dir + 'train.csv')
print(train.shape)
X_train = train.values[0:train_row,1:] #
y_train = train.values[0:train_row,0]
Pred_test = pd.read_csv(data_dir + 'test.csv').values
Pred_test = Pred_test[:train_row]
return X_train, y_train, Pred_test
train_row = 5000
Origin_X_train,Origin_y_train,Origin_X_test = load_data(data_dir,train_row)
(42000, 785)
print(Origin_X_train.shape,Origin_y_train,Origin_X_test.shape)
(5000, 784) [1 0 1 ... 8 7 9] (5000, 784)
可视化数据集
row = 7
print(Origin_y_train[row])
plt.imshow(Origin_X_train[row].reshape(28,28))
plt.show()
3

classes = ["0","1","2","3","4","5","6","7","8","9"]
rows = 4
for y, cls in enumerate(classes):
idxs = np.nonzero([i == y for i in Origin_y_train])
idxs = np.random.choice(idxs[0],rows)
for i, idx in enumerate(idxs):
plt_idx = i * len(classes) + y + 1
plt.subplot(rows,len(classes),plt_idx)
plt.imshow(Origin_X_train[idx].reshape((28,28)))
plt.axis('off')
if i == 0:
plt.title(cls)
plt.show()

from sklearn.model_selection import train_test_split
X_train,X_vali,y_train,y_vali = train_test_split(Origin_X_train,Origin_y_train,test_size=0.2,random_state=0)
print(X_train.shape,X_vali.shape,y_train.shape,y_vali.shape)
(4000, 784) (1000, 784) (4000,) (1000,)
import time
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.neighbors import KNeighborsClassifier
ans_k = 0
k_range = range(1,8)
scores = []
for k in k_range:
print('k = ' + str(k) + ' begin')
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(X_train,y_train)
y_pred = knn.predict(X_vali)
acc = accuracy_score(y_vali,y_pred)
scores.append(acc)
print(classification_report(y_vali,y_pred))
print(confusion_matrix(y_vali,y_pred))
k = 1 begin
precision recall f1-score support
0 0.96 0.98 0.97 103
1 0.90 0.98 0.94 100
2 0.97 0.88 0.92 104
3 0.89 0.93 0.91 100
4 0.93 0.93 0.93 107
5 0.95 0.88 0.92 94
6 0.93 0.97 0.95 93
7 0.92 0.94 0.93 116
8 0.89 0.85 0.87 85
9 0.85 0.85 0.85 98
micro avg 0.92 0.92 0.92 1000
macro avg 0.92 0.92 0.92 1000
weighted avg 0.92 0.92 0.92 1000
[[101 0 0 1 0 0 1 0 0 0]
[ 0 98 0 1 0 0 0 0 0 1]
[ 0 1 91 2 2 0 1 2 3 2]
[ 0 0 1 93 0 1 0 1 3 1]
[ 0 0 0 0 99 0 1 0 0 7]
[ 0 2 1 3 0 83 3 0 2 0]
[ 1 1 0 0 0 0 90 0 1 0]
[ 0 4 0 0 1 0 0 109 0 2]
[ 0 2 1 3 1 3 1 0 72 2]
[ 3 1 0 1 4 0 0 6 0 83]]
k = 2 begin
precision recall f1-score support
0 0.89 0.99 0.94 103
1 0.85 0.99 0.92 100
2 0.94 0.88 0.91 104
3 0.89 0.94 0.91 100
4 0.91 0.99 0.95 107
5 0.94 0.84 0.89 94
6 0.95 0.96 0.95 93
7 0.90 0.91 0.90 116
8 0.93 0.75 0.83 85
9 0.90 0.78 0.84 98
micro avg 0.91 0.91 0.91 1000
macro avg 0.91 0.90 0.90 1000
weighted avg 0.91 0.91 0.90 1000
[[102 0 0 1 0 0 0 0 0 0]
[ 0 99 0 0 0 0 0 0 0 1]
[ 3 2 92 0 0 0 0 2 3 2]
[ 1 0 1 94 0 0 0 1 2 1]
[ 0 0 0 0 106 0 0 0 0 1]
[ 1 3 1 5 1 79 4 0 0 0]
[ 3 1 0 0 0 0 89 0 0 0]
[ 0 7 1 0 2 0 0 105 0 1]
[ 2 3 3 4 1 5 1 0 64 2]
[ 3 1 0 2 7 0 0 9 0 76]]
k = 3 begin
precision recall f1-score support
0 0.94 0.98 0.96 103
1 0.84 0.98 0.90 100
2 0.95 0.88 0.92 104
3 0.94 0.96 0.95 100
4 0.95 0.93 0.94 107
5 0.97 0.89 0.93 94
6 0.92 0.97 0.94 93
7 0.94 0.91 0.92 116
8 0.92 0.82 0.87 85
9 0.86 0.87 0.86 98
micro avg 0.92 0.92 0.92 1000
macro avg 0.92 0.92 0.92 1000
weighted avg 0.92 0.92 0.92 1000
[[101 0 0 0 0 0 2 0 0 0]
[ 0 98 0 0 0 0 1 0 0 1]
[ 1 3 92 1 0 0 0 2 3 2]
[ 0 0 0 96 0 0 0 1 2 1]
[ 0 0 0 0 99 0 1 0 0 7]
[ 0 3 1 2 0 84 3 0 1 0]
[ 2 0 0 0 0 1 90 0 0 0]
[ 0 9 0 0 1 0 0 105 0 1]
[ 1 3 3 2 1 2 1 0 70 2]
[ 3 1 1 1 3 0 0 4 0 85]]
k = 4 begin
precision recall f1-score support
0 0.94 0.98 0.96 103
1 0.87 0.98 0.92 100
2 0.94 0.89 0.92 104
3 0.94 0.93 0.93 100
4 0.94 0.94 0.94 107
5 0.94 0.87 0.91 94
6 0.90 0.98 0.94 93
7 0.91 0.92 0.91 116
8 0.93 0.80 0.86 85
9 0.86 0.83 0.84 98
micro avg 0.92 0.92 0.92 1000
macro avg 0.92 0.91 0.91 1000
weighted avg 0.92 0.92 0.91 1000
[[101 0 0 0 0 0 2 0 0 0]
[ 0 98 0 0 0 0 1 0 0 1]
[ 0 3 93 1 0 0 0 3 3 1]
[ 1 0 1 93 0 0 1 1 2 1]
[ 0 0 0 0 101 0 0 0 0 6]
[ 1 3 1 2 0 82 5 0 0 0]
[ 1 0 0 0 0 1 91 0 0 0]
[ 0 5 0 0 2 0 0 107 0 2]
[ 1 3 3 2 1 4 1 0 68 2]
[ 3 1 1 1 4 0 0 7 0 81]]
k = 5 begin
precision recall f1-score support
0 0.94 0.98 0.96 103
1 0.85 0.98 0.91 100
2 0.97 0.91 0.94 104
3 0.94 0.92 0.93 100
4 0.94 0.93 0.93 107
5 0.92 0.86 0.89 94
6 0.88 0.98 0.93 93
7 0.93 0.90 0.91 116
8 0.93 0.81 0.87 85
9 0.86 0.87 0.86 98
micro avg 0.92 0.92 0.92 1000
macro avg 0.92 0.91 0.91 1000
weighted avg 0.92 0.92 0.91 1000
[[101 0 0 0 0 0 2 0 0 0]
[ 0 98 0 0 0 0 1 0 0 1]
[ 0 3 95 0 0 0 0 2 3 1]
[ 1 0 1 92 0 1 1 1 2 1]
[ 0 0 0 0 99 0 1 0 0 7]
[ 1 3 1 2 0 81 6 0 0 0]
[ 1 0 0 0 0 1 91 0 0 0]
[ 0 7 0 0 3 0 0 104 0 2]
[ 1 3 0 3 1 5 1 0 69 2]
[ 3 1 1 1 2 0 0 5 0 85]]
k = 6 begin
precision recall f1-score support
0 0.95 0.98 0.97 103
1 0.84 0.98 0.90 100
2 0.98 0.90 0.94 104
3 0.92 0.94 0.93 100
4 0.94 0.92 0.93 107
5 0.93 0.87 0.90 94
6 0.89 0.98 0.93 93
7 0.92 0.91 0.91 116
8 0.93 0.79 0.85 85
9 0.85 0.86 0.85 98
micro avg 0.91 0.91 0.91 1000
macro avg 0.92 0.91 0.91 1000
weighted avg 0.92 0.91 0.91 1000
[[101 0 0 0 0 0 2 0 0 0]
[ 0 98 0 0 0 0 1 0 0 1]
[ 0 3 94 1 0 0 0 2 3 1]
[ 0 0 1 94 0 0 1 1 2 1]
[ 0 2 0 0 98 0 1 0 0 6]
[ 1 3 0 2 0 82 5 0 0 1]
[ 1 0 0 0 0 1 91 0 0 0]
[ 0 7 0 0 2 0 0 105 0 2]
[ 1 3 0 4 1 5 1 0 67 3]
[ 2 1 1 1 3 0 0 6 0 84]]
k = 7 begin
precision recall f1-score support
0 0.94 0.98 0.96 103
1 0.83 0.98 0.90 100
2 0.98 0.89 0.93 104
3 0.95 0.92 0.93 100
4 0.95 0.93 0.94 107
5 0.93 0.89 0.91 94
6 0.88 0.97 0.92 93
7 0.90 0.90 0.90 116
8 0.97 0.81 0.88 85
9 0.84 0.87 0.85 98
micro avg 0.92 0.92 0.92 1000
macro avg 0.92 0.91 0.91 1000
weighted avg 0.92 0.92 0.92 1000
[[101 0 0 0 0 0 2 0 0 0]
[ 0 98 0 0 0 0 1 0 0 1]
[ 0 4 93 1 0 0 0 4 1 1]
[ 0 0 1 92 0 1 1 2 1 2]
[ 0 0 0 0 99 0 1 0 0 7]
[ 0 3 0 1 0 84 6 0 0 0]
[ 2 0 0 0 0 1 90 0 0 0]
[ 0 9 0 0 1 0 0 104 0 2]
[ 2 3 0 2 1 4 1 0 69 3]
[ 2 1 1 1 3 0 0 5 0 85]]
scores
[0.919, 0.906, 0.92, 0.915, 0.915, 0.914, 0.915]
plt.plot(k_range,scores)
plt.xlabel('value of K')
plt.ylabel('Testing accuracy')
plt.show()

k = 3
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(Origin_X_train,Origin_y_train)
y_pred = knn.predict(Origin_X_test[:300])
y_pred
array([2, 0, 9, 0, 3, 7, 0, 3, 0, 3, 5, 7, 4, 0, 4, 3, 3, 1, 9, 0, 9, 1,
1, 5, 7, 4, 2, 7, 7, 7, 7, 5, 4, 2, 6, 2, 5, 5, 1, 6, 7, 7, 4, 9,
8, 7, 8, 2, 6, 1, 6, 8, 8, 3, 8, 2, 1, 2, 1, 0, 9, 1, 7, 0, 0, 0,
1, 9, 0, 1, 6, 5, 8, 8, 2, 8, 3, 9, 2, 3, 5, 4, 1, 0, 9, 2, 4, 3,
6, 7, 2, 0, 6, 6, 1, 4, 3, 9, 7, 4, 0, 8, 2, 0, 7, 3, 0, 5, 0, 9,
0, 0, 4, 7, 1, 7, 1, 1, 3, 3, 3, 7, 2, 8, 6, 3, 8, 7, 1, 4, 3, 5,
6, 0, 0, 0, 3, 1, 5, 6, 4, 3, 4, 5, 5, 8, 7, 7, 2, 8, 4, 3, 5, 6,
5, 3, 7, 5, 7, 8, 3, 0, 4, 5, 1, 2, 7, 6, 3, 0, 2, 7, 9, 6, 1, 3,
7, 2, 1, 2, 4, 8, 5, 2, 4, 9, 2, 1, 6, 0, 6, 1, 4, 9, 6, 0, 9, 7,
6, 9, 1, 9, 0, 9, 9, 0, 8, 4, 6, 2, 0, 9, 3, 6, 9, 2, 1, 6, 3, 4,
2, 3, 1, 0, 2, 0, 4, 6, 1, 0, 0, 4, 9, 1, 7, 3, 2, 3, 8, 6, 8, 6,
2, 2, 5, 5, 9, 8, 3, 4, 9, 7, 1, 3, 8, 4, 5, 1, 4, 3, 6, 3, 3, 5,
7, 0, 6, 8, 6, 1, 6, 0, 6, 3, 9, 5, 1, 5, 8, 4, 0, 9, 2, 0, 5, 3,
7, 1, 9, 9, 5, 7, 7, 9, 9, 6, 3, 0, 3, 3])
print(y_pred[200])
plt.imshow(Origin_X_test[200].reshape((28,28)))
1

pd.DataFrame({"ImageId":list(range(1,len(y)))})
网友评论