欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Titanic数据集:仅用名字列就取得0.8的正确率

程序员文章站 2024-03-15 19:55:18
...

前言

表格机器学习的4类特征

最近在思考表格机器学习,或者说对表格数据、结构化数据的有监督机器学习的工作流。

我认为在大部分场景下,大概有4类特征:

  1. categorical
  2. numerical
  3. date
  4. 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
Titanic数据集:仅用名字列就取得0.8的正确率

分词

name_list=name.str.split()

分词(tokenlize)
Titanic数据集:仅用名字列就取得0.8的正确率

删除低频词

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)

删除低频词

Titanic数据集:仅用名字列就取得0.8的正确率

建模

建模我分两类,一类用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(" ")

Titanic数据集:仅用名字列就取得0.8的正确率

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf=TfidfVectorizer().fit_transform(str_series)

Titanic数据集:仅用名字列就取得0.8的正确率

Titanic数据集:仅用名字列就取得0.8的正确率

用TF-IDF的确可以取得不错的效果。缺点是维度高,这里我已经删除了只出现一次的词了,但是还有400维。如果在更复杂的任务一般会上10万维。

而且TFIDF的输出是稀疏矩阵,很多学习器和预处理器不支持这样的数据,虽然可以做密集化,但是可能OOM。

NMF

非负矩阵分解

from sklearn.decomposition import NMF

x=NMF(n_components=4,random_state=42).fit_transform(tfidf);x

Titanic数据集:仅用名字列就取得0.8的正确率
可以看到信息损失不大,但维度显著降低了

TruncatedSVD

https://scikit-learn.org/stable/modules/decomposition.html#lsa

https://blog.csdn.net/mmc2015/article/details/46867773

TSVD其实就是LSA,与LSI相似。

Titanic数据集:仅用名字列就取得0.8的正确率
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的稀疏矩阵的内存占用可能差不多…)

Titanic数据集:仅用名字列就取得0.8的正确率

LDA

latent dirichlet allocation

model = LdaTransformer(num_topics=4, id2word=dic, iterations=20, random_state=1)

Titanic数据集:仅用名字列就取得0.8的正确率
不知道为什么,LDA是本文表现最差的模型

LSI

latent semantic indexing
Titanic数据集:仅用名字列就取得0.8的正确率
这里需要注意的是,LSI的API中并没有random_state,并且模型的表现是有随机性的。

RP

RandomProjection
Titanic数据集:仅用名字列就取得0.8的正确率
这里需要注意的是,RP的API中并没有random_state,并且模型的表现是有随机性的。

HDP

hierarchical dirichlet process

这个模型我没有跑通。这个模型可以指定random_state,但是却不能指定topic数目(实际的topic数目是根据数据判断出来的)

相关标签: NLP automl