20种经纬度特征工程

本文介绍了20种基于经纬度的特征工程方法,包括经度/纬度的相减、相除、欧几里得距离、Manhattan距离、Haversine距离计算,以及聚类、特殊地点距离、经纬度逆向编码、其他转换等,旨在提高地理空间数据的分析效果。
1 两个经度/纬度的相减

使用相邻经度进行相减,相邻纬度相减,类似于经纬度的绝对变化特征

def lat_diff(lat1, lat2): 
    return lat1 - lat2
def lat_absdiff(lat1, lat2): 
    return abs(lat1 - lat2)
def lng_diff(lng1, lng2): 
    return lng1 - lng2
def lng_absdiff(lng1, lng2): 
    return abs(lng1 - lng2)
2 两个经度/纬度的相除

计算两个经度或者纬度的相除,减法如果是绝对特征,那么相除可以认为是相对特征

def lat_ratio(lat1, lat2): 
    return lat2 / lat1

def lgn_ratio(lgn1, lgn2): 
    return lgn2 / lgn1
3 经纬度相除

计算经纬度的相除的特征,类似于斜度计算

def lng_lat_ratio(lat1,lng1): 
    return lng1 / lat1

def lat_lng_ratio(lgn1, lgn2): 
    return lat1 / lgn1
4 两个经纬度的欧几里得距离计算

计算两个经纬度之间的欧几里得距离

def euclidean_distance(lat1, lng1, lat2, lng2): 
    return np.sqrt((lat1 - lat2) ** 2 + (lng1 - lng2) ** 2)
5 两个经纬度的Manhattan距离计算

计算两个经纬度之间的Manhattan距离

def manhattan_distance(lat1, lng1, lat2, lng2): 
    return abs(lat1 - lat2)  + abs(lng1 - lng2)
6 经纬度与斜边的比例特征

类似于三角形中两个直角边与斜边的比例信息

def lat_lng_hypotenuse_ratio(lat1, lng1): 
    hypotenuse = np.sqrt((lat1 ** 2 +  lng1 ** 2))
    return lat1 /  hypotenuse, lng1/  hypotenuse
7 基于经纬度的聚类1

基于经纬度进行聚类,将经纬度聚类的结果当做特征,例如常用的Kmeans。
此处我们用1表示,在第二部分我们会介绍升级版

from sklearn.cluster import MiniBatchKMeans
coords = np.vstack((train[['pickup_latitude', 'pickup_longitude']].values,
                    train[['dropoff_latitude', 'dropoff_longitude']].values,
                    test[['pickup_latitude', 'pickup_longitude']].values,
                    test[['dropoff_latitude', 'dropoff_longitude']].values))

sample_ind = np.random.permutation(len(coords))[:500000]
kmeans = MiniBatchKMeans(n_clusters=100, batch_size=10000).fit(coords[sample_ind])

train.loc[:, 'pickup_cluster'] = kmeans.predict(train[['pickup_latitude', 'pickup_longitude']])
train.loc[:, 'dropoff_cluster'] = kmeans.predict(train[['dropoff_latitude', 'dropoff_longitude']])
test.loc[:, 'pickup_cluster'] = kmeans.predict(test[['pickup_latitude', 'pickup_longitude']])
test.loc[:, 'dropoff_cluster'] = kmeans.predict(test[['dropoff_latitude', 'dropoff_longitude']])
7 基于经纬度的聚类2

前面的部分,我们说基于Kmeans,但很多专家更加倾向于加入其他的非线性聚类。
1.Perform some Hierarchical Clustering instead of KMeans because of KMeans workes along the maximizing variance if the feature space is linear in nature but if it is non-linear, then Hierarchical Clusterings like PAM, CLARA, and DBSCAN are best to use.

2.The choice of the clustering algorithm matters. I tested many algorithms like K-means, DBSCAN, and hierarchical clustering—the latter two seem to give better results when it comes to geospatial features.

from sklearn.cluster import KMeans ,AgglomerativeClustering

# creates 5 clusters using hierarchical clustering.
agc = AgglomerativeClustering(n_clusters =5, affinity='euclidean', linkage='ward')
train['pickup cluster'] = agc.fit_predict(train[['Pickup Lat','Pickup Long']])

# creates 5 clusters using k-means clustering algorithm.
kmeans = KMeans(5)
clusters = kmeans.fit_predict(train[['Pickup Lat','Pickup Long']])
train['pickup cluster'] = kmeans.predict(train[['Pickup Lat','Pickup Long']])
8 特殊经纬度信息

例如第一个出现的经纬度可能是出发地点,最后一个现实的经纬度是终点站,那么这两个就是非常重要的特殊经纬度

9 距离某些特殊地点的经纬度距离

例如距离地铁的距离,距离汽车站的距离(距离可以是Manhattan距离等等)

def manhattan_distance_tostation(lat1, lng1, st_lat, st_lng): 
    return abs(lat1 - st_lat)  + abs(lng1 - st_lng)

def euclidean_distance_tostation(lat1, lng1, st_lat, st_lng): 
    return np.sqrt((lat1 - st_lat) ** 2 + (lng1 - st_lng) ** 2)
10 两个经纬度Haversine距离计算

haversine公式确定了给定两个经纬度在球体上两点之间的 great-circle 距离, 在很多比赛中也是最常见到的一种特征

def haversine_array(lat1, lng1, lat2, lng2): 
    lat1, lng1, lat2, lng2 = map(np.radians, (lat1, lng1, lat2, lng2)) 
    AVG_EARTH_RADIUS = 6371 # in km 
    lat = lat2 - lat1 
    lng = lng2 - lng1 
    d = np.sin(lat * 0.5) ** 2 + np.cos(lat1) * np.cos(lat2) *      np.sin(lng * 0.5) ** 2 
    h = 2 * AVG_EARTH_RADIUS * np.arcsin(np.sqrt(d)) 
    return h
11 两个经纬度之间的Manhattan距离计算

沿直角轴测得的两点之间的距离

def dummy_manhattan_distance(lat1, lng1, lat2, lng2): 
    a = haversine_array(lat1, lng1, lat1, lng2) 
    b = haversine_array(lat1, lng1, lat2, lng1) 
    return a + b
12 两个经纬度之间的方位特征

表示两个经纬度之间的方位信息

def bearing_array(lat1, lng1, lat2, lng2): 
    AVG_EARTH_RADIUS = 6371 # in km 
    lng_delta_rad = np.radians(lng2 - lng1) 
    lat1, lng1, lat2, lng2 = map(np.radians, (lat1, lng1, lat2, lng2)) 
    y = np.sin(lng_delta_rad) * np.cos(lat2) 
    x = np.cos(lat1) * np.sin(lat2) - np.sin(lat1) * np.cos(lat2) * np.cos(lng_delta_rad) 
    return np.degrees(np.arctan2(y, x))
12 两个经纬度之间的Manhattan距离计算

沿直角轴测得的两点之间的距离

def dummy_manhattan_distance(lat1, lng1, lat2, lng2): 
    a = haversine_array(lat1, lng1, lat1, lng2) 
    b = haversine_array(lat1, lng1, lat2, lng1) 
    return a + b
13 两个经纬度之间的方位特征

表示两个经纬度之间的方位信息

def bearing_array(lat1, lng1, lat2, lng2): 
    AVG_EARTH_RADIUS = 6371 # in km 
    lng_delta_rad = np.radians(lng2 - lng1) 
    lat1, lng1, lat2, lng2 = map(np.radians, (lat1, lng1, lat2, lng2)) 
    y = np.sin(lng_delta_rad) * np.cos(lat2) 
    x = np.cos(lat1) * np.sin(lat2) - np.sin(lat1) * np.cos(lat2) * np.cos(lng_delta_rad) 
    return np.degrees(np.arctan2(y, x))
14 经纬度逆向编码

通过很多地图的api,将经纬度信息转换为详细地址信息,然后对这些地址进行编码

from pygeocoder import Geocoder
location = Geocoder.reverse_geocode(12.9716,77.5946)
print("City:",location.city)
print("Country:",location.country)

from geopy.geocoders import Nominatim
# create the locator
geolocator = Nominatim(user_agent="myGeocoder")
# getting the location address
location = geolocator.reverse("52.509669, 13.376294")
location.raw.get('address').get('state')
location.raw.get('address').get('city_district')
location.raw.get('address').get('country')
location.raw.get('address').get('postcode')
15 对经纬度进行其他转换

常见的是PCA转换(有些竞赛中说这种转换可以帮助树模型更好地分割)

pca = PCA().fit(coords)
train['pickup_pca0'] = pca.transform(train[['pickup_latitude', 'pickup_longitude']])[:, 0]
train['pickup_pca1'] = pca.transform(train[['pickup_latitude', 'pickup_longitude']])[:, 1]
train['dropoff_pca0'] = pca.transform(train[['dropoff_latitude', 'dropoff_longitude']])[:, 0]
train['dropoff_pca1'] = pca.transform(train[['dropoff_latitude', 'dropoff_longitude']])[:, 1]
test['pickup_pca0'] = pca.transform(test[['pickup_latitude', 'pickup_longitude']])[:, 0]
test['pickup_pca1'] = pca.transform(test[['pickup_latitude', 'pickup_longitude']])[:, 1]
test['dropoff_pca0'] = pca.transform(test[['dropoff_latitude', 'dropoff_longitude']])[:, 0]
test['dropoff_pca1'] = pca.transform(test[['dropoff_latitude', 'dropoff_longitude']])[:, 1]
16 距离某些特殊地点的经纬度距离

例如距离地铁的距离,距离汽车站的距离(距离计算换算成上面的Haversine等距离)
距离最近城市的距离
距离最近的最大的城市的距离
距离某些特殊站点(家,地铁…)的距离

17 经纬度的衍生编码等特征

例如距离地铁的距离,距离汽车站的距离(距离计算换算成上面的Haversine等距离)
距离最近的城市编码(人口数编码,城市编码等)
距离最近的最大的城市编码(人口数编码,城市编码等)等

参考:https://www.kesci.com/home/project/5e72091fc59d610036222d90

在AIS(Automatic Identification System)数据中,船舶类型的特征工程方法主要围绕如何从原始AIS数据中提取出能够有效描述船舶类型特征的变量。这些特征可以用于后续的船舶分类、行为分析、轨迹预测等任务。以下是一些常见的特征提取与工程方法: ### 1. 静态特征提取 静态特征通常是指船舶在AIS数据中固有的、不随时间变化的属性。这些特征包括: - **MMSI(Maritime Mobile Service Identity)**:船舶的唯一标识符,可用于关联同一船舶的多条AIS记录。 - **船舶名称(Name)**:船舶的名称,可用于辅助识别船舶类型。 - **船舶类型(Type of Ship)**:AIS数据中通常包含船舶类型的编码信息,例如货船、油轮、渔船等。这一字段可以直接作为分类任务的目标变量或特征之一。 - **船舶尺寸(Length and Beam)**:船舶的长度和宽度是区分不同船舶类型的重要特征。例如,大型油轮通常比渔船长得多。 ### 2. 动态特征提取 动态特征是指随时间变化的船舶运动状态特征。这些特征可以从AIS数据中的位置、速度和方向等信息中提取: - **航速(Speed Over Ground, SOG)**:船舶的地面速度,反映了船舶的运动状态。不同类型的船舶在航行时的航速分布可能不同。例如,高速渡轮的航速通常比货船高。 - **航向(Course Over Ground, COG)**:船舶的航行方向,可以用于分析船舶的运动模式。 - **位置信息(Latitude and Longitude)**:船舶的经纬度坐标,可用于计算船舶的移动轨迹和区域分布。 - **时间戳(Timestamp)**:记录AIS数据的时间信息,可用于分析船舶的活动时间模式。 ### 3. 轨迹特征提取 轨迹特征是指从船舶的连续AIS记录中提取的与轨迹相关的特征。这些特征可以帮助分析船舶的运动行为: - **轨迹长度**:船舶在一段时间内的轨迹总长度,可以通过计算相邻AIS记录之间的距离并累加得到。 - **轨迹弯曲度**:反映轨迹的复杂程度,可以通过计算轨迹的曲率或使用道格拉斯-普克(Douglas-Peucker, DP)算法进行轨迹压缩后保留的关键点数量来衡量。 - **轨迹方向变化率**:船舶在轨迹上的方向变化频率,可以通过计算相邻航向的变化量并求平均值来得到。 - **轨迹停留时间**:船舶在某一区域停留的时间,可以用于识别船舶的停泊行为。 ### 4. 衍生特征工程 衍生特征是指通过组合或变换原始特征得到的新特征,通常能够更好地捕捉数据中的潜在模式: - **速度与航向的组合特征**:例如,将航速与航向结合,计算船舶的运动向量(Velocity Vector),用于分析船舶的运动方向和速度变化。 - **时间间隔特征**:计算相邻AIS记录之间的时间间隔,用于分析船舶的AIS信号发送频率。 - **轨迹分段特征**:将船舶的轨迹划分为多个段,每一段可以提取静态特征(如平均航速、平均航向)和动态特征(如速度变化率、方向变化率)。 - **多维度特征组合**:例如,将船舶的航速、航向、位置和时间戳结合,构建多维特征向量,用于机器学习模型的输入。 ### 5. 特征标准化与规范化 在特征工程的最后阶段,通常需要对提取的特征进行标准化和规范化处理,以确保不同特征之间的可比性和模型的稳定性: - **标准化**:将特征转换为均值为0、标准差为1的分布,适用于具有高斯分布的特征。 - **归一化**:将特征缩放到一个特定的范围(如[0,1]),适用于分布不均匀或具有明显边界的特征。 - **离散化**:将连续特征转换为离散特征,例如将航速划分为多个区间,每个区间对应一个离散值。 ### 6. 特征选择 在完成特征提取后,通常需要进行特征选择,以减少特征维度并提高模型的性能: - **过滤法**:根据特征与目标变量之间的相关性(如皮尔逊相关系数)选择重要特征。 - **包装法**:通过模型的性能评估来选择最优特征子集。 - **嵌入法**:在模型训练过程中自动选择重要特征,例如Lasso回归和随机森林中的特征重要性评估。 ### 示例代码:特征提取与标准化 以下是一个简单的Python代码示例,展示如何从AIS数据中提取船舶类型的特征并进行标准化处理: ```python import pandas as pd from sklearn.preprocessing import StandardScaler # 假设ais_data是一个包含AIS数据的DataFrame # 提取静态特征 static_features = ais_data[['MMSI', 'Name', 'Type of Ship', 'Length', 'Beam']] # 提取动态特征 dynamic_features = ais_data[['SOG', 'COG', 'Latitude', 'Longitude', 'Timestamp']] # 提取轨迹特征 # 计算相邻记录之间的距离 ais_data['Distance'] = ((ais_data['Latitude'].diff() ** 2 + ais_data['Longitude'].diff() ** 2) ** 0.5) trajectory_length = ais_data.groupby('MMSI')['Distance'].sum().reset_index() trajectory_length.columns = ['MMSI', 'Trajectory_Length'] # 标准化处理 scaler = StandardScaler() dynamic_features_scaled = pd.DataFrame(scaler.fit_transform(dynamic_features[['SOG', 'COG']]), columns=['SOG_Scaled', 'COG_Scaled']) # 合并所有特征 final_features = pd.merge(static_features, dynamic_features_scaled, left_index=True, right_index=True) final_features = pd.merge(final_features, trajectory_length, on='MMSI') # 输出最终特征 print(final_features.head()) ``` ### 相关问题 1. 如何利用AIS数据进行船舶轨迹预测? 2. 在AIS数据中,如何处理缺失值和异常值? 3. 船舶类型的分类模型中,哪些特征最为重要? 4. 如何评估AIS数据特征工程的效果? 5. 在AIS数据中,如何结合时间序列分析提取动态特征
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值