DataWhale NLP第二期 第一次打卡

发布时间 2023-08-06 22:48:48作者: VanHope

理解赛题,跑通竞赛实践全流程
跑通实践基线Baseline,获得自己的成绩
提交任务一打卡,查看个人成绩排行榜

赛题理解

赛题链接
本赛题要求构建一个文本分类器,来区分真实对话和由AI产生的对话,训练的数据包括一系列真实对话和ChatGPT生成的对话样本,参赛选手需要设计并训练一个模型,使其能够准确地将这两种类型的对话进行分类。使用准确率作为评价指标。

baseline代码理解

本赛题是一个文本分类任务
主要分为几个步骤

  1. 数据收集与预处理: 首先,需要收集用于文本分类的数据集。数据集应包含已标注好的文本样本,每个样本都对应一个预定义的类别或标签。在预处理阶段,对文本数据进行清洗、分词、去除停用词和特殊字符等操作,以便为后续的特征提取和模型训练做准备。

  2. 特征提取: 特征提取是将文本数据转换为计算机可处理的数值表示的过程。常用的特征提取方法包括词袋模型(Bag of Words)、TF-IDF(词频-逆文档频率)、Word2Vec、BERT(Bidirectional Encoder Representations from Transformers)等。这些方法能够将文本数据转换为向量形式,保留了文本的语义和语法信息。

  3. 建立分类模型: 在特征提取之后,我们需要选择一个适合的分类模型来训练。常见的分类模型包括朴素贝叶斯(Naive Bayes)、支持向量机(Support Vector Machine, SVM)、逻辑回归(Logistic Regression)、决策树(Decision Tree)、随机森林(Random Forest)和深度学习模型如卷积神经网络(Convolutional Neural Networks, CNN)和循环神经网络(Recurrent Neural Networks, RNN)等。

  4. 模型训练: 将预处理后的特征数据输入选择的分类模型,并对模型进行训练。在训练过程中,模型根据已标注的数据样本进行学习和优化,调整模型的参数以最小化分类错误。

  5. 模型评估: 使用测试集来评估训练好的模型的性能。常见的评估指标包括准确率、精确率、召回率、F1 分数等。

  6. 调优优化: 根据评估结果,可以对模型进行调优优化,以提高模型的性能。调优方法包括调整模型参数、优化特征提取过程、尝试不同的分类模型等。

数据样例

name label content
1 0 [4509 3181 1253 2278 290 3562 2051 599 3125 4790 1504 5219 4390 4544 ... ]

两个baseline的思路

https://aistudio.baidu.com/bj-cpu-01/user/680935/6614735/lab/tree/main.ipynb

思路一:就是人工选取一些特征,然后使用逻辑回归模型进行训练和预测
样例代码

import glob # 导入glob模块,用于查找符合特定规则的文件路径名
import numpy as np # 导入NumPy库,用于数值计算
import pandas as pd # 导入Pandas库,用于数据分析和操作
from sklearn.linear_model import LogisticRegression # 导入逻辑回归模型
# LogisticRegression原理: https://juejin.cn/post/7192114678812639293

# 读取训练和测试数据
train_data = pd.read_csv('./ChatGPT生成文本检测器公开数据-更新/train.csv') # 读取训练数据
test_data = pd.read_csv('./ChatGPT生成文本检测器公开数据-更新/test.csv') # 读取测试数据

# 移除内容列中的第一个和最后一个字符
train_data['content'] = train_data['content'].apply(lambda x: x[1:-1]) # 移除训练数据中内容列的每个字符串的第一个和最后一个字符
test_data['content'] = test_data['content'].apply(lambda x: x[1:-1]) # 移除测试数据中内容列的每个字符串的第一个和最后一个字符

def simple_feature(s):
    if len(s) == 0:
        s = '123 123' # 如果字符串为空,则设为'123 123'
    
    w = s.split() # 这行代码将字符串s按照空格分割,得到一个单词列表w。
    
    # 统计字符出现次数
    w_count = np.bincount(w)

    # 这行代码过滤掉w_count中的0,即过滤掉没有出现过的单词。
    w_count = w_count[w_count != 0]

    return np.array([
        len(s), # 原始字符长度
        len(w), # 字符个数
        len(set(w)), # 不重复字符个数
        len(w) - len(set(w)), # 字符个数 - 不重复字符个数
        len(set(w)) / (len(w) + 1), # 不重复字符个数占比
        np.max(w_count), # 字符的频率的最大值
        np.min(w_count), # 字符的频率的最小值
        np.mean(w_count), # 字符的频率的平均值
        np.std(w_count), # 字符的频率的标准差
        np.ptp(w_count), # 字符的频率的极差
    ])

# 对训练和测试数据的内容列应用上述特征提取函数
train_feature = train_data['content'].iloc[:].apply(simple_feature) # 对训练数据的内容列应用特征提取函数
test_feature = test_data['content'].iloc[:].apply(simple_feature) # 对测试数据的内容列应用特征提取函数

# 将特征堆叠成NumPy数组(其实形状没有改变)
train_feature = np.vstack(train_feature.values) # 将训练数据的特征堆叠成NumPy数组
test_feature = np.vstack(test_feature.values) # 将测试数据的特征堆叠成NumPy数组
m = LogisticRegression() # 初始化逻辑回归模型
m.fit(train_feature, train_data['label']) # 使用训练数据拟合模型
test_data['label'] = m.predict(test_feature) # 对测试数据进行预测
test_data[['name', 'label']].to_csv('simple.csv', index=None) # 将预测结果保存到CSV文件

思路二:采用TD-IDF统计特征,然后使用逻辑回归模型进行训练和预测
下面的代码选取了三种不同的tf-idf构造,分别是

  1. 初始化TF-IDF向量化器,设置单词的最小长度为1,最大特征数量为2000
  2. 初始化TF-IDF向量化器,设置单词的最小长度为1,最大特征数量为5000
  3. 初始化TF-IDF向量化器,设置单词的最小长度为1,最大特征数量为5000,n-gram范围为1到2

最后的结果是使用第三种的结果
样例代码

# 思路二完整代码如下:

import glob # 导入glob模块,用于查找符合特定规则的文件路径名
import numpy as np # 导入NumPy库,用于数值计算
import pandas as pd # 导入Pandas库,用于数据分析和操作
from sklearn.linear_model import LogisticRegression # 导入逻辑回归模型
from sklearn.feature_extraction.text import TfidfVectorizer # 导入TF-IDF向量化器,用于将文本数据转换为数值特征
from sklearn.model_selection import cross_val_predict # 导入交叉验证预测函数
from sklearn.metrics import classification_report # 导入分类报告函数,用于评估模型性能

# 读取训练和测试数据
train_data = pd.read_csv('./ChatGPT生成文本检测器公开数据-更新/train.csv') # 读取训练数据
test_data = pd.read_csv('./ChatGPT生成文本检测器公开数据-更新/test.csv') # 读取测试数据

# 移除内容列中的第一个和最后一个字符
train_data['content'] = train_data['content'].apply(lambda x: x[1:-1]) # 移除训练数据中内容列的每个字符串的第一个和最后一个字符
test_data['content'] = test_data['content'].apply(lambda x: x[1:-1]) # 移除测试数据中内容列的每个字符串的第一个和最后一个字符

# 使用第1种TF-IDF参数进行特征提取
tfidf = TfidfVectorizer(token_pattern=r'\w{1}', max_features=2000) # 初始化TF-IDF向量化器,设置单词的最小长度为1,最大特征数量为2000
train_tfidf = tfidf.fit_transform(train_data['content']) # 将训练数据的内容列转换为TF-IDF特征
test_tfidf = tfidf.transform(test_data['content']) # 将测试数据的内容列转换为TF-IDF特征

# 使用交叉验证进行预测,并打印分类报告
print(classification_report(
    cross_val_predict(
        LogisticRegression(), # 使用逻辑回归模型
        train_tfidf, # 训练数据的特征
        train_data['label'], # 训练数据的标签
    ),
    train_data['label'], # 真实的训练数据标签
    digits=4 # 设置打印的小数位数为4
))

# 使用第2种TF-IDF参数进行特征提取
tfidf = TfidfVectorizer(token_pattern=r'\w{1}', max_features=5000) # 初始化TF-IDF向量化器,设置单词的最小长度为1,最大特征数量为5000
train_tfidf = tfidf.fit_transform(train_data['content']) # 将训练数据的内容列转换为TF-IDF特征
test_tfidf = tfidf.transform(test_data['content']) # 将测试数据的内容列转换为TF-IDF特征

# 使用交叉验证进行预测,并打印分类报告
print(classification_report(
    cross_val_predict(
        LogisticRegression(), # 使用逻辑回归模型
        train_tfidf, # 训练数据的特征
        train_data['label'], # 训练数据的标签
    ),
    train_data['label'], # 真实的训练数据标签
    digits=4 # 设置打印的小数位数为4
))

# 使用第3种TF-IDF参数进行特征提取
tfidf = TfidfVectorizer(token_pattern=r'\w{1}', max_features=5000, ngram_range=(1,2)) # 初始化TF-IDF向量化器,设置单词的最小长度为1,最大特征数量为5000,n-gram范围为1到2
train_tfidf = tfidf.fit_transform(train_data['content']) # 将训练数据的内容列转换为TF-IDF特征
test_tfidf = tfidf.transform(test_data['content']) # 将测试数据的内容列转换为TF-IDF特征

# 使用交叉验证进行预测,并打印分类报告
print(classification_report(
    cross_val_predict(
        LogisticRegression(), # 使用逻辑回归模型
        train_tfidf, # 训练数据的特征
        train_data['label'], # 训练数据的标签
    ),
    train_data['label'], # 真实的训练数据标签
    digits=4 # 设置打印的小数位数为4
))

# 使用第3种TF-IDF参数训练逻辑回归模型,并进行预测
m = LogisticRegression() # 初始化逻辑回归模型
m.fit(
    train_tfidf, # 训练数据的特征
    train_data['label'] # 训练数据的标签
)
test_data['label'] = m.predict(test_tfidf) # 对测试数据进行预测

# 将预测结果保存到CSV文件
test_data[['name', 'label']].to_csv('tfidf.csv', index=None) # 将测试数据的名称和预测标签保存到CSV文件


结果提交