CSDN-NLP:基于技能树和弱监督学习的博文难度等级分类 (一)

团队博客: CSDN AI小组

1. 背景

CSDN 每天都会产生数以万计的博客数据,但是这些数据没有难度等级的体系结构,这种体系结构在 个性化推荐用户画像榜单 等业务上都有很大的作用和价值。

本文主要阐述如何从头开始构建一个难度等级分类框架,用于实现博客在 初级中级高级 三个类别上的分类。

在实现方法上,由于精确的标注数据难以获取,故本文根据各个时间阶段的特点,分别使用不同的方法,逐步提升分类的效果。

2. 方法

本文的框架根据框架构建的不同阶段,主要分为以下 3 个部分。

2.1 规则:快速实现

第 1 部分是规则构建,规则可以拉通整个流程,在保证精确率(Precision)的前提下,实现部分博客数据的难度等级分类。

具体而言,通过观察博客样本发现,标题中的某些关键词或模式能够明确地体现文章的难度等级,我们称之为强规则。通过对 初级中级高级 三个等级强规则的归纳,可得出以下规则 (为了便于说明问题,下面展示的是简化的规则)

初级类别强规则

primary_level_pat = re.compile(r'初级|初阶|入门|基础|错题集|练习|课后习题|习题答案|学习笔记|考试复盘|每日一练|每日一题|每日真题|管理系统|管理平台|常见|常用|环境搭建|安装|随手记|随记|打卡|踩坑|小技巧')

中级类别强规则

middle_level_pat = re.compile(r'((?:(?:中级|架构|构架)(?!.*?(?:师|岗)))|(?:中阶|进阶|深入))')

高级类别级强规则

high_level_pat = re.compile(r'高级(?!.*?(?:师|岗))|高阶(?!函数)|论文')

基于以上规则,通过对博客标题的正则匹配,可快速实现博客难度等级的判断

def strong_rules_4_level(title):
    ''' 博客难度等级分类强规则 '''
    rule_level = None
    kw_list = None

	# 初级
    kw_list = primary_level_pat.findall(title)
    if kw_list:
        rule_level = "1"
        kw_list = list(set(kw_list))
        return rule_level, kw_list

	# 中级
    kw_list = middle_level_pat.findall(title)
    if kw_list:
        rule_level = "2"
        kw_list = list(set(kw_list))
        return rule_level, kw_list

	# 高级
    kw_list = high_level_pat.findall(title)
    if kw_list:
        rule_level = "3"
        kw_list = list(set(kw_list))
        return rule_level, kw_list

    return rule_level, kw_list

此外,对于低质量的博客可直接判定为初级类别。博客质量分的计算逻辑请参考 博客质量分计算(二),质量分取值 {0, 1, 2, 3, …, 100},当质量分小于 20 分时,判定为低质量博客。

优化:实现落地快、精确率(Precision)高、可解释性强。
缺点:缺乏体系结构、覆盖率和召回率(Recall)低(泛化能力差)。

2.2 匹配:结构化知识体系

第 2 部分是结构化知识数据体系的融入。在第 1 部分中,通常只能通过观察样本数据的方法,构建极其简单的规则集合。这种规则集合通常比较简单朴素、缺乏体系性,而体系结构需要领域专家才能构建。因此,为了进一步提升难度等级分类的效果,本文引入由领域专家构建的 CSDN 技能树,并基于匹配的方法,实现博客难度等级的分类。

技能树体系结构示例如下所示 (C语言技能树简化版)

C语言
├── C语言初阶
│   ├── C语言概述
│   │   ├── C语言发展史
│   │   ├── C语言特点
│   │   └── 编程机制
│   ├── 数据类型
│   │   ├── 变量
│   │   ├── 常量
│   │   └── 基本数据类型
│   └── 语句与控制流
│       ├── 语句与程序块
│       ├── 判断语句
│       └── 循环语句
├── C语言中阶
│   ├── 函数与程序结构
│   │   ├── 函数的声明与定义
│   │   ├── 函数的调用
│   │   └── 函数的递归
│   ├── 数组
│   │   ├── 一维数组
│   │   ├── 二维数组
│   │   └── 变长数组
│   └── 指针
│       ├── 指针与地址
│       ├── 指针与函数参数
│       └── 指针与数组
└── C语言高阶
    ├── 结构体
    │   ├── 结构体数组
    │   ├── 结构体指针
    │   └── 链式结构
    ├── 预处理器
    │   ├── 宏定义
    │   ├── 条件编译
    │   └── 内联函数
    └── 存储管理
        ├── 存储类别
        └── 内存动态管理

本文根据博客的标签或标题中某些关键词,通过标签或关键词 和 技能树之间的映射关系,判断与当前博客最相关的技能树,映射关系表如下所示 (以C语言技能树为例)

{
    "tree_name": "c",
    "keywords": [
        "C语言",
        "C/C++",
        "结构体",
        ...
    ]
}

确定技能树之后,使用技能树匹配算法,计算博客和技能树中知识点的相似度,具体方法请看 CSDN问答标签技能树(二) —— 效果优化 中的 2.2 匹配算法效果优化。在匹配到最相似的知识点后,通过该知识点的难度等级,进而得出文章的难度等级。

优点:权威、可解释性强。
缺点:知识构建需要耗费大量人力物力。(当前已上线的技能树还未覆盖所有的领域)。

2.3 分类:弱监督学习

第 3 部分是基于弱监督学习的分类模型的使用。分类方法 可以缓解第 1 部分中泛化能力差的问题,以及第 2 部分中知识体系不完善的问题。

训练分类模型需要大量的标注数据,为了降低数据标注带来的人力物力的消耗,本文使用弱监督学习的方法实现难度等级的分类。

具体而言,在博客数据中,有一部分数据用户自己标注了难度等级,但由于每个人对难度等级体系的认知存在差异,导致数据集中存在较多的噪声,为了缓解该问题,本文使用数据编辑(data-editing)的方法优化数据集 (参考论文 A brief introduction to weakly supervised learning),提升数据集的质量。详细步骤如下所示:

  • (1) 向量化:使用 TF-IDF 算法对数据集中所有的博文样本(博客标题)进行向量化;
  • (2) 图构建:以博客样本为节点,样本之间的相似度为边权重,构建样本关系图;
  • (3) 数据编辑:
    • a) 对于一个节点,如果 top_n 的相邻节点都是同一类别,且与当前节点的类别一致,直接加入到新的数据集中;
    • b) 对于一个节点,如果 top_n 的相邻节点都是同一类别,且与当前节点的类别不一致,将标签修改为相邻节点的类别后,加入到新的数据集中;
    • c) 其他情况的节点,直接舍弃。

CSDN-NLP:基于技能树和弱监督学习的博文难度等级分类 (一)
图1. 数据编辑

得到优化后的数据集之后,直接使用 sklearn.ensemble.RandomForestClassifier 分类器实现博客样本的分类。

优点:成本低、泛化能力较强。
缺点:弱监督效果的可信度较低。

2.4 融合:各尽其能

以上三种方法分别有不同的优缺点,通过特定的融合策略可以实现不同方法的互补,发挥各种方法优点的同时,弱化缺点。具体策略如下:

  • (1) 对于强规则方法识别的样本,直接使用强规则的结果;
  • (2) 对于有匹配结果(相似度得分)的样本,与分类概率值进行加权融合;
  • (3) 对于没有匹配结果的样本,直接通过分类概率进行判定。

使用上述策略,a) 可充分发挥强规则的作用,提升整体框架的准确率(Precision);b) 由于弱监督方法结果的置信度不够高,故可通过技能树匹配的结果,对分类结果进行调整;c) 由于匹配方法中,技能树知识体系并没有覆盖所有领域,故可通过直接分类的方法对未覆盖领域的样本进行分类。

3. 总结与展望

3.1 总结

难度等级分类看似一个简单的分类问题,但由于缺乏精确的标注数据难,依据快速落地并不断快速迭代的思路,本文先后同归强规则、基于知识体系的匹配算法、基于弱监督的分类算法,逐步完善整个分类框架,具有较强的可执行性和较快的迭代速度。

3.2 展望

  • (1) 当前的匹配算法是基于关键词的匹配,下一步会考虑基于向量的匹配方法,以提升匹配算法的泛化能力;
  • (2) 当前的弱监督策略还比较简单,后续会使用少量标注数据,基于半监督的方法,进一步优化数据集。

4. 相关链接

CSDN 技能树
博客质量分计算(二)
CSDN问答标签技能树(二) —— 效果优化
A brief introduction to weakly supervised learning

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年5月27日 下午3:46
下一篇 2022年5月27日 下午3:49

相关推荐