Python爬虫小结之Selenium
上学期和同学一块儿接了个爬虫的活儿,赚了人生第一桶金。本来打算寒假好好整理一下,但是,但是寒假整整玩儿了一个月,说好的总结博客没有写,想学的新东西也没有看,真是不思进取啊。现在提前几天回学校,一来准备一下实验室新开的项目,二来对这学期做一个小的规划吧,顺带整理一下上学期的工作。这篇博客主要总结了我在这个爬虫项目中学习到的一些新知识,在此要感谢我的两位同学killers Death和yohoho。
上学期和同学一块儿接了个爬虫的活儿,赚了人生第一桶金。本来打算寒假好好整理一下,但是,但是寒假整整玩儿了一个月,说好的总结博客没有写,想学的新东西也没有看,真是不思进取啊。现在提前几天回学校,一来准备一下实验室新开的项目,二来对这学期做一个小的规划吧,顺带整理一下上学期的工作。这篇博客主要总结了我在这个爬虫项目中学习到的一些新知识,在此要感谢我的两位同学killers Death和yohoho。
傅国涌在他的演讲《民国教育的花开花落》中有这么一段话:
我在和年轻人说“读书”这件事的时候,常常会想到这样一番话:你说读这本书有什么用,尤其是这本书考试不考的,读了干什么?你读那本书,也不考的,有什么用?是的,没有用。但是,也许在十年后,二十年后,甚至三、四十年后,你少年时代读过的某一本书、某一篇文章,会在你的脑子中跳出来。或者,在你做某一件事的时候,它会突然跳出来,那是什么?那就是一条神秘的线索。这条神秘的线索就像天罗地网一样埋在你生命的深处,待某一天它就会被拎出来。这条线索就是你的人生,就是你的精神世界。
在此处贴出在读、想读和已读的书单,欢迎交流讨论。
最近学习了一点网络爬虫,并实现了使用python来爬取知乎的一些功能,这里做一个小的总结。网络爬虫是指通过一定的规则自动的从网上抓取一些信息的程序或脚本。我们知道机器学习和数据挖掘等都是从大量的数据出发,找到一些有价值有规律的东西,而爬虫则可以帮助我们解决获取数据难的问题,因此网络爬虫是我们应该掌握的一个技巧。
python有很多开源工具包供我们使用,我这里使用了requests、BeautifulSoup4、json等包。requests模块帮助我们实现http请求,bs4模块和json模块帮助我们从获取到的数据中提取一些想要的信息,几个模块的具体功能这里不具体展开。下面我分功能来介绍如何爬取知乎。
前面写了使用theano来实现kaggle中的手写识别,分别用的是逻辑回归和多层感知机,这次加上卷积神经网络,将三者放在一块儿做个总结。下一步的工作是继续系统学习theano及其他深度学习工具,自己去实现更多模型和优化方法。
首先是逻辑回归,这里我用了个类似十折交叉验证的方法:将train.csv中的数据分成了十份,最后一份作为模型训练过程中的测试集,每次训练时选取前九份中的一份作为验证集,其余八份作为训练集,这样我们就可以得到同一个模型的九组参数设置。在预测阶段,前面得到的九组参数设置同时参与预测,具体做法是,对于同一组测试数据,我们分别用九组参数设置去预测,得到九个预测值,我们将这九个预测值中出现次数最多的那个label作为改组测试数据的最终预测值。
上一篇博客介绍了如何使用Theano+logistic regression来实现kaggle上的数字手写识别,文末提到了CPU计算实在太慢,因此在做完这个实验之后,博主查阅了Theano的文档,了解到Theano官方仅支持CUDA进行GPU运算,不支持OpenCL,也就是说Theano官方仅支持N卡。原因是,CUDA和OpenCL是两个GPU计算平台,CUDA仅支持N卡,OpenCL支持所有的显卡,二者的具体区别还请自行查询。无奈博主的笔记本有一张intel的集成显卡和AMD的一张入门独显,而Theano非官方的提供了libgpuarray来支持OpenCL,因此博主花了大量的时间来尝试安装libgpuarray。
前面学习了机器学习的一些基础知识,这两天尝试着做了几个小实验,手写就是利用theano来实现kaggle上的入门问题——手写识别。
Theano是一个Python库,允许我们来定义、优化和评估涉及多维数组的数学表达式,因此其是实现深度学习框架的一个很重要的模块。Deep Learning Tutorials则介绍了如何使用theano来搭建我们需要的深度学习网络来解决我们的实际问题。这里跳过了theano的基本知识(有需要的同学可以阅读Theano basic tutorial),直接通过改造Deep Learning Tutorials中的Logistic Regression、Multilayer perceptron和Deep Convolutional Network实现了kaggle的入门问题——手写识别,虽然精度不高,希望能给后面的同学提供一点点帮助。
Geoffery Hinton教授的Neuron Networks for Machine Learning的第十讲介绍了如何combine模型,并进一步从实际应用的角度介绍了完全贝叶斯方法。
这一小节,我们讨论在做预测时为什么要结合许多模型。使用多个模型可以在拟合真正的规则和拟合样本错误之间做一个很好的折中。
我们已经知道,当训练数据比较少时容易出现过拟合,如果我们平均一下许多不同模型的预测,那我们就可以降低过拟合的程度。对于回归来讲,当模型的capacity较弱时容易出现high-bias;当模型的capacity太强时,模型就会过多的拟合样本错误,从而出现high-variance。而结合多个不同的模型,我们就可以实现一个更好的折中。
Geoffery Hinton教授的Neuron Networks for Machine Learning的第八讲为可选部分,好像很难,这里就先跳过了,以后有用的时候再回来补。第九讲介绍了如何避免过拟合,提高模型的泛化能力。
这是Cousera上的课程链接
这一小节,我们介绍如何在网络有过多能力处理过多容量的训练数据集时,如何通过降低过拟合来提高网络模型的泛化能力。下面将介绍几种控制网络容量的方法,以及如何设置度量参数。下图回顾了什么是过拟合(overfitting),由于是以前讲过的东西,这里只贴截图,不再文字叙述。
Geoffery Hinton教授的Neuron Networks for Machine Learning的第七讲介绍了循环神经网络(recurrent neural network, RNN)和Long Short Term Memory。
在这一小节,我们将对应用于序列(sequences)的不同类型的模型做一个概括。我们从最简单的模型——ultra aggressive models(该模型尝试根据前一个序列(term or sequence)去预测下一个序列)开始,接着再讨论该模型使用了隐含层的复杂变形,然后再介绍更多有着hidden state和hidden dynamics的模型(这其中包含了linear dynamics systems和hidden Markov models)。这些模型都与RNN有关,因此先介绍,有兴趣了解模型细节的请自行搜索。
当我们用机器学习来构建序列时,我们通常想要将一种序列转换到另一种序列。例如,我们希望能将英语转换成法语,语音识别中我们希望将语音序列转换成词汇序列等。有时,目标序列不是孤立的,我们可以得到一种教学信号来尝试从输入序列中预测下一个序列,因此目标输出序列只是有着进一步形式的输入序列。比起根据一张图像中所有其他像素点去预测一个像素点或者根据一张图像的其他部分来预测一个部分,这种序列的转换看起来更自然。原因是,对于时间序列来讲会有一个很自然的顺序来预测下一步,而对图像处理来讲你不知道接下来的预测是基于什么(不过类似的方法很适用于图像处理)。另外,在进行序列转换时,监督式学习与非监督式学习的区别可能就模糊了(不太明白,但感觉不是很重要)。
Geoffery Hinton教授的Neuron Networks for Machine Learning的第六讲介绍了随机梯度下降法(SGD),并且介绍了加快学习速度的动量方法(the momentum method)、针对网络中每一个连接的自适应学习步长(adaptive learning rates for each connection)和RMSProp算法。
这几个算法的难度很大,需要反复推理思考,并在实践中摸索以加深理解。
这一小节介绍随机梯度下降法(stochastic gradient descent)在神经网络中的使用,随机梯度下降法在Andrew Ng的课程中已有介绍,所以这里可能会有所简略,大家可以阅读Machine Learning第十周笔记:大规模机器学习
这里首先回顾了第三讲中介绍的线性神经网络的误差曲面(error surface),如下图所示。线性神经网络对应的误差曲面的纵截面如碗装,横截面则如一组同心的椭圆。梯度下降法的作用就是不断调整参数,使得模型的误差由“碗沿”降到“碗底”,参数由椭圆外部移动到椭圆的中心附近。当然,这里说的是只有两个参数的情况,参数更多的情况则更复杂。