《机器学习实战》笔记(三) 示例1

使用k-近邻算法改进约会网站的配对效果

 

一、 准备数据:从文本中解析

1.数据:datingTestSet2.txt :一个数据一行,共1000行

  三种特征:飞行里程数 视频游戏耗时 冰淇淋数

 

2.函数:file2matrix(filename):

使用:datingDataMat, datingLabels = file2matrix(‘datingTestSet2.txt’) 

用于处理文本格式文件的函数,将文本格式的数据变为可用于输入模型的数据

如果不是都放在KNN.py里面或者是在命令提示符里面使用用KNN.file2matrix()

# 文本转矩阵
def file2matrix(filename):
    fr = open(filename)                         # 打开文件
    arrayOLines = fr.readlines()                 # readlines()自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for... in ... 结构进行处理
                                                # readline()每次只读取一行
    numberOfLines = len(arrayOLines)            # 得到文件行数
    returnMat = zeros((numberOfLines,3))        # 创建返回的numpy矩阵  3是三个属性 里程数 百分比和冰淇淋公升数
    classLabelVector = []                       # 创建标签向量 类型为列表
    fr = open(filename)                         # 没写这行就一直报could not convert string to float的错囧 也不知道为啥
    index = 0

    for line in arrayOLines:                                 # 从文件所得的行列表的第一行开始
        line = line.strip()                                  # strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
        listFromLine = line.split('\t')                     # split()通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串    split(str=" ", num = 2)
                                                            # \t  水平制表(HT) (跳到下一个TAB位置)
        returnMat[index,:] = listFromLine[0:3]              # 选取前三个元素,存储在特征矩阵的第i行中
        classLabelVector.append(int(listFromLine[-1]))      # list[-1]取从最后一个元素往前第几个  -1就是取最后一个
                                                            # 此处最后一个味属性 所以将属性标签放到标签类别的vector里
        index += 1                                          # 下一行的转换
    return returnMat,classLabelVector

 

二、分析数据

三、准备数据:归一化数值

函数:autoNorm(dataSet)

#归一化数据处理
def autoNorm(dataSet):
    minVals = dataSet.min(0)        # 得到每一列的最小值     min() 参数为0表示从列中选最小值,1位从行中选最小值
    maxVals = dataSet.max(0)        # 得到每一列的最大值
    ranges = maxVals - minVals     # 得到每一列最大值-最小值的差
    normDataSet = zeros(shape(dataSet))     # dataSet形状的全0矩阵
    m = dataSet.shape[0]            # shape[0]为行数
    normDataSet = dataSet - tile(minVals,(m,1))     # tile(minVals,(m,1))得到一个每列都为min的和dataSet形状相同的矩阵 每个数都减去了最小值
    normDataSet = normDataSet / tile(ranges,(m,1))  # 每个数都除以ranges
    return normDataSet,ranges,minVals

 

四、测试算法

函数:datingClassTest()

def datingClassTest():
    hoRatio = 0.10                                                      # 使用真实数据的多大部分来作为测试集
    datingDataMat,datingLables = file2matrix('datingTestSet2.txt')    # 将datingTestSet2.txt中的内容转化为数据矩阵和标签矩阵
    normMat,ranges,minVals = autoNorm(datingDataMat)                    # 对数据进行归一化
    m = normMat.shape[0]                                                # m为数据矩阵的行数 即有多少个数据
    numTestVecs = int(m*hoRatio)                                        # 测试集数量为 数据总数* 百分比
    errorCount = 0.0                                                    # 初始错误个数为0
    for i in range(numTestVecs):                                        # 对1 - 测试个数 的每一个样本
        # 输入归一化数据的第i行,输出,标签向量,k
        # 用于分类的输入向量(未知样本)——normMat[i,:]      dataSet——normMat[numTestVecs:m,:]   normMat中从numTestVecs到m行的所有列
        # lables——datingLables[numTestVecs:m]               k——3
        classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLables[numTestVecs:m],3)
        print("the classifier came back with:%d, the real anser is: %d" % (classifierResult,datingLables[i]))
        if (classifierResult!=datingLables[i]):
            errorCount += 1
    print("the total error rate is : %f" % (errorCount/float(numTestVecs)))

 

五、使用算法

函数:classifyPerson()

def classifyPerson():
    resultList = ['not at all','in small doses','in large doses']
    percentTats = float(input("percentage of time spent playing video games?\n"))     # python3中将 raw_input() 重命名为 input()
    ffmiles = float(input("frequent flier miles earned per year?\n"))
    iceCream = float(input("liters of ice cream consumed per year\n"))                # 得到三个属性的输入
    datingDataMat,datingLabels = file2matrix("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])      # 训练集中喜欢不喜欢的分类是1 2 3  但是在结果标签中下标为0 1 2 因此要-1

 

猜你喜欢

转载自blog.csdn.net/qq_22527013/article/details/81221355
今日推荐