我的数据集看起来像这样
['','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',' ', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '一世' ,'','','ABIIII','','','','','我','','','','','','','',''' ,'','','','','','','','','','','AAAAA','AFGFE','FGFEEFGFEFGFEFGJJGFEACHJ','','',' ','','','','','','','','','','','','','',''','','', “ ','JFEFFFFFFF','','AAIIJFFGEFGCABAGG','','','','','','','','','','F','JFJFJFJ','' ,'','','','','','','','','','','','','','','','','',' ','','','F','','','','','','','','','F','','','',' ','','','','','','','','','','','','','',''','','', '','','','','','','','','','','','','','',''','',''' ,'','','','','','','','','','','','','','','','','',' ','','','','','','','','','','','','','',''','','', '','','','','','','','','','','','','','',''','',''' ,'','','','','','','','','F','FGFEFGFE','','','','','',''' ,'','','','','','','','','','','','','','','','','',' ','','','','','','','','','','','','','',''','','', '','','','','','','','','','','','','','',''','',''' ,'','','','','','','','','','','','','','','','','',' ','','','','','','','','','','','','','',''','','', '','','','','','','','', '','','','','','']
这只是一个示例,但我会有更多的字符串。我如何对它们进行聚类,使每个聚类都有一些模式
答案 0 :(得分:2)
我建议的想法源于文本处理,NLP和信息检索,并且在您拥有遗传信息等字符/信息序列的情况下非常广泛使用。因为你必须保留序列,我们可以使用n-gram的概念。我在下面的例子中使用了bi-gram,尽管你可以推广更高阶的克数。 N-gram有助于保留数据中的顺序模式。别担心 - 我们不断借鉴其他科学领域的想法 - 即使编辑距离和动态编程也不是计算机科学概念。
有许多可能的方法可以解决这个问题 - 每一个都是独一无二的,而且没有正确的方法 - 至少没有足够的研究来证明哪一个是正确的。这是我的看法。
因此,我们的目标是从数据字符串中创建一个像矢量一样的词袋 - 这些矢量可以很容易地输入到任何机器学习工具或库中进行聚类。步骤的快速摘要: -
让我们开始吧
import numpy
from sklearn.cluster import KMeans
def getStringBigrams(string):
if len(string) <= 0: return []
if len(string) == 1: return string[0] # Handle strings with only one character = extract unigram
return [string[i]+string[i+1] for i in range(len(string)-1)]
def getDataBigrams(strings):
return [getStringBigrams(x) for x in strings]
所以这里这些函数会将给定的字符串转换为一组两个字符(如果只有一个字符,则为单个字符)。您可以修改它们以捕获3克甚至完整的所有可能的单,双和三克。随意尝试。
现在如何将字符串转换为向量?我们将定义一个函数,它将字符串转换为向量,负责处理特定n-gram出现的次数。这被称为BAG OF WORDS。在这里,这些是屏幕包。以下两个功能可以帮助您:
def generateDictionary(data):
'''
This function identifies unique n-grams in your data.
'''
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):
'''
Take single document in bigram format and return a vector
'''
vect = [0]*len(dictionary) # Initialize vector to zero
for gram in bigramData:
vect[dictionary[gram]]+=1
return numpy.asarray(vect) # Convert to numpy vector
瞧!我们完成了。现在将数据向量提供给您选择的任何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] # Just cleanup for experiment purpose
nGramData = getDataBigrams(strings)
dictionary = generateDictionary(nGramData)
data = [doc2Bow(nGramData[i], dictionary) for i in range(len(nGramData))]
K = 10
km = KMeans(init='k-means++', n_clusters=K, n_init=10)
km.fit(data)
然后我终于使用KMeans类的km.labels_属性看到了我的簇的样子。
这是你的集群。查看控制台(底部)窗口 - 有十个集群。
现在,您可以修改我在代码中编写的功能生成,并查看修改的执行情况。而不仅仅是bigrams,提取所有可能的unigrams,bigrams和trigrams并使用它们来创建BOW。会有显着差异。您还可以使用字符串的长度作为功能。您还可以尝试其他算法,包括层次聚类。修改后请务必向我发送最新结果。
享受!