# encoding=utf-8

from __future__ import absolute_import

import os

import jieba

import jieba.posseg

from operator import itemgetter

_get_module_path = lambda path: os.path.normpath(os.path.join(os.getcwd(),

os.path.dirname(__file__), path))

#调用jieba/init.py中_get_abs_path 函数赋值给变量_get_abs_path

_get_abs_path = jieba._get_abs_path

DEFAULT_IDF = _get_module_path("idf.txt") #默认的逆文档频率文件路径

class KeywordExtractor(object):

#初始化的一个停用词典

STOP_WORDS = set((

"the", "of", "is", "and", "to", "in", "that", "we", "for", "an", "are",

"by", "be", "as", "on", "with", "can", "if", "from", "which", "you", "it",

"this", "then", "at", "have", "all", "not", "one", "has", "or", "that"

))

#设置自定义停用词

def set_stop_words(self, stop_words_path):

abs_path = _get_abs_path(stop_words_path) #获取自定义停用词路径

if not os.path.isfile(abs_path):

raise Exception("jieba: file does not exist: " + abs_path)

#文件存在,则读取文件内容,并添加到已有词典STOP_WORDS中

content = open(abs_path, 'rb').read().decode('utf-8')

for line in content.splitlines():

self.stop_words.add(line)

def extract_tags(self, *args, **kwargs):

raise NotImplementedError

#

class IDFLoader(object):

def __init__(self, idf_path=None):

self.path = ""

self.idf_freq = {}

self.median_idf = 0.0 #idf频率中位数

if idf_path:#是否自定义逆文档频率文件

self.set_new_path(idf_path)

#自定义逆文档频率文件 并计算idf频率中位数

def set_new_path(self, new_idf_path):

if self.path != new_idf_path:

self.path = new_idf_path

content = open(new_idf_path, 'rb').read().decode('utf-8') #读取文件

self.idf_freq = {} #初始化idf频率字典

"""

遍历idf文件每行数据,格式如下

word idf频率

劳动防护 13.900677652

生化学 13.900677652

奥萨贝尔 13.900677652

考察队员 13.900677652

"""

for line in content.splitlines():

# 每行按空格切分为词,及其idf频率

word, freq = line.strip().split(' ')

#构建key,value字典,key为word, value为idf频率

self.idf_freq[word] = float(freq)

"""

求逆词频中位数 整除法,

sorted(self.idf_freq.values()),排序后是词频列表[13.900677652,13.900677653,.....]

然后用idf词频字典长度除以2求中位数索引

最后根据索引求词频列表中位数

"""

self.median_idf = sorted(

self.idf_freq.values())[len(self.idf_freq) // 2]

#返回idf词频字典与idf词频中位数

def get_idf(self):

return self.idf_freq, self.median_idf

class TFIDF(KeywordExtractor):

def __init__(self, idf_path=None):

#jieba.dt是 jieba/init.py 文件中 class Tokenizer(object)类的实例化 jieba分词器类

self.tokenizer = jieba.dt

#jieba/posseg/init.py文件中 dt = POSTokenizer(jieba.dt)类的实例化 新建自定义分词器类

self.postokenizer = jieba.posseg.dt

#停用词字典的浅拷贝,随原始字典改变而改变

self.stop_words = self.STOP_WORDS.copy()

#初始化IDFLoader类 自定义逆文档频率文件或选择默认逆文档频率文件

self.idf_loader = IDFLoader(idf_path or DEFAULT_IDF)

#获取idf词频字典与idf词频中位数

self.idf_freq, self.median_idf = self.idf_loader.get_idf()

#用户调用函数 自定义逆文档频率文件

def set_idf_path(self, idf_path):

new_abs_path = _get_abs_path(idf_path)

if not os.path.isfile(new_abs_path):

raise Exception("jieba: file does not exist: " + new_abs_path)

self.idf_loader.set_new_path(new_abs_path)

self.idf_freq, self.median_idf = self.idf_loader.get_idf()

"""

使用tf-idf算法提取关键词函数

sentence:文本

topk: int类型 返回关键词数量(按idf频率最高返回吗???)

withweight: bool类型 如果true返回词权重列表(word, weight); false只返回词列表

allowPOS:自定义词性列表,不在该词性列表中的词被过滤

withFlag:定义了allowPOS词性列表后才有效,如果true返回词权重列表 word/权重 idf

设置了allowpos 与不设置allowpos 权重不一样??有些词被过滤的原因吗

eg:

sentence = ‘此外,公司拟对全资子公司吉林欧亚置业有限公司增资4.3亿元,增资后,吉林欧亚置业注册资本由7000万元增加到5亿元。

吉林欧亚置业主要经营范围为房地产开发及百货零售等业务。目前在建吉林欧亚城>市商业综合体项目。2013年,实现营业收入0万元,实现净利润-139.13万元。’

a = ['ns', 'n', 'vn', 'v','nr']

参数选择 allowPOS=a,withWeight=True,withFlag=True

欧亚/ns 1.0397172936775758

吉林/ns 0.9386301413806061

置业/n 0.6960464319372728

增资/v 0.47829481615333336

实现/v 0.2834381985812121

参数选择 withWeight=True

欧亚 0.7458841454643479

吉林 0.6733651014252174

置业 0.49933765769413047

万元 0.3466477318421739

增资 0.3431245420230435

参数选择 allowPOS=a,withWeight=True

欧亚 1.0397172936775758

吉林 0.9386301413806061

置业 0.6960464319372728

增资 0.47829481615333336

实现 0.2834381985812121

"""

def extract_tags(self, sentence, topK=20, withWeight=False, allowPOS=(), withFlag=False):

"""

Extract keywords from sentence using TF-IDF algorithm. 使用tf-idf算法提取关键词

Parameter:

- topK: return how many top keywords. `None` for all possible words.

- withWeight: if True, return a list of (word, weight);

if False, return a list of words.

- allowPOS: the allowed POS list eg. ['ns', 'n', 'vn', 'v','nr'].

if the POS of w is not in this list,it will be filtered.

- withFlag: only work with allowPOS is not empty.

if True, return a list of pair(word, weight) like posseg.cut

if False, return a list of words

"""

#如果选择自定义词性列表 返回words

if allowPOS:

allowPOS = frozenset(allowPOS) #frozenset 创建不可变词性集合

words = self.postokenizer.cut(sentence) #使用自定义分词器 dt = POSTokenizer(jieba.dt) jieba/posseg/init.py文件中

else:

words = self.tokenizer.cut(sentence) #否则使用jieba默认分词器

#初始化一个保存单词与词数的字典

freq = {}

#获取分词后的列表,遍历

# 如果设置allowPOS 分词后返回值类似这样[(pair('欧亚','ns'),1.0333333),........]

# pair格式 pair(flag:'ns','word','欧亚')

# 没设置allowPOS 不会返回词性flag

for w in words:

if allowPOS:

#过滤词,只需要自定义指定词性的词,

#如果该词词性不在自定义词性列表中,继续for循环,

if w.flag not in allowPOS:

continue

#如果没有withFlag,只保留词w.word

elif not withFlag:

w = w.word

#如果设置allowPOSand and withFlag获取w.word eg:pair(flag:'ns','word','欧亚')

#否则只获取词

#反正最终统计词数只需要词就行

wc = w.word if allowPOS and withFlag else w

#过滤一个字的词,以及停用词

if len(wc.strip()) < 2 or wc.lower() in self.stop_words:

continue

#利用dict字典累计,统计词数 eg{'a': 1.0}

freq[w] = freq.get(w, 0.0) + 1.0

#计算总的词数

total = sum(freq.values())

#遍历获取字典的键

for k in freq:

#如果withFlag了 并且设置了词性列表allowPOS 只返回单词

kw = k.word if allowPOS and withFlag else k

#这里idf是已经算好的,在加载的逆文档频率文件中 eg:默认的idf.txt

#计算权重算法:(freq[k] 词数) * (self.idf_freq.get(kw, self.median_idf) 词idf) / total文章总词数

freq[k] *= self.idf_freq.get(kw, self.median_idf) / total

if withWeight:

#按权重值 并从大到小排序 返回 eg: 公司/n 1.1678233145266665

tags = sorted(freq.items(), key=itemgetter(1), reverse=True)

else:

#没设置withWeight 则不返回权重值 eg :公司 n

tags = sorted(freq, key=freq.__getitem__, reverse=True)

if topK:

#返回权重最大的前几个词

return tags[:topK]

else:

return tags

tfidf处理代码_解霸源代码学习——用TF-IDF方法计算词权,jieba,源码,TFIDF,权重相关推荐

  1. 机器人编程python代码_自己动手开发智能聊天机器人完全指南(附python完整源码)...

    一.前言 人工智能时代,开发一款自己的智能问答机器人,一方面提升自己的AI能力,另一方面作为转型AI的实战练习.在此把学习过程记录下来,算是自己的笔记. 二.正文 2.1 下载pyaiml 下载pya ...

  2. java EE crm代码_基于jsp的小型企业CRM-JavaEE实现小型企业CRM - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的小型企业CRM, 该项目可用各类java课程设计大作业中, 小型企业CRM的系统架构分为前后台两部分, 最终实现在 ...

  3. 用python实现csdn博主全部博文下载,html转pdf,有了学习的电子书了。。。(附源码)

    用python实现csdn博主全部博文下载,html转pdf,有了学习的电子书了...(附源码) 我们学习编程,在学习的时候,会有想把有用的知识点保存下来,我们可以把知识点的内容爬下来转变成pdf格式 ...

  4. 【深度学习模型】智云视图中文车牌识别源码解析(二)

    [深度学习模型]智云视图中文车牌识别源码解析(二) 感受 HyperLPR可以识别多种中文车牌包括白牌,新能源车牌,使馆车牌,教练车牌,武警车牌等. 代码不可谓不混乱(别忘了这是职业公司的准产品级代码 ...

  5. jieba tfidf_【NLP】【三】jieba源码分析之关键字提取(TF-IDF/TextRank)

    [一]综述 利用jieba进行关键字提取时,有两种接口.一个基于TF-IDF算法,一个基于TextRank算法.TF-IDF算法,完全基于词频统计来计算词的权重,然后排序,在返回TopK个词作为关键字 ...

  6. 常用算法 之三 详解 SHA1 实现(基于算法的官方原文档)及源码详细注释

    写在前面   在之前的工作中,用到了CRC16.MD5 和 SHA1 算法,主要用来校验下发的文件.网上关于这些算法的文章铺天盖地,以下内容仅仅是自己在学习时候的一个记录,一些套话来自于互联网.下面先 ...

  7. 常用算法 之一 详解 MD5 实现(基于算法的官方原文档)及源码详细注释

    写在前面   在之前的工作中,用到了CRC16.MD5 和 SHA1 算法,主要用来校验下发的文件.网上关于这些算法的文章铺天盖地,以下内容仅仅是自己在学习时候的一个记录,一些套话来自于互联网.下面先 ...

  8. sheng的学习笔记-ConcurrentHashMap(JDK1.7和16)源码分析

    1.7版本 概述 注意,以下代码都是1.7版本(不同版本代码不一样),最下面有1.8版本部分内容 ConcurrentHashMap是线程安全的key value存储结构,底层也是数组+链表的结构 下 ...

  9. Slicer学习笔记(四十二)slicer c++源码编译

    Slicer学习笔记(四十二)slicer c++源码编译 1.cmake生成项目 2.编译失败的原因汇总 2.1.下载代码失败 之前在windows下编译slicer,没有做笔记. 后面再次编译还会 ...

最新文章

  1. ecshop transport.js/run() error:undefined
  2. [每日一题] 11gOCP 1z0-053 :2013-09-29 Flashback Data Archive ...................................6...
  3. 【HTML5】标记文字
  4. 10个月产品演化之路-快速试错,快速反应,探索产品成功之道
  5. windows编写linux脚本,Windows PowerShell:共享您的脚本 - 在脚本中编写 Cmdlet | Microsoft Docs...
  6. OXite解读(1)----- 概述
  7. HYSBZ - 2160 拉拉队排练(回文自动机)
  8. 汇编语言中常见的标志位: CF, PF, AF, ZF, SF,TF,IF,DF, OF
  9. 给你的博客换个装-园子换装指南
  10. Docker Compose运行MySQL、Redis服务
  11. Java关系表达式x y,java8--函数式接口,以及和Lambda表达式的关系
  12. 在二维码中间添加logo或者图片
  13. leetcode刷题笔记(1-10)持续更新中
  14. 4宫格 android,四宫格拼图软件
  15. server2003服务器安全攻略
  16. 解决AppUpdate不能使用的问题
  17. 机器学习笔试面试题目 二
  18. 缓存Cache-Control
  19. Landesk学习笔记1_Landesk三种拖送方式
  20. 如何使用 Podman 签署和分发容器镜像

热门文章

  1. 4. Flume和Kafka连通测试
  2. linux快捷键(mac版)
  3. IDEA连接数据库时报错org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection
  4. python程序输出日历
  5. 动图图解GC算法 - 让垃圾回收动起来
  6. fmx 获取全局消息之消息传递
  7. Linux内核之旅/张凯捷——系统调用分析(2)
  8. Windows Socket select函数使用
  9. oppok7x可以用鸿蒙系统吗,超能续航!用上OPPO K7x后,终于跟充电宝说拜拜了
  10. 粗略使用.NetCore2.0自带授权登陆Authorize