论文辅助笔记:处理geolife数据

news2024/12/26 20:58:50

论文笔记:Context-aware multi-head self-attentional neural network model fornext location prediction-CSDN博客

 对应命令行里

    python preprocessing/geolife.py 20

这一句

1 读取geolife数据

pfs, _ = read_geolife(config["raw_geolife"], print_progress=True)

2  生成staypoint 数据

根据geolife数据,使用滑动窗口的方法获取staypoint
    
   同时geolife DataFrame加一列staypoint

pfs, sp = pfs.as_positionfixes.generate_staypoints(
        gap_threshold=24 * 60, 
        include_last=True, 
        print_progress=True, 
        dist_threshold=200, 
        time_threshold=30, 
        n_jobs=-1
    )

 

2.1  判断staypoint是否是活动对应的staypoint

sp = sp.as_staypoints.create_activity_flag(
    method="time_threshold", 
    time_threshold=25)

如果staypoint停留时间>25min,那么是为一个活跃的staypoint

3 在两个stypoint之间的部分创建行程段

在两个stypoint之间的部分创建行程段
【如果两个非staypoint之间的时间间隔大于阈值的话,视为两个行程段】

pfs, tpls = pfs.as_positionfixes.generate_triplegs(sp)

4 根据停留点和行程段创建trip数据集

sp, tpls, trips = generate_trips(sp, tpls, add_geometry=False)

staypoint之前的trip_id,之后的trip_id

行程和行程的trip_id

行程和行程的始末staypoint_id

5 每个用户时间跟踪质量相关内容

quality_path = os.path.join(".", "data", "quality")
quality_file = os.path.join(quality_path, "geolife_slide_filtered.csv")
quality_filter = {"day_filter": 50, "window_size": 10}
valid_user = calculate_user_quality(
    sp.copy(), 
    trips.copy(), 
    quality_file, 
    quality_filter)
'''

array([  0,   2,   3,   4,   5,  10,  11,  12,  13,  14,  15,  17,  20,
        22,  24,  25,  26,  28,  30,  34,  35,  36,  37,  38,  39,  40,
        41,  42,  43,  44,  45,  46,  50,  51,  52,  55,  56,  58,  59,
        62,  63,  65,  66,  67,  68,  71,  73,  74,  78,  81,  82,  83,
        84,  85,  89,  91,  92,  95,  96,  97,  99, 101, 102, 104, 110,
       111, 112, 114, 115, 119, 122, 125, 126, 128, 130, 131, 132, 133,
       134, 140, 142, 144, 147, 153, 155, 163, 167, 168, 172, 174, 179,
       181], dtype=int64)
'''
'''
        
        valid_user——有记录天数大于day_filter天的那些user_id
        这个函数同时返回了一个csv文件,记录了这些user_id的的时间跟踪质量
    
'''

这个函数的原理如下: 

5.0 准备部分

trips["started_at"] = pd.to_datetime(trips["started_at"]).dt.tz_localize(None)
trips["finished_at"] = pd.to_datetime(trips["finished_at"]).dt.tz_localize(None)
sp["started_at"] = pd.to_datetime(sp["started_at"]).dt.tz_localize(None)
sp["finished_at"] = pd.to_datetime(sp["finished_at"]).dt.tz_localize(None)

sp["type"] = "sp"
trips["type"] = "tpl"
df_all = pd.concat([sp, trips])

 

5.1  横跨多天的staypoint/行程段进行拆分

df_all = _split_overlaps(df_all, granularity="day")
'''
如果一个trips/staypoint横跨多天了,那么就拆分成两个trips/staypoint
'''

5.2 更新每个trips/staypoint的持续时

df_all["duration"] = (df_all["finished_at"] - df_all["started_at"]).dt.total_seconds()

5.3 计算每个用户的时间跟踪质量

trackintel 笔记:generate_staypoints,create_activity_flag-CSDN博客

total_quality = temporal_tracking_quality(df_all, granularity="all")

某一用户从第一条记录~最后一条记录 这一段时间内,有多少比例的时间是在staypoint/trip的范围内的

【但这个好像没啥用?】

5.4  计算每个用户第一条&最后一条记录之间的天数跨度

total_quality["days"] = (
        df_all.groupby("user_id").apply(lambda x: (x["finished_at"].max() - x["started_at"].min()).days).values
    )

5.5 筛选时间跨度>阈值的user id

user_filter_day = (
        total_quality.loc[(total_quality["days"] > quality_filter["day_filter"])]
        .reset_index(drop=True)["user_id"]
        .unique()
    )

5.6 user_id,每window_size周的时间跟踪质量

sliding_quality = (
        df_all.groupby("user_id")
        .apply(_get_tracking_quality, window_size=quality_filter["window_size"])
        .reset_index(drop=True)
    )

 

5.6.1 _get_tracking_quality

def _get_tracking_quality(df, window_size):

    weeks = (df["finished_at"].max() - df["started_at"].min()).days // 7
    '''
    一个user有几周有数据
    '''
    start_date = df["started_at"].min().date()

    quality_list = []
    # construct the sliding week gdf
    for i in range(0, weeks - window_size + 1):
        curr_start = datetime.datetime.combine(start_date + datetime.timedelta(weeks=i), datetime.time())
        curr_end = datetime.datetime.combine(curr_start + datetime.timedelta(weeks=window_size), datetime.time())
        #这里window_size=10,也即10周

        # the total df for this time window
        cAll_gdf = df.loc[(df["started_at"] >= curr_start) & (df["finished_at"] < curr_end)]
        #这10周这个用户的记录
        if cAll_gdf.shape[0] == 0:
            continue
        total_sec = (curr_end - curr_start).total_seconds()

        quality_list.append([i, cAll_gdf["duration"].sum() / total_sec])
        #这10周有记录的比例
    ret = pd.DataFrame(quality_list, columns=["timestep", "quality"])
    ret["user_id"] = df["user_id"].unique()[0]
    return ret

5.7 有记录天数大于50天的那些user_id,每window_size周的时间跟踪质量

filter_after_day = sliding_quality.loc[sliding_quality["user_id"].isin(user_filter_day)]
filter_after_day

5.8 每个筛选后的user_id的平均滑动时间跟踪质量

filter_after_user_quality = filter_after_day.groupby("user_id", as_index=False)["quality"].mean()

5.9 函数结束

filter_after_user_quality.to_csv(file_path, index=False)
#平均滑动时间跟踪质量保存至本地
return filter_after_user_quality["user_id"].values
#返回持续时间大于50天的数据

6 筛选staypoint

6.1 筛选在valid_user里面的

sp = sp.loc[sp["user_id"].isin(valid_user)]

6.2 筛选活跃的

sp = sp.loc[sp["is_activity"] == True]
sp

7 聚合staypoint(成为station)

sp, locs = sp.as_staypoints.generate_locations(
        epsilon=50, 
        num_samples=2, 
        distance_metric="haversine", 
        agg_level="dataset", 
        n_jobs=-1
    )

7.1 去除不在station里面的staypoint(因为这个任务是next station prediction)

sp = sp.loc[~sp["location_id"].isna()].copy()

7.2 station去重

不同user 可能共享一个location,相同位置的location只保留一个

locs = locs[~locs.index.duplicated(keep="first")]

 

7.2 将station信息保存至locations_geolife.csv

8 合并时间阈值内的staypoint

sp_merged = sp.as_staypoints.merge_staypoints(
        triplegs=pd.DataFrame([]), 
        max_time_gap="1min", 
        agg={"location_id": "first"}
    )

如果两个停留点之间的最大持续时间小于1分钟,则进行合并

9 每个staypoint的持续时间

sp_merged["duration"] = (sp_merged["finished_at"] - sp_merged["started_at"]).dt.total_seconds() // 60

10 添加和计算新的时间相关字段

sp_time = enrich_time_info(sp_merged)
sp_time

10.1 enrich_time_info(sp)

def enrich_time_info(sp):
    sp = sp.groupby("user_id", group_keys=False).apply(_get_time)
    #使用 groupby 根据 user_id 对数据进行分组,并应用辅助函数 _get_time 处理每个组的数据。

    sp.drop(columns={"finished_at", "started_at"}, inplace=True)
    #删除 finished_at 和 started_at 列

    sp.sort_values(by=["user_id", "start_day", "start_min"], inplace=True)
    #对数据进行排序

    sp = sp.reset_index(drop=True)

    # 
    sp["location_id"] = sp["location_id"].astype(int)
    sp["user_id"] = sp["user_id"].astype(int)

    # final cleaning, reassign ids
    sp.index.name = "id"
    sp.reset_index(inplace=True)
    return sp

10.2 _get_time(df)

def _get_time(df):
    min_day = pd.to_datetime(df["started_at"].min().date())
    #将 started_at 的最小日期(min_day)作为基准点,用于计算其他时间点相对于此日期的差异

    df["started_at"] = df["started_at"].dt.tz_localize(tz=None)
    df["finished_at"] = df["finished_at"].dt.tz_localize(tz=None)

    df["start_day"] = (df["started_at"] - min_day).dt.days
    df["end_day"] = (df["finished_at"] - min_day).dt.days
    #计算 start_day 和 end_day 字段,这两个字段表示相对于 min_day 的天数差异。

    df["start_min"] = df["started_at"].dt.hour * 60 + df["started_at"].dt.minute
    df["end_min"] = df["finished_at"].dt.hour * 60 + df["finished_at"].dt.minute
    #计算 start_min 和 end_min 字段,这些字段表示一天中的分钟数,用于精确到分钟的时间差异计算

    df.loc[df["end_min"] == 0, "end_min"] = 24 * 60
    #如果 end_min 等于 0,表示结束时间为午夜,为了避免计算错误,手动将其设置为 1440(即24小时*60分钟)

    df["weekday"] = df["started_at"].dt.weekday
    #计算 weekday 字段,表示 started_at 所在的星期几(0代表星期一,6代表星期日)

    return df

11 sp_time 存入sp_time_temp_geolife.csv

12 _filter_sp_history(sp_time)

这一部分写的有点繁琐,有一些语句都是没有必要的,我精简一下

12.0 辅助函数

12.0.1 split_dataset

12.0.2 get_valid_sequence

12.1 划分训练、验证、测试集

train_data, vali_data, test_data = split_dataset(sp_time)

每一个user 前60%天 训练,中间20%天验证,后20%天测试

12.2 获取所有“valid”的行id

所谓valid,指的是那些在给定时间窗口(previous_day 天,这里例子中是7天)内,在当前记录之前有至少三条记录的行ID

previous_day_ls = [7]
all_ids = sp[["id"]].copy()

for previous_day in previous_day_ls:
        valid_ids = get_valid_sequence(train_data, previous_day=previous_day)
        valid_ids.extend(get_valid_sequence(vali_data, previous_day=previous_day))
        valid_ids.extend(get_valid_sequence(test_data, previous_day=previous_day))

        all_ids[f"{previous_day}"] = 0
        all_ids.loc[all_ids["id"].isin(valid_ids), f"{previous_day}"] = 1
all_ids.set_index("id", inplace=True)
final_valid_id = all_ids.loc[all_ids.sum(axis=1) == all_ids.shape[1]].reset_index()["id"].values
#这一行写的很复杂,其实就是
'''
all_ids[all_ids['7']==1].index.values
'''

筛选所有valid的行id

12.3 筛选train、valid、test中valid的行对应的user_id

valid_users_train = train_data.loc[train_data["id"].isin(final_valid_id), "user_id"].unique()
valid_users_vali = vali_data.loc[vali_data["id"].isin(final_valid_id), "user_id"].unique()
valid_users_test = test_data.loc[test_data["id"].isin(final_valid_id), "user_id"].unique()
valid_users_train

12.4 在train、test、valid上都有的user

valid_users = set.intersection(set(valid_users_train), set(valid_users_vali), set(valid_users_test))

len(valid_users)
#47

12.5 筛选对应的staypoint

filtered_sp = sp_time.loc[sp_time["user_id"].isin(valid_users)].copy()

12.5 valid_user_id和staypoint 分别保存

data_path = f"./data/valid_ids_geolife.pk"
with open(data_path, "wb") as handle:
        pickle.dump(final_valid_id, handle, protocol=pickle.HIGHEST_PROTOCOL)
filtered_sp.to_csv(f"./data/dataset_geolife.csv", index=False)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1612955.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文本生成任务的评价方法BLEU 和 ROUGE

BLEU 是 2002 年提出的&#xff0c;而 ROUGE 是 2003 年提出的。这两种指标虽然存在着一些问题&#xff0c;但是仍然是比较主流的评价指标。 BLUE BLEU 的全称是 Bilingual evaluation understudy&#xff0c;BLEU 的分数取值范围是 0&#xff5e;1&#xff0c;分数越接近1&a…

Mysql The last packet sent successfully to the server was 0 milliseconds ago.

项目启动后&#xff0c;报错&#xff0c;但是我的navicat 数据库连接工具是连接上的&#xff0c;没有问题的&#xff0c;但是程序就是连接不上。端口放开了&#xff0c;防火墙也放开了 先说问题&#xff1a;是网络问题&#xff0c; 如何解决&#xff1a;因为我的机子上又跑了…

思颜肌密:匠心独蕴,传世掠影

赋予延绵岁月以华彩乐章&#xff0c;将来自时间的承诺注入生活每分每秒&#xff0c;在思颜肌密的世界里&#xff0c;恒久之美并非遥不可及&#xff0c;它是艺术&#xff0c;亦是心意。华美节日翩然而至&#xff0c;思颜肌密拉开神秘帷幕&#xff0c;在惊鸿掠影中向世人展现传世…

IO实现方式(同步阻塞、同步非阻塞、IO多路复用)

1. 同步阻塞IO 同步阻塞io在数据在数据拷贝到两个阶段都是阻塞的&#xff0c;即把socket的数据拷贝到内核缓冲区和把内核缓冲区的数据拷贝到用户态到应用程序缓冲区都是阻塞的。用户线程在这个期间不能处理其他任务。 优点&#xff1a;简单易用 缺点&#xff1a;为每一次io请…

基于Springboot+Vue的Java项目-网上超市系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

腾讯后端一面:如果需要实现一个分布式锁,你该如何实现?

更多大厂面试内容可见 -> http://11come.cn 腾讯后端一面&#xff1a;如果需要实现一个分布式锁&#xff0c;你该如何实现&#xff1f; 分布式锁 如果让你来实现一个分布式锁&#xff0c;该如何实现&#xff1f; 实现分布式锁的话&#xff0c;肯定需要一个地方去存储锁的…

Python | Leetcode Python题解之第35题搜索插入位置

题目&#xff1a; 题解&#xff1a; class Solution:def searchInsert(self, nums: List[int], target: int) -> int:left, right 0, len(nums) #采用左闭右开区间[left,right)while left < right: # 右开所以不能有,区间不存在mid left (right - left)//2 # 防止溢出…

java线程-线程池

简介 工作原理 如何获取线程池对象 构造器的参数含义 注意事项 构造器-ThreadPoolExecutor // ArrayBlockingQueue 是一个有界的阻塞队列&#xff0c;它的内部实现是一个数组。有界的意思是它的容量是有限的&#xff0c;我们必须在创建 ArrayBlockingQueue 实例的时候指定容量…

IMUGNSS的误差状态卡尔曼滤波器(ESKF)---更新过程

IMU&GNSS的误差状态卡尔曼滤波器&#xff08;ESKF&#xff09;---更新过程 ESKF的更新过程 ESKF的更新过程 前面介绍的是ESKF的运动过程&#xff0c;现在考虑更新过程。假设一个抽象的传感器能够对状态变量产生观测&#xff0c;其观测方程为抽象的h,那么可以写为 其中z为…

科研基础与工具(论文搜索)

免责申明&#xff1a; 本文内容只是学习笔记&#xff0c;不代表个人观点&#xff0c;希望各位看官自行甄别 参考文献 科研基础与工具&#xff08;YouTube&#xff09; 搜索论文 Google Scholar 谷歌学术 涵盖面太全了&#xff0c;都收录&#xff0c;就会有很多低质量的论文…

NodeRed节点编辑用于边缘计算和规则引擎,能做带UI界面和业务逻辑的上位机或前端应用吗?

先说结论&#xff0c;可以&#xff0c;但是需要有页面嵌套继承类似的技术&#xff0c;实现页面模块化封装&#xff0c;否则难以实现复杂应用。 相信目光敏锐的人都在关注节点编辑在自身行业的应用&#xff01; NodeRed在边缘计算做数据协议解析、以及物联网平台中作为规则链引…

算法训练营day13

一、SlidingWindowMaximum(滑动窗口最大值) 前置题&#xff0c;155.最小栈 参考K神155. 最小栈 - 力扣&#xff08;LeetCode&#xff09; 做完最小栈的题能更好的理解这道题 鄙人想到了开辟空间来保存最小值&#xff0c;使用的HashMap&#xff1b;K神用的是栈逻辑优化 cla…

网盘_游戏_博客自动化部署(Nginx多项目部署)

目录 一.前提介绍 二.环境介绍 三.自述&#xff08;脚本&#xff09; 四.关于Nginx多项目部署 一.前提介绍 在我之前的博客里详细介绍了上述项目的部署&#xff0c;那么如何使用简单脚本自动部署和使用Nginx多项目部署是本文来介绍的基础篇章。 二.环境介绍 CentOS Linux…

吴恩达深度学习 (week5,6)

文章目录 一、训练开发测试集二、机器学习基础三、 正则化初步介绍四、Dropout 正则化五、其他正则化方法六、归一化输入介绍七、梯度消失与梯度爆炸八、神经网络的权重初始化九、梯度数值逼近和检验十、上述学习总结第一题 划分训练/开发/测试集第二题 开发和测试集分布第三题…

gradle安装和部署

准备工作 下载地址&#xff1a;https://gradle.org/releases/ 安装和配置环境变量 将压缩包解压到/usr/local/目录下 unzip gradle-8.7-bin.zip -d /usr/local/找到gradle的安装目录/usr/local/gradle-8.7 编辑/etc/vi /etc/profileprofile配置环境变量&#xff08;这是ce…

duke liver datasets数据处理

Duke liver datasets 如果大家是做医学图像处理的&#xff0c;刚好又是做肝脏那边的&#xff0c;对这个数据集应该不会陌生 我发现网上现有的资料很少有说怎么读取这个数据集的&#xff0c;由于我之前一直都是做的nii格式的数据集&#xff0c;现在碰到了dicom格式的数据集页研…

SQLite导出数据库至sql文件

SQLite是一款实现了自包含、无服务器、零配置、事务性SQL数据库引擎的软件库。SQLite是世界上部署最广泛的SQL数据库引擎。 SQLite 是非常小的&#xff0c;是轻量级的&#xff0c;完全配置时小于 400KiB&#xff0c;省略可选功能配置时小于250KiB。 SQLite 源代码不受版权限制。…

分类神经网络3:DenseNet模型复现

目录 DenseNet网络架构 DenseNet部分实现代码 DenseNet网络架构 论文原址&#xff1a;https://arxiv.org/pdf/1608.06993.pdf 稠密连接神经网络&#xff08;DenseNet&#xff09;实质上是ResNet的进阶模型&#xff08;了解ResNet模型请点击&#xff09;&#xff0c;二者均是…

数字阅览室解决方案

一、方案概述 “数字阅览室”概念一经提出&#xff0c;就得到了广泛的关注&#xff0c;纷纷组织力量进行探讨、研究和开发&#xff0c;进行各种模型的试验。随着数字地球概念、技术、应用领域的发展&#xff0c;数字阅览室已成为数字地球家庭的成员&#xff0c;为信息高速公路…

Flowable 基本用法

一. 什么是Flowable Flowable 是一个基于 Java 的开源工作流引擎&#xff0c;用于实现和管理业务流程。它提供了强大的工作流引擎和一套丰富的工具&#xff0c;使开发人员能够轻松地建模、部署、执行和监控各种类型的业务流程。Flowable 是 Activiti 工作流引擎的一个分支&am…