python向量点乘_Python线性代数学习笔记——向量的点乘与几何意义,实现向量的点乘操作...
好久沒(méi)有寫(xiě)文章了,抱歉了,以后每天都會(huì)更新一篇的....
向量的點(diǎn)乘,也就是兩個(gè)向量相乘:
我們是不這么定義的,不是兩個(gè)向量對(duì)應(yīng)的坐標(biāo)元素相乘:
兩個(gè)向量“相乘”,結(jié)果是?個(gè)數(shù)!,兩個(gè)向量"相乘",更嚴(yán)格的說(shuō)法:兩個(gè)向量的點(diǎn)乘,兩個(gè)向量的內(nèi)積。
兩個(gè)向量“相乘”:等于兩個(gè)向量的模(長(zhǎng)度)乘于夾角的余弦
在二維空間中,向量的點(diǎn)乘:
使用余弦定理證明:
向量點(diǎn)乘的直觀理解:
向量的點(diǎn)乘,兩個(gè)向量必須是同方向的,所以做投影以后的長(zhǎng)度再相乘
同樣,可以用坐標(biāo)來(lái)理解:
v向量分解為x軸的x2向量,y軸的y2向量,u向量分解為x軸的x1向量,和y軸的y1向量,然后分別相乘,有4種情況,垂直的向量相乘為0,所以是x1.x2+y1.y2
使用Python實(shí)現(xiàn)向量的點(diǎn)乘:
具體代碼:
定義一個(gè)內(nèi)部使用的文件_globals,用來(lái)存儲(chǔ)全局使用的變量 EPSILON,用來(lái)判斷精度用的
EPSILON = 1e-8
Vector的代碼:
import math
from ._globals import EPSILON
class Vector:
def __init__(self, lst):
self._values = list(lst)
@classmethod
def zero(cls, dim):
"""返回一個(gè)dim維的零向量"""
return cls([0] * dim)
def __add__(self, another):
"""向量加法,返回結(jié)果向量"""
assert len(self) == len(another), \
"Error in adding. Length of vectors must be same."
return Vector([a + b for a, b in zip(self, another)])
def __sub__(self, another):
"""向量減法,返回結(jié)果向量"""
assert len(self) == len(another), \
"Error in subtracting. Length of vectors must be same."
return Vector([a - b for a, b in zip(self, another)])
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()
def dot(self, another):
"""向量點(diǎn)乘,返回結(jié)果標(biāo)量"""
assert len(self) == len(another), \
"Error in dot product. Length of vectors must be same."
return sum(a * b for a, b in zip(self, another))
def __mul__(self, k):
"""返回?cái)?shù)量乘法的結(jié)果向量:self * k"""
return Vector([k * e for e in self])
def __rmul__(self, k):
"""返回?cái)?shù)量乘法的結(jié)果向量:k * self"""
return self * k
def __truediv__(self, k):
"""返回?cái)?shù)量除法的結(jié)果向量:self / k"""
return (1 / k) * self
def __pos__(self):
"""返回向量取正的結(jié)果向量"""
return 1 * self
def __neg__(self):
"""返回向量取負(fù)的結(jié)果向量"""
return -1 * self
def __iter__(self):
"""返回向量的迭代器"""
return self._values.__iter__()
def __getitem__(self, index):
"""取向量的第index個(gè)元素"""
return self._values[index]
def __len__(self):
"""返回向量長(zhǎng)度(有多少個(gè)元素)"""
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))
測(cè)試代碼:
from playLA.Vector import Vector
if __name__ == "__main__":
vec = Vector([5, 2])
print(vec)
print("len(vec) = {}".format(len(vec)))
print("vec[0] = {}, vec[1] = {}".format(vec[0], vec[1]))
vec2 = Vector([3, 1])
print("{} + {} = {}".format(vec, vec2, vec + vec2))
print("{} - {} = {}".format(vec, vec2, vec - vec2))
print("{} * {} = {}".format(vec, 3, vec * 3))
print("{} * {} = {}".format(3, vec, 3 * vec))
print("+{} = {}".format(vec, +vec))
print("-{} = {}".format(vec, -vec))
zero2 = Vector.zero(2)
print(zero2)
print("{} + {} = {}".format(vec, zero2, vec + zero2))
print("norm({}) = {}".format(vec, vec.norm()))
print("norm({}) = {}".format(vec2, vec2.norm()))
print("norm({}) = {}".format(zero2, zero2.norm()))
print("normalize {} is {}".format(vec, vec.normalize()))
print(vec.normalize().norm())
print("normalize {} is {}".format(vec2, vec2.normalize()))
print(vec2.normalize().norm())
try:
zero2.normalize()
except ZeroDivisionError:
print("Cannot normalize zero vector {}.".format(zero2))
print(vec.dot(vec2))
注意:
向量的點(diǎn)乘的應(yīng)?
1、求出兩個(gè)向量之間的夾角范圍,或者具體值
2、判斷兩個(gè)向量的相似程度(推薦系統(tǒng))
一組物品進(jìn)行推薦,可能是電影,音樂(lè)....在推薦的時(shí)候,最典型的推薦策略就是推薦和你的喜好最相似的內(nèi)容,比如說(shuō),你已經(jīng)在系統(tǒng)上留下足跡,喜歡電影A,此時(shí)電影B和A相似,推薦系統(tǒng)就會(huì)傾向把電影B推薦給你,電影C和電影B極其不相似,推薦系統(tǒng)就不會(huì)推薦。
在這個(gè)背后如何判斷兩個(gè)電影是否相似?
很簡(jiǎn)單的判斷就是使用向量的點(diǎn)乘,在這種情況下,可以想象一下,每一個(gè)電影都可以理解為一個(gè)高維空間中的點(diǎn),把向量另外一種視角看待(高維空間中的一個(gè)點(diǎn)),對(duì)電影來(lái)說(shuō),它可能有(電影的時(shí)間,演員的列表,電影的導(dǎo)演,電影的類(lèi)型,電影的色調(diào),臺(tái)詞量....)的一個(gè)高維度信息,就是在一個(gè)高維空間中的點(diǎn),在這種情況下,如果我們轉(zhuǎn)換我們的視角,把每個(gè)電影又轉(zhuǎn)換成一個(gè)高維空間中的一個(gè)向量,每?jī)蓚€(gè)電影之間就會(huì)存在一個(gè)夾角,這時(shí)候,我們可以看這兩個(gè)電影之間的夾角是直角,鈍角,還是銳角,,如果是銳角,那么這兩個(gè)電影之間有一部分是重合的,我就說(shuō)這兩個(gè)電影是相似的,如果是垂直的,那么這兩部電影就是無(wú)關(guān)的,如果是頓角那么這兩部電影是背離的。
在這里我們不僅可以看兩個(gè)向量之間的夾角,還可以看點(diǎn)乘的結(jié)果(值),如果點(diǎn)乘的值為正值,并且越大,說(shuō)明這兩個(gè)電影越相似,在最極端的情況下,這兩個(gè)向量完全重合的時(shí)候,那么這時(shí)候這兩個(gè)向量的點(diǎn)乘將達(dá)到最大值,也就是兩個(gè)電影的高維空間中的點(diǎn)(電影的時(shí)間,演員的列表,電影的導(dǎo)演,電影的類(lèi)型,電影的色調(diào),臺(tái)詞量....)已經(jīng)重合了。
換句話說(shuō),我們可以使用向量點(diǎn)乘的方式,來(lái)看兩個(gè)向量(電影)的相似,值越大,越相似,值越小,越不一樣,這就是向量的點(diǎn)乘在推薦系統(tǒng)中的一個(gè)典型應(yīng)用,當(dāng)然了,現(xiàn)在的推薦
系統(tǒng)都比較復(fù)雜,在判斷兩個(gè)物品是否相似的時(shí)候,也有其他更加準(zhǔn)確的方法,不僅如此,在具體判斷兩個(gè)物品是否相似之前,對(duì)兩個(gè)物品所對(duì)應(yīng)的數(shù)據(jù)也也需要進(jìn)行很多的處理。
3、?何計(jì)算
v向量投影到u向量上
投影點(diǎn)的方向,也就是u向量除以u(píng)向量的模,也就是u向量方向的單位向量,舉例子,u向量為(3,4),模長(zhǎng)為5,u向量方向的單位向量為(3/5,4/5)
總結(jié)
以上是生活随笔為你收集整理的python向量点乘_Python线性代数学习笔记——向量的点乘与几何意义,实现向量的点乘操作...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: To change the IDENTI
- 下一篇: Python 小项目 猜数字小游戏