sklearn:TfidfVectorizer中文处理及一些使用参数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
sklearn:TfidfVectorizer中⽂处理及⼀些使⽤参数
sklearn: TfidfVectorizer 中⽂处理及⼀些使⽤参数
常规使⽤
TfidfVectorizer可以把原始⽂本转化为tf-idf的特征矩阵,从⽽为后续的⽂本相似度计算,主题模型(如),⽂本搜索排序等⼀系列应⽤奠定基础。
基本应⽤如:
from sklearn.feature_extraction.text import TfidfVectorizer
document = ["I have a pen.",
"I have an apple."]
tfidf_model = TfidfVectorizer().fit(document)
# 得到tf-idf矩阵,稀疏矩阵表⽰法
sparse_result = tfidf_model.transform(document)
print(sparse_result)
# 第0个字符串,对应词典序号为3的词的TFIDF为0.8148
# (0, 3) 0.814802474667
# (0, 2) 0.579738671538
# (1, 2) 0.449436416524
# (1, 1) 0.631667201738
# (1, 0) 0.631667201738
print(sparse_result.todense())
# 转化为更直观的⼀般矩阵
# [[ 0. 0. 0.57973867 0.81480247]
# [ 0.6316672 0.6316672 0.44943642 0. ]]
print(tfidf_model.vocabulary_)
# 词语与列的对应关系
# {'have': 2, 'pen': 3, 'an': 0, 'apple': 1}
注意:在上述计算tfidf过程中,有的词因为过于简短,会被⾃动丢弃,⽐如 I a 这两个词会被⾃动丢掉,这和
参数有关系,token_pattern。
它默认只匹配长度>=2的单词。
中⽂使⽤:
分词
使⽤中⽂预料来统计tfidf
中⽂不⽐英⽂,词语之间有着空格的⾃然分割,所以我们⾸先要进⾏分词处理,再把它转化为与上⾯的document类似的格式。
⽤著名的中⽂分词库jieba进⾏分词:
import jieba
text = """我是⼀条天狗呀!
我把⽉来吞了,
我把⽇来吞了,
我把⼀切的星球来吞了,
我把全宇宙来吞了。
我便是我了!"""
sentences = text.split()
sent_words = [list(jieba.cut(sent0)) for sent0 in sentences]
document = [" ".join(sent0) for sent0 in sent_words]
print(document)
# ['我是⼀条天狗呀!', '我把⽉来吞了,', '我把⽇来吞了,', '我把⼀切的星球来吞了,', '我把全宇宙来吞了。
', '我便是我了!']
建模
理论上,现在得到的document的格式已经可以直接拿来训练了。
让我们跑⼀下模型试试。
tfidf_model = TfidfVectorizer().fit(document)
print(tfidf_model.vocabulary_)
# {'⼀条': 1, '天狗': 4, '⽇来': 5, '⼀切': 0, '星球': 6, '全宇宙': 3, '便是': 2}
sparse_result = tfidf_model.transform(document)
print(sparse_result)
# (0, 4) 0.707106781187
# (0, 1) 0.707106781187
# (2, 5) 1.0
# (3, 6) 0.707106781187
# (3, 0) 0.707106781187
# (4, 3) 1.0
# (5, 2) 1.0
注意:这⾥没有出现报错,但是我们发现,这⾥丢掉了⼀些词,是参数搞的怪,会⾃动丢掉过短的词。
参数
单字的问题是token_pattern这个参数搞的⿁。
它的默认值只匹配长度≥2的单词,就像其实开头的例⼦中的'I'也被忽略了⼀样,⼀般来说,长度为1的单词在英⽂中⼀般是⽆⾜轻重的,但在中⽂⾥,就可能有⼀些很重要的单字词,所以修改如下:
tfidf_model2 = TfidfVectorizer(token_pattern=r"(?u)\b\w+\b").fit(document)
print(tfidf_model2.vocabulary_)
# {'我': 8, '是': 12, '⼀条': 1, '天狗': 7, '呀': 6, '把': 9, '⽉': 13, '来': 14, '吞': 5, '了': 2, '⽇来': 10, '⼀切': 0, '的': 15, '星球': 11, '全宇宙': 4, '便是': 3}
token_pattern这个参数使⽤正则表达式来分词,其默认参数为r"(?u)\b\w\w+\b",其中的两个\w决定了其匹配长度⾄少为2的单词,所以这边减到1个。
对这个参数进⾏更多修改,可以满⾜其他要求,⽐如这⾥依然没有得到标点符号,在此不详解了。
过滤单词
1. max_df/min_df: *[0.0, 1.0]内浮点数或正整数, 默认值=1.0*当设置为浮点数时,过滤出现在超过max_df/低于min_df⽐例的句⼦中的词语;正整数时,则是超过max_df句句
⼦。
这样就可以帮助我们过滤掉出现太多的⽆意义词语,如下⾯的"我"就被过滤(虽然这⾥“我”的排⽐在⽂学上是很重要的)。
# 过滤出现在超过60%的句⼦中的词语
tfidf_model3 = TfidfVectorizer(token_pattern=r"(?u)\b\w+\b", max_df=0.6).fit(document)
print(tfidf_model3.vocabulary_)
# {'是': 8, '⼀条': 1, '天狗': 5, '呀': 4, '⽉': 9, '来': 10, '⽇来': 6, '⼀切': 0, '的': 11, '星球': 7, '全宇宙': 3, '便是': 2}
2. stop_words: *list类型*直接过滤指定的停⽤词。
tfidf_model4 = TfidfVectorizer(token_pattern=r"(?u)\b\w+\b", max_df=0.6, stop_words=["是", "的"]).fit(document)
print(tfidf_model4.vocabulary_)
# {'⼀条': 1, '天狗': 5, '呀': 4, '⽉': 8, '来': 9, '⽇来': 6, '⼀切': 0, '星球': 7, '全宇宙': 3, '便是': 2}
3. vocabulary: dict*类型*
只使⽤特定的词汇,其形式与上⾯看到的tfidf_model4.vocabulary_相同,也是指定对应关系。
这⼀参数的使⽤有时能帮助我们专注于⼀些词语,⽐如我对本诗中表达感情的⼀些特定词语(甚⾄标点符号)感兴趣,就可以设定这⼀参数,只考虑他们:
tfidf_model5 = TfidfVectorizer(token_pattern=r"(?u)\b\w+\b",vocabulary={"我":0, "呀":1,"!":2}).fit(document)
print(tfidf_model5.vocabulary_)
# {'我': 0, '呀': 1, '!': 2}
print(tfidf_model5.transform(document).todense())
# [[ 0.40572238 0.91399636 0. ]
# [ 1. 0. 0. ]
# [ 1. 0. 0. ]
# [ 1. 0. 0. ]
# [ 1. 0. 0. ]
4. ngram_range: tuple
有时候我们觉得单个的词语作为特征还不⾜够,能够加⼊⼀些词组更好,就可以设置这个参数,如下⾯允许词表使⽤1个词语,或者2个词语的组合:
这⾥顺便使⽤了⼀个⽅便的⽅法 get_feature_names() ,可以以列表的形式得到所有的词语
tfidf_model5 = TfidfVectorizer(token_pattern=r"(?u)\b\w+\b", ngram_range=(1,2), stop_words=["是", "的"]).fit(document)
print(tfidf_model5.get_feature_names())
"""
['⼀切', '⼀切星球', '⼀条', '⼀条天狗', '了', '便是', '便是我', '全宇宙', '全宇宙来', '吞', '吞了', '呀', '天狗', '天狗呀', '我', '我⼀条', '我了', '我便是', '我把', '把', '把⼀切', '把全宇宙', '把⽇来', '把⽉', '⽇来', '⽇来吞', '星球', '星球来', '⽉', '⽉来', '来', '来吞"""
5. max_feature: int
在⼤规模语料上训练TFIDF会得到⾮常多的词语,如果再使⽤了上⼀个设置加⼊了词组,那么我们词表的⼤⼩就会爆炸。
出于时间和空间效率的考虑,可以限制最多使⽤多
少个词语,模型会优先选取词频⾼的词语留下。
下⾯限制最多使⽤10个词语:
tfidf_model6 = TfidfVectorizer(token_pattern=r"(?u)\b\w+\b", max_features=10, ngram_range=(1,2), stop_words=["是", "的"]).fit(document)
print(tfidf_model6.vocabulary_)
"""
{'我': 3, '把': 5, '来': 8, '吞': 1, '了': 0, '我把': 4, '来吞': 9, '吞了': 2, '⽇来吞': 6, '星球': 7}
"""
⽐如这⾥⼤部分的词组都被过滤了,但是“我把”因为多次出现⽽保留了。
参考博客:。