如何对一组字符串进行聚类?

我的数据集看起来像这样

[”, ‘ABCDH’, ”, ”, ‘H’, ‘HHIH’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘FECABDAI’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘FABHJJFFFFEEFGEE’, ‘FFFF’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘FF’, ‘F’, ‘FF’, ‘F’, ‘F’, ‘FFFFFFIFF’, ”, ‘FFFFFFF’, ‘F’, ”, ”, ‘F’, ”, ”, ”, ”, ”, ”, ”, ‘F’, ”, ”, ‘ABB’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘FF’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘F’, ‘FFEIE’, ‘FF’, ‘ABABCDIIJCCFG’, ”, ‘FABACFFF’, ‘FEGGIHJCABAGGFEFGGFEECA’, ”, ‘FF’, ‘FFGEFGGFFG’, ‘F’, ‘FFF’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘I’, ”, ”, ‘ABIIII’, ”, ”, ”, ”, ‘I’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘AAAAA’, ‘AFGFE’, ‘FGFEEFGFEFGFEFGJJGFEACHJ’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘JFEFFFFFFF’, ”, ‘AAIIJFFGEFGCABAGG’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘F’, ‘JFJFJFJ’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘F’, ”, ”, ”, ”, ”, ”, ”, ”, ‘F’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ‘F’, ‘FGFEFGFE’, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”, ”]

这只是一个样本,但我会有很多更多的字符串。我该如何对它们进行聚类,使得每个聚类都有一些模式?


回答:

我提出的想法源自文本处理、自然语言处理和信息检索,并且在处理像基因信息这样的字符/信息序列时被广泛使用。因为你需要保留序列,我们可以使用n-gram的概念。我在下面的例子中使用了二元组,尽管你可以推广到更高阶的n-gram。N-gram有助于保留数据中的顺序模式。别担心——我们经常从其他科学领域借用想法——即使是编辑距离和动态规划最初也不是计算机科学的概念。

解决这个问题有许多可能的方法——每一种都是独特的,没有一种是正确的——至少没有足够的研究证明哪一种是正确的。这是我的看法。

所以目标是根据你的数据字符串创建一个类似词袋的向量——这些向量可以很容易地输入到任何机器学习工具或库中进行聚类。步骤的简要总结如下:

  1. 收集二元组(以及一元组等)
  2. 创建一个字典来获取词袋(附带代码)
  3. 创建从字符串获取向量的功能

让我们开始吧

import numpyfrom sklearn.cluster import KMeansdef getStringBigrams(string):    if len(string) <= 0: return []    if len(string) == 1: return string[0] # 处理只有一个字符的字符串 = 提取一元组    return [string[i]+string[i+1] for i in range(len(string)-1)]def getDataBigrams(strings):    return [getStringBigrams(x) for x in strings]

所以这里这些函数会将给定的字符串转换为一组两个字符(如果只有一个字符则提取单个字符)。你可以修改它们来捕获三元组甚至是所有可能的一元、二元和三元组。请随意实验。

现在如何将字符串转换为向量?我们将定义一个函数,该函数将字符串转换为向量,并考虑特定n-gram出现的次数。这被称为词袋。这里,这些是屏幕袋。以下两个函数可以帮助你实现这一点:

def generateDictionary(data):    '''    此函数识别数据中的唯一n-gram。    '''    vocab = set()    for line in data:        for item in line:            vocab.add(item)    dictionary = {}    i=0    for item in vocab:        dictionary[item] = i        i+=1    return dictionary    def doc2Bow(bigramData, dictionary):    '''     将单个文档以二元组格式转换为向量    '''    vect = [0]*len(dictionary) # 初始化向量为零    for gram in bigramData:        vect[dictionary[gram]]+=1    return numpy.asarray(vect)  # 转换为numpy向量

好了!我们完成了。现在将你的数据向量输入到你选择的任何K-Means实现中。我使用了SKLearn。

strings = ['', 'ABCDH', '', '', 'H', 'HHIH', '', '', '', '', '', '', '', '', '', '', '', 'FECABDAI', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'FABHJJFFFFEEFGEE', 'FFFF', '', '', '', '', '', '', '', '', '', 'FF', 'F', 'FF', 'F', 'F', 'FFFFFFIFF', '', 'FFFFFFF', 'F', '', '', 'F', '', '', '', '', '', '', '', 'F', '', '', 'ABB', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'FF', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'F', 'FFEIE', 'FF', 'ABABCDIIJCCFG', '', 'FABACFFF', 'FEGGIHJCABAGGFEFGGFEECA', '', 'FF', 'FFGEFGGFFG', 'F', 'FFF', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'I', '', '', 'ABIIII', '', '', '', '', 'I', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'AAAAA', 'AFGFE', 'FGFEEFGFEFGFEFGJJGFEACHJ', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'JFEFFFFFFF', '', 'AAIIJFFGEFGCABAGG', '', '', '', '', '', '', '', '', '', 'F', 'JFJFJFJ', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'F', '', '', '', '', '', '', '', '', 'F', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'F', 'FGFEFGFE', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']

你应该选择从文件中读取字符串

strings = [x for x in strings if len(x) > 0] # 仅为实验目的进行清理nGramData = getDataBigrams(strings)dictionary = generateDictionary(nGramData)data = [doc2Bow(nGramData[i], dictionary) for i in range(len(nGramData))]K = 10km = KMeans(init='k-means++', n_clusters=K, n_init=10)km.fit(data)

然后我最终可以使用KMeans类的km.labels_属性查看我的聚类是什么样的。

这里是你的聚类。查看控制台(底部)窗口 – 有十个聚类。enter image description here

现在你可以修改我在代码中编写的特征生成,并查看你的修改效果如何。与其只提取二元组,不如提取所有可能的一元、二元和三元组,并使用它们来创建词袋。这将有显著的不同。你还可以使用字符串的长度作为一个特征。你还可以尝试其他算法,包括层次聚类。请务必在修改后将更新的结果发送给我。

享受吧!

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注