diff --git a/README.md b/README.md index 14c74d6aa91eb437f4b3146e8e218425b53545d9..b0346e1e628f0bf31dc666398208b0daa21c7083 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,14 @@ * 入门只看: 步骤 1 => 2 => 3,你可以当大牛! * 中级补充 - 资料库: +> 补充 + +* 头条视频汇总: +* 算法刷题: +* 面试求职: +* 机器学习实战: +* NLP教学视频: + ## 1.机器学习 - 基础 ### 基本介绍 diff --git "a/docs/nlp/2.\345\210\206\350\257\215.md" "b/docs/nlp/2.\345\210\206\350\257\215.md" index 0d71de58e77f7d31b69a4e1086714e30aaa32dcc..93c7d11854ce7dfb88a804aa9fcd9b9aed80e849 100644 --- "a/docs/nlp/2.\345\210\206\350\257\215.md" +++ "b/docs/nlp/2.\345\210\206\350\257\215.md" @@ -235,11 +235,47 @@ print('/'.join(jieba.cut('「台中」正确应该不会被切开', HMM=False))) ## 关键词提取 -> 基于 TF-IDF 算法的关键词抽取 +### 基于 TF-IDF 算法的关键词抽取 + +* 基于该框架的 TF-IDF 效果一般 + * 1.它使用的是他默认的 IDF 值的文件【不是针对我们的项目】 + * 2.我们先得有词,你才能计算 IDF的值。而框架是要先提供IDF值才能计算最终的 TF-IDF 值。 +* 如果你有计算IDF的值存成文件,再加载进来,计算TF-IDF值,才能得到适合这个类型数据的值! + +> TF `优化点: 分子/分母 都加1` + +TF: term frequency 短期频率, 用于衡量一个词在一个文件中的出现频率。因为每个文档的长度的差别可以很大,因而一个词在某个文档中出现的次数可能远远大于另一个文档,所以词频通常就是一个词出现的次数除以文档的总长度,相当于是做了一次归一化。 + +公式: `TF(t) = (词t在某个文档中出现的总次数) / (某个文档的词总数)` + +> IDF `优化点: 分子/分母 都加1` + +IDF: inverse document frequency 逆向文件频率,用于衡量一个词的重要性/区分度。计算词频TF的时候,所有的词语都被当做一样重要的,但是某些词,比如”is”, “of”, “that”很可能出现很多很多次,但是可能根本并不重要,因此我们需要减轻在多个文档中都频繁出现的词的权重。 + +公式: `IDF = log_e(总文档数/词t出现的文档数)` + +> TF-IDF(term frequency–inverse document frequency) + +公式: `TF-IDF = TF*IDF` + +> 注意 + +`非常短的文本很可能影响 tf-idf 值` + +> 行业用途 + +``` +TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与文本挖掘的常用加权技术。 +TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。 +TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。 +除了TF-IDF以外,互联网上的搜索引擎还会使用基于连结分析的评级方法,以确定文件在搜寻结果中出现的顺序。 +``` + ```python import jieba.analyse +# allowPOS('ns', 'n', 'vn', 'v') 地名、名词、动名词、动词 tags = jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=()) """ * sentence 为待提取的文本 @@ -247,6 +283,8 @@ tags = jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS= * withWeight 为是否一并返回关键词权重值,默认值为 False * allowPOS 仅包括指定词性的词,默认值为空,即不筛选 * jieba.analyse.TFIDF(idf_path=None) 新建 TFIDF 实例,idf_path 为 IDF 频率文件 + # idf是jieba通过语料库统计得到的 + # idf的值时通过语料库统计得到的,所以,实际使用时,可能需要依据使用环境,替换为使用对应的语料库统计得到的idf值。 """ # 关键词提取所使用逆向文件频率(IDF)文本语料库可以切换成自定义语料库的路径 @@ -263,44 +301,129 @@ the of is """ -jieba.analyse.set_stop_words("../extra_dict/stop_words.txt") +jieba.analyse.set_stop_words("~/work/data/nlp/jieba/extra_dict/stop_words.txt") # 下载地址: https://raw.githubusercontent.com/fxsjy/jieba/master/extra_dict/idf.txt.big """格式如下: 劳动防护 13.900677652 勞動防護 13.900677652 奥萨贝尔 13.900677652 """ -jieba.analyse.set_idf_path("../extra_dict/idf.txt.big") -s = "此外,公司拟对全资子公司吉林欧亚置业有限公司增资4.3亿元,增资后,吉林欧亚置业注册资本由7000万元增加到5亿元。吉林欧亚置业主要经营范围为房地产开发及百货零售等业务。目前在建吉林欧亚城市商业综合体项目。2013年,实现营业收入0万元,实现净利润-139.13万元。" -for word, weight in jieba.analyse.extract_tags(s, withWeight=True): +jieba.analyse.set_idf_path("~/work/data/nlp/jieba/extra_dict/idf.txt.big") +content = "此外,公司拟对全资子公司吉林欧亚置业有限公司增资4.3亿元,增资后,吉林欧亚置业注册资本由7000万元增加到5亿元。吉林欧亚置业主要经营范围为房地产开发及百货零售等业务。目前在建吉林欧亚城市商业综合体项目。2013年,实现营业收入0万元,实现净利润-139.13万元。" +# content = open("~/work/data/nlp/jieba/extra_dict/test_content.txt", 'rb').read() +for word, weight in jieba.analyse.extract_tags(content, withWeight=True): print('%s %s' % (word, weight)) + +"""输出结果: +吉林 1.0174270215234043 +欧亚 0.7300142700289363 +增资 0.5087135107617021 +实现 0.5087135107617021 +置业 0.4887134522112766 +万元 0.3392722481859574 +此外 0.25435675538085106 +全资 0.25435675538085106 +有限公司 0.25435675538085106 +4.3 0.25435675538085106 +注册资本 0.25435675538085106 +7000 0.25435675538085106 +增加 0.25435675538085106 +主要 0.25435675538085106 +房地产 0.25435675538085106 +业务 0.25435675538085106 +目前 0.25435675538085106 +城市 0.25435675538085106 +综合体 0.25435675538085106 +2013 0.25435675538085106 +""" ``` -> 基于 TextRank 算法的关键词抽取 +### 基于 TextRank 算法的关键词抽取 -基本思想: +> 基本思想: 1. 将待抽取关键词的文本进行分词 2. 以固定窗口大小(默认为5,通过span属性调整),词之间的共现关系,构建图 3. 计算图中节点的PageRank,注意是无向带权图 +> 举例说明 + +```py +例如: sentence = "A B C A D B C B A" + +第一次 index = 0 +dict[(A, B)] = 2 +dict[(A, C)] = 1 +dict[(A, A)] = 1 +dict[(A, D)] = 2 + +第一次 index = 1 +dict[(B, A)] = 3 +dict[(B, B)] = 1 +dict[(B, C)] = 2 +dict[(B, D)] = 1 + +由于是 无向带权图 + +graph[start].append((start, end, weight)) +graph[end].append((end, start, weight)) + +假设: +A B => 20 +所有 B => 50 +A, C => 5 +所有 C => 15 +总共: 10个单词 +A 权重PR值: 1/10 = 0.1 +s_A = 20/50) * 0.1 + 5/15 * 0.1 +d阻尼系数,即按照超链接进行浏览的概率,一般取经验值为0.85 +1−d浏览者随机跳转到一个新网页的概率 +A 权重PR值: (1 - d) + d * s_A +``` + +> 代码案例 ```python # encoding=utf-8 import jieba -# 直接使用,接口相同,注意默认过滤词性。 +# 直接使用,接口相同,注意默认过滤词性。 +# allowPOS('ns', 'n', 'vn', 'v') 地名、名词、动名词、动词 jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) # 新建自定义 TextRank 实例 jieba.analyse.TextRank() # 测试案例 -s = "此外,公司拟对全资子公司吉林欧亚置业有限公司增资4.3亿元,增资后,吉林欧亚置业注册资本由7000万元增加到5亿元。吉林欧亚置业主要经营范围为房地产开发及百货零售等业务。目前在建吉林欧亚城市商业综合体项目。2013年,实现营业收入0万元,实现净利润-139.13万元。" -for x, w in jieba.analyse.textrank(s, withWeight=True): +content = "此外,公司拟对全资子公司吉林欧亚置业有限公司增资4.3亿元,增资后,吉林欧亚置业注册资本由7000万元增加到5亿元。吉林欧亚置业主要经营范围为房地产开发及百货零售等业务。目前在建吉林欧亚城市商业综合体项目。2013年,实现营业收入0万元,实现净利润-139.13万元。" +# content = open("~/work/data/nlp/jieba/extra_dict/test_content.txt", 'rb').read() +for x, w in jieba.analyse.textrank(content, withWeight=True): print('%s %s' % (x, w)) +""" +吉林 1.0 +欧亚 0.9966893354178172 +置业 0.6434360313092776 +实现 0.5898606692859626 +收入 0.43677859947991454 +增资 0.4099900531283276 +子公司 0.35678295947672795 +城市 0.34971383667403655 +商业 0.34817220716026936 +业务 0.3092230992619838 +在建 0.3077929164033088 +营业 0.3035777049319588 +全资 0.303540981053475 +综合体 0.29580869172394825 +注册资本 0.29000519464085045 +有限公司 0.2807830798576574 +零售 0.27883620861218145 +百货 0.2781657628445476 +开发 0.2693488779295851 +经营范围 0.2642762173558316 +""" ``` + ## 词性标注 * `jieba.posseg.POSTokenizer(tokenizer=None)` 新建自定义分词器, tokenizer 参数可指定内部使用的 `jieba.Tokenizer` 分词器, `jieba.posseg.dt` 为默认词性标注分词器