Code: https://github.com/SimonLliu/DGB_AlphaTeam
在本次比賽中且轨,由于是采用傳統(tǒng)模型的原因,特征工程占的比重較重谷羞,幾乎占了比賽全部時(shí)間的70%俗批。
采用的方法主要有如下:
1、經(jīng)典文本特征
CountVectorizer秘蛔、TfidfVectorizer陨亡、HashingVectorizer、Doc2Vec
2深员、用模型提取特征
LR提取重要特征负蠕、SVM提取重要t特征
3、特征降維
LSA特征降維倦畅、LDA特征降維(降維時(shí)間太長遮糖,放棄)
4、不同特征提取方法的組合叠赐、拼接
一欲账、CountVectorizer
1、使用方法
官方文檔:class?sklearn.feature_extraction.text.CountVectorizer
(input=’content’,?encoding=’utf8’,?decode_error=’strict’,?strip_accents=None,?lowercase=True,?preprocessor=None,?tokenizer=None,?stop_words=None,?token_pattern=’(?u)\b\w\w+\b’,?ngram_range(1,?1),?analyzer=’word’,?
max_df=1.0,?min_df=1,?max_features=None,?vocabulary=None,?binary=False,?dtype=<class ‘numpy.int64’>)
核心參數(shù):
1) ngram_range:詞組切分的長度范圍芭概,劃分了計(jì)算詞頻用的相鄰的詞的數(shù)量赛不,
在本次比賽中選用了(1,1)(1罢洲,2)(1踢故,3)(1,4)四個(gè)參數(shù)來提取特征惹苗,ngram_range的范圍越大殿较,提取時(shí)間越長,且時(shí)間增長非線性桩蓉,建議若若數(shù)據(jù)量過大淋纲,不宜超過(1,3)
?2) max_df:可以設(shè)置為范圍在[0.0 1.0]的float触机,也可以設(shè)置為沒有范圍限制的int帚戳,默認(rèn)為1.0,含義為大于某一限度的詞頻忽略儡首。
在比賽中試了不同的值片任,包括0.8、0.9蔬胯、0.99对供,建議選擇0.9,結(jié)果表現(xiàn)較好
3)? min_df:可以設(shè)置為范圍在[0.0 1.0]的float,也可以設(shè)置為沒有范圍限制的int产场,默認(rèn)為1.0鹅髓,含義為小于某一限度的詞頻忽略。
在比賽中同樣試了不同的值京景,包括0.01窿冯、0.1、3确徙、5醒串、10等,最終結(jié)果認(rèn)為3較好
2鄙皇、原理分析:
旨在通過計(jì)數(shù)來將一個(gè)文檔轉(zhuǎn)換為向量芜赌。當(dāng)不存在先驗(yàn)字典時(shí),Countvectorizer可作為Estimator來提取詞匯伴逸,并生成一個(gè)Countvectorizermodel缠沈。該模型產(chǎn)生文檔關(guān)于詞語的稀疏表示,其表示可以傳遞給其他算法如LDA错蝴。
由圖可知洲愤,經(jīng)過統(tǒng)計(jì)文章的詞頻,會(huì)生成一個(gè)三值向量顷锰,第一個(gè)值代表不同詞的數(shù)量禽篱,第二個(gè)值對(duì)不同的詞進(jìn)行標(biāo)記,第三個(gè)值為詞頻列表。
二荠雕、TfidfVectorizer
1适揉、使用方法
官網(wǎng)文檔:class?sklearn.feature_extraction.text.TfidfVectorizer(input=’content’,?encoding=’utf-8’,?decode_error=’strict’,?strip_accents=None,?lowercase=True,?preprocessor=None,?tokenizer=None,?analyzer=’word’,?stop_words=None,?token_pattern=’(?u)\b\w\w+\b’,?ngram_range=(1,?1),?max_df=1.0,?min_df=1,?
max_features=None,?vocabulary=None,?binary=False,?dtype=<class ‘numpy.int64’>,?norm=’l2’,?use_idf=True,?smooth_idf=True,?sublinear_tf=False)
核心參數(shù):
1) ngram_range:同上
?2) max_df:同上
3)? min_df:同上
2、原理分析
我們需要一個(gè)重要性權(quán)值調(diào)整參數(shù)唯竹,來衡量一個(gè)詞是不是常見詞。因?yàn)椴怀R姷脑~出現(xiàn)的頻率越高,顯然重要性越大良狈,增加權(quán)重調(diào)整參數(shù)。
這個(gè)權(quán)重調(diào)整參數(shù)就是“逆文檔頻率”(IDF笨枯,Inverse Document Frequency)薪丁,它的大小與一個(gè)詞的常見程度成反比。
知道了 TF 和 IDF 以后馅精,將這兩個(gè)值相乘严嗜,就得到了一個(gè)詞的TF-IDF值。某個(gè)詞對(duì)文章的重要性越高洲敢,它的TF-IDF值就越大漫玄。如果用公式來表示,則對(duì)于某個(gè)特定文件中的詞語?titi?而言,它的 TF 可以表示為:?
其中?ni,j 是該詞在文件?dj中出現(xiàn)的次數(shù)睦优,而分母則是文件?dj 中所有詞匯出現(xiàn)的次數(shù)總和渗常。
某一特定詞語的IDF,可以由總文件數(shù)目除以包含該詞語之文件的數(shù)目汗盘,再將得到的商取對(duì)數(shù)即可:?
其中皱碘,|D|是語料庫中的文件總數(shù)。?|{j:ti∈dj}| 表示包含詞語?ti 的文件數(shù)目(即?ni,j≠0 的文件數(shù)目)隐孽。如果該詞語不在語料庫中癌椿,就會(huì)導(dǎo)致分母為零,因此一般情況下使用?1+|{j:ti∈dj}缓醋。
最后如失,便可以來計(jì)算?TFTF-IDF(t)=TF(t)×IDF(t)IDF(t)=TF(t)×IDF(t)。
三送粱、HashingVectorizer
1褪贵、使用方法
官方文檔:class?sklearn.feature_extraction.text.HashingVectorizer(input=’content’,?encoding=’utf-8’,?decode_error=’strict’,?strip_accents=None,?lowercase=True,?preprocessor=None,?tokenizer=None,?stop_words=None,?token_pattern=’(?u)\b\w\w+\b’,?ngram_range=(1,?1),?analyzer=’word’,?n_features=1048576,?binary=False,?norm=’l2’,?alternate_sign=True,?non_negative=False,?dtype=<class ‘numpy.float64’>)
核心參數(shù):
ngram_range:同上
n_features:輸出矩陣的列數(shù),比賽中選用200抗俄,特征較小脆丁,大概為300M
2、原理分析
https://blog.csdn.net/mbx8x9u/article/details/78801282
四动雹、Doc2Vec
1槽卫、使用方法(參考了Jian老師的代碼)
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(texts)]
model = Doc2Vec(documents, vector_size=200, window=5, min_count=3, workers=4, epochs=25)
docvecs = model.docvecs
x_train = []
for i in range(0, 102277):
? ? x_train.append(docvecs[i])
x_train = np.array(x_train)
x_test = []
for j in range(102277, 204554):
? ? x_test.append(docvecs[j])
x_test = np.array(x_test)
2、原理分析
https://blog.csdn.net/Walker_Hao/article/details/78995591
五胰蝠、利用模型提取特征
from sklearn.feature_selection import SelectFromModel
slt = SelectFromModel(lsvc, prefit=True)
x_train_s = slt.transform(x_train)
x_test_s = slt.transform(x_test)
SelectFromModel 是一個(gè)通用轉(zhuǎn)換器,其需要的Model只需要帶有conef_或者feature_importances屬性,那么就可以作為SelectFromModel的Model來使用. 如果相關(guān)的coef_?或者?featureimportances?屬性值低于預(yù)先設(shè)置的閾值歼培,這些特征將會(huì)被認(rèn)為不重要并且移除掉。除了指定數(shù)值上的閾值之外茸塞,還可以通過給定字符串參數(shù)來使用內(nèi)置的啟發(fā)式方法找到一個(gè)合適的閾值躲庄。可以使用的啟發(fā)式方法有 mean 钾虐、 median 以及使用浮點(diǎn)數(shù)乘以這些(例如噪窘,0.1*mean )。
https://blog.csdn.net/fontthrone/article/details/79064930
六效扫、LSA特征降維
from sklearn.decomposition import TruncatedSVD
lsa = TruncatedSVD(n_components=200)
https://blog.csdn.net/mmc2015/article/details/46867773
核心問題在于奇異值分解倔监,TruncatedSVD是SVD的變形,只計(jì)算用戶指定的最大的K個(gè)奇異值菌仁,直接處理樣本矩陣X
LSA降維后浩习,特征大小大概在300M-500M
七、LDA特征降維
from sklearn.decomposition import LatentDirichletAllocation
lda = LatentDirichletAllocation(n_components=200)
x_train = lda.fit_transform(x_train)
https://blog.csdn.net/aws3217150/article/details/53840029
在這做兩篇文章的記錄:
《LDA數(shù)學(xué)八卦》
《Parameter estimation for text analysis》
八掘托、不同特征提取方法的組合瘦锹、拼接
1、將article和word_segment直接拼接。
article是達(dá)觀數(shù)據(jù)提供的字符數(shù)據(jù)集弯院,word_segment是達(dá)觀數(shù)據(jù)提供的詞數(shù)據(jù)集辱士。
在首先嘗試的時(shí)候,分別用Tf-idf提取特征听绳,用線性模型svm和lr進(jìn)行訓(xùn)練颂碘,結(jié)果都在0.76-0.776之間。
后思考到能否直接擴(kuò)充訓(xùn)練數(shù)據(jù)集椅挣,遂將article和word_segment直接拼接头岔。
df_train["word_seg"] = df_train["article"].map(str) + df_train["word_seg"].map(str)
df_test["word_seg"] = df_test["article"].map(str) + df_test["word_seg"].map(str)
在隊(duì)友的服務(wù)器支持下,將?ngram_ranged調(diào)到1-4鼠证,訓(xùn)練時(shí)間大概將近一天峡竣,模型25GB,特征也有十幾GB,測試結(jié)果達(dá)到了0.779
2量九、將article/word_segment的Hash适掰、tf、doc2vec拼接
考慮到tf-idf的特征太大荠列,遂不將tf-idf與其他特征融合
拼接的過程是先將hash类浪、doc2vec轉(zhuǎn)換成稀疏矩陣,再與tf-idf拼接
"""將numpy 數(shù)組 轉(zhuǎn)換為 csr稀疏矩陣"""
x_train_1 = sparse.csr_matrix(x_train_1)
x_test_1 = sparse.csc_matrix(x_test_1)
x_train_2 = sparse.csr_matrix(x_train_2)
x_test_2 = sparse.csc_matrix(x_test_2)
x_train_3 = sparse.csr_matrix(x_train_3)
x_test_3 = sparse.csc_matrix(x_test_3)
x_train_4 = sparse.csr_matrix(x_train_4)
x_test_4 = sparse.csc_matrix(x_test_4)
"""讀取tf特征"""
#f_tfidf = open('./data_tf_article.pkl', 'rb')
#x_train_3, _, x_test_3= pickle.load(f_tfidf)
#f_tfidf.close()
"""對(duì)稀疏矩陣進(jìn)行合并"""
x_train_5 = hstack([x_train_1, x_train_2])
x_test_5 = hstack([x_test_1, x_test_2])
x_train_6 = hstack([x_train_5, x_train_3])
x_test_6 = hstack([x_test_5, x_test_3])
x_train_7 = hstack([x_train_6, x_train_4])
x_test_7 = hstack([x_test_6, x_test_4])
3肌似、將從article_tf-idf中利用svm挑選出來的特征與將從word_segment_tf-idf中利用lr挑選出來的特征拼接
4费就、將從article_tf-idf中利用lr挑選出來的特征與將從word_segment_tf-idf中利用svm挑選出來的特征拼接