DatawhaleAI夏令营NLP学习笔记1
本期学习
-
文本分类是自然语言处理(NLP)中的一个重要任务,其作用是将输入的文本按照预先定义的类别或标签进行分类。
-
文本分类的思路和步骤:数据收集与预处理;特征提取;建立分类模型;模型训练;模型评估;调优;
打卡任务
使用云环境跑通Baseline
基础:(思路一)人工统计特征
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文件
进阶:(思路二)TFIDF统计特征
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文件
提交结果
总结
通过本期学习,使用云环境运行模型和相关代码,以及部署AI环境到本地配置,能够跑通baseline并得到结果,TF-IDF的准确率相较于人工统计高,它结合了词频(TF)和逆文档频率(IDF),用于对每个词赋予一个权重,从而将文本数据转换为数值形式,能够对文本进行更好的分类,另外,也可以采用的one-hot编码等方式进行分类。