在结构化数据中经常遇到列表或交易等非结构化列,比较典型的案例如下,此时一个列表列会包含字符串 或 一个列表:
ID列 Tag列
用户A tag1, tag2, tag3
用户B tag3, tag5, tag6, tag10
用户C tag3, tag5, tag6, tag10
如何对此类列进行编码和提取特征呢?本文将给出一些基础和进阶的解决方法。
在进行编码时,最基础的想法是可以统计个数,个数的多少可以直观反应这列包含的信息的多少。
df['Tag列'].apply(len)
当然可以直接进行统计列表长度,也可以先计算每个tag的频次,然后进行相应的统计。
在进行编码的过程中,可以使用onehot对单个某个tag进行编码,又或者使用直接使用TFIDF进行编码。
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
进行次数编码容易造成维度爆炸,一种代替的方法是先进行TFIDF编码,然后进行降维:LDA、SVD或者t-SNE降维。
from sklearn.decomposition import PCA
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.decomposition import TruncatedSVD
词向量是一种非常有效的单词编码方法,可以对单词进行映射。我们可以参考无监督句子编码的方法,对tag进行嵌入,然后对多个tag进行聚合。
如果一个tag编码为100维度,则我们需要将任意多个tag都编码为100维度。这里的聚合方法包括:
上述实现过程需要额外训练词向量,如果使用深度学习框架实现会更加快速。
对于tag列可以作为集合进行处理,可以参考频繁项挖掘的方法进行聚类操作。频繁项集聚类提供了一个减少维度,聚类之后的聚类类别可以单独当做类别变量。
相应簇由包含频繁项集,当然也可以使用文本聚类的方法,比如层次聚类。
在多个tag进行编码的过程,可以单独计算每个tag的IDF,也就是权重。当然我们也可以将多个tag组合在一起视为一个图。
比如tag1, tag2, tag3可以构建为一个三个节点的有向图,构建完成之后然后计算每个节点的权重。
通过PageRank可以计算得到每个tag的权重,也可以得到所有tag得到的图的核心节点。
如果将tag列表当做集合看待,我们可以使用minihash进行对集合进行编码,然后使用LSH进行编码。LSH包含多次哈希,最终可以将包含相同tag的列表哈希得到相同的桶中。