Coggle 30 Days of ML(24年5月):对话意图识别

Part1 内容介绍

本月竞赛学习将以对话意图识别展开,意图识别是指分析用户的核心需求,错误的识别几乎可以确定找不到能满足用户需求的内容,导致产生非常差的用户体验。在对话过程中要准确理解对方所想表达的意思,这是具有很大挑战性的任务。在本次学习中我们将学习:

  • 自然语言处理基础
  • 文本分类路线:正则表达式、TFIDF、FastText、BERT、T5、Prompt、GPT
  • 大模型分类路线:提示词、思维链、高效微调

内容在线地址(持续更新):Coggle 30 Days of ML(24年5月):对话意图识别

代码汇总:notebooks/notebooks/Coggle202405意图识别 at main · coggle-club/notebooks · GitHub

Part2 活动安排

  • 免费学习活动,不会收取任何费用。
  • 请各位同学添加下面微信,并回复【竞赛学习】,即可参与。

Part3 积分说明和奖励

为了激励各位同学完成的学习任务,将学习任务根据难度进行划分,并根据是否完成进行评分难度高中低的任务分别分数为3、2和1。在完成学习后(本次活动,截止6月1),将按照积分顺序进行评选 Top3 的学习者。

打卡地址:https://shimo.im/forms/RgMDEojsngITUIJz/fill

Top1的学习者将获得以下奖励

  • 天池便携音响
  • Coggle 竞赛专访机会

Top2-3的学习者将获得以下奖励

  • Coggle 周边福利
  • Coggle 竞赛专访机会

历史活动打卡链接,可以参考如下格式:

Part4 意图识别

背景介绍

意图识别(Intent Recognition)是指通过自然语言文本来自动识别出用户的意图或目的的一项技术任务。在人机交互、语音识别、自然语言处理等领域中,意图识别扮演着至关重要的角色。

意图识别有很多用途,例如在搜索引擎中分析用户的核心搜索需求,在对话系统中了解用户想要什么业务或者闲聊,在身份识别中判断用户的身份信息等等。意图识别可以提高用户体验和服务质量。

学习打卡

任务名称 难度/分值
任务1:数据读取与分析 低/1
任务2:正则关键词与文本分类 低/1
任务3:TFIDF提取与文本分类 中/2
任务4:词向量训练与使用 中/2
任务5:LSTM意图分类 高/3
任务6:BERT意图分类 高/3
任务7:T5/Prompt意图分类 高/3
任务8:BERT高效微调 高/3
任务9:大模型N-Shot文本分类 高/3
任务10:大模型高效微调 高/3

打卡地址:https://shimo.im/forms/RgMDEojsngITUIJz/fill

昵称 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10
无盐 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
叶文强 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
NULL :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
ringwraith :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
又双叒叕 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
任宇の神樣 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
Cary
CSlearning
李培
Serendipity
zwen10628

注明:

  1. 在任务积分外还考虑模型在排行榜的得分,同等积分下排名榜排名优先。
  2. 如果使用Paddle或AI Studio打卡的同学,会获取额外的奖励。

任务1:数据读取与分析

NLP是自然语言处理的缩写,是研究如何让计算机理解和处理自然语言的一门技术。自然语言是人类交流和表达思想的主要工具,具有丰富的语义和多样的形式。学习NLP需要掌握基本的语言学概念、文本预处理和文本表示方法等基础知识。语言学概念可以帮助我们分析自然语言的结构和规律,文本预处理可以帮助我们清洗和规范化文本数据,文本表示方法可以帮助我们将文本转换为计算机可处理的数值向量。

学习NLP很难的原因可能有以下几点:NLP涉及多个领域的知识,需要有较强的综合能力和自学能力;NLP是一个快速发展的领域,需要不断更新自己的知识和技能;NLP面临很多挑战和难题,如自然语言的歧义性、复杂性、多样性等。

  • 步骤1:下载意图识别数据集,该数据集是一个多分类任务,目标是根据用户的输入文本判断用户的意图。意图识别数据集的加载方法如下代码。
  • 步骤2:使用Pandas库读取数据集,Pandas是一个用于数据分析和处理的Python库,可以方便地读取、操作和保存各种格式的数据文件。使用Pandas的read_csv函数可以读取csv格式的数据文件,并返回一个DataFrame对象。
  • 步骤3:统计训练集和测试集的类别分布、文本长度等基本信息,以了解数据集的特征和难度。使用DataFrame对象的value_counts函数可以统计每个类别出现的次数和比例,使用apply函数和len函数可以统计每个文本的长度。
  • 步骤4:通过上述步骤,请回答下面问题
    • 数据集的文本长度分布一致吗?
    • 数据集中的文本是长文本还是短文本?根据统计结果,查看每个文本的长度分布情况,如文本长度的中位数。
    • 数据集中总共包含了多少个字符,多少个单词?将单词按照意图类别绘制云图。
# 读取数据集,这里是直接联网读取,也可以通过下载文件,再读取
import pandas as pd

data_dir = 'https://mirror.coggle.club/dataset/coggle-competition/'
train_data = pd.read_csv(data_dir + 'intent-classify/train.csv', sep='\t', header=None)
test_data = pd.read_csv(data_dir + 'intent-classify/test.csv', sep='\t', header=None)

train_data[1].value_counts()

train_data[0].apply(len).describe()
from wordcloud import WordCloud  
import matplotlib.pyplot as plt
import jieba

# 中文分词
content = ''.join(train_data[train_data[1] == 'Music-Play'][0])
words = jieba.lcut(content)

# 读取中文停用词
cn_stopwords = ' '.join(pd.read_csv('https://mirror.coggle.club/stopwords/baidu_stopwords.txt', header=None)[0])
words = [x for x in words if x not in cn_stopwords]

# 中文字体,https://mirror.coggle.club/STHeiti-Light.ttc
# 手动下载中文字体到当前代码目录
wordcloud = WordCloud(background_color = 'white', max_words = 1000, font_path = 'STHeiti-Light.ttc')
wordcloud.generate(' '.join(words))
plt.imshow(wordcloud)
plt.xticks([]); plt.yticks([])

https://cdn.coggle.club/img/Music-Play-WordCloud.png

任务2:正则关键词与文本分类

正则表达式(Regular Expressions,简称regex)是一种用于字符串搜索和操作的强大工具。它使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。正则表达式在计算机科学、编程、数据挖掘和文本处理中有着广泛的应用。

  1. 定义规则:根据分类需求,定义一组正则表达式规则。
  2. 预处理文本:对输入文本进行清洗,如去除标点符号、转换为小写等。
  3. 模式匹配:使用正则表达式在文本中搜索定义的模式。
  4. 分类决策:根据匹配结果,将文本分配到相应的类别。

使用正则表达式进行文本分类时,确定关键词是一个关键步骤,因为它直接影响到分类的准确性和效率。可以从分析中找出每个类别的高频词汇,或考虑类别相关的专业术语或行业特定的词汇。

任务3:TFIDF提取与分类

TFIDF(词频-逆文档频率)是一种常见的文本表示方法,可以用于文本分类任务。TFIDF将文本表示为词项的权重向量,其中每个词项的权重由其在文本中出现的频率和在整个语料库中出现的频率共同决定。TFIDF可以反映出词项在文本中的重要程度,越是常见的词项权重越低,越是稀有的词项权重越高。

  • 步骤1:使用sklearn中的TfidfVectorizer类提取训练集和测试集的特征,
  • 步骤2:使用KNN/LR/SVM等分类器对训练集进行训练,并对验证集和测试集进行预测,评估模型的性能。
  • 步骤3:通过上述步骤,请回答下面问题
    • TFIDF中可以设置哪些参数,如何影响到提取的特征?TfidfVectorizer类中可以设置以下参数:
      • max_df: 用于过滤掉高频词项,在[0.0, 1.0]之间表示比例;
      • min_df: 用于过滤掉低频词项,在[0.0, 1.0]之间表示比例;
      • max_features: 用于限制提取特征的数量,默认为None。
      • ngram_range: 用于指定提取n元语法特征时n值范围,默认为(1, 1),即只提取单个词项。
      • stop_words: 用于指定停用词列表,默认为None。
      • norm: 用于指定归一化方法,默认为’l2’范数。
      • use_idf: 是否使用逆文档频率计算权重,默认为True。
      • smooth_idf: 是否平滑逆文档频率计算,默认为True
    • KNN/LR/SVM的精度对比:根据实验结果,比较三种分类器在验证集和测试集上预测正确率、召回率、F1值等指标,并分析各自优缺点。
data_dir = 'https://mirror.coggle.club/dataset/coggle-competition/'
train_data = pd.read_csv(data_dir + 'intent-classify/train.csv', sep='\t', header=None)
test_data = pd.read_csv(data_dir + 'intent-classify/test.csv', sep='\t', header=None)
cn_stopwords = pd.read_csv('https://mirror.coggle.club/stopwords/baidu_stopwords.txt', header=None)[0].values

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf = TfidfVectorizer(
    tokenizer=jieba.lcut,
    stop_words=list(cn_stopwords)
)
train_tfidf = tfidf.fit_transform(train_data[0])
test_tfidf = tfidf.transform(test_data[0])
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import LinearSVC
from sklearn.metrics import classification_report
from sklearn.model_selection import cross_val_predict

cv_pred = cross_val_predict(
    KNeighborsClassifier(),
    train_tfidf, train_data[1]
)
print(classification_report(train_data[1], cv_pred))

model = LinearSVC()
model.fit(train_tfidf, train_data[1])
pd.DataFrame({
    'ID':range(1, len(test_data) + 1),
    "Target":model.predict(test_tfidf)
}).to_csv('svm.csv', index=None)
# 可以提交

任务4:词向量训练与使用

词向量是一种将单词转化为向量表示的技术,在自然语言处理中被广泛应用。通过将单词映射到一个低维向量空间中,词向量可以在一定程度上捕捉到单词的语义信息和关联关系,进而提高自然语言处理任务的性能。以下是使用词向量进行文本分类的一个简单示例:

  • 步骤1:使用结巴对文本进行分词,结巴是一个基于Python的中文分词工具,并支持自定义字典和停用词。
  • 步骤2:使用gensim训练词向量,也可以考虑加载已有的预训练词向量。gensim是一个基于Python的自然语言处理库,可以方便地训练或加载词向量,并进行相似度计算、最近邻查询等操作。
  • 步骤3:使用词向量对单词进行编码,然后计算句子向量(可以直接求词向量均值)。将每个单词替换为其对应的词向量后,得到一个由多个向量组成的矩阵。为了简化计算和降低维度,可以对矩阵按行求均值,得到一个代表句子含义的句子向量。
  • 步骤4:使用LR、SVM和决策树对句子向量进行训练,验证和预测。LR(逻辑回归)、SVM(支持向量机)和决策树都是常用的机器学习分类算法,可以使用sklearn库中提供的相关函数来实现。
  • 步骤5:通过上述步骤,请回答下面问题
    • 词向量的维度会影响到模型精度吗?一般来说,词向量的维度越高,则表示单词语义信息和关联关系的能力越强;但同时也会增加计算复杂度和过拟合风险。
    • 词向量编码后使用树模型和LR,谁的精度高,为什么?这个问题没有确定性答案,可能取决于数据集特征、参数设置、随机因素等。

任务5:LSTM意图分类

LSTM(Long Short-Term Memory)是一种特殊的循环神经网络,在文本分类任务中表现良好。LSTM可以通过对输入文本进行序列建模来捕捉文本中的长期依赖关系,并对文本进行分类。

  • 步骤1:搭建LSTM模型,具体结构为Embedding层、LSTM层和全连接层;
    • Embedding层:将输入的文本转换为词向量表示,降低维度并保留语义信息;
    • LSTM层:使用长短期记忆单元处理词向量序列,学习文本中的上下文信息,并输出隐藏状态;
    • 全连接层:将LSTM层的最后一个隐藏状态作为特征输入,使用softmax函数输出每个类别的概率。
  • 步骤2:使用任务3中的词向量初始化Embedding层
  • 步骤3:LSTM模型的训练,验证和预测
  • 步骤4:通过上述步骤,请回答下面问题
    • Embedding层的精度与初始化方式相关吗?
    • LSTM模型精度与文本最大长度是否相关?

任务6:BERT意图分类

BERT(Bidirectional Encoder Representations from Transformers)是一种预训练语言模型,它可以生成高质量的文本表示,并被广泛应用于文本分类任务。BERT使用双向Transformer编码器来捕捉文本中的上下文信息,从而获得更好的表示效果。

  • 步骤1:加载BERT模型,对文本进行编码
  • 步骤2:BERT模型的训练,验证和预测
  • 步骤3:通过上述步骤,请回答下面问题
    • BERT模型精度与文本最大长度是否相关?
    • BERT模型分类时最后全连接层的输入是什么含义?

任务7:T5/Prompt意图分类

Prompt分类(Prompt-based Classification)是一种新兴的文本分类技术,它通过将任务特定的提示文本(Prompt Text)与输入文本(Input Text)一起输入到预训练语言模型(Pre-trained Language Model)中来实现文本分类。Prompt分类具有高度灵活性和可扩展性,并已经在多个NLP任务中取得了优异的性能。

Prompt分类的基本思想是将文本分类任务转化为掩码语言模型(Masked Language Modeling,MLM)任务,通过预测掩码位置([MASK])的输出来判断类别。例如,通过文本描述判定天气好坏,类别【好、坏】:常规方法是在BERT模型之后添加一个分类层,哪个输出节点概率最大则划分到哪一类别;而Prompt分类方法是在输入文本前后添加提示文本,并在类别位置添加掩码标记:

  • 输入:[CLS] 文字描述:今天阳光明媚,微风拂面。 天气:[MASK] [SEP]
  • 输出:天气:好

Prompt分类的优势是可以利用预训练语言模型的强大表达能力和泛化能力,无需额外增加参数或进行微调。Prompt分类的挑战是如何设计合适的提示文本来引导模型进行正确的推理和预测。

  • 步骤1:加载BERT模型 或 T5模型
  • 步骤2:将样本加入自定义prompt
  • 步骤3:使用[MASK]分类进行训练和预测
  • 步骤4:通过上述步骤,请回答下面问题
    • Prompt分类比BERT分类相比,在精度上有什么区别?
    • 自定义prompt对模型的精度是否有影响?可以尝试2种不同的prompt。

任务8:BERT高效微调

BERT(Bidirectional Encoder Representations from Transformers)是一种预训练的深度学习模型,用于自然语言处理任务。由于其规模庞大,对BERT等大型模型进行微调通常成本很高。为了解决这个问题,研究者们提出了一种称为参数高效微调(Parameter-Efficient Fine-Tuning,简称PEFT)的方法,它允许通过只微调模型中的一小部分参数来适应各种下游应用,从而显著降低了计算和存储成本。

LoRA(Low-Rank Adaptation)是一种参数高效的微调方法,用于调整大型预训练模型,如BERT。这种方法的核心思想是只对模型中的一小部分参数进行微调,而不是整个模型。这样,它能够以较低的计算成本实现对模型的快速适应,同时保持了模型的原有性能。

LoRA.ipynb · PEFT/sequence-classification at main

from peft import LoraConfig, TaskType
from transformers import BertForSequenceClassification

lora_config = LoraConfig(
    task_type=TaskType.SEQ_CLS, r=1, lora_alpha=1, lora_dropout=0.1
)

model = BertForSequenceClassification.from_pretrained(
    'bert-base-cased', 
    num_labels=2
)

from peft import get_peft_model
model = get_peft_model(model, lora_config)

任务9:大模型N-Shot文本分类

N-Shot文本分类是一种机器学习技术,它允许模型在给定少量(N个)标注样本的情况下学习新的任务。这种技术特别适用于数据稀缺的情况,其中获取大量标注数据是不可行或成本过高的。在自然语言处理(NLP)领域,N-Shot学习可以用于快速适应新的文本分类任务。

提示词是一种将模型引导至特定任务的技术。在NLP中,提示词通常是一个精心设计的文本模板,它能够指导模型理解任务的要求并生成合适的响应。对于大型预训练模型,提示词可以显著减少对大量标注数据的依赖,允许模型在少量或没有标注数据的情况下学习新任务。N-Shot学习的核心是在只有少量标注样本的情况下训练模型。这些样本通常被称为“支持集”(support set),它们用于快速调整模型参数。

https://arxiv.org/pdf/2305.08377

任务10:大模型高效微调

Baichuan2/fine-tune/fine-tune.py at main · baichuan-inc/Baichuan2 · GitHub

Qwen1.5/examples/sft/finetune.sh at main · QwenLM/Qwen1.5 · GitHub

self-llm/LLaMA3/LLaMA3-8B-Instruct Lora.ipynb at master · datawhalechina/self-llm · GitHub

用这个字体,STHeiti-Light.ttc。报错:ValueError: Only supported for TrueType fonts
wordcloud不支持这个字体,这是怎么回事

https://mirror.coggle.club/STHeiti-Light.ttc

下载一下到代码目录,再试试

麻烦问一下,你们提供TOB的服务吗?我们的客服系统目前正缺少一个类似的意图分类模型,如果可以的话请私联我,谢谢

暂时没有,我们主要以知识分享和方案分享为主。

在哪里能看别人的解决方案呢

你好,我有相关经验,可以探讨一下具体细节。

水哥,如何联系到上面的用户,论坛没有私信功能,求帮助 :rose:

这个我也没有他的信息