一种过滤权重数据的方法

说明:本文是对我的一个小程序 DEVONthink-Chinese-Search 中的一个关键函数做的总结。

摘要:在结巴分词中,提取出的关键词是没有阈值的(但是对提取数量可以有限制,不在本文讨论之列),也就是对整段输入文本中的关键词进行降序排列,这就有一个问题,是根据经验给定一个阈值实现过滤还是找一种能描述整体变化趋势的方法去求每一种的阈值。本文通过求不精确的导数值来评估其变化趋势从而实现对当前文本的关键词阈值的设置。

选择这篇文章进行测试 《梁思成林徽因寻访古建筑之旅:知我者谓我心忧》 利用结巴分词对其提取关键词,并绘制权重的变化曲线,可以看到有明显的下降趋势:

权重曲线

而如果绘制散点图,则能看到除极少部分点,其余点的权重值几乎没有变化,是很平稳的。只有那少数的点才是我们需要的高价值关键词

我想到有两种方法进行过滤。

一种是根据其分布规律,算出高价值关键词所占百分比,通过确定相应百分比的最低权重值进行过滤。

另一种则通过对求权重曲线的导数,当导数值接近0时,也就是曲线进入右端相当平滑的那部分时,求出相应的权重值进行顾虑。

方法一有些复杂,方法二如果真的去拟合曲线,求导,那么程序的运行时间将会有些不可接受。所以我采用了每隔3个点,求一次两点间斜率作为那一段的导数值。这样还能绕开【散点图局部】中,[9, 10] 区间里,那段斜率接近于0的部分。对于更多的曲折不平的曲线,也可以有较好的适应能力

文章绘制散点图的代码示例

import jieba.analyse
import pyperclip

content = str(pyperclip.paste())
text_length = len(content)
words_num_max = int(text_length/2)

keywords = jieba.analyse.extract_tags(content, topK=words_num_max, withWeight=True, allowPOS=( ))

weights = len(keywords)*['']
for i, item in enumerate(keywords):
    weights[i] = item[1]

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']

plt.scatter(range(len(weights)),weights)
plt.xlabel('numbers of *keywords*')
plt.ylabel('weights')
plt.title(u'散点图')
plt.show()
Comments
Write a Comment