参考文章:
《Python大战机器学习》(不好,就是官方文档的中文版再加上几个简单的例子)
数据挖掘十大算法–K近邻算法
机器学习笔记—KNN算法
常用样本相似性和距离度量方法
KNN(K近邻法)
输入为实例的特征向量,计算新数据与训练数据之间的距离,选取K个距离最近的数据进行分类或回归判断
对于分类问题:输出为实例的类别。分类时,对于新的实例,根据其k个最近邻的训练实例的类别,通过多数表决等方式进行预测。
对于回归问题:输出为实例的值。回归时,对于新的实例,取其k个最近邻的训练实例的平均值为预测值。
neighbors-based (基于邻居的) 监督学习分为两种: classification (分类)针对的是具有离散标签的数据,regression (回归)针对的是具有连续标签的数据。
不具有显示的学习过程,只是利用训练数据集对特征向量空间的划分,并作为其分类的模型
三要素:K如何选择、距离如何度量、分类决策的规则
K选取
- k=1,最邻近算法
- k较小,在较小的邻域中训练实例,近似误差会减小,但估计误差会增大。预测结果对近邻点非常敏感,模型整体变复杂,易过拟合
- k较大,在较大的邻域中训练实例,近似误差会增大,但估计误差会减小。模型变简单,容易忽略实例中大量有用信息
应用中,k值一般取一个较小的数值。通常采用叉验证法来选取最优的k值就是比较不同k值时的交叉验证平均误差率,选择误差率最小的那个大值。例如选择k= 1,2.3.对每个k=i做若干次交叉验证,计算出平均误差,然后比较、选出最小的那个
距离度量
- 特征在训练前必须量化为数值特征
- 每个参数对距离的计算的影响不同,应采取归一化处理
距离Lp分类:欧氏距离、曼哈顿距离、汉明距离等
一般,连续变量选择欧式距离作为度量,像文本分类这种离散的使用汉明距离
数据挖掘十大算法–K近邻算法
机器学习笔记—KNN算法
常用样本相似性和距离度量方法
分类决策规则
通常使用多数表决(经验风险最小化),也可使用基于距离远近进行加权投票(距离越近权重越大)
import numpy as np
from sklearn.datasets import load_digits
from sklearn.neighbors import KNeighborsClassifier
最近邻分类
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=1, **kwargs)
参数
- n_neighbors: k值
- weights:指定投票权重类型,默认值 weights = ‘uniform’ 为每个近邻分配统一的权重。而 weights = ‘distance’ 分配权重与查询点的距离成反比。 或者,用户可以自定义一个距离函数用来计算权重
- algorithm:指定计算最近邻的算法
- ‘auto’:自动决定最合适的
- ‘ball_tree’:BallTree算法
- ‘kd_tree’:KDTree算法
- ‘brute’:暴力搜索法
- leaf_size:int,指定BallTree/KDTree叶节点规模,影响树的构建和查询速度
- metric:指定距离度量,参考文档距离表示
- p:指定在minkowski距离上的指数p,p=1 对应曼哈顿距离,p=2 对应欧式距离
方法:
- fit(X,y)
- predict(X)
- score(X,y)
- kneighbors(X=None, n_neighbors=None, return_distance=True):返回样本点的k个邻近点,return_distance=True 同时返回到k个邻近点距离
from sklearn.model_selection import train_test_split
def load_classification_data():
digits = load_digits()
xtrain = digits.data
ytrain = digits.target
return train_test_split(xtrain,ytrain,test_size = 0.2,random_state=0)
def test_KNC(*data):
xtrain, xtest, ytrain, ytest = data
knc = KNeighborsClassifier()
knc.fit(xtrain,ytrain)
print('train score: ',knc.score(xtrain,ytrain))
print('test score: ',knc.score(xtest,ytest))
xtrain, xtest, ytrain, ytest = load_classification_data()
test_KNC(xtrain, xtest, ytrain, ytest)
train score: 0.9902574808629089
test score: 0.975
def test_KNC_params(*data,weight,k):
xtrain, xtest, ytrain, ytest = data
knc = KNeighborsClassifier(n_neighbors=k,weights=weight)
knc.fit(xtrain,ytrain)
print('train score: ',knc.score(xtrain,ytrain))
print('test score: ',knc.score(xtest,ytest))
xtrain, xtest, ytrain, ytest = load_classification_data()
test_KNC_params(xtrain, xtest, ytrain, ytest,k=100,weight='distance')
train score: 1.0
test score: 0.9361111111111111
调节k值和weights,p
- k越大预测反而不稳定
- weights选择distance比uniform策略好
- p参数对于分类器预测性能影响不大
最临近回归
sklearn.neighbors.RadiusNeighborsRegressor(radius=1.0, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, **kwargs)
参数、方法和分类一样
from sklearn.neighbors import KNeighborsRegressor
def test_KNR(*data):
xtrain, xtest, ytrain, ytest = data
knc = KNeighborsClassifier()
knc.fit(xtrain,ytrain)
print('train score: ',knc.score(xtrain,ytrain))
print('test score: ',knc.score(xtest,ytest))