image.png
在刻画房子的时候,可以用如上的五个维度。
所以就可以用(120,3,2,2,666)这个向量来表示。
向量里蕴含了方向和大小。因为(4,3),(8,6)是不同的向量。
方向和点是一一对应的。因为当坐标轴原点都取0的时候,就等价了。
image.png
理解向量可以从下面2个角度去理解。
一个是一个有向线段,一个是空间中的一个点。
image.png
我们在这里考虑向量是和起始点无关的。
image.png
实现自己的向量类
class Vector:
def __init__(self, lst):
self._values = lst
def __getitem__(self, index):
return self._values[index]
def __len__(self):
return len(self._values)
def __repr__(self):
return "Vector({})".format(self._values)
def __str__(self):
return "({})".format(", ".join(str(e) for e in self._values))
向量的加法
image.png
image.png
向量的数量乘法
本质是向量的加法,所以可以用加法的定义去得到公式。
image.png
image.png
实现自己的向量运算
def __iter__(self):
return self._values.__iter__()
def __add__(self, another):
assert len(self) == len(another), \
"error in adding. length should be same"
return Vector([a + b for a, b in zip(self, another)])
def __sub__(self, another):
assert len(self) == len(another), \
"error in subtracting. length should be same"
return Vector([a - b for a, b in zip(self, another)])
def __mul__(self, k):
return Vector([a * k for a in self])
def __rmul__(self, k):
return self * k
def __pos__(self):
return 1 * self
def __neg__(self):
return -1 * self
向量运算的基本性质
image.png
零向量
image.png
零向量没有方向。但是有维度。
向量的长度
image.png
image.png
image.png
image.png
向量的点乘
image.png
两个向量相乘,结果是一个数(标量)
2个向量的点乘,内积
image.png
image.png
image.png
image.png
应用可以算夹角,之后可以根据夹角来做推荐系统,角度越小,相似度越大。
求一个向量在另一个向量的投影点坐标。
image.png
最终代码
import math
from ._global import EPSILON
class Vector:
def __init__(self, lst):
self._values = list(lst)
def __getitem__(self, index):
return self._values[index]
def __len__(self):
return len(self._values)
def __repr__(self):
return "Vector({})".format(self._values)
def __str__(self):
return "({})".format(", ".join(str(e) for e in self._values))
def __iter__(self):
return self._values.__iter__()
def __add__(self, another):
assert len(self) == len(another), \
"error in adding. length should be same"
return Vector([a + b for a, b in zip(self, another)])
def __sub__(self, another):
assert len(self) == len(another), \
"error in subtracting. length should be same"
return Vector([a - b for a, b in zip(self, another)])
def dot(self, another):
assert len(self) == len(another), \
"error in dot"
return sum(a * b for a,b in zip(self,another))
def __mul__(self, k):
return Vector([a * k for a in self])
def __rmul__(self, k):
return self * k
def __pos__(self):
return 1 * self
def __neg__(self):
return -1 * self
def __truediv__(self, k):
return (1 / k) * self
@classmethod
def zero(cls, dim):
return cls([0] * dim)
def norm(self):
return math.sqrt(sum(e ** 2 for e in self))
def normalize(self):
if self.norm() < EPSILON:
raise ZeroDivisionError("Normalize error! norm is zero")
return Vector(self._values) / self.norm()
EPSILON = 1e-8