前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >sklearn: TfidfVectorizer 中文处理及一些使用参数

sklearn: TfidfVectorizer 中文处理及一些使用参数

作者头像
blmoistawinde
发布2019-10-30 20:16:28
3K0
发布2019-10-30 20:16:28
举报

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/blmoistawinde/article/details/80816179

TfidfVectorizer可以把原始文本转化为tf-idf的特征矩阵,从而为后续的文本相似度计算,主题模型(如LSI),文本搜索排序等一系列应用奠定基础。基本应用如:

代码语言:javascript
复制
#coding=utf-8
from sklearn.feature_extraction.text import TfidfVectorizer
document = ["I have a pen.",
            "I have an apple."]
tfidf_model = TfidfVectorizer().fit(document)
sparse_result = tfidf_model.transform(document)     # 得到tf-idf矩阵,稀疏矩阵表示法
print(sparse_result)
# (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}

但是要把它运用到中文上还需要一些特别的处理,故写此文分享我的经验。

第一步:分词

中文不比英文,词语之间有着空格的自然分割,所以我们首先要进行分词处理,再把它转化为与上面的document类似的格式。这里采用著名的中文分词库jieba进行分词:

代码语言:javascript
复制
    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)
    # ['我 是 一条 天狗 呀 !', '我 把 月 来 吞 了 ,', '我 把 日来 吞 了 ,', '我 把 一切 的 星球 来 吞 了 ,', '我 把 全宇宙 来 吞 了 。', '我 便是 我 了 !']

PS:语料来自郭沫若《天狗》。另外,由于分词工具的不完善,也会有一些错误,比如这边错误地把"日来"分到了一起。

第二步:建模

理论上,现在得到的document的格式已经可以直接拿来训练了。让我们跑一下模型试试。

代码语言:javascript
复制
    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的单词在英文中一般是无足轻重的,但在中文里,就可能有一些很重要的单字词,所以修改如下:

代码语言:javascript
复制
    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句句子。

这样就可以帮助我们过滤掉出现太多的无意义词语,如下面的"我"就被过滤(虽然这里“我”的排比在文学上是很重要的)。

代码语言:javascript
复制
    # 过滤出现在超过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类型

直接过滤指定的停用词。

代码语言:javascript
复制
    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_相同,也是指定对应关系。

这一参数的使用有时能帮助我们专注于一些词语,比如我对本诗中表达感情的一些特定词语(甚至标点符号)感兴趣,就可以设定这一参数,只考虑他们:

代码语言:javascript
复制
    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.        ]
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-06-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档