作者:来自 Elastic Alexander Dávila
了解如何使用 significant terms 聚合来发现你数据中的洞察。
更多阅读:Elasticsearch:significant terms aggregation
Elasticsearch 拥有大量新功能,可以帮助你为你的使用场景构建最佳搜索解决方案。深入查看我们的示例 notebooks 了解更多信息,开始免费云试用,或立即在本地机器上体验 Elastic。
在 Elasticsearch 中, significant terms 聚合不仅仅是找出最常见的词项,而是发现数据集中统计上不寻常的值。这使我们能够发现有价值的洞察和非显而易见的模式。 significant terms 聚合的响应中包含两个有用的参数:
- bg_count(背景计数):在父数据集中找到的文档数量
- doc_count:在结果数据集中找到的文档数量
例如,在一个手机销售数据集中,我们可以像下面这样对 iPhone 16 的销售查找 significant terms:
`
1. GET phone_sales_analysis/_search
2. {
3. "size": 0,
4. "query": {
5. "term": {
6. "phone_model": {
7. "value": "iPhone 16"
8. }
9. }
10. },
11. "aggs": {
12. "significant_cities": {
13. "significant_terms": {
14. "field": "city_region",
15. "size": 1
16. }
17. }
18. }
19. }
`AI写代码
然后,响应会给出:
`
1. {
2. "aggregations": {
3. "significant_cities": {
4. "doc_count": 122,
5. "bg_count": 424,
6. "buckets": [
7. {
8. "key": "Houston",
9. "doc_count": 12,
10. "score": 0.1946481360617346,
11. "bg_count": 14
12. }
14. ]
15. }
16. }
17. }
`AI写代码
Houston 并不是整个数据集中排名前十的城市,也不是 iPhone 16 的销量最高城市。然而, significant terms 聚合显示,与数据集的其余部分相比,iPhone 16 在这个城市的购买量不成比例地偏高。让我们更深入地看看数据:
- 在顶层:
- doc_count: 122 — 查询总共匹配了 122 个文档
- bg_count: 424 — 背景集(所有销售文档)包含 424 个文档
- 在 Houston 的 bucket 中:
- doc_count: 12 — 在 122 个查询结果中,Houston 出现了 12 次
- bg_count: 14 — 在背景数据集的 424 个文档中,Houston 出现了 14 次
这告诉我们,在总共 424 笔购买中,只有 14 笔发生在 Houston,占比为 3.3%。但如果我们只看 iPhone 16 的销售,就会发现有 12 笔发生在 Houston,占比为 9.8%,是整体数据集的 3 倍,这就是 “significant”!
下面是这个分析在可视化中的表现:每个 city_region 的总销量。
我们可以看到 Houston 有 14 笔销售,在数据集中按销量排名第 14。
现在,如果我们应用一个过滤器,仅查看 iPhone 16 的销售,Houston 有 12 笔销售,成为该型号销量第 2 高的城市:
了解 significant terms 聚合
根据 Elastic 文档, significant terms 聚合:
“(查找)在前景集和背景集之间受欢迎程度发生显著变化的词项。”
这意味着它使用统计指标将某个词项在数据子集(前景集)中的频率与在整个父数据集(背景集)中的频率进行比较。这样,评分反映的是统计显著性,而不是某个词项在数据中出现的次数。
significant terms 聚合与普通 terms 聚合的主要区别在于:
-
significant terms 比较的是数据的一个子集,而 terms 聚合只处理查询结果数据集。
-
terms 聚合返回的是数据集中最常见的词项,而 significant terms 会忽略常见词项,找出让数据子集独特的词项。
-
significant terms 对性能的影响可能更大,因为它需要从磁盘读取数据,而不是像 terms 聚合那样从内存中读取。
实际应用(消费者行为分析)
为分析准备数据
在本次分析中,我们生成了一个合成的手机销售数据集,包括价格、手机规格、购买者的人口统计信息和反馈。我们还基于用户反馈生成了 embedding,方便后续运行语义查询。我们使用的是 Elasticsearch 中开箱即用的 multilingual e5 small 模型。
在 Elasticsearch 中使用这个数据集的方法如下:
-
使用 Kibana 的 Upload data files 功能上传 CSV 文件(可以从此处下载)。
-
设置一个名为 “embedding” 的语义字段,使用 multilingual-e5-small 模型,如本博客所示。
-
使用默认字段类型完成导入(除 purchase_date 和 user_feedback 外,其它字段为 keyword)。确保设置索引名为 phone_sales_analysis,以便能够直接运行本文展示的查询。
本次分析的主要目标是发现:“What's different about the iPhone 16 buyers versus other segments of the population? - iPhone 16 的购买者与其他人群有何不同?”并以此为基础做市场营销的用户分群。
以下是数据集中的一个示例文档:
`
1. {
2. "customer_type": "Returning",
3. "user_feedback": "I have to say, quality is great for the price. The battery life is really good.",
4. "upgrade_frequency": "2 years",
5. "storage_capacity": "256GB",
6. "occupation": "Technology & Data",
7. "color": "Phantom Black",
8. "gender": "Male",
9. "price_paid": 899,
10. "previous_brand_loyalty": "Mixed",
11. "location_type": "Urban",
12. "phone_model": "Samsung Galaxy S24",
13. "city_region": "San Francisco Bay Area",
14. "@timestamp": "2024-03-15T00:00:00.000-05:00",
15. "income_bracket": "75000-100000",
16. "purchase_channel": "Online",
17. "feedback_sentiment": "positive",
18. "education_level": "Bachelor",
19. "embedding": "I have to say, quality is great for the price. The battery life is really good.",
20. "customer_id": "C001",
21. "purchase_date": "2024-03-15",
22. "age": 34,
23. "trade_in_model": "iPhone 13"
24. }
`AI写代码
理解人口统计模式
这里,我们将对总体人群进行分析,并将其与 iPhone 16 用户的 significant terms 聚合中的有趣发现进行比较。
常规模式
为了理解常规的购买模式,我们可以在所有文档上对不同字段进行聚合。为简化起见,我们将重点分析购买手机人群的职业。这可以通过向 Elasticsearch 发送请求来完成。
`
1. GET phone_sales_analysis/_search
2. {
3. "aggs": {
4. "occupation_distribution": {
5. "terms": {
6. "size": 5,
7. "field": "occupation"
8. }
9. }
10. },
11. "size": 0
12. }
`AI写代码
这告诉我们,数据集中主要的职业(按记录数量排序)是:
iPhone 16 用户的模式
为了了解购买 iPhone 16 的人群有何不同,我们可以在相同字段上运行一个 terms 聚合,并添加一个过滤器,在查询中筛选出这些人,如下所示:
`
1. GET phone_sales_analysis/_search
2. {
3. "query": {
4. "term": {
5. "phone_model": "iPhone 16"
6. }
7. },
8. "aggs": {
9. "occupation_distribution": {
10. "terms": {
11. "size": 5,
12. "field": "occupation"
13. }
14. }
15. },
16. "size": 0
17. }
`AI写代码
所以,对于 iPhone 16 用户来说,主要的职业是:
我们可以看到,iPhone 16 用户的职业分布模式与其他手机型号的用户不同。让我们用 Kibana 来轻松可视化这些结果:
在这个图表中,我们可以看到 iPhone 16 的趋势与整体人群的趋势不同。
我们可以跳过整个分析,直接运行一个 significant terms 聚合,看看是什么让 iPhone 16 用户与普通人群不同:
`
1. GET phone_sales_analysis/_search
2. {
3. "query": {
4. "term": {
5. "phone_model": "iPhone 16"
6. }
7. },
8. "aggs": {
9. "occupation_distribution": {
10. "significant_terms": {
11. "size": 5,
12. "field": "occupation"
13. }
14. }
15. },
16. "size": 0
17. }
`AI写代码
简而言之,我们得到了这个响应:
| Values of occupations for the iPhone 16 | doc_count | bg_count |
|---|---|---|
| occupation_distribution (top level) | 122 | 424 |
| Medical & Healthcare bucket | 45 | 57 |
响应清楚地表明,与普通人群相比,iPhone 16 用户中医疗和健康领域的人数异常(即具有显著性!)。让我们看看响应中的数字含义:
- 顶层:
- doc_count: 122 — 查询总共匹配了 122 个文档
- bg_count: 424 — 背景集(所有销售文档)包含 424 个文档
- 在医疗与健康(Medical & Healthcare)桶中:
- doc_count: 45 — “Medical & Healthcare” 出现在 122 个查询结果中的 45 个
- bg_count: 57 — “Medical & Healthcare” 出现在背景数据集 424 个文档中的 57 个
在 424 名买家中,有 57 人从事医疗和健康行业,占比 13.44%。但在 iPhone 16 买家中,有 45 人从事该行业,占比 36.88%。这意味着在 iPhone 16 用户中,找到医疗和健康行业从业者的概率是普通人群的两倍!
我们可以用同样的方法分析其它字段(年龄、地点、收入等级等),以发现更多关于 iPhone 16 用户独特之处的信息。
消费者分群
我们可以使用 significant terms 聚合来提取产品、类别和客户分群之间的关联洞察。为此,我们先构建感兴趣类别的父聚合,然后使用 significant terms 和普通 terms 子聚合,找出该类别中有趣的洞察,并与该职业大多数人使用的情况进行比较。
例如,来看一些职业领域的人们偏好什么:
- 为了让分析更清晰,我们把搜索范围限制在 3 个职业领域:["Administrative & Support", "Technology & Data", "Medical & Healthcare"]
- 在聚合方面,我们先对职业做 terms 聚合
- 添加第一个子聚合:按手机型号的 terms 聚合 —— 找出各职业领域用户购买的手机型号
- 添加第二个子聚合:按手机型号的 significant terms 聚合 —— 找出各职业领域特别偏好的手机型号
`
1. GET phone_sales_analysis/_search
2. {
3. "query": {
4. "terms": {
5. "occupation": [
6. "Administrative & Support",
7. "Technology & Data",
8. "Medical & Healthcare"
9. ]
10. }
11. },
12. "aggs": {
13. "occupations": {
14. "terms": {
15. "size": 15,
16. "field": "occupation"
17. },
18. "aggs": {
19. "general_models": {
20. "terms": {
21. "field": "phone_model"
22. }
23. },
24. "significant_models": {
25. "significant_terms": {
26. "field": "phone_model"
27. }
28. }
29. }
30. }
31. },
32. "size": 0
33. }
`AI写代码
让我们分解聚合结果:
职业:Administrative & Support
Terms 聚合:
Significant terms 聚合:
从这张表中,我们可以推断该职业的趋势与整体人群的趋势没有显著差异。
职业:Technology & Data
Terms 聚合:
Significant terms 聚合
总文档数:424
该职业中的文档数:71
| phone model | doc_count (this model in this occupation) | bg_count (this model in all the documents) | % in all the documents | % in this occupation |
|---|---|---|---|---|
| Google Pixel 8 | 12 | 22 | 5.19% | 16.90% |
| OnePlus 11 | 9 | 14 | 3.30% | 12.68% |
| OnePlus 12 Pro | 3 | 3 | 0.71% | 4.23% |
| Google Pixel 8 Pro | 9 | 21 | 4.95% | 12.68% |
| Nothing Phone 2 | 5 | 8 | 1.89% | 7.04% |
| Samsung Galaxy Z Fold5 | 4 | 6 | 1.42% | 5.63% |
| OnePlus 12 | 8 | 20 | 4.72% | 11.27% |
职业:Medical & Healthcare
Terms 聚合:
Significant terms 聚合
总文档数:424
该职业中的文档数:57
| phone model | doc_count (this model in this occupation) | bg_count (this model in all the documents) | % in all the documents | % in this occupation |
|---|---|---|---|---|
| iPhone 16 | 45 | 122 | 28.77% | 78.95% |
| iPhone 15 Pro Max | 3 | 13 | 3.07% | 5.26% |
| iPhone 15 | 7 | 40 | 9.43% | 12.28% |
让我们看看这些数据告诉我们什么故事:
- 医疗和健康专业人士偏爱 iPhone 16,并且总体上非常倾向于使用 Apple 手机。
- 技术和数据专业人士偏好高端 Android 手机,但不一定使用三星品牌。这个类别中 iPhone 也有较大趋势。
- 行政和支持类专业人士偏好三星和 Google 手机,但没有明显且独特的趋势。
Significant terms 聚合和混合搜索
混合搜索结合了文本搜索和语义搜索结果,提供更好的搜索体验。在这种情况下, significant terms 聚合可以通过回答 “与所有文档相比,这个数据集有什么特别之处?” 来为上下文感知搜索的结果提供洞察。
为演示此功能,我们来看当用户谈论 “good performance” 时,哪些手机型号出现频率过高:
-
构建一个语义查询,寻找在 embedding 字段中与输入 “good performance” 最接近的用户反馈
-
同时在 user_feedback 文本字段上使用相同词项的文本搜索
-
添加 significant terms 查询,找出这些结果中比整个数据集中更频繁出现的手机型号
`
1. GET phone_sales_analysis/_search
2. {
3. "retriever": {
4. "rrf": {
5. "retrievers": [
6. {
7. "standard": {
8. "query": {
9. "bool": {
10. "must": [
11. {
12. "match": {
13. "user_feedback": {
14. "query": "good performance",
15. "operator": "and"
16. }
17. }
18. }
19. ]
20. }
21. }
22. }
23. },
24. {
25. "standard": {
26. "query": {
27. "semantic": {
28. "field": "embedding",
29. "query": "good performance"
30. }
31. }
32. }
33. }
34. ],
35. "rank_window_size": 20
36. }
37. },
38. "aggs": {
39. "Models": {
40. "significant_terms": {
41. "field": "phone_model"
42. }
43. }
44. }
45. }
`AI写代码
让我们来看一个匹配文档的示例:
这是我们得到的响应:
`
1. {
2. "took": 388,
3. "timed_out": false,
4. "_shards": {
5. "total": 1,
6. "successful": 1,
7. "skipped": 0,
8. "failed": 0
9. },
10. "hits": {
11. "total": {
12. "value": 20,
13. "relation": "eq"
14. },
15. "max_score": 0.016393442,
16. "hits": [...]
17. },
18. "aggregations": {
19. "Models": {
20. "doc_count": 20,
21. "bg_count": 424,
22. "buckets": [
23. {
24. "key": "iPhone 15",
25. "doc_count": 5,
26. "score": 0.4125,
27. "bg_count": 40
28. }
29. ]
30. }
31. }
32. }
`AI写代码
这告诉我们,虽然 iPhone 15 在 424 个总文档中出现了 40 次(占 9.4%),但在与语义搜索 “good performance” 匹配的 20 个文档中出现了 5 次(占 25%)。因此我们可以得出结论:在谈论 “good performance” 时,出现 iPhone 15 的概率是随机情况的 2.7 倍。
结论
significant terms 聚合通过将数据集与所有文档进行比较,可以发现数据中的独特细节。这能揭示数据中意想不到的关系,超越简单的出现次数统计。我们可以在多种场景中应用 significant terms,开启非常有趣的功能,例如:
-
欺诈检测中的模式发现 — 识别被盗信用卡的常见交易。
-
用户评价中的品牌质量洞察 — 发现收到不成比例差评的品牌。
-
发现错误分类的文档 — 识别属于某类别(term 过滤器),但描述中使用该类别不常见词汇的文档(significant terms 聚合)。