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

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.rhkb.cn/news/431430.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第18届全国热管会议举办,积鼎科技分享「环路热管相变传热仿真」前沿实践

第18届全国热管会议于9月20日至22日在海滨城市日照举行,该会议由中国工程热物理学会热管专业组主办,山东大学和日照市科学技术协会联合承办,汇聚了全国热管技术领域的专家学者及企业代表。在该会议上,积鼎科技在热管仿真方面的成果…

移动剧院:流动艺术空间的声学革命—轻空间

在当今多元化的文化环境中,移动剧院作为一种新兴的演出形式,正在迅速崛起。它不仅提供了灵活多变的演出场地,更以其卓越的声学性能,为观众带来了沉浸式的视听体验。移动剧院的声学优势,使其成为各种艺术活动的理想选择…

TomCat乱码问题

TomCat控制台乱码问题 乱码问题解决: 响应乱码问题 向客户端响应数据: package Servlet;import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servl…

C++中的IO流

1. C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据,并将值存放在变量中。printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。注意宽度输出和精度输出控制。C语言借助了相应的缓冲…

DELPHI编译软件时带上当前IDE的版本号

如果通过 CompilerVersion 得到的也只是编译器的版本号。 比如:delphi XE12 是 36 ,也仅此而己。 我想得到的是IDE的版本号,比如当前最新版本的DELPHI是:Embarcadero RAD Studio 12 Version 29.0.53571.9782 我想得到 29.0.53…

轰!天文学家刚刚目睹了三年来最大的太空爆炸

天文学家目睹了太空中最大的一次爆炸。 被标记为 AT2021lwx 的这次爆炸事件被观测到比任何已知的超新星都要亮十倍,超新星爆炸发生在大质量恒星死亡之时。而且超新星爆炸只持续几个月,而这次爆炸事件已经持续了至少三年。 AT2021lwx 也比恒星被超大质量…

聊一下cookie,session,token的区别

cookie cookie是存放在客户端的,主要用于会话管理和用户数据保存;cookie通过http报文的请求头部分发送给服务器,服务器根据cookie就可以获取到里面携带的session id(用于获取服务器中对应的session数据),因为http是无状态协议,我们通常就是通过cookie去维护状态的 cookie是在…

LabVIEW提高开发效率技巧----使用状态机架构

状态机架构(State Machine Architecture)是LabVIEW编程中的一种常见且高效的设计模式,特别适合用于处理具有多个操作状态的复杂系统。通过这种架构,程序能够根据不同的输入条件或事件,在多个状态之间切换,从…

守护您的数字世界:IObit Malware Fighter 11 PRO,您的全能电脑卫士

在这个数字化时代,我们的电脑和个人数据面临着前所未有的威胁。病毒、恶意软件、黑客攻击,这些词汇听起来或许遥远,但它们无时无刻不在威胁着我们的网络安全。幸运的是,IObit Malware Fighter 11 PRO,这款屡获殊荣的杀…

【Python】数据可视化之点线图

目录 散点图 气泡图 时序图 关系图 散点图 Scatterplot(散点图)是一种用于展示两个变量之间关系的图表类型。在散点图中,每个观测值(或数据点)都被表示为一个点,其中横轴(X轴)代…

php发送邮箱教程:如何实现邮件发送功能?

php发送邮箱性能优化策略?怎么使用PHPMail发送邮箱? 无论是用户注册验证、密码重置,还是系统通知,邮件发送都是不可或缺的一部分。AokSend将详细介绍如何使用PHP实现邮件发送功能,帮助开发者快速掌握这一技能。 php发…

CSS 实现文本溢出省略号显示,含单行与多行文本溢出

🚀 个人简介:某大型国企资深软件研发工程师,信息系统项目管理师、CSDN优质创作者、阿里云专家博主,华为云云享专家,分享前端后端相关技术与工作常见问题~ 💟 作 者:码喽的自我修养&#x1f9…

【干货来了】PLC多种通讯方式汇总学习~

PLC的通讯功能是其连接设备、控制系统和外部系统的重要组成部分。PLC支持多种通讯方式,本文将讲述PLC常见的通讯方式及其优缺点,别再傻傻分不清楚~ 一.点对点通讯(P2P) 点对点通讯是一种简单的通讯方式,它直接将两个…

【Docker】Docker快速入门

Docker学习笔记 一、Docker概述 为什么会出现Docker? 安卓开发流程:apk(java开发的)发布到应用商店,用户安装apk即可使用。 后端开发流程: jar(java开发的)带上环境发布到Docker仓库,用户从Docker仓库拉取镜像并部署。 总结…

OpenAI o1团队突破性论文:『过程推理』中数学推理能力大幅提升,从正确中学习的新方法

原创 超 近年来,大型语言模型(LLMs)在复杂的多步推理任务中取得了令人瞩目的进展。这些模型能够生成逐步的思维链,解决从小学数学到高等微积分的各种问题。然而,即使是最先进的模型也常常陷入逻辑陷阱,产生看似合理但实际错误的推…

统信服务器操作系统【刻录镜像制作U盘启动盘的工具】

统信服务器操作系统各版本上刻录镜像制作U盘启动盘的工具方案 文章目录 应用场景一、问题现象二、问题分析解决方案应用场景 硬件/整机信息:全平台 CPU架构:全架构 OS版本信息:服务器a版,e版,d版(其中d版遇到的刻录类问题较少) 软件信息:dd工具、Fedora Media Writer工…

【Linux实践】实验三:LINUX系统的文件操作命令

【Linux实践】实验三:LINUX系统的文件操作命令 实验目的实验内容实验步骤及结果1. 切换和查看目录2. 显示目录下的文件3. 创建和删除目录① mkdir② rm③ rmdir 4. 输出和重定向① 输出② 重定向 > 和 >> 5. 查看文件内容① cat② head 6. 权限7. 复制8. 排…

Gnu Radio抓取WiFi信号,流程图中模块功能

模块流程如图所示: GNURadio中抓取WiFi信号的流程图中各个模块的功能: UHD: USRP Source: 使用此模块配置USRP硬件进行信号采集。设置频率、增益、采样率等参数。Complex to Mag^2: 将复数IQ数据转换为幅度的平方。Delay&#xf…

【计网】从零开始掌握序列化 --- 实现网络计算器项目

​​​请各位保持头脑清醒, ​​​读些好书,做点有用的事, ​​​快快乐乐地生活。 ​​​ --- 斯蒂芬金 《肖申克的救赎》--- 从零开始掌握序列化 1 知识回顾2 服务器框架3 客户端框架4 运行测试 1 知识回顾 前面两篇文章学习中基础知识…

微服务学习笔记之Docker

目录 认识Docker 安装Docker 安装yum工具 配置Docker的yum源 更新yum,建立缓存 安装Docker 启动并校验 配置镜像加速 Docker常见命令 命令 演示 给命令起别名 Docker数据卷 认识数据卷 数据卷常见命令 nginx的html目录挂载演示 数据卷挂载本地目录或…