去年年初的时候,我曾经发布过某专业课期末作业研究过程中带来的一个有趣的副产品:汉字的字义网络图。不过,当时我是直接调用的 Mathematica 的相关函数,函数几乎不能调整参数,并且也无法处理边上权重不同的情况。最近在研究引力斥力绘图算法,突然想到把当时的数据重新画一张图。于是就有了汉字地图第二版(点击小图看大图):
还是简述一下整个图的制作方法吧。我们的基本依据就是,在全唐诗中,经常对偶的字往往都有非常密切的关系。于是,我们首先找出全唐诗中的对偶字:
1. 从全唐诗中提取所有处于对偶位置的字对(不管这些字对实际上是否是对偶的);
2. 利用 Bayesian 评分系统 给字对的对偶程度评分;
3. 选出对偶评分最高的 8000 个字对;
4. 随机指定所有涉及到的字在图中的初始位置。
现在,假设每两个字之间都有斥力,这些斥力大小都符合 Coulomb 定律,即斥力大小与距离的平方成反比。另外,再假设那 8000 个字对之间都有一根橡皮筋,它所带来的引力大小符合 Hooke 定律,其中字对的对偶评分越高,橡皮筋的倔强系数越大(或者说橡皮筋越强劲)。现在,假设把整个系统往桌面上一放,这些字就会在引力斥力的作用下弹过去弹过来,静止时应该就有很好的聚类效果了。不过这里有一个问题——谁说这个系统最终一定会静止下来?考虑两个点和一根橡皮筋的情况,它们最终会吸引、排斥、吸引、排斥,做出重复性的周期运动,毕竟机械能守恒嘛。那为什么在实际情况下,这个系统会静止下来呢?原因很简单,因为在实际情况下,系统会有能量损耗(比如摩擦力)。因此,我们必须假设系统每时每刻都有一定比例的能量损耗,具体落实下来,便是给每个字的实际运动速度强制性地打折扣。这样,这些字的位置最终才能收敛起来。下面,我们需要模拟这个物理过程。
5. 按照 0.01 个单位时间的间隔迭代 1000 次,不断更新每个字的受力、速度和位置;
6. 按照计算出来的结果绘图,并在 8000 个字对之间连线,连线颜色越深表示对偶评分越高。
其中,前面 3 步是用 Mathematica 实现的,与物理模拟有关的步骤是用 Python 实现的( Mathematica 太慢了),最后的绘图工作又重新交给了 Mathematica 。这个绘图算法的缺点就是运行效率太低,即使使用 Python ,迭代 1000 次也需要用大概一整夜的时间。我试了一些不同的参数(每跑一次都需要一整夜的时间),在第三次得到了比较令人满意的结果。其实和当初直接用 Mathematica 生成的结果相比,也好不到哪里去,不过我还是挺高兴的。首先,图上用不同的颜色表现出了不同权重的边,看起来更好看了。另外,整个过程更加透明,我也更加心安一些。当然,值得改进的地方还挺多的,不知道各位朋友有什么好的想法没。
哦,对了,赶在 11 月 26 日结束之前赶快发布。今天是 localhost_8080 的生日,在这里祝她生日快乐。
sofa?
赞一个!数学就是该学以致用
看到物理模拟,我决定不再潜水了,第一次在这里留言……
提个点子:用显卡来做物理模拟~比如用CUDA,OpenCL什么的,用DirectX,OpenGL什么的也可以……
哪位高手有闲来实现一下?
估计比用python至少能快2个数量级?
想法挺不错,,,好玩。。。
哦 太神奇了
希望能放出一个PDF的版本来,这样更容易搜索之类的
不同的斥力系数跟倔强系数比会导致不同的图象,而不同的初始位置也可能会导致形成不同的图象吧,只是猜测。谁来建哈密顿方程看看。
不错,很壮观。数字聚在了一起,东南西北也聚在了一起。
是不是唐人比较讨厌 东
西南北几乎等距,但是东相对远
只是一个感觉 要在这么大图片里面检索到一个特定的字不容易啊
哈哈,很不错,自然景物聚在一起,数词聚在一起,东南西北聚在一起,还有一堆虚词聚在一起。
西南北几乎等距,但是东相对远,可能是因为初始值的原因,东被内、太两个字挡住了,未能继续靠近。估计是系统达到了局部最优,但是没达到全局最优。
牛X,但是使用起来并不方便
那些个量词好靠近
正如11所说,全局最优这种东西有可能求解么
另外考虑到人为加入的衰减,这个最终状态一定是唯一的吗?
说到引力斥力算法,我一下子就想到了你之前推荐过的Ubigraph,可惜该项目的server部分的license很那个啥,并且停滞在alpha阶段就不更新了。球类似物/替代品=w=
能不能3D一下?
这图太文艺了。。求普通版和二逼版
建议试试看先用很弱的斥力迭代,再加强到正常的斥力。或许会是个好办法。
说个题外话:看到这张图时,我反而产生了一种“我竟然认识这么多个文字”的感觉,换做是不认识的语言中有这么多符号的话,我一定没有认全的自信。
请看一下我最近在做的图……还有,同学你是文科生出生么?如果是,花时间进入定量用了多久?
呵呵,我的本科论文有一个章节提出的就是你的方法,引力斥力方法,有兴趣给我发个邮件,我给你传看下,共勉!
如果在三维空间得到的结果是不是应该更好?或者更高维,减弱二维下受初始状态的影响,然后把结果向低维投影可否?
以系统势能为依据,运用模拟退火?
http://web.mit.edu/newsoffice/2011/large-data-sets-algorithm-1216.html
最近Science上的一篇文章,我怎么觉得想法跟这个差不多呢……
接下来是不是又要做CSDN密码的统计了呢?….
接下来是不是又要做CSDN密码的统计了呢?…(笑
写得不错。
可以把C/C++嵌入python 一个程序的限速部分一般只有20%不到 ,把那部分换成C就可以了
python迭代的速度大约是C的几百分之一 我验证过
太文艺了,
引力斥力绘图算法,描述的形象生动、言简意赅,学习了。
Articles like these put the consumer in the driver seat-very imttopanr.
Howdy! This is my 1st comment here so I just wanted to give a quick shout out and say
I genuinely enjoy reading your blog posts. Can you recommend any other blogs/websites/forums that cover the same topics?
Appreciate it!