机器学习(一):K-近邻算法(KNN)分类与回归

文章目录

      • K-近邻算法(KNN)
        • 介绍
        • 原理
        • 实现
          • Python代码实现
          • 使用scikit-learn实现
            • KNN做分类
            • KNN做回归
        • 总结

K-近邻算法(KNN)

介绍

K-近邻算法是一种惰性学习模型(lazy learning),也称为基于实例学习模型,这与勤奋学习模型(eager learning)不一样。例如线性回归模型就是属于勤奋学习模型。
勤奋学习模型在训练模型的时候会很耗资源,它会根据训练数据生成一个模型,在预测阶段直接带入数据就可以生成预测的数据,所以在预测阶段几乎不消耗资源
惰性学习模型在训练模型的时候不会估计由模型生成的参数,他可以即刻预测,但是会消耗较多资源,例如KNN模型,要预测一个实例,需要求出与所有实例之间的距离。
K-近邻算法是一种非参数模型,参数模型使用固定的数量的参数或者系数去定义模型,非参数模型并不意味着不需要参数,而是参数的数量不确定,它可能会随着训练实例数量的增加而增加,当数据量大的时候,看不出解释变量和响应变量之间的关系的时候,使用非参数模型就会有很大的优势,而如果数据量少,可以观察到两者之间的关系的,使用相应的模型就会有很大的优势。

原理

存在一个样本集,也就是训练集,每一个数据都有标签,也就是我们知道样本中每个数据与所属分类的关系,输入没有标签的新数据后,新数据的每个特征会和样本集中的所有数据对应的特征进行比较,算出新数据与样本集其他数据的欧几里得距离,这里需要给出K值,这里会选择与新数据距离最近的K个数据,其中出现次数最多的分类就是新数据的分类,一般k不会大于20。

实现

Python代码实现
import operator
def class_KNN(X,dataset,y,K):
    datasize = dataset.shape[0] # 返回dataset的行数
    diff = np.tile(X,(datasize,1))-dataset  # tile可以在1列上重复生成datasize个X
    distances = ((diff**2).sum(axis=1))**0.5 # 
    sort_distance = distances.argsort()
    class_count = {}
    for i in range(K):
        votelabel = y[sort_distance[i]]
        class_count[votelabel] = class_count.get(votelabel,0) + 1
        sort_class_count = sorted(class_count.items(),key=operator.itemgetter(1),reverse=True)
        return sort_class_count[0][0]
data = np.array([[158,64],[170,86],[183,84],[191,80],[155,49],[163,59],[180,67],[158,54],[170,67]])
y = ['m','m','m','m','fm','fm','fm','fm','fm']
x = [150,50]
print(class_KNN(x,data,y,3))
使用scikit-learn实现
KNN做分类
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelBinarizer
from sklearn.neighbors import KNeighborsClassifier
X_train = np.array([[158,64],[170,86],[183,84],[191,80],[155,49],[163,59],[180,67],[158,54],[170,67]])
y_train = ['m','m','m','m','fm','fm','fm','fm','fm']
lb = LabelBinarizer()   # 将y_train转化为整数
y_train_transform = lb.fit_transform(y_train)
k = 3 # 设置K值
KNN = KNeighborsClassifier(n_neighbors=k)
KNN.fit(X_train,y_train_transform)
y_predict = KNN.predict(np.array([155,70]).reshape(1,-1))[0]
y_predict_transform = lb.inverse_transform(y_predict) # 将数值型变量转化为原先字符创标签
y_predict_transform

# output
array(['fm'], dtype='
KNN做回归
from sklearn.neighbors import KNeighborsRegressor 
from sklearn.metrics import mean_squared_error,mean_absolute_error
from sklearn.preprocessing import StandardScaler  # 标准化数据
X_train = np.array([[158,1],[170,1],[183,1],[191,1],[155,0],[163,0],[180,0],[158,0],[170,0]])
y_train = [64,86,84,80,49,59,67,54,67]
X_test = np.array([[168,1],[180,1],[160,0],[169,0]])
y_test = [65,96,52,67]
ss = StandardScaler()
X_train_scaled = ss.fit_transform(X_train)
X_test_scaled = ss.transform(X_test)
K = 3
KN = KNeighborsRegressor(n_neighbors=K)
KN.fit(X_train_scaled,y_train)
predictions = KN.predict(X_test_scaled)
print('预测的数据:',predictions)
print('MAE为',mean_absolute_error(y_test,predictions))  # 平均绝对误差
print('MSE为',mean_squared_error(y_test,predictions))  # 均方误差


# output:
预测的数据: [78.         83.33333333 54.         64.33333333]
MAE为 7.583333333333336
MSE为 85.13888888888893

总结

KNN模型是一种既可以做分类也可以做回归的模型。是一个简单但是强大的模型。

优点:精度高、对异常值不敏感、无数据输入假定
缺点:计算复杂度高,空间复杂度高

你可能感兴趣的:(机器学习)