TimeScope,一个简单的桌面活动记录器
TimeScope
这是几个月前一时兴起写的小项目,最近差不多完结了,在博客里稍微记录一下
这是repo的地址:repo-address
Abstract
TimeScope – 一个面向windows的桌面应用记录小程序
主要依赖的库:
- 进程与窗口采集:
pywin32psutil - 数据存储:
sqlite - 数据可视化:
matplotlib - 文本分类:
fasttext,jieba - gui,后台与托盘化:
customtkinter,pytray,PIL
1. Analysis , 数据获取与处理
1).数据获取
简单的说,就是定一个时钟,用pywin32库去获取一下当前的焦点窗口的信息,包括
- 进程名
- 窗口名
然后结合当前的时间去把这个数据放到数据库里。
数据库的结构是这样的,有两张表
| Processes | window_sessions |
|---|---|
| name | process_id |
| executable_path (暂时未使用,辅助调试) | window_title |
| first_seen (暂时未使用,辅助调试) | start_time |
| last_seen (暂时未使用,辅助调试) | end_time |
主要的循环是这样的,就是检查当前的焦点和current_session是否相同,不相同则更新记录
更新的时候,如果获取到当前窗口的process对应的name,和current_process_id一致的时候,会用这个process的id去创建一个新的session;
如果process.name发生了变化,那就再新建一个process和对应的session
1 | loop(): |
2).数据统计
最后统计的时候遍历的是window_session里的内容,然后用matplotlib画图就好了
3).遇到的问题
主要遇到的问题是,当你的电脑熄屏的时候,代码无法自动识别并终止记录。这就导致当你终止当前的应用的时候,是包含了熄屏的时间的
我首先想到的是让程序能够识别熄屏和开机,win32库里似乎有相关的实现,但是很遗憾实际上并没有用,这个功能似乎没那么灵敏
于是我想到了一个内置时钟的方法,通过维护一个内置的时钟time_manager,它自己更新自己的状态。当这个内置时钟的时间与系统实际的时间大于一个设定的阈值max_gap_seconds之后,就触发一个修复,用内置时钟的时间结束上一段进程,同时更新内置时钟
2.classifier/ML分类器
有了统计数据之后,我就想再设计一个classifier,用来统计用于各项类型活动的时间
一开始的构想是用一些规则+训练一个小型的bert,毕竟一些特定的应用只属于特定的活动类型,而网页和一些视频播放器则要根据窗口标题去进行更细致的分类
但是发现bert实在太大了,就换成了用TF-IDF和fasttext各训了几版
1).TF-IDF
Token Frequency - Inverse Document Frequency,是词频TF和逆文档频率IDF的乘积
其核心思想是:出现在当前文段频率高,但是在全集中不常见的词是一个重要的特征词
- 词频
- 逆文档频率
- 权重$ TF-IDF(t,d)=TF(t,d)⋅IDF(t)$
通过对一个句子里的所用文段使用以上算法,能得到一个高维向量
例子:
词表:["code","visual","studio","python","game"]
文本向量:[0.8, 0.3, 0.3, 0, 0]
训练的目标是一个线性多分类器,对于每一个分类的类别都有对应的权重 和偏置 ,
输入向量后得到对应类别的分数
最后挑出最高的哪一类就行
缺点:
- 在遇到新词的时候无能为力
- 特征维度不稳定
2).FastText
工作流程(简化版)
- 切词:文本被拆成词(中文可先分词)。
- 拆子词:每个词再被拆成字符 n‑gram(比如 “coding” → “co”,“cod”,“odi”,…)。
- 词向量构造:词向量 = 它的所有 n‑gram 向量相加。
- 句向量构造:文本向量 = 所有词向量平均或加权求和。
- 线性分类:用一个线性层(softmax)输出各类别概率。
3.未完待续
目前还考虑在添加一个久坐提醒功能。
想要实现一个笨笨的提醒似乎不难,打包上系统提醒的库就行。
但是有没有更智能的方法?比如有可能有的时候人并不在电脑前(每种类型的程序都有一个运行的时间合理性,人总会在一定的时间后切换程序,而不是长时间一直保持一个不变焦点窗口),可以以此为凭据设计出更智能的提醒