PostgreSQL 文本数据分析实践之 - 相似度分析

背景

在日常的生活中,我们可能会经常需要一些像相近、相仿、距离接近、性格接近等等类似这样的需求,对数据进行筛选。

这些需求PostgreSQL居然都支持,是不是很变态。

变态的例子

这些场景都支持索引排序和检索,否则怎么叫变态呢。

按长相相似度排序

比如最近的王宝强和马蓉的事件,估计很多人会拿宋喆的照片进行相似度的搜索,八卦八卦。
说起图像搜索,我前几天才写了一篇这样的文章,是关于在PG数据库中使用图像搜索插件的文章。
《弱水三千,只取一瓢,当图像搜索遇见PostgreSQL(Haar wavelet)》

按喜好重合度排序

比如收集了人群的各种喜好的数据,按喜好进行聚类,或者按喜好的重叠度进行排序,找出目标人群。

按年龄相近程度排序

这个相对简单,比如输入23岁,按接近23岁的输出即可。
例子 https://www.postgresql.org/docs/9.5/static/btree-gist.html
输出与100最接近的10条数据。

postgres=# create extension btree_gist;
CREATE EXTENSION
postgres=# create table test12(id int);
CREATE TABLE
postgres=# insert into test12 select trunc(random()*1000) from generate_series(1,100000);
INSERT 0 100000
postgres=# create index idx_test12 on test12 using gist(id);
CREATE INDEX
postgres=# select * from test12 order by id <-> 100 limit 10;
 id
-----
 100
 100
 100
 100
 100
 100
 100
 100
 100
 100
(10 rows)

按距离排序

https://www.postgresql.org/docs/9.5/static/functions-geometry.html
例如取出与某个点最近的10个点。

postgres=# create table test13(c1 point);
CREATE TABLE
postgres=# insert into test13 select ('('||trunc(random()1000)||','||trunc(random()5000)||')')::point from generate_series(1,10000);
INSERT 0 10000
postgres=# create index idx_test13 on test13 using gist(c1);
CREATE INDEX
postgres=# select * from test13 order by c1 <-> point '(1,10000)' limit 10;
     c1
------------
 (58,4993)
 (191,4995)
 (48,4991)
 (326,4998)
 (99,4988)
 (205,4991)
 (348,4998)
 (53,4986)
 (174,4988)
 (136,4984)
(10 rows)

按文本的相似度排序

https://www.postgresql.org/docs/9.5/static/pgtrgm.html
例如,根据文本的相似程度,排序输出。

postgres=# create extension pg_trgm;
CREATE EXTENSION
postgres=# create table test14(c1 text);
CREATE TABLE
postgres=# insert into test14 values ('hello digoal'), ('china'), ('hello china'), ('nihao digoal');
INSERT 0 4
postgres=# select * from test14;
      c1
--------------
 hello digoal
 china
 hello china
 nihao digoal
(4 rows)
postgres=# create index idx_test14 on test14 using gist(c1 gist_trgm_ops);
CREATE INDEX
postgres=# explain select *,c1 <-> 'digoal' from test14 order by c1 <-> 'digoal' limit 2;
                                   QUERY PLAN
--------------------------------------------------------------------------------
 Limit  (cost=0.13..4.17 rows=2 width=36)
   ->  Index Scan using idx_test14 on test14  (cost=0.13..8.21 rows=4 width=36)
         Order By: (c1 <-> 'digoal'::text)
(3 rows)
postgres=# select *,c1 <-> 'digoal' from test14 order by c1 <-> 'digoal' limit 2;
      c1      | ?column?
--------------+----------
 hello digoal | 0.461538
 nihao digoal | 0.461538
(2 rows)

按分词的相似度排序

https://github.com/postgrespro/rum
这个与前面的文本相似度不同,因为它统计的是分词的相似度,而不是文本的相似度。
支持计算相似度的类型分别为tsvector和tsquery。
例如 搜索带有postgresql 或 digoal 或 oracle 或 postgres 关键词的文章,通常来说返回顺序是只要包含就返回,而不会管它的相似度高低来顺序返回。
rum插件则满足按相似度高低来返回的需求。
rum是类GIN的索引访问接口。

export PATH=/home/digoal/pgsql9.6/bin:$PATH
git clone https://github.com/postgrespro/rum
cd rum
make USE_PGXS=1
make USE_PGXS=1 install
//
//
git clone https://github.com/jaiminpan/pg_jieba
cd pg_jieba
make USE_PGXS=1
make USE_PGXS=1 install
//
//
postgres=# create extension rum;
CREATE EXTENSION
postgres=# create extension pg_jieba;
CREATE EXTENSION
// 分词举例
postgres=#  select * from to_tsvector('jiebacfg', '小明硕士毕业于中国科学院计算所,后在日本京都大学深造');
                                   to_tsvector
----------------------------------------------------------------------------------
 '中国科学院':5 '小明':1 '日本京都大学':10 '毕业':3 '深造':11 '硕士':2 '计算所':6
(1 row)
// 有相似度
postgres=#  select * from rum_ts_distance(to_tsvector('jiebacfg', '小明硕士毕业于中国科学院计算所,后在日本京都大学深造') , to_tsquery('计算所'));
 rum_ts_distance
-----------------
         16.4493
(1 row)
// 没有相似度
postgres=#  select * from rum_ts_distance(to_tsvector('jiebacfg', '小明硕士毕业于中国科学院计算所,后在日本京都大学深造') , to_tsquery('计算'));
 rum_ts_distance
-----------------
        Infinity
(1 row)
// 或相似度
postgres=# select * from rum_ts_distance(to_tsvector('jiebacfg', '小明硕士毕业于中国科学院计算所,后在日本京都大学深造') , to_tsquery('计算所 | 硕士'));
 rum_ts_distance
-----------------
         8.22467
(1 row)
// 与相似度
postgres=# select * from rum_ts_distance(to_tsvector('jiebacfg', '小明硕士毕业于中国科学院计算所,后在日本京都大学深造') , to_tsquery('计算所 & 硕士'));
 rum_ts_distance
-----------------
         32.8987
(1 row)
// 排序
postgres=# create table test15(c1 tsvector);
CREATE TABLE
postgres=# insert into test15 values (to_tsvector('jiebacfg', 'hello china, i''m digoal')), (to_tsvector('jiebacfg', 'hello world, i''m postgresql')), (to_tsvector('jiebacfg', 'how are you, i''m digoal'));
INSERT 0 3
postgres=# select * from test15;
                         c1
-----------------------------------------------------
 ' ':2,5,9 'china':3 'digoal':10 'hello':1 'm':8
 ' ':2,5,9 'hello':1 'm':8 'postgresql':10 'world':3
 ' ':2,4,7,11 'digoal':12 'm':10
(3 rows)
postgres=# create index idx_test15 on test15 using rum(c1 rum_tsvector_ops);
CREATE INDEX
postgres=# select *,c1 <=> to_tsquery('hello') from test15;
                         c1                          | ?column?
-----------------------------------------------------+----------
 ' ':2,5,9 'china':3 'digoal':10 'hello':1 'm':8     |  16.4493
 ' ':2,5,9 'hello':1 'm':8 'postgresql':10 'world':3 |  16.4493
 ' ':2,4,7,11 'digoal':12 'm':10                     | Infinity
(3 rows)
postgres=# explain select *,c1 <=> to_tsquery('postgresql') from test15 order by c1 <=> to_tsquery('postgresql');
                                   QUERY PLAN
--------------------------------------------------------------------------------
 Index Scan using idx_test15 on test15  (cost=3600.25..3609.06 rows=3 width=36)
   Order By: (c1 <=> to_tsquery('postgresql'::text))
(2 rows)

不再举例,如果你有更好的想法,PG还不支持的话,可以自己扩展哦。

参考
《找对业务G点, 体验酸爽 - PostgreSQL内核扩展指南》

如果你觉得还不够意思,要来点基于文本集合的深度挖掘,没关系,还有MADlib插件在等你,支持丰富的文本分析和训练接口。

http://madlib.incubator.apache.org/docs/latest/index.html

祝大家玩得开心,欢迎随时来 阿里云促膝长谈业务需求 ,恭候光临

阿里云的小伙伴们加油,努力 做好内核与服务,打造最贴地气的云数据库

时间: 2024-08-04 00:08:49

PostgreSQL 文本数据分析实践之 - 相似度分析的相关文章

性能测试-文本相似度分析的性能检测?

问题描述 文本相似度分析的性能检测? 利用tf-idf算法和余弦相似度算法计算了文本之间的相似度,可是结果出来了,不知道结果的好坏啊,请问大神们有没有知道怎么评测结果的好坏啊? 解决方案 分析算法复杂度.如果算法太复杂,分析起来有困难,评价算法的好坏就是给数据量大小不等的测试样本,运行得到耗费的时间. 对数据量和运行时间的曲线拟合. 糟糕的算法就是随着数据量的增加,时间或者存储的开销呈现几何级数地发散出去. 好的算法是,时间随着数据的增加,呈现常数.收敛在某个值或者是线性增加的. 解决方案二:

PostgreSQL 异步消息实践 - 亿级/分钟 FEED系统实时监测

标签 PostgreSQL , 异步消息 , 触发器 , 规则 , insert on conflict , 实时分析 背景 在很多业务系统中,为了定位问题.运营需要.分析需要或者其他需求,会在业务中设置埋点,记录用户的行为在业务系统中产生的日志,也叫FEED日志. 比如订单系统.在业务系统中环环相扣,从购物车.下单.付款.发货,收货(还有纠纷.退款等等),一笔订单通常会产生若干相关联的记录. 每个环节产生的属性可能是不一样的,有可能有新的属性产生,也有可能变更已有的属性值. 为了便于分析,通常

基于ELK的数据分析实践——满满的干货送给你

很多人刚刚接触ELK都不知道如何使用它们来做分析,经常会碰到下面的问题: 安装完ELK不知从哪下手 拿到数据样本不知道怎么分解数据 导入到elasticsearch中奇怪为什么搜不出来 搜到结果后,不知道它还能干什么 本篇就以一个完整的流程介绍下,数据从 读取-->分析-->检索-->应用 的全流程处理.在阅读本篇之前,需要先安装ELK,可以参考之前整理安装文档:ELK5.0部署教程 在利用ELK做数据分析时,大致为下面的流程: 1 基于logstash分解字段 2 基于字段创建Mapp

网站推广之链接广泛度分析

链接|推广|网站推广 Internet的变化日新月异,其庞大的容量对搜索引擎的索引更新和服务无疑是一种考验.搜索引擎也一直在努力寻求创新的途径,例如以关联站点的广泛度为基础进行排名,以此抵消对搜索引擎的spam伎俩和对页面因素恶意操纵的不良竞争结果,达到为用户提供最为精准和相关的搜索结果的目的.如今,通过将链接广泛度这个因素整合到其排名算法中,搜索引擎(例如Google)已然能够为冲浪者们提供卓越的搜索经验. 但这并不意味着我们就可以对页面因素和网站内容掉以轻心.正确的理解应该是:对于两个页面优

针对智能家居互联网竞争度分析 如何做好推广

中介交易 SEO诊断 淘宝客 云主机 技术大厅 如今科技不断的发展,互联网从我们刚开始的聊天.游戏到购物.社交.分享到现在的电子商务.如今互联网已经是企业营销必走的一种渠道.根据我对智 能家居行业的分析,互联网的竞争度可见一斑,上至行业巨头,下至中小企业都在互联网这一领域展开布局,今天谈谈针对智能家居互联网竞争度分析,如何做好推 广,分享给大家. 一.分析行业的竞争度: 如今各行各业都在重视互联网,所以要认真的分析行业在互联网的竞争度,然后再按策略进行推广.根据我对智能家居行业的分析,智能家居行

盘点关键词竞争度分析新方法

网站SEO优化核心工作之一是关键词的选择.我们在选择关键词的时候会考虑一些因素.但是现在随着搜索引擎的算法不断改变,将排名的权利逐渐向用户倾斜.也就是在网站排名里面越来越多的加入了用户体验的因素.导致现在就算是新站也有可能会战胜老站.今天就来介绍一些新方法进行关键词竞争度分析. 我们常见的关键词竞争度分析考虑的因素有:百度指数,搜索量,看排序中竞价网站的个数,自然排名中网站首页的个数,自然排名前十网站的质量,百度推广后台服务等等.在考虑这些因素的时候,我们会对关键词的热门程度做一个统计.分析出关

seo网站优化之关键词竞争度分析

对从事关键词优化的seoer们来说,关键词竞争度的分析是一项基本技能.关键词难易程度的分析是评估项目操作的难度的主要指标,是的明确网站架构调整参数,是明确关键词布局思路主要因素,更是制定项目的操作计划的主要参考依据.既然关键词的分析作为网站优化的根基,那么接下来我将结合我的关键词优化项目从三方面来给大家阐述关键词竞争度分析包含的内容以及注意事项,希望对大家能有所帮助. 第一.SERP数量 SERP英文为Search Engine Results Page,也就是搜索引擎搜索页的意思.通过SERP

网站数据分析:多维交叉分析 排查网站数据异常

中介交易 SEO诊断 淘宝客 云主机 技术大厅 我们在进行数据分析的时候,大部分时间都在使用趋势分析.比较分析.细分分析这三类方法,但其实还有一个方法我们也会经常使用--交叉分析,尤其是在排查数据异常的问题时,交叉分析就能展现其强大的威力.另外要跟大家说声抱歉的是博客的更新频率可能没有那么频繁了,但是尽量每个月至少能发布一篇,希望文章的质量有所保证,还是欢迎大家留言讨论,能够发起一些有趣的话题,一起拓展在网站数据分析方面的思路. 什么是交叉分析? 交叉分析是指对数据在不同维度进行交叉展现,进行多

PRICAI 2016 论文精选 | 基于多核学习整合文本信息的微博图片情绪分析

近年来,微博已经成为了人们最常用的网络社交工具之一,所以对微博中的信息进行挖掘是非常有价值的.因为图片具有快捷方便的天然属性,只用图片发布微博是一个新的趋势.目前大多数微博的情绪分析研究都聚焦在文本,已经不能适用.利用机器学习技术对图片进行情绪分析是实现高级人机交互的重要部分,对于实现人机交互.人-计算机接口以及智能计算机等有重要意义,这已成为目前模式识别.机器学习和认知科学等研究领域的热门研究课题之一. 标题:基于多核学习整合文本信息的微博图片情绪分析 摘要:微博上,图片是表达用户情绪最重要的