查找一组文本消息后出现的频繁模式的算法

时间:2019-06-20 09:31:37

标签: algorithm nlp cluster-analysis text-classification unsupervised-learning

我有很多短信。我想找到带有这些消息的常用模式(例如20种最常见的模式)。消息示例:

msg1 = "Rahul, Your New Delhi (NDLS) - Agra Cantt (AGC) train booking is confirmed.\nPNR: 1234567890\nBooking ID: ABCDE123456789012\nView your Trip Here: https://xyz.app.link/A0b1cDEFGH\nFor any queries please write to some_url.com.\n\nHappy with our service? Rate us 5 stars: https://xyz.app.link/e/5stars"
msg2 = "Shyamu, Your Tenali Jn (TEL) - Secunderabad Jn (SC) train booking is confirmed.\nPNR: 2345678901\nBooking ID: ABCDE123456789011\nView your Trip Here: https://xyz.app.link/Ab0cdEFGHI\nFor any queries please write to some_url.com.\n\nHappy with our service? Rate us 5 stars: https://xyz.app.link/e/5stars"
msg3 = "Ramu, Sorry! Booking for your Jammu Tawi (JAT) - Kurukshetra Jn (KKDE) train with Booking ID: ABCDE123456789013 could not be confirmed due to payment failure.If money has been deducted from your account, your money will automatically be refunded to your account within 5 days.\nRe-book your ticket https://xyz.app.link/a0B1cDEFGH"

您可以看到msg1和msg2共享相同的模式/模板(见下文),而msg3不同(可能还有其他消息与msg3共享模式)。我的要求是在我的数据中找到如此频繁的模板。对于上面的示例,模式/模板如下:

"<> Your <> - <> train booking is confirmed.\nPNR: <> ID: <> your Trip Here: <> any queries please write to some_url.com.\n\nHappy with our service? Rate us 5 stars: https://xyz.app.link/e/5stars"

我尝试了以下操作:

  1. 使用CountVectorizer对文本数据进行矢量化。
  2. 使用DBSCAN集群查找所有集群,并根据集群大小进行排序。
  3. 对于前20个集群:

    i)选择10条随机消息。

    ii)使用一些字符串操作找到跟随它们的模式。

以上方法有效,但是聚类似乎是瓶颈,需要花费大量时间。 (我的系统上的100000条消息大约需要10分钟)

用于查找簇的Python函数:

from sklearn.cluster import DBSCAN
import collections

def find_cluster(M_vector):
    # M_vector: Vectorized messages
    dbscan = DBSCAN(eps = 2, min_samples = 5)
    cls = dbscan.fit_predict(M_vector)
    count_dict = collections.Counter(cls)
    count_dict = sorted(count_dict.items(), key = lambda kv:(kv[1], kv[0]), reverse = True)
    return cls, count_dict

我觉得无需使用机器学习就可以解决问题,但是我不知道如何在更短的时间内完成结果。最糟糕的情况是,DBSCAN的时间复杂度似乎是O(n^2)(平均O(nlog(n)))。

我认为使用Wagner-Fischer算法将导致更长的时间,因为它将对每条消息以及其他每条消息进行计算(时间O(n^2))。

2 个答案:

答案 0 :(得分:0)

由于您拥有所有数据,并且该数据属于封闭集,因此您的问题是closed worldopen world。我不会在封闭世界问题上使用神经网络。

如果这是我的问题,我会

  1. 隔离定界符。根据您的样本输入,它看起来很简单whitespace
  2. 将基于delimiters的每个输入解析为tokens,并将标记的连接与每个标记的计数放置在图形中。我认为根据给定的示例数据,它应该是DAG
  3. 然后在图形中找到abstract syntax tress(AST)。我知道这需要更多的解释,但是我不想花几个小时来回答这个问题。付出比不付出更好。 :)
  4. 使用您在问题中指出的变量标识符替换AST中变化的令牌,例如<>

由于我整天都在Prolog中使用DCG,所以这个问题对我来说似乎很直观,但是对于某些不了解此问题的人来说,这个问题似乎daunting

也可以用笔和纸手工做一些示例,以便在编写代码之前先理解它们。如果您只花笔和纸来花时间就可以掌握全局和细节,那么编写代码并进行破解就毫无意义。

如果这是用于家庭作业,请先与您的老师讨论,因为他们可能不接受这作为答案,因为这可能会喊叫您获得帮助。

答案 1 :(得分:0)

在这样的数据上,sklearn中的索引将无济于事,您实际上将获得O(n²)运行时。您应该对文本使用倒排索引!您可以更有效地找到相似的文档。

出于模板生成的目的,我将使用另一种方法。使用minhash,这是一种用于查找几乎重复的网页的技术,但请对其参数进行调整以使其容忍得多。然后检查非常频繁的哈希。这些对应于许多文本中出现的共享词。

这将只有O(n)个运行时。