基于tf_idf思想的文本特征词提取 实践

tf_idf的假设是:一个词语在一篇文章中出现次数越多, 同时在所有文档中出现次数越少, 越能够代表该文章.

因为想知道文章的主题,说的内容,查看他包含的名词就好,所以接下来我们就需要根据tf_idf的思想从文章包含的众多名词中,提取出能够表征其内容的几个名次。

tf_idf 涉及到两个统计量,一个是词语在本文章中出现的次数,简称词频,一个是在所有文章里面出现的次数,以下简称词文量。

下面分别统计这两个统计量的分布特性

从某网站抓取文章5641度篇,作为我们分析的一个样本。

查看其包含的词频分布,比如第一条数据,解释为 同花顺在一篇文章中出现3次,像这样的单词有18102个, 如果是绘图的话。可以很清晰的看出,类似于负指数分布曲线,随着出现次数增加骤降,几乎没有词语在同一篇文章中出现超过60词。

3     18102
4      8229
5      4387
6      2609
7      1578
8      1137
9       822
10      600
11      433
12      371

如果对单个单词出现在所有的文章的这个数据的分布进行统计,则绝大多数单词的词文量,也就是出现在的文章数,为100多。把这些数据 导出到文件里面看的话,会发现,词文量大于200的,大部分都是一些表征性不是很强的单词,其实也很好理解,就是一个单词,几乎一半的文章都用它,那肯定是一个很常见普遍没什么表征性的单词,比如 “市场 ”,“行业”,“投资”,都是没有用的单词,但是如果看词文量为个位数的单词,很多都是一些分词错误的,比如,查看的数据里面,有前房,中用,大险 等,都是切词错误导致的。当然,也有表征性很强的一些单词,比如人名,盖茨,项俊波等等。

那提出一个问题,如何计算一个单词在文章之中的表征能力呢?

第一次的尝试是 使用 (表征值 = 词频 / 词文量) 然后通过对表征值排序,得到每篇文章里面的表征值top N,计算方式很简单,也符合 tf_idf的思想,第一眼看上去,感觉也不错,很多文章,通过这几个词语,就能猜到大概在描述什么。仔细分析数据,发现其实是有缺陷的,这种算法过于倾向 那种在使用频率极低的词语,比如 前房,它其实是“目前房地产市场” 分词错误导致的,在其他文字中出现频率极低,但是本文中出现一两次,就导致表征值很高,而相对通用的词,真正希望出现的词“房地产”,则因为在多达 几十篇文章中被用到,而权重很低。

第二次的表征值时候,就倾向于 得到 词文量 为  0.05 * 总文章数 的单词,这样的单词被合理的引用到,并没有过度泛滥,也不太可能被是分词错误导致的,能够比较合理的反应文章主题,而引用次数超过0.1 * 总文章数的单词,则被视为泛滥,无表征意义而直接拒绝。这里使用一个 函数  np.sin( 被引用文章数 / (0.1 * 总文章数) * np.pi ), 这样的话,0.05 * 总文章数附近的单词能够得到相应大的权重,而相对更远的单词,得到的权重更小。

考虑另一个变量,词频,我们还是希望能得到在文章出反复提及的词,可能比较合适的表征 文章的中心,但是又需要做到归一化,具体的方案为 自身相对词频 = 提及数 / (该单词被用到的平均值),应该能够反映 该单词在文章内 使用的 频繁程度。

两个系数相乘,则为该单词在此文章内的表征值,对表征值排序。提取top N

就实测而言, 以这篇文章为例,进行分词分析  房地产行业周度报告:年末将至‚市场观望情绪明显

房	0.01	0.91
商品房	0.05	0.50
场主	0.06	0.87
均值	0.08	0.70
大事	0.10	0.95
对冲	0.03	0.81
底价	0.04	0.88
开发商	0.03	0.68
总价	0.02	0.85
成交量	0.11	1.94
房地产	0.23	1.26
房市	0.01	1.53
房市场	0.01	0.79
新政	0.07	0.68
本周一	0.02	1.77

按照上述算法得到的结果,其中房地产 的 两项指标 为0.23和1.26 ,均为结果的各项之首,作为一篇将房地产市场的文章,这样的分析结果是非常合理的,第二项为成交量,则可以看出 跟房地产的成交量有关,至于 词频得分很高的 本周一,则因为 词文量意向得分低 而总分低。

不过 仔细检查结果而言,还是不够好,筛选出来的大量的词都是只在文章中出现一次,并不能很好的反映文章自身的特征,刚刚的权重得来的重要性排行,第二列为出现的词频,可以看到,按照这种权重设计,得到的还是很多对本文特征表现不是很好的词。因为 出现一次的词的分布是负指数分布,所以相对来说,出现2词以上的词,能更清晰的反映文章的主旨,

上证		1	0.19	0.28	0.69	 1 	 47 	5242	j
中小		1	0.17	0.23	0.73	 1 	 47 	5242	j
上证指数		1	0.12	0.12	0.96	 1 	 47 	5242	n
要闻		1	0.12	0.12	1.00	 1 	 47 	5242	n
纺织		4	0.10	0.11	0.95	 4 	 47 	5242	n
棉花		4	0.09	0.04	2.07	 4 	 47 	5242	n
事业		1	0.09	0.16	0.55	 1 	 47 	5242	n
实业		1	0.08	0.12	0.67	 1 	 47 	5242	n
对公		1	0.08	0.09	0.90	 1 	 47 	5242	n
效益		1	0.08	0.09	0.86	 1 	 47 	5242	n
关注度		1	0.07	0.08	0.92	 1 	 47 	5242	n
全资		1	0.07	0.09	0.74	 1 	 47 	5242	n
大众		1	0.07	0.11	0.66	 1 	 47 	5242	n
个人		1	0.06	0.12	0.54	 1 	 47 	5242	n
责任		1	0.06	0.08	0.74	 1 	 47 	5242	n
收益率		1	0.06	0.12	0.47	 1 	 47 	5242	n
集资		1	0.06	0.08	0.72	 1 	 47 	5242	n
实施方案		1	0.05	0.06	0.81	 1 	 47 	5242	n
织品		2	0.05	0.04	1.19	 2 	 47 	5242	n

这里提出一个设想,就是 在同一个文章内出现的次数越多的单词,越能够体现文章的主题。但是又必须跟 词文量结合起来,避免出现多普遍出现多的单词。所以新的权重公式应该为:权重 = np.sin( 被引用文章数 / (0.1 * 总文章数) * np.pi ) * 自身相对词频 * np.exp(词频 * 0.5), 相比于之前的权重公式 区别仅在于 增加了np.exp(词频 * 0.5),希望出现次数少的单词权重系数低,而出现超过3次以上的单词,出现频率高,0.5的意义在于避免指数过于迅速的上升,为避免过度倾向于本文内出现频率高的词,np.exp(词频 * 0.5)的词频最大值设为9个,np.ext(4.5) = 90 这样有一些无意义的单词出现,词文量 权值小于 0.01,也可以被及时中和过滤掉,而不会因为指数权重过大导致成为权重排行成为词频 倒排。
实测结果,刚刚相同的文章,得到的新的权重排行如下

纺织		4	0.75	0.11	7.05	 4 	 47 	5242	n
棉花		4	0.67	0.04	15.27	 4 	 47 	5242	n
上证		1	0.32	0.28	1.13	 1 	 47 	5242	j
中小		1	0.27	0.23	1.20	 1 	 47 	5242	j
上证指数		1	0.20	0.12	1.58	 1 	 47 	5242	n
同比		3	0.20	0.28	0.70	 3 	 47 	5242	n
要闻		1	0.19	0.12	1.64	 1 	 47 	5242	n
事业		1	0.14	0.16	0.91	 1 	 47 	5242	n
实业		1	0.13	0.12	1.10	 1 	 47 	5242	n
对公		1	0.13	0.09	1.48	 1 	 47 	5242	n

可以看出来,棉花 纺织的排行上升,而 相对普遍中庸的词 上证中小则 排名下降,而 上证, 中小的 自我相对系数很高,所以维持在了相对高位,可以看出,这篇文章和 棉纺织的证券市场有关    纺织服装行业:周报

Leave a comment

Your email address will not be published.

*