1. 向量化 

1.1 概念

       词袋模型在分词之后,通过统计每个词在文本中出现的次数,就可以得到该文本基于词的特征,如果将各个文本样本的这些词与对应的词频放在一起,就是我们常说的向量化。向量化完毕后一般也会使用TF-IDF进行特征的权重修正,再将特征进行标准化。 再进行一些其他的特征工程后,就可以将数据带入机器学习算法进行分类聚类了。

       在词袋模型的统计词频这一步,会得到该文本中所有词的词频,有了词频,我们就可以用词向量表示这个文本。

1.2 向量化方式

(1)One-hot表示方式/词袋模型

    优点:

  •  解决了分类器不好处理离散数据的问题
  •  在一定程度上也起到了扩充特征的作用

   缺点:

  • 不考虑词与词之间的顺序
  • 其假设词与词之间相互独立(大多数情况下,词与词之间是相互有关联的)
  • 得到的特征是离散稀疏的

(2)N-gram

优点:

  • 考虑了词的顺序,信息量更充分

缺点:

  • 词表迅速膨胀,数据出现大量的稀疏化问题
  • 每增加一个词,模型参数增加40万倍
  • 无法衡量词项量之间的关系

(3)word2vec 

3.  Hash Trick

     将文本做了词频统计后,我们一般会通过TF-IDF进行词特征值修订。向量化的方法很好用,也很直接,但是在有些场景下很难使用,比如分词后的词汇表非常大,达到100万+,此时如果我们直接使用向量化的方法,将对应的样本对应特征矩阵载入内存,有可能将内存撑爆,在这种情况下怎么办呢?第一反应是要进行特征的降维,说的没错!而Hash Trick就是常用的文本特征降维方法。

        在大规模的文本处理中,由于特征的维度对应分词词汇表的大小,所以维度可能非常恐怖,此时需要进行降维,不能直接用上一节的向量化方法。而最常用的文本降维方法是Hash Trick。说到Hash,一点也不神秘,学过数据结构的同学都知道。这里的Hash意义也类似。

       那么,这种方法来处理特征,哈希后的特征是否能够很好的代表哈希前的特征呢?从实际应用中说,由于文本特征的高稀疏性,这么做是可行的。理论研究参考论文:Feature hashing for large scale multitask learning.。

  在scikit-learn的HashingVectorizer类中,实现了基于signed hash trick的算法,其为hash trick的变种。这里就用HashingVectorizer来实践一下Hash Trick,为了简单,使用上面的19维词汇表,并哈希降维到6维。当然在实际应用中,19维的数据根本不需要Hash Trick,这里只是做一个演示,代码如下:

向量化:

# 向量化
from sklearn.feature_extraction.text import CountVectorizer

# 实例化分词对象
vec = CountVectorizer(min_df=1)
# 将文本进行词袋处理
corpus=["I come to China to travel",
    "This is a car polupar in China",
    "I love tea and Apple ",
    "The work is to write some papers in science"]

X = vec.fit_transform(corpus)
print('CountVectorizer:\n',X)

CountVectorizer:
  (0, 16)    1
  (0, 3)    1
  (0, 15)    2
  (0, 4)    1
  (1, 5)    1
  (1, 9)    1
  (1, 2)    1
  (1, 6)    1
  (1, 14)    1
  (1, 3)    1
  (2, 1)    1
  (2, 0)    1
  (2, 12)    1
  (2, 7)    1
  (3, 10)    1
  (3, 8)    1
  (3, 11)    1
  (3, 18)    1
  (3, 17)    1
  (3, 13)    1
  (3, 5)    1
  (3, 6)    1
  (3, 15)    1 

特例:Hsah trick 

# 特例:Hsah trick
from sklearn.feature_extraction.text import HashingVectorizer

vectorizer2=HashingVectorizer(n_features=6,norm=None)
X2 = vectorizer2.fit_transform(corpus)

print('HashingVectorizer:\n', X2)

HashingVectorizer:
   (0, 1)    2.0
  (0, 2)    -1.0
  (0, 4)    1.0
  (0, 5)    -1.0
  (1, 0)    1.0
  (1, 1)    1.0
  (1, 2)    -1.0
  (1, 5)    -1.0
  (2, 0)    2.0
  (2, 5)    -2.0
  (3, 0)    0.0
  (3, 1)    4.0
  (3, 2)    -1.0
  (3, 3)    1.0
  (3, 5)    -1.0 

  和PCA类似,Hash Trick降维后的特征,已经不知道它代表的特征名字和意义。此时不能像向量化时候可以知道每一列的意义,所以Hash Trick的解释性不强。

4. 向量化与Hash Trick小结

  在特征预处理的时候,什么时候用一般意义的向量化,什么时候用Hash Trick呢?标准也很简单。

  一般来说,只要词汇表的特征不至于太大,大到内存不够用,肯定是使用一般意义的向量化比较好。因为向量化的方法解释性很强,我们知道每一维特征对应哪一个词,进而我们还可以使用TF-IDF对各个词特征的权重修改,进一步完善特征的表示。

  而Hash Trick用大规模机器学习上,此时我们的词汇量极大,使用向量化方法内存不够用,而使用Hash Trick降维速度很快,降维后的特征仍然可以帮我们完成后续的分类和聚类工作。当然由于分布式计算框架的存在,其实一般我们不会出现内存不够的情况。因此,实际工作中我使用的都是特征向量化