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

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

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

前言:

        一般来说,我们费劲得到如此多的信息,总不能说直接导入系统就完事了吧,真要这样,那就大炮打蚊子了。不妨扩展下思维,比如依据这些数据做一些分析,或者把它转换一下格式,分下类,作为模型训练的数据。正好,依据当下热门的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 = encodings
        self.labels = labels

    def __getitem__(self, idx):
        item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
        item['labels'] = torch.tensor(self.labels[idx])
        return item

    def __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 = encodings

        def __getitem__(self, idx):
            item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
            return item

        def __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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

难绷,一种重命名+符号链接禁用EDR(Crowdstrike)的方法

最近看到的一个项目&#xff1a;https://github.com/rad9800/FileRenameJunctionsEDRDisable #include <windows.h>#include <winioctl.h>#include <stdio.h> typedef struct _REPARSE_DATA_BUFFER{ ULONG ReparseTag; USHORT ReparseDataLength; …

数仓建模(三)建模三步走:需求分析、模型设计与数据加载

本文包含&#xff1a; 数据仓库的背景与重要性数据仓库建模的核心目标本文结构概览&#xff1a;需求分析、模型设计与数据加载 目录 第一部分&#xff1a;需求分析 1.1 需求分析的定义与目标 1.2 需求分析的步骤 1.2.1 业务需求收集 1.2.2 技术需求分析 1.2.3 成果输出…

微信小程序-Docker+Nginx环境配置业务域名验证文件

在实际开发或运维工作中&#xff0c;我们时常需要在 Nginx 部署的服务器上提供一个特定的静态文件&#xff0c;用于域名验证或第三方平台验证。若此时使用 Docker 容器部署了 Nginx&#xff0c;就需要将该验证文件正确地映射&#xff08;挂载&#xff09;到容器中&#xff0c;并…

Python Wi-Fi密码测试工具

Python Wi-Fi测试工具 相关资源文件已经打包成EXE文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Python相关程序案例&#xff0c;秉着开源精神的想法&#xff0c;望大家喜欢&#xff0c;点…

usb通过hdc连接鸿蒙next的常用指令

参考官方 注册报名https://www.hiascend.com/developer/activities/details/44de441ef599450596131c8cb52f7f8c/signup?channelCodeS1&recommended496144 hdc-调试命令-调测调优-系统 - 华为HarmonyOS开发者https://developer.huawei.com/consumer/cn/doc/harmonyos-guid…

前端性能-HTTP缓存

前言 开启 HTTP 缓存是提升前端性能的常见手段之一。通过缓存&#xff0c;浏览器可以临时存储资源&#xff0c;在后续请求中直接使用本地副本&#xff0c;从而有效减少 HTTP 请求次数&#xff0c;显著缩短网页加载时间。以下是 HTTP 缓存的几个关键点&#xff1a; 1、减少重复…

【Unity-Game4Automation PRO 插件】

Game4Automation PRO 插件 是一个用于 Unity 引擎 的工业自动化仿真工具&#xff0c;它提供了对工业自动化领域的仿真和虚拟调试支持&#xff0c;特别是在与工业机器人、生产线、PLC 系统的集成方面。该插件旨在将工业自动化的实时仿真与游戏开发的高质量 3D 可视化能力结合起来…

【Linux】--- 进程的等待与替换

进程的等待与替换 一、进程等待1、进程等待的必要性2、获取子进程status3、进程等待的方法&#xff08;1&#xff09;wait&#xff08;&#xff09;函数&#xff08;2&#xff09;waitpid函数 4、多进程创建以及等待的代码模型5、非阻塞接口 轮询 二、进程替换1、替换原理2、替…

一个超快低延迟.Net网络通信库:支持TCP, SSL, UDP, HTTP,HTTPS, WebSocket多协议

今天给大家推荐一个性能好、低延迟.Net网络通信库&#xff0c;基本支持所有协议。 01 项目简介 NetCoreServer是一个基于.NET Core的开源项目&#xff0c;一个高性能、跨平台的异步套接字服务器与客户端库。该项目支持多种传输协议&#xff0c;包括TCP、SSL、UDP、HTTP、HTTP…

苍穹外卖08——(涉及接收日期格式数据、ApachePOI导出报表、sql获取top10菜品数据)

营业额统计 service层 在需要处理空值、与数据库交互或使用集合时&#xff0c;Integer 、Double是更好的选择。 // 导入string工具类 import org.apache.commons.lang.StringUtils; Service // 标记该类为Spring的服务组件 Slf4j // 引入日志功能 public class Repor…

数据结构9——二叉搜索树

&#x1f947;1.二叉搜索树的概念 二叉搜索树(Binary Search Tree,BST)又称二叉排序树或二叉查找树&#xff0c;其要么是一棵空树&#xff0c;要么具有以下性质&#xff1a; ①&#xff1a;左子树上所有节点的值都小于根节点&#xff1b; ②&#xff1a;右子树上所有节点的值都…

如何使用wireshark 解密TLS-SSL报文

目录 前言 原理 操作 前言 现在网站都是https 或者 很多站点都支持 http2。这些站点为了保证数据的安全都通过TLS/SSL 加密过&#xff0c;用wireshark 并不能很好的去解析报文&#xff0c;我们就需要用wireshark去解密这些报文。我主要讲解下mac 在 chrome 怎么配置的&…

c++ haru生成pdf输出文本实例

haru是一个开源的生成pdf的库&#xff0c;花时间终于编译成功&#xff0c;以下是一个特别简单的写文本的实例&#xff1a; #include "hpdf.h" void CDemoDlg::OnBnClickedOk() { HPDF_Error_Handler error_handler NULL; HPDF_Doc pdf; pdf HPDF_New(…

Redis与MySQL主从复制原理解析

目录 1. 介绍2. Mysql主从复制的工作原理3. Mysql复制的类型3.1 基于语句的复制&#xff08;Statement-based Replication, SBR&#xff09;3.2 基于行的复制&#xff08;Row-based Replication, RBR&#xff09;3.3 混合复制&#xff08;Mixed Replication&#xff09; 4. Red…

一步到位Python Django部署,浅谈Python Django框架

Django是一个使用Python开发的Web应用程序框架&#xff0c;它遵循MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;旨在帮助开发人员更快、更轻松地构建和维护高质量的Web应用程序。Django提供了强大的基础设施和工具&#xff0c;以便于处理复杂的业务逻…

迅为RK3568开发板篇OpenHarmony配置HDF驱动控制LED-新增 topeet子系统-编写 bundle.json文件

bundle.json 文件内容如下所示&#xff1a; 下面是对各个字段的解释&#xff1a; 1. name: "ohos/demos" - 这是组件或项目的名称&#xff0c;这里表示它属于 OHOS&#xff08;OpenHarmony OS&#xff09;生态系统下的一个名为"demos"的组件。 2. descri…

STM32 物联网智能家居 (三) 输入子系统

STM32 物联网智能家居 (三) 输入子系统 下面是物联网智能家居的输入子系统&#xff0c;见下图&#xff0c;在输入子系统中会实现按键输入、网络输入、标准输入Scanf&#xff0c;其中的网络输入放入到网络子系统中进行讲解。 一、输入子系统核心功能 STM32 物联网智能家居输入…

Windows 正确配置android adb调试的方法

下载适用于 Windows 的 SDK Platform-Tools https://developer.android.google.cn/tools/releases/platform-tools?hlzh-cn 设置系统变量&#xff0c;路径为platform-tools文件夹的绝对路径 点击Path添加环境变量 %adb%打开终端输入adb shell 这就成功了&#xff01;

【C#深度学习之路】如何使用C#实现Yolo8/11 Segment 全尺寸模型的训练和推理

【C#深度学习之路】如何使用C#实现Yolo8/11 Segment 全尺寸模型的训练和推理 项目背景项目实现推理过程训练过程 项目展望写在最后项目下载链接 本文为原创文章&#xff0c;若需要转载&#xff0c;请注明出处。 原文地址&#xff1a;https://blog.csdn.net/qq_30270773/article…

线性回归超详解

目录 一、回归问题 vs 分类问题 二、线性回归 1、一句话理解 2、数学推导 2.1 线性函数表示 2.2 损失函数 2.3 梯度下降 2.3.1 什么是梯度 2.3.2 梯度下降目标 2.3.3 过程 2.3.4 迭代公式 3、特征预处理 3.1 为什么要预处理 3.2 数据归一化方法 1&#xff09;最小…