K 近邻算法(一)+https://developer.aliyun.com/article/1544595?spm=a2c6h.13148508.setting.14.2a1e4f0enzfh9f
分类算法的评估
- 利用训练好的模型使用测试集的特征值进行预测
- 将预测结果和测试集的目标值比较,计算预测正确的百分比
from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier X,y = datasets.load_iris(return_X_y = True) X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2) knn_clf = KNeighborsClassifier(n_neighbors=6) knn_clf.fit(X_train,y_train) y_predict = knn_clf.predict(X_test) sum(y_predict==y_test)/y_test.shape[0]
SKlearn中模型评估
- sklearn.metrics包中的accuracy_score方法: 传入预测结果和测试集的标签, 返回预测准确率
from sklearn.metrics import accuracy_score accuracy_score(y_test,y_predict)
如何确定合适的K值
K值过小:容易受到异常点的影响
k值过大:受到样本均衡的问题
我们可以采用交叉验证法来选择最优的K值。
GridSearchCV
GridSearchCV 是 scikit-learn 库中的一个类,用于进行参数网格搜索。它结合了交叉验证和网格搜索的功能,可以自动地对给定的模型和参数组合进行训练和评估,以找到最佳的参数设置。
from sklearn.model_selection import GridSearchCV from sklearn.svm import SVC model = SVC() param_grid = {'C': [0.1, 1, 10], 'kernel': ['linear', 'rbf']} grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5) grid_search.fit(X_train, y_train) best_params = grid_search.best_params_ best_score = grid_search.best_score_ best_model = grid_search.best_estimator_ best_model.fit(X_train, y_train) y_pred = best_model.predict(X_test)
GridSearchCV
会遍历所有可能的参数组合,并对每个组合进行交叉验证。这可能会消耗大量的计算资源和时间,特别是当参数空间较大时。因此,在使用 GridSearchCV
时,需要权衡参数网格的大小和计算资源的可用性。
from sklearn.model_selection import GridSearchCV x, y = load_iris(return_X_y=True) x_train, x_test, y_train, y_test = \ train_test_split(x, y, test_size=0.2, stratify=y, random_state=0) estimator = KNeighborsClassifier() param_grid = {'n_neighbors': [1, 3, 5, 7]} estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5, verbose=0) estimator.fit(x_train, y_train) print('最优参数组合:', estimator.best_params_, '最好得分:', estimator.best_score_) print('测试集准确率:', estimator.score(x_test, y_test))
手写数字案例
数据集:可以从MNIST数据集或UCI欧文大学机器学习存储库中获取手写数字的数据。这些数据集包含了大量已经标注好的手写数字图片。
import matplotlib.pyplot as plt import pandas as pd from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier import joblib from collections import Counter def show_digit(idx): data = pd.read_csv('手写数字识别.csv') if idx < 0 or idx > len(data) - 1: return x = data.iloc[:, 1:] y = data.iloc[:,0] print('当前数字的标签为:',y[idx]) # 查看当前数字的数值 data_ = x.iloc[idx].values data_ = data_.reshape(28, 28) # 显示当前数字在数据集的图片 plt.imshow(data_) plt.show() def train_model(): data = pd.read_csv('手写数字识别.csv') x = data.iloc[:, 1:] / 255 y = data.iloc[:, 0] print('数据基本信息:', x.shape) print('类别数据比例:', Counter(y)) split_data = train_test_split(x, y, test_size=0.2, stratify=y, random_state=0) x_train, x_test, y_train, y_test = split_data estimator = KNeighborsClassifier(n_neighbors=3) estimator.fit(x_train, y_train) acc = estimator.score(x_test, y_test) print('测试集准确率: %.2f' % acc) joblib.dump(estimator, 'knn.pth') def test_model(): import matplotlib.pyplot as plt import joblib img = plt.imread('demo.png') # 对于灰度图像,返回的是一个二维数组,其中每个元素是一个介于0和1之间的浮点数,表示该像素的灰度值 plt.imshow(img) knn = joblib.load('knn.pth') y_pred = knn.predict(img.reshape(1, -1)) #首先将从图片中读取到的数据 (img) 重塑为一维数组形式,以便给 KNN 分类器进行预测。 print('您绘制的数字是:', y_pred) show_digit(1) train_model() test_model()
小结:
KNN(K-Nearest Neighbors)算法,即K最近邻算法,是一种监督学习算法,可以用于分类和回归问题。其基本思想是:给定一个训练数据集,对于新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类别,则该输入实例也属于这个类别。
KNN算法的主要步骤如下:
- 计算输入实例与训练数据集中的每个实例之间的距离。常用的距离度量方法有欧氏距离、曼哈顿距离等。
- 对计算出的距离进行排序,找出距离最近的K个邻居。
- 统计这K个邻居所属的类别,选择出现次数最多的类别作为输入实例的预测类别。
- 如果用于回归问题,则计算这K个邻居的平均值或加权平均值作为输入实例的预测值。
KNN算法的优点:
- 算法简单,易于理解。
- 适用于多分类问题。
- 对于一些非线性问题,KNN算法具有较好的性能。
KNN算法的缺点:
- 当训练数据集较大时,计算距离的时间复杂度较高。
- K值的选择对算法性能影响较大,但目前没有确定K值的通用方法。
- 对于不平衡数据集,KNN算法的性能较差。