查找嵌入式时间序列矩阵与超平面相交的点
Find Points where Embedded Time Series Matrix Intersects Hyperplane
我有一个 3 维嵌入式时间序列。如何找到时间序列的 3d 矩阵与任意超平面相交的 points/coordinates (x, y, z)。问题是我没有嵌入式时间序列的方程式。我是找到离超平面最近的点并将它们投影到我的超平面上,还是找到一个点穿过另一侧到另一点的位置,然后找到该线的方程并插入我的 z 值以找到( x, y) 坐标?我的情节是这样的:
这是我当前的可复制性代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from teaspoon.SP.tsa_tools import takens
import seaborn as sns
from datetime import datetime
import pandas_datareader.data as pdr
sns.set_style("darkgrid")
def fetch_data(symbol, from_date, to_date, cols_to_drop):
""" Fetch OHLC data."""
df = pdr.DataReader(symbol, "yahoo", from_date, to_date)
df.drop(columns=cols_to_drop, inplace=True)
return df
if __name__ == "__main__":
# Fetch OHLC Data #
symbol = "EURUSD=X" # ticker
from_date = datetime(2000, 1, 1)
to_date = datetime.now()
drop_columns = ["Adj Close", "Volume"]
df = fetch_data(symbol=symbol, from_date=from_date,
to_date=to_date, cols_to_drop=drop_columns)
# TAKEN'S EMBEDDING THEOREM #
taken_matrix = takens(np.array(df.Close), n=3, tau=62) # emb_dim =3, time delay=62
x_min, x_max = np.min(taken_matrix[:, 0]), np.max(taken_matrix[:, 0]) # x_min and x_max
y_min, y_max = np.min(taken_matrix[:, 1]), np.max(taken_matrix[:, 1]) # y_min and y_max
z_min, z_max = np.min(taken_matrix[:, 2]), np.max(taken_matrix[:, 2]) # z_min and z_max
# Method 1
x = np.array([x_min, x_max])
y = np.array([y_min, y_max])
xx, yy = np.meshgrid(x, y)
z = np.array([[1.4, 1.4], [1.4, 1.4]])
hyperplane = np.array([xx, yy, z])
hyperplane = np.reshape(hyperplane.T, (4, 3)) # 4 co-ords
fig = plt.figure(dpi=50)
ax = plt.axes(projection="3d")
ax.set_xlabel("x"); ax.set_ylabel("y"); ax.set_zlabel("z")
ax.plot(taken_matrix[:, 0], taken_matrix[:, 1], taken_matrix[:, 2], c="black", lw=0.6, alpha=0.8) # phase space
ax.plot_surface(xx, yy, z, alpha=0.2, color="seagreen") # Hyperplane
plt.show()
# Method 2
hyperplane1 = hyperplane[:-1, :] # 3 coordinates
p0, p1, p2 = hyperplane1
x0, y0, z0 = p0
x1, y1, z1 = p1
x2, y2, z2 = p2
ux, uy, uz = u = [x1 - x0, y1 - y0, z1 - z0] # first vector
vx, vy, vz = v = [x2 - x0, y2 - y0, z2 - z0] # second vector
u_cross_v = [uy*vz - uz*vy, uz*vx - ux*vz, ux*vy - uy*vx] # cross product
point1 = np.array(p1)
normal1 = np.array(u_cross_v) # hyerplane normal vector
d1 = -point1.dot(normal1) # computed for equation of plane
print('plane equation:\n{:1.4f}x + {:1.4f}y + {:1.4f}z + {:1.4f} = 0'.format(normal1[0], normal1[1], normal1[2], d1))
xx, yy = np.meshgrid(x, y)
z1 = (-normal1[0] * xx - normal1[1] * yy - d1) * 1. / normal1[2]
fig = plt.figure()
ax = plt.axes(projection="3d")
ax.plot_surface(xx, yy, z1, color="orange")
ax.plot(taken_matrix[:, 0], taken_matrix[:, 1], taken_matrix[:, 2], c="black", lw=0.6, alpha=0.8)
plt.show()
所以这是我的解决方案,用于查找从任意超平面上方到下方通过的点的交点。在我的代码中,在我创建了 taken 矩阵之后,这是我的新实现:
x = np.array([1, 1.6])
y = ([1, 1.6])
xx, yy = np.meshgrid(x, y)
z = np.array([[1, 1.3], [1.3, 1.6]])
hyperplane = np.array([xx, yy, z])
hyperplane2 = np.reshape(hyperplane.T, (4, 3))
hyperplane2 = hyperplane2[:-1, :] # we only need 3 points
p0, p1, p2 = hyperplane2
x0, y0, z0 = p0
x1, y1, z1 = p1
x2, y2, z2 = p2
ux, uy, uz = u = [x1 - x0, y1 - y0, z1 - z0] # first vector
vx, vy, vz = v = [x2 - x0, y2 - y0, z2 - z0] # second vector
u_cross_v = [uy*vz - uz*vy, uz*vx - ux*vz, ux*vy - uy*vx] # cross product
point1 = np.array(p1)
normal1 = np.array(u_cross_v)
d1 = -point1.dot(normal1)
print('\nplane equation:\n{:1.4f}x + {:1.4f}y + {:1.4f}z + {:1.4f} = 0'.format(normal1[0], normal1[1], normal1[2], d1))
xx, yy = np.meshgrid(x, y)
z1 = (-normal1[0] * xx - normal1[1] * yy - d1) * 1. / normal1[2]
from sympy import symbols, Eq
from sympy.solvers import solve
t = symbols("t")
x, y, z = symbols("x, y, z")
g = symbols("g")
plane = Eq(normal1[0] * x + normal1[1] * y + normal1[2] * z + d1, g) # create plane
print(plane)
# Points that pass from above to below the plane (not below to above because I want it to be transveral)
above_or_below = np.array([solve(plane.subs([(x, taken_matrix[i][0]),
(y, taken_matrix[i][1]),
(z, taken_matrix[i][2])]), g) \
for i in tqdm(range(len(taken_matrix)))])
above1, below1 = [], []
for i in tqdm(range(1, len(above_or_below))):
if above_or_below[i-1] >= 0 and above_or_below[i] < 0:
above1.append(taken_matrix[i-1])
below1.append(taken_matrix[i])
above1 = np.array(above1)
below1 = np.array(below1)
# Parametric Equations for x_coords, y_coords and z_coords
xs1 = [Eq((above1[i][0] - below1[i][0])*t + below1[i][0] - x, 0) for i in range(len(above1))]
ys1 = [Eq((above1[i][1] - below1[i][1])*t + below1[i][1] - y, 0) for i in range(len(above1))]
zs1 = [Eq((above1[i][2] - below1[i][2])*t + below1[i][2] - z, 0) for i in range(len(above1))]
# Solve Equations
xs1 = np.array([solve(i, x) for i in xs1])
ys1 = np.array([solve(i, y) for i in ys1])
zs1 = np.array([solve(i, z) for i in zs1])
ts1 = np.array([solve(plane.subs([(g, 0), (x, np.squeeze(i)),
(y, np.squeeze(j)), (z, np.squeeze(k))]), t) \
for i, j, k in zip(xs1, ys1, zs1)]) # plug x, y and z eqn's into plane to get t
# Get x, y and z co-ordinates
xs1 = np.array([solve(Eq(np.squeeze(i), x).subs(t, np.squeeze(j)), x) for i, j in zip(xs1, ts1)])
ys1 = np.array([solve(Eq(np.squeeze(i), y).subs(t, np.squeeze(j)), y) for i, j in zip(ys1, ts1)])
zs1 = np.array([solve(Eq(np.squeeze(i), z).subs(t, np.squeeze(j)), z) for i, j in zip(zs1, ts1)])
points_on_plane1 = np.concatenate([xs1, ys1, zs1], axis=1) # put coordinates together
fig = plt.figure()
ax = plt.axes(projection="3d")
ax.plot_surface(xx, yy, z1, alpha=0.2, color="seagreen")
ax.plot(taken_matrix[:, 0], taken_matrix[:, 1], taken_matrix[:, 2], c="black", lw=0.6, alpha=0.5)
ax.scatter(points_on_plane1[:, 0], points_on_plane1[:, 1], points_on_plane1[:, 2], c="red")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
plt.show()
我有一个 3 维嵌入式时间序列。如何找到时间序列的 3d 矩阵与任意超平面相交的 points/coordinates (x, y, z)。问题是我没有嵌入式时间序列的方程式。我是找到离超平面最近的点并将它们投影到我的超平面上,还是找到一个点穿过另一侧到另一点的位置,然后找到该线的方程并插入我的 z 值以找到( x, y) 坐标?我的情节是这样的:
这是我当前的可复制性代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from teaspoon.SP.tsa_tools import takens
import seaborn as sns
from datetime import datetime
import pandas_datareader.data as pdr
sns.set_style("darkgrid")
def fetch_data(symbol, from_date, to_date, cols_to_drop):
""" Fetch OHLC data."""
df = pdr.DataReader(symbol, "yahoo", from_date, to_date)
df.drop(columns=cols_to_drop, inplace=True)
return df
if __name__ == "__main__":
# Fetch OHLC Data #
symbol = "EURUSD=X" # ticker
from_date = datetime(2000, 1, 1)
to_date = datetime.now()
drop_columns = ["Adj Close", "Volume"]
df = fetch_data(symbol=symbol, from_date=from_date,
to_date=to_date, cols_to_drop=drop_columns)
# TAKEN'S EMBEDDING THEOREM #
taken_matrix = takens(np.array(df.Close), n=3, tau=62) # emb_dim =3, time delay=62
x_min, x_max = np.min(taken_matrix[:, 0]), np.max(taken_matrix[:, 0]) # x_min and x_max
y_min, y_max = np.min(taken_matrix[:, 1]), np.max(taken_matrix[:, 1]) # y_min and y_max
z_min, z_max = np.min(taken_matrix[:, 2]), np.max(taken_matrix[:, 2]) # z_min and z_max
# Method 1
x = np.array([x_min, x_max])
y = np.array([y_min, y_max])
xx, yy = np.meshgrid(x, y)
z = np.array([[1.4, 1.4], [1.4, 1.4]])
hyperplane = np.array([xx, yy, z])
hyperplane = np.reshape(hyperplane.T, (4, 3)) # 4 co-ords
fig = plt.figure(dpi=50)
ax = plt.axes(projection="3d")
ax.set_xlabel("x"); ax.set_ylabel("y"); ax.set_zlabel("z")
ax.plot(taken_matrix[:, 0], taken_matrix[:, 1], taken_matrix[:, 2], c="black", lw=0.6, alpha=0.8) # phase space
ax.plot_surface(xx, yy, z, alpha=0.2, color="seagreen") # Hyperplane
plt.show()
# Method 2
hyperplane1 = hyperplane[:-1, :] # 3 coordinates
p0, p1, p2 = hyperplane1
x0, y0, z0 = p0
x1, y1, z1 = p1
x2, y2, z2 = p2
ux, uy, uz = u = [x1 - x0, y1 - y0, z1 - z0] # first vector
vx, vy, vz = v = [x2 - x0, y2 - y0, z2 - z0] # second vector
u_cross_v = [uy*vz - uz*vy, uz*vx - ux*vz, ux*vy - uy*vx] # cross product
point1 = np.array(p1)
normal1 = np.array(u_cross_v) # hyerplane normal vector
d1 = -point1.dot(normal1) # computed for equation of plane
print('plane equation:\n{:1.4f}x + {:1.4f}y + {:1.4f}z + {:1.4f} = 0'.format(normal1[0], normal1[1], normal1[2], d1))
xx, yy = np.meshgrid(x, y)
z1 = (-normal1[0] * xx - normal1[1] * yy - d1) * 1. / normal1[2]
fig = plt.figure()
ax = plt.axes(projection="3d")
ax.plot_surface(xx, yy, z1, color="orange")
ax.plot(taken_matrix[:, 0], taken_matrix[:, 1], taken_matrix[:, 2], c="black", lw=0.6, alpha=0.8)
plt.show()
所以这是我的解决方案,用于查找从任意超平面上方到下方通过的点的交点。在我的代码中,在我创建了 taken 矩阵之后,这是我的新实现:
x = np.array([1, 1.6])
y = ([1, 1.6])
xx, yy = np.meshgrid(x, y)
z = np.array([[1, 1.3], [1.3, 1.6]])
hyperplane = np.array([xx, yy, z])
hyperplane2 = np.reshape(hyperplane.T, (4, 3))
hyperplane2 = hyperplane2[:-1, :] # we only need 3 points
p0, p1, p2 = hyperplane2
x0, y0, z0 = p0
x1, y1, z1 = p1
x2, y2, z2 = p2
ux, uy, uz = u = [x1 - x0, y1 - y0, z1 - z0] # first vector
vx, vy, vz = v = [x2 - x0, y2 - y0, z2 - z0] # second vector
u_cross_v = [uy*vz - uz*vy, uz*vx - ux*vz, ux*vy - uy*vx] # cross product
point1 = np.array(p1)
normal1 = np.array(u_cross_v)
d1 = -point1.dot(normal1)
print('\nplane equation:\n{:1.4f}x + {:1.4f}y + {:1.4f}z + {:1.4f} = 0'.format(normal1[0], normal1[1], normal1[2], d1))
xx, yy = np.meshgrid(x, y)
z1 = (-normal1[0] * xx - normal1[1] * yy - d1) * 1. / normal1[2]
from sympy import symbols, Eq
from sympy.solvers import solve
t = symbols("t")
x, y, z = symbols("x, y, z")
g = symbols("g")
plane = Eq(normal1[0] * x + normal1[1] * y + normal1[2] * z + d1, g) # create plane
print(plane)
# Points that pass from above to below the plane (not below to above because I want it to be transveral)
above_or_below = np.array([solve(plane.subs([(x, taken_matrix[i][0]),
(y, taken_matrix[i][1]),
(z, taken_matrix[i][2])]), g) \
for i in tqdm(range(len(taken_matrix)))])
above1, below1 = [], []
for i in tqdm(range(1, len(above_or_below))):
if above_or_below[i-1] >= 0 and above_or_below[i] < 0:
above1.append(taken_matrix[i-1])
below1.append(taken_matrix[i])
above1 = np.array(above1)
below1 = np.array(below1)
# Parametric Equations for x_coords, y_coords and z_coords
xs1 = [Eq((above1[i][0] - below1[i][0])*t + below1[i][0] - x, 0) for i in range(len(above1))]
ys1 = [Eq((above1[i][1] - below1[i][1])*t + below1[i][1] - y, 0) for i in range(len(above1))]
zs1 = [Eq((above1[i][2] - below1[i][2])*t + below1[i][2] - z, 0) for i in range(len(above1))]
# Solve Equations
xs1 = np.array([solve(i, x) for i in xs1])
ys1 = np.array([solve(i, y) for i in ys1])
zs1 = np.array([solve(i, z) for i in zs1])
ts1 = np.array([solve(plane.subs([(g, 0), (x, np.squeeze(i)),
(y, np.squeeze(j)), (z, np.squeeze(k))]), t) \
for i, j, k in zip(xs1, ys1, zs1)]) # plug x, y and z eqn's into plane to get t
# Get x, y and z co-ordinates
xs1 = np.array([solve(Eq(np.squeeze(i), x).subs(t, np.squeeze(j)), x) for i, j in zip(xs1, ts1)])
ys1 = np.array([solve(Eq(np.squeeze(i), y).subs(t, np.squeeze(j)), y) for i, j in zip(ys1, ts1)])
zs1 = np.array([solve(Eq(np.squeeze(i), z).subs(t, np.squeeze(j)), z) for i, j in zip(zs1, ts1)])
points_on_plane1 = np.concatenate([xs1, ys1, zs1], axis=1) # put coordinates together
fig = plt.figure()
ax = plt.axes(projection="3d")
ax.plot_surface(xx, yy, z1, alpha=0.2, color="seagreen")
ax.plot(taken_matrix[:, 0], taken_matrix[:, 1], taken_matrix[:, 2], c="black", lw=0.6, alpha=0.5)
ax.scatter(points_on_plane1[:, 0], points_on_plane1[:, 1], points_on_plane1[:, 2], c="red")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
plt.show()