scikit-learn K-近邻算法(KNN)

k-近邻算法原理:采用测量不同特征值之间的距离方法进行分类。

  • 优点:精度高、对异常值不敏感、无数据输入假定。
  • 缺点:时间复杂度高、空间复杂度高。
  • 适用数据范围:数值型和标称型。

工作原理:存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据 与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的 特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们 只选择样本数据集中前K个最相似的数据,这就是K-近邻算法中K的出处,通常K是不大于20的整数。 最后 ,选择K个最相似数据中出现次数最多的分类,作为新数据的分类。

思想:分类回归

数学依据:欧几里得距离

依赖包:

  • 分类问题:from sklearn.neighbors import KNeighborsClassifier
  • 回归问题:from sklearn.neighbors import KNeighborsRegressor

常用方法:

  • knn.fit(X, y) 将模型使用X作为培训数据和y作为目标值
  • knn.predict(X) 为所提供的数据预测类标签
  • datasets.load_iris(return_X_y=False) 载入并返回数据集(分类)
    • 'data':学习的数据
    • 'target':分类的标签
    • 'target_names':标签的含义
    • 'feature_names':特征的含义和“DESCR”,即数据集的完整描述。
  • train_test_split(*arrays, **options) 将数组或矩阵分割成随机的训练和测试子集
  • knn.score(X, y, sample_weight=None) 返回给定测试数据和标签的平均精度。
  • r2_score(y_true, y_pred, sample_weight=None, multioutput='uniform_average') R 2(确定系数)回归分数函数。

参数说明:

  • X_train:训练样本集
  • X_test:测试样本集
  • y_train:目标值(标签)
  • y_test:真实数据
  • y_:预测数据

本文需要用到的所有包

import numpy as np
import matplotlib.pyplot as plt

from sklearn.neighbors import KNeighborsClassifier
from sklearn.neighbors import KNeighborsRegressor

import sklearn.datasets as datasets     # datasets,专门为机器学习封装好的一个数据集
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
from sklearn.externals import joblib

一、 分类:对标称型数据进行预测

先举个简单栗子:

# 训练样本集
X_train = np.array([[175,60,43],[160,48,36],[186,120,49],[155,50,37],[169,67,40]])
# 测试样本集(标签)
labels = ["男","女","男","女","男"]
# 训练数据
# 定义一个knn分类器
knn = KNeighborsClassifier()
knn.fit(X_train,labels)
# 测试数据
X_test = np.array([[158,40,36]])
knn.predict(X_test)

第二个栗子:

iris_data = datasets.load_iris()
#获取训练样本集
data = iris_data.data            # data.shape (150,4)   
#获取label
target = iris_data.target        # target.shape  (150,)

#将data随机打乱,并拆成两部分(训练数据和测试数据)
X_train,X_test,y_train,y_test = train_test_split(data, target, test_size = 0.1)
#X_train(训练样本集)从data数据中(150)135个数据 ; X_test(测试数据) 15个数据
#y_train(目标值) 从target中(150)135个数据 ;  y_test(真实数据) 15个数据
X_train.shape       # (135, 4)
X_test.shape        # (15, 4)
y_train.shape       # (135,)
y_test.shape        # (15,)

#训练数据
knn = KNeighborsClassifier()
knn.fit(X_train,y_train)

#进行预测
y_ = knn.predict(X_test)        # y_(预测数据)

#查看预测的准确率
knn.score(X_test,y_test)
knn.score(X_train,y_train)
r2_score(y_,y_test)


# 绘图
%matplotlib inline
#获取训练样本集
X_train = data[:,:2]
#获取目标值
y_train = target
plt.scatter(X_train[:,0],X_train[:,1], c = y_train, cmap = "rainbow")

另一个栗子:

knn = KNeighborsClassifier()
#训练数据
knn.fit(X_train,y_train)

#生成测试数据
x_min,x_max = X_train[:,0].min(),X_train[:,0].max()
y_min,y_max = X_train[:,1].min(),X_train[:,1].max()

x = np.linspace(x_min,x_max,500)         # (500,)
y = np.linspace(y_min,y_max,300)         # (300,)

#从背景中根据x,y坐标抠出150000个点当做测试数据
xx,yy = np.meshgrid(x,y)           # 返回一个列表,列表中包含两个(300, 500)矩阵
X_test = np.c_[xx.ravel(), yy.ravel()]       # (150000, 2)

#对数据进行预测
y_ = knn.predict(X_test)

# 绘图
plt.scatter(X_test[:,0], X_test[:,1], c = y_)
plt.scatter(X_train[:,0],X_train[:,1], c = y_train, cmap = "rainbow")

二、 回归:对连续型数据进行预测

栗子:

X_train = np.random.rand(80,1)*10     # 随机生成(80, 1)的0-10之间的数据作为训练数据
X_train = np.sort(X_train,axis=0)          
y_train = np.sin(X_train)          # 自定义的目标值,与训练样本集是一个模型关系
y_train[::4] += np.random.randn(20,1)*0.3     # 对y_train添加噪音(每隔4个数据取一个),模拟统计数据
# plt.scatter(X_train,y_train)

knn = KNeighborsRegressor()
knn.fit(X_train,y_train)
x_test = np.linspace(0,10,1000).reshape((1000,1))   # 生成(1000,1)的0-10之间的线性数据
y_ = knn.predict(x_test)

# 绘图
plt.scatter(X_train,y_train,c='red')
plt.plot(x_test,y_,c='green')

#保存训练模型
joblib.dump(knn, "./xxx.m")

#使用保存好的训练模型
digist_estimator = joblib.load("./xxx.m")
#进行预测
y_ = digist_estimator.predict(X_test)

欠拟合:训练样本集数量过少,或者特征属性过少,会导致模型得分偏低, 这种情况叫欠拟合

过拟合:训练样本数据过于严格,得分虽然高,但是对个个别物体识别的时候,准确率是非常低的

猜你喜欢

转载自blog.csdn.net/qq_37212752/article/details/83094052