ML_inAction—Chapetr2--(2) kNN算法改进约会网站
1.python预备知识
1.1 readlines()
fileObject.readlines( ) 无参数,返回列表,包含所有的行
1.2 zeros()、ones()、empty()
ones函数可以创建任意维度和元素个数的数组,其元素值均为1;
empty一样,只是它所常见的数组内所有元素均为空,没有实际意义,所以它也是创建数组最快的方法。
zeros、ones、empty的使用方法差不多
创建一个一维数组时,只需要一个参数就可以了,代表数组长度。
在默认的情况下,zeros创建的数组元素类型是浮点型的,如果要使用其他类型,可以设置dtype参数进行声明

创建多维数组,但是多维数组的创建,参数形式需要注意,如下:

同样可以使用第二个参数设置数组元素类型。
2.从文本中解析数据
!注意书中给的文本数据之间用TAB隔开,因此用split(“\t”)
#程序清单2.2 从文本中解析数据 def file2matrix(filename,feature_num): feature_num = int(feature_num) with open(filename) as f: fline = f.readlines() line_num = len(fline) returnMat = zeros((line_num,feature_num)) index = 0 label_vector = [] for line in fline: line_digit = line.strip().split('\t') #字符串转浮点型,不过其实是多余的 index1 = 0 for item in line_digit: line_digit[index1] = float(item) index1 += 1 returnMat[index,:] = line_digit[0:feature_num] index += 1 label_vector.append(int(line_digit[-1])) return returnMat,label_vector #2.2 test import kNN date_dataSet,date_labels = kNN.file2matrix('datingTestSet2.txt',3) print date_dataSet print date_labels[0:10] print type(date_dataSet) #书中给的程序并未将字符串转浮点型,但给的结果中数组元素是浮点型的,有点奇怪 #自己用小例子试了下,确实是可以自动转换成浮点类型数据的 from numpy import * aa = ' 1 2 3 ' aa = aa.strip() bb = aa.split('\t') cc = zeros((1,3)) cc[0,:] = bb[0:3] print cc print type(cc) >>>[[1. 2. 3.]] >>><type 'numpy.ndarray'>
3.matplotlib
3.1 python 画子图(add_subplot & subplot)
子图:就是在一张figure里面生成多张子图。
Matplotlib对象简介
FigureCanvas 画布
Figure 图
Axes 坐标轴(实际画图的地方)

注意,pyplot的方式中plt.subplot()参数和面向对象中的add_subplot()参数和含义都相同。
使用面向对象的方式:
#!/usr/bin/python #coding: utf-8 import numpy as np import matplotlib.pyplot as plt x = np.arange(0, 100) fig = plt.figure()
ax1 = fig.add_subplot(221) ax1.plot(x, x) ax2 = fig.add_subplot(222) ax2.plot(x, -x) ax3 = fig.add_subplot(223) ax3.plot(x, x ** 2) ax4 = fig.add_subplot(224) ax4.plot(x, np.log(x)) plt.show()
pyplot的方式:
#!/usr/bin/python #coding: utf-8 import numpy as np import matplotlib.pyplot as plt x = np.arange(0, 100) plt.subplot(221) plt.plot(x, x) plt.subplot(222) plt.plot(x, -x) plt.subplot(223) plt.plot(x, x ** 2) plt.subplot(224) plt.plot(x, np.log(x)) plt.show()

简易教程见:https://blog.csdn.net/Notzuonotdied/article/details/77876080
关于散点图scatter函数,参考https://www.cnblogs.com/shanlizi/p/6850318.html
def scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None,
alpha=None, linewidths=None, verts=None, edgecolors=None, hold=None, data=None, **kwargs)
---------------------
#注意关键字参数s此处应该是数组,颜色参数也是,并按照关键字传参 #不知道为什么书里面的例子没有按照关键字传参也行 import kNN date_dataSet,date_labels = kNN.file2matrix('datingTestSet2.txt',3) # print date_dataSet print date_labels[0:10] print type(date_dataSet) from numpy import array #没有这句话会报错? import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(date_dataSet[:,1],date_dataSet[:,2],s=15*array(date_labels),c=15*array(date_labels)) plt.show()
补一个:https://blog.csdn.net/luoganttcc/article/details/64440091
3.2 归一化特征值
书里采用的归一化方法为:newValue = (oldvalue - minvalue)/(maxvalue-minvalue)
#程序清单2.3 归一化特征值 ''' >>> a = array([[1,2,3],[0,0,0],[-1,-2,-3],[2,2,2]]) >>> a.min(0) #表示不同列相比较得出最小,并返回一个结果数组 array([-1, -2, -3]) >>> a.min(1) #表示每一行自身元素相互比较得出最小 array([ 1, 0, -3, 2]) 此外,两个数组进行四则运算就是对各对应元素分别进行运算 ''' def autoNorm(dataSet): minValue = dataSet.min(0) maxValue = dataSet.max(0) data_range = maxValue - minValue dataSet_num = dataSet.shape[0] dataSet_norm = (dataSet - tile(minValue,(dataSet_num,1)))/tile(data_range,(dataSet_num,1)) #norm return dataSet_norm,data_range,minValue #2.3 test import kNN date_dataSet,date_labels = kNN.file2matrix('datingTestSet2.txt',3) dataSet_norm,data_range,minValue = kNN.autoNorm(date_dataSet) print dataSet_norm[0:3,:],'\n' print data_range,'\n' print minValue #result [[0.44832535 0.39805139 0.56233353] [0.15873259 0.34195467 0.98724416] [0.28542943 0.06892523 0.47449629]] [9.1273000e+04 2.0919349e+01 1.6943610e+00] [0. 0. 0.001156]
3.4 分类器测试代码——基于约会网站例子
#程序清单2.4 分类器测试代码——基于约会网站例子 ''' 这里假设所有的样本分布是随机的,故简化地取前10%为测试样本,其余为训练集(留出法) 1.解析数据为数据型输入特征和类别 2.归一化数据 3.分测试集和训练集 4.训练模型(kNN无此步骤)计算错误率 ''' def dateClassTest(filename,feature_num,k,kk): #kk = testSet_num/total_sample_num #k : the k of kNN returnMat,label_vector = file2matrix(filename,feature_num) dataSet_norm,data_range,minValue = autoNorm(returnMat) #choose testSet and trainSet m = dataSet_norm.shape[0] testSet = dataSet_norm[:int(kk*m),:] trainSet = dataSet_norm[int(kk*m):,:] test_label = label_vector[:int(kk*m)] #label_vector is a list train_label = label_vector[int(kk*m):m] label_index = 0 error_count = 0 for i in testSet: class_predict = classify0(i,trainSet,train_label,k) if class_predict != test_label[label_index]: error_count += 1 print "the class_predict is: %d ,but the real class is: %d"\ %(class_predict,test_label[label_index]) label_index += 1 error_rate = float(error_count/(kk*m)) return error_rate #test: import kNN filename = 'datingTestSet2.txt' feature_num = 3 k = 5 kk = 0.1 print kNN.dateClassTest(filename,feature_num,k,kk) #result: the class_predict is: 2 ,but the real class is: 3 the class_predict is: 3 ,but the real class is: 1 the class_predict is: 2 ,but the real class is: 3 the class_predict is: 2 ,but the real class is: 1 0.04
最后,来聊聊raw_input()和input():
python3中已将raw_input()函数删了,因此,来看看python2和3中的input有啥区别,以及python2中raw_input()和input()的区别
#1. python2和3中的input的区别 #先看py2的input >>> aa = input('aa = ') aa = 1 >>> type(aa) <type 'int'> #输入数字返回的是数字 >>> aa = input('aa = ') aa = china no.1 Traceback (most recent call last): File "<pyshell#12>", line 1, in <module> aa = input('aa = ') File "<string>", line 1 china no.1 ^ SyntaxError: invalid syntax #输入没加引号的字符串,报错! >>> aa = input('aa = ') aa = 'china no.1' >>> aa 'china no.1' >>> type(aa) <type 'str'> #输入带引号的字符串,返回带引号的字符串 #再看看py3的input >>> aa = input('aa = ') aa = 1 >>> type(aa) <class 'str'> #输入数字返回的是字符串!! >>> aa '1' >>> aa = input('aa = ') aa = china no.1 forever >>> aa 'china no.1 forever' #输入没加引号的字符串,返回的是字符串 >>> aa = input('aa = ') aa = 'china no.1 forever' >>> aa "'china no.1 forever'" #输入带引号的字符串,返回带更外一层引号的字符串
#2. python2中raw_input()和input()的区别 >>> aa = raw_input('aa = ') aa = 1 >>> aa '1' >>> aa = raw_input('aa = ') aa = china no.1 forever >>> aa 'china no.1 forever' >>> aa = raw_input('aa = ') aa = 'china no.1 forever' >>> aa "'china no.1 forever'" #obvious,python2中的raw_input()就是python3的input()~
小结:
python2的input():输入数字返回数字;要输入字符串需给字符串加引号(否则报错),返回的字符串不会再添加一层引号!
python3的input():不管输入什么类型的数据(数字、字符串、列表...)均返回字符串,并添加一层引号!
python2中的raw_input()就是python3的input()
浙公网安备 33010602011771号