المتجه قائمة أرقام لها قواعد
المتجه قائمة مرتّبة من الأرقام بطول ثابت، مثل أوزان محفظة [0.5, 0.3, 0.2] أو عوائد يوم واحد لثلاثة أصول [0.02, -0.01, 0.03]. وفي بايثون تؤدي قائمة أعداد عشرية الغرض. يمكن جمع المتجهات وتحجيمها ودمجها موضعًا موضعًا، ولهذا يُكتب جزء كبير من المالية الكمية بلغتها. ولا يمكن دمج متجهين إلا إذا تساوى طولاهما؛ وخلط الأطوال خطأ تريد أن تعرف به بوضوح.
weights = [0.5, 0.3, 0.2]
returns = [0.02, -0.01, 0.03]
# Position by position: zip pairs the elements
products = [w * r for w, r in zip(weights, returns)]
print([round(p, 4) for p in products]) # [0.01, -0.003, 0.006]
# Scaling and adding vectors
print([2 * w for w in weights]) # [1.0, 0.6, 0.4]
print([a + b for a, b in zip(weights, returns)]) # [0.52, 0.29, 0.23]الجداء النقطي
يضرب الجداء النقطي متجهين موضعًا موضعًا ويجمع النواتج: a1*b1 + a2*b2 + ... + an*bn. ويُرجع رقمًا واحدًا. وهو عائد المحفظة حين يحمل a الأوزان وb العوائد: 0.5*0.02 + 0.3*(-0.01) + 0.2*0.03 = 0.013. وهو أيضًا قيمة قائمة مراكز (الكميات ضرب الأسعار) واللبنة الأساسية للانحدار. وفي بايثون: sum(x * y for x, y in zip(a, b)) بعد التأكد من أن len(a) == len(b) لأن zip تتوقف بصمت عند القائمة الأقصر.
def dot(a, b):
if len(a) != len(b):
raise ValueError("vectors must have the same length")
return sum(x * y for x, y in zip(a, b))
print(dot([1, 2, 3], [4, 5, 6])) # 32
print(round(dot([0.5, 0.3, 0.2], [0.02, -0.01, 0.03]), 6)) # 0.013 (portfolio return)
try:
dot([1, 2], [1, 2, 3])
except ValueError as error:
print(error) # vectors must have the same lengthالطول والاتجاه والتشابه
حاصل الجداء النقطي لمتجه مع نفسه هو مربع طوله، فتكون النظيم (الطول) math.sqrt(dot(a, a)): وهو 5.0 للمتجه [3, 4]. وقسمة المتجه على نظيمه تعطي متجه وحدة طوله 1 يحتفظ بالاتجاه وحده (لكن المتجه الصفري لا اتجاه له فارفضه بـValueError). وتشابه جيب التمام dot(a, b) / (norm(a) * norm(b)) يقيس مدى توافق متجهين، من -1 (متعاكسان) مرورًا بـ0 (لا علاقة، بزاوية قائمة) إلى 1 (الاتجاه نفسه مهما كان المقياس). وعند تطبيقه على سلاسل عوائد مطروح منها متوسطها فهو الارتباط، كمية محورية في مخاطر المحافظ.
import math
def dot(a, b):
return sum(x * y for x, y in zip(a, b))
def norm(a):
return math.sqrt(dot(a, a))
print(norm([3, 4])) # 5.0
def normalize(a):
length = norm(a)
if length == 0:
raise ValueError("a zero vector has no direction")
return [x / length for x in a]
print(normalize([3, 4])) # [0.6, 0.8]
def cosine_similarity(a, b):
return dot(a, b) / (norm(a) * norm(b))
print(round(cosine_similarity([1, 2], [2, 4]), 6)) # 1.0 (same direction)
print(cosine_similarity([1, 0], [0, 1])) # 0.0 (perpendicular)
print(round(cosine_similarity([1, 2], [-1, -2]), 6)) # -1.0 (opposite)import math
def dot(a, b):
return sum(x * y for x, y in zip(a, b))
def mean(values):
return sum(values) / len(values)
# Correlation is the cosine of the demeaned series
a = [0.01, 0.02, -0.01, 0.03]
b = [0.02, 0.04, -0.02, 0.06] # always twice a
da = [x - mean(a) for x in a]
db = [x - mean(b) for x in b]
corr = dot(da, db) / math.sqrt(dot(da, da) * dot(db, db))
print(round(corr, 6)) # 1.0
# Value of a book: quantities dot prices
quantities = [100, -50, 20]
prices = [184.0, 410.0, 171.0]
print(dot(quantities, prices)) # 1320.0zip وإلا أسقطت بيانات بصمت. ولا تختبر نتائج الأعداد العشرية بـ==: فقد يخرج جيب تمام اتجاهين متطابقين 0.9999999999999999. قارن بـmath.isclose(...) كما تفعل اختبارات المختبر. وستستخدم قريبًا NumPy التي تؤدي np.dot وnp.linalg.norm فيها كل هذا بسرعة؛ ومعرفة ما تحسبانه تتيح لك التحقق منهما.- الجداء النقطي: اضرب موضعًا موضعًا واجمع؛ وتحقق من الأطوال أولًا.
- النظيم
sqrt(dot(a, a))؛ ومتجه الوحدةa / norm(a)(ارفض المتجه الصفري). - تشابه جيب التمام
dot(a, b) / (norm(a) * norm(b))من -1 إلى 1؛ وقارن الأعداد العشرية بـisclose.
التالي: المصفوفات والأنظمة الخطية، جداول أرقام تعمل على المتجهات وتحل معادلات كثيرة دفعة واحدة.
المختبر: ما الذي يُقيَّم
- اجمع الأوزان والعوائد باستخدام
dot25 نقطة - قِس طول متجه باستخدام
norm25 نقطة - قارن الاتجاهات باستخدام
cosine_similarity25 نقطة - اجعل طول متجه 1 باستخدام
normalize25 نقطة