美文网首页
机器学习:K-近邻算法代码详细注释笔记

机器学习:K-近邻算法代码详细注释笔记

作者: Messix_1102 | 来源:发表于2021-01-17 21:34 被阅读0次

    分类方法代码及注释

    # 分类方法代码及注释
    #inx 要分类的向量, dataset 数据集, labels 数据集分类, k 取最接近的前k个分类
    def classify0(inx, dataSet, labels, k):
        # 获取数据集行数
        dataSetSize = dataSet.shape[0]
        # 复制输入向量,使其与数据集具有相同行数,做矩阵减法
        # 此处tile函数把inx向量复制 dataSetSize 行、1列,使之可以与数据集做矩阵减法
        # https://blog.csdn.net/cszhang570221322/article/details/85107935
        diffMat = tile(inx, (dataSetSize, 1)) - dataSet
        # 矩阵求平方
        sqDiffMat = diffMat**2
        # 每行相加
        # https://blog.csdn.net/laobai1015/article/details/85720875
        sqDistance = sqDiffMat.sum(axis=1)  
        # 取平方根
        distances = sqDistance ** 0.5
        # 取排序下标
        # argsort 方法举例
        # x=np.array([1,4,3,-1,6,9])
        #             0 1 2  3 4 5
        #             3 2 3  1 4 5        
        # x.argsort()
        # [3,0,2,1,4,5]
        sortedDistIndicies = distances.argsort()
        # 声明字典
        classCount = {}
        for i in range(k):
            # 获取对应的目标变量
            voteIlable = labels[sortedDistIndicies[i]]
            # 目标变量存入字典
            classCount[voteIlable] = classCount.get(voteIlable, 0) + 1
        # 根据目标变量出现频率倒序
        # 参数1 为排序的数据,参数 2 为用于比较大小的字段,参数3 表示是否倒序
        sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)
        return sortedClassCount
    

    读取文件内容转换为矩阵方法

    # 读取文件中的数据,转换为训练集
    def file2matrix(filename):
        fr = open(filename)
        arrayOline = fr.readlines()
        numberOfLines = len(arrayOline)
        # 创建 numberOfLines 行 3 列的局长
        returnMat = zeros((numberOfLines, 3))
        classLabelVector = []
        index = 0
        for line in arrayOline:
            # 行字符串去除前后空格
            line = line.strip()
            # 以table空格截取字符串
            listFormLine = line.split('\t')
            # 把解析后数组的前三项赋值给矩阵
            returnMat[index, :] = listFormLine[0:3]
            # 取解析后数组的最后一项 赋值给目标值
            classLabelVector.append(int(listFormLine[-1]))
            index += 1
        return returnMat, classLabelVector
    

    利用matplotlib绘制散点图方法

    # 创建散点图
    # datingDataMat 矩阵, datingLabels 特征值, x1 x2 绘图所取的 矩阵列数据,
    def showDot(datingDataMat, datingLabels, x1, x2):
        # 创建画布
        # num 散点图名称
        # figsize 画布宽 8 英寸长,高 8 英寸
        # dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80 
        # facecolor 背景颜色
        # edgecolor 边框颜色
        # frameon 是否显示边框
        fig = plt.figure(num='约会对象分类散点图', figsize = [8, 8], dpi = 80)
        # 将画布分割成1行1列,图像画在从左到右从上到下的第1块
        # fig.add_subplot(349) 的含义
        # ----    
        # ----
        # +---
        # 其中 “+” 所在的位置为绘图位置
        ax = fig.add_subplot(111)
        # x、y 点的位置
        # s 点的大小
        # c 点的颜色
        ax.scatter(x = datingDataMat[:, x1], y = datingDataMat[:, x2], s = 15.0*array(datingLabels), c = 150.0*array(datingLabels))
        plt.show()
    

    数据归一化方法

    # 归一化,规范特征值,防之过大值影响计算结果
    def autoNorm(dataSet):
        # 获取矩阵每一列最小值
        # eg: a = np.array([[1,1,3],[2,0,4],[3,5,1]])
        # dataSet.min() 获取矩阵所有元素最小值: 0
        # dataSet.min(0) 获取矩阵每一列最小值: [1,0,1]
        # dataSet.min(1) 获取矩阵每一行最小值: [1,0,1]
        minVals = dataSet.min(0)
        # 同上
        maxVals = dataSet.max(0)
        # 矩阵减法获取最大最小值范围
        ranges = maxVals - minVals
        # shape 函数获取矩阵 形状,比如 3 行 4 列 矩阵结果为 (3, 4)
        # zeros 函数获取跟dataSet同形状的0维数组
        # np.zeros(np.shape(a)) 结果为 [[0,0,0],[0,0,0],[0,0,0]]
        normDataSet = zeros(shape(dataSet))
        # a = np.array([[1,1,3],[2,0,4],[3,5,1],[4,5,6]])
        # a.shape[0] = 4 行数
        # a.shape[1] = 4 列数
        m = dataSet.shape[0]
        # 归一算法 (old - min) / (max - min)
        # tile(minVals, (m, 1)) 把最小值 向量复制 m 行 1 列
        normDataSet = dataSet - tile(minVals, (m, 1))
        # tile(ranges, (m, 1)) 把最大值 向量复制 m 行 1 列
        normDataSet = normDataSet / tile(ranges, (m, 1))
        return normDataSet, ranges, minVals
    

    约会数据分类测试

    # 约会数据分类测试
    def datingClassTest():
        hoRatio = 0.10
        # 从 datingTestSet2 文件中获取矩阵和目标值
        datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
        # 归一化
        normMat, ranges, minVals = autoNorm(datingDataMat)
        # 行数
        m = normMat.shape[0]
        # 列数
        n = normMat.shape[1]
        # 获取10%的数据
        numTestVecs = int(m * hoRatio)
        errorCount = 0.0
    
        # 遍历计算每条数据
        for i in range(numTestVecs):
            # eg: nmArr = np.array([[1,2,3],
            #                       [4,5,6],
            #                       [7,8,9],
            #                       [10,11,12]])
            # X[i,j] 取矩阵X的第i行第j列的元素 nmArr[2,2] = 9
            # X[-1, -1]为数组X中位于最后一行,最后一列的元素
    
            # X[:,j] 从第0行开始到最后一行结束,取矩阵X的第 i 列的元素              nmArr[:,1] = [2,5,8,11]
            # X[a:, j]---->从第 a 行开始到最后一行结束,取矩阵X的第 j 列的元素      nmArr[1:,1] = [5,8,11]
            # X[:b, j]---->从第 0 行开始到第b-1行结束,取矩阵X的第 j 列的元素       nmArr[:2,1] = [2,5]
            # X[a:b, j]---->从第 a 行开始到第b-1行结束,取矩阵X的第 j 列的元素      nmArr[1:2,1] = [5]
            # X[:, i:j]---->从第0行开始到最后一行结束,取矩阵X的第 i 列到 j-1 列的元素    nmArr[:,1:3] = [[2,3],[5,6],[8,9],[11,12]]
            # X[:, i:j]---->从第0行开始到最后一行结束,取矩阵X的第 i 列到 j-1 列的元素    nmArr[1:,1:3] = [[5,6],[8,9],[11,12]]
            classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
            # 获取分类结果
            resultLabel = classifierResult[0][0]
            print ("the classifer came back with: %d, the real anwser is: %d" % (resultLabel, datingLabels[i]))
    
            if (resultLabel != datingLabels[i]): 
                print("   %d X", (i))
                errorCount += 1.0
    
        print ("the total error rate is %f" % (errorCount / float(numTestVecs)))
    

    约会对象分类

    # 约会对象分类
    def classifyPerson():
        resultList = ['not at all', 'in small doses', 'in large doses']
        # input('XXX') 为输入提示信息
        # float(input('XXX')) 把输入的信息 转换为float
        ffMiles = float(input("frequent flier miles eaarned per year?"))
        percentTags = float(input("percentage of time spent playing video games?"))
        iceCream = float(input("liters of ice cream consumed per year?"))
    
        datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
        normMat, ranges, minVals = autoNorm(datingDataMat)
        # 输入转换为计算向量
        inArr = array([ffMiles, percentTags, iceCream])
        # 输入向量 先归一,然后分类
        classifierResult = classify0((inArr - minVals) / ranges, normMat, datingLabels, 3)
        # 获取分类结果
        resultMark = classifierResult[0][0]
        print ("You will probably like this person: %s" % (resultList[resultMark - 1]))
    

    图片文件转换为向量

    # 图片文件转换成向量
    def img2vector(filename):
        returnVect = zeros((1, 1024))
        fr = open(filename)
        for i in range(32):
            lineStr = fr.readline()
            for j in range(32):
                returnVect[0, 32 * i + j] = int(lineStr[j])
        return returnVect
    

    手写输入测试

    # 手写数字测试
    def handwritingClassTest():
        hwLabels = []
        # 从文件夹加载文件列表
        trainingFileList = listdir('machinelearninginaction/Ch02/trainingDigits')
        # 获取文件数量
        m = len(trainingFileList)
        # 创建训练矩阵
        trainingMat = zeros((m, 1024))
    
        for i in range(m):
            fileNameStr = trainingFileList[i]
            fileStr = fileNameStr.split('.')[0]
            classNumStr = int(fileStr.split('_')[0])
            # 收集目标向量
            hwLabels.append(classNumStr)
            # 训练举证赋值
            trainingMat[i, :] = img2vector('machinelearninginaction/Ch02/trainingDigits/%s' % fileNameStr)
        
        # 加载测试文件
        testFileList = listdir('machinelearninginaction/Ch02/testDigits')
        errorCount = 0.0
        mTest = len(testFileList)
        # 循环分类测试文件
        for i in range(mTest):
            fileNameStr = testFileList[i]
            fileStr = fileNameStr.split('.')[0]
            # 图片手写值
            classNumStr = int(fileStr.split('_')[0])
            vectorUnderTest = img2vector('machinelearninginaction/Ch02/testDigits/%s' % fileNameStr)
            # 分类结果
            classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)[0][0]
            print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
    
            if(classifierResult != classNumStr):
                errorCount += 1.0
    
            print("the total number of errors is: %d" % errorCount)
            print("the total error rate is: %f" % (errorCount/float(mTest)))
    

    相关文章

      网友评论

          本文标题:机器学习:K-近邻算法代码详细注释笔记

          本文链接:https://www.haomeiwen.com/subject/hspzaktx.html