【大模型实战篇】一种关于大模型高质量数据的处理方法-无标注数据类别快速识别及重复数据检测(加权向量-卷积神经网络-聚类算法结合)

1. 背景介绍  

        大模型的能力很大程度上依赖于高质量的数据,在之前的一篇文章《高质量数据过滤及一种BoostedBaggingFilter处理方法的介绍》中,我们介绍了大模型的数据处理链路,本文继续关注在高质量数据的模块。

        本文所要介绍的处理方法,其实是很多年之前在构建对话机器人系统中涉及的,当时的场景是需要对不同地区的用户大量问题进行自动化区分,识别出热门问题,并给出类别划分,进而给出不同类别问题的热门问答示例,展现在用户的对话框窗口,对于不同地区的问题都需要做类似处理。做过对话系统的同学应该有一种感受,那就是当用户问答数据够多时,其实问答系统的主要任务就变成了对于历史问题的匹配和检索,因此用户问题往往是相似的。

        之所以该方法同样可以适用大模型数据处理领域,是因为大模型的训练数据往往是从大量的网站或者其他数据源获取的,原始数据可能并没有完整的类别区分,并且可能涉及到重复数据,而人工标注又非常的耗时且昂贵。因此完全可以采用类似的针对热门问题自动识别的方式,对原始数据进行快速自动划分类别,识别重复数据等。

2. 具体算法介绍

        针对热门问题自动识别的方法,我们主要采用cnn+kmeans方式,结合了卷积神经网络(CNN)特征提取和 K均值聚类(K-Means)算法,用于文本数据的聚类识别,这种处理方式速度快、资源要求低,适合在大规模数据上进行处理。这个处理流程整合了词嵌入、卷积神经网络以及聚类算法,能够对文本数据进行有效的特征提取和聚类分析。其中对于加权平均词嵌入向量的处理可以注意下,这一步对于文本语意的表达比较重要。

算法流程及原理

  1. 数据预处理

    • 文本清洗和分词:去除噪声并分词。
    • 分词序列化:使用 Tokenizer 对文本进行编码,将文本转换为词索引的序列。
    • 词嵌入:加载预训练的词向量,并构建词嵌入矩阵,其中每个词都有对应的向量表示。
    • 序列填充:对词索引序列进行填充或截断,使得所有样本具有相同的长度。
  2. 构建词嵌入矩阵

    • 加载预训练的词向量模型。
    • 初始化嵌入矩阵,使用预训练的词向量填充矩阵。
    • 统计未命中词向量的词。
  3. 构建平均词嵌入向量

    • 使用 TF-IDF 对词频进行加权。
    • 归一化 TF-IDF 值,并计算加权平均词嵌入向量。
    • 将平均词嵌入向量二值化,即对每个样本的向量进行处理,保留那些超过中位数的特征。
  4. 构建模型

    • 输入层接受序列化的文本数据。
    • 嵌入层使用预训练的词向量。
    • 卷积层对嵌入后的序列进行卷积操作。
    • 全局最大池化层提取卷积特征。
    • 输出层使用 Sigmoid 激活函数,输出维度等于二值化后的向量维度。
  5. 训练模型

    • 使用二值化的向量作为监督信号训练模型。
    • 保存最佳权重,并从倒数第二层推断出中间表示。
    • 对中间表示进行 L2 归一化,并使用 K-Means 聚类算法进行聚类。

主要步骤

  • 初始化:加载预训练词向量,初始化 tokenizer。
  • 文本预处理:分词、构建词嵌入矩阵、计算平均词嵌入向量并二值化。
  • 构建模型:定义 CNN 模型结构,编译模型。
  • 训练模型:拟合模型,保存最佳权重。
  • 推断:使用训练好的模型从倒数第二层获取中间表示。
  • 聚类:对中间表示进行聚类,并将结果输出。

示例代码:

from utils.data_preprocess import DataTools
import numpy as np
from gensim.models.keyedvectors import KeyedVectors
from keras.callbacks import ModelCheckpoint
from keras.optimizers import Adam
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.layers import Input, Embedding
from keras.layers import Dense, Conv1D, Dropout
from keras.layers import GlobalMaxPooling1D
from keras.models import Model
from sklearn.cluster import KMeans
from sklearn.preprocessing import normalizeclass CNNKMeans(object):def __init__(self):self.data_tools = DataTools()self.EMBEDDING_FILE = 'data/ss_vector300.bin' #加载预训练的词向量数据self.tokenizer = Tokenizer()self.EMBEDDING_DIM = 300def cluster_texts(self, texts, clusters=50, n_iters=10):self.text_preprocess(texts)model = self.get_model()H = self.train_model_and_infer(model, n_iters)#使用倒数第二层的输出作为infer的向量进行聚类km = KMeans(n_clusters=clusters, n_jobs=2)V = normalize(H, norm='l2')km.fit(V)pred_y = km.labels_return pred_y# 文本预处理&构建格式化输入输出数据def text_preprocess(self, texts):'''(1)分词并向量化'''texts = [" ".join(self.data_tools.process_text(text)) for text in texts]self.tokenizer.fit_on_texts(texts)#texts_to_sequences可获得 [词的index列表]sequences_full = self.tokenizer.texts_to_sequences(texts)word_index = self.tokenizer.word_indexprint('Found %s unique tokens.' % len(word_index))MAX_NB_WORDS = len(word_index)seq_lens = [len(s) for s in sequences_full]print("Average length: %d" % np.mean(seq_lens))print("Max length: %d" % max(seq_lens))self.MAX_SEQUENCE_LENGTH = max(seq_lens)self.X = pad_sequences(sequences_full, maxlen=self.MAX_SEQUENCE_LENGTH)'''(2)构建词嵌入矩阵'''word2vec = KeyedVectors.load_word2vec_format(self.EMBEDDING_FILE, binary=True)self.nb_words = min(MAX_NB_WORDS, len(word_index)) + 1self.embedding_matrix = np.zeros((self.nb_words, self.EMBEDDING_DIM))for word, i in word_index.items():if word in word2vec.vocab:self.embedding_matrix[i] = word2vec.word_vec(word)else:print(word)print('Null word embeddings: %d' % np.sum(np.sum(self.embedding_matrix, axis=1) == 0))'''(3)通过 Average embeddings (AE)构建目标映射向量, binary Y'''Y = {}#sequences_to_matrix 获得每一句话在全量词列表中对应出现词的tf-idf向量,如[[0,0,0, 0.3, 0, 1, 0, 0.5],[...]]tfidf = self.tokenizer.sequences_to_matrix(sequences_full, mode='tfidf')denom = 1 + np.sum(tfidf, axis=1)[:, None] #按行求和#对每一行进行归一化normed_tfidf = tfidf / denom#假如normed_tfidf.shape 为N X 1000, embedding_matrix shape  为 1000 X 300, 那么average_embeddings 的shape为 N X 300, 这一步可以理解为使用tf-idf的词重要性对每一句中的词向量做了加权求和,得到每一句文本的新的表征向量,之所以这么做,是考虑结合全局词重要性信息+局部的词语义信息。average_embeddings = np.dot(normed_tfidf, self.embedding_matrix)Y["ae"] = average_embeddingsprint("Shape of average embedding: ", Y['ae'].shape)reduction_name = "ae"self.B = self.binarize(Y[reduction_name])self.TARGET_DIM = self.B.shape[1]# 构建模型计算图def get_model(self):embedding_matrix_copy = self.embedding_matrix.copy()trainable_embedding = False# Embedding layerpretrained_embedding_layer = Embedding(input_dim=self.nb_words,output_dim=self.EMBEDDING_DIM,weights=[self.embedding_matrix],input_length=self.MAX_SEQUENCE_LENGTH,)# Inputsequence_input = Input(shape=(self.MAX_SEQUENCE_LENGTH,), dtype='int32')embedded_sequences = pretrained_embedding_layer(sequence_input)# 1st Layerx = Conv1D(100, 5, activation='tanh', padding='same')(embedded_sequences)x = GlobalMaxPooling1D()(x)# Outputx = Dropout(0.5)(x)predictions = Dense(self.TARGET_DIM, activation='sigmoid')(x)model = Model(sequence_input, predictions)model.layers[1].trainable = trainable_embeddingadam = Adam(lr=1e-3, beta_1=0.9, beta_2=0.999, epsilon=1e-08)# Loss and Optimizermodel.compile(loss='binary_crossentropy',optimizer=adam,metrics=['mae'])# Fine-tune embeddings or notmodel.summary()return model# 原始数据表征学习def train_model_and_infer(self, model, nb_epoch):checkpoint = ModelCheckpoint('models/weights.{epoch:03d}-{val_acc:.4f}.hdf5', monitor='val_acc', verbose=1,save_best_only=True, mode='auto')model.fit(self.X, self.B, validation_split=0.2,epochs=nb_epoch, batch_size=100, verbose=1, shuffle=True)input = model.layers[0].inputoutput = model.layers[-2].outputmodel_penultimate = Model(input, output)# inference of penultimate layerH = model_penultimate.predict(self.X)print("Sample shape: {}".format(H.shape))return H# 二值化向量#只保留向量中超过中位数的特征值,置为1,其他置为0。也就是仅保留最重要的信息。def binarize(self, target):median = np.median(target, axis=1)[:, None]binary = np.zeros(shape=np.shape(target))binary[target > median] = 1return binaryif __name__ == "__main__":query_path = "data/query.txt"citywise=TrueK = 20nb_epoch = 50city = "北京"dir = "/cluster_result/"+city+"/cnnkmeans/"CKM = CNNKMeans()city_query_tokens = CKM.data_tools.data_taxonomy(query_path)if city in city_query_tokens:texts = city_query_tokens[city]clusters = CKM.cluster_texts(texts, K, nb_epoch)CKM.data_tools.cluster2csv(dir, clusters, texts, K, "CKM")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/146905.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vscode 配置django

创建运行环境 使用pip安装Django:pip install django。 创建一个新的Django项目:django-admin startproject myproject。 打开VSCode,并在项目文件夹中打开终端。 在VSCode中安装Python扩展(如果尚未安装)。 在项…

滑动窗口经典题目

目录 滑动窗口 什么是滑动窗口? 什么时候用滑动窗口? 怎么用滑动窗口? 209. 长度最小的子数组(滑动窗口的引入) 3. 无重复字符的最长子串 1004. 最大连续1的个数 III 1658. 将 x 减到 0 的最小操作数 904. 水…

Fyne ( go跨平台GUI )中文文档-容器和布局 (四)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章: Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…

【重学 MySQL】三十七、聚合函数

【重学 MySQL】三十七、聚合函数 基本概念5大常用的聚合函数COUNT()SUM()AVG()MAX()MIN() 使用场景注意事项示例查询 聚合函数(Aggregate Functions)在数据库查询中扮演着至关重要的角色,特别是在处理大量数据时。它们能够对一组值执行计算&a…

37. Vector3与模型位置、缩放属性

本文章给通过组对象Group (opens new window)给大家讲解一下threejs层级模型或树结构的概念。 Group层级模型(树结构)案例 下面代码创建了两个网格模型mesh1、mesh2,通过THREE.Group类创建一个组对象group,然后通过add方法把网格模型mesh1、mesh2作为设置为组对象g…

Vuex的使用看这一篇就够了

Vuex概述 Vuex 是一个专为 Vue.js 应用程序开发的状态管理库。它采用集中式存储管理应用的所有组件的状态,并以一种可预测的方式来保证状态以一种可预测的方式发生变化。 state状态 把公用的数据放到store里的state就行了,上面是vue2的代码,下…

[大语言模型] LINFUSION:1个GPU,1分钟,16K图像

1. 文章 2409.02097 (arxiv.org)https://arxiv.org/pdf/2409.02097 LINFUSION: 1 GPU, 1 MINUTE, 16K IMAGE 摘要 本文介绍了一种新型的扩散模型LINFUSION,它能够在保持高分辨率图像生成性能的同时显著降低时间和内存复杂度。该模型采用了基于Transformer的UNet进…

【前端】ES6:Class语法和Class继承

文章目录 1 Class语法1.1 类的写法1.2 getter与setter1.3 静态属性和静态方法 2 Class继承 1 Class语法 1.1 类的写法 class Person {constructor(name,age){this.name name;this.age age;}say(){console.log(this.name,this.age)} } let obj new Person("kerwin&quo…

python--基础语法(2)

1.顺序语句 默认情况下,Python的代码执行顺序是按照从上到下的顺序,依次执行的。 2.条件语句 条件语句能够表达“如果 ...否则 ...”这样的语义这构成了计算机中基础的逻辑判定条件语, 也叫做 分支语句。表示了接下来的逻辑可能有几种走向…

SysML图例-10cm最小航天器AC-10

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> SysML图中词汇 AC10 AeroCube-10,大小仅为10 10 15 cm的卫星,更多信息参见下文: AeroCube-10成为迄今为止完成在轨接近操作的最小航天…

yolov8模型在手部关键点检测识别中的应用【代码+数据集+python环境+GUI系统】

yolov8模型在手部关键点检测识别中的应用【代码数据集python环境GUI系统】 背景意义 在手势识别、虚拟现实(VR)、增强现实(AR)等领域,手部关键点检测为用户提供了更加自然、直观的交互方式。通过检测手部关键点&#…

移动登录页:让用户开启一段美好的旅程吧。

Hi,大家好,我是大千UI工场,移动登录页千千万,这里最好看,本期分享一批移动端的登录页面,供大家欣赏。 本次分享的是毛玻璃/3D风格的登录页。

Linux文件IO(七)-复制文件描述符

在 Linux 系统中,open 返回得到的文件描述符 fd 可以进行复制,复制成功之后可以得到一个新的文件描述符,使用新的文件描述符和旧的文件描述符都可以对文件进行 IO 操作,复制得到的文件描述符和旧的文件描述符拥有相同的权限&#…

【文化课学习笔记】【化学】选必三:合成高分子生物大分子

【化学】选必三:合成高分子&生物大分子 如果你是从 B 站一化儿笔记区来的,请先阅读我在第一篇有机化学笔记中的「读前须知」(点开头的黑色小三角展开):链接 加聚反应 基本概念 聚合反应 由小分子化合物合成高分子化合物的反应叫聚合反应。…

学习 git 命令行的简单操作, 能够将代码上传到 Gitee 上

首先登录自己的gitee并创建好仓库 将仓库与Linux终端做链接 比如说我这里已经创建好了一个我的Linux学习仓库 点开克隆/下载: 在你的终端中粘贴上图中1中的指令 此时他会让你输入你的用户名和密码,用户名就是上图中3中Username for ....中后面你的一个…

秒变 Vim 高手:必学的编辑技巧与隐藏功能大揭秘

文章目录 前言一、vi与vim二、Vim的三种模式1. 普通模式2. 插入模式3. 命令模式 三、Vim中的查找与替换1. 查找2. 替换 四、给Vim设置行号1. 临时显示行号2. 永久显示行号 总结 前言 在Linux系统中,文本编辑器是开发者和系统管理员日常工作中的重要工具之一。其中&…

手机号归属地查询-运营商归属地查询-手机号归属地信息-运营商手机号归属地查询接口-手机号归属地

手机号归属地查询接口是一种网络服务接口,它允许开发者通过编程方式查询手机号码的注册地信息。这种接口通常由第三方服务提供商提供,并可通过HTTP请求进行调用。以下是一些关于手机号归属地查询接口的相关信息: 1. 接口功能 归属地查询&am…

HTB-GreenHorn 靶机笔记

GreenHorn 靶机笔记 概述 GreenHorn 是 HTB 上的一个 linux easy 难度的靶机,主要是通过信息搜集和代码审计找到对我们有用的信息。其中还包含了对pdf文件的修复技术 靶机地址:https://app.hackthebox.com/machines/GreenHorn 一丶 nmap 扫描 1&…

https加密原理

以为http的数据都是以明文传送,会有很大的安全问题,所以出现的https协议。https就是在http协议的基础上增加了一个安全层,可以对数据进行加密和解密(例如SSL、TLS等)。 https加密解密的原理:证书非对称加密对称加密 在讲解原理前…

用友网络交付总监刘伟伟受邀为第四届中国项目经理大会演讲嘉宾

全国项目经理专业人士年度盛会 用友网络科技股份有限公司区域交付总监刘伟伟先生受邀为PMO评论主办的全国项目经理专业人士年度盛会——2024第四届中国项目经理大会演讲嘉宾,演讲议题为“如何有效提升项目经理领导力”。大会将于10月26-27日在北京举办,主…