Titanic数据集:仅用名字列就取得0.8的正确率
文章目录
前言
表格机器学习的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='''!"'#$&()*+,-./:;<=>aaa@qq.com[\]^_{|}~`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数目是根据数据判断出来的)