У меня есть следующий кросс-табличные данные:Визуальной кластеризации на основе сходства оценки
biz user1 user2 user3 user4
user
A 1 1 0 0
B 1 1 0 0
C 1 1 1 0
D 1 0 0 0
E 0 0 1 1
F 0 0 1 1
G 0 0 1 1
J 0 0 0 1
M 0 1 0 0
и с помощью ковариации превратить его в:
[ 1. , 0.75, 0.25, 0. ],
[ 0.75, 1. , 0.25, 0. ],
[ 0.25, 0.25, 1. , 0.75],
[ 0. , 0. , 0.75, 1. ]
Используя следующий код, я пытаюсь построить график этих данных :
import pandas as pd
import numpy as np
import networkx as nx
users=[]
user_s=[(x+',')*4 for x in ['user1', 'user2', 'user3', 'user4']]
for s in user_s:
users.extend([e for e in s.split(',') if e!=''])
X=[]
user_s=[(x+',')*4 for x in ['32.5', '32.2', '30.4', '31.5']]
for s in user_s:
X.extend([float(e) for e in s.split(',') if e!=''])
Y=[]
user_s=[(x+',')*4 for x in ['-110', '-110', '-115', '-114']]
for s in user_s:
Y.extend([float(e) for e in s.split(',') if e!=''])
dat=pd.DataFrame({'user':users,
'biz':['A', 'B', 'C', 'D', 'A', 'B', 'C', 'M', 'C', 'E', 'F', 'G', 'E', 'F', 'G', 'J'],
'X':X, 'Y':Y})
rel=pd.crosstab(dat.user, dat.biz, rownames=['biz'], colnames=['user']).transpose()
cov=np.dot(rel.transpose(), rel)/np.diag(np.dot(rel.transpose(), rel))
dat.groupby('user').mean()[['X', 'Y']]
dat.groupby('user').mean()[['X', 'Y']]
G=nx.Graph()
for i in rel.columns.tolist():
G.add_node(i, X=dat.loc[dat.user==i, 'X'].mean(), Y=dat.loc[dat.user==i, 'Y'].mean())
for i in np.arange(0, cov.shape[0]):
idx=np.where(cov[i,]>.0)[0].tolist() ##for column i, get index of cov values above quantile p
for j in idx:
if i!=j: #eliminates (0,0) as an edge bc its redundant
G.add_edge(rel.columns[i],
rel.columns[j],weight=cov[i,j],length=1/cov[i,j], width=cov[i,j])
centrality=nx.degree_centrality(G)
pos=nx.spring_layout(G)
nx.draw(G,pos, node_size=[centrality[key]*500 for key in centrality.keys()],
cm=plt.cm.Spectral,edge_cm=plt.cm.Blues,
width=[(x[2]['width']*2)**2 for x in G.edges(data=True)], alpha=.5)
nx.draw_networkx_labels(G,pos,fontsize=16)
Обратите внимание, что user1 и user2 сильно коррелированы, как и user3 и user4; в то время как связь между двумя кластерами слаба.
Я хочу сделать две вещи:
- Есть две группы имеют один и тот же цвет (сказать членство кластера)
- Есть расстояние между user1 & user2 быть меньше, чем между user1 и user3. Аналогично для user3 и user4.
Я новичок в графическом дизайне, поэтому, если вы можете предложить алгоритм, который поможет в кластеризации, я был бы очень благодарен.
Моя главная цель состоит в том, чтобы представить себе это в гораздо большем наборе данных (10k пользователей)
где вы получаете «веса»? – ethanenglish
@ethanenglish Весы исходят из нормализованной матрицы ковариации; выше приведен взвешенный граф. –