背景:尝试使用日期时间特征和外生变量(如温度)来预测某种消耗值(如水)。
采用一些日期时间功能,例如工作日 ( mon=1, tue=2, ..., sun=7
) 和月份 ( jan=1, ..., dec=12
)。
一个天真的 KNN 回归器会判断周日和周一之间的距离是 6,十二月和一月之间的距离是 11,尽管在这两种情况下实际上都是 1。
域
hours = np.arange(1, 25)
days = np.arange(1, 8)
months = np.arange(1, 13)
days
>>> array([1, 2, 3, 4, 5, 6, 7])
type(days)
>>> numpy.ndarray
功能
自定义距离函数是可能的:
def distance(x, y, domain):
direct = abs(x - y)
round_trip = domain - direct
return min(direct, round_trip)
导致:
# weeks
distance(x=1, y=7, domain=7)
>>> 1
distance(x=4, y=2, domain=7)
>>> 2
# months
distance(x=1, y=11, domain=12)
>>> 2
distance(x=1, y=3, domain=12)
>>> 2
但是,使用 Sci-Kit 的KNeighborsRegressor的自定义距离函数会使它变慢,我不想在其他功能上使用它本身。
坐标
我正在考虑的另一种方法是使用元组来表示向量空间中的坐标,就像我们在圆形时钟上表示一天中的小时一样。
def to_coordinates(domain):
""" Projects a linear range on the unit circle,
by dividing the circumference (c) by the domain size,
thus giving every point equal spacing.
"""
# circumference
c = np.pi * 2
# equal spacing
a = c / max(domain)
# array of x and y
return np.sin(a*domain), np.cos(a*domain)
导致:
x, y = to_coordinates(days)
# figure
plt.figure(figsize=(8, 8), dpi=80)
# draw unit circle
t = np.linspace(0, np.pi*2, 100)
plt.plot(np.cos(t), np.sin(t), linewidth=1)
# add coordinates
plt.scatter(x, y);
显然,这让我在计算距离时得到了我正在寻找的对称性。
问题
现在我想不通的是:我可以使用什么数据类型来最好地表示这些向量,以便 knn 回归器自动计算距离?也许是一组元组;一个二维的numpy数组?
试图
一旦我尝试将坐标与其他变量混合,就会出现问题。目前,最直观的尝试引发了一个异常:
data = df.values
出于简单演示的目的,目标变量是分类域变量days
。
TypeError Traceback (most recent call last)
TypeError: only size-1 arrays can be converted to Python scalars
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
<ipython-input-112-a34d184ab644> in <module>
1 neigh = KNeighborsClassifier(n_neighbors=3)
----> 2 neigh.fit(data, days)
ValueError: setting an array element with a sequence.
我只希望算法能够处理新的观察结果(coordinate
代表星期几和temperature
)并找到最接近的匹配项。我知道坐标当然是目标变量的直接表示,因此会泄露答案,但它是关于启用算法的数学运算。
先感谢您。