ML_inAction—Chapetr2--(2) kNN算法改进约会网站

1.python预备知识

1.1 readlines()

fileObject.readlines( )   无参数,返回列表,包含所有的行

1.2 zeros()、ones()、empty()

在给数组赋初始值的时候,经常会用到0数组,而Python中,我们使用zeros()函数来实现。
ones函数可以创建任意维度和元素个数的数组,其元素值均为1;
empty一样,只是它所常见的数组内所有元素均为空,没有实际意义,所以它也是创建数组最快的方法。
zeros、ones、empty的使用方法差不多
创建一个一维数组时,只需要一个参数就可以了,代表数组长度。

在默认的情况下,zeros创建的数组元素类型是浮点型的,如果要使用其他类型,可以设置dtype参数进行声明

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

同样可以使用第二个参数设置数组元素类型。

ones和empty示例,注意empty创建的数组中,包含的均是无意义的数值。

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()

 

 

posted @ 2018-10-29 21:11  bo0814  阅读(89)  评论(0)    收藏  举报