昨天学习了Python 数据分析相关的库(pandas和sklearn),文本特征提取的方法(基于TF-IDF提取和基于BOW提取,以及停用词的用法),划分数据集的方法,以及机器学习的模型。
1. 学习内容
AI夏令营第三期–基于论文摘要的文本分类与关键词抽取挑战赛教程
1.1 数据探索
数据探索性分析,是通过了解数据集,了解变量间的相互关系以及变量与预测值之间的关系,对已有数据在尽量少的先验假设下通过作图、制表、方程拟合、计算特征量等手段探索数据的结构和规律的一种数据分析方法,从而帮助我们后期更好地进行特征工程和建立模型,是机器学习中十分重要的一步。
本次实践中我们使用 pandas 来读取数据以及数据探索。
✅ 使用pandas读取数据
我们利用 pd.read_csv() 方法对赛题数据进行读取,pd.read_cs() 参数为需要读取的数据地址,读取后返回一个DataFrame 数据:
import pandas as pd train = pd.read_csv('./基于论文摘要的文本分类与关键词抽取挑战赛公开数据/train.csv') train['title'] = train['title'].fillna('') train['abstract'] = train['abstract'].fillna('') test = pd.read_csv('./基于论文摘要的文本分类与关键词抽取挑战赛公开数据/testB.csv') test['title'] = test['title'].fillna('') test['abstract'] = test['abstract'].fillna('')
✅ 查看数据特征
通过pandas提供的一些方法,我们可以在快速查看数据的一些特征:
通过 DataFrame.apply(len).describe() 方法查看数据长度
print(train['text'].apply(len).describe())
观察输出发现数据长度平均值在1620左右。
通过 DataFrame.value_counts() 方法查看数据数量
print(train["label"].value_counts())
观察输出发现 01 标签分布的比较均匀,也就是说我们不必担心数据分布不均而发生过拟合,保证模型的泛化能力。
✅ 数据清洗
数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。分析完数据后,特征工程前,必不可少的步骤是对数据清洗。
数据清洗的作用是利用有关技术如数理统计、数据挖掘或预定义的清理规则将脏数据转化为满足数据质量要求的数据。主要包括缺失值处理、异常值处理、数据分桶、特征归一化/标准化等流程。
同时由于表格中存在较多列,我们将这些列的重要内容组合在一起生成一个新的列方便训练。
# 提取文本特征,生成训练集与测试集 train['text'] = train['title'].fillna('') + ' ' + train['author'].fillna('') + ' ' + train['abstract'].fillna('')+ ' ' + train['Keywords'].fillna('') test['text'] = test['title'].fillna('') + ' ' + test['author'].fillna('') + ' ' + test['abstract'].fillna('')
fillna 函数: 补充缺失值
pandas中 fillna() 方法,能够使用指定的方法填充 NA/NaN 值。如果数据集中某行缺少 title author abstract 中的内容,我们需要利用 fillna() 来保证不会出现报错。
✅ 特征工程
特征工程指的是把原始数据转变为模型训练数据的过程,目的是获取更好的训练数据特征。特征工程能使得模型的性能得到提升,有时甚至在简单的模型上也能取得不错的效果。
使用BOW将文本转换为向量表示:
#特征工程 vector = CountVectorizer().fit(train['text']) train_vector = vector.transform(train['text']) test_vector = vector.transform(test['text'])
✅ 模型训练与验证
模型的建立和调参决定了最终的结果,模型的选择决定结果的上限, 如何更好的去达到模型上限取决于模型的调参。
对于逻辑回归模型:
# 模型训练 model = LogisticRegression() # 开始训练,这里可以考虑修改默认的batch_size与epoch来取得更好的效果 model.fit(train_vector, train['label'])
结果输出:提交结果需要符合提交样例结果
# 利用模型对测试集label标签进行预测 test['label'] = model.predict(test_vector) test['Keywords'] = test['title'].fillna('') # 生成任务一推测结果 test[['uuid', 'Keywords', 'label']].to_csv('submit_task1.csv', index=None)
在当前目录下会生成 submit_task1.csv
2. 实践项目
任务平台
本次夏令营的代码运行平台是百度的 AI Studio,运行结果提交至讯飞开放平台进行验证评分。
题目要求
机器通过对论文摘要等信息的理解,判断该论文是否属于医学领域的文献。
任务示例
输入:
论文信息,格式如下:
Inflammatory Breast Cancer: What to Know About This Unique, Aggressive Breast Cancer.,
[Arjun Menta, Tamer M Fouad, Anthony Lucci, Huong Le-Petross, Michael C Stauder, Wendy A Woodward, Naoto T Ueno, Bora Lim],
Inflammatory breast cancer (IBC) is a rare form of breast cancer that accounts for only 2% to 4% of all breast cancer cases. Despite its low incidence, IBC contributes to 7% to 10% of breast cancer caused mortality. Despite ongoing international efforts to formulate better diagnosis, treatment, and research, the survival of patients with IBC has not been significantly improved, and there are no therapeutic agents that specifically target IBC to date. The authors present a comprehensive overview that aims to assess the present and new management strategies of IBC.,
Breast changes; Clinical trials; Inflammatory breast cancer; Trimodality care.
输出:
是(1)
赛题数据集
训练集与测试集数据为CSV格式文件,各字段分别是标题、作者、摘要、关键词。
评价指标
本次竞赛的评价标准采用 F1_score,分数越高,效果越好。
模型评估的指标可以按照不同的任务进行分类,主要包括:
分类任务评估指标: 准确率(Accuracy)、精确率(Precision)、召回率(Recall)、PR 曲线、F1 值、ROC
曲线、AUC、对数损失
回归任务评估指标:平均绝对误差(MAE)、均方误差(MSE)、均方根误差(RMSE)、归一化均方根误差(NRMSE)、决定系数(R2)
聚类任务评估指标:纯度、NMI、兰德系数、调整兰德系数
目标检测任务评估指标:IOU
3. 实践代码
baseline
# 导入pandas用于读取表格数据 import pandas as pd # 导入BOW(词袋模型),可以选择将CountVectorizer替换为TfidfVectorizer(TF-IDF(词频-逆文档频率)),注意上下文要同时修改,亲测后者效果更佳 from sklearn.feature_extraction.text import CountVectorizer # 导入LogisticRegression回归模型 from sklearn.linear_model import LogisticRegression # 过滤警告消息 from warnings import simplefilter from sklearn.exceptions import ConvergenceWarning simplefilter("ignore", category=ConvergenceWarning) # 读取数据集 train = pd.read_csv('./基于论文摘要的文本分类与关键词抽取挑战赛公开数据/train.csv') train['title'] = train['title'].fillna('') train['abstract'] = train['abstract'].fillna('') test = pd.read_csv('./基于论文摘要的文本分类与关键词抽取挑战赛公开数据/testB.csv') test['title'] = test['title'].fillna('') test['abstract'] = test['abstract'].fillna('') # 提取文本特征,生成训练集与测试集 train['text'] = train['title'].fillna('') + ' ' + train['author'].fillna('') + ' ' + train['abstract'].fillna('')+ ' ' + train['Keywords'].fillna('') test['text'] = test['title'].fillna('') + ' ' + test['author'].fillna('') + ' ' + test['abstract'].fillna('') vector = CountVectorizer().fit(train['text']) train_vector = vector.transform(train['text']) test_vector = vector.transform(test['text']) # 引入模型 model = LogisticRegression() # 开始训练,这里可以考虑修改默认的batch_size与epoch来取得更好的效果 model.fit(train_vector, train['label']) # 利用模型对测试集label标签进行预测 test['label'] = model.predict(test_vector) test['Keywords'] = test['title'].fillna('') # 生成任务一推测结果 test[['uuid', 'Keywords', 'label']].to_csv('submit_task1.csv', index=None)
我的代码
我在跑通 baseline 的基础上,尝试用 SVM、 AdaBoost 等方法。
SVM:
# 导入pandas用于读取表格数据 import pandas as pd # 导入BOW(词袋模型),可以选择将CountVectorizer替换为TfidfVectorizer(TF-IDF(词频-逆文档频率)),注意上下文要同时修改,亲测后者效果更佳 from sklearn.feature_extraction.text import CountVectorizer # 过滤警告消息 from warnings import simplefilter from sklearn.exceptions import ConvergenceWarning simplefilter("ignore", category=ConvergenceWarning) # 读取数据集 train = pd.read_csv('./data/data231041/train.csv') train['title'] = train['title'].fillna('') train['abstract'] = train['abstract'].fillna('') test = pd.read_csv('./data/data231041/testB.csv') test['title'] = test['title'].fillna('') test['abstract'] = test['abstract'].fillna('') # 读取数据集 train = pd.read_csv('./data/data231041/train.csv') train['title'] = train['title'].fillna('') train['abstract'] = train['abstract'].fillna('') test = pd.read_csv('./data/data231041/testB.csv') test['title'] = test['title'].fillna('') test['abstract'] = test['abstract'].fillna('') # 提取文本特征,生成训练集与测试集 train['text'] = train['title'].fillna('') + ' ' + train['author'].fillna('') + ' ' + train['abstract'].fillna('')+ ' ' + train['Keywords'].fillna('') test['text'] = test['title'].fillna('') + ' ' + test['author'].fillna('') + ' ' + test['abstract'].fillna('') # 考虑停用词 stops =[i.strip() for i in open(r'stop.txt',encoding='utf-8').readlines()] # vector = CountVectorizer().fit(train['text']) vector = CountVectorizer(stop_words=stops).fit(train['text']) train_vector = vector.transform(train['text']) test_vector = vector.transform(test['text']) # SVM from sklearn.svm import SVC model = SVC() # 开始训练,这里可以考虑修改默认的batch_size与epoch来取得更好的效果 model.fit(train_vector, train['label']) # 利用模型对测试集label标签进行预测 test['label'] = model.predict(test_vector) test['Keywords'] = test['title'].fillna('') test[['uuid','Keywords','label']].to_csv('submit_task_SVM.csv', index=None)
4. 实践成绩
8.14 submit_task1.csv 得分:0.67116
第一次测试是基于逻辑回归模型的,没有考虑停用词;
8.16 submit_task_LR.csv 得分:0.67435
第二次测试也是基于逻辑回归模型的,但考虑了停用词;
8.16 submit_task_SVM.csv 得分:0.6778
第三次测试是基于SVM模型的,考虑了停用词;
8.16 submit_task_AdaBoost.csv 得分:0.76263
第四次测试是基于AdaBoost模型的,考虑了停用词;
8.17 尝试了XGBoost模型、GBDT模型,并且稍微调整了一下AdaBoost参数,但效果不行,得分比baseline低了将近0.01,这里就不展示了。接下来会想办法提升分数。