将纬度/经度位置组合成单个特征

数据挖掘 Python 熊猫 特征工程 特征构造
2021-10-06 22:53:39

我一直在使用 pandas 进行二维机器学习(尝试做这样的事情,我想将 Lat/Long 组合成一个单一的数字特征——最好是线性的。是否有“最佳实践”来做到这一点?

2个回答

注意:对于那些在这里寻找散列技术的人来说,geohash 可能是您的最佳选择

由于它们的域本质上是 3D 空间,因此不可能在单个线性尺度中表示纬度和经度。根据您的需要减少它需要一种我闻所未闻的空间扁平化技术。

推理

就 lat/long 合并而言,最佳实践是使用 Haversine 公式,该公式计算球面上两点之间的距离,并接收这些点的坐标作为输入。

将其合并到您的用例中的一种方法 - 每个点可能应该有一个独立的纬度/经度组合 - 将假设距离的原点坐标为 (φ1,λ1)=(0,0),这将呈现

d=2r反正弦(2(φ2-02)+(0)(φ2)2(λ2-02))

=2r反正弦(2(φ22)+(φ2)2(λ22))

r 是地球的半径(~6371km)和 (φ2,λ2) 您的点的纬度和经度,分别。

然而,如前所述,这不可能给你一个线性关系,你可以通过3d 绘制函数看到: 相对化半正弦 3D 图

执行

这些情况表明您可能正在使用pandas,或者至少应该使用。这是这个相对化Haversine公式的示例实现:

from math import radians, cos, sin, asin, sqrt

def single_pt_haversine(lat, lng, degrees=True):
    """
    'Single-point' Haversine: Calculates the great circle distance
    between a point on Earth and the (0, 0) lat-long coordinate
    """
    r = 6371 # Earth's radius (km). Have r = 3956 if you want miles

    # Convert decimal degrees to radians
    if degrees:
        lat, lng = map(radians, [lat, lng])

    # 'Single-point' Haversine formula
    a = sin(lat/2)**2 + cos(lat) * sin(lng/2)**2
    d = 2 * r * asin(sqrt(a)) 

    return d

可以在下面的最小示例中使用:

>>> import pandas as pd

>>> df = pd.DataFrame([[45.0, 120.0], [60.0, 30.0]], columns=['x', 'y'])
>>> df
      x      y
0  45.0  120.0
1  60.0   30.0

>>> df['harvesine_distance'] = [single_pt_haversine(x, y) for x, y in zip(df.x, df.y)]
>>> df
      x      y  harvesine_distance
0  45.0  120.0        12309.813344
1  60.0   30.0         7154.403197

最好的做法是不要试图将地球压平成一条单维线……因为你可能知道,地球更像一个球体而不是一条线。正确对待它要好得多。

不过,确实存在将 k 维空间展平为一维顺序的方法。这些被称为空间填充曲线,来自 19 世纪。它们的局限性是众所周知的:在许多方面它们会很好地工作 - 但在其他地方它们的工作非常糟糕。从复数论可知,您无法找到平面的良好线性阶。