about.me/acgtyrant

2017 Sep 24
无视原则

遥想还呆在 Acfun 的当年,大家在关于自杀现象的某文章里正战得欢时,一条评论留给了我很深的印象,原话已不可考,按照模糊的印象大概是:日本社会算是彻彻底底冷漠到了极点,同情也好,挖苦也好,都意味著被自杀者触动了。然而日本大多人已经冷漠到对愈演愈烈的自杀现象依然无动于衷,该干嘛的就干嘛,不管自杀者在人生尽头故意能闹得有多惊天动地,也很快地在一阵喧嚣后被世人尽数遗忘。于是自杀现象俨然成了日本人中平淡无奇,再熟视无睹不过的日常。

此后很长时间里,它成了我一直所发现的「最残忍的被动反应」,注意这行为只属于被动激发的反射行为分类。若要考虑主动层次上的恶意行为,方法多得是,但这并不在本文的讨论范围之内。

我并不是左右脸均给敌方扇的圣人,若必要时,便只能以敌意对抗恶意。不过我贯彻更为中庸的「无视原则」,即遭到来自敌方的恶意攻击行为,若物理上的损失可忽略,就自动激发无视其的被动反应。注意,这里的「无视」纯粹就是字面上的意思,并不掺带多余的任何其他反应。而且,无视既是高贵的蔑视,又是宏大的宽容。无视原则能够化来恶意为虚无,且不作出任何攻击反弹,「我蔑视他人这恶意的攻击,但我还是宽恕他人这愚蠢的行为」,很符合我的「和」价值观。

恕我再改言之,无视意味著绝对无比的「无动于衷」,算是绝妙的蔑视态度了。那些并不造成任何物理上损失的恶意攻击,可以粗糙地归为一类:「挑衅」。这行为上的的确如同字面意义,为的是想激怒受害方,使后者产生不悦感,那么「无视」反应恰恰就能很好地挫败敌方的这一意图。心境如水,霸气十足。我来示范下:我在知乎上拉黑用户的原则是一旦遭受来自恶意用户的人身攻击,就直接「静默拉黑」,这举动在敌方看来就仿佛当事人泰然不为所动,没有任何反应,只轻轻地把他一手指弹到黑名单池,一劳永逸且不可逆转地切断了一切接触途径。毫无疑问,这脑补能当场给予敌方99999伤害,后者越中二伤害就越高。

于是,我反而奇怪 Real Life 中为什么仍旧有那么多人热衷于讨论令人反感的事物,例如几年前天天输的国足,这货臭名昭著得不能再臭,于是满口国足国足的观众,就如同满口排泄物排泄物一样令我厌恶。国足已经差劲到没有再被关注的任何价值,就让它自生自灭去,还偏要提,不光自我弄脏嘴巴,还影响他人心情。

我说过,欣赏也好,厌恶也好,都意味著被触动,有触动就意味著关注,而而大量的关注就能创造经济上的价值二〇一二年年初归真堂活取熊胆的事件闹得很火,其实这可以算是对官方非常有利益的炒作,试想,如果哪天某人的亲人突然处于生命危险期,要被救活只有一个办法:「使用熊胆产品」,那么他人最先想到的会是什么?没错就是那因活熊取胆而一举臭名昭著的归真堂,但当事人一般情况下会不管一二,就消费熊胆产品先救活了亲人再说,于是说到底赢家还是归真堂。凤姐,芙蓉姐姐等人颇为使人反感,却笑到了最后,也同理。

最后,我并不提倡对一切来自敌方的恶意一律采取「无视原则」,否则有时就和阿Q的「精神胜利法」没两样。那么什么情况下不便采用被动的「无视原则」呢,那便是遭到物理上的实际损失时,这时就要站出来主动维持自己的利益了。对于归真堂案例,若要惩罚这家公司,理想的情况便是舆论批评得严重到后者被法院执行经济制裁,或是遭到市场上的抵制而损失惨重。后来这家公司上市曲折无比。

2017 Sep 19
只有 Python 高手知道的 tuple

熟悉 Python 的人都知道,它从语法上支持的内置数据结构一共四种,即 tuple, list, dict, set 等, sequence comprehension 一共有三个,唯独没有 tuple comprehension, 其形式被解析为生成器表达式,而且表示单元素的 tuple 也很不一样,需要额外添加一个在新手看来十分碍眼的逗号(1,).

但其实我们只简单地把 tuple 理解为一个 immutable 版 list 了,并没有深刻理解到它的本质。推上有人如此一针见血地指出:

我终于发现了,tuple 既可以当数据结构,又可以当模式来匹配变量。所以 tuple 说穿了是一个「不规则又不可变的数据结构或模式」,自然没有「推导规律」介入的余地,也难怪没有所谓的 tuple comprehension 了。

一旦洞察 tuple 的本质后,你就发现,tuple 原来大有文章:

其一,事实上,返回多个值的函数实则是在返回一个 tuple, 只不过可以省略括号而已。一旦理解透这个,就不会再写出 tp, label_tp = [], [] if len(result) == 0 else zip(*result) 这大坑了。

其二,只有一个变量的 tuple 在模式里可谓等价于变量本身,于是不是说 (1,) 里的逗号多余,而是它本身的括号就多余,毕竟没人爱写 (a,) = (b,); 其实 () 才是唯一真正特殊的 tuple; 于是纯括号就可以被名正言顺地赋予数学上的意义了,即 (a) 等于 a, 而且其实这还带来了方便 wrap line 的额外好处:

1
2
3
hfm_dir_str = (
'/home/acgtyrant/Projects/HamsterForMTK/'
'Hamster_Android_SDK/src/com/mapbar/hamster')

其三,虽说没多少人喜欢 (1,) 这写法,但我们可以分拆 sequence 值成多行,且每行后更有一个逗号!这对强迫症患者真是终极福音:

1
2
3
4
5
6
7
8
9
10
11
12
phodopus_evaluate_command = (
command_pathname,
'-v', video_pathname,
'--proto', proto_pathname,
'--model', model_pathname,
'--mean', mean_pathname,
'-c', cascade_model_pathname,
'--lf_proto', lf_proto_pathname,
'--lf_model', lf_model_pathname,
'--lf_mean', lf_mean_pathname,
'--noshow',
)

于是我习惯分拆函数的超长形参列表多行了,且最后一行以右括号结尾;多行的 sequence 值则倒数第二行以逗号结尾,倒数一行以右括号结尾且不缩进。

其四,tuple 不光可当安全的 immutable 数据结构,而且效率公认比 list 好

此外,tuple 在模式匹配上也威力十足:

其一,方便交换变量:a, b = b, a, 毕竟等价于 (a, b) = (b, a) 模式匹配嘛。

其二,PEP 3132 – Extended Iterable UnpackingPEP 448 – Additional Unpacking Generalizations 也是模式匹配。此外,我们不能直接用星号 unpack generator, 但照样可以模式匹配 a, *_ = range(10), 毕竟只要后者能迭代就行了。现在看来,由于我已经洞察了 tuple 的本质,对它原本的坏印象也没有了。

其三,如果你想要可读性更好的模式匹配,可以试试 collections.namedtuple 库。

2017 Sep 12
「听力残疾」不完全科普

中国残疾人联合会指定的听力残疾等级标准指出:

听力残疾,是指人由于各种原因导致双耳不同程度的永久性听力障碍,听不到或听不清周围环境声及言语声,以致影响其日常生活和社会参与。

听力残疾的分为如下几级:

听力残疾一级:

听觉系统的结构和功能方面极重度损伤,较好耳平均听力损失≥ 91 dB HL
,在无助听设备帮助下,不能依靠听觉进行言语交流,在理解和交流等活动上极度受限,在参与社会生活方面存在极严重障碍。

听力残疾二级:

听觉系统的结构和功能重度损伤,较好耳平均听力损失在 81~90 dB HL
之间,在无助听设备帮助下,在理解和交流等活动上重度受限,在参与社会生活方面存在严重障碍。

听力残疾三级:

听觉系统的结构和功能中重度损伤,较好耳平均听力损失在 61~80 dB HL
之间,在无助听设备帮助下,在理解和交流等活动上中度受限,在参与社会生活方面存在中度障碍。

听力残疾四级:

听觉系统的结构和功能中度损伤,较好耳平均听力损失在 41~60dB HL
之间,在无助听设备帮助下,在理解和交流等活动上轻度受限,在参与社会生活方面存在轻度障碍。

我属于一级,但有很多人难以暸解其具体困难之处,以致有相当多不准确的解读,我便感到很有必要一次性澄清了。

所发现的解读主要有:「听不见」、「听不清」和「听不懂」等。若你语文嗅觉足够敏锐,当然容易一眼看出其不同:

  • 听不见:又称「听不到」,即几乎感觉不出一切声音
  • 听不清:听得见声音,但是「干扰」很严重,从而只接收到「失真」的声音,听障人本身的听力缺陷有可能会引发此现象。
  • 听不懂:听得见又听得请,但是不知要如何理解其意思。就像小孩听不懂大人的高深话题,中国人听不懂老外说啥一样。

不过,就我的经验来看,实际情况是要更复杂些,以上三种并非彻底彼此独立,即彼此有多为交集:

其一,若听不见的缺陷并不完全,也就是说还是能听得见部分声音,就会产生由「听不见」缺陷所导致的「听不清」障碍。打个比方,一个听障人能明确听得见「aoe」,但是几乎听不见「iu」。于是若一个人对ta说了「啊噢呃咦唔」,但是ta是「听不清」完整的句子的,因为ta只能明确地听得见「啊噢呃」,「咦唔」就听不见,于是ta或许可以通过对方的口型看出有发出了五个字的声音,ta 还知道前三个字是什么,但是就是不清楚后两者又是什么。于是此谓由并不完全的「听不见」缺陷,所导致的「听不清」缺陷

其二,若一个人听不清对方的话,当然就会不好理解对方所表达的,即由「听不清」所导致的「听不懂」的障碍。我猜学过英语的诸位应该深有体会:在正式学习英语之前,当听见一段纯粹的英语对白时,只会觉得它如同「呼噜呼噜」一样足够「模糊不清」的一段声音,要模仿发音更是不可能,因为我们连其所包含的每一个音标单位的发音都不知道。于是我们若要听得懂这段对白,就得弄清楚句子的完整读法,即把它分割成众多独立的单词,再一个一个地弄清楚其意思,其发音又是什么。当我们熟悉了每一个单词,于是要听得懂完整句子就不难了,理解其意思也水到渠成。所以结论是:若要听得懂外语,就必须先克服「听不清」的障碍,而这恰恰是需要练习的。其实对母语的学习也是如此,只不过因为在母语环境中,实在足够「耳濡目染」,以致大家长大了,都会几乎忘了自己对母语的掌握,其实是有「练习」过的印象。

我说过自己属于听力残疾一级级别,当然也就处于纯粹的「听不见」处境了,听力损失有一百分贝多,是什么样子的?家庭聚餐时,我扭头看电视,全然听不见位置相邻的父亲狂涛怒吼过。若你靠近我耳旁用力尖叫,能听得见一点点点。不过如今可不好说,因为听力衰退越来越厉害了,其实据母亲说,一开始听力分贝损失是 85-110, 可至少在两年前衰退到 100-120 了。

好在「助听器」能打破这困境,原理应该是通过耳背上的仪器收集物理上的外部声音,并放大声音响度并输送到耳部,突破听力损失的阈值,从而让用户「听得见」了。

仍无法解决「听不清」的障碍,我说过听力缺陷比较复杂,其实上面所用到的「啊噢呃咦唔」例子还不够贴切,用颜色来类比更好:正常人能看到五颜六色的世界,但听障人就像色盲一样,只能看到有颜色偏差的世界。什么颜色看得见,什么颜色看不见?这个就因人而异了。

于是就轮到我正在使用的「人工耳蜗」隆重登场了。听障人的种种问题,大多应该可以归结于「耳蜗」的生理缺陷,但人工耳蜗就可以取而代之,即通过手术,把它嵌入到耳蜗处,并通过「电磁感应」现象,来接收附在外部的「言语处理器」所在物理上所收集到的外部声音信号,转化为神经上的脉冲信号,绕过了原本功能缺失的耳蜗,直接发送给大脑,从而让大脑直接感到「听觉」。

既然彻底绕过了原本有缺陷的「耳蜗」,则「听不清」障碍就几乎全无,用户能像正常人一样直接听到极其不失真的「原声」。所以如今我实际上只处于「听不懂」处境,即对汉语和英语的掌握,前者需要进一步的练习,后者需要从零开始,这些都只是如同小孩牙牙学语的另一外回事了。

当然,就目前的技术来说,人工耳蜗并不能像天然耳蜗输送纯粹的「原声」,只能尽可能地减少「失真度」而已。就目前来说,我的困难之处如下:

  1. 需要花时间从头开始学习英语听说,很久以前我就开始上某英国绅士的英语口语课,当前只听得懂大概六分之一;该绅士真是好人。
  2. 几乎没法进行「多人对话」,很多饭局就只能默默地低头吃饭……
  3. 在空间相当大却又嘈杂的地方,很难听清对方的话。
  4. 没法一边注意力分散在别处时,一边听同行者的话,比如上下楼梯。
  5. 很疲劳的时候,听力效果也会大幅度下降,可谓累得不想再听了……
  6. 普通话口音很怪,先天没训练好,矫正要付出大量精力。

2017 Sep 4
单位元对编程的启发

最近,我在处理一个文本文件,它有三列,分别为文件名,数字,字符串,且其中第一列中有若干重复了的部分,于是我需要把这些重复的行合并起来,即第二列合并为总和,第三列合并为一条新字符串,且用空格分隔。

我一开始想如此合并:

1
2
3
4
5
sum = 0
string = ''
for duplicate_line in duplicate_lines:
sum += int(duplicate_line.split()[1])
string = ' '.join(string, duplicate_line.split()[2])

但迭代完后 string 并不符合我的期望,它包含了一个 heading space! 这令我想起了抽象代数学上的「单位元」,即它在某二元运算中,与任意元素运算后,结果的值恒为后者本身。比如加法中的 0 与任何数字相加,恒返回后者的原值;乘法中的 1 也同理。

于是我们可以说,把 ‘ ‘.join() 当二元运算符来看时,不存在单位元,即 ‘ ‘.join([a, b]) 中 b 为任意字符串时,不存在 a 变量能使这函数返回 b 本身,哪怕变量 a 为空字符串时,也会返回包含了一个 heading space 和 b 值的新字符串!就像我上面的代码一样。不过 ‘’.join() 当然就有单位元即空字符串。

反观 Python 的 int 加法,它就有单位元,即 sum 的初值 0, 也难怪它和悲剧的 string 君不同,可以安全地返回我期望的值。

这启发了我又一条编程规范:要小心那些没有单位元的函数或运算符,并处理得当。其实上面合并 string 的代码可以妙用 list comprehension, 回避掉 heading space.

1
' '.join([duplicate_line.split()[2] for duplicate_line in duplicate_lines])

举一反三,Python Sequences 的 index 为什么从 0 而不是 1 开始计呢?您倒不如想想另一个问题:Sequences Index 的单位元是什么?即对 Index 进行二元运算时,加多少就返回原 Index? 当然是 0 了!再看 C 指针,它和 0 相加时就返回原指针,也难怪 C 的 Array Index 和 Python 的 Sequences Index 都从 0 开始,这是为了当直接把原 Index(甚至 C 的指针即地址)和 Index 初始值(即单位元)相加时,能方便且直接地得到原 Index(甚至 C 的原指针即原地址)

2017 Sep 3
什么情况下 map 比 list comprehension 好?

事实上,list comprehension 公认效率比 map 好所以当 map 比 list comprehension 可读性好且不在乎性能时,可以优先用前者。

那问题又来了:什么时候 map 的可读性比较好?当且只当低阶函数是你所熟悉的 Python 函数,便利的 sequence 对象也够一目了然时。比如我就经常用它转换命令列表,够一气呵成:

1
2
3
4
5
6
7
8
traincascade_command = [
command_pathname,
'-w', weight,
'-h', height,
'vec', vec_pathname,
]
traincascade_command = map(str, traincascade_command)
subprocess.call(traincascade_command)

妈妈再也不用担心我不小心传 int, pathlib.Path 进命令列表了,写的 list comprehension 又长又臭得超出 79 个字符了。同理,rects = map(int, rect_strs), positives = map(abs, integers) 之类的精炼表达式也可以。

因为你很清楚 str, int 和 abs 等是一元函数,作用是什么;反之,即用你所不熟悉的 Python 函数,比如 a = map(b, c), 这时你往往会产生四重疑惑:

其一,b 是一个 callable 对象吗?
其二,b 可以只接受一个形参吗,即它到底是不是一元函数?
其三,c 是否为 sequence 对象?
其四,c 的 iterable 元素又是什么鬼?

更别说用雪上加霜的 lambda 了。

但换用 list comprehension 就没这问题:a = [b(d) for d in c], 显然 b(d) 表达了 b 彻彻底底是个一元函数,且 c 作为 sequence 对象时 iterable 元素是 d, 最终 a 会被 bind 到一个 list 对象。可读性更胜一筹。

举一反三,你可以琢磨什么情况下 filter, funtools.reduce 等也能如法炮制。

2017 Sep 2
using 指示命名空间习惯不好

如果不禁止 using 指示,那么你在多人项目里,如何判断同一个标识符在由不同工程师编写的源代码里,是否为同一个东西?

如果大家保持一致性,即某些命名空间都要 using 指示出来,别的不 using 指示。然而,又如何规定哪些要指示哪些不用指示?害得大家束手束脚地保持一致,规定也众口难调地麻烦;对个人项目也是一样的道理,如果开发者随心所欲地在这里不 using 指示 std, 却又在那边 using 指示它,从长远来看维护将是灾难。

最后,你能保证将来永远不会取消对某命名空间的 using 指示吗?否则你得给这被 using 指示的命名空间里所有用到的标识符一一加上命名空间作用域前缀,你想象一下怎么弄吧,你有办法自动化处理且绝不出错吗?

对我来说,与其大费周章地划出可以被 using 指示的命名空间,还不如一劳永逸地用奥卡姆柴刀砍掉 using 指示用法,也省了我在 tweets 里列举的种种缺点。

我写 C++ 时,爱把迭代器对象直接声明为 iterator 并拿来用,也很清楚 vector 是一个「向量」对象或别的什么,反正不会是 std::vector 那种容器,我放心我舒服。你呢?

2017 Aug 31
代码,编码,编程,规范和风格

我最近下定决心不再拖延博客的更新,但也懒得重启独立的技术博客,于是以后技术博文就在这里发表。

计算机科学基础老生常谈,编程语言也是如此。我没兴趣当 language lawyer, 就讲讲颇为人文的编程规范吧。

大家过去应该也看到过不少类似的关键词:代码风格、编码风格、编程风格和编程规范等等。光一家著名的 Google Coding Guide Style 的民间翻译就囊括了以上用词。最初,李开复先生称它为「编码规范」,且我以前翻译 Google C++ Guide Style 时,没仔细琢磨好翻译用词,就同时用到了「风格」,「编码」,「编程」等等,不一致啊。

咬文嚼字了一会,先从「代码」、「编码」、「编程」汰劣存优开始吧。「代码」只是一个名词,不如动词来得亲切;「编码」即是表示一系列机器级别指令的名词,又是表示手动转换机器码与汇编码的动词;然而人类死跟机器码较劲的时代已经结束了,现在是高级编程语言的天下了,我们不想拘泥于表面的「编码」,而只关心足够抽象的 Program, 即程序,所以现在看来「编程」是最理想的翻译用词。

至于「风格」与「规范」又如何呢?我倾向于 The conventions we follow 对此的分析:「风格」只讲究代码的格式化形式,比如缩进啊空白啊注释形式啊,然而「规范」涉及的更为广泛,即同时包括了编程风格和其它规范,就像该不该用某语言特性,用什么编译工具链,甚至如何版本控制等等。

编程可谓一门艺术,又是一项工程。若要运用得炉火纯青,可不能光划个风格就了事,还要相当洞悉所用编程语言的特性,以及开发环境的理想部署等等,这时「规范」就很重要了。从此以后,我将不时地探讨种种编程规范。

2017 Aug 30
C++ 怎么念

我有听力障碍,于是就算三次元里周围有人谈及 C++ 且把它读成「C加加」,我也不怎么有印象。倒是长期以来受英文资料薰陶,英文上的 C++ 便先入为主了,毕竟 + 在英文里就是 “plus”. 于是我凡看到这词时,脑海就默默地响起 “C plus plus”, 也难怪我在上北京大学的公开课时,不由得呵呵一笑。不过推上大多数人不以为然,有的猜读为 “C double plus”, 有的搞怪成「C艹」,有的恶俗地叫「C屁屁」。

其实 C++ 到底读成什么并不重要,就看你和谁打交道了。如果就只局限于品读谭浩强大师著作、不会上 StackOverflow、天天百度 C++98/03 文档、从来没去过官网 isocpp.org、靠 Visual C++ 6 开发的小圈子里,大家约定俗成地一起读成C加加,也挺好;如果你向来满口污言秽语,「C艹」很适合你;如果你想和 Bjarne Stroustrup 之风流谈笑风生,小心点别念错 cplusplus 是了。

其实查 C++, C#, TeX 之类的英文读法也不难:去英文维基百科看条目即可,一般开头就有音标,C++ 念 /siː plʌs plʌs/.

2017 Aug 29
如何跟进深度学习的研究前沿?

起步

一开始没必要就读论文,而是通过 cs231n, deep learning 等教程打好基础。其实由于深度学习这领域刚发展起来,所以 CS213n 给了不少论文的对应关键词,比如 AlexNet, VGGNet, ZFNet, GoogLeNet, ResNet 等等。可以从这相当基本的论文开始读,如果作为本科生且没有接受过学术训练,花一周以上才免强读懂一篇论文也不奇怪,但读多了就越来越快,我现在刚两小时略读完一篇论文,如果是很水的论文大概可能在半小时就全读完。

如果很难读懂论文,可以先搜搜别人的论文笔记(当然是中文),来源经常包括 CSDN 博客,简书,知乎问答,知乎专栏甚至个人博客等等,我都订阅了它们的 RSS, 其中知乎专栏可以直接用 Inoreader 订阅。

用 Zotero 管理论文

我用 Zotero 管理论文,它有三个优势:可以通过浏览器插件在相关网页上(比如 arXiv, Google Scorlar, Microsoft Research 等等)一键收录论文到 Zotero; 可以在论文条目下写笔记;论文分类、归档、排序十分方便。怎么用 Zotero 管理网上满是教程,我就不赘述了,我只给大家看看我的分类树以及时间排序界面:

Zotero 界面

于是读的论文可以按时间和重要性排序递增,顺便一提,分类树随时要修改以符合你当前心中的最佳分类,比如我以前把 AlexNet, VGGNet, ZFNet, GoogLeNet, ResNet 等都是放到「年度论文」的,但现在我把它们改移到「网络结构」里了,同时该分类还有 Network in Network, Highway Networks 等等;此外我曾经有个分类「奇技淫巧」,旗下又有「训练算法」,「防过拟合」,「权重初始化」和「激活函数」等等,但我最近嫌分类太散乱,于是又花了点时间苦思冥想,终于想出更合适的分类「优化理论」,我便取消「奇技淫巧」这分类,把大部分论文都归档到这新分类。

收集论文、开始跟进研究前沿

读论文多了,你就会越来越熟悉你所从事领域的学术大牛,比如物体检测的 Ross Girshick, 语义识别的 Jifeng Dai, 对抗学习的 Goodfellow 等等。这时可以直接在 Google Scholar 的学术用户页面上关注他们的新文章,这样可以在第一时间收到他们发表论文的最新动态。或者干脆天天刷 arxiv 也可以,当初 Focal Loss 那篇论文我晚了好几天才收到 Google 快讯,而别人早在知乎相关问题讨论起来了,一问才知道他们习惯天天刷 arxiv, 可惜我连 Zotero 里的论文都没读完,更别说天天刷新论文了。

在知乎上也可以关注顶级会议、学术竞赛的相关问题,比如 CVPR 2017 有什么值得关注的亮点?如何评价ILSVRC2016的比赛结果? 上面会有别人帮你总结好的答案,直接按图索骥即可。

也可以直接去学术竞赛看天梯排名,看看当前战斗力最强的模型对应的论文是啥,扒下来读,比如 PASCAL VOC 2012 Segmentation Competition 当前的首席 DeepLabv3 和第五席 PSPNet.

如果打算专心用 PyTorch 做研究,可以订阅 awesome-pytorch 的 RSS, 对其他 GitHub 上的类似 awesome 项目也可如法炮制。

最后,若有人能带你就更好,比如导师会收集论文并传给学生,据我所知商汤他们每周有论文分享会,以跟进论文最新前沿。

Written with StackEdit.

2017 Jun 27
如何打分

豆瓣对书籍和电影的评分是五星制,即一星到五星的字面意义分别为:很差——较差——还行——推荐——力荐。

我对这评分制很满意,因为它的评级是奇数,即存在中间值,又向高低延伸了恰到好处的两个评级。这么以来我可以如此进一步阐释该评分机制:

三星:可有可无,即看了没啥快感,不看也没损失。
二星:反感,即有负面评价。
四星:好看,使我产生了愉悦感,自然愿意向他人推荐。
五星:特别好看,让我十分狂喜,以致愿意给出远超四星的高评价,证明这是佳作中的佳作。
一星:负面情绪更为强烈,即对其抱有纯粹的敌意,我也许会为此破口大骂,执行制裁。

一星和二星的区别很关键,世界那么大,我不喜欢的东西自然也多了去,对于二星作品,我讨厌它,但可以老死不相往来,于是彼此的互动也就到此为止了。不过我若给作品一星,说明这作品不光惹我讨厌,而且还彻底激怒了我,以致我竟然产生纯粹的敌意来。所以我不会轻易给作品打一星,如果打了,说明性质很严重。

我回顾了下我到目前为止看过的 179 部电影,其中被我打一星的作品只有「美丽中国乡村行」和「嫁给大山的女人」,一个涉及抄袭,另一个在宣传我所敌视的拐卖价值观。

此外,我在回顾中又重新审视了下四星和五星的区别,其实它们应该贯彻二八定律:即五星只给一堆已经达到四星水准的作品中特别出色的部分,即佳作中的佳作。且如果五星评价次数与四星的比例越小,说明其评价越愈发稀缺,份量自然也越高。于是我重新把过多的五星评价打回三四星,留下了极少数我觉得愿意给出五星评价的上乘作品。

我决定每年不光归档当年已观看的作品,还要集中重新回顾作品一次,原本好看且被评为四星的作品要么继续保留四星,要么因为我审美观进一步提高而被降星,给出五星的评价次数一定要控制在百分之二十以内。原则上来说五星评价应该越少越好,且大多数作品的得分集中在三星四星,毕竟若看的二星作品过多,说明我自己在自讨苦吃,没有意义。

我给出五星评价的作品到目前为止有:狩猎、地心引力、降临、你的名字、革命机、疯狂动物城、火星救援、西游记之大圣归来、迷雾、消失的爱人、海洋天堂、辩护人、僵尸世界大战、环太平洋、福音战士新剧场版:Q、守法公民、美丽心灵、万能钥匙、调音师。

最后我要批评大众点评的评分机制,得分制也是五星,但中间值竟然是二星,即差——一般——好——很好——非常好。

「差」这一星可不能有效区分「我吃到了苍蝇,激怒了我!」和「难吃」这两种评价;为了区分「好」、「很好」和「非常好」三种评价,按照二八定律,顾客需要先光顾二十五多种不同的商户,才能从中挑出五种达到「很好」的商户,以及仅一种达到「非常好」的商户。显然若顾客的消费经验不足,容易被这三种评价弄得手足无措,以致只能随便打分了事,没法有效科学区分。

Written with StackEdit.