熱詞統計分析

so_easy發表於2020-11-11

前言

為了能夠出熱詞,走了不少歪路。所以就記下來。嘗試的方案有如下:

  • 按條件搜尋文件後分析詞頻
  • keep words:按自己的詞典去構建熱詞分析
  • 按條件搜尋文件後按查詢的分值分析熱詞

按條件搜尋文件後分析詞頻

{
  "from": 0,
  "_source": false,
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "ctime": {
              "gte": "2018-10-10 09:36:00",
              "lte": "2020-10-10 09:36:00"
            }
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "aggs": {
    "genres": {
      "terms": {
        "size": 100,
        "field": "content",
        "min_doc_count": 3
      }
    }
  }
}

這種方式查詢的結果如下:

熱詞統計分析

雖然可以統計出詞頻最多的片語,但是也可能會出現很多不相關的片語。因為目的是監控輿情,可是和輿情相關的片語太少。

需要注意的是contentmappings中必須開啟filedata

"content": {
          "store": false,
          "analyzer": "cnFilter",
          "search_analyzer": "ik_smart",
          "type": "text",
          "index": true,
          "fielddata": true
        },

keep_words

keep words是正向匹配熱詞,只會對keep words配置的字典分詞統計。所以為了能夠即滿足ik_smart分詞,又滿足keep words,需要多欄位配置。

"content": {
          "store": false,
          "analyzer": "cnFilter",
          "search_analyzer": "ik_smart",
          "fields": {
            "keyword": {
              "type": "text",
              "index": true,
              "analyzer":"keep_words",
              "search_analyzer":"keep_words",
              "fielddata": true
            }
          },
          "type": "text",
          "index": true,
          "fielddata": true
        },

如此在熱詞統計的時候只要指定content.keyword查詢並統計即可。這裡analyzersearch_analyzer都配置為keep_wordskeep_words是自定義的分析器,主要是用到了過濾器:

"keep_word_file": {
            "type": "keep",
            "keep_words_path": "keep_words.dic"
          }

keep_words連結

這麼做的好處就是得到的片語都是我們需要的片語,不好的地方就是更新熱詞需要重啟ES,並且只能對後來的文件分析起作用。

按條件搜尋文件後按查詢的分值分析熱詞

{
    "size": 0,
    "query": {
        "bool": {
            "must": [
                {
                    "range": {
                        "ctime": {
                            "from": "2019-11-11 10:12:31",
                            "to": "2020-11-11 10:12:31"
                        }
                    }
                },
                {
                    "query_string": {
                        "query": " (賭局 OR 非法 OR 內幕 OR 黑彩 OR 坐莊 OR 賭博 OR 調包 OR 勾結 OR 犯罪 OR 欺詐 OR 詐騙 OR 合謀 OR 窩藏 OR 私分 OR 盜竊 OR 虛假 OR 假幣 OR 醜聞 OR 行賄 OR 開庭 OR 查處 OR 舉報 OR 報案 OR 公安 OR 違規 OR 造假) ",
                        "fields": [
                            "content^1.0"
                        ],
                        "type": "best_fields",
                        "default_operator": "and",
                        "analyzer": "ik_max_word",
                        "max_determinized_states": 10000,
                        "enable_position_increments": true,
                        "fuzziness": "AUTO",
                        "fuzzy_prefix_length": 0,
                        "fuzzy_max_expansions": 50,
                        "phrase_slop": 0,
                        "escape": false,
                        "auto_generate_synonyms_phrase_query": true,
                        "fuzzy_transpositions": true,
                        "boost": 1
                    }
                }
            ],
            "must_not": [
                {
                    "query_string": {
                        "fields": [
                            "content^1.0"
                        ],
                        "query": "(牆體彩繪 OR 人體彩繪 OR 牙齒 OR 房價 OR 口腔 OR 膽碼 OR 刪號 OR 公式 OR 連號 OR 拖碼 OR 順子 OR 質數 OR 冷碼 OR 熱碼 OR 冷號 OR 熱號 OR 區間 OR 和值 OR 跨度 OR 獨膽 OR 大小比 OR 012路 OR 5碼 OR 4碼 OR 3碼 OR 2碼 OR 紅球遺漏 OR 藍球遺漏 OR 質合 OR 龍頭 OR 鳳尾 OR 縮水 OR 亞指 OR 歐指 OR 讓球 OR 上盤 OR 下盤 OR 主讓 OR 客讓 OR 主負 OR 主勝 OR 讓平 OR 讓勝 OR 讓負 OR 銀行 OR 郵政 OR 快遞 OR 地鐵 OR 火車 OR 高鐵 OR 鐵路 OR 動畫 OR 電影)"
                    }
                },
                {
                    "query_string": {
                        "fields": [
                            "kw^1.0"
                        ],
                        "query": "(好運射擊 OR 站點)"
                    }
                }
            ],
            "should": [
                {
                    "query_string": {
                        "query": " (彩票 OR 體彩 OR 福彩 OR 博彩 OR 賭博 OR 黑彩 OR 彩民 OR 開獎 OR 投注站 OR 網點 OR 站點 OR 大樂透 OR 排列 OR 排列三 OR 排3 OR 排三 OR 排列5 OR 排列五 OR 排5 OR 排五 OR 七星彩 OR 7星彩 OR 任選九 OR 任選9 OR 任九 OR 任9 OR 競彩 OR 競猜 OR 頂呱刮 OR 頂呱呱 OR 足彩 OR 足球彩票 OR 北京單場 OR 北單 OR 中彩中心 OR 中福線上 OR 快開 OR 高頻 OR 雙色球 OR 3D OR 快樂8 OR 快樂八 OR 刮刮樂 OR 即開票 OR 即開 OR 影片彩票 OR 影片票 OR 電腦彩票 OR 電腦票 OR 好運射擊 OR 連環奪寶 OR 趣味高爾夫 OR 三江風光 OR 四花選五 OR 幸運五彩) ",
                        "fields": [
                            "content^1.0"
                        ],
                        "type": "best_fields",
                        "default_operator": "and",
                        "analyzer": "ik_max_word",
                        "max_determinized_states": 10000,
                        "enable_position_increments": true,
                        "fuzziness": "AUTO",
                        "fuzzy_prefix_length": 0,
                        "fuzzy_max_expansions": 50,
                        "phrase_slop": 0,
                        "escape": false,
                        "auto_generate_synonyms_phrase_query": true,
                        "fuzzy_transpositions": true,
                        "boost": 1
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1
        }
    },
    "aggregations": {
        "agg_b_significant_text_content_sampler": {
            "sampler": {
                "shard_size": 400
            },
            "aggregations": {
                "agg_b_significant_text_content": {
                    "significant_text": {
                        "size": 300,
                        "min_doc_count": 3,
                        "shard_min_doc_count": 0,
                        "field": "content",
                        "filter_duplicate_text": true,
                        "exclude": [],
                        "mutual_information": {
                            "include_negatives": true,
                            "background_is_superset": true
                        }
                    }
                }
            }
        }
    }
}

搜尋得到的結果如:

熱詞統計分析

雖然在返回的片語中依然存在不相關的,但是可以透過配置exclude和include動態的去實現遮蔽或者增加新的片語。也可以從長遠考慮的角度上將無關的詞配置到ik的stopwords。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章