Python 聚类算法的编程结构是什么
我正在尝试实现以下(分裂)聚类算法(以下是该算法的简短形式,完整描述可用): 从样本x开始,i=1,…,n被视为n个数据点的单个簇,并为所有点对定义了相异矩阵D。修复一个阈值T,用于决定是否拆分群集Python 聚类算法的编程结构是什么,python,data-structures,cluster-analysis,hierarchical-clustering,Python,Data Structures,Cluster Analysis,Hierarchical Clustering,我正在尝试实现以下(分裂)聚类算法(以下是该算法的简短形式,完整描述可用): 从样本x开始,i=1,…,n被视为n个数据点的单个簇,并为所有点对定义了相异矩阵D。修复一个阈值T,用于决定是否拆分群集 首先确定所有数据点对之间的距离,并选择它们之间距离最大(Dmax)的一对 比较Dmax和T。如果Dmax>T,则使用所选对作为两个新簇中的第一个元素,将单个簇一分为二。剩下的n-2个数据点被放入两个新集群中的一个。如果D(x_i,x_l)=2: 实际值=构造新记录(距离,结果[i]) 最大动作=最大
# Read data from GitHub
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/nico/collectiveintelligence-book/master/blogdata.txt', sep = '\t', index_col = 0)
data = df.values.tolist()
data = data[1:10]
# Define correlation coefficient as distance of choice
def pearson(v1, v2):
# Simple sums
sum1 = sum(v1)
sum2 = sum(v2)
# Sums of the squares
sum1Sq = sum([pow(v, 2) for v in v1])
sum2Sq = sum([pow(v, 2) for v in v2])
# Sum of the products
pSum=sum([v1[i] * v2[i] for i in range(len(v1))])
# Calculate r (Pearson score)
num = pSum - (sum1 * sum2 / len(v1))
den = sqrt((sum1Sq - pow(sum1,2) / len(v1)) * (sum2Sq - pow(sum2, 2) / len(v1)))
if den == 0: return 0
return num / den
# Find largest distance
dist={}
max_dist = pearson(data[0], data[0])
# Loop over upper triangle of data matrix
for i in range(len(data)):
for j in range(i + 1, len(data)):
# Compute distance for each pair
dist_curr = pearson(data[i], data[j])
# Store distance in dict
dist[(i, j)] = dist_curr
# Store max distance
if dist_curr > max_dist:
max_dist = dist_curr
编辑2:下面粘贴的是来自Dschoni答案的函数
# Euclidean distance
def euclidean(x,y):
x = numpy.array(x)
y = numpy.array(y)
return numpy.sqrt(numpy.sum((x-y)**2))
# Create matrix
def dist_mat(data):
dist = {}
for i in range(len(data)):
for j in range(i + 1, len(data)):
dist[(i, j)] = euclidean(data[i], data[j])
return dist
# Returns i & k for max distance
def my_max(dict):
return max(dict)
# Sort function
list1 = []
list2 = []
def sort (rcd, i, k):
list1.append(i)
list2.append(k)
for j in range(len(rcd)):
if (euclidean(rcd[j], rcd[i]) < euclidean(rcd[j], rcd[k])):
list1.append(j)
else:
list2.append(j)
结果如下:
[24]、[17]、[4]、[7]、[40]、[13]、[14]、[15]、[26、27、38]、[3、16、,
39], [25], [42], [18, 20, 45], [43], [1, 2, 11, 46], [12, 37, 41],
[5], [21], [22], [10, 23, 28, 29], [6, 34, 48], [0, 8, 33, 36, 44],
[31]、[32]、[19]、[30]、[35]、[9,47]]
一些数据点仍然聚集在一起。我通过向排序
函数中的实际
字典添加少量数据噪声来解决此问题:
# Add small random noise
for key in actual:
actual[key] += np.random.normal(0, 0.005)
你知道如何正确地解决这个问题吗?欧几里德距离的正确工作示例:
import numpy as np
#For random number generation
def create_distance_list(l):
'''Create a distance list for every
unique tuple of pairs'''
dist={}
for i in range(len(l)):
for k in range(i+1,len(l)):
dist[(i,k)]=abs(l[i]-l[k])
return dist
def maximum(distance_dict):
'''Returns the key of the maximum value if unique
or a random key with the maximum value.'''
maximum = max(distance_dict.values())
max_key = [key for key, value in distance_dict.items() if value == maximum]
if len(max_key)>1:
random_key = np.random.random_integers(0,len(max_key)-1)
return (max_key[random_key],)
else:
return max_key
def construct_new_dict(distance_dict,index_list):
'''Helper function to create a distance map for a subset
of data points.'''
new={}
for i in range(len(index_list)):
for k in range(i+1,len(index_list)):
m = index_list[i]
n = index_list[k]
new[(m,n)]=distance_dict[(m,n)]
return new
def sort(distance_dict,idl,threshold=4):
result=[idl]
i=0
try:
while True:
if len(result[i])>=2:
actual=construct_new_dict(dist,result[i])
act_max=maximum(actual)
if distance_dict[act_max[0]]>threshold:
j = act_max[0][0]
k = act_max[0][1]
result[i].remove(j)
result[i].remove(k)
l1=[j]
l2=[k]
for iterr in range(len(result[i])):
s = result[i][iterr]
if s>j:
c1=(j,s)
else:
c1=(s,j)
if s>k:
c2=(k,s)
else:
c2=(s,k)
if actual[c1]<actual[c2]:
l1.append(s)
else:
l2.append(s)
result.remove(result[i])
#What to do if distance is equal?
l1.sort()
l2.sort()
result.append(l1)
result.append(l2)
else:
i+=1
else:
i+=1
except:
return result
#This is the dataset
a = [1,2,2.5,5]
#Giving each entry a unique ID
idl=range(len(a))
dist = create_distance_list(a)
print sort(dist,idl)
将numpy导入为np
#用于生成随机数
def创建距离列表(l):
''为每个项目创建一个距离列表
对“”的唯一元组
dist={}
对于范围内的i(len(l)):
对于范围(i+1,len(l))中的k:
dist[(i,k)]=abs(l[i]-l[k])
返回区
def最大值(距离):
''如果唯一,则返回最大值的键
或具有最大值的随机键。“”
最大值=最大值(距离值()
max\u key=[键对键,距离中的值\u dict.items(),如果值==最大值]
如果len(最大键)>1:
random\u key=np.random.random\u整数(0,len(max\u key)-1)
返回(最大密钥[随机密钥],)
其他:
返回max_键
定义构造新目录(距离目录、索引列表):
''帮助函数为子集创建距离贴图
数据点的数量
新={}
对于范围内的i(len(索引列表)):
对于范围内的k(i+1,len(索引列表)):
m=索引列表[i]
n=索引列表[k]
新的[(m,n)]=距离
还新
def排序(距离、idl、阈值=4):
结果=[idl]
i=0
尝试:
尽管如此:
如果len(结果[i])>=2:
实际值=构造新记录(距离,结果[i])
最大动作=最大(实际)
如果距离[act\U max[0]]>阈值:
j=最大值[0][0]
k=最大值[0][1]
结果[i]。删除(j)
结果[i]。删除(k)
l1=[j]
l2=[k]
对于范围内的iterr(len(结果[i]):
s=结果[i][iterr]
如果s>j:
c1=(j,s)
其他:
c1=(s,j)
如果s>k:
c2=(k,s)
其他:
c2=(s,k)
如果实际[c1]
一些数据点仍然聚集在一起。我用计算机解决这个问题
向排序中的实际字典添加少量数据噪声
功能
如果Dmax>T,则将单个集群一分为二
您的描述不一定会创建n
集群。
如果集群有两条距离小于T
的记录,
它们将聚集在一起(我是否遗漏了什么?我不完全确定如何回答所问的问题。如果您指的是数据结构,那么您的算法的哪些部分需要结构,以及对数据结构的要求是什么?如果您只想重复拆分元素集合,而不关心数据最终是如何表示的,那么数组或链表可能会起作用。或者,你可以考虑某种形式的树(像二进制搜索树)。我只需要重复地分割数据点。我想一个数组就足够了。你知道从哪里开始/如何开始吗?你有一种编程语言吗?你有一个算法,所以你只需要把算法的步骤转换成一些代码。我想从编写函数开始。我用Python编程,但不管哪种语言都可以。我只需要两个人的帮助。三,。我附加了我最初尝试的代码。我在上面粘贴了适当的函数。你能帮我处理排序函数中的递归吗?你需要按层次顺序排列的簇吗?或者仅仅是集群?结果是将输入中数据列表的索引聚集在一起。如果您需要数据值,只需将索引列表中的每个值设置为输入列表的值。您能告诉我这是否是您要查找的吗?是的,这正是我要查找的。谢谢
import numpy as np
#For random number generation
def create_distance_list(l):
'''Create a distance list for every
unique tuple of pairs'''
dist={}
for i in range(len(l)):
for k in range(i+1,len(l)):
dist[(i,k)]=abs(l[i]-l[k])
return dist
def maximum(distance_dict):
'''Returns the key of the maximum value if unique
or a random key with the maximum value.'''
maximum = max(distance_dict.values())
max_key = [key for key, value in distance_dict.items() if value == maximum]
if len(max_key)>1:
random_key = np.random.random_integers(0,len(max_key)-1)
return (max_key[random_key],)
else:
return max_key
def construct_new_dict(distance_dict,index_list):
'''Helper function to create a distance map for a subset
of data points.'''
new={}
for i in range(len(index_list)):
for k in range(i+1,len(index_list)):
m = index_list[i]
n = index_list[k]
new[(m,n)]=distance_dict[(m,n)]
return new
def sort(distance_dict,idl,threshold=4):
result=[idl]
i=0
try:
while True:
if len(result[i])>=2:
actual=construct_new_dict(dist,result[i])
act_max=maximum(actual)
if distance_dict[act_max[0]]>threshold:
j = act_max[0][0]
k = act_max[0][1]
result[i].remove(j)
result[i].remove(k)
l1=[j]
l2=[k]
for iterr in range(len(result[i])):
s = result[i][iterr]
if s>j:
c1=(j,s)
else:
c1=(s,j)
if s>k:
c2=(k,s)
else:
c2=(s,k)
if actual[c1]<actual[c2]:
l1.append(s)
else:
l2.append(s)
result.remove(result[i])
#What to do if distance is equal?
l1.sort()
l2.sort()
result.append(l1)
result.append(l2)
else:
i+=1
else:
i+=1
except:
return result
#This is the dataset
a = [1,2,2.5,5]
#Giving each entry a unique ID
idl=range(len(a))
dist = create_distance_list(a)
print sort(dist,idl)