【问题标题】:clickhouse approach for word frequency count on textual field文本字段上单词频率计数的 clickhouse 方法
【发布时间】:2020-03-09 09:39:16
【问题描述】:

我有一个 Clickhouse 表,其中一个字段包含文字说明(约 300 个字)。

例如评论:

Rev_id    Place_id    Stars    Category    Text
1         12           3        Food       Nice food but a bad dirty place.
2         31           4        Sport      Not bad, they have everything.
3         55           1        Bar        Poor place,bad audience.

我想做一些字数分析,例如一般字频计数(每个单词出现了多少次)或每个类别的前 K 个单词。

在示例中:

word    count
bad     3
place   2

... 有没有办法只在 ClickHouse 中完成而不涉及编程语言?

【问题讨论】:

    标签: word-count clickhouse


    【解决方案1】:
    SELECT
        arrayJoin(splitByChar(' ', replaceRegexpAll(x, '[.,]', ' '))) AS w,
        count()
    FROM
    (
        SELECT 'Nice food but a bad dirty place.' AS x
        UNION ALL
        SELECT 'Not bad, they have everything.'
        UNION ALL
        SELECT 'Poor place,bad audience.'
    )
    GROUP BY w
    ORDER BY count() DESC
    
    ┌─w──────────┬─count()─┐
    │            │       4 │
    │ bad        │       3 │
    │ place      │       2 │
    │ have       │       1 │
    │ Poor       │       1 │
    │ food       │       1 │
    │ Not        │       1 │
    │ they       │       1 │
    │ audience   │       1 │
    │ Nice       │       1 │
    │ but        │       1 │
    │ dirty      │       1 │
    │ a          │       1 │
    │ everything │       1 │
    └────────────┴─────────┘
    
    
    SELECT CATEGORY, ....
    GROUP BY CATEGORY, w
    

    【讨论】:

      【解决方案2】:

      如果它适用于您的情况,我会考虑使用alphaTokens 作为更有效的方法。

      SELECT
          category,
          arrayJoin(arrayFilter(x -> NOT has(['a', 'the', 'but' /*.. exclude stopwords */], x), alphaTokens(text))) token,
          count() count
      FROM
      (
          /* test data */
          SELECT data.1 AS rev_id, data.2 AS place_id, data.3 AS stars, data.4 AS category, data.5 AS text
          FROM
          (
              SELECT arrayJoin([
                (1, 12, 3, 'Food', 'Nice      food but a bad dirty place.'), 
                (4, 12, 3, 'Food', ' the the the the good food   ..'), 
                (2, 31, 4, 'Sport', 'Not bad,,, they have everything.'), 
                (3, 55, 1, 'Bar', 'Poor place,bad audience..')]) AS data
          )
      )
      GROUP BY category, token
      ORDER BY count DESC
      LIMIT 5;
      /*
      ┌─category─┬─token────┬─count─┐
      │ Food     │ food     │     2 │
      │ Food     │ bad      │     1 │
      │ Bar      │ audience │     1 │
      │ Food     │ Nice     │     1 │
      │ Bar      │ Poor     │     1 │
      └──────────┴──────────┴───────┘
      */
      

      topK使用示例:

      SELECT
          category,
          arrayReduce('topK(3)', 
                      arrayFilter(x -> (NOT has(['a', 'the', 'but' /*.. exclude stopwords */], x)), groupArrayArray(alphaTokens(text)))) AS result
      FROM
      (
          /* test data */
          SELECT data.1 AS rev_id, data.2 AS place_id, data.3 AS stars, data.4 AS category, data.5 AS text
          FROM
          (
              SELECT arrayJoin([
                (1, 12, 3, 'Food', 'Nice      food but a bad dirty place.'), 
                (4, 12, 3, 'Food', ' the the the the good food   ..'), 
                (2, 31, 4, 'Sport', 'Not bad,,, they have everything.'), 
                (3, 55, 1, 'Bar', 'Poor place,bad audience..')]) AS data
          )
      )
      GROUP BY category;
      /* result
      ┌─category─┬─result─────────────────┐
      │ Bar      │ ['Poor','place','bad'] │
      │ Food     │ ['food','Nice','bad']  │
      │ Sport    │ ['Not','bad','they']   │
      └──────────┴────────────────────────┘
      */
      
      

      ps:在处理之前可能对lower所有字符串/令牌有意义

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-05
        • 1970-01-01
        • 1970-01-01
        • 2011-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多