(四)tf-idf算法
参考文档:机器学习:生动理解TF-IDF算法
1、tf-idf算法基本概念
tf
:词频idf
:逆文本频率指数
(1)引子
- 引子:百度通过什么了解抓取到的网页在讲什么?
- 外链的投票:通过外链中对该网页的描述判断
- 网页内容与布局:通过网页内容文字和布局判断(
tf-idf
算法就是在该方法中使用)
- 思考1:光获取到文字内容又如何让百度理解
- 通过
tf(词频)
判断,如果一个词的词频过高,那么这段内容的基本上都是在讲述该词。
- 通过
- 思考2:一篇文章中出现最多的词往往是停顿词,如“的”,“是”,“了”等对判断结果毫无意义的词,如何过滤这些词?
- 通过
tf(词频)
统计这些停用词并过滤,当高频词过滤后只剩下需要考虑判断的有实际意义的词。
- 通过
- 思考3:如果“词A”“词B”“词C”的出现次数一样,那对于百度来说,这三个词是否同样重要?
- 通过
idf(逆文档频率)
判断,IDF会给常见词较少的权重,该值的大小与词的常见长度成反比
- 通过
- 思考4:什么样的位置中的文字是最重要的?
- 存在于
<title>
、<h1>
、<h2>
、<h3>
、<h4>
、<h5>
、<h6>
、<strong>
、<em>
之中
扩展前端知识:\与\,\与\之间的区别
- 存在于
<b></b>
bold,字体加粗<strong></strong>
是要表达强调而字体被加粗<i></i>
就是italic,字体斜体<em></em>
也是强调内容,而被倾斜
详细解释:
- 相同点
- 被
<b>
和<strong>
包围的文字将会被加粗 - 被
<i>
和<em>
包围的文字将以斜体的形式呈现
- 被
- 不同点1
<b>
和<i>
是自然样式标签,分别表示无意义的加粗,无意义的斜体,详细表现样式:{font-weight:bolder}
用粗体显示,{font-style : italic}
用斜体显示,
<em>
和<strong>
是语义样式标签,都表示为强调文本<em>
表示一般的强调文本,而<strong>
表示比<em>
语义更强的强调文本。使用阅读设备阅读网页时:<strong>
会重读, 而<b>
是展示强调内容。
- 不同点2
<b>
和<i>
是视觉元素(presentational elements),分别表示无意义的加粗,无意义的斜体<em>
和<strong>
是表达要素 (phrase elements)。<em>
(emphasized text)表示一般的强调文本<strong>
(strong emphasized text )表示比<em>
语义更强的强调文本。
- 总结:
<b>
和<i>
创建之初就是简单地表示粗体和斜体样式,但现在是 HTML5 的天下。语义化是 HTML5 最大的特性之一,而所有被 HTML5 保留的标签都带有其特有的语义,<b>
和<i>
也不例外,它们分别被重新赋予了语义。相比较而言,标签的样式反而变得无足轻重,所以上面所讲的两组标签,虽然样式上表现极其相似,但其实语义上各有侧重。
- 总结:通过
tf
和idf
的关系就可以得出网页核心词是什么,从而判断出具体内容的分类 - PS:详细的计算方法见下一节
(2)计算方法
① 计算原理
- 原理:通过
tf(词频)
和idf(逆文档频率)
的积就可得出一个新的数值TF-IDF
。 - 作用:某个词在文章中的TF-IDF越大,那么一般而言这个词在这篇文章的重要性会越高,所以通过计算文章中各个词的TF-IDF,由大到小排序,排在最前面的几个词,就是该文章的关键词。
② TF-IDF
算法步骤
- 第一步:计算词频(TF)
$词频(TF) = 某个词在文章中出现的次数$
考虑到文章有长短之分,为了便于不同文章中的比较,进行“词频”标准化,优化计算方法
$词频(TF) = \frac{某个词在文章中的出现次数}{文字的总次数}$
- 第二步:计算逆文档频率(IDF)
$逆文档频率(IDF) = log(\frac{语料库的文档总数}{包含该词的文档数 + 1})$
- 第三步:计算TF-IDF
$TF - IDF = 词频(TF) \times 逆文档频率(IDF)$
③ 总结
可以看到,TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。
④ 扩展
扩展内容:示例代码
示例代码.py
def TF_IDF(path,dic)
tf_idf = {}
fold_list = os.listdir(path)
count = 0
idf = {}
for key in dic.keys():
idf[key] = 1
tf_idf[key] = 0
for flod in fold_list:
file_list = os.listdir(path + '/' + flod)
count += len(file_list)
for file in file_list:
with open(path + '/' + flod + '/' + file) as f:
text = f.read()
for key in dic.keys():
if key in text:
idf[key] += 1
for key,value in idf.items():
idf[key] = log(count/value+1)
for key,value in tf_idf.items():
tf_idf[key] = dic[key] * idf[key]
return tf_idf
示例代码.js
function TF_IDF(path, dic) {
let tf_idf = {};
let fold_list = fs.readdirSync(path);
let count = 0;
let idf = {};
for (let key in dic) {
idf[key] = 1;
tf_idf[key] = 0;
}
for (let i = 0; i < fold_list.length; i++) {
let file_list = fs.readdirSync(path + '/' + fold_list[i]);
count += file_list.length;
for (let j = 0; j < file_list.length; j++) {
let text = fs.readFileSync(path + '/' + fold_list[i] + '/' + file_list[j], 'utf8');
for (let key in dic) {
if (text.includes(key)) {
idf[key] += 1;
}
}
}
}
for (let key in idf) {
idf[key] = Math.log(count / (idf[key] + 1));
}
for (let key in tf_idf) {
tf_idf[key] = dic[key] * idf[key];
}
return tf_idf;
}
(3)算法的优缺点
① 优点
- 简单快速且容易理解
② 缺点
- 使用词频(TF)判断文章中的核心词不够全面
- 如果核心词出现的不够多就无法体现位置信息和核心词在上下文中的重要性
- 举例:百度百科明明主要讲解的是
tf-idf
,但是最高频词为idf
(4)算法的实际运用
- 文章模板(注意:标题标签中也是需要布置关键词的)
附:大牛博客中对h1、h2、h3标签的使用规则 Official Google Reader Blog 的定义方式:
- h1 定义网站标题。
- h2 定义文章标题。
- h3 定义侧边栏目标题。
知名网页设计师“JeffreyZeldman”的博客定义方式:
- 使用 h1 定义网站标题。
- 使用 h2 定义文章标题和侧边栏目标题。
- 使用 h3 定义文章时间。
- 关键词出现的次数/频率
- 保证关键词密度为:1个/100字,即大约每一百个字中出现一次关键词
- 关键词以不同形式出现
- 纯文本
- 锚文本(推荐)
- 手动添加的文章,最好在正文中间的位置添加内链锚文本,“推荐阅读:XXX(锚文本)”
- 采集类型的文章,可以在底部添加相关文章指向原文或者内链
- 结合HITS算法使用
- 关键词出现的次数/频率
Comments | NOTHING