1,根据皮尔逊相关系数计算出所有点之间的距离,称之为目标距离。
2,将所有点随机投放在二维界面(Xi,Yi),计算出随机点之间的距离,称为当前距离。
3,计算误差值:(目标距离-当前距离)/当前距离。
4,根据误差值按比例位移,直到误差值最小为止,获得所有点的二维图形。
Python代码:
def scaledown(data, distance=pearson, rate=0.01): n = len(data) # 每对数据之间的皮尔逊距离 realdist = [[distance(data[i], data[j]) for j in range(n)] for i in range(0, n)] # 随机初始化二维空间位置 loc = [[random.random(), random.random()] for i in range(n)] fakedist = [[0.0 for j in range(n)] for i in range(n)] lasterror = None for m in range(0, 1000): # 寻找投影后的距离 for i in range(n): for j in range(n): fakedist[i][j] = sqrt(sum([pow(loc[i][x] - loc[j][x], 2) for x in range(len(loc[i]))])) # 移动节点 grad = [[0.0, 0.0] for i in range(n)] totalerror = 0 for k in range(n): for j in range(n): if j == k: continue # 误差值=(目标距离-差值)/差值 errorterm = (fakedist[j][k] - realdist[j][k]) / realdist[j][k] # 每个节点都需要根据误差的多少,按比例移动 grad[k][0] += ((loc[k][0] - loc[j][0]) / fakedist[j][k]) * errorterm grad[k][1] += ((loc[k][1] - loc[j][1]) / fakedist[j][k]) * errorterm # 总误差 totalerror += abs(errorterm) print (totalerror) # 如果移动后,结果跟坏,则结束 if lasterror and lasterror < totalerror: break lasterror = totalerror # 根据rate参数与grad值相乘结果,移动节点 for k in range(n): loc[k][0] -= rate * grad[k][0] loc[k][1] -= rate * grad[k][1] return loc