前言

之前在计划开发自己的独立游戏的时候,有在 Game Jolt 这个网站上创建游戏项目。在设置的时候,我发现这个平台对游戏分级的把控很严,这里的分级指的不只是色情(Sex)内容,还包括了酒精(Alcohol)、赌博(Gamble)、语言(Language,这里特指言语的“文明程度”)
其中「语言」的分级主要有四个,也是美国最常用的分类标准,分别是 Mild(温和)、Medium(中等)、Strong(强)、Strongest(最强)。Mild 不代表没有骂人的话,但很少出现脏字;Strongest 也不代表全是脏话,而是程度深的脏话出现频率较高。

有一天我坐在马桶上突然想到,汉语的脏话不比英语里丰富多了?从各个方言中大大小小的脏话,到全国通用的「问候双亲」,到现在全球皆知的「nmsl」,这些脏话有的是常用的,不太冒犯人的,有的多是用来开玩笑,有的却是十分恶毒的。这些脏话在不同的情况下还有不同的用法,在不同的语境下可能还会改变它本身的意思,怎样给他们分级呢?
前面提到的那四个分级,在我看来,界限有些太模糊了,特别是 Strong 和 Strongest,从字面意思上是一个形容词原型和一个最高级,但没人能说出它们明确的界限。
所以我打算自己设计一套「汉语脏话分级标准」,尽管没什么实际的用武之地,从更具体的角度来对不文明用语进行更确切的分类。

摸索

找参考

要设计一套分级标准,首先最重要的事情当然是:找参考。

我翻遍了维基百科,发现现有个各种分级标准,大都是以年龄为界限的,无论是电影还是影视,一般都只有「未成年人禁止观看」「未成年人需在监护人指导下观看」「未成年人可以观看」之类的限制。这时我才意识到一个问题,这些对艺术作品的年龄限制,考虑到的因素里就包括了「脏话」,也就是说,这些分级标准并不可以用来衡量「脏话」这个单一的因素,而是包括了「酒精」「情色」「毒品」等敏感内容的总集。找它们做参考是不合理且无效的。

于是我换了个思路,在 GitHub 上找了一下与「脏话过滤」相关的中文项目,不过都没有达到我需要的「分级」的要求,甚至还发现了一些不是脏话的脏话(为什么过滤对象里会有「共产主义的幽灵这个词」,这不是共产党宣言里的吗?)

看来找参考是不行了,就只有靠自己了。

分析

既然要分级,要不就先分个类吧:

  • 直接怼人类(例:傻逼、废物、人渣...)
  • 问候双亲类(例:操你妈、你妈死了...)
  • 长辈晚辈一起怼类(例:狗娘养的、你妈没教过你吗...)
  • 语气助词类(例:他妈的、卧槽...)
  • ......

我逐渐发现这样是分不完的,因为这其中很多的类是互相包含的,而且还有很多的类无法全面地考虑到。具有歧视性色彩的脏话,可以单独分类,但这种歧视也可以分为「种族/国家歧视」(例:黑鬼、棒子、毛子...)、「对性少数群体的歧视」(例:人妖...)、「地域歧视」、「性别歧视」「职业歧视」等等;具有低级侮辱性质的也可以再分个类,例如身体侮辱、人格侮辱;亲密的朋友间开玩笑,没有冒犯性的脏话,还可以分个类,这样的词在不同的语境下还可以有不同的意思,例如:傻瓜,在前面加上一个「小」就变味了;方言里的脏话,也可以单独分成一个类,不过这就不在「分级」的讨论范围中了......

这样看来,分级和分类并不能共通,只能换个思路了。

要分级,侧重点应该放在对他人的影响上,这样才能决定脏话的冒犯性有多强,一句脏话有多脏。这里我想到了边沁的「快乐计算」,他将快乐分为了程度、广度、持续性等,用它们来量化快乐(矢量的分解?),再根据社会平均的快乐程度来决定社会的幸福指数。

这里或许可以参考这种计算方式,用来量化语言的「文明程度」。

我们将「脏话」的“脏的程度”定义为「粗鲁度」,将其分解为以下几个量:

  • 歧视性:对某一特定群体的针对程度
  • 侮辱性:对辱骂对象造成的冒犯程度
  • 攻击性:言语发生时的认真程度(即目的偏向于攻击的程度)
  • 低级性:对辱骂对象外在因素的聚焦程度

若一句脏话是针对某一个特定的群体而言的,那么歧视性就较高;若一句脏话让被辱骂的对象感到十分不舒服,甚至情绪激动,那么侮辱性就较高;若一句脏话被说出,只是为了让对方感到被冒犯,或是为了上对方吃点苦头,那么攻击性就较高;如果一句脏话的集中点在对方的外貌上,例如「丑八怪」,那么低级性就较高。

将这四个量综合起来,最后来判定一个词的「粗鲁度」,再根据粗鲁度给词汇进行分级。若我们规定这四个量的最大值都是 25,只能取 0-25 的数字,那么加起来,粗鲁度的最大值就是 100。

让我们再回到之前谈到的美国常用的几个语言分级:Wild、Medium、Strong、Strongest。我在这里借鉴一下这四个分级的意思,做一些修改,对不同粗鲁度的脏话进行分级:

  • 普通:0-25
  • 中度:25-50
  • 强烈:50-75
  • 恶毒:75-100

实践

现在让我们找一些实例来分析。例如「黑鬼」,它具有强烈的种族歧视意味,歧视性较强;它的侧重点在黑人的黑色皮肤上,但不是具体或比较整体的外卖,低级性中度;它会让黑人群体感到被冒犯,具有侮辱性;根据语境的不同,黑人自己说 nigger(黑鬼)这个词的时候,很多时候是为了艺术创作,它在黑人说唱中就很常见,而白人说这个词就通常被认为是恶意攻击,所以攻击性据情况而定。综上所述,这个词的「粗鲁度」在中度和强烈之间。

看起来这种方法是可用的,但出现了一个小问题:词汇/语句的四个量无法被确切地界定,只能对其进行估值,在不同的情况下,其中一个量的大小也是不确定的,于是就导致粗鲁度最终的结果只能是一个范围。

语言毕竟是感性的东西,要用理性的量来计算它,可行度本身就不高,能进行简单地分级已经很不错了,至少能简单且较直观地让人们了解到一句脏话大概有多脏。

进一步规范

既然各个量的数值只能估计,难以确定,那么我们就从语言的角度来看问题。我们可以用描述程度的语句来对应一个范围内的数值,像这样:

  • 具有 XX 性:1-5
  • XX 性较弱:6-10
  • XX 性中度:11-15
  • XX 性较强:16-20
  • XX 性极强:21-25

这样我们就可以把感受表述为语言,再由语言来找到对应的取值范围。

那么问题又来了,这样还是不能得到一个确定的数啊,要怎样才能把范围再缩小?

之前我们把「粗鲁度」分成了四个「属性」,在分别把这四个属性分成了五个用语言描述的「程度」,那干脆就一分到底,把程度也分解开来。

每个程度都有一个取值范围,我们只取整数,每个范围里就只有 5 个数,给每个范围内同一个位置的数各找一个词:

  • 极低(1、6、11、16、21)
  • (2、7、12、17、22)
  • (3、8、13、18、23)
  • (4、9、14、19、24)
  • 极高(5、10、15、20、25)

姑且把这些分解出来的量称作「程度分量」吧,有了它们就可以从确切地整数来衡量粗鲁度了。

完成?

我们已经把「粗鲁度」量化到了具体的整数,不过它仍然处于一个「感性」与「理性」之间的一个尴尬状态,我仍然没有办法将其准确地量化。

于是一个神奇的东西突然蹦进了我的脑海——机器学习

先把我摸索出来的分级规范重新整理一下:

粗鲁度是指语句在特定语境下表现出的不文明程度,或是给他人带来的冒犯程度。

粗鲁度被分解为四个属性,分别是歧视性、侮辱性、攻击性、低级性。歧视性指对某一特定群体的针对程度;侮辱性指对辱骂对象造成的冒犯程度;攻击性指言语发生时的认真程度(即目的偏向于攻击的程度);低级性指对辱骂对象外在因素的聚焦程度。这四个量都是可以被量化的,取值范围是 0-25,取值为 0 时则表示该语句不具有对应的属性。这四个量之和则为「粗鲁度」,取值为 0-100。

为了进一步量化粗鲁度,粗鲁度的四个属性可以再次被分解为它们各自的程度,程度是一个范围值,由语言来描述:

  • 具有 XX 性 / XX 性低:1-5
  • XX 性较弱:6-10
  • XX 性中度:11-15
  • XX 性较强:16-20
  • XX 性极强:21-25

在一个程度范围内,只存在 5 个可被取用的整数,这 5 个整数都是其对应程度范围的程度分量。程度分量用于将粗鲁度分解到确定的整数,它被定义为:

  • 极低(1、6、11、16、21)
  • (2、7、12、17、22)
  • (3、8、13、18、23)
  • (4、9、14、19、24)
  • 极高(5、10、15、20、25)

为了方便,我们将歧视性、侮辱性、攻击性、低级性分别简记为 D(Discriminate)、I(Insult)、A(Abuse)、F(Foolishness),将程度记为 l(Level),将程度分量记为 cl(Component of Levels),粗鲁度记为 R(Rudeness)。

由此得出粗鲁度的计算公式:

R = clD + clI + clA + clF

根据这样的规范,设计一套简单地机器学习程序,让用户对一个词或一个常见的句子进行反应,判断它的粗鲁度。并且,用户不需要知道如何量化「粗鲁度」,只需要回答「您认为这句话的 XX 性____。」,选择弱、较弱、中度、较强、极强,唯一需要进一步提醒用户的是,需要让他们给选择的程度进行进一步的界定,是较低、低、中、高,还是极高?

这张图直观的展示了粗鲁的属性与它们的程度以及程度的分量的关系,可以以这个为模型,在前端做成滚动条让用户更快速地进行判断。

只要收集到足够多的数据并进行合理的分析与学习,就能够做出一套较为可观的脏话分级系统

于是这样,可乐就又立了一个 flag