继续学习机器学习实战
今天主要学习的是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'>