k近邻分类算法(KNN)
程序员文章站
2024-01-25 08:10:34
...
KNN实现
class KnnClassifier:
def __init__(self,k=7):
self.k = k
self._X_train = None
self._y_train = None
def fit(self,X_train,y_train):
'''训练模型'''
self._X_train = X_train
self._y_train = y_train
def predict(self,X_predict):
'''对多个进行分类预测'''
y_predict = np.array( [self._predict(x) for x in X_predict] ) #对X_predict中的每一个都进行训练
return y_predict
def _predict(self,x):
'''对一个新样本进行分类预测'''
distance = np.sqrt( np.sum( (self._X_train - x)**2,axis=1) )
votes = Counter(self._y_train[np.argpartition(distance,self.k)[:self.k]])
return votes.most_common(1)[0][0]
数据集分析
from sklearn import datasets
import numpy as np
from collections import Counter
import matplotlib.pyplot as plt
from sklearn import datasets
# load鸢尾花的数据集
iris = datasets.load_iris()
print('该数据集属性:', iris.keys())
print("数据集的特征为", iris.feature_names)
X = iris.data
y = iris.target
#伪造一个样本x作为测试样本
x = np.array([5.2,2.6,7.5,2.1])
# 散点图”可以帮助分析不同特征的分布关系 横轴是一个特征,竖轴是另外一个特征 通过不同类别不同颜色来区分
# 花萼的长宽特征分布图,不同颜色代表不同的针类 花萼的特征为第0列第1列
plt.figure(num=0)
plt.scatter(X[y==0, 0], X[y==1, 1],color='red') # 指定行为对应y==0的类 因为一行代表一个样本,正好y也是一行一个样本
plt.scatter(X[y==1, 0], X[y==1, 1],color='green')
plt.scatter(X[y==2, 0], X[y==2, 1],color='blue')
plt.scatter(x[0], x[1], color='black') #伪造的数据
plt.show()
# 花瓣的长宽特征分布图 不同颜色代表不同的针类 花瓣的特征为第3列第4列
plt.figure(num=1)
plt.scatter(X[y==0, 2], X[y==1, 3],color='red') # 指定行为对应y==0的类 因为一行代表一个样本,正好y也是一行一个样本
plt.scatter(X[y==1, 2], X[y==1, 3],color='green')
plt.scatter(X[y==2, 2], X[y==2, 3],color='blue')
plt.scatter(x[2], x[3], color='black') #伪造的数据
plt.show()
程序输出:
花萼长宽与花种类的关系 | 花瓣长宽与花种类的关系 |
可见,通过花瓣长宽特征能更好的区分更好能区分花种类
训练测试
对sklearn中数据集中的 鸢尾花的数据集 进行训练和测试
from sklearn import datasets
import numpy as np
from collections import Counter
# 鸢尾花的数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
class KnnClassifier:
def __init__(self,k=7):
self.k = k
self._X_train = None
self._y_train = None
def fit(self,X_train,y_train):
'''训练模型'''
self._X_train = X_train
self._y_train = y_train
def predict(self,X_predict):
'''对多个进行分类预测'''
y_predict = np.array( [self._predict(x) for x in X_predict] ) #对X_predict中的每一个都进行训练
return y_predict
def _predict(self,x):
'''对一个新样本进行分类预测'''
distance = np.sqrt( np.sum( (self._X_train - x)**2,axis=1) )
votes = Counter(self._y_train[np.argpartition(distance,self.k)[:self.k]])
return votes.most_common(1)[0][0]
knn = KnnClassifier()
knn.fit(X,y)
print ( knn.predict(X[2:4,:]) ) #对原始样本中的样本进行测试