Python拾遗 接口和抽象基类 --流畅的python
本章的notebook文件在这里
接口:从协议到抽象基类前面讨论过了以鸭子类型的代表,特征动态协议,本章继续来讨论到使接口更加明确的,能验证实现是否符合规定的抽象基类(Abstract Base Class, ABC).简单来说,我们接口的限制从协议的弱限制,到抽象基类的强限制。
Python中的接口和协议所谓接口就是类实现或者继承的公开属性,即其他对象能够调用/访问的部分。 那么按照这个定义,受保护的属性和私有属性都不属于接口。
协议则是只由文档和约定定义的非正式接口,那么它不能像正式接口那样施加限制,那么一个类可能只实现了部分接口。
一般对于Python程序员而言, “XX类对象”,“XX协议”和“XX接口”都是一个意思。
猴子补丁所谓猴子补丁指的是在运行时对类进行修改以实现协议,例如,我们自己定义一个序列类型,但是不实现它的__getitem__方法。
1234class Foo: def __init__(self, loo=[]): self._content = loo
12f = Foo([1,2,3])f[0]TypeEr ...
【西瓜书】第十一章 特征选择与稀疏学习
本文是周志华老师《机器学习》第十一章内容特征选择与稀疏学习的学习笔记
子集搜索与评价在学习任务中,我们经常会需要对已有的特征进行选择,选出对当前学习任务有用的相关特征而排除无关特征。这样,既可以减轻维度灾难,又降低了学习难度。由于直接计算所有特征的组合显然不可行,我们通常是先生成候选子集,然后评估其优劣,接着再生成下一个候选子集,如此往复直到结束。
那么,这里我们就需要考虑两个方面的方法,一个是子集搜索,一个是子集评价。
子集搜索上我们通常采用贪心的方法,有从0特征开始增加的前向搜索,也有全特征开始排除的后向搜索,以及同时开始增加和减少的双向搜索。子集评价方面,信息熵是常见的指标。其定义为:
Ent(D)=-\sum_{i=1}^{|y|}p_klog_2p_k那么信息增益就是:
Gain(A)=Ent(A)-\sum_{v=1}^V\frac{|D^v|}{|D|}Ent(D^v)信息增益越大,说明包含有用信息越多。
过滤式Relief方法是最常见的过滤式方法,这类方法主要是先用特征选择来对原始特征进行过滤,然后将过滤后的特征传入学习器。Relief给 ...
Python拾遗 符合python风格的对象 --流畅的python
本章的notebook文件在这里
符合Python风格的对象这次来讨论一下如何写出符合Python风格(Pythonic)的对象.
对象的表示形式如何用字符串来表示Python对象呢, python提供了两种方式: repr和str. 前者是以便于开发者理解的方式表示, 后者则是以便于用于理解的方式表示. 我们需要分别实现__repr__和__str__两个特殊方法.
我们以Counter对象为例介绍一下:
123from collections import Counterct = Counter([1,2,34,1,])repr(ct)
'Counter({1: 2, 2: 1, 34: 1})'
我们自己在面向对象编程时, 可以通过实现__repr__方法来自定义对象的表示形式, 但是一般遵循的原则是最好表示出来的字符串能够被eval执行, 返回一个满足要求的对象, 而__str__则可以简单些.
下面以一个学生类为例:
123456789101112class student: def __init__(self, ...
【西瓜书】第十章 降维与度量学习
本文是周志华老师《机器学习》第十章降维与度量学习的学习笔记
k近邻学习k近邻学习是一种常用的监督学习方法, 工作的机制非常简单,对于每个给定的测试样本, 基于某种距离找出训练集中与其最相近的k个训练样本, 然后基于这些邻居的信息来预测该测试样本. 在分类任务中,可以采取投票法, 在回归任务中可以采取平均法, 更复杂一些也可以采取各种加权方式.
显然可以看出, k近邻方法没有显式的训练过程, 它是懒惰学习的著名达标,训练时间开销为零.
k近邻学习中两个重要的点:
k的选取
距离的定义
假设我们固定住第二点, 并设$k=1$, 来讨论一些这种最近邻分类器在二分类问题上的性能. 此时我们给定测试样本$x$, 并设其最邻近样本为$z$, 则容易得出分类器出错概率为:
P(err)=1-\sum_{c\in Y}P(c|x)P(c|z)假设样本独立同分布, 且对任意$x$和任意小正数$\delta$, 在$x$附近$\delta$距离范围内总能找到一个训练样本. 令$c^*=arg \max_{c\in Y}P(c|x)$表示贝叶斯最有分类器的结果, ...
Python拾遗 对象引用 --流畅的python
本章的notebook文件在这里
对象引用, 可变性和垃圾回收
变量这里首先纠正一个观念, 变量并不是一个存储着值的盒子, 而更像是一个贴在值上的便利贴, 我们假设一个dict存储了关于鲁迅的内容:1234luxun = {'name': 'zhoushuren', 'penname':'luxun'}zhoushuren = luxun luxun == zhoushuren True1id(zhoushuren), id(luxun) (139695789640392, 139695789640392)
可以看出, 鲁迅和周树人的值是相等的, 且用id函数可以看出二者是同一个对象, 这里体现出luxun,zhoushuren都是别名, 绑定了同一个对象, 对二者之一的修改都会影响到另一个.
12345zhoushuren['publication'] = 'The True Story of Ah Q' ``` ```py ...
Python函数拾遗 函数装饰器与闭包 --流畅的python
本章的notebook文件在这里
函数装饰器与闭包装饰器基础知识 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数). 装饰器可能会处理被装饰的函数并返回, 或者将其替换为另一个函数或者可调用对象.
例如,下面两段代码是等价的:
1234567891011121314151617181920212223242526@decorate def target(): print('running target()')``` ---分---割---线-----```pydef target(): print('runing target()') target = decorate(target)``` 我们实现一个简单的装饰器来说明一下: ```pythondef deco(func): def youarepig(): print('你是猪') return youarepig@decodef target(): print('哈哈哈' ...
读书月报1810
十月, 四本书, 如下:
地理与世界霸权 可以算是地缘政治的开山之作? 当然,年代很久远了,受时代影响有许多现在看来是谬误的观点.不过整体上提出的一些关于地理,能量和历史的观点还是值得思考借鉴的.
形而上学的命运 一本读后感类型的科普书,是恩格斯<路德维希 费尔巴哈和德国古典主义哲学的终结>的缩减版. 由于是思想的二道贩子,所以也就是读来打发时间没太认真.不过总的来说还是表达出观点的, 即将马克思的思想简单看做黑格尔的辩证法+费尔巴哈的唯物主义是大错特错(好像高中政治书上还是这么写的),并阐述了费尔巴哈和德国古典哲学中存在的形而上学部分.
历史真相的探索 同上一篇一样,是<德意志意识形态 费尔巴哈>的读后感. 其中一个观点印象挺深的, 马克思一直以来都很讨厌意识形态,认为其虚幻而歪曲,仅仅代表统治阶级的思想,一旦意识形态开始支配世界,就开始禁锢思想,掩盖历史.
万历十五年 哎..这本书拖了很久了,断续看了快七八个月,总算在十月份连附录里的神宗实录都看完了. 当时看<大明王朝1566>的时候就开始慢慢读这篇. 本篇的英文名直译过 ...
Python函数拾遗 一等函数与设计模式 --流畅的python
本章就Python中函数与设计模式做一些探讨, notebook文件在这里.
一等函数与设计模式虽然设计模式与语言无关,但是某些设计模式并不适用于某些语言. 下面就Python中策略模式做一些讨论.
策略模式 在设计模式中,策略模式的概述如下:
定义一系列算法,把它们一一封装起来,并且使它们可以互相替换.本模式使得算法可以独立于使用它的客户而变化.
这里举的例子是电商的促销策略,即根据客户的属性或订单中的商品计算折扣(顺便吐槽近几年双十一的折扣是越来越复杂了…).
例如某个网店制定了如下的折扣策略:
1000积分以上客户,享受5%折扣
同一订单下,单个商品数量达到20个或以上,享受10%折扣
订单的不同产品达到10个或以上,享受7%折扣
那么按照策略模式,我们需要有如下的类:
上下文 把一些计算委托给实现的不同算法的可互换组件,它提供服务. 在该例子中,上下文即为订单Order,它会根据不同算法计算促销折扣.策略 实现不同算法的组建的共同接口. 在该例子中,即为Promotion.具体策略 策略的具体子类. 在该例子中,即为上述的三种 ...
【西瓜书】第六章 支持向量机
本文是周志华老师《机器学习》第六章支持向量机的学习笔记。部分内容来自PRML,凸优化, 线代启示录和李航老师的统计学习方法.
间隔与支持向量支持向量机(Support Vector Machine)是最常用的机器学习算法之一.首先我们从最简单的SVM开始回顾. 假设一个特征空间中有若干二分类样本, 且它们是线性可分的,那么在能够将其正确分类的无数个超平面中,我们应该挑选怎样的超平面呢?SVM给出的答案是: 找到在两类样本正中间的超平面. 很容易想出,此时该划分的泛化能力比较强.
我们用下式来表示划分的超平面:$w^Tx+b=0$其中$w$为法向量,$b$为位移, 那么样本空间中任一点$x$到该超平面的距离即为:
r=\frac{|w^Tx+b|}{||w||}假设超平面能够分类正确,则可以(通过适当放缩)使下式成立:
\begin{cases}
w^Tx_i+b \ge +1& y_i = +1\\
w^Tx_i+b \le -1& y_i = -1
\end{cases}此时, 距离超平面最近的这几个训练样本刚好使上式的等号成立,它们就被称作支持向量,两 ...
Python函数拾遗 一等函数 --流畅的python
这次的python回顾来到函数的知识,首先来探讨一下作为一等兑现的函数。相关的jupyte notebook文件在这里。
函数作为对象python中,函数是一等对象(first-class object),一等对象的定义为满足以下条件的程序实体:
在运行时创建
能够赋值给其他元素
能作为参数传递给函数,且能作为函数的返回结果
下面以一个阶乘的例子来说明函数如何作为对象:
123from IPython.core.interactiveshell import InteractiveShellInteractiveShell.ast_node_interactivity = "all"
1234def factorial(n): '''定义一个阶乘函数''' return 1 if n < 2 else n * factorial(n -1 )
12fact = factorial #将函数赋值给其他元素 fact
<function __main__. ...