Memoria 开发记录 30:时刻分组不是按时间切块——地点、时间与垃圾隔离
前言
相册里的“时刻分组”看起来像是按时间分段:同一天、同一小时或同一批照片合并成一个事件。但真实相册并不是均匀时间序列。用户可能两小时内从一个城市移动到另一个城市,也可能在同一个景区持续拍摄半天。
如果只按时间合并,会把不相关的照片揉在一起;如果只按地点合并,又会拆散一次连续行程。时刻分组需要同时考虑时间、地点、移动距离和照片质量。
为什么不能只按时间
一个简单规则可能是“两小时内的照片属于同一时刻”。但这会遇到明显问题:
10:00 在车站
11:30 到另一个城区
12:00 在景区
这些照片时间接近,但地点跨度很大。它们可以属于同一天行程,却不应该被合成同一个“时刻”。时刻的语义更接近“在一段连续场景中发生的回忆”,而不是纯时间窗口。
因此聚类需要在短时间内检查地点距离。如果时间很近但距离超过阈值,应拆分为不同事件。
地点也不能过度严格
另一边,如果地点完全依赖 POI 精确匹配,也会把同一景区内的照片拆得过碎。定位可能落在附近商铺、青年旅舍、停车场或景区入口。景区本身也不是一个点。
更合理的策略是:
- 同城内允许一定移动;
- 景区、校区、商圈允许合理半径;
- 短时间远距离移动要拆分;
- 合并两个事件时检查边界距离;
- 不跨城市强行合并。
这比“同一 POI 才合并”更符合真实相册。
confirmed junk 不应进入用户可见分组
低价值照片治理引入了多个状态:候选、待确认、已确认垃圾。用户可见的相册分组应该只排除已确认垃圾,而不是把所有候选都隐藏。
这是一个很重要的产品边界:
pending / candidate:
系统怀疑低价值,但用户还没确认
不应从普通相册中消失
confirmed junk:
用户确认隔离
不应进入时刻分组、推荐和故事候选
如果候选阶段就隐藏照片,系统误判会直接造成“照片丢了”的体验;如果 confirmed junk 仍进入分组,又会破坏清理功能的可信度。
分组结果要服务于行程感
用户看“时刻分组”,其实是在寻找一段行程或一次活动。好的分组应该能形成这样的阅读体验:
上午:出发与路上
中午:到达景区
下午:核心游览
晚上:夜景和返程
这要求事件聚类不仅能切开明显不同地点,也要保留连续段落。时间、地点和照片数量都只是信号,最终目标是让用户觉得“这确实是一段回忆”。
人脸聚类也需要保守合并
同一轮改造中,人脸聚类也收紧了合并逻辑。原因类似:把相似的人错误合并,比把同一个人拆成两个簇更伤信任。
人物聚类尤其容易出现链式合并:
A 像 B
B 像 C
但 A 不像 C
如果算法只看局部邻居,就会把三者合并。更保守的策略应检查候选与簇中心、多个成员之间的一致性,并为低质量样本保留独立状态。
总结
时刻分组不是简单按时间切块,而是对一次活动或一段行程的近似建模。时间、地点、移动距离、低价值隔离和人物线索都需要共同约束。
关键经验包括:
- 短时间不等于同一时刻;
- 地点距离过大时应拆分事件;
- 景区和区域型地点要容忍定位偏移;
- 用户可见分组只排除 confirmed junk;
- 候选垃圾状态不应直接隐藏照片;
- 人脸聚类要防止相似人物链式误合并;
- 分组最终要服务于“行程感”和可读性。
对应提交:1c8b77f、419e851。
浙公网安备 33010602011771号