本Task的主要任务,是进行文本分类。在原始数据中,有作者填写好的分类。而我们要通过机器学习的方法,根据文章的标题、摘要,来预测文章分类。
数据处理步骤
- 对论文标题和摘要进行处理
- 对论文类别进行处理
- 构建文本分类模型
文本分类思路
- 思路1:TF-IDF + 机器学习分类器
直接使用TF-IDF对文本提取特征,使用分类器进行分类,分类器的选择上,可以使用SVM、LR、XGBoost等 - 思路2:FastText
FastText是入门款的词向量,利用FaceBook提供的FastText工具,可以快速构建分类器。 - 思路3:WordVec+深度学习分类器
WordVec是进阶款的词向量,并通过构建深度学习分类完成分类。深度学习分类的网络结构可以选择TextCNN、TextRnn、或者Bilstm - 思路4:Bert词向量
Bert是高配款词向量,具有强大的建模学习能力。
处理文本Feature(标题&摘要)
data["text"] = data["title"]+data["abstract"]
data["text"] = data["text"].apply(lambda x:x.replace('\n',' '))
data["text"] = data["text"].apply(lambda x: x.lower())
data = data.drop(['abstract',"title"],axis=1)
str.replace('\n',' ')替换条换行符
str.lower()统一变成小写
处理类别Target(类别)
由于一篇论文是有多个分类的标签的,所以这是一个多目标分类问题。
# 多个类别,包含子分类
data["categories"]=data["categories"].apply(lambda x:x.split(' '))
# 单个类别,不包含子分类
data["categories_big"] = data["categories"].apply(lambda x: [xx.split(".")[0] for xx in x])
str.split(" ")使用空格进行切分,形成列表。
[xx.split(".")[0] for xx in x]对每一项,再使用点进行切分,保留点前面的
Target多类别的编码
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
data_label = mlb.fit_transform(data["categories_big"])
由于总共有34种论文的分类,所以目标列就被fit_transform为一个34列的系数矩阵,某一篇论文属于哪几种分类,就在对应的列写1,其余的就是0。
多分类编码的类别名称,可以使用mlb.classes_获得。
思路1:使用TFIDF+机器学习
步骤1:将文本提取出TFIDF特征
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(max_features=4000)
初始化一个TfidfVectorizer模型,限制最多4000个单词
data_tfidf = vectorizer.fit_transform(data['text'])
使用文本特征进行fit_transform,
vectorizer.get_feature_names()可以获得单词表,总共有4000个单词。
每一篇论文的标题和摘要,都通过TFIDF,转换成为了一个4000维的向量。但是稀疏矩阵的形式,没法直接print出来。这个4000维的向量,可以理解为这4000个单词在该条文本中的重要度吧。
步骤2:划分训练集和测试集
# 划分训练集和验证集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(data_tfidf
,data_label
,test_size=0.2
,random_state=1)
以上,使用MultiLabelBinarizer把Target转换为34列,使用TfidfVectorizer把文本转换为4000列。在次基础上,再进行测试集的划分。
步骤3:构建多标签分类器
# 构建多标签分类模型
from sklearn.multioutput import MultiOutputClassifier
from sklearn.naive_bayes import MultinomialNB
clf = MultiOutputClassifier(MultinomialNB()).fit(x_train,y_train)
from sklearn.metrics import accuracy_score
accuracy_score(y_test,clf.predict(x_test))
这里使用了两层嵌套的模型,MultiOutputClassifier里面,包着MultinomialNB。
MultiOutputClassifier是用来扩展多目标分类的。
而里面的MultinomialNB就是一个分类器,多项式本朴素贝叶斯,可以换成SVM、LR、XGBoost等其他的分类器。
如使用XGBoost,代码如下,此时模型fit的时间会比较长。
import xgboost as xgb
model = MultiOutputClassifier(xgb.XGBClassifier(n_jobs = -1))
model.fit(x_train, y_train)
accuracy_score(y_test,model.predict(x_test))
步骤4:查看分类报告
from sklearn.metrics import classification_report
print(classification_report(y_test,clf.predict(x_test), target_names=classes))
分类报告提供了每种类别的准确率、召回率以及F1值