一 样本距离
A(X11,X12,......,X1n)与B(X21,X22,......,X2n)
闵可夫斯基距离是将多个距离公式总结而成的一个公式。
当p=1,是曼哈顿距离;p=2,欧式距离;p为无穷大,就是切比雪夫距离。
二 KNN算法原理
k-近邻算法,根据k个邻居样本的类别来判断当前样本的类别。
如果一个样本在特征空间的k个最相似也就是最临近样本的大多数属于某个类别,则该类别也属于这个类别。
打个比方,在一百个物品中,选择十个距离样本最近的物品,其中类别1有1,类别二有5,类别三有3,类别四有1。那么就认为样本属于类别二,因为离其最近的十个物品有五个都是类比二,这就是KNN。
三 KNN缺点
对于大规模的数据集,要计算测试样本与所有训练样本的距离,其计算量大;对于高维数据,距离度量变得不那么有意义,也就是维度灾难;
四 API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
参数:
(1)n_neighbors:
int, default=5, 默认情况下用于kneighbors查询的近邻数,就是K
(2)algorithm:
{'auto', 'ball_tree', 'kd_tree', 'brute'}, default='auto'。找到近邻的方式,注意不是计算距离 的方式,与机器学习算法没有什么关系,开发中请使用默认值'auto'
方法:fit(x,y) x作为训练数据,y作为目标数据、predict(x)预测提供的数据,得到预测数据
五 代码实例
print(pd.DataFrame(res.toarray(),columns=transfer.get_feature_names_out()))
#%%
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
'''保存模型'''
import joblib
'''获取数据'''
iris = load_iris()
'''打印形状,只有4个特征,150个样本'''
print("鸢尾花形状:", iris.data.shape)
'''4个特征的描述'''
print("鸢尾花特征描述:", iris.feature_names)
'''150个目标,对应150个样本的类别'''
print(iris.target.shape)
'''目标值只有012三种,说明150个样本属于三类中的一种'''
print(iris.target_names)
'''数据集的划分'''
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=22)
'''特征工程,标准化,只有4个特征'''
transfer=StandardScaler()
'''对训练特征进行标准化,对测试也做。
因为fit_transform中已经有fit进行计算了,则x_test只需要做transform。
训练中用的什么数据,模式只能识别到什么样的数据'''
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
'''KNN算法预估器,k=7表示找7个邻近来判断自身类型'''
estimator = KNeighborsClassifier(n_neighbors=7)
'''该步骤就是estimator根据训练特征和训练模型再自己学习,让它自己变聪明'''
estimator.fit(x_train, y_train)
'''模型评估,测试一下estimator'''
y_predict=estimator.predict(x_test)#y_predict预测的目标结果
print("预测结果:", y_predict)
print("准确率:", y_test == y_predict)
''''计算准确率'''
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
'''保存模型'''
joblib.dump(estimator, "../data/estimator.pkl")
'''加载模型'''
estimator = joblib.load("../data/estimator.pkl")
'''使用模型预测'''
y_test = estimator.predict([[0.4,0.2,0.4,0.6]])
print("预测结果:", y_test)
结果:
鸢尾花形状: (150, 4)
鸢尾花特征描述: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
(150,)
'setosa' 'versicolor' 'virginica'
预测结果: [2 1 1 1 2 1 2 2 1 1 0 1 0 0 1 2 1 0 2 1 1 0]
准确率: [ True True False True True True True True True True True True
True True True True True True True True True True]
准确率为:
0.9545454545454546
预测结果: [1]
拓展
KNN实现葡萄酒分类