tfidf关键词提取php,TFIDF介绍

简介全称: Term Frequency-inverse document frequency(文本频率与逆文档频率指数)

目的: 表征一个token(可以是一个字或者一个词)的重要程度

是ElasticSearch的评分算法

TF - 如果该token出现的频率很高, 且不是常用连接词或语气词, 那么该词的重要程度就更高。

如果该词是常用连接词或语气词, 那该词即使出现很多次也不是很重要。为了处理该种情况, 出现了逆文档频率指数(idf)。

逆文档评率指数(idf)公式: log(所有的文档条数/有这个词的文档条数) => 这个词尽可能的只在某几条文档中出现过, 那样才更有区分性。

举个小栗子:(a, b, c, d, e) 五个词, 所有词汇总数是5,若词d出现了1次, 那么其tf=1/5

若文档总数为4条, d的idf=log(4/1), 实际操作中会加入平滑因子, 防止统计数为0出现。

该词d的权重为 tf * idf = 1/5 * log(4 / 1)对每个词都做一下这样的计算,最后得到的是一个样品数量 * 唯一token总数维度的矩阵,在例子中样本数量为3,唯一token总数为5,那么我们会得到一个3*5的矩阵,如果这一条文档中没有这个词就直接赋值0就可以了。

使用python调numpy库实现#!/usr/bin/env python

# encoding: utf-8

import numpy as np

class TFIDF(object):

"""TFIDF简单实现"""

def __init__(self, corpus):

self.word_id = {}

self.vocabulary_count = {}

self.corpus = corpus

self.smooth_idf = 0.01

def fit_transform(self, corpus):

pass

def get_vocabulary_frequency(self):

"""

计算文本特征的出现次数, 返回self.vocabulary_count

"""

# 统计各词出现个数

id = 0

for single_corpus in self.corpus:

# 判断单个corpus是否为list类型

if isinstance(single_corpus, list):

pass

# 判断是否为string类型

if isinstance(single_corpus, str):

# 去除换行符, 再按空格分开, 返回的应该是一个list

single_corpus = single_corpus.strip("\n").split(" ")

for word in single_corpus:

# 如果该词不在词汇统计表的key中

if word not in self.vocabulary_count:

# 将该词放入到词汇统计表及词汇编码表中

self.vocabulary_count[word] = 1

self.word_id[word] = id

id += 1

else:

# 如果已经在了, 词频统计加一就ok

self.vocabulary_count[word] += 1

# 生成corpus长度 X 词频统计表长度的全零矩阵

X = np.zeros((len(self.corpus), len(self.vocabulary_count)))

for i in range(len(self.corpus)):

# 如果是string类型, 就去换行符并分割

if isinstance(self.corpus[i], str):

single_corpus = self.corpus[i].strip("\n").split(" ")

else:

single_corpus = self.corpus[i]

# 遍历单个single_corpus

for j in range(len(single_corpus)):

# 获取特征值和特征id, 并将他们放入矩阵对应的位置上

feature = single_corpus[j]

feature_id = self.word_id[feature]

X[i, feature_id] = self.vocabulary_count[feature]

return X.astype(int) # 需要转为int

def get_tf_tdf(self):

"""

计算idf并生成最后的TFIDF矩阵

"""

X = self.get_vocabulary_frequency()

num_samples, n_features = X.shape

df = []

for i in range(n_features):

# 统计每个特征的非0的数量,也就是逆文档频率指数的分式中的分母,是为了计算idf

# bincount: 传入一个数组, 返回对应索引出现的次数的数组(大致可以这么理解)

df.append(num_samples - np.bincount(X[:,i])[0])

df = np.array(df)

# 是否需要添加平滑因子

df += int(self.smooth_idf)

num_samples += int(self.smooth_idf)

idf = np.log(num_samples / df) + 1 # 核心公式

return X*idf/len(self.vocabulary_count)

if __name__ == '__main__':

corpus = [["此", "生", "不", "换"],["此", "情", "此", "景"],["不", "蔓", "不", "枝"]]

test = TFIDF(corpus)

print(test.get_tf_tdf())

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值