机器学习笔记(2)

这次分享的是第二章K-近邻算法
具体理论知识就不写出来了,关于k近邻算法的含义等可以直接去书上找,也可以直接百度

k-近邻算法采用测量不同特征值之间的距离方法进行分类
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。
适用数据范围:数值型和标称型。

算法使用流程
(1) 收集数据:可以使用任何方法。
(2) 准备数据:距离计算所需要的数值,最好是结构化的数据格式。
(3) 分析数据:可以使用任何方法。
(4) 训练算法:此步骤不适用于k-近邻算法。
(5) 测试算法:计算错误率。
(6) 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输
入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。

首先创建一个KNN.py文件,代码是k-近邻算法的实现代码,全部是用命令的方式启动的,可以直接在pycharm的终端中运行项目,也可以用cmd运行项目
编写基本通用函数

命令行中语句:

# 第一个是科学计算包NumPy;第二个是运算符模块
from numpy import *
import operator

def createDataSet():
    group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels

在terminal中运行,下同
import KNN
group, labels = KNN.createDataSet()
group
labels

def classify0(inX, dataSet, labels, k):
    # 距离计算
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat ** 2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances ** 0.5
    sortedDistIndicies = distances.argsort()
    classCount = {}
    # 选择距离最小的K个点
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    # 排序
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

KNN.classify0([0,0], group, labels, 3)

# 将文本记录转换为NumPy的解析程序
def file2matrix(filename):
    fr = open(filename)
    arrayOLines = fr.readlines()
    # 打开文件,得到文件行数
    numberOfLines = len(arrayOLines)
    # 创建返回的Numpy矩阵,矩阵以0进行填充
    returnMat = zeros((numberOfLines, 3))
    classLabelVector = []
    index = 0
    # 解析文件数据到列表
    for line in arrayOLines:
        # 首先使用函数line.strip()截取掉所有的回车字符,
        line = line.strip()
        # 使用tab字符\t将上一步得到的整行数据分割成一个元素列表
        listFormLine = line.split('\t')
        # 我们选取前3个元素,将它们存储到特征矩阵中
        returnMat[index, :] = listFormLine[0: 3]
        # 将列表中元素存储为整型,否则会按照字符串进行处理
        # 注意这里不是单纯的把字符串改为整型数据,而是改成表,网上找的别人的解释
        labels = {'didntLike': 1, 'smallDoses': 2, 'largeDoses': 3}  # 新增
        classLabelVector.append(labels[listFormLine[-1]])  # 去掉了int
        # classLabelVector.append(int(listFormLine[-1]))
        index += 1
    return returnMat, classLabelVector

import importlib
importlib.reload(KNN)
这里需要将数据导入项目中,因为要从datingTestSet.txt读取数据
完全按照书中的方式会出现错误,网上有人给出了方法
datingDataMat, datingLabels = KNN.file2matrix(‘datingTestSet.txt’)
datingDataMat
datingLabels[0: 20]

②分析数据:使用 Matplotlib 创建散点图
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
#Matplotlib库提供的scatter函数支持个性化标记散点图上的点
ax.scatter(datingDataMat[:,1], datingDataMat[:,2])
plt.show()

from numpy import *
ax.scatter(datingDataMat[:,1], datingDataMat[:,2], 15.0array(datingLabels),15.0array(datingLabels))
更改scatter中的参数时,会出现array错误,此时将所需要的包导入进来即可

# 归一化特征值
def autoNorm(dataSet):
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals
    normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0]
    # 矩阵除法
    normDataSet = dataSet - tile(minVals, (m, 1))
    # 特征值相除
    normDataSet = normDataSet / tile(ranges, (m, 1))
    return normDataSet, ranges, minVals

importlib.reload(KNN)
normMat, ranges, minVals = KNN.autoNorm(datingDataMat)
normMat
ranges
minVals

# 分类器针对约会网站的测试代码
def datingClassTest():
    hoRatio = 0.10
    # 从文件中读取数据并将其转换为归一化特征值
    datingDataMat, datingLabels = file2matrix('datingTestSet.txt')
    normMat, ranges, minVals = autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m * hoRatio)
    errorCount = 0.0
    for i in range(numTestVecs):
        classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
        print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]))
        if classifierResult != datingLabels[i]:
            errorCount += 1.0
    # 计算错误率并输出结果
    print("the total error rate is %f" % (errorCount / float(numTestVecs)))

importlib.reload(KNN)
KNN.datingClassTest()

# 约会网站预测函数
def classifyPerson():
    resultList = ['not at all', 'in small doses', 'in large doses']
    percentTats = float(input("percentage of time spent playing video games?"))
    ffMiles = float(input("frequent flier miles earned per year?"))
    iceCream = float(input("liters of ice cream consumed per year?"))
    datingDataMat, datingLabels = file2matrix2('datingTestSet2.txt')
    normMat, ranges, minVals = autoNorm(datingDataMat)
    inArr = array([ffMiles, percentTats, iceCream])
    classifierResult = classify0((inArr - minVals) / ranges, normMat, datingLabels, 3)
    print("You will probably like this person: ", resultList[classifierResult - 1])

importlib.reload(KNN)
KNN.classifyPerson()

手写识别系统

# 将数据处理成分类器可以识别的格式
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

importlib.reload(KNN)
testVector = KNN.img2vector(‘testDigits/0_13.txt’)
testVector[0, 0:31]
testVector[0, 32:63]

# 函数handwritingClassTest()是测试分类器的代码
def handwritingClassTest():
    hwLabels = []
    # 将trainingDigits目录中的文件内容存储在列表中
    trainingFileList = listdir('trainingDigits')
    # 可以得到目录中有多少文件,并将其存储在变量m中
    m = len(trainingFileList)
    # 代码创建一个m行1024列的训练矩阵,该矩阵的每行数据存储一个图像
    trainingMat = zeros((m, 1024))
    # 从文件名解析分类数字
    for i in range(m):
        fileNameStr = trainingFileList[i]
        fileStr = fileNameStr.split('.')[0]
        classNumStr = int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        # 使用img2vector函数载入图像
        trainingMat[i, :] = img2vector('trainingDigits/%s' % fileNameStr)
    testFileList = listdir('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('testDigits/%s' % fileNameStr)
        # 使用classify0()函数测试该目录下的每个文件
        classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
        print("the classifer came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
        if classifierResult != classNumStr:
            errorCount += 1.0
    print("\nthe total number of errors is: %d" % errorCount)
    print("\nthe total error rate is: %f" % (errorCount / float(mTest)))

importlib.reload(KNN)
KNN.handwritingClassTest()

代码是跟着书上的敲的,书上使用的是python2,目前大家使用的是python3,我全部使用python3跑通了,有的直接指出来了,有的在代码里直接改了

看书,看书,看书。和同组的其他人相比,好菜啊,加油吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值