赞
踩
通过计算所提供的数据库中的金庸小说的信息熵,熟悉自然语言处理的方法与过程。
1948年,为了解决信息量化的问题,香农从热力学中借用了热熵的概念提出了“信息熵”的概念,把信息中排除了冗余后的平均信息量称为“信息熵”,并给出了计算信息熵的数学表达式。
H
(
X
)
=
∑
x
∈
χ
p
(
x
)
l
o
g
p
(
x
)
H(X)=\sum_{x∈χ} p(x)logp(x)
H(X)=x∈χ∑p(x)logp(x)
信息论之父克劳德·香农给出的信息熵的三个性质[1]:
jieba.cut
方法接受三个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 HMM 模型jieba.cut_for_search
方法接受两个参数:需要分词的字符串;是否使用 HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细jieba.cut
以及 jieba.cut_for_search
返回的结构都是一个可迭代的 generator,可以使用 for 循环来获得分词后得到的每一个词语(unicode),或者用jieba.lcut
以及 jieba.lcut_for_search
直接返回 listjieba.Tokenizer(dictionary=DEFAULT_DICT)
新建自定义分词器,可用于同时使用不同词典。jieba.dt
为默认分词器,所有全局分词相关函数都是该分词器的映射载入辞典
dict.txt
一样,一个词占一行;每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。file_name
若为路径或二进制方式打开的文件,则文件必须为 UTF-8 编码。调整词典
add_word(word, freq=None, tag=None)
和 del_word(word)
可在程序中动态修改词典。suggest_freq(segment, tune=True)
可调节单个词语的词频,使其能(或不能)被分出来。基于 TF-IDF 算法的关键词抽取
import jieba.analyse
数据集大小,size: 5457833
信息熵:12.144266718132455
分词结果:
‘只得’, ‘罢了’, ‘好’, ‘在’, ‘双儿’, ‘为’, ‘人’, ‘温柔’, ‘谦和’, ‘和’, ‘六位’, ‘夫人’, ‘个个’, ‘情谊’, ‘甚好’, ‘大家’, ‘也’, ‘不’, ‘妒嫉’, ‘于’, ‘她’, ‘只’, ‘建宁’, ‘建宁公主’, ‘宁公主’, ‘公主’, ‘自忖’, ‘以’, ‘皇上’, ‘御’, ‘妹’, ‘的’, ‘身分’, ‘分金’, ‘金枝’, ‘金枝玉叶’, ‘玉叶’, ‘居然’, ‘还’, ‘及’, ‘不’, ‘上’, ‘一个’, ‘出身’, ‘微贱’, ‘的’, ‘小丫头’, ‘丫头’, ‘心中’, ‘着实’, ‘气恼’, ‘不过’, ‘七位’, ‘夫人’, ‘人平’, ‘平时’, ‘若’, ‘有’, ‘纷争’, ‘其余’, ‘六’, ‘人’, ‘一定’, ‘联盟’, ‘对付’, ‘公主’, ‘建宁’, ‘建宁公主’, ‘宁公主’, ‘公主’, ‘主人’, ‘孤’, ‘势’, ‘单’, ‘韦小’, ‘韦小宝’, ‘小宝’, ‘又’, ‘不对’, ‘她’, ‘回护’, ‘近年’, ‘近年来’, ‘年来’, ‘来气’, ‘气焰’, ‘已’, ‘大为’, ‘收敛’, ‘轻易’, ‘不敢’, ‘启’, ‘次日’, ‘韦小’, ‘韦小宝’, ‘小宝’, ‘命’, ‘双儿’, ‘取出’, ‘郑克’, ‘当年’, ‘在’, ‘通吃岛’, ‘岛上’, ‘血书’, ‘的’, ‘借据’, ‘请’, ‘了’, ‘多隆’, ‘来’, ‘交给’, ‘了’, ‘他’, ‘多隆’, ‘大喜’, ‘说道’, ‘既有’, ‘亲笔’, ‘借据’, ‘咱们’, ‘石头’, ‘头里’, ‘也’, ‘要’, ‘榨出’, ‘他’, ‘油’, ‘来’,
上面随机节选了部分分词结果,整体效果还好,但也有诸如“人平”、“来气”、“通吃岛”、“韦小”等效果很差的分词。
下面是计算词频(TF)、逆文本频率指数(IDF)的结果
白马 8.844901865223905 啸 8.924944572897441 西风 9.618091753457387 碧血 9.618091753457387 碧血剑 10.311238934017332 飞狐 19.236183506914774 外传 8.70180102158323 连城 9.330409681005605 连城诀 10.311238934017332 鹿鼎记 10.02355686156555 三十 8.519479464789276 三十三 9.01195594988707 十三 8.576637878629224 三剑客 10.311238934017332 剑客 9.330409681005605 图 8.63726250044566 射雕 9.463941073630128 英雄 8.519479464789276 英雄传 10.02355686156555 传神 10.02355686156555 神雕侠侣 9.618091753457387 侠侣 9.618091753457387 书剑 9.618091753457387 恩仇 9.01195594988707 恩仇录 9.800413310251342 天龙 9.330409681005605 天龙八部 10.02355686156555 八部 9.800413310251342 侠客 9.330409681005605 侠客行 10.311238934017332 笑傲 9.618091753457387 笑傲江湖 10.02355686156555 傲江湖 10.02355686156555 江湖 8.576637878629224 雪山 8.844901865223905 雪山飞狐 10.02355686156555 倚天 9.618091753457387 天屠龙 9.800413310251342 屠龙 9.463941073630128 屠龙记 9.800413310251342 鸳鸯 8.770793893070183 鸳鸯刀 9.800413310251342 越女剑 9.463941073630128
`
import os import time import jieba import re from math import log # 1、递归读取文件 # 2、读取到文件,文件内容转换成文本,使用jieba进行分词 class TraversalFun(): # 1 初始化 def __init__(self, rootDir): self.rootDir = rootDir def TraversalDir(self): return TraversalFun.getCorpus(self, self.rootDir) def getCorpus(self, rootDir): corpus = [] r1 = u'[a-zA-Z0-9’!"#$%&\'()*+,-./::;<=>?@,。?★、…【】《》?“”‘’![\\]^_`{|}~]+' # 用户也可以在此进行自定义过滤字符 listdir = os.listdir(rootDir) for file in listdir: path = os.path.join(rootDir, file) if os.path.isfile(path): # 打印文件地址 #print(os.path.abspath(path)) # 获取文章内容,fromfile主要用来处理数组 pass # filecontext = np.fromfile(os.path.abspath(path)) with open(os.path.abspath(path), "r", encoding='ANSI') as file: filecontext = file.read(); #print(filecontext) # 分词 去掉符号 filecontext = re.sub(r1, '', filecontext) filecontext = filecontext.replace("\n", '') filecontext = filecontext.replace(" ", '') seg_list = jieba.cut(filecontext, cut_all=True) corpus += seg_list #print(seg_list) #print("[精确模式]:" + "/".join(seg_list)) elif os.path.isdir(path): TraversalFun.AllFiles(self, path) return corpus #构造词典,统计每个词的频率,并计算信息熵 def calc_tf(corpus): # 统计每个词出现的频率 word_freq_dict = dict() for word in corpus: if word not in word_freq_dict: word_freq_dict[word] = 1 word_freq_dict[word] += 1 # 将这个词典中的词,按照出现次数排序,出现次数越高,排序越靠前 word_freq_dict = sorted(word_freq_dict.items(), key=lambda x:x[1], reverse=True) # 计算TF概率 word_tf = dict() # 信息熵 shannoEnt = 0.0 # 按照频率,从高到低,开始遍历,并未每个词构造一个id for word, freq in word_freq_dict: # 计算p(xi) prob = freq / len(corpus) word_tf[word] = prob shannoEnt -= prob*log(prob, 2) return word_tf, shannoEnt if __name__ == "__main__": startTime = time.time() tra = TraversalFun("./2") corpus = tra.TraversalDir() print("数据集大小,size: " + str(len(corpus))) print(corpus) word_tf, shannoEnt = calc_tf(corpus) print("信息熵:" + str(shannoEnt)) #print("TF: ") #print(word_tf) endTime = time.time() print("\ntotal cost time(s)", (endTime-startTime), 's')
`
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。