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

简介: 背景 在日常的生活中,我们可能会经常需要一些像相近、相仿、距离接近、性格接近等等类似这样的需求,对数据进行筛选。 这些需求PostgreSQL居然都支持,是不是很变态。 变态的例子 按长相相似度排序 比如最近的王宝强和马蓉的事件,估计很多人会拿宋喆的照片进行相似度的搜索,八卦八卦。

背景

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

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

变态的例子

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

按长相相似度排序

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

按喜好重合度排序

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

按年龄相近程度排序

这个相对简单,比如输入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内核扩展指南》
https://yq.aliyun.com/articles/55981

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

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

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

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

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
机器学习/深度学习 人工智能 自然语言处理
如何构建企业级数据智能体:Data Agent 开发实践
本篇将介绍DMS的一款数据分析智能体(Data Agent for Analytics )产品的技术思考和实践。Data Agent for Analytics 定位为一款企业级数据分析智能体, 基于Agentic AI 技术,帮助用户查数据、做分析、生成报告、深入洞察。
|
机器学习/深度学习 人工智能 自然语言处理
构建企业级数据分析助手:Data Agent 开发实践
本篇将介绍DMS的一款数据分析智能体(Data Agent for Analytics )产品的技术思考和实践。Data Agent for Analytics 定位为一款企业级数据分析智能体, 基于Agentic AI 技术,帮助用户查数据、做分析、生成报告、深入洞察。由于不同产品的演进路径,背景都不一样,所以只介绍最核心的部分,来深入剖析如何构建企业级数据分析助手:能力边界定义,技术内核,企业级能力。希望既能作为Data Agent for Analytics产品的技术核心介绍,也能作为读者的开发实践的参考。
724 1
构建企业级数据分析助手:Data Agent 开发实践
|
6月前
|
SQL 存储 关系型数据库
PostgreSQL窗口函数避坑指南:如何让复杂分析查询提速300%?
本文基于真实企业级案例,深入剖析PostgreSQL窗口函数的执行原理与性能陷阱,提供8大优化策略。通过定制索引、分区裁剪、内存调优及并行处理等手段,将分钟级查询压缩至秒级响应。结合CTE分阶段计算与物化视图技术,解决海量数据分析中的瓶颈问题。某金融客户实践表明,风险分析查询从47秒降至0.8秒,效率提升5800%。文章附带代码均在PostgreSQL 15中验证,助您高效优化SQL性能。
349 0
|
4月前
|
供应链 监控 搜索推荐
35页PPT|零售行业自助数据分析方法论:指标体系构建平台集成、会员与商品精细化运营实践
在零售行业环境剧变的背景下,传统“人找货”模式正被“货找人”取代。消费者需求日益个性化,购买路径多元化,企业亟需构建统一的指标体系,借助BI平台实现数据驱动的精细化运营。本文从指标体系构建、平台集成到会员与商品运营实践,系统梳理零售经营分析的方法论,助力企业实现敏捷决策与业务闭环。
35页PPT|零售行业自助数据分析方法论:指标体系构建平台集成、会员与商品精细化运营实践
|
6月前
|
SQL 存储 缓存
基于 StarRocks + Iceberg,TRM Labs 构建 PB 级数据分析平台实践
从 BigQuery 到开放数据湖,区块链情报公司 TRM Labs 的数据平台演进实践
|
6月前
|
数据采集 人工智能 算法
“脏数据不清,分析徒劳”——聊聊数据分析里最容易被忽视的苦差事
“脏数据不清,分析徒劳”——聊聊数据分析里最容易被忽视的苦差事
239 34
|
5月前
|
数据采集 SQL 监控
“你分析个锤子啊,米都没洗净”——数据采集和数据分析的底层逻辑真相
“你分析个锤子啊,米都没洗净”——数据采集和数据分析的底层逻辑真相
131 0
|
DataWorks 数据挖掘 大数据
方案实践测评 | DataWorks集成Hologres构建一站式高性能的OLAP数据分析
DataWorks在任务开发便捷性、任务运行速度、产品使用门槛等方面都表现出色。在数据处理场景方面仍有改进和扩展的空间,通过引入更多的智能技术、扩展数据源支持、优化任务调度和可视化功能以及提升团队协作效率,DataWorks将能够为企业提供更全面、更高效的数据处理解决方案。
|
运维 数据挖掘 网络安全
场景实践 | 基于Flink+Hologres搭建GitHub实时数据分析
基于Flink和Hologres构建的实时数仓方案在数据开发运维体验、成本与收益等方面均表现出色。同时,该产品还具有与其他产品联动组合的可能性,能够为企业提供更全面、更智能的数据处理和分析解决方案。
|
数据挖掘 UED
ChatGPT数据分析——探索性分析
ChatGPT数据分析——探索性分析
185 1

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多