如何计算文章标题和内容相关度

2020.08.16 -

做seo的都知道,搜索引擎一直提倡标题和内容是要高相关性的,对于那些标题党或者是文不对题的那种是比较打击的。

但是,我们不知道搜索引擎是如何计算这个相关度的,如果自己要做一个审核相关度的功能,该如何实现呢?

从seo出现以来,一直有一个概念是整个seo优化过程都需要知道的东西,那就是关键词密度。很多的seo教程一直强调关键词密度要在2%~8%之间是最好的,低于这个范围就没啥竞争力,主题不集中;而高于这个值就会导致关键词堆砌,优化过度了,容易受到搜索引擎的打击。

那是不是说明这个关键词密度是计算主题相关度的一个重要指标呢?但是这个关键词的密度是完整的关键词密度还是分词后的关键词密度呢?是正文部分的关键词密度还是整个网页文字内容部分的关键词密度呢?这个不好说,但是我们能从搜索结果里面的百度快照看出点啥来。

【干货】如何计算文章标题和内容相关度?提供完整代码
【干货】如何计算文章标题和内容相关度?提供完整代码
【干货】如何计算文章标题和内容相关度?提供完整代码

从搜索结果里面来看,其实是有分词的,但是完整匹配的排名效果会更好。(这个显然大伙都知道,哈哈) 于是就有很多做seo的,特别是做黑帽的,就直接往文章里面插入完整的关键词,一般插入2-3次这样,用以提高关键词的密度和文章的相关性。

好了,这些都不是本文的关注点,我们来看看如果要实现一个关键词密度计算的程序应该如何实现。

如何实现关键词密度计算

首先说下算法实现过程

  1. 分别将关键词和文章内容进行分析
  2. 统计文章中出现关键词分词结果的次数
  3. 用2的结果除以文章分词后的总次数
  4. 优化点,可以先去除文章和关键词中的停止词之后再做计算,这样可能更贴切一点。(留给大家实现了)

代码

# coding: utf-8
# 作者:brooks
import jieba

# 初始化结巴分词
jieba.initialize()


def calc_keyowrd_density(keyword: str, article: str) -> float:
    # 使用搜索分词,最大化分词
    cut_keyword = jieba.lcut_for_search(keyword)
    cut_article = jieba.lcut_for_search(article)
    # 去除关键词部分的重复词语
    cut_keyword_set = set(cut_keyword)
    # 计算关键词分词在文章中包含的数量
    total_include = 0
    for w in cut_keyword_set:
        total_include += cut_article.count(w)
    # 计算关键词密度
    return total_include / len(cut_article)

我拿了篇文章做了下计算,结果如下:

计算的文章地址:https://game.china.com/industry/focus/11118308/20200630/38421717.html

【干货】如何计算文章标题和内容相关度?提供完整代码

这篇文章的关键词密度是11.4% 看起来有点优化过度了?但实际上并没有超出很多,而且目前这个是排名在第4的。而且我计算的只是正文内容的关键词密度。

当然了,我这个也只是一种粗略的计算方式,相信搜索引擎会有更加完善的计算。大家如果感兴趣可以自己试试哦。

那么这个关键词密度是不是影响这个排名的重要因素呢?这个大家可以去验证一下,这个不是本文的主题哈。

回到正题,如果只是通过关键词密度来计算文本的相关性似乎有点不太靠谱,还有没有其它好的办法来实现呢?这里我又想到了另外的一种思路:

另一种计算文章主题相关性的方法

思路如下:

  1. 将标题和文章正文进行分词处理
  2. 利用TF_IDF算法提取出文章的N个核心词语,这里的N可以是一个固定的数值,比如10个,也可以是动态的数值,比如跟关键词分词后的个数一样
  3. 去除标题分词中字数少于2个字的,只有一个字的词默认就认为文中是包含的。
  4. 将3中的结果进行去重然后拿去跟2中的词做对比,得到3没有包含在2中的词语
  5. 将4中没有包含词语的个数除以1中的总个数,再用1减去计算值就得到相似度 具体代码实现如下:

代码

# coding: utf-8
# 作者:brooks
import jieba
from jieba import analyse

# 初始化结巴分词
jieba.initialize()


def calc_title_relate(title: str, article: str) -> float:
    cut_keyword = jieba.lcut(title)
    article_tfidf = analyse.tfidf(article, topK=len(cut_keyword))
    cut_keyword_set = set(w for w in cut_keyword if len(w) > 1)
    article_tfidf_set = set(article_tfidf)
    notin = cut_keyword_set - article_tfidf_set
    return 1 - len(notin) / len(cut_keyword)
    

跟关键词密度一起来作对比,运行上次的文章,得到如下结果:

【干货】如何计算文章标题和内容相关度?提供完整代码

这里可以看到,关键词密度是11.4%,而相似度是80%,看起来还是可以的。当然了,没有做大量的测试,感兴趣的同学可以用下哦。

如果你有更好的方法或者idea欢迎留言一起探讨学习。我这个方法是比较简单的。当精度的要求没那么高的时候,简单快速的方法是我们实现功能的首先。

完整代码

# coding: utf-8
# 作者:brooks
import jieba
from jieba import analyse

# 初始化结巴分词
jieba.initialize()


def calc_keyowrd_density(keyword: str, article: str) -> float:
    # 使用搜索分词,最大化分词
    cut_keyword = jieba.lcut_for_search(keyword)
    cut_article = jieba.lcut_for_search(article)
    # 去除关键词部分的重复词语
    cut_keyword_set = set(cut_keyword)
    # 计算关键词分词在文章中包含的数量
    total_include = 0
    for w in cut_keyword_set:
        total_include += cut_article.count(w)
    # 计算关键词密度
    return total_include / len(cut_article)


def calc_title_relate(title: str, article: str) -> float:
    cut_keyword = jieba.lcut(title)
    article_tfidf = analyse.tfidf(article, topK=len(cut_keyword))
    cut_keyword_set = set(w for w in cut_keyword if len(w) > 1)
    article_tfidf_set = set(article_tfidf)
    notin = cut_keyword_set - article_tfidf_set
    return 1 - len(notin) / len(cut_keyword)


if __name__ == '__main__':
    with open('article.txt', encoding='utf-8') as f:
        article_text = f.read()
        kwdes = calc_keyowrd_density('印度3名村民遭雷击后被埋入牛粪治疗', article_text)
        kwrelate = calc_title_relate('印度3名村民遭雷击后被埋入牛粪治疗', article_text)
        print(f"关键词密度: {kwdes:.3f} 相似度: {kwrelate:.3f}")

article.txt 文件里面存放的就是该测试文章的纯文本内容

欢迎转载和分享,本文我将开放白名单权限。你的支持是我更新的动力,你的关注是我努力的目标。

原文始发于微信公众号(brooks的技术小屋)

- END -

253
0

如何计算文章标题和内容相关度

做seo的都知道,搜索引擎一直提倡标题和内容是要高相关性的,对于那些标题党或者是文不对题的那种是比较打击的。 […]