机器学习实战这本书是在python2.x的环境下写的,而python3.x中好多函数和2.x中的名称或使用方法都不一样了,因此对原书中的内容需要校正,下面简单的记录一下学习过程中fix的部分

1、print 函数后面需要加括号(程序清单2-4开始出现print函数)

2、raw_input改为input函数,在3.x中python使用input替代了raw_input函数(程序清单2-5)

3、reload(KNN)->import importlib

importlib.reload(KNN)

4、程序清单3-6中

在python2.7中,找到key所对应的第一个元素为:firstStr = myTree.keys()[0],这在python3.4中运行会报错:‘dict_keys‘ object does not support indexing,这是因为python3改变了dict.keys,返回的是dict_keys对象,支持iterable 但不支持indexable,我们可以将其明确的转化成list,则此项功能在python3中应这样实现:

firstSides = list(myTree.keys()) 
firstStr = firstSides[0]#找到输入的第一个元素

5、程序清单3-9

pickle对数据进行持久化的时候是采用二进制的方式进行存储和读取的,所以写入文件的时候将

fw=open(filename,'w')---->fw=open(filename,'wb')

将文件以二进制的形式打开,方便pickle的写入

从文件中读取数据的时候也要用二进制的方式读取做以下修改

fr=open(filename)---->fr=open(filename,'rb')

6、程序清单4-5中

wordList=textParse(open('ch04/email/ham/%d.txt' % i).read())

这一句在运行的时候老是报编码错误,结果是读取的文件中有乱码,删除乱码后问题解决

错误代码如下:

UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 199: illegal multibyte sequence

trainingSet=range(50);

del(trainingSet[randIndex])

由于range不能返回List,不支持del操作,所以运行时出现以下错误:

TypeError: 'range' object doesn't support item deletion

可以将代码修改为:

trainingSet = list(range(50));

7.代码清单8-5

由于程序运行在python3.x 环境下,而python3.x中用urllib代替了 urllib2函数库

所以 import urllib2--->import urllib.request

之所以用urllib.request是因为urllib2.open()方法在python3.x中已经升级成为了urllib.request.open(),所以做此改动,可保无失

另外,由于原文提及的Google购物API服务已经关闭,所以只能从作者下载的相关页面中提取乐高积木的价格了,需要增加以下函数用于分析页面获取价格数据:

from BeautifulSoup import BeautifulSoup
# 从页面读取数据,生成retX和retY列表
def scrapePage(retX, retY, inFile, yr, numPce, origPrc):
    # 打开并读取HTML文件
    fr = open(inFile,encoding='utf-8')#规定读取文件时编码的格式
    soup = BeautifulSoup(fr.read())
    i=1
    # 根据HTML页面结构进行解析
    currentRow = soup.findAll('table', r="%d" % i)
    while(len(currentRow)!=0):
        currentRow = soup.findAll('table', r="%d" % i)
        title = currentRow[0].findAll('a')[1].text
        lwrTitle = title.lower()
        # 查找是否有全新标签
        if (lwrTitle.find('new') > -1) or (lwrTitle.find('nisb') > -1):
            newFlag = 1.0
        else:
            newFlag = 0.0
        # 查找是否已经标志出售,我们只收集已出售的数据
        soldUnicde = currentRow[0].findAll('td')[3].findAll('span')
        if len(soldUnicde)==0:
            print "item #%d did not sell" % i
        else:
            # 解析页面获取当前价格
            soldPrice = currentRow[0].findAll('td')[4]
            priceStr = soldPrice.text
            priceStr = priceStr.replace('$','') #strips out $
            priceStr = priceStr.replace(',','') #strips out ,
            if len(soldPrice)>1:
                priceStr = priceStr.replace('Free shipping', '')
            sellingPrice = float(priceStr)
            # 去掉不完整的套装价格
            if  sellingPrice > origPrc * 0.5:
                    print "%d\t%d\t%d\t%f\t%f" % (yr,numPce,newFlag,origPrc, sellingPrice)
                    retX.append([yr, numPce, newFlag, origPrc])
                    retY.append(sellingPrice)
        i += 1
        currentRow = soup.findAll('table', r="%d" % i)

同时,SetDATaCollect函数也要做相应的修改:

# 依次读取六种乐高套装的数据,并生成数据矩阵       
def setDataCollect(retX, retY):
    scrapePage(retX, retY, '/setHtml/lego8288.html', 2006, 800, 49.99)
    scrapePage(retX, retY, '/setHtml/lego10030.html', 2002, 3096, 269.99)
    scrapePage(retX, retY, '/setHtml/lego10179.html', 2007, 5195, 499.99)
    scrapePage(retX, retY, '/setHtml/lego10181.html', 2007, 3428, 199.99)
    scrapePage(retX, retY, '/setHtml/lego10189.html', 2008, 5922, 299.99)
    scrapePage(retX, retY, '/setHtml/lego10196.html', 2009, 3263, 249.99)

8、代码清单9-1

在函数loadDataSet中

fltLine = list(map(float, curLine))#将每行映射成浮点数,python3 map返回值改变,所以需要添加list()函数

在函数binSplitDataSet中

    #mat0 = dataSet[nonzero(dataSet[:, feature] > value)[0], :][0]
#mat1 = dataSet[nonzero(dataSet[:, feature] <= value)[0], :][0]

改为:

mat0 = dataSet[nonzero(dataSet[:, feature] > value)[0], :]
mat1 = dataSet[nonzero(dataSet[:, feature] <= value)[0], :]

逻辑上mat0,mat1返回的是划分后的新矩阵,而不是矩阵的第一行

9、程序清单9-2

在chooseBestSplit函数中,由于Matrxi类型不能被Hash(featIndex是随机数)

将代码

for splitVal in set(dataSet[:,featIndex]): 

改为:

for splitVal in set((dataSet[:,featIndex].T.A.tolist())[0]): 
 

10、9.7.1节用Tkinter创建GUI

#windows下python3.2版本之后是自动安装tkinter的,python3.3的引入方式为:
>>> import _tkinter
>>> import tkinter
>>> tkinter._test() #弹出测试窗口
>>>
#第一个小测试
>>> root=Tk() #创建一个空的tk窗口,注意弹出后不要关闭,然后继续输入下一行
>>> myLabel=Label(root,text="hello,Tkinter!")
>>> myLabel=grid()#输入以上两行,框内显示文字
>>> #使程序完整:
>>> root.mainloop()

11、treeExplorer.py代码修改如下:(标红的地方为修改的地方)

from numpy import *
from tkinter import *
import regTrees
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg def reDraw(tolS,tolN):
reDraw.f.clf()#清空画布
reDraw.a=reDraw.f.add_subplot(111)#添加新的子图
if chkBtnVar.get():
#检查复选框是否被选中
if tolN<2:tolN=2
myTree=regTrees.createTree(reDraw.rawdata, regTrees.modelLeaf, regTrees.modelErr,(tolS,tolN))
yHat=regTrees.createForeCast(myTree,reDraw.testdata,regTrees.modelTreeEval)
else:
myTree=regTrees.createTree(reDraw.rawdata,ops=(tolS,tolN))
yHat=regTrees.createForeCast(myTree,reDraw.testdata)
reDraw.a.scatter(reDraw.rawdata[:,0].tolist(),reDraw.rawdata[:,1].tolist(),s=5)#绘出真实值,散点图
reDraw.a.plot(reDraw.testdata,yHat,linewidth=2.0)#绘出测试值,曲线图
reDraw.canvas.show() def getInputs():
try:tolN=int(tolNentry.get())
except:
tolN=10
print("enter Integer for tolN")
#❷(以下两行) 清除错误的输入并用默认值替换
tolNentry.delete(0, END)
tolNentry.insert(0,'')
try:tolS=float(tolSentry.get())
except:
tolS=1.0
print("enter Float for tolS")
tolSentry.delete(0,END)
tolSentry.insert(0,'1.0')
return tolN,tolS def drawNewTree():
tolN,tolS=getInputs()
reDraw(tolS, tolN) root=Tk()
#Label(root,text="plot place Holder").grid(row=0,columnspan=3)
#利用TkAgg创建画布
reDraw.f=Figure(figsize=(5,4),dpi=100)
reDraw.canvas=FigureCanvasTkAgg(reDraw.f,master=root)
reDraw.canvas.show()
reDraw.canvas.get_tk_widget().grid(row=0,columnspan=3)#widget:部件 Label(root,text="tolN").grid(row=1,column=0)
tolNentry=Entry(root)#Entry:文本输入框
tolNentry.grid(row=1,column=1)
tolNentry.insert(0,'')
Label(root,text="tolS").grid(row=2,column=0)
tolSentry=Entry(root)#文本输入框
tolSentry.grid(row=2,column=1)
tolSentry.insert(0,'1.0')
Button(root,text="ReDraw",command=drawNewTree).grid(row=1,column=2,rowspan=3)
chkBtnVar=IntVar()#按钮整数值ֵ
chkBtn=Checkbutton(root,text="Model Tree",variable=chkBtnVar)#复选框
chkBtn.grid(row=3,column=0,columnspan=2)
reDraw.rawdata=mat(regTrees.loadDataSet('sine.txt'))
reDraw.testdata=arange(min(reDraw.rawdata[:,0]),max(reDraw.rawdata[:,0]),0.01)
reDraw(1.0,10)
root.mainloop()

12、使用K均值聚类,并使用该算法计算波兰的酒吧聚集地及可以到各个酒吧的最佳位置。由于国内使用YahooAPi的地图功能,故使用百度地图提供的API代替,整个代码现改如下:

from numpy import *
from matplotlib.markers import MarkerStyle
def loadDataSet(filename):
dataMat=[]
fr=open(filename)
for line in fr.readlines():
curLine=line.strip().split('\t')
fltLine=list(map(float,curLine))
dataMat.append(fltLine)
return dataMat #计算欧几里德距离
def distEclud(vecA,vecB):
return sqrt(sum(power(vecA-vecB,2))) #生成随机中心质点
def randCent(dataSet,k):
n=shape(dataSet)[1]
centroids=mat(zeros((k,n)))
#构建簇质心
for j in range(n):
minJ=min(dataSet[:,j])
rangeJ=float(max(dataSet[:,j])-minJ)
centroids[:,j]=minJ+rangeJ*random.rand(k,1)#random.rand生成k行1列的数组,其中元素值均分布在(0,1)范围内,实际上是每列对应向量的计算
return centroids #k-均值聚类算法
def kMeans(dataSet,k,distMeas=distEclud,createCent=randCent):
m=shape(dataSet)[0]
clusterAssment=mat(zeros((m,2)))#簇分配结果矩阵(该表是质心变化记录表,m代表元素个数,第一列存放的是距离该点最近的质心,第二列出存放的距该质心的距离的平方)
centroids=createCent(dataSet,k)
clusterChanged=True
while clusterChanged:
clusterChanged=False
for i in range(m):
minDist=inf;minIndex=-1
for j in range(k):
#❶(以下三行) 寻找最近的质心
distJI=distMeas(centroids[j,:],dataSet[i,:])#寻找距离i点最近的质心
if distJI<minDist:
minDist=distJI;minIndex=j
if clusterAssment[i,0]!=minIndex:clusterChanged=True
clusterAssment[i,:]=minIndex,minDist**2
#❷(以下四行) 更新质心的位置
print(centroids)
#获取新的K个点作为新的质心
for cent in range(k):
ptsInClust=dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#返回该质点对应的所有DataSet中的点(所有距离该质心距离最短的点)
centroids[cent,:]=mean(ptsInClust,axis=0)#按列(压缩行)返回均值(返回每列的平均值),产生新的质心
return centroids,clusterAssment #二分K-均值聚类算法
def biKmeans(dataSet,k,distMeas=distEclud):
m=shape(dataSet)[0]
clusterAssment=mat(zeros((m,2)))
#❶(以下两行) 创建一个初始簇
centroid0=mean(dataSet,axis=0).tolist()[0]#所有点的平均值:绝对中心位置
centList=[centroid0]
for j in range(m):
clusterAssment[j,1]=distMeas(mat(centroid0),dataSet[j,:])**2#计算所有点距离中心点的距离平方
while(len(centList)<k):#质点不足K个
lowestSSE=Inf#SSE:距离质点的距离平方和
for i in range(len(centList)):
#❷(以下两行) 尝试划分每一簇
ptsInCurrCluster=dataSet[nonzero(clusterAssment[:,0].A==i)[0],:]
centroidMat,splitClusAss=kMeans(ptsInCurrCluster,2,distMeas)
sseSplit=sum(splitClusAss[:,1])#新划分的簇质点距离平方和
sseNotSplit=sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1])#老簇除了第i个质点外距离平方和
print("sseSplit,and notSplit",sseSplit,sseNotSplit)
if(sseSplit+sseNotSplit)<lowestSSE:#新的总和<老的总和
bestCentToSplit=i#最佳划分质点
bestNewCents=centroidMat#最佳新质点集
bestClustAss=splitClusAss.copy()#最佳簇分配矩阵
lowestSSE=sseSplit+sseNotSplit#刷新最小SSE
bestClustAss[nonzero(bestClustAss[:,0].A==1)[0],0]=len(centList)#更新质点序号
bestClustAss[nonzero(bestClustAss[:,0].A==0)[0],0]=bestCentToSplit#以方便并入总质点集
print('the bestCentToSplit is:',bestCentToSplit)
print('the len of bestClusAss is:',len(bestClustAss))
#(以下两行)将老的一个质点用两个最佳的新质点替换
centList[bestCentToSplit] = bestNewCents[0,:].tolist()[0]
centList.append(bestNewCents[1,:].tolist()[0])
clusterAssment[nonzero(clusterAssment[:,0].A==bestCentToSplit)[0],:]=bestClustAss#更新簇分配矩阵(将最佳划分点相关的部分全部用新的划分点和距离替代)
return mat(centList),clusterAssment import urllib
import urllib.request
import json def geoGrab(stAddress,city):
apiStem="http://api.map.baidu.com/geocoder/v2/?"
params={}
#❶ 将返回类型设为JSON
params['address']='%s%s'%(stAddress,city)
params['ak']='您自己申请的百度API的key'
params['output']='json'
url_params=urllib.parse.urlencode(params)
baiduApi=apiStem+url_params
print(baiduApi)
#❷ 打印输出的的URL
c=urllib.request.urlopen(baiduApi)
return json.loads(c.read().decode('utf-8'))#指定编码,否则默认为字节不是字符串 from time import sleep
#批量获取经纬度并将“地址+经纬度”写入place.txt
def massPlaceFind(fileName):
fw=open('places.txt','w')
for line in open(fileName).readlines():
line=line.strip()
lineArr=line.split('\t')
#print(lineArr)
retDict=geoGrab(lineArr[1],lineArr[2])#1和2分别是详细地址(精确到门牌号)和城市名称
if retDict['status']==0:#正常返回
lat=float(retDict['result']['location']['lat'])#纬度
lng=float(retDict['result']['location']['lng'])#经度
print("%s\t%f\t%f"%(lineArr[0],lat,lng))
fw.write('%s\t%f\t%f\n'%(line,lat,lng))#将经纬度添加到原来对应的行上
else:
print("error fetching")
sleep(1)
fw.close() #使用余弦定理计算两点之间距离
def distSLC(vecA,vecB):
a=sin(vecA[0,1]*pi/180)*sin(vecB[0,1]*pi/180)
b=cos(vecA[0,1]*pi/180)*cos(vecB[0,1]*pi/180)*cos(pi*(vecB[0,0]-vecA[0,0])/180)
return arccos(a+b)*6371.0 import matplotlib
import matplotlib.pyplot as plt
def clusterClubs(numClust=5):
datList=[]
for line in open('places.txt').readlines():
lineArr=line.split('\t')
datList.append([float(lineArr[4]),float(lineArr[3])])#基于进度和纬度创建矩阵
datMat=mat(datList)
myCentroids,clustAssing=biKmeans(datMat,numClust,distMeas=distSLC)
fig=plt.figure()
rect=[0.1,0.1,0.8,0.8]#决定绘制图的哪一部分的矩阵
scatterMarkers=['s','o','^','','p','d','v','h','>','<']#形状标记
axprops=dict(xticks=[],yticks=[])
ax0=fig.add_axes(rect,label='ax0',**axprops)
imgP=plt.imread('Portland.png')
#❶ 基于图像创建矩阵
ax0.imshow(imgP)
ax1=fig.add_axes(rect,label='ax1',frameon=False)#使用ax1在原图像上绘制新图
for i in range(numClust):
ptsInCurrCluster=datMat[nonzero(clustAssing[:,0]==i)[0],:]
markerStyle=scatterMarkers[i%len(scatterMarkers)]#循环使用标记
ax1.scatter(ptsInCurrCluster[:,0].flatten().A[0],ptsInCurrCluster[:,1].flatten().A[0],marker=markerStyle,s=90)
ax1.scatter(myCentroids[:,0].flatten().A[0],myCentroids[:,1].flatten().A[0],marker='+',s=300)#使用+标记中心位置
plt.show()

13、apriori算法修改如下

def loadDataSet():
return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]] def createC1(dataSet):
C1=[]#大小为1的所有候选项集合
for transaction in dataSet:
for item in transaction:
if not [item] in C1:
C1.append([item])
C1.sort()
#对C1中每个项构建一个不变集合
return list(map(frozenset,C1))#frozenset:用户不可改的集合 #D:数据集
#Ck:候选项集列表
#minSupport:最小支持度
#生成频繁项集
def scanD(D,Ck,minSupport):
ssCnt={}#ssCnt:{key:value},key为项,value为其出现的次数
for tid in D:
for can in Ck:
if can.issubset(tid):#can是tid的子集
if not can in ssCnt:ssCnt[can]=1
else:ssCnt[can]+=1
numItems=float(len(D))
retList=[]
supportData={}
for key in ssCnt:
#计算所有项集的支持度
support=ssCnt[key]/numItems
if support>=minSupport:
retList.insert(0,key)#在列表头部插入
supportData[key]=support#最频繁项集及其支持度 key:value
return retList,supportData

变化的部分都用红色标出,以后也会采取类似的做法

to be continued……

《机器学习实战》 in python3.x的更多相关文章

  1. 【机器学习实战 第九章】树回归 CART算法的原理与实现 - python3

    本文来自<机器学习实战>(Peter Harrington)第九章"树回归"部分,代码使用python3.5,并在jupyter notebook环境中测试通过,推荐c ...

  2. 机器学习实战python3 K近邻(KNN)算法实现

    台大机器技法跟基石都看完了,但是没有编程一直,现在打算结合周志华的<机器学习>,撸一遍机器学习实战, 原书是python2 的,但是本人感觉python3更好用一些,所以打算用python ...

  3. 【机器学习实战学习笔记(2-2)】决策树python3.6实现及简单应用

    文章目录 1.ID3及C4.5算法基础 1.1 计算香农熵 1.2 按照给定特征划分数据集 1.3 选择最优特征 1.4 多数表决实现 2.基于ID3.C4.5生成算法创建决策树 3.使用决策树进行分 ...

  4. 机器学习实战笔记(Python实现)-08-线性回归

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  5. 机器学习实战笔记(Python实现)-06-AdaBoost

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  6. 机器学习实战笔记(Python实现)-05-支持向量机(SVM)

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  7. 机器学习实战笔记(Python实现)-04-Logistic回归

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  8. 机器学习实战笔记(Python实现)-03-朴素贝叶斯

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  9. 机器学习实战笔记(Python实现)-01-K近邻算法(KNN)

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

随机推荐

  1. data-ng-model 指令

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  2. CentOS 7 安装oracle 11.2.0.4 Error in invoking target 'agent nmhs' of makefile

    %86时出现报错   Error in invoking target 'agent nmhs' of makefile 解决方案在makefile中添加链接libnnz11库的参数修改$ORACLE ...

  3. 自动化维护任务 – Automated Maintenance Task (转)

    1. Oracle有三个已定义好的automated maintenance tasks. Automatic Optimizer Statistics Collection—用于收集各种数据库对象的 ...

  4. c#常用数据库封装再次升级

    c#封装的几类数据库操作: 1.sqilte 2.berkeleydb 3.一般数据库 4.redis 包含其他项目: 1.序列化 2.通信 3.自定义数据库连接池 再次升级内容: 1.新增redis ...

  5. node读写文件

    结束了一天的工作和学习,今天对于自己最大的收获就是node读写文件和对callback函数有了更深一步的理解.总结一下node读写的文件的注意事项吧(注意:下面讲的是增加数据的方法): 1.我们可以封 ...

  6. 在ReactNative中使用Typescript

    在ReactNative中使用Typescript 少侠放心,跟着我的这个步骤走,保你完美在RN项目中使用Typescript,废话不多说,走你 1.全局安装create-react-native-a ...

  7. ThinkPHP框架介绍

    什么是框架 php框架是许多代码的集合,这些代码的程序结构的代码(并不是业务代码)代码中有许多的函数,类,功能类包 不使用框架开发的缺陷 代码编写不规范 牵一发而动全身 不能很好满足客户各方面的需求 ...

  8. ThinkPHP 5 整合支付宝微信支付(支付宝H5,微信H5、APP支付、公众号支付)

    因项目没有PC站所以没有写电脑网站支付. Pay.php支付控制器 <?php // +----------------------------------------------------- ...

  9. js 节点

    var chils= s.childNodes; //得到s的全部子节点 var par=s.parentNode;  //得到s的父节点 var ns=s.nextSbiling;  //获得s的下 ...

  10. Teen Readers【青少年读者】

    Teen Readers Teens and younger children are reading a lot less for fun, according to a Common Sense ...