爬虫后的数据处理与使用(使用篇--实现分类预测)

()紧接上文,在完成基本的数据处理后,接下来就是正常的使用了。当然怎么用,确实需要好好思考一下~   

上文:爬虫后的数据处理与使用(处理篇)

前言:

        一般来说,我们费劲得到如此多的信息,总不能说直接导入系统就完事了吧,真要这样,那就大炮打蚊子了。不妨扩展下思维,比如依据这些数据做一些分析,或者把它转换一下格式,分下类,作为模型训练的数据。正好,依据当下热门的AI,我们不妨做个“小模型”,这样放到论文里,那妥妥的创新点!

        但是,由于上一篇文章运行后的结果(聚类的结果显示集中在一种分类,无法实现分类的预期),实在不如意。因此有了以下猜想,既然要做,为什么不试试监督学习呢!。而上篇的尝试就当作初步的数据筛选(就是把距离中心最远的数据去除掉,作为数据清洗)。

        在初筛数据后,我的数据有一部分是从贴吧爬取的,有的是我们从最基本的分类上做起吧~

推荐配置:

        数据量 > 4000条,手工标注量 > 400条

        python 3.11 

        Jupyter      

一、数据的分类划分

1、制定规则,确定分类依据。

按照你的需求来,比如你数据库设计中有许多标签分类,那按照它来就行。

如果不知道自己的需求,可以想一下自己要做啥,进而推导出自己要的数据,还有分类要求

比如我这个,分类划分为:杂谈1、互助2、生活分享3、交流合作4、闲置5,共计5个分类。

2、手工标注,尽量多些

如图,对数据进行手工标注,我这儿是标注了600多条(如果觉得麻烦,可以分点给你的小伙伴……),数据越多预测结果相对也更准确一点。

二、模型选择与比较

1、基于XGBoost的文本分类模型

(1)代码:

直接上代码了,

import matplotlib
import pandas as pd
import re
import nltk
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt
import seaborn as sns
from xgboost import XGBClassifier
# 设置字体为支持中文的字体
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 下载停用词和词形还原器
nltk.download('stopwords')
nltk.download('wordnet')
# 定义数据预处理函数
def preprocess_text(text):# 小写化text = text.lower()# 去除特殊字符和数字text = re.sub(r'[^a-zA-Z\u4e00-\u9fa5]', ' ', text)  # 保留汉字和英文字符# 分词words = text.split()# 去除停用词words = [word for word in words if word not in stopwords.words('chinese')]# 词形还原lemmatizer = WordNetLemmatizer()words = [lemmatizer.lemmatize(word) for word in words]# 返回处理后的文本return ' '.join(words)# 读取数据集
df = pd.read_excel('tieba.xlsx')  # 替换为你的文件名#  '标题' 是要识别的文本列,'分类(杂谈1、互助2、生活分享3、交流合作4、闲置5)' 列是标注的数据列
texts = df['标题'].tolist()
labels = df['分类(杂谈1、互助\t2、生活分享3、交流合作4、闲置5)'].tolist()# 数据预处理
processed_texts = [preprocess_text(text) for text in texts]# 选择手动标注的数据
labeled_texts = [text for text, label in zip(processed_texts, labels) if pd.notna(label)]
labeled_labels = [int(label) - 1 for label in labels if pd.notna(label)]  # 将标签转换为整数并减去 1# 将手动标注的数据划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(labeled_texts, labeled_labels, test_size=0.2, random_state=42, stratify=labeled_labels)# 将未标注的数据分开
unlabeled_texts = [text for text, label in zip(processed_texts, labels) if pd.isna(label)]# 使用SMOTE进行过采样
vectorizer = TfidfVectorizer(max_features=10000, ngram_range=(1, 2))
X_train_vect = vectorizer.fit_transform(X_train)
X_test_vect = vectorizer.transform(X_test)smote = SMOTE(random_state=42)
X_train_balanced, y_train_balanced = smote.fit_resample(X_train_vect, y_train)# 创建一个流水线并进行网格搜索以调整超参数
pipeline = Pipeline([('clf', XGBClassifier(eval_metric='mlogloss', n_jobs=-1))  # 移除 use_label_encoder 参数
])# 定义参数网格
param_grid = {'clf__max_depth': [5, 10, 15],'clf__n_estimators': [50, 100, 150],'clf__learning_rate': [0.01, 0.1, 0.2],
}grid_search = GridSearchCV(pipeline, param_grid, cv=5)
grid_search.fit(X_train_balanced, y_train_balanced)# 获取最佳参数和分数
print("最佳参数:", grid_search.best_params_)
print("最佳分数:", grid_search.best_score_)# 预测测试集的分类
y_pred = grid_search.predict(X_test_vect)# 打印分类报告
print("分类报告:")
print(classification_report(y_test, y_pred))# 绘制混淆矩阵
conf_matrix = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(10, 7))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues',xticklabels=grid_search.best_estimator_.classes_, yticklabels=grid_search.best_estimator_.classes_)
plt.title('混淆矩阵')
plt.xlabel('预测分类')
plt.ylabel('真实分类')
plt.show()# 预测未标注数据的分类
X_unlabeled_vect = vectorizer.transform(unlabeled_texts)
predicted_labels = grid_search.predict(X_unlabeled_vect)# 将预测结果存储到一个 DataFrame 中
predicted_df = pd.DataFrame({'标题': unlabeled_texts,'预测分类': predicted_labels + 1  # 预测结果转换回原始标签(1-5)
})# 将结果保存到 Excel 文件
predicted_df.to_excel('预测结果.xlsx', index=False)print("预测结果已保存到 '预测结果.xlsx' 文件中。")

(2)结果如下:

整体来看,效果不怎么样,看来这种模型效果不佳,我们可以换一个。

(3)解释:

  • Precision(精确率):所有预测为正类的样本中,实际上是正类的比例。(正类就是随机指定的一种分类,比如“1”)

  • Recall(召回率):所有真实为正类的样本中,模型能够正确识别为正类的比例。

  • F1-score:精确率和召回率的调和平均值,综合考虑了精确率和召回率。

  • Support(支持度):每个类别在测试集中出现的样本数。

  • 准确率(Accuracy) = 0.52:模型的总体准确率是 52%。即 52% 的样本被正确分类。

  • 宏平均(Macro Avg):对各类别的精确率、召回率和 F1-score 进行平均(不考虑样本的不平衡):

    • Precision = 0.24
    • Recall = 0.21
    • F1-score = 0.15
    • 说明了这些值较低,说明模型的表现较差,尤其是在少数类(类别 0、3、4)上。
  • 加权平均(Weighted Avg):根据每个类别的样本数加权计算:

    • Precision = 0.44
    • Recall = 0.52
    • F1-score = 0.37
    • 这些值相较于宏平均更高,说明模型对类别 1 和类别 2 的表现稍好。

2、transformer 模型

(1)代码:

import pandas as pd
import re
import nltk
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from transformers import BertTokenizer, BertForSequenceClassification
from transformers import Trainer, TrainingArguments
import torch# 下载停用词
nltk.download('stopwords')# 定义数据预处理函数
def preprocess_text(text):# 小写化text = text.lower()# 去除特殊字符和数字,保留汉字和英文字符text = re.sub(r'[^a-zA-Z\u4e00-\u9fa5]', ' ', text)return text# 读取数据集
df = pd.read_excel('tieba.xlsx')  # 替换为你的文件名# 这些行基本和上文一致
texts = df['标题'].tolist()
labels = df['分类(杂谈1、互助\t2、生活分享3、交流合作4、闲置5)'].tolist()# 数据预处理
processed_texts = [preprocess_text(text) for text in texts]# 将标签转换为整数并减去 1
labeled_labels = [int(label) - 1 for label in labels if pd.notna(label)]
labeled_texts = [text for text, label in zip(processed_texts, labels) if pd.notna(label)]# 确保文本和标签的长度一致
assert len(labeled_texts) == len(labeled_labels), "文本和标签长度不一致"# 将手动标注的数据划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(labeled_texts, labeled_labels, test_size=0.2, random_state=42, stratify=labeled_labels)# 加载BERT分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')# 对文本进行编码
train_encodings = tokenizer(X_train, truncation=True, padding=True, max_length=128)
test_encodings = tokenizer(X_test, truncation=True, padding=True, max_length=128)# 创建数据集类
class TextDataset(torch.utils.data.Dataset):def __init__(self, encodings, labels):self.encodings = encodingsself.labels = labelsdef __getitem__(self, idx):item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}item['labels'] = torch.tensor(self.labels[idx])return itemdef __len__(self):return len(self.labels)# 创建训练集和测试集
train_dataset = TextDataset(train_encodings, y_train)
test_dataset = TextDataset(test_encodings, y_test)# 加载BERT模型
model = BertForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=5)# 设置训练参数
training_args = TrainingArguments(output_dir='./results2', #定义模型存放位置num_train_epochs=4, #设置训练的 epoch 数,即重复学习次数,初始为3,当调整为10时,在第五次后出现了过拟合现象,所以采用:4次# 这里的epoch数,需要验证一下,总之多试几次……per_device_train_batch_size=16,per_device_eval_batch_size=64,warmup_steps=500, #定义学习率预热的步骤数weight_decay=0.01, #权重衰减系数(也称为 L2 正则化),用于防止过拟合logging_dir='./logs',logging_steps=10,eval_strategy="epoch",  
)# 使用Trainer API进行训练
trainer = Trainer(model=model,args=training_args,train_dataset=train_dataset,eval_dataset=test_dataset,
)# 训练模型
trainer.train()# 预测测试集的分类
predictions, labels, _ = trainer.predict(test_dataset)
predicted_labels = predictions.argmax(-1)# 打印分类报告
print("分类报告:")
print(classification_report(y_test, predicted_labels))# 将预测的标签和原始文本保存到 DataFrame 中
output_df = pd.DataFrame({'标题': X_test,'真实标签': y_test,'预测标签': predicted_labels
})# 将结果保存到 Excel 文件
output_df.to_excel('prediction_results.xlsx', index=False)print("预测结果已保存到 'prediction_results.xlsx'")# 对未标注的数据进行预测并保存# 提取未标注的数据
unlabeled_texts = df[df['分类(杂谈1、互助\t2、生活分享3、交流合作4、闲置5)'].isna()]['标题'].tolist()# 打印未标注的数据数量和内容,确保数据被正确提取
print(f"未标注的数据数量: {len(unlabeled_texts)}")
# print(f"未标注的文本数据: {unlabeled_texts}")# 如果有未标注的数据,进行处理
if len(unlabeled_texts) > 0:# 对未标注的文本进行编码unlabeled_encodings = tokenizer(unlabeled_texts, truncation=True, padding=True, max_length=128)# 创建未标注数据集class UnlabeledTextDataset(torch.utils.data.Dataset):def __init__(self, encodings):self.encodings = encodingsdef __getitem__(self, idx):item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}return itemdef __len__(self):return len(self.encodings['input_ids'])# 创建未标注数据集unlabeled_dataset = UnlabeledTextDataset(unlabeled_encodings)# 使用训练好的模型对未标注数据进行预测predictions, _, _ = trainer.predict(unlabeled_dataset)predicted_labels = predictions.argmax(-1)# 将预测的标签和未标注文本保存到 DataFrame 中unlabeled_df = pd.DataFrame({'标题': unlabeled_texts,'预测标签': predicted_labels})# 将未标注数据的预测结果填充到原始 DataFrame 中对应的位置df.loc[df['分类(杂谈1、互助\t2、生活分享3、交流合作4、闲置5)'].isna(), '分类(杂谈1、互助\t2、生活分享3、交流合作4、闲置5)'] = predicted_labels + 1# 将包含预测结果的原始数据保存到 Excel 文件df.to_excel('预测数据.xlsx', index=False)print("未标注数据的预测结果已保存到 '预测数据.xlsx'")
else:print("没有未标注的数据。")

(2)结果如下:

 

结果显示,该模型的总体准确率为 76%,整体差强人意吧。反正够凑合着用了,hhhh

在完成之后,会生成一个文件夹,那个就是模型

(3)预测示例:

以下是结果图,整体还算可以。

好了,以上就是对数据的应用的示例啦,希望可以给到各位启发,欢迎留言讨论哦~

               

项目地址:https://github.com/blhqwjs/spider

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

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

相关文章

RabbitMQ--延迟队列

(一)延迟队列 1.概念 延迟队列是一种特殊的队列,消息被发送后,消费者并不会立刻拿到消息,而是等待一段时间后,消费者才可以从这个队列中拿到消息进行消费 2.应用场景 延迟队列的应用场景很多,…

flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈

flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈 开发背景 可能大家听过过蓝湖可以转ui设计图为vue.js,react native代码,那么请问听说过将figma的设计图转换为flutter源代码吗?本文优雅草央千澈带…

当设置dialog中有el-table时,并设置el-table区域的滚动,看到el-table中多了一条横线

问题:当设置dialog中有el-table时,并设置el-table区域的滚动,看到el-table中多了一条横线; 原因:el-table有一个before的伪元素作为表格的下边框下,初始的时候已设置,在滚动的时候并没有重新设置…

代理模式实现

一、概念:代理模式属于结构型设计模式。客户端不能直接访问一个对象,可以通过代理的第三者来间接访问该对象,代理对象控制着对于原对象的访问,并允许在客户端访问对象的前后进行一些扩展和处理;这种设置模式称为代理模…

windows 搭建flutter环境,开发windows程序

环境安装配置: 下载flutter sdk https://docs.flutter.dev/get-started/install/windows 下载到本地后,随便找个地方解压,然后配置下系统环境变量 编译windows程序本地需要安装vs2019或更新的开发环境 主要就这2步安装后就可以了&#xff0…

Redis系列之底层数据结构字典Dict

Redis系列之底层数据结构字典Dict Dict数据结构 Dict是Redis数据结构中使用最为频繁的复合型数据结构,本质上是一个哈希表 查看redis6.0版本的源码,链接:https://github.com/redis/redis/blob/6.0/src/dict.h 哈希表的结构定义&#xff1…

【Azure 架构师学习笔记】- Azure Function (2) --实操1

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Function 】系列。 接上文【Azure 架构师学习笔记】- Azure Function (1) --环境搭建和背景介绍 前言 上一文介绍了环境搭建,接下来就在本地环境下使用一下。 环境准备 这里我下载了最新的VS studio&…

【NextJS】PostgreSQL 遇上 Prisma ORM

NextJS 数据库 之 遇上Prisma ORM 前言一、环境要求二、概念介绍1、Prisma Schema Language(PSL) 结构描述语言1.1 概念1.2 组成1.2.1 Data Source 数据源1.2.2 Generators 生成器1.2.3 Data Model Definition 数据模型定义字段(数据)类型和约束关系&…

左神算法基础提升--3

文章目录 Manacher 算法经典算法Manacher算法原理 单调栈或单调队列 Manacher 算法 经典算法 在每学习Manacher算法之前我们可能会使用一种比较经典暴力的算法:遍历str字符串,将字符串中的每个字符作为对称点,向两边扩散找到回文字段&#x…

浅谈操作系统与初识Linux

一、Linux操作系统的出现 1.1操作系统的出现以及相关的四个要素 1.2最早出现的操作系统及其创始人 起初,IBM为了让计算机可以以更低技术成本进行使用,以此来售卖计算机; 为计算机搭载上了Unix操作系统,Unix由肯汤普森用汇编语…

ElasticSearch下

DSL查询 叶子查询:在特定字段里查询特定值,属于简单查询,很少单独使用复合查询:以逻辑方式组合多个叶子查询或更改叶子查询的行为方式 在查询后还可以对查询结果做处理: 排序:按照1个或多个字段做排序分页…

java根据模板导出word,并在word中插入echarts相关统计图片以及表格

引入依赖创建word模板创建ftl模板文件保存的ftl可能会出现占位符分割的问题,需要处理将ftl文件中的图片的Base64删除,并使用占位符代替插入表格,并指定表格的位置在图片下方 Echarts转图片根据模板生成word文档DocUtil导出word文档 生成的wor…

链式前向星的写法

【图论02】动画说图的三种保存方式 降低理解门槛 邻接表 链式前向星 邻接矩阵_哔哩哔哩_bilibili 杭电ACM刘老师-算法入门培训-第12讲-拓扑排序及链式前向星_哔哩哔哩_bilibili 图论003链式前向星_哔哩哔哩_bilibili(链式前向星的遍历) head数组的下标…

想品客老师的第一天:值类型使用

前面两章的摘要 ECMAscript(也就是ES)是JavaScript的一个标准,就像c的c11和c99一样,几把的一年出一套标准 freeze()是一个对象方法,表示锁定、固定一个对象不可改变(因为const对于标量不可变,…

贪心算法(题1)区间选点

输出 2 #include <iostream> #include<algorithm>using namespace std;const int N 100010 ;int n; struct Range {int l,r;bool operator <(const Range &W)const{return r<W.r;} }range[N];int main() {scanf("%d",&n);for(int i0;i&l…

解决本地运行MR程序访问权限问题

文章目录 1. 提出问题2. 解决问题2.1 临时解决方案2.2 永久解决方案 3. 小结 1. 提出问题 运行DeduplicateIPsDriver类&#xff0c;抛出如下异常&#xff1a; 该错误信息表明在尝试运行 DeduplicateIPsDriver 类时&#xff0c;遇到了 HDFS&#xff08;Hadoop 分布式文件系统&a…

html全局遮罩,通过websocket来实现实时发布公告

1.index.html代码示例 <div id"websocket" style"display:none;position: absolute;color:red;background-color: black;width: 100%;height: 100%;z-index: 100; opacity: 0.9; padding-top: 30%;padding-left: 30%; padding-border:1px; "onclick&q…

高通8255 Android STR 启动失败要因分析调查

目录 背景&#xff1a; 调查过程&#xff1a; 步骤1&#xff1a; slog2info | grep vmm_service 步骤2&#xff1a; slog2info | grep qvm 总结&#xff1a; 解决方案 背景&#xff1a; 调试高通8255 STR的STR过程中发现Android和QNX进入STR状态后&#xff0c;脱出STR时…

Linux UDP 编程详解

一、引言 在网络编程领域&#xff0c;UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;作为一种轻量级的传输层协议&#xff0c;具有独特的优势和适用场景。与 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff0…

可解释性机器学习

一、引言 随着机器学习&#xff08;ML&#xff09;在各个领域的广泛应用&#xff0c;模型的复杂度不断增加&#xff0c;如深度神经网络等黑盒模型逐渐成为主流。这些模型虽然具有很高的预测性能&#xff0c;但其内部的决策机制往往难以理解&#xff0c;导致模型的透明度和可解释…