KNN算法和sklearn中的KNN算法

2018年9月9日20:25:28教程评论51阅读模式

2018​文章源自随机的未知-https://sjdwz.com/11100.html

 KNN基本思想

KNN是通过测量不同特征值之间的距离进行分类。它的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别,其中K通常是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。文章源自随机的未知-https://sjdwz.com/11100.html

使用图来说话比较方便:文章源自随机的未知-https://sjdwz.com/11100.html

原始数据的散点图如下:文章源自随机的未知-https://sjdwz.com/11100.html

KNN算法和sklearn中的KNN算法文章源自随机的未知-https://sjdwz.com/11100.html

如果增加一个数据点(增加的数据点用绿色来表示)如下:文章源自随机的未知-https://sjdwz.com/11100.html

KNN算法和sklearn中的KNN算法文章源自随机的未知-https://sjdwz.com/11100.html

那么新增的数据点归为哪一类呢?文章源自随机的未知-https://sjdwz.com/11100.html

如果我们测量3个点分别到绿色点的距离,那么很显然归为蓝色这一类。文章源自随机的未知-https://sjdwz.com/11100.html

如此便可以很形象的说,knn,就是选择k个点与新增加的点测量距离,距离最近点最多的意味着得到的票数越多,便归为那一类。文章源自随机的未知-https://sjdwz.com/11100.html

 文章源自随机的未知-https://sjdwz.com/11100.html

使用python进行编程:

# -*- coding: utf-8 -*-
import numpy as np
from math import sqrt
from collections import Counter

class KNN_Classifier:
    def __init__(self,k):
        """构造函数"""
        #给定k值
        self.k=k
        self.X_train=None
        self.y_train=None
    def fit(self,X_train,y_train):
        """训练模型"""
       #knn的训练模型实际上就是把训练数据集进行保存
        assert self.k<=X_train.shape[0],\
               "k的值必须小于等于X_train的第二个维度"
        self._X_train=X_train
        self._y_train=y_train
        return self
    def predicty(self,x):
        """对矩阵中的元素进行预测"""
        assert self._X_train is not None and self._y_train is not None,\
               "X_train and y_train must be fit"
        assert self._X_train.shape[1]==x.shape[1],\
               "X_train和x的维度应该相等"
        y_predict=[self._predict(m) for m in x]
        return np.array(y_predict)
    def _predict(self,m):
        """预测每个点的函数"""
        #求距离
        distances=np.array(np.array([sqrt(np.sum((x-m)**2)) for x in self._X_train]))
        #得到值从小到大后排序的索引值
        top_y=distances.argsort()
        #取出最近的k个值
        nearest=self._y_train[top_y[:self.k]]
        #得到预测值
        predict_y=Counter(nearest).most_common(1)[0][0]
        return predict_y

KNN算法和sklearn中的KNN算法文章源自随机的未知-https://sjdwz.com/11100.html

sklearn中的KNN

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt

raw_data_X = [
    [3.393533211, 2.331273381],
    [3.110073483, 1.781539638],
    [1.343808831, 3.368360954],
    [3.582294042, 4.679179110],
    [2.280362439, 2.866990263],
    [7.423436942, 4.696522875],
    [5.745051997, 3.533989803],
    [9.172168622, 2.511101045],
    [7.792783481, 3.424088941],
    [7.939820817, 0.791637231]
]  # 两列分别代表肿瘤的长和宽 X是大写
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] # 分为0,1两个类别
#x训练集
X_train=np.array(raw_data_X)
y_train=np.array(raw_data_y)

#看一下原始数据点的分布
plt.figure(1)
plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1],color='red',marker='o',label='y==0')
plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1],color='blue',marker='x',label='y==1')
plt.legend()
plt.show()

X_new = np.array([8.093623049, 3.365732334])#增加一个新的数据
#用散点图直观观察一下新增数据之后新的数据的分布
plt.figure(2)
plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1],color='red',marker='o',label='y==0')
plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1],color='blue',marker='x',label='y==1')
plt.legend()
plt.scatter(X_new[0],X_new[1],marker='+',color='green',s=100)
plt.show()

"""sklearn中的KNN"""

#创建knn类

knn=KNeighborsClassifier()
#训练knn
knn.fit(X_train,y_train)
#将X_new变成两列的
X_new=X_new.reshape(-1,2)
#输出类别
print(knn.predict(X_new))

KNN算法和sklearn中的KNN算法文章源自随机的未知-https://sjdwz.com/11100.html

使用knn对sklearn中的数据进行训练和预测

import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier

#加载 sklearn 中的 datasets 数据中的digits(手写字体数据)

digits=datasets.load_digits()
x=digits.data
y=digits.target

#使用 train_test_split 进行模型建立和测试的分离,加zhiqian是因为没有进行
#归一化处理

X_train_zhiqian,X_test_zhiqian,y_train,y_test=train_test_split(x,y,test_size=0.2)

#使用 StandardScaler进行归一化处理
"""为什么使用X_train_zhiqian进行归一化处理的均值和方差进行对X_test的归一化呢?
是因为要服从现实情况,如果只有一个数据进行预测,就没有办法得出均值和方差
"""

s=StandardScaler()
s.fit(X_train_zhiqian)
X_train=s.transform(X_train_zhiqian)
X_test=s.transform(X_test_zhiqian)

knn_clf=KNeighborsClassifier()
#使用网格搜索的方法进行对超参数的选取
#超参数是指在算法进行时对不确定的参数进行调整以使得算法的预测准确率最高
params=[
{"weights":["uniform"],
 "n_neighbors":[k for k in range(1,11)]
},
{"weights":["distance"],
 "n_neighbors":[k for k in range(1,11)],
 "p":[k for k in range(1,6)]
}
]

#n_jobs 这个参数是使用计算机的几个核,赋值为-1表示全都使用

gridsearch=GridSearchCV(knn_clf,params,n_jobs=-1)
gridsearch.fit(X_train,y_train)
print("best_score",gridsearch.best_score_)
print("best_params",gridsearch.best_params_)

#将最好的赋值给knn_clf
knn_clf=gridsearch.best_estimator_

print(knn_clf.score(X_test,y_test))

KNN算法和sklearn中的KNN算法文章源自随机的未知-https://sjdwz.com/11100.html

​本文在未建站时所写,排版会有些问题,大家可以去访问原文链接查看原文
原文链接:https://blog.csdn.net/qq_41243472/article/details/82558491
文章源自随机的未知-https://sjdwz.com/11100.html

欢迎关注本站微信公众号:随机的未知 如果喜欢本文,欢迎点赞,收藏,转发,打赏。
教程最后更新:2022-2-23
  • 本文由 发表于 2018年9月9日20:25:28
  • 转载请注明:来源:随机的未知 本文链接https://sjdwz.com/11100.html
教程

详解MySQL索引

索引介绍 索引是帮助MySQL高效获取数据的数据结构。在数据之外,数据库系统还维护着一个用来查找数据的数据结构,这些数据结构指向着特定的数据,可以实现高级的查找算法。 本文以MySQL常用的B+Tre...
java

详解java接口interface

引言 接口这个词在生活中我们并不陌生。 在中国大陆,我们可以将自己的家用电器的插头插到符合它插口的插座上; 我们在戴尔,惠普,联想,苹果等品牌电脑之间传输数据时,可以使用U盘进行传输。 插座的普适性是...
java

Java中的抽象类和抽象方法

引言 实例图片 如上图,二维图形类有三个子类,分别是正方形类,三角形类,圆形类; 我们都知道要求正方形的面积,直接使用面积公式边长的平方即可,同理三角形的是底乘高除以2,圆的面积是**乘以半径的平方。...
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定