Python中的六边形自组织映射
我在找关于六边形的自组织映射的Python实现。
- 有没有现成的模块?如果有的话。
- 怎么绘制六边形单元。
- 有没有算法可以把六边形单元当作数组或者其他东西来处理。
关于: 自组织映射(SOM)或者自组织特征映射(SOFM)是一种人工神经网络,它通过无监督学习来训练,目的是生成一个低维度的(通常是二维的)表示。
2 个回答
8
我知道这个讨论已经有4年了,不过我在网上没有找到一个令人满意的答案。
假设你有一个数组,用来把输入映射到神经元,还有一个二维数组,表示每个神经元的位置。
比如可以考虑这样的例子:
hits = array([1, 24, 14, 16, 6, 11, 8, 23, 15, 16, 15, 9, 20, 1, 3, 29, 4,
32, 22, 7, 26, 26, 35, 23, 7, 6, 11, 9, 18, 17, 22, 19, 34, 1,
36, 3, 31, 10, 22, 11, 21, 18, 29, 3, 6, 32, 15, 30, 27],
dtype=int32)
centers = array([[ 1.5 , 0.8660254 ],
[ 2.5 , 0.8660254 ],
[ 3.5 , 0.8660254 ],
[ 4.5 , 0.8660254 ],
[ 5.5 , 0.8660254 ],
[ 6.5 , 0.8660254 ],
[ 1. , 1.73205081],
[ 2. , 1.73205081],
[ 3. , 1.73205081],
[ 4. , 1.73205081],
[ 5. , 1.73205081],
[ 6. , 1.73205081],
[ 1.5 , 2.59807621],
[ 2.5 , 2.59807621],
[ 3.5 , 2.59807621],
[ 4.5 , 2.59807621],
[ 5.5 , 2.59807621],
[ 6.5 , 2.59807621],
[ 1. , 3.46410162],
[ 2. , 3.46410162],
[ 3. , 3.46410162],
[ 4. , 3.46410162],
[ 5. , 3.46410162],
[ 6. , 3.46410162],
[ 1.5 , 4.33012702],
[ 2.5 , 4.33012702],
[ 3.5 , 4.33012702],
[ 4.5 , 4.33012702],
[ 5.5 , 4.33012702],
[ 6.5 , 4.33012702],
[ 1. , 5.19615242],
[ 2. , 5.19615242],
[ 3. , 5.19615242],
[ 4. , 5.19615242],
[ 5. , 5.19615242],
[ 6. , 5.19615242]])
所以我用以下方法来实现:
from matplotlib import collections, transforms
from matplotlib.colors import colorConverter
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
def plot_map(hits, n_centers, w=10):
"""
Plot Map
"""
fig = plt.figure(figsize=(w, .7 * w))
ax = fig.add_subplot(111)
hits_count = np.histogram(hits, bins=n_centers.shape[0])[0]
# Discover difference between centers
collection = RegularPolyCollection(
numsides=6, # a hexagon
rotation=0, sizes=( (6.6*w)**2 ,),
edgecolors = (0, 0, 0, 1),
array= hits_count,
cmap = cm.winter,
offsets = n_centers,
transOffset = ax.transData,
)
ax.axis('off')
ax.add_collection(collection, autolim=True)
ax.autoscale_view()
fig.colorbar(collection)
return ax
_ = plot_map(som_classif, matrix)
最后我得到了这个输出:
编辑
这个代码的更新版本可以在 https://stackoverflow.com/a/23811383/575734 找到。
7
我对第一个问题没有答案,但可以给你一些关于第二和第三个问题的提示。在你的情况下,你并不是在建模一个真实的二维空间,而是在建模一个概念空间,这里有六个邻居的方块。这可以用方形的瓷砖来表示,瓷砖排成列,奇数列的瓷砖会向下移动半个方块的高度。我来试着画个简单的ASCII图:
___ ___ ___
| |___| |___| |___
|___| |___| |___| |
| |___| |___| |___|
|___| |___| |___| |
| |___| |___| |___|
|___| |___| |___| |
|___| |___| |___|
你可以很容易地看到,每个方块都有6个邻居(当然,边缘的方块除外)。这可以很简单地用一个二维数组来表示这些方块,而计算某个位置(i, j)上方块的坐标的规则也很简单,其中i是行,j是列:
如果j是偶数:
(i+1, j), (i-1, j), (i, j-1), (i, j+1), (i-1, j-1), (i+1, j-1)
如果j是奇数:
(i+1, j), (i-1, j), (i, j-1), (i, j+1), (i+1, j-1), (i+1, j+1)
(前四个项是相同的)