我给大家介绍一个算法,计算一个和给定向量相关度最小的向量,使用的是迭代的方法。
先来看一下算法的描述
这个描述很长,主要看算法部分就行了。
这里面
β
β
β记录的是路径,说白了就是迭代的过程,其实对于我们这段程序来说没什么用,y就是我们要求的向量。
x
1
x_1
x1~
x
p
x_p
xp代表的是输入向量,我们的优化目标就是让y和{
x
1
x_1
x1…
x
p
x_p
xp}中相关度最大的向量的相关度最小,说起来有点绕。
我们计算两个向量的相关度的时候,一般都是计算向量夹角的余弦值,因为余弦值如果为1那么就表示两个向量同向,他们经过平移操作就能重合,所以我们认为这时候他们的相关度最高,如果余弦值为0,那么就代表两个向量垂直,我们这道题目得到的理想状态就是y和所有给定的x都是垂直的。当然对于n维空间,假设我们给定的向量大于等于n,并且他们都是不线性相关的,那么我们的y是不可能精确到和所有的输入向量都垂直的。
主要的计算步骤就是,首先计算每一个输入向量和y的相关度,选择相关度最大的那个向量
x
j
x_j
xj,使用这个向量更新向量
y
y
y,更新的公式是
y
=
y
−
α
∗
x
j
y = y-\alpha*x_j
y=y−α∗xj
其中有
α
=
ε
∗
s
(
x
j
T
y
)
\alpha = \varepsilon*s(x_j^Ty)
α=ε∗s(xjTy)
s
(
x
j
T
y
)
=
{
1
,
x
j
T
y
>
0
−
1
,
x
j
T
y
<
0
0
,
o
t
h
e
r
w
i
s
e
s(x_j^Ty) = \begin{cases} 1, \quad x_j^Ty>0 \\ -1, \quad x_j^Ty<0 \\ 0, \quad otherwise \end{cases}
s(xjTy)=⎩⎪⎨⎪⎧1,xjTy>0−1,xjTy<00,otherwise
代码如下
import numpy as np
import matplotlib.pyplot as plt
# 设置参数
p = 3
n = 3
# 学习率
bias = 0.01
# 输入矩阵x,n行p列的标准正态分布
x = np.random.randn(p,n)
# 计算每个epoch的相关度
rs = []
# 返回最大相关向量和点积
def getMaxR(r):
# 记录点积
mat = 0.0
index = -1
for i in range(p):
# 计算点积,取绝对值
tmp = np.dot(x[i], r)
if(abs(tmp) > mat):
mat = tmp
index =i
return mat, index
# 训练
def train(epoches, r):
for epoch in range(epoches):
max, index = getMaxR(r)
if(max > 0):
print("+")
r = r - bias*x[index]
rs.append(max)
elif(max < 0):
print("-")
r = r + bias*x[index]
rs.append(max)
else:
print("0")
rs.append(max)
print("epoch "+str(epoch) + ": correlation: %.6f"%(max))
def draw(epoches):
x = np.arange(epoches)
plt.plot(x, rs)
plt.title("correlation curve")
plt.grid()
plt.xlabel("epoch")
plt.ylabel("correlation")
plt.show()
def boot(epoches,r ):
train(epoches, r)
draw(epoches)
if __name__ == "__main__":
# n行1列的输出向量,初始化为0
r = np.random.randn(n)
boot(2000, r)
由于我们的输入值是随机初始化的,所以每次运行脚本得到的结果可能都不一样
最后都会收敛到接近0的区域。
有什么疑问欢迎到评论区留言哈哈。