机器学习实战KNN----手写体识别

    最近在学习机器学习,觉得机器学习特别有趣,现在将KNN算法做一个总结。

一、简介

        KNN是一种有监督的分类算法,思想很简单,就是通过测量预测数据与训练数据之间的距离,选取前K个距离最短(或距离在K以内)的训练样本,在得到的训练样本中取标签数占的最多的类别即为预测类别。

        KNN的操作步骤:

  1. 计算testdata与每一个trainingdata之间的距离
  2. 按距离递增次序排序
  3. 选取与当前点距离最小的k个点
  4. 确定前k个点所在类别出现的频率
  5. 返回前k个点出现频率最高的类别作为当前点的预测类别

二、优缺点

        优点:精度高、对异常值敏感、无数据输入假定 

        缺点:计算复杂度高、空间复杂度高、测试时间长

三、实战

        通过阅读机器学习实战的knn章节,我自己也将书上的手写体识别(分类)写了一遍,我已将数据集和代码已上传至https://github.com/ZhangPengFe/KNN_HandWrite ,希望你们也能自己写一遍,看和写的收获完全不一样

        由于代码很简单,我就不解释了,如果有不懂的代码段,大家可以留言,我看到会和大家一起讨论。

import numpy as np
import os


def load_data(file_dir, file_name):
    file_path = os.path.join(file_dir, file_name)
    data = np.zeros((1, 1024))
    with open(file_path, 'r') as f:
        for i in range(32):
            line = f.readline()
            for j in range(32):
                data[0, i*32+j] = int(line[j])
    label = int(file_name.split('_')[0])
    return data, label


def handwrite():
    train_dir = 'trainingDigits'
    train_filename = os.listdir(train_dir)  # return a list, which include all file name under the train_dir
    train_filenum = len(train_filename)
    train_data = np.zeros((train_filenum, 1024))
    train_label = []
    # read train data and label
    for i in range(train_filenum):
        train_data[i, :], label = load_data(train_dir, train_filename[i])
        train_label.append(label)

    test_dir = 'testDigits'
    test_filename = os.listdir(test_dir)
    test_filenum = len(test_filename)
    a_test_data = np.zeros((1, 1024))
    real = 0
    for i in range(test_filenum):
        a_test_data, test_label = load_data(test_dir, test_filename[i])
        diff_data = np.tile(a_test_data, (train_filenum, 1)) - train_data
        diff_data_square = diff_data**2
        temp = diff_data_square.sum(axis=1)
        distance = temp**0.5
        sort = distance.argsort()
        predict = {}
        for j in range(10):
            predict[j] = 0
        for j in range(3):          # k of knn is 3
            predict[train_label[sort[j]]] += 1
        pre_result = max(predict, key=predict.get)
        print("the classifier came back with: %d, the real answer is: %d" % (pre_result, test_label))
        if pre_result == test_label:
            real += 1
    print(real/test_filenum)


if __name__ == '__main__':
    handwrite()

 

好的,我会尽力回答你的问题。首先,针对你的问题,我需要说明一下,我是一个AI语言模型,没有存储任何历史信息,所以我并不知道你之前对我说了什么话。不过,我可以帮助你解决问题,以下是我对你的问题的回答。 针对你的问题,我将一步一步地介绍如何使用python语言,应用Kmeans++算法,编写程序实现聚类并测试MNIST数据集数据库。具体步骤如下: 一、载入数据,然后划分为训练集测试集。 首先,我们需要从MNIST数据集中载入数据。MNIST数据集是一个手写数字识别的数据集,其中包含了60000个训练样本10000个测试样本,每个样本是一个28*28的灰度图像。你可以从官网下载MNIST数据集,也可以使用python中的keras库直接载入数据。 代码示例: ```python from keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() ``` 接下来,我们需要将数据进行预处理,将像素值缩放到0到1之间,并将28*28的图像转换为一个784维的向量。同时,我们需要将训练集测试集进行划分,一般情况下,我们可以将70%的数据作为训练集,30%的数据作为测试集。 代码示例: ```python import numpy as np from sklearn.model_selection import train_test_split x_train = x_train.reshape(-1, 784) / 255.0 x_test = x_test.reshape(-1, 784) / 255.0 y_train = np.eye(10)[y_train] y_test = np.eye(10)[y_test] x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.3, random_state=2021) ``` 二、应用PCA算法对数据进行降维处理。 MNIST数据集的维度是很高的,这会导致计算量非常大,因此我们需要对数据进行降维处理。常用的降维方法有PCAt-SNE等。这里我们使用PCA对数据进行降维。 代码示例: ```python from sklearn.decomposition import PCA pca = PCA(n_components=50) x_train_pca = pca.fit_transform(x_train) x_val_pca = pca.transform(x_val) x_test_pca = pca.transform(x_test) ``` 三、编写Kmeans++算法程序,用训练集实现聚类Kmeans++是一种常用的聚类算法,在处理大规模数据时效果比较好。其主要思想是选择初始聚类中心时,让它们尽可能地分散开来,避免聚类中心过于靠近或者重合。在Kmeans++算法中,将数据划分为K个簇,然后通过不断迭代,使得每个数据点与最近的聚类中心相连。最终的目标是使得所有数据点都距离最近的聚类中心最近,同时使得每个簇的内部方差最小。 代码示例: ```python from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=10, init='k-means++', random_state=2021) kmeans.fit(x_train_pca) train_pred = kmeans.predict(x_train_pca) val_pred = kmeans.predict(x_val_pca) test_pred = kmeans.predict(x_test_pca) ``` 四、计算聚类的sh系数。 为了评估聚类的效果,我们可以采用sh系数来衡量聚类的紧密程度分离程度。sh系数越大,说明聚类效果越好。 代码示例: ```python from sklearn.metrics import silhouette_score train_score = silhouette_score(x_train_pca, train_pred) val_score = silhouette_score(x_val_pca, val_pred) test_score = silhouette_score(x_test_pca, test_pred) print("Train sh score: {:.4f}, Val sh score: {:.4f}, Test sh score: {:.4f}".format(train_score, val_score, test_score)) ``` 五、用测试集进行验证(可以采用KNN算法)。 最后,我们可以使用KNN算法来对测试集进行验证。KNN算法是一种基于距离的分类算法,它的基本思想是将每个测试样本与训练集中的所有样本进行距离比较,然后将距离最近的K个样本作为该测试样本的邻居,根据邻居的标签进行分类。 代码示例: ```python from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=5) knn.fit(x_train_pca, np.argmax(y_train, axis=1)) train_acc = knn.score(x_train_pca, np.argmax(y_train, axis=1)) val_acc = knn.score(x_val_pca, np.argmax(y_val, axis=1)) test_acc = knn.score(x_test_pca, np.argmax(y_test, axis=1)) print("Train acc: {:.4f}, Val acc: {:.4f}, Test acc: {:.4f}".format(train_acc, val_acc, test_acc)) ``` 以上就是使用python语言,应用Kmeans++算法,编写程序实现聚类并测试MNIST数据集数据库的完整步骤。希望我的回答能够对你有所帮助。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值