在处理文本数据时,经常需要将文本转换为数值形式,以便机器学习算法能够处理。因此,需要一些预处理技术将文本转换为数值。词袋模型(Bag-of-Words, BOW)和TF-IDF是两种常用的文本预处理技术,它们可以将输入文本转换为数值形式。
词袋模型通过计算每个词在文档中出现的次数,将文本转换为固定长度的向量。以以下句子为例:
文本处理是必要的。
文本处理是必要且重要的。
文本处理是简单的。
将上述每个句子称为一个文档。如果提取所有这些句子中的独特词汇,词汇表将包括这7个词:{‘文本’, ‘处理’, ‘是’, ‘必要’, ‘和’, ‘重要’, ‘简单’}。进行词袋模型处理时,只需计算每个词在每个文档中出现的次数。因此,为每个文档得到以下长度为7的向量:
文档1: [1,1,1,1,0,0,0]
文档2: [1,1,1,1,1,1,0]
文档3: [1,1,1,0,0,0,1]
词袋模型的局限性在于,如果将其应用于大型文档,生成的向量会非常大,并且会有很多空值,导致稀疏向量的产生。此外,词袋模型不包含任何关于文本意义的信息。例如,如果考虑这两个句子——“文本处理简单但繁琐。”和“文本处理繁琐但简单。”——词袋模型会为它们创建相同的向量,尽管它们有不同的含义。
TF-IDF通过成比例地增加一个词在文档中出现的次数,但同时被文档中它出现的次数所平衡。因此,像‘这个’、‘是’等在所有文档中普遍存在的词不会被赋予很高的排名。然而,一个在少数文档中出现太多次的词将被赋予更高的排名,因为它可能表明文档的上下文。
词频(Term Frequency)定义为一个词(i)在文档(j)中出现的次数除以文档中的总词数。逆文档频率(Inverse Document Frequency)指的是总文档数除以包含该词的文档数的对数。对数的加入是为了减弱一个非常高的IDF值的重要性。TF-IDF通过将词频与逆文档频率相乘来计算。
让现在来看一个TF-IDF的示例,称之为文档。
文档1:
文本处理是必要的。
文档2:
文本处理是必要且重要的。
上述表格显示了某些词的TF-IDF为零,而某些词的TF-IDF为非零,这取决于它们在文档中的频率以及在所有文档中的频率。TF-IDF的局限性在于,这种向量化并不帮助引入词的上下文含义,因为它仅基于频率。
在Python中,可以使用sklearn库轻松地执行词袋模型或计数向量化和TF-IDF向量化。
# 词袋模型使用计数向量化
from sklearn.feature_extraction.text import CountVectorizer
corpus = ['文本处理是必要的。', '文本处理是必要且重要的。', '文本处理是简单的。']
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())
打印特征得到以下输出:
print(X.toarray())
上述数组表示使用词袋模型向量化为3个文档创建的向量。
# TF-IDF向量化
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
print(X.toarray())
上述数组表示使用TF-IDF向量化为3个文档创建的向量。
了解重要参数:
- Sklearn的CountVectorizer & TFIDF向量化:
max_features:此参数允许使用‘n’个最频繁的词作为特征,而不是所有词。可以为此参数传递一个整数。
stop_words:可以通过使用此参数删除像‘这个’、‘是’、‘的’等极其常见的词,因为这些共同词对模型的价值很小。可以将此参数设置为‘english’以使用内置列表。也可以将其设置为自定义列表。
analyzer:此参数告诉模型特征应该是由词n-gram还是字符n-gram组成。可以将其设置为‘word’、‘char’或‘char_wb’。选项‘char_wb’仅从文本内部的单词边界创建字符n-gram。
ngram_range:n-gram是一行中的词串。例如,在句子“文本处理是简单的。”中,2-gram可能是‘文本处理’、‘处理是’或‘是简单的’。可以将ngram_range设置为(x,y),其中x是想要包含在特征中的n-gram的最小大小,y是最大大小。默认的ngram_range是(1,1)。
min_df, max_df:这些指的是一个词/n-gram作为特征应该具有的最小和最大文档频率。这里的频率指的是文档的比例。两个参数都必须设置在[0,1]的范围内。