Python OOP(Object Oriented Programming)

面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。我们以一个例子来说明面向过程和面向对象在程序流程上的不同之处。假设我们需要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用一个dict表示:1234std1 = { 'name': 'Michael', 'score': 98 }std2 = { 'name': 'Bob', 'score': 81 }而处理学生成绩可以通过函数实现,比如打印学生的成绩:12def print_score(std): print('%s: %s' % (std['name'], std['score']))如果采用面向对象的程序设计思想,我们首选思考的不是程序的执行流程,而是Student这种数据类型应该被视为一个对象,这个对象拥有name和score这两个属性(Property)。如果要打印一个学生的成绩,首先必须创建出这个学生对应的对象,然后,给对象发一个print_score消息,让对象自己把自己的数据打印出来。12345678class Student(object): def __init__(self, name, score): self.name =…

0 Comments

Workflow for automatic extract and jump to the true URL of 91porn.com

主要讲述自己开发的Alfred Workflow 91url:自动获取某网站的真实视频地址并跳转的应用。相信许多朋友都爱看91的视频,但是免费用户的每日有限的观看次数总是让人意犹未尽。。。于是FreeGet 免费福利资讯应运而生。。。但是重复的从浏览器窗口点击复制url,切换窗口、粘贴再点击。。。有什么办法可以让众狼友的双手解放出来呢?作为程序员的我当然不能忍,所以耗费一下午的时间开发了这个Workflow:91url,能够自动获取当前的浏览器窗口的网址并提交到FreeGet网站,并用火狐浏览器打开真实视频网址(抱歉是0.1版本,功能受限,不足之处待之后版本解决)。使用方法非常简单,只要在我的Github下载并拖到Alfred 的Workflow即可,另外还需要安装Python的自动化网页测试工具包selenium:1pip install selenium然后浏览器处于91视频的页面的时候,用command + 空格 输入91url并enter即可(当然也可以修改HotKey来触发):之后91url将自动打开火狐浏览器并跳转至FreeGet获取真实网址,如上图,点击即可播放或者下载,so,enjoy!  

0 Comments

python源码解析0:趣事

About 两处python源码的趣味解读。The Zen of Python我们知道,import this会打印如下“蟒蛇之禅”:123456789101112131415161718192021The Zen of Python, by Tim PetersBeautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better…

0 Comments

数据挖掘流程:数据可视化与预处理

数据挖掘的第一步,当我们手中拿到一份数据,当然是对数据进行观察与预处理了。本文主要对这两个方面做一个个人的总结。import 掉包?第0步,调包。。通常numpy、pandas、scipy、seaborn已经matplotlib是必须的为防止烦人的warning,还需要12import warningswarnings.filterwarnings('ignore')因为我们不管warning只管error,哈哈 seaborn的设置颜色格式1sns.set_style('whitegrid')以及1%matplotlib inline观察与可视化一般来说,我们应该首先观察标签的分布以及特征的分布,对于前者通常使用pandas Dataframe的columns,对于后者则是value_counts()和describe()来展示。如1df_train.columns1int_level = train_df['interest_level'].value_counts()1df_train['SalePrice'].describe()describe()会给出标签的各种数值信息,如123456789count 1460.000000mean 180921.195890std 79442.502883min 34900.00000025% 129975.00000050% 163000.00000075% 214000.000000max 755000.000000Name: SalePrice, dtype: float64同时也可以借助于seaborn图来显示1sns.distplot(df_train['SalePrice']);接下来可以看看标签的偏度和峰度(skewness and kurtosis)12print("Skewness: %f" % df_train['SalePrice'].skew())print("Kurtosis: %f" % df_train['SalePrice'].kurt())特征与标签关系对于数值特征可用散点图来展示123var = 'GrLivArea'data =…

0 Comments

Devide and Conquer Counting Inversions with Python

本文主要内容关于python归并排序求逆序数的算法。解决问题:给定有限长度的无重复乱序数组,求其逆序数个数。简单来说我们可以用两个循环来解决,但是复杂度为$O(N^2)$,若利用归并排序,复杂度就降为了$O(N log(N))$。以下给出一个实现,123456789101112131415161718192021222324252627282930313233343536373839404142class Ivrs_num(object): def __init__(self, filename): self.count = 0 self.filename = filename def load_txt(self): '''载入txt文件保存为list''' int_list = [] with open(self.filename) as f: for line in f: int_list.append(int(line)) return int_list def…

0 Comments

Understanding EM algorithm

本文主要内容为用一个简短的例子解释EM算法。EM算法是聚类中常用的机器学习算法,但是相比喜闻乐见的k-means算法,大家可能对于EM算法的了解可能没有那么直观深入,所以本文主要利用一个简单的例子,在对比k-means算法的过程中,帮助大家建立一个清晰明确的对EM算法的理解。当我们在聚类的领域谈论k-means算法时,分组的概念是非常清晰直观的–每个样本点只属于它离得最近的那个中心点所属的分组。如果给出一些样本点和中心,那么我们很容易给这些点打标签。但是对于EM算法而言,分组的概念就么那么直观了(因为EM算法考虑每个样本点都有一定的概率属于所有的分组)。在我们介=引入EM算法之前,我们先复习一下k-means里面的分组概念。k-means里面的分组概念假设我们有如下的三个样本点(2D平面情况下的点):数据集XY点0105点121点237如果在上面的数据集上跑k-means算法,假定中心点如下:中心XYA34B63C46使用欧几里得距离,可以分配聚类如下距离群组A中心群组B中心群组C中心群组分配点07.0714.4726.083群组B点13.1624.4725.385群组A点23.0005.0001.414群组C到此,我们可以给出一个回答:到底把一个点归类到一个群组意味着什么?举例来说,点1只被分配到分组A,也就是点1的100%属于群组A并且0%属于群组B和群组C。那么根据这个定义,我们可以得到如下表格,群组A群组B群组C点0010点1100点2001成员个数111注意到,对于一个群组来说,其得到的每一行的和都是1(因为一个点的百分比就是之和就是1);另外,每一列的和就是这个群组的成员点的个数。推而广之:每一行的和总是1,因为一个点的百分比之和是1每一列的和就是分配到这个群组的点的个数EM算法中的群组分配到此为止,我们做的似乎不错,但是存在一个问题,我们这里每个点都只能属于一个群组,不过这一点有时候不是那么合理,比如点0分配到群组B似乎没什么问题,但是比如点1距离群组A和群组B的距离差别不那么大,那么只因为距离群组A近那么一点点就只把它分配到群组A,难道没什么问题吗?我们可能更加想表达这样一种概念:点1更可能属于群组A,但是我们也想保留点1也有一些可能属于群组B的不确定性。距离群组A中心群组B中心群组C中心群组分配点07.0714.4726.083群组B点13.1624.4725.385群组A点23.0005.0001.414群组C我们如何表述这种不确定性呢?这就是分组权重的由来。分组权重表达了一个点有多可能属于某个群组。比如之前的形式是这样的,群组A群组B群组C点0010点1100点2001成员个数111把上表的0和1换成分数(不要质疑这些分数怎么来的,等下会给出合理解释,:))群组A群组B群组C点00.0070.9380.055点10.8120.1540.034点20.2340.0160.750软计数1.0531.1080.839上表中,点0以93.8%的概率属于群组B,同时下一行中,点1以81.2%的概率属于群组A。这些分数也就是分组权重。比如,点0属于分组A的权重就是0.7%。和k-means算法中每个点只能属于一个群组不同,这里每个点都以某种程度地属于每一个群组。例如,93.8%的点0属于群组,其余的属于其他的群组。那么,在上面的分配矩阵里面,每一行和每一列的含义如下,每一行的和都是1,因为每个点都100%属于所有的群组,将这一些部分加起来和必定是1每一列的和是这个群组的“软计数”,它代表着所有的点属于这个群组的百分比之和所有的群组的软计数之和就是样本点的总数步骤E:给定分组参数计算分组权重分组权重是怎么来的?来自给定分组的分布的时候,我们观察样本点可能是什么。而EM算法中的每一个群组都由一个分组权重,一个均值向量,一个协方差矩阵构成。其中,均值表示群组的中心,协方差体现群组的范围,而分组权重体现了样本点与此分组的关联程度。所有,每个群组都由一个多变量高斯分布所定义。回顾上面的例子,加上一个不确定度的椭圆,如下,图中每个椭圆表示着协方差矩阵,在这个例子中,每个群组都是用的是对角协方差矩阵[[3,0],[0,3]]。因为对角线外元素都是0,所有图中的椭圆实际上看起来是圆。并且,由于并没有什么理由认为哪个群组比其他群组更加重要,那么我们定义每个群组的分组权重都是1/3。那么,点0属于群组A的概率是多少?这里用来衡量潜在的高斯分布的标准是概率密度函数(probability density function,PDF),使用scipy.stats.multivariate_normal.pdf可计算出来:12print multivariate_normal.pdf([10,5], mean=[3,4], cov=[[3,0],[0,3]])>>> 1.275199678019219e-05我们还要将这个概率乘以分组权重才行,12print 1/3.*multivariate_normal.pdf([10,5], mean=[3,4], cov=[[3,0],[0,3]])>>> 4.2506655934e-06点0属于群组A的似然值是4.251e-6。单看看不出什么,我们还要依次计算群组B和群组C的值。分别计算B和C的PDF并且乘以分组权重:12print 1/3.*multivariate_normal.pdf([10,5], mean=[6,3], cov=[[3,0],[0,3]])>>> 0.00063085470900512print 1/3.*multivariate_normal.pdf([10,5], mean=[4,6], cov=[[3,0],[0,3]])>>> 3.71046481027e-05那么,总结一下,群组A群组B群组C点(10,5)的PDF乘以分组权重4.251e-66.309e-43.710e-5很明显,群组B的似然值是最高的,这容易理解因为点0距离群组B中心的距离最近。似然值看起来太小了,我么可以对其做一个归一化:都除以所有群组的似然值的和得到百分比值。点0群组A群组B群组C总和似然值4.251e-66.309e-43.710e-56.722e-4似然值,处以总和4.251e-6 / 6.722e-4 = 0.0076.309e-4 / 6.722e-4 = 0.9383.710e-5 / 6.722e-4 =…

0 Comments

RECURRENT NEURAL NETWORK TUTORIAL, PART 4 – IMPLEMENTING A GRU/LSTM RNN WITH PYTHON AND THEANO

本文中,我们将学习关于LSTM (Long Short Term Memory)网络和 GRUs (Gated Recurrent Units)的知识。LSTM最初由Sepp Hochreiter and Jürgen Schmidhuber于1997年提出,如今是深度学习自然语言处理领域最流行的模型。GRU,出现于2014年,是LSTM的简化版,与LSTM有许多相似的特性。##LSTM 网络在第三部分我们提到了梯度消失问题妨碍了标准的RNN学习长期依赖问题。LSTM被设计于用gate结构解决梯度消失问题。为了理解这个机制,我们来看看LSTM如何计算隐藏状态$$s_t$$(其中小圆圈代表Hadamard product,即同型矩阵各元素对应相乘,不同于矩阵点乘)。式子看起来复杂,一步一步来理解实则简单。首先,LSTM的一层代表的只是另一种计算隐藏层的方法。之前我们计算了隐藏状态$$s_t = tanh(Ux_t + WS_{s-1})$$。对于当前的单元,输入是$$t$$时刻的$$x_t$$,而$$s_{t-1}$$是之前的隐藏状态,输出是新的隐藏状态$$s_t$$。其实,LSTM做的事情是完全一样的,只不过换了种方式,这也是理解LSTM的核心。我们可以把LSTM单元看作是黑盒子,给予其当前输入和之前的隐藏状态,它可以输出下一个隐藏状态。把这个牢记于心,我们开始来阐述LSTM如何计算隐藏状态。关于这一点,详细可看这篇文章,这里我们只作简短描述:$$i,f,o$$分别被称为输入门、遗忘门和输出门。注意到,它们具有相同的等式,只是参数矩阵不同。它们之所以被称为“门”,是因为sigmoid函数将向量值压缩到0和1之间,再与另一个向量相乘,我们因此决定向量的多少“通过”。输入门决定当前输入计算出来的状态的多少成分被通过,遗忘门决定之前的状态有多少可以被保留到之后,输出门决定当前的状态有多少被传送到外层的网络(高层网络和下一时刻)。这些门的维度都是$$d_s$$,即隐藏层的大小。$$g$$是一个候选的隐藏状态,基于当前的输入和之前的隐藏状态计算而出。其与vanilla RNN的计算等式相同,只是把参数$$U,W$$改名为$$U^g,W^g$$。和RNN的直接将$$g$$作为心的隐藏状态不同,我们将其通过一个输入门来决定保留它的多少成分。$$c_t$$是单元的内部的记忆,它由之前的记忆$$c_{t-1}$$通过遗忘门再加上新计算出来的隐藏状态$$g$$通过输入门计算得出。因此,它代表了旧的记忆与新的输入的结合。我们可以选择全部忽略旧的记忆(遗忘门全部置零),或者忽略全部的计算出的新状态(输入门全部置零),但是通常来说,我们可能更希望介于两者之间。给定记忆$$c_t$$,我们最终通过让记忆和输出门相乘计算出输出隐藏层状态$$s_t$$。在网络内,不是所有的内部记忆都与其他单元使用的隐藏状态有关。换一种说法,我们可以将标准的RNN看作是特殊的LSTM,如果我们将遗忘门全部置零,输入门全部置一,输出门全部置一,我们就几乎得到一个标准的RNN。通过门机制,LSTM可以操作记忆从而解决长期依赖问题。注意到,还有许多的LSTM变种,一种添加上“猫眼”结构,它的门同时取决于之前的隐藏状态$$s_{t-1}$$和之前的内部状态$$c_{t-1}$$。 LSTM: A Search Space Odyssey 实验观察了许多不同的LSTM机制。##GRU网络GRU的理念类似于LSTM,其等式如下:GRU拥有两个门,称为重置门$$r$$和更新门$$z$$。直观来说,重置门决定如何联合新的输入和之前的记忆,而更新门决定留下多少之前的记忆。如果将重置门全部置一并且更新门全部置零,那么我们又得到了我们原始的RNN了。GRU的解决长期依赖的理念和LSTM基本类似,以下是一些不同之处:两个门VS三个门GRU不处理内层记忆$$c_t$$输入门和遗忘门被组合成更新门$$z$$,重置门$$r$$直接连接之前的隐藏状态。因此,计算输出是不加上第二个非线性变换##GRU VS LSTM如今你认识了两个对抗梯度消失的模型  

0 Comments