Sklearn文本特征提取
- 1、TF-IDF矢量化器
- 2、英文文档计算TF-IDF
- 3、中文文档计算TF-IDF
 
 
1、TF-IDF矢量化器
Sklearn提供了计算TF-IDF(详见:传送门)值的API:TfidfVectorizer(TF-IDF矢量化器)
class sklearn.feature_extraction.text.TfidfVectorizer(*, input='content', encoding='utf-8', decode_error='strict', strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, analyzer='word', stop_words=None, token_pattern='(?u)\\b\\w\\w+\\b', ngram_range=(1, 1), max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False, dtype=<class 'numpy.float64'>, norm='l2', use_idf=True, smooth_idf=True, sublinear_tf=False)
官方对该API的描述如下:
TfidfVectorizer将原始文档集合转换为TF-IDF特征矩阵。相当于CountVectorizer后接TfidfTransformer。CountVectorizer将文本文档集合转换为词频/字符频数矩阵;TfidfTransformer将词频/字符频数矩阵转换为标准化的TF或TF-IDF矩阵
官方文档:https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html
API参数及说明如下:
| 参数 | 说明 | 
|---|---|
| input | content(默认):输入为字符串或字节类型的文本内容;filename:输入为可序列化的文件名;file:输入为内存中的文件流对象 | 
| encoding | 对给定字节或文件的解码的编码,默认为 utf-8 | 
| decode_error | 指定不是 encoding编码时,如何做,默认为strict,直接抛出UnicodeDecodeError错误。其他参数:ignore(忽略错误);replace:使用占位符?替换非法字符 | 
| strip_accents | 使用 ascii或unicode编码在预处理步骤中删除原始文本中的重音符号(accents),重音符号指的是加粗、单引号等,默认为None,不执行此操作 | 
| lowercase | 是否在分词前将所有字符转换为小写,默认为True | 
| preprocessor | 在分词和生成 n-grams时,覆盖预处理阶段,即指定预处理步骤。该参数只在analyzer未设置可调用对象时使用,默认为None | 
| tokenizer | 在预处理和生成 n-grams时,覆盖分词步骤。该参数只在analyzer为word时使用 | 
| analyzer | 指定特征向量是基于单词还是 n-grams的字符形式。word(默认):特征由单词组成;char:特征由字符组成;char_wb:特征由字符组成(以n-gram为边界,n-gram用空格填充) | 
| stop_words | 指定停用词,默认为None,不使用停用词,但当 max_df参数在[0.7,1.0]时,可以自动检测并根据语料库过滤停用词。其他参数有:english(使用内置默认的英文停用词);list(指定停用词列表,只有在analyzer为word时才起作用) | 
| token_pattern | 分词方式(按正则表达式)。默认筛选长度大于等于2的字母和数字混合字符(标点符号被当作分隔符),仅在 analyzer为word时使用 | 
| ngram_range | 要提取的 n-grams中n值范围的上限和下限,取(min_n,max_n)区间的全部值,元组类型,默认为(1,1) | 
| max_df | 在构建词汇表时,忽略文档中频率高于该阈值的词条,默认为1.0。 float类型应介于[0.0,1.0],表示词条在文档中出现的比例阈值;int类型时,表示词条在文档中出现的频数阈值 | 
| min_df | 在构建词汇表时,忽略文档中频率低于该阈值的词条,默认为1。 float类型应介于[0.0,1.0],表示词条在文档中出现的比例阈值;int类型时,表示词条在文档中出现的频数阈值 | 
| max_features | 最大的特征词条数,默认为None,表示词条有多少算多少,这时要注意维度爆炸 | 
| vocabulary | 指定词表的映射,字典类型, key是词条,value是列索引值,默认为None,生成默认词条列索引 | 
| binary | 一个关键词在一个文档中可能出现n次,如果设置为True,非零的n将全部置为1,这对需要布尔值输入的离散概率模型有用。默认为False | 
| dtype | fit_transform()和transform()函数返回的矩阵元素的数据类型 | 
| norm | 输出结果是否标准化/归一化。 l2(默认):向量元素的平方和为1,当应用l2范数时,两个向量之间的余弦相似度是它们的点积;l1:向量元素的绝对值之和为1;None:不使用标准化/归一化 | 
| use_idf | 是否计算IDF,默认为True。设置为False时,IDF=1 | 
| smooth_idf | 是否在文档频率上加1来平滑IDF,避免分母为0,默认为True | 
| sublinear_tf | 是否应用亚线性 tf缩放,即将tf替换为1+log(tf),默认为False | 
API常用属性及说明如下:
| 属性 | 说明 | 
|---|---|
| vocabulary_ | 特征单词与列索引的映射 | 
API常用方法及说明如下:
| 方法 | 说明 | 
|---|---|
| fit(raw_documents) | 拟合模型,学习文档词汇和IDF | 
| transform(raw_documents) | 将文档词汇转成TF-IDF特征矩阵返回 | 
| fit_transform(raw_documents) | 学习文档词汇和IDF,返回TF-IDF特征矩阵,相当于拟合后变换 | 
| get_feature_names_out() | 获取用于转换的不重复的特征词汇 | 
| get_stop_words() | 获取有效的停用词列表 | 
TfidfVectorizer(TF-IDF矢量化器)的一般使用步骤如下:
# 1)定义TF-IDF矢量化器
vectorizer = TfidfVectorizer()
# 2)使用fit_transform拟合转换训练集
train_matrix = vectorizer.fit_transform(X_train)
# 3)使用transform转换测试集
test_matrix = vectorizer.transform(X_test)
以下是TfidfVectorizer(TF-IDF矢量化器)分别在英文文档和中文文档处理中的应用
2、英文文档计算TF-IDF
TfidfVectorizer将原始文本转化为TF-IDF特征矩阵,从而为后续的文本相似度计算奠定基础。以下是一个示例:
1)定义文档
# 定义3个文档
docs = ['I am a student.','I live in Beijing.','I love China.',
]
2)计算TF-IDF值
from sklearn.feature_extraction.text import TfidfVectorizer# TF-IDF矢量化器
vectorizer = TfidfVectorizer()
# 拟合模型
tfidf_matrix = vectorizer.fit_transform(docs)
# 获取所有不重复的特征词汇
print(vectorizer.get_feature_names_out())  # ['am' 'beijing' 'china' 'in' 'live' 'love' 'student']
不知道你有没有发现,这些特征词汇中不包含i和a,你能解释这是为什么吗?
# 获取特征词汇的TF-IDF矩阵值
print(tfidf_matrix.todense())
print(tfidf_matrix.toarray())
'''
[[0.70710678 0.         0.         0.         0.         0.0.70710678][0.         0.57735027 0.         0.57735027 0.57735027 0.0.        ][0.         0.         0.70710678 0.         0.         0.707106780.        ]]
'''
# 获取特征词汇与列的对应关系
print(vectorizer.vocabulary_)  # {'am': 0, 'student': 6, 'live': 4, 'in': 3, 'beijing': 1, 'love': 5, 'china': 2}
3、中文文档计算TF-IDF
与英文文档不同,中文文档的词汇之间没有像英文那样的自然空格分割,因此,需要额外处理,要将中文文档转换为类似英文文档中自然空格分割的格式。以下是一个示例:
1)定义文档
# 定义3个文档
docs = ["我是一名学生。","我居住在北京。","我爱中国。"
]
2)中文文档预处理
import jieba# 使用中文分词库jieba进行分词
doc_words = [jieba.lcut(doc) for doc in docs]
new_docs = [' '.join(words) for words in doc_words]
print(new_docs)  # ['我 是 一名 学生 。', '我 居住 在 北京 。', '我 爱 中国 。']
3)计算TF-IDF值
# TF-IDF矢量化器
vectorizer = TfidfVectorizer()
# 拟合模型
tfidf_matrix = vectorizer.fit_transform(new_docs)
# 获取所有不重复的特征词汇
print(vectorizer.get_feature_names_out())  # ['一名' '中国' '北京' '学生' '居住']
同样,这些特征词汇中不包含“我”、“是”、“在”和“爱”,你能解释这是为什么吗?
# 获取特征词汇的TF-IDF矩阵值
print(tfidf_matrix.todense())
print(tfidf_matrix.toarray())
'''
[[0.70710678 0.         0.         0.70710678 0.        ][0.         0.         0.70710678 0.         0.70710678][0.         1.         0.         0.         0.        ]]
'''
# 获取特征词汇与列的对应关系
print(vectorizer.vocabulary_)  # {'一名': 0, '学生': 3, '居住': 4, '北京': 2, '中国': 1}
通过对比,我们发现,在计算中文文档TF-IDF时,需要先对文档进行特别处理,将文档处理成类似英文的自然空格分割形式,以方便应用TF-IDF矢量化器