在Python中创建一个没有for循环的内核矩阵



我知道有其他帖子问类似的问题,但没有设法找到回答我的具体问题的东西。我有下面的代码:

def kernel_function(self, x1, x2):
h = 0.5
return np.exp(-(np.linalg.norm(x2 - x1)/h)**2)
for i, x1 in enumerate(train_x):
for j, x2 in enumerate(train_x):
K[i,j] = self.kernel_function(x1, x2)

,其中x1x2为形状为(2,)的数组。为了提高性能,我需要把它垂直化。我看了看np.fromfunction,np.outer,但它们似乎不是我要找的……

提前谢谢你。对不起,如果已经有一个答案在某处!

假设train_x具有以下格式:

>>> train_x = np.array(((-.2, -.1), (0, .1), (.2, 0), (.1, -.1)))

执行你的代码,你得到:

>>> np.set_printoptions(precision=2)
>>> K
[[1.   0.73 0.51 0.7 ]
[0.73 1.   0.82 0.82]
[0.51 0.82 1.   0.92]
[0.7  0.82 0.92 1.  ]]

你可以重塑train_x:

>>> train_x_cols = train_x.T.reshape(2, -1, 1)
>>> train_x_rows = train_x.T.reshape(2, 1, -1)

所以,多亏了广播,当你减去它们时,你得到了所有的组合:

>>> train_x_rows - train_x_cols
[[[ 0.   0.2  0.4  0.3]
[-0.2  0.   0.2  0.1]
[-0.4 -0.2  0.  -0.1]
[-0.3 -0.1  0.1  0. ]]
[[ 0.   0.2  0.1  0. ]
[-0.2  0.  -0.1 -0.2]
[-0.1  0.1  0.  -0.1]
[ 0.   0.2  0.1  0. ]]]

你可以重写kernel_function(),只计算第一个轴上的范数:

def kernel_function(x1, x2):
h = 0.5
return np.exp(-(np.linalg.norm(x2 - x1, axis=0) / h) ** 2)

则得到:

>>> kernel_function(train_x_cols, train_x_rows)
[[1.   0.73 0.51 0.7 ]
[0.73 1.   0.82 0.82]
[0.51 0.82 1.   0.92]
[0.7  0.82 0.92 1.  ]]

最新更新