学习scikit-learn中的knn使用
并自己实现一个封装
学习scikit-learn中的knn使用
ps:代码块加标题会让字变红
python 首先引入库
在这里插入代码片
#在这个库里面所有的算法都是以面向对象的形式进行包装的,使用时要先进行实例化
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
测试数据
Raw_data_X = [[3.4,2.3],
[3.1,1.7],
[1.3,3.3],
[3.6,4.6],
[2.2,2.8],
[7.4,4.6],
[5.7,3.5],
[9.17,2.5],
[7.8,3.4],
[8,0.8]
]
Raw_data_y = [0,0,0,0,0,1,1,1,1,1]
使用np数组加快计算过程
X_train = np.array(Raw_data_X)
y_train = np.array(Raw_data_y)
初始化模型
knn_classfier = KNeighborsClassifier(n_neighbors=6)#初始化一个值
fit得到’模型’
knn_classfier.fit(X_train,y_train)
测试点x
x = np.array([8,3.3])#2*1
x的shape为2行1列向量
我们输入时要把其转成矩阵,就这个例子来说就是转成1*2
X_predict = x.reshape(1,-1)#1*2的矩阵
调整好数据后进行预测(这个例子中只传入一个x,如何传入多个x呢)
预测结果为
y_predict =knn_classfier.predict(X_predict)
print(y_predict[0])
python 对于Knn来说,训练集就是模型
自己实现一个封装
这是一个函数实现
import numpy as np
from collections import Counter
def Knn_classify(k,X_train,y_train,x):
# shape[0]指的就是行数,也就是X_train的数据点的个数,k显然必须小于总体样本个数
assert 1 <= k <= X_train.shape[0]
# 数据点的个数必须与数据标签个数相同
assert X_train.shape[0] == y_train.shape[0]
#x的维数必须和数据集中的X_train的维数保持一致
assert x.shape[0] == X_train.shape[1]
distances = [np.sqrt(np.sum((x_train - x) ** 2)) for x_train in X_train]
nearest = np.argsort(distances)
topK_y = [y_train[i] for i in nearest[:k]]
votes = Counter(topK_y)
return votes.most_common(1)[0][0]
我们需要用面向对象的思想去重构我们的代码,让它更符合sklearn的的风格
KNN.
首先引入相关包
import numpy as np
from collections import Counter
定义类KNNClassifier(这个只能输入单个点)
class KNNClassifier:
初始化
def __init__(self,k):
"""初始化KNN分类器,需要传入K的值"""
assert k>=1,"k必须合法"
self.k = k
self._X_train = None#将我们训练的数据私有化,加 _
self._y_train = None#私有化
fit训练分类器
def fit(self,X_train, y_train):
"""根据训练数据集X_train和y_train训练分类器"""
# shape[0]指的就是行数,也就是X_train的数据点的个数,k显然必须小于总体样本个数
assert 1 <= self.k <= X_train.shape[0],'K必须在一个合理的范围'
# 数据点的个数必须与数据标签个数相同
assert X_train.shape[0] == y_train.shape[0],'数据点个数必须与数据标签个数相同'
self._X_train = X_train
self._y_train = y_train
return self
预测
给定待遇测数据集X_predict,返回表示X_predict的结果向量
def predict(self,X_predict):
"""给定待遇测数据集X_predict,返回表示X_predict的结果向量"""
#传入的数据不为空
assert self._X_train != None and self._y_train != None,'传入数据不为空,要先fit'
#数据的维数必须一致
assert X_predict.shape[1] == self._X_train.shape[1],'the feature number of X_predict must be equal to X_train'
y_predict = [self._predict(x) for x in X_predict]
给定单个待测数据,返回x的预测值结果
def _predict(self,x):
"""给定单个待测数据x,返回x的预测结果值"""
# x的维数必须和数据集中的X_train的维数保持一致
assert x.shape[0] == self.X_train.shape[1]
distances = [np.sqrt(np.sum((x_train - x) ** 2)) for x_train in self.X_train]
nearest = np.argsort(distances)
topK_y = [self.y_train[i] for i in nearest[:self.k]]
votes = Counter(topK_y)
return votes.most_common(1)[0][0]
显示属性
def __repr__(self):
"""显示属性"""
return "KNN(k=%d)" % self.k
测试一下
from knn.KNN import KNNClassifier
knn_clf = KNNClassifier(6)
knn_clf.fit(X_train,y_train)
预测
y_predict = knn_classfier.predict(X_predict)
print(y_predict)
PS:10个点测试
需要修改的代码:
数据x
第一块
x = [[3.4,2.3],
[3.1,1.7],
[1.3,3.3],
[3.6,4.6],
[2.2,2.8],
[7.4,4.6],
[5.7,3.5],
[9.17,2.5],
[7.8,3.4],
[8,0.8]
]
x = np.array(x)
第二块
将reshape成10*2的矩阵
X_predict = x.reshape(len(x),-1)#1*2的矩阵