[2] Python KNN用于约会网站的配对效果

继续学习机器学习实战

今天主要学习的是Python从txt文件读取数据,处理数据(归一化处理),分析数据(画图),测试算法,使用算法(预测分类的结果)

首先在网上下载了书的源代码(只是为了拿到测试用的数据)

首先插入今天新加的代码:

from numpy import *
import operator 
def classify0(inX, dataset,labels,k):
    # 计算输入数据和已有所有数据的距离
    dataSetSize=dataset.shape[0]
    diffMat=tile(inX,(dataSetSize,1))-dataset
    sqDiffMat=diffMat**2
    sqDistances=sqDiffMat.sum(axis=1) #没有axis参数表示全部相加,axis=0表示按列相加,axis=1表示按照行的方向相加
    distances=sqDistances**0.5
    
    #排序
    sortedDistIndex=distances.argsort()  #argsort将数据从小到大排列,并返回其索引值
    # 选择距离最小的k个点
    classCount={} #字典类型
    
    for i in range(k):
        votelabel=labels[sortedDistIndex[i]]
        classCount[votelabel]=classCount.get(votelabel,0)+1
    sortedClasscount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    
    return sortedClasscount[0][0] 

# 读取txt文件中的数据
def file2matrix(filename):
    fr=open(filename)
    arrayOLines=fr.readlines() #读取每行
    numberOfLines=len(arrayOLines)
    returnMat=zeros((numberOfLines,3))
    classLabelVector=[]
    index=0
    
    for line in arrayOLines:
        line=line.strip()  #去掉每行头尾空白
        listFromLine=line.split('\t') #用tab字符将整行数据分割成一个元素列表
        returnMat[index,:]=listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index+=1
    return returnMat,classLabelVector

# 对数据进行归一化处理
def autoNorm(dataSet):
    minvalue=dataSet.min(0) #0是从列中取得最小值
    maxvalue=dataSet.max(0)
    ranges=maxvalue-minvalue
    normDataSet=zeros(shape(dataSet))
    m=dataSet.shape[0]
    normDataSet=dataSet-tile(minvalue,(m,1))
    normDataSet= normDataSet/tile(ranges,(m,1))
    return normDataSet,ranges,minvalue

# 用错误率测试算法,这里选择了10%做测试数据集,90%做训练集
def datingClassTest():
    hoRatio=0.10
    datingDataset,datingLabels=file2matrix('datingTestSet2.txt')
    normMat,ranges,minValue=autoNorm(datingDataset)
    m=normMat.shape[0]
    numTestVecs=int(m*hoRatio)
    errorCount=0.0
    
    for i in range(numTestVecs):
        classifyResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],\
                                 datingLabels[numTestVecs:m],3) #分类
        print( "分类结果:%d,真实的类别:%d" %(classifyResult, datingLabels[i]))
        if (classifyResult!=datingLabels[i]): errorCount+=1.0
    print ("总的错误率是%f" %(errorCount/float(numTestVecs)))
# 预测新输入的数据的分类情况  
def classfyPerson():
    resultList=['not at all','in small doses','in large doses']
    percentTats=float(input("玩视频游戏时间百分比(0-100)"))
    ffMiles=float(input("每年获取的飞行常客里程数"))
    iceCream=float(input("每周消费的冰淇淋公升数"))
    datingData,datingLabels=file2matrix('datingTestSet2.txt')
    normData,ranges,minvalue=autoNorm(datingData)
    inArr=array([percentTats, ffMiles,iceCream])
    inArrNorm=(inArr-minvalue)/ranges
    classfyResult=classify0(inArrNorm,normData,datingLabels,3)
    print("你喜欢与这个人约会的可能性:%s" %(resultList[classfyResult-1]))

有了第一个简单KNN的铺垫,对算法的理解倒是没有问题,这里主要学习的是整个算法从处理数据、测试算法到使用算法的过程。

同样地,对于python小白来说,简单梳理一下今天碰到的新问题,方便以后查阅,也加深自己的理解。

  • 读取文件中的数据

  file对象用open来创建,三种读取的函数,现有一个txt文件

  file.read([size])

  

fr=open('1.txt')
>>> fr.read()
'34 56\n78 rr\nToday is Tuesday.'

  参数是读取的字节,包括空格和'\n'

  

fr=open('1.txt')
>>> fr.read(10)
'34 56\n78 r'

  另外一种读取函数是file.readline([size]),读取整行,包括'\n'

  

fr=open('1.txt')
>>> fr.readline()
'34 56\n'

  默认读取第一行,这是对象还在,可以继续读取

fr.readline(4)
'78 r'

  还有一种读取是file.readlines()

  用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for... in ... 结构进行处理。 如果碰到结束符 EOF 则返回空字符串。

如果碰到结束符 EOF 则返回空字符串。

fr=open('1.txt')
>>> fr.readlines()
['34 56\n', '78 rr\n', 'Today is Tuesday.']
>>> fr=open('1.txt')
for line in fr.readlines():
    line=line.strip()
    print("数据:%s" %(line))

    
数据:34 56
数据:78 rr
数据:Today is Tuesday.

  这样就可以根据实际的使用需求选择合适的读取方法了。

  • strip

  用于移除字符串头尾指定的字符(默认为空格)。

  

str1 = "  1.txt   "
>>> print(str1.strip())
1.txt

  也可以指定字符

str2="000034560000"
>>> print(str2.strip('0'))
3456
  • split

   通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则仅分隔 num 个子字符串

  

str.split(str="", num=string.count(str)).

  str -- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。

  

str3 = "Line1-abcdef \nLine2-abc \nLine4-abcd"
>>> print(str3.split())
['Line1-abcdef', 'Line2-abc', 'Line4-abcd']
print(str3.split(' ',1))
['Line1-abcdef', '\nLine2-abc \nLine4-abcd']
  • input

Python3.x 中 input() 函数接受一个标准输入数据,返回为 string 类型。

Python2.x 中 input() 相等于 eval(raw_input(prompt)) ,用来获取控制台的输入。

raw_input() 将所有输入作为字符串看待,返回字符串类型。而 input() 在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型( int, float )。

注意:python3 里 input() 默认接收到的是 str 类型。

>>> a=input("input:")
input:123
>>> type(a)
<class 'str'>

 

posted @ 2018-04-12 09:10  mzhourr  阅读(558)  评论(0编辑  收藏  举报