賽題分析
本賽題是一個入門級的文本多分類問題,賽題數據是新聞文本數據,為了防止人工標註按照字符級別進行了匿名處理。
數據包含14個類別,類別標籤映射字典如下:
{'科技': 0, '股票': 1, '體育': 2, '娛樂': 3, '時政': 4, '社會': 5, '教育': 6, '財經': 7, '家居': 8, '遊戲': 9, '房產': 10, '時尚': 11, '彩票': 12, '星座': 13}
比賽數據劃分為:訓練集20w條,測試集A 5w條,測試集B 5w條。
數據評測標準評價標準為類別f1_score的均值,結果越大越好文本分類的思路通常包括兩種:
文本特徵提取+機器學習分類器
深度學習微調
具體方法有:
詞袋模型+分類器
TF-IDF+分類器
WordVec+分類器
FastText
TextCNN 文本分類
Bert 文本分類
數據探索文本類型數據分析,一般包括:
%matplotlib inlineimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn.naive_bayes import MultinomialNBfrom sklearn.linear_model import RidgeClassifierfrom sklearn.metrics import f1_scoreplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=False1、數據加載
train_df=pd.read_csv("d:/data/aliyun/news/train_set.csv",sep='\t',nrows=40000)test_df=pd.read_csv("d:/data/aliyun/news/test_a.csv",sep='\t')print('train dataframe shape=>',train_df.shape)print('test dataframe shape=>',test_df.shape)train_df.head(3)train dataframe shape=> (40000, 2)
test dataframe shape=> (50000, 1)
2、類別分布統計用於發現類別不均衡問題,通常解決方法有:欠採樣、過採樣、代價敏感學習
tag2id={'科技': 0, '股票': 1, '體育': 2, '娛樂': 3, '時政': 4, '社會': 5, '教育': 6, '財經': 7, '家居': 8, '遊戲': 9, '房產': 10, '時尚': 11, '彩票': 12, '星座': 13}id2tag={y:x for x,y in tag2id.items()}value_counts=train_df['label'].value_counts()news_index=[id2tag[x] for x in value_counts.index]plt.bar(news_index,value_counts.values)3、文本長度分布統計部分算法要求輸入的文本長度相同,對於不足或超過設定長度的文本分別進行padding或truncation
train_df['words']=train_df['text'].apply(lambda x: x.split())train_df['word_count']=train_df['words'].apply(lambda x: len(x))train_df.head(3)train_df['word_count'].describe()#文本長度大於5000的數據有222條print(train_df['word_count'][train_df['word_count']>5000].count()) #只繪製文本長度小於5000的數據plt.hist(train_df[train_df['word_count']<5000]['word_count'],bins=100) plt.xlabel('word count')4、數據集詞頻統計詞頻特別高的單詞通常為標點符號、介詞等停用詞,有些算法需要去掉停用詞。
from collections import defaultdictword_count=defaultdict(int)for line in train_df['words']: for word in line: word_count[word]=word_count[word]+1sorted_word_count=sorted(word_count.items(),key=lambda kv:kv[1],reverse=True)sorted_word_count[:10][('3750', 1493823),
('648', 981796),
('900', 650003),
('3370', 402088),
('6122', 318080),
('4464', 308330),
('7399', 289577),
('4939', 276546),
('3659', 249766),('4811', 230110)]
文本向量化文本向量化是文本特徵提取的一種方法,常見的文本向量化方法包括:
1、使用詞袋模型文本向量化%%timecv=CountVectorizer()vec=cv.fit_transform(train_df['text'])cv_train_x,cv_test_x,cv_train_y,cv_test_y=vec[:20000],vec[20000:],train_df.iloc[:20000]['label'],train_df.iloc[20000:]['label']2、使用TF-IDF進行文本向量化%%timetf_idf=TfidfVectorizer(ngram_range=(1,3),max_features=3000)vec=tf_idf.fit_transform(train_df['text'])tf_train_x,tf_test_x,tf_train_y,tf_test_y=vec[:20000],vec[20000:],train_df.iloc[:20000]['label'],train_df.iloc[20000:]['label']
文本分類此處只使用TF-IDF文本向量化的結果作為特徵,分別使用樸素貝葉斯和嶺回歸模型進行分類
1、使用樸素貝葉斯模型分類bayes_model=MultinomialNB()bayes_model.fit(tf_train_x,tf_train_y)test_pred=bayes_model.predict(tf_test_x)f1_score(tf_test_y,test_pred,average='macro')0.7418091913024885
2、使用嶺回歸模型分類rc_model=RidgeClassifier()rc_model.fit(tf_train_x,tf_train_y)test_pred=rc_model.predict(tf_test_x)f1_score(tf_test_y,test_pred,average='macro')0.8880642674979569
預測測試集數據,並提交結果vec=tf_idf.fit_transform(test_df['text'])result=rc_model.predict(vec)pd.DataFrame(data=result,columns=['label']).to_csv('result.csv',index=False)本文僅做了一個最基本的實現,可以作為一個base,後續的優化方向有:
1、特徵處理:padding、truncation、去除停用詞等
2、模型融合
3、使用bert等深度學習方法 Fine-Tuning
更多天池、kaggle比賽題講解請掃下方二維碼,關注:「 AI社區 」
加小編微信(備註:機器學習)
拉你入「機器學習交流群」