前言
表格機器學習的4類特徵
最近在思考表格機器學習,或者說對錶格數據、結構化數據的有監督機器學習的工作流。
我認爲在大部分場景下,大概有4類特徵:
- categorical
- numerical
- date
- text
text 特徵組
最近在調研text
特徵組。如果一個表格中有一列全是文本,其實這個文本是可以包含很多信息的,可以用TFIDF提取重要度,然後用主題模型建模或者用矩陣分解的方法進行降維。TFIDF的輸出是一個稀疏矩陣,一般不能直接丟給學習器,最好做個降維,其實降維後信息的損失並不大,甚至對於模型還有提升的效果。
數據處理
載入數據
import pandas as pd
df=pd.read_csv("train_classification.csv")
name=df.Name
讀入數據,只取出名字列
def clean_text(text):
text=text.replace("\n"," ").replace("\r"," ")
punc_list='''!"'#$&()*+,-./:;<=>?@[\]^_{|}~`0123456789'''
t=str.maketrans(dict.fromkeys(punc_list," "))
text=text.translate(t)
return text
數據清洗
name=name.apply(clean_text)
對數據進行清洗,方便做tokenlization
分詞
name_list=name.str.split()
分詞(tokenlize)
刪除低頻詞
from functools import reduce
from operator import add
flattern_name_list=reduce(add, name_list)
from collections import Counter
counter=Counter(flattern_name_list)
counter={k:v for k,v in counter.items() if v >1}
def remove_low_requency(items):
return [item for item in items if item in counter]
filter_name_list=name_list.apply(remove_low_requency)
刪除低頻詞
建模
建模我分兩類,一類用sklearn
建模,一類用gensim
建模
benchmark模型採用沒調參的RandomForest
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
rf=RandomForestClassifier(random_state=100)
y=df["Survived"].values
sklearn
TF-IDF
把list
拼起來
str_series=filter_name_list.str.join(" ")
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf=TfidfVectorizer().fit_transform(str_series)
用TF-IDF的確可以取得不錯的效果。缺點是維度高,這裏我已經刪除了只出現一次的詞了,但是還有400維。如果在更復雜的任務一般會上10萬維。
而且TFIDF的輸出是稀疏矩陣,很多學習器和預處理器不支持這樣的數據,雖然可以做密集化,但是可能OOM。
NMF
非負矩陣分解
from sklearn.decomposition import NMF
x=NMF(n_components=4,random_state=42).fit_transform(tfidf);x
可以看到信息損失不大,但維度顯著降低了
TruncatedSVD
https://scikit-learn.org/stable/modules/decomposition.html#lsa
https://blog.csdn.net/mmc2015/article/details/46867773
TSVD
其實就是LSA
,與LSI
相似。
TSVD在本文中表現是最好的,直接取得了0.8的正確率
gensim
from gensim.sklearn_api import LdaTransformer, LsiTransformer, HdpTransformer, RpTransformer
與sklearn的API不同,gensim多了很多自己的東西,比如corpus和dictionary等,所以這裏將gensim的模型單獨拿到一個目錄下說。
dic=Dictionary(filter_name_list)
首先要將filter_name_list
這個元素都是list的series處理成字典
bow_list=[dic.doc2bow(item) for item in filter_name_list]
處理成文檔詞袋(感覺這種形式的數據結構和CSR的稀疏矩陣的內存佔用可能差不多…)
LDA
latent dirichlet allocation
model = LdaTransformer(num_topics=4, id2word=dic, iterations=20, random_state=1)
不知道爲什麼,LDA
是本文表現最差的模型
LSI
latent semantic indexing
這裏需要注意的是,LSI的API中並沒有random_state,並且模型的表現是有隨機性的。
RP
RandomProjection
這裏需要注意的是,RP的API中並沒有random_state,並且模型的表現是有隨機性的。
HDP
hierarchical dirichlet process
這個模型我沒有跑通。這個模型可以指定random_state,但是卻不能指定topic數目(實際的topic數目是根據數據判斷出來的)