4.1 任務(wù)說明
學(xué)習(xí)主題:論文分類(數(shù)據(jù)建模任務(wù)),利用已有數(shù)據(jù)建模,對新論文進(jìn)行類別分類;
學(xué)習(xí)內(nèi)容:使用論文標(biāo)題完成類別分類;
學(xué)習(xí)成果:學(xué)會文本分類的基本方法、TF-IDF等;
在原始arxiv論文中論文都有對應(yīng)的類別,而論文類別是作者填寫的。在本次任務(wù)中我們可以借助論文的標(biāo)題和摘要完成:
對論文標(biāo)題和摘要進(jìn)行處理;
對論文類別進(jìn)行處理;
構(gòu)建文本分類模型;
思路1:TF-IDF+機(jī)器學(xué)習(xí)分類器
直接使用TF-IDF對文本提取特征,使用分類器進(jìn)行分類,分類器的選擇上可以使用SVM、LR、XGboost等
思路2:FastText
FastText是入門款的詞向量,利用Facebook提供的FastText工具,可以快速構(gòu)建分類器
思路3:WordVec+深度學(xué)習(xí)分類器
WordVec是進(jìn)階款的詞向量,并通過構(gòu)建深度學(xué)習(xí)分類完成分類。深度學(xué)習(xí)分類的網(wǎng)絡(luò)結(jié)構(gòu)可以選擇TextCNN、TextRnn或者BiLSTM。
思路4:Bert詞向量
Bert是高配款的詞向量,具有強(qiáng)大的建模學(xué)習(xí)能力。
為了方便大家入門文本分類,我們選擇思路1和思路2給大家講解。首先完成字段讀取:
data=[]#初始化#使用with語句優(yōu)勢:1.自動關(guān)閉文件句柄;2.自動顯示(處理)文件讀取數(shù)據(jù)異常withopen("arxiv-metadata-oai-snapshot.json",'r')asf:foridx,lineinenumerate(f):d=json.loads(line)d={'title':d['title'],'categories':d['categories'],'abstract':d['abstract']}data.append(d)# 選擇部分?jǐn)?shù)據(jù)ifidx>200000:breakdata=pd.DataFrame(data)#將list變?yōu)閐ataframe格式,方便使用pandas進(jìn)行分析
為了方便數(shù)據(jù)的處理,我們可以將標(biāo)題和摘要拼接一起完成分類。
data['text']=data['title']+data['abstract']data['text']=data['text'].apply(lambdax:x.replace('\n',' '))data['text']=data['text'].apply(lambdax:x.lower())data=data.drop(['abstract','title'],axis=1)
由于原始論文有可能有多個類別,所以也需要處理:
# 多個類別,包含子分類data['categories']=data['categories'].apply(lambdax:x.split(' '))# 單個類別,不包含子分類data['categories_big']=data['categories'].apply(lambdax: [xx.split('.')[0]forxxinx])
然后將類別進(jìn)行編碼,這里類別是多個,所以需要多編碼:
fromsklearn.preprocessingimportMultiLabelBinarizermlb=MultiLabelBinarizer()data_label=mlb.fit_transform(data['categories_big'].iloc[:])
思路1使用TFIDF提取特征,限制最多4000個單詞:
fromsklearn.feature_extraction.textimportTfidfVectorizervectorizer=TfidfVectorizer(max_features=4000)data_tfidf=vectorizer.fit_transform(data['text'].iloc[:])
由于這里是多標(biāo)簽分類,可以使用sklearn的多標(biāo)簽分類進(jìn)行封裝:
# 劃分訓(xùn)練集和驗(yàn)證集fromsklearn.model_selectionimporttrain_test_splitx_train,x_test,y_train,y_test=train_test_split(data_tfidf,data_label,test_size=0.2,random_state=1)# 構(gòu)建多標(biāo)簽分類模型fromsklearn.multioutputimportMultiOutputClassifierfromsklearn.naive_bayesimportMultinomialNBclf=MultiOutputClassifier(MultinomialNB()).fit(x_train,y_train)
驗(yàn)證模型的精度:
fromsklearn.metricsimportclassification_reportprint(classification_report(y_test,clf.predict(x_test)))
思路2使用深度學(xué)習(xí)模型,單詞進(jìn)行詞嵌入然后訓(xùn)練。首先按照文本劃分?jǐn)?shù)據(jù)集:
fromsklearn.model_selectionimporttrain_test_splitx_train,x_test,y_train,y_test=train_test_split(data['text'].iloc[:],data_label,test_size=0.2,random_state=1)
將數(shù)據(jù)集處理進(jìn)行編碼,并進(jìn)行截斷:
# parametermax_features=500max_len=150embed_size=100batch_size=128epochs=5fromkeras.preprocessing.textimportTokenizerfromkeras.preprocessingimportsequencetokens=Tokenizer(num_words=max_features)tokens.fit_on_texts(list(x_train)+list(x_test))x_sub_train=tokens.texts_to_sequences(x_train)x_sub_test=tokens.texts_to_sequences(x_test)x_sub_train=sequence.pad_sequences(x_sub_train,maxlen=max_len)x_sub_test=sequence.pad_sequences(x_sub_test,maxlen=max_len)
定義模型并完成訓(xùn)練:
# LSTM model# Keras Layers:fromkeras.layersimportDense,Input,LSTM,Bidirectional,Activation,Conv1D,GRUfromkeras.layersimportDropout,Embedding,GlobalMaxPooling1D,MaxPooling1D,Add,Flattenfromkeras.layersimportGlobalAveragePooling1D,GlobalMaxPooling1D,concatenate,SpatialDropout1D# Keras Callback Functions:fromkeras.callbacksimportCallbackfromkeras.callbacksimportEarlyStopping,ModelCheckpointfromkerasimportinitializers,regularizers,constraints,optimizers,layers,callbacksfromkeras.modelsimportModelfromkeras.optimizersimportAdamsequence_input=Input(shape=(max_len, ))x=Embedding(max_features,embed_size,trainable=False)(sequence_input)x=SpatialDropout1D(0.2)(x)x=Bidirectional(GRU(128,return_sequences=True,dropout=0.1,recurrent_dropout=0.1))(x)x=Conv1D(64,kernel_size=3,padding="valid",kernel_initializer="glorot_uniform")(x)avg_pool=GlobalAveragePooling1D()(x)max_pool=GlobalMaxPooling1D()(x)x=concatenate([avg_pool,max_pool])preds=Dense(20,activation="sigmoid")(x)model=Model(sequence_input,preds)model.compile(loss='binary_crossentropy',optimizer=Adam(lr=1e-3),metrics=['accuracy'])model.fit(x_sub_train,y_train,batch_size=batch_size,epochs=epochs)