红辣椒——今敏

电影名: 红辣椒

导演: 今敏

评分: 7

剧情: 野心董事长利用控梦机器妄图将人类拽入梦境,从而自己成为统治者。控梦机器的发明者千叶和时田在梦中合体打破野心董事长的故事。千叶有精神分类,红辣椒是她的一个人格,串起了整个故事。

泄密者——邱礼涛

电影名: 泄密者

导演: 邱礼涛

评分: 7

剧情:马来西亚药业公司老板张日善通过一边释放病毒一边卖药赚取巨额非法利润。大儿子和其妻子检举不成惨遭杀害。小儿子在香港躲避追杀过程中,证据被毁。但其与一名记者和一名警察达成同盟,设计使得张日善构成意图杀人事实,将其送入监狱。

unittest

单元测试是对程序中最小的可测试模块——函数来进行测试。被测对象一定要有输出结果,哪怕是异常也需要有异常输出,只有这样单元测试才能够捕获返回值,并且与预期值进行比较,从而得出测试通过与否。

但是对于python自带的exception或者error输出,其实不显式指定是捕获不到的,那么应当如何处理这种情况呢?我个人的理解是这并不重要。比如因为传参类型报错,我们不可能对于各种情况都去进行unittest,并且都去在原函数中写exception,何况python自己就会报错告诉我们错在哪里。我们写unittest应该是我们所希望实现的函数功能是不是得到了正确实现,而不是报错。换言之,函数虽然可以运行但其实和我们预想的不一样这才是我们真正需要担心并unittest的地方!

unittest 框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import cls
import unittest

class clsTestCase(unittest.TestCase):
def setUp(self):
self.cls = cls()
def teardown(self):
self.cls = None
def test_func1(self):
self.assertEqual(self.cls.func1,expect1)
def test_func2(self):
self.assertRaises(Exception,self.cls.func2,func2_params)

if __name__ '__main__':
unittest.main()

unittest代码基本是以上代码格式,需要注意的点:

  1. cls为需要测试的类。一般把unittest类名起为clsTestCase
  2. class需要继承unittest.TestCase
  3. 需要测试的函数必须都以test开头命名,不然测试不到。
  4. 如果是测试Exception,func的参数不能直接传进func里面,而应该写成 self.assertRaises(Exception,self.cls.func2,func2_params)
  5. 最好有def setUp 和 def teardown 两个函数,用于对class中每个test函数测试前的初始化和测试后的清空。

输出格式

如果希望对输出每个test func的测试情况,可以这样:

1
2
3
4
if __name__ == "__main__":
#unittest.main()
suite = unittest.TestLoader().loadTestsFromTestCase(clsTestCase)
unittest.TextTestRunner(verbosity=2).run(suite)

setUp&teardown

unittest module包含了编写运行unittest的功能,自定义的test class都要继承unitest.TestCase类,test method要以test开头,运行顺序根据test method的名字排序,特殊方法:

  1. setup():每个测试函数运行前运行
  2. teardown():每个测试函数运行完后执行
  3. setUpClass():必须使用@classmethod 装饰器,所有test运行前运行一次
  4. tearDownClass():必须使用@classmethod装饰器,所有test运行完后运行一次

unittest.skip

可以使用unitest.skip装饰器族跳过test method或者test class,这些装饰器包括:

  1. @unittest.skip(reason):无条件跳过测试,reason描述为什么跳过测试
  2. @unittest.skipif(conditition,reason):condititon为true时跳过测试
  3. @unittest.skipunless(condition,reason):condition不是true时跳过测试
1
2
3
4
5
#这是一个自定义的skip decorrator
def skipUnlessHasattr(obj, attr):
if hasattr(obj, attr):
return lambda func: func
return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))

其他特殊方法

使用@unittest.expectedFailure装饰器,如果test失败了,这个test不计入失败的case数目

How to unit test complex methods

How to unit test complex methods

测试代码覆盖率

1
2
3
4
5
6
7
8
9
# 安装所需包
pip install coverage
# terminal运行unittest脚本
coverage run test_mymath.py
# 在终端打印出信息
coverage report -m
# 生成html文件夹
coverage html
# 用浏览器打开其中index.html

unittest报告

HTMLTestRunner_PY3 repo提供了报告生成脚本和使用范例。范例中也提供了测试用例集合的构造方法。

references

Python中unittest用法实例

如何测试代码覆盖率:coverage.py 简介

How to unit test complex methods

Python3 unittest单元测试

Python单元测试unittest

获取脚本路径

假设现在的文件结构是

1
2
3
4
5
6
7
- a.py
-- import c
- bfolder
- c.py
-- print(os.getcwd())
-- print(__file__)
-- print(os.path.abspath(__file__))

执行

1
python a.py

a再执行时调用了c.py,虽然os.getcwd()写在c里面,但是打印的结果却是a的父目录,但是os.path.abspath(__file__)打印出来的则是c.py自己的绝对路径。

需要注意的是print(__file__),在终端里面运行打印出来的仅仅是文件名,在jupyter里面则是打印绝对路径(网上看到有说pycharm也存在此问题)。已前者为准。

covariate shift

covariate shift

训练集和测试集的分布不一致,会导致train得到的estimator无法在test上有好的效果。

method

可以通过sample reweight方法来改变训练集的分布,从而达到实际训练的train分布和test分布一致。

权重计算一般可以采用这样的方式:

将train和test合在一起建模,label为case所属的数据集,train-1,test-0,通过五折交叉可以得到trian的每个case的预测得分,得分越高,说明越容易和test区分,也就是越不可能是test分布所产出的结果。故而得分取倒数在做归一化就可以得到train的每个case对应权重。

同时根据得分可以计算mcc指标,该指标可以作为train和test分布不一致性的一个度量指标,越大越不一致。

但是在个人实践中发现,sample reweight并不能带来更好的效果,反而有时效果还更差。

由于这个结果比较反常识,个人查阅了一些资料,发现确实有论文和实验强调sample reweight无效。具体见Understanding covariate shift in model performance

当然,可以不同的数据集适用不同的处理方法, 不能一概而论之。

另一种解决方法

可以考虑从分布不一致的根源上入手来解决问题。

个人面临的实际问题是业务策略频繁变动,导致同一个产品在不同时间的客群并不一样(对客群划分等级,然后这个星期将低等级用户分发给该产品,下个星期将高等级用户分发给该产品)。在这种情况下,如果使用历史样本进行建模,会发现在近期客群上效果很差。由于一般情况下,客群本身并不大可能在短时间频繁变动。因此,可以拉长采样的时间线,确保客群的不同类型都可以被纳入样本之中,如此一来,就可以保证模型对新客群(总体客群中的某一部分)具有适应性。在这个过程中,有一点需要注意,采样时应当保证客群各等级比例和实际情况应当一致,不然会受到产品策略的影响导致比重失衡。

reference

数据结构第六讲:图(上)

6.1 什么是图

什么是图

怎么在程序中表示一个图

邻接矩阵

找到Gij在数组中的对应下标很容易,反过来貌似还是挺困难的。

邻接表

6.2 图的遍历

深度优先搜索(DFS)

对于邻接表,N个顶点需要遍历,每个顶点只需要遍历该链表上的结点,也就是一共2E(一条边会被在不同的链表各存一次)个结点,所以是O(N+2E)

对于邻接矩阵,每个顶点都需要遍历,而对于每个顶点,都需要遍历它和所有其他顶点的对应值才能知道是否是邻接点,因此是$O(N^2)$

广度优先搜索(BFS)

类似于层序遍历

为什么需要两种遍历?

不同的情况下不同的遍历方式会更有优势

图不连通怎么办?

强连通图依旧是有向图,虽然任意两顶点之间都可以互通往来,存在性质上的区别,不能和无向图中的连通图混为一谈。

对于非连通图,需要遍历所有顶点去实现bfs或者dfs,对于连通图,只需要从一个初始点出发就可以。

6.3 应用实例:拯救007

6.4 应用实例:六度空间

小白专场:如何建立图

心花怒放——宁浩

电影名:心花怒放

导演: 宁浩

评分: 0

剧情: 耿浩妻子移情别恋,耿浩陷入痛苦绝望。好兄弟花花公子郝义为了帮助他带他开车自驾前往丽江。中间郝义各种猎艳,耿浩却沉浸在与妻子的感情中依旧难以释怀。最终,耿浩丢下郝义独自前往丽江,回到和妻子初遇的地方。当看到妻子的视频被酒吧未经授权随便播放,大打出手,幸得郝义赶来相救。在这种拳脚争斗之后,耿浩最终释怀。

一出好戏——黄渤

电影名:一出好戏

导演: 黄渤

评分: 0

剧情: 在陨石将要撞击地球的谣言背景下,公司团建遇到风浪,导致全员被困孤岛,误以为世界已经毁灭。退伍军人出身的导游凭借出色的荒野生存能力被拥护为领袖,并慢慢有了暴力权威的特质。公司老板意外发现有充裕生活物资的游轮残骸,利用商业头脑带一批人另起炉灶。中了千万大奖的马进急于返回陆地,为两派所不容。他巧妙的挑起两派之间矛盾,坐收渔利,成为最大赢家。马进弟弟小兴在这个过程从一个老实被欺负的角色成长为一个阴谋家,他发现了海上游轮的踪迹,但隐瞒事实并欺骗老板签署财产转让协议。马进良心发现,阻止了小兴的计划,点燃大火传递信号,让所有人都得救。

或许是困于荒岛的时间太短,人们之间的行为并没有明显的逾越,没有蝇王的残酷。

反贪风暴3——林德禄

电影名: 反贪风暴3

导演: 林德禄

评分: 7

剧情: 香港警方和ICAC追查一桩巨额洗黑钱犯罪。其间,ICAC首席主任在陷害停职,但其依靠同事的帮助拿到录音证据,最终和各部门同事一起破获该案件。

片子开头和结尾大陆反贪污处的生硬嵌入和官话实在无语。

信息简史——詹姆斯·格雷克

引子

它看不见摸不着,但当科学家最终开始理解信息时,他们好奇信息是否才是真正基本得东西,甚至比物质本身更基本。

将宇宙理解为一台大型计算机,那么空间就不是问题,量子纠缠也可以理解,毕竟信息不是依空间分布在内存条表面的。

第1章 会说话的鼓

为了克服歧义和进行纠错而专门引入额外的比特

冗余在特定情况下也是有用的。

可用的符号越少,为表示给定信息量所需传递的符号数就得越多。

第2章 持久的文字

试想这样一种文化,在其中没有人是“查阅”东西。……人类历经数千年才把这种将语言表达成符号系统的能力内化为第二天性。而一旦习得之后,回归天真无邪的退路就不复存在了。已经忘了从什么时候开始,我们只有在看到一个词时,才能产生关于这个词的感受。

文字,作为一种技术,使用时需要提前考虑清楚并掌握特殊i技能。而语言则不是一种技术,无论多么成熟、多么发达的语言,都不能被视作心外之物,因为语言是心智本身的功能。……但当词语被具象化在一张纸或一块石头上时,它就成了一种独立存在的人工品。它是工具的产物,同时本身又是一种工具。

文字带来的将是思想的贫瘠:

你这个发明结果会使学会文字的人们善忘,因为他们就不再努力记忆了。

口语面对面交流,可以充分调动感官,从而能够更加精准的进行表达,也能更加贴近现实的去理解。而现实的生活赋予了人最直接的创造力。

书面文字的出现,使得信息传播变得僵硬死板,脱离现实,成为概念。这样的概念形态容易使人似懂非懂,当一个词无法在脑海中还原为它的现实状态时,就是支离破碎、无意义的。所幸,通过逻辑和字典,文字得意义得以贯通,落于实地。

第3章 两本字典

语言是对共同经验的一种量度,而后者源于互连通性。……互联网正在以完全不同的方式改变着语言。这种不同之处在于,它不带偏见地涵盖了从最大到最小的尺度。

连通性依旧是必须的。只是原先连通性依靠地理上的连通性,而网络使得地理隔离被打破。

旧词新义,新词的不断涌现,如果只是依靠滞后的字典和印刷物是无法提供支撑,也无法及时响应的。

第4章 将思想的力量注入齿轮机械

知识的价值与发现的成本,需要核算和权衡。

过往几个世纪科学的发展不仅仅得益于天才式的灵感,也得益于计算能力的加强,或者说信息获取成本的降低,工程能力的提升。

第5章 地球的神经系统

前面几章更关注的是信息传播方式的演变带来的含义变化,从口语到文字到数。第4章已经开始考量信息的获取和计算成本问题。本章则是信息传播方式带来的速度和成本变化。并经由成本出现压缩信息再解密的编码传输方式。

经由电报带动的密码学热潮,进一步推动了符号和数学的结合,将逻辑学收入麾下。至此,语言(符号)不仅仅是表达的工具,也是思维的工具。

第6章 新电线,新逻辑

絮叨了香农以及和他相关的一些人事物(电话、贝尔实验室、普林斯顿高等研究院、哥德尔(数学的不完全性)、哈特利)的情况。

第7章 信息论

介绍香农熵。

第8章 信息转向

数据结构第五讲:树(下)

5.1 堆

什么是堆

最大堆的插入

思路:

  1. 将插入值放到末尾
  2. 比较其于父结点的大小关系,如果大于父结点,则交换位置,循环往复直至root,小于则直接停止。

用完全二叉树可以直接定位父结点下标

最大堆的删除

思路:

  1. 删除root,同时将二叉树最后一个结点放到root补位
  2. 取其左右儿子中大的和其进行比较,如果大于则交换位置,循环往复直至叶结点,不然直接停止。

最大堆的建立

方法一:

复杂度[TBC]

方法二思路:

  1. 从最后一个非叶子结点开始,把这颗子树调成一个堆,循环往复,直到root。

每个非叶子结点的调整过程最坏情况下挪动元素次数是它的高度。因此建堆时,最坏情况下需要挪动元素次数是等于树中各结点的高度和

5.2 哈夫曼树与哈夫曼编码

什么是huffman树

huffman树的构造

[TBC]如何利用堆构造、复杂度?

huffman编码

5.3 集合及运算

集合的表示

并查集

5.4 小白专场:堆中的路径