commit 7fc76aaafd5ee359e4686682428a138f810653ad Author: LorenzoZhao Date: Wed Sep 23 23:24:01 2026 +0800 建立分批同步基线(基础文件) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8e774e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +/E题数据/ +/.venv/ +/.uv/ +/.python-version +/uv.lock +/math/.venv/ +/math/.uv/ +/math/.python-version +/math/uv.lock +/math/.cache/ +/math/cache/ +/math/**/__pycache__/ +/math/**/*.py[cod] +/Q1/.venv/ +/Q1/models/ +/Q1/__pycache__/ +/Q1/outputs/ +# TEMPORARY: output batches are force-added from the saved path lists +/deep_learning/Q1/outputs/ diff --git a/deep_learning/Q1.md b/deep_learning/Q1.md new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/deep_learning/Q1.md @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deep_learning/Q1/.python-version b/deep_learning/Q1/.python-version new file mode 100644 index 0000000..a128d5c --- /dev/null +++ b/deep_learning/Q1/.python-version @@ -0,0 +1 @@ +3.14.7 diff --git a/deep_learning/Q1/README.md b/deep_learning/Q1/README.md new file mode 100644 index 0000000..55b90b8 --- /dev/null +++ b/deep_learning/Q1/README.md @@ -0,0 +1,286 @@ +# Q1: feature extraction and temporal alignment + +Q1's required output is a reproducible set of three-modality features extracted +from all 100 raw videos in Attachment 1, with traceable timestamps and at least +one inspectable text/audio/video example. The four-method comparison and +learned probes are optional research extensions; they follow the extraction and +submission artifacts rather than replacing them. + +For a nontechnical introduction to the extraction steps and their limits, see [方法说明_零基础版.md](方法说明_零基础版.md). + +## Environment + +The project is managed with `uv`. The Linux environment selects PyTorch's CUDA +13.0 wheel; the checked machine is an RTX 5070 Ti under Fedora WSL. + +```bash +cd Q1 +uv sync +uv run python -c "import torch; print(torch.__version__, torch.cuda.is_available())" +``` + +`uv.lock` records the exact environment. The root data directory remains +outside the Python environment and is not copied into the package. + +## Q1-E1: extract the 100 raw-video samples + +```bash +cd Q1 +uv run python -m q1.extract_features --output-dir outputs/q1_features +``` + +The first run downloads the pinned-by-name Hugging Face model revisions to the +local cache and the MediaPipe face model to `Q1/models/`. Use `--resume` to +continue an interrupted run. The supplied transcripts remain unchanged. + +Each compressed NPZ keeps variable-length features without disk padding: + +- Text: 768-d BERT vectors, one mean-pooled vector per supplied whitespace word. +- Audio: 25-d eGeMAPSv02 low-level descriptors from mono 16 kHz audio, with + frame-center timestamps. +- Vision: 192-d DeiT-Tiny CLS embeddings for every frame sampled at 5 fps; + optional 52-d MediaPipe face blendshapes have a separate validity mask. +- Alignment: CTC Viterbi word intervals in seconds from clip start, plus + word-level mean Audio and Vision features. Missing CTC word spans are + interpolated only as a flagged fallback (`word_alignment_valid=false`). + +Outputs are written to `outputs/q1_features/`: one NPZ per original +`video_id/clip_id`, JSONL sample logs, a 100-row sample table, a 300-row +sample-by-modality table, a run manifest, and a typical-sample figure under +`reports/`. Missing faces do not remove the general Vision embedding; missing +modality values remain masked and are logged. + +The extracted feature files and reports are approximately 10 MB before any +optional Q1 method-comparison outputs. Keep the final combined Q1/Q2/Q3 +attachments under the problem's 50 MB cap. + +## Q1-E0: sample coverage audit + +```bash +cd Q1 +uv run python -m q1.audit +``` + +The audit checks that the label workbook contains exactly 100 unique +`(video_id, clip_id)` pairs, resolves each pair to one MP4, counts the 37 +`video_id` groups, probes each MP4's duration and audio/video streams, and checks +polarity labels against the sign of the continuous label. It writes +`outputs/audit/manifest.csv` and `outputs/audit/coverage_summary.json`. + +## Required Q1 deliverables + +1. Three-modality features generated from the original 100 videos and their + supplied transcripts. Keep every original row and label; if a stream needs a + mask or truncation, retain the source and record the rule. +2. Per-sample and per-modality records for effective duration, feature + dimension, valid length, padding rule, alignment granularity, and mapping + back to source time. +3. A 100-sample results table and a typical-sample view connecting transcript + text, aligned speech intervals, video frame times, and feature positions. +4. A run manifest with tool/model versions, parameters, logs, and commands. +5. Compressed feature files that fit the competition's 50 MB total-attachment + limit together with the Q2/Q3 code and result files. + +The Attachment 1 media and labels are fixed input. The labels are for the +required inventory and later prediction probes; they are not a required training +target for the primary Q1 alignment model. + +## Common feature and alignment contract + +Each modality is supplied as a padded `SequenceBatch`: + +- `features`: `[B, L_m, D_m]` feature values; +- `times`: `[B, L_m]` timestamps in seconds from clip start; +- `valid`: `[B, L_m]` boolean mask; padded positions are false. + +The duration vector is `[B]`. Every method returns `AlignmentOutput` with +`weights[m]` shaped `[B, K, L_m]`. Rows sum to one and columns for padding stay +zero. `aligned[m]` is the weighted or learned representation on the shared +`K=50` grid. M1 takes one ordered `[word_count, 2]` forced-word-interval array +per sample; its 50 grid intervals partition transcript word order and preserve +the measured word times. M2 uses equal-duration windows. + +M3 uses text-order slots as queries for Audio and Vision. M4 learns K shared +latent queries and attends separately to all three sequences. Both use the same +module dimensions and can be trained with `alignment_training_loss`; M1/M2 have +no training loss. + +## Initial metrics + +`q1.metrics` provides normalized expected-time trajectories, monotonicity +violation rate, normalized attention entropy, and shortest contiguous 80% +attention width. Entropy and width are diagnostics, not one-direction ranking +scores. A flat trajectory has zero backward violations too, so inspect its +time span as well; otherwise a collapsed alignment can look monotone. Grid-slot +retrieval is also available as a representation-consistency probe; because its +positive is defined by the shared grid index, it is not independent evidence +of temporal correctness. Use a human-labeled event subset for direct temporal +claims. + +## Optional method-comparison rules + +- Extract all three modalities once with the same extractor versions and keep + source timestamps, model IDs, and preprocessing parameters in the manifest. +- Split clips by `video_id`; never allow clips from one source video into both + training and validation folds. +- Fit learned M3/M4 models only on training folds. Freeze them before probes. +- Keep reconstruction and emotion probes identical across alignment methods. +- Do not use emotion labels in the primary alignment loss. +- Record all seeds, fold IDs, attention matrices, masks, and metrics alongside + each output. + +## M1–M4 grouped comparison runner + +Run the optional method comparison after feature extraction and the coverage +audit are complete: + +```bash +cd Q1 +uv run python -m q1.compare_methods +``` + +The runner selects CUDA when available, fits feature normalization on each +training fold only, and uses five grouped folds by `video_id`. M3/M4 share the +same masked-reconstruction, cross-modal contrastive, and temporal-monotonicity +objective; emotion labels are withheld from alignment training. It writes +fold checkpoints, out-of-fold alignment matrices, trajectories, retrieval and +reconstruction probes, and a frozen emotion probe under +`outputs/method_comparison/`. Retrieval uses same-grid positives, so it is a +representation-consistency check rather than independent temporal ground +truth. Direct human IoU/MATE scores require a separately annotated event set. +On Fedora WSL, PyTorch's Triton CUDA backward path also needs a system C +compiler and Python headers (`sudo dnf install gcc python3-devel`); Python +packages remain managed by `uv`. + +## M3/M4 attention-collapse follow-up + +After the first comparison showed nearly uniform M3/M4 attention, the staged +follow-up changes only learned alignment losses and probes. It reuses the saved +feature files and original video-grouped folds, and leaves M1/M2 untouched: + +```bash +cd Q1 +uv run python -m q1.train_alignment_variants +``` + +The runner executes v2-a (Span), v2-b (Span + far-slot Diversity), and v2-c +(Span + Diversity + weak Temporal Band) with the same folds and three seeds. +It records `C_row` during validation, tests within-clip temporal retrieval, +and compares frozen masked reconstruction with shuffled cross-modal slots. +Full checkpoints and per-sample alignment matrices are written under +`outputs/alignment_v2/`; use `outputs/alignment_v2/report_bundle/` for a +lightweight shareable summary. RoPE/Gaussian-bias experiments should wait until +the attention maps show time-progressing local bands. + +## M3/M4 learnability diagnostics + +Before running more architecture or positional-encoding sweeps, diagnose the +attention-collapse behavior with the small D0–D5 suite plus the D1-S synthetic +control: + +```bash +cd Q1 +uv run python -m q1.alignment_debug +uv run python -m q1.synthetic_alignment_sanity +uv run python -m q1.alignment_key_position_debug +uv run python -m q1.alignment_heldout_debug +uv run python -m q1.summarize_alignment_debug +``` + +D0/D1 overfit one representative clip. D2/D3 use all 100 clips for an +in-sample optimization diagnostic, with one seed. D1 compares M4 with and +without fixed sinusoidal positions; D2 uses a timestamp-derived Gaussian +attention target; D3 adds the same reconstruction and contrastive components +used in the prior learned methods. The Gaussian target is only a weak temporal +prior, not human alignment ground truth. The run records component losses and +gradients for attention Q/K and M4 latent slots, then saves per-sample metrics, +heatmaps, trajectories, and checkpoints under `outputs/alignment_debug/`. +The optional synthetic control uses only `[t, t², 1]` source features to verify +that M3/M4 can fit a known time band when position information is explicit. +The source-time diagnostic adds Fourier time identity to attention keys while +keeping the projected content as values; the held-out runner uses grouped fold +1 by default and fits feature normalization on its training videos only. Its +`--fold` and `--output-dir` options allow the same diagnostic to run on the +remaining grouped folds. +Summarize the existing run without retraining with the second command; it also +builds a compact `outputs/alignment_debug/report_bundle/` without checkpoints. +The diagnostics found nonzero gradients. D4/D5 show that M4 Audio/Vision can +form local bands with explicit time identity, while M3 and the M4 Text branch +still need work. Keep follow-up focused on those branches instead of broad +positional-encoding sweeps; see [RESULTS.md](RESULTS.md) for metrics and +interpretation. + +## Same-slot vs shifted-time correspondence evaluation + +Temporal attention bands only show where a slot looks. To check whether the +frozen content in the slot can match the other modalities, first create D5 +checkpoints for all five `video_id`-grouped folds with +`q1.alignment_heldout_debug`, then run: + +```bash +cd Q1 +uv run python -m q1.correspondence_eval --device cuda --epochs 40 --seed 42 +``` + +The evaluator applies the same train-only linear probe to M1, M2, and both +time-code settings of M3/M4. It reports within-video shifted-similarity curves, +same-video temporal retrieval, and matched-vs-shifted AUC on held-out videos. +The probe learns same-slot matching from training clips only; its held-out +scores indicate whether that matchability transfers, not whether semantic +alignment has independent ground truth. Outputs and grouped confidence +intervals are written to `outputs/correspondence_eval/`; see +[RESULTS.md](RESULTS.md) for the current results. + +## M4 Shared Latent structural and functional re-evaluation + +Once the five grouped D5 `M4_sourceTime` checkpoints exist, re-evaluate M4 +without retraining its alignment model: + +```bash +cd Q1 +uv run python -m q1.m4_shared_latent_eval --device cuda --seed 42 --probe-epochs 40 --decoder-epochs 40 --shuffle-repeats 20 +``` + +The evaluator checks self-Gram structure, derives six modality-to-modality +maps through the shared latent slots, measures physical-time trajectories, +cycle and triangle consistency, and runs held-out content-only correspondence, +within-clip retrieval, independent content-shuffle, and aligned-versus-shifted +reconstruction probes. It fits only these small evaluation probes on training +video groups; no emotion labels enter them. The reconstruction target is the +M4 attention-pooled content representation, not raw audio or video. Because +D5 used a timestamp-derived Gaussian prior, its attention weights may carry +time information indirectly even though the probe receives no explicit time +code or slot ID. Time structure and temporal maps therefore are not +independent semantic ground truth. Human event IoU/center error still requires +annotated events. CSVs, checkpoints, the run manifest, and figures are written +to `outputs/m4_shared_latent_eval/`; see [RESULTS.md](RESULTS.md) for the +five-fold results and interpretation. + +## TSFA coarse-to-fine correspondence experiment + +After the five grouped D5 checkpoints exist, freeze M4's source-time branch and +train a content-only local attention branch. The main variant searches within +`±0.10` normalized video time around each frozen M4 temporal center. A +multiply variant applies the M4 attention weights as an additional prior; +random-window and global-window controls test whether the temporal candidate +range matters. The original BERT text, eGeMAPS audio, and DeiT image features +stay fixed. Emotion labels are not used. + +```bash +cd Q1 +uv run python -m q1.tsfa_experiment --device cuda --seed 42 +uv run python -m q1.tsfa_alignment_only_eval --device cuda --seed 42 +``` + +The first command fits one semantic branch and equal-seed correspondence probes +per fold, then evaluates all seven methods on held-out `video_id` groups. The +second pools the *same normalized raw source features* with each method's +alignment matrix before fitting equal probes. It separates source-position +selection from native model value/output projections. Both commands cover all +100 clips exactly once as held-out examples. Summary CSVs, per-clip metrics, +paired video-group confidence intervals, monotonicity/span/entropy diagnostics, +plots, manifests, and checkpoints are written to `outputs/tsfa/`; the small +`report_bundle/` contains shareable +summaries and figures. See [RESULTS.md](RESULTS.md) for the measured tradeoff +and interpretation limits. + diff --git a/deep_learning/Q1/RESULTS.md b/deep_learning/Q1/RESULTS.md new file mode 100644 index 0000000..c299b76 --- /dev/null +++ b/deep_learning/Q1/RESULTS.md @@ -0,0 +1,356 @@ +# Q1 特征提取结果 + +## 题面要求与完成范围 + +按题面第 2、3、5、6 页,Q1 首先要从附件 1 的原始 100 条视频建立可追溯的文本、语音、视觉特征,保持样本覆盖完整,并给出 100 条汇总表、至少一个文本—语音—视频帧对应样例、工具参数与复现信息。原始视频和标签没有被修改。 + +全量特征提取与对应性核验已经完成;随后也按 `video_id` 分组跑完了 M1–M4 的五折方法比较、重构探针与冻结情感探针。结果显示当前 M3/M4 训练目标会产生注意力塌缩,详见文末比较结果;因此没有宣称某个方法已经获得可靠的跨模态对齐。 + +## 数据覆盖审计 + +| 核验项 | 结果 | +| --- | ---: | +| 标签表样本 | 100 | +| 唯一 `(video_id, clip_id)` | 100 | +| 视频文件 | 100 | +| `video_id` 分组 | 37 | +| 音视频均可读取 | 100 | +| 重复、缺失、额外文件 | 0 | +| 标签极性不匹配 | 0 | + +题面给出的片段时长范围下限为 2.648 秒。按解码视频帧时间统计,有两条原始视频短于该下限:`-mJ2ud6oKI8/6` 为 2.2356 秒,`-s9qJ7ATP7w/6` 为 2.4667 秒。两条均保留并正常提取,没有为满足区间而裁剪或删除。详见 [coverage_summary.json](outputs/audit/coverage_summary.json)。 + +## 提取结果 + +| 模态/特征 | 每位置维数 | 全部样本总长度 | 有效覆盖 | +| --- | ---: | ---: | ---: | +| 文本:BERT 词向量 | 768 | 1,932 个词 | 100/100 样本 | +| 音频:eGeMAPSv02 LLD | 25 | 77,261 帧 | 100/100 样本 | +| 视觉:DeiT-Tiny 帧 CLS 向量,5 fps | 192 | 3,948 帧 | 100/100 样本 | +| 补充视觉:MediaPipe 人脸 blendshape | 52 | 随人脸帧变化 | 87/100 样本检测到人脸 | + +词级强制对齐共直接得到 1,920/1,932 个词的时间区间。另有 12 个词分布在 9 条样本中无法直接对齐;它们以单调的零宽度时间点插值,并在 `word_alignment_valid` 中标为 `false`。这些词的音频和视觉词级特征用最近的有效源帧回退,回退标志单独保存在 NPZ 中。 + +本次运行 100 条均无提取错误;13 条样本没有检测到人脸,但它们仍有有效的 DeiT 通用视觉帧嵌入。每条样本一个 NPZ,数值特征存为 float16,时间戳为 float32,掩码为 bool。文件中同时保留原始变长时间序列和按词级时间区间平均后的 Audio/Vision 特征,不做磁盘填充。 + +## 典型样本 + +样本 `-tPCytz4rww/12` 展示了 transcript 词序、CTC 强制对齐区间、eGeMAPS 时序特征,以及相同片段内的抽样视频帧。例图里的文本片段为 “and going to similar in, similar with bedrooms and bathrooms as well”。 + +![典型样本的文本—语音—视频对应图](outputs/q1_features/reports/typical_sample_-tPCytz4rww__12.png) + +## 产物与复现 + +- [100 条样本汇总表](outputs/q1_features/reports/sample_summary.csv) +- [100×3 样本—模态明细表](outputs/q1_features/reports/feature_summary_100x3.csv) +- [逐样本运行日志](outputs/q1_features/logs/samples.jsonl) +- [模型、版本、参数、哈希与运行命令](outputs/q1_features/reports/run_manifest.json) +- [100 个压缩特征文件](outputs/q1_features/features/) + +100 个 NPZ 合计 9,261,634 字节;核心提取报告、日志与特征文件合计 10,460,565 字节。连同下面的轻量对比报告包仍低于题面 50 MB 上限;不要把完整训练检查点和全部逐样本对齐矩阵也放进提交包。 + +复现步骤(在 `deep_learning` 目录执行): + +```bash +cd Q1 +uv sync +uv run python -m q1.audit +uv run python -m q1.extract_features --output-dir outputs/q1_features +``` + +环境为 Python 3.14.7、PyTorch 2.14.0+cu130、torchvision 0.29.0,运行设备为 NVIDIA GeForce RTX 5070 Ti。具体依赖锁定在 [uv.lock](uv.lock),模型修订号、MediaPipe 资产 SHA-256、特征规则和运行参数记录在 `run_manifest.json`。 + +## M1–M4 方法比较 + +### 实验协议 + +- M1 使用 CTC 强制词时间;M2 把每条视频分成 50 个等长时间窗;M3 以文本顺序槽查询音频和视频;M4 使用 50 个共享潜在槽分别查询三个模态。 +- M3/M4 采用相同的自监督目标:连续块跨模态重构、跨模态对比损失和时间单调性损失。情绪标签不进入对齐模型训练。 +- 100 条样本按 37 个 `video_id` 分成 5 折;同一原始视频的片段不会跨训练/验证集。M3/M4 各用 3 个随机种子,所有特征归一化参数只由当前训练折估计。 +- 在每折验证集上冻结对齐,再训练相同结构的检索投影、连续块重构和轻量情绪 Probe。情绪 Probe 使用五段时间池化后的正则化线性分类器/回归器,适合小样本诊断,不代表大型数据集上的最终模型。 + +### 主要发现 + +| 方法 | Audio 熵 ↓ | Vision 熵 ↓ | Audio 时间跨度比例 ↑ | Vision 时间跨度比例 ↑ | T→A R@1 ↑ | Audio 重构 MAE ↓ | 情绪宏 F1 ↑ | 情绪 Pearson ↑ | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| M1 强制时间 | 0.358 | 0.021 | 0.894 | 0.896 | 0.0012 | 0.691 | 0.437 | 0.531 | +| M2 固定窗口 | 0.392 | 0.016 | 0.968 | 0.974 | 0.0014 | 0.662 | 0.343 | 0.508 | +| M3 文本锚定注意力 | 0.992 | 0.983 | -0.002 | -0.005 | 0.0197 | 0.384 | 0.438 | 0.546 | +| M4 共享潜轴 | 1.000 | 1.000 | 0.000 | 0.000 | 0.0071 | 0.378 | 0.414 | 0.507 | + +时间跨度比例是每条样本“最后槽的期望时间减第一槽的期望时间”,再除以片段时长。接近 1 表示大致走过整段视频;接近 0 表示所有槽都落在同一时间附近。熵接近 1 表示注意力近似平均分布。检索使用训练折拟合的相同线性投影,正样本是同片段、同共享槽,因此只是表示一致性探针,不是人工对齐真值。 + +当前结果清楚暴露了学习型方法的问题:M3 的音频/视觉注意力接近均匀,时间跨度接近零;M4 的三种模态注意力几乎完全均匀。M4 的 MVR 虽然为 0,但这是因为平坦轨迹没有“向后走”;所以 MVR 必须与时间跨度和注意力熵一起看。重构误差更低也不能单独证明对齐更好,因为全局平均表示本身容易被重构。冻结情绪 Probe 的折间波动也较大,不能据此断言 M3 的细小优势稳定存在。 + +因此第一轮结论是:M1/M2 提供了可解释、覆盖完整的时间基线;v1 的 M3/M4 没有学到可信的细粒度跨模态对齐。没有人工事件时间标注,第一轮不报告 IoU/MATE,也不声称有直接对齐准确率。 + +### v2 对齐塌缩复查 + +按顺序只改变 M3/M4 的损失项,原始特征、提取器、M1/M2、五折 `video_id` 分组、三个随机种子和训练预算均保持不变。三阶段共训练 90 个 M3/M4 模型,使用 CUDA RTX 5070 Ti,完整运行耗时约 18 分钟。 + +| 阶段 | 新增约束 | 固定设置 | +| --- | --- | --- | +| v2-a | Span | 最小轨迹跨度 0.7,权重 5.0 | +| v2-b | Span + Diversity | 另加相隔至少 6 个槽的注意力行余弦相似度,权重 0.5 | +| v2-c | Span + Diversity + Band | 另加弱时间带约束,容许偏差 0.10,权重 10.0 | + +所有阶段继续使用相同的重构、对比和单调性损失。M3 的时间带目标取文本词时间;M4 使用 50 个均匀槽中心。另记录 `C_row`,即不同槽位注意力行的平均余弦相似度;它越接近 1,槽位关注的位置越相似。 + +| 阶段/方法 | Audio 跨度 | Vision 跨度 | C_row Audio | C_row Vision | T→A R@1(±1 槽) | T→A 精确 R@1 | T→A MASE(槽) | Audio 重构增益 | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| 固定 M1 | 0.894 | 0.896 | 0.000 | 0.028 | 0.067 | 0.025 | 16.28 | 0.012 | +| 固定 M2 | 0.968 | 0.974 | 0.000 | 0.016 | 0.077 | 0.028 | 16.00 | 0.016 | +| v2-a M3 | 0.025 | -0.014 | 0.847 | 0.979 | 0.175 | 0.074 | 14.14 | 0.036 | +| v2-b M3 | 0.030 | -0.016 | 0.777 | 0.961 | 0.191 | 0.083 | 13.59 | 0.060 | +| v2-c M3 | 0.030 | -0.017 | 0.784 | 0.964 | 0.185 | 0.080 | 13.55 | 0.057 | +| v2-a M4 | 0.001 | -0.002 | 0.994 | 0.999 | 0.060 | 0.024 | 17.94 | 0.002 | +| v2-b M4 | 0.002 | -0.001 | 0.983 | 1.000 | 0.061 | 0.025 | 17.90 | 0.005 | +| v2-c M4 | 0.005 | -0.001 | 0.965 | 0.999 | 0.069 | 0.029 | 15.09 | 0.010 | + +跨度是验证样本上的平均“末槽期望时间减首槽期望时间”除以片段时长;负值表示两端略有倒退,仍属于未覆盖时间轴。检索用训练折拟合的投影,在每条留出片段自己的 50 个槽中找匹配位置;R@1 允许误差 ±1 槽,精确 R@1 要求同槽,MASE 是 top-1 的平均绝对槽位误差。随机猜测时 ±1 槽 R@1 约为 0.06。重构增益为 `MAE_shuffled - MAE_aligned`,正值表示保留跨模态槽位关系后误差下降。各均值汇总了折、种子和样本,样本量不应被当作独立视频数。 + +结果表明,Diversity 让 M3 的 Audio 注意力行有所分化,Audio 重构增益也从 v2-a 的 0.036 增至 v2-b 的 0.060;但 M3 Audio 时间跨度仍只有约 0.03,Vision 跨度接近零且 `C_row` 仍高。M4 的弱 Band 约束只带来有限改善,Audio/Vision 注意力仍接近塌缩,重构增益也很小。典型样本图同样显示 M3 Audio/Vision 近似水平轨迹,M4 三模态轨迹近乎平坦。因此这些阶段没有达到“沿时间移动的局部带状对齐”,也不足以证明 M3/M4 学到了可靠对齐;本轮不继续 RoPE、Gaussian Bias 或 latent 长度消融。下一步应先检查学习型注意力为何难以利用时间监督,并调整对齐目标或优化策略,再用相同探针复核。 + +![v2-c 典型样本的对齐热图](outputs/alignment_v2/v2_c/typical_alignment_heatmaps.png) + +![v2-c 典型样本的期望时间轨迹](outputs/alignment_v2/v2_c/typical_alignment_trajectories.png) + +### 文件与复现 + +- [对比总表](outputs/method_comparison/comparison_summary.csv) +- [逐样本对齐指标](outputs/method_comparison/alignment_metrics.csv) 与 [按方法汇总](outputs/method_comparison/alignment_summary.csv) +- [检索探针](outputs/method_comparison/retrieval_summary.csv)、[重构探针](outputs/method_comparison/reconstruction_summary.csv)、[情绪 Probe](outputs/method_comparison/emotion_summary.csv) +- [折分清单](outputs/method_comparison/splits.json)、[训练记录](outputs/method_comparison/training_summary.csv)、[运行清单](outputs/method_comparison/run_manifest.json) +- [典型样本对齐热图](outputs/method_comparison/typical_alignment_heatmaps.png) 与 [时间轨迹图](outputs/method_comparison/typical_alignment_trajectories.png) +- [v2 三阶段对比总表](outputs/alignment_v2/v2_c/comparison_summary.csv)、[v2-c 注意力指标](outputs/alignment_v2/v2_c/alignment_summary.csv)、[v2-c 检索摘要](outputs/alignment_v2/v2_c/retrieval_summary.csv) 与 [v2-c 重构摘要](outputs/alignment_v2/v2_c/reconstruction_summary.csv) +- [v2-c 典型样本热图](outputs/alignment_v2/v2_c/typical_alignment_heatmaps.png)、[v2-c 时间轨迹图](outputs/alignment_v2/v2_c/typical_alignment_trajectories.png)、[逐 epoch 训练记录](outputs/alignment_v2/v2_c/training_history.csv) 与 [运行日志](outputs/alignment_v2/experiment.log) +- [v2 轻量结果包](outputs/alignment_v2/report_bundle/README.md),约 4.6 MB;不含检查点和逐样本矩阵 + +复现命令: + +```bash +cd Q1 +uv sync +uv run python -m q1.compare_methods +uv run python -m q1.train_alignment_variants +uv run python -m q1.alignment_debug +uv run python -m q1.synthetic_alignment_sanity +uv run python -m q1.alignment_key_position_debug +uv run python -m q1.alignment_heldout_debug +uv run python -m q1.summarize_alignment_debug +``` + +本机的 GPU Triton 路径还需要系统 GCC 和 Python 开发头文件;Fedora WSL 可用 `sudo dnf install gcc python3-devel` 安装。完整方法比较目录约 119 MB,其中 30 个折/种子检查点约 53.5 MB;它们是本地研究复现材料,不应和必须提交的特征文件一起全部打包到 50 MB 附件中。可提交/分享的轻量结果包位于 [report_bundle](outputs/method_comparison/report_bundle/),约 1.18 MB;全量训练检查点和 800 个逐样本矩阵仍保存在其上一级目录。 + +v2 塌缩复查的完整材料位于 `outputs/alignment_v2/`,约 348 MB;其中检查点和 1,800 个逐样本矩阵只用于本地研究复现。分享时使用 [v2 report_bundle](outputs/alignment_v2/report_bundle/README.md),约 4.6 MB。完整比较运行清单在 [alignment_v2/run_manifest.json](outputs/alignment_v2/run_manifest.json)。 + +### M3/M4 可学习性诊断(D0–D5 与 D1-S) + +v2 后先做小规模诊断,再决定是否增加位置编码或结构消融。本轮复用现有的 100 条特征,没有修改提取器、M1 或 M2;在 Fedora WSL 中通过 `uv` 使用 RTX 5070 Ti 运行,耗时 103.7 秒,环境为 Python 3.14.7、PyTorch 2.14.0+cu130。 + +| 编号 | 数据与目标 | M4 位置编码 | 目的 | +| --- | --- | --- | --- | +| D0 | 单样本 `-tPCytz4rww/12`,`5 × span + 10 × band`,1,000 步 | 无 | 检查时间损失是否能推动注意力 | +| D1 | 同一样本,仅 Gaussian target KL,1,000 步 | 无 / 固定正弦位置编码 | 检查直接注意力监督与槽位对称性 | +| D1-S | 只用合成时间输入 `[t, t², 1]`,Gaussian target KL,1,000 步 | M4 无 PE / 有 PE | 极简验证注意力实现能否拟合已知时间带 | +| D2 | 全部 100 条,仅 Gaussian target KL,500 步 | 固定正弦位置编码 | 检查全数据下直接时间目标是否可优化 | +| D3 | 全部 100 条,Gaussian KL + 遮挡重构 + 跨模态对比,500 步 | 固定正弦位置编码 | 检查内容损失是否干扰时间监督 | +| D4 | 单样本 Gaussian KL,1,000 步;对照显式时间身份 | M4 保留 absolute PE | 检查真实特征加入时间码后能否形成局部带 | +| D5 | 按 `video_id` 分组 fold 1:80 条训练、20 条留出,纯 Gaussian KL,500 步 | 对照无时间码 / 有时间码 | 检查时间码能否迁移到未见原视频 | + +Gaussian target 是根据时间戳构造的弱时间先验,归一化时间上的 `sigma=0.10`;它**不是人工对齐真值**。D0/D1 是单样本过拟合诊断;D2/D3 在相同 100 条数据上训练并评价、每种方法仅一个随机种子,因此只反映优化情况,不表示泛化表现。每 20 步记录损失分量以及注意力 Q/K 投影和 M4 latent slots 的梯度。 + +| 诊断 | 结果 | +| --- | --- | +| D0 时间损失 | M3/M4 的最终 span loss 均为 0;band loss 分别为 `1.28e-5`、`7.10e-5`。损失对 Q/K 有梯度,M4 slots 也有非零梯度。 | +| D1 真实特征的逐模态 KL | M3:Audio `0.5254`,Vision `0.0001`;M4 无 PE:Text/Audio/Vision `0.000009/0.5496/0.000075`;M4 有 PE:`0.000026/0.5452/0.000065`。总体均值掩盖了 Audio 目标拟合失败,PE 几乎没有改善 Audio。 | +| D1-S 合成时间输入 | M3 Audio/Vision KL `0.000098/0.000103`、轨迹跨度 `0.836/0.840`;M4 无 PE 的三模态 KL 均约 `0.000025–0.000032`,有 PE 约 `0.000024–0.000035`。轨迹跨度约 `0.835–0.845`,中心时间误差约 `0.012–0.014`。 | +| D2 全量训练最终 KL | M3 `0.5194`;M4 `0.6222`。Q/K 梯度非零,M4 slots 梯度也非零。 | +| D3 最终损失 | M3:total `2.3617`、align KL `0.8575`、reconstruction `0.0652`、contrastive `1.4390`。M4:total `2.5226`、align KL `0.7414`、reconstruction `0.0345`、contrastive `1.7467`。Q/K 与 M4 slots 梯度非零。 | +| D4 单样本时间码 | Audio KL:M3 `0.5254 → 0.0012`,M4 `0.5452 → 0.0011`;Audio 轨迹跨度:M3 `0.426 → 0.803`,M4 `0.439 → 0.824`。两者 Vision KL 均低于 `0.00013`。 | +| D5 留出 20 条、6 个未见 video_id | M4 时间码版 Audio/Vision KL `0.0035/0.0135`、跨度 `0.814/0.822`、中心误差 `0.017/0.017`;无时间码版 KL `0.994/1.359`、跨度 `0.010/-0.077`。M3 时间码版有改善,但留出 KL 仍为 `0.491/0.479`、跨度 `0.716/0.712`、中心误差约 `0.09`。 | + +KL 的取平均模态数不同:M3 只对 Audio/Vision 计算 Gaussian target,M4 对 Text/Audio/Vision 都计算。因此 D1–D3 的 KL 数值用于看各自能否下降,不能直接作为 M3 对 M4 的胜负排名;D1 更应看逐模态值,而不是整体均值。 + +D1-S 使用实际 M3/M4 注意力层,但输入不含真实内容,只含合成时间坐标。它把 Gaussian 时间带拟合到约 `1e-4` KL,说明这套注意力计算和优化在输入携带时间位置时可以学出局部带状结构。结合 D1 真实特征上的 Audio 失败,问题更可能在真实 Audio 表示/时间线索与注意力目标的衔接,而非完全断开的 Q/K 梯度。代码检查也确认当前真实 M3/M4 注意力把投影后的源特征直接作为 key/value,没有显式把源时间戳编码进 key;这使“Audio key 缺少足够时间身份”成为优先验证的假设,但还不是已证实的唯一原因。 + +D4 为 source key 加固定 Fourier 时间码,value 保留投影后的真实特征;M3 query 同时加文本词时间中心码,M4 query 保留 absolute PE 并加对应网格时间码。真实单样本上两者都形成局部带。首次 D5 只跑了 fold 1:训练集 80 条、31 个 `video_id`,留出集 20 条、6 个 `video_id`,两侧无组重叠;归一化参数只用训练集拟合。该折支持 M4 的 Audio/Vision 时间带可迁移到未见视频;M3 优于无时间码基线,但仍有明显泛化差距。M4 Text 分支也仍弱,留出平均 Gaussian KL 为 `0.477`。后续新增的五折 D5 汇总见“Q1-Correspondence Evaluation”。D5 仍只有一个训练随机种子,Gaussian target 又来自源时间戳,因此这不是人工对齐准确率或多种子稳定性结论。 + +汇总 100 条样本的逐样本诊断,D2 的 M3 Audio 注意力仍较分散(归一化熵 `0.965`,平均轨迹跨度 `0.152`);Vision 更随时间变化(熵 `0.781`,跨度 `0.601`),但热图仍未清晰贴合目标。D2 的 M4 Audio 几乎均匀(熵 `0.997`,跨度 `0.011`),Vision 时间覆盖也有限(熵 `0.937`,跨度 `0.199`)。D3 加入重构和对比损失后,Audio 塌缩更明显:M3 熵/跨度为 `0.995/0.016`,M4 为 `0.999/0.002`;M4 Vision 跨度也从 D2 的 `0.199` 降至 `0.061`。因此重构误差降低不能单独视为对齐改善。 + +这组诊断排除了“注意力计算图完全断开或没有梯度”这一简单解释:D0 时间损失可优化,D1-S 可拟合合成时间带,全数据训练时 Q/K(以及 M4 slots)也有非零梯度。D4/D5 显示显式时间身份能解决 M4 Audio/Vision 的塌缩,但 M3 和 M4 Text 还未达到同样水平。后续优先检查 M3 文本查询时间身份和 M4 Text 分支,再考虑其他结构;暂不恢复大规模 RoPE 或 latent 长度扫参。可以先在其余 grouped folds 上复核 M4 音视频,再单独改进 M3/Text 时间条件化。 + +![D2 M3 学得的注意力与 Gaussian 时间目标](outputs/alignment_debug/D2/M3_heatmap.png) + +![D3 M4 学得的注意力与 Gaussian 时间目标](outputs/alignment_debug/D3/M4_sinPE_heatmap.png) + +![D1-S 合成时间输入下 M4 拟合 Gaussian 时间带](outputs/alignment_debug/synthetic/M4_sinPE/M4_sinPE_heatmap.png) + +![D5 留出样本中 M4 的 Audio/Vision 时间带](outputs/alignment_debug/heldout/M4_sourceTime/M4_sourceTime_heatmap.png) + +诊断产物见 [逐方法汇总指标](outputs/alignment_debug/metric_summary.csv)、[训练及梯度汇总](outputs/alignment_debug/debug_summary.csv)、[运行清单](outputs/alignment_debug/run_manifest.json)、[合成控制指标](outputs/alignment_debug/synthetic/metrics.csv)、[D4 时间码指标](outputs/alignment_debug/source_time/per_sample_metrics.csv)、[D5 留出汇总](outputs/alignment_debug/heldout/heldout_summary.csv) 和 [D5 运行清单](outputs/alignment_debug/heldout/run_manifest.json)。可分享的轻量结果包在 [report_bundle](outputs/alignment_debug/report_bundle/README.md);逐方法训练历史、指标、热图、轨迹及检查点保存在 `outputs/alignment_debug/`。 + +### Q1-Correspondence Evaluation:同槽与时间错位 + +为区分“注意力找到了时间”与“同一槽中的模态内容确实可匹配”,新增冻结特征上的对应性探针。M1、M2、M3、M4 共六个设置(M3/M4 各含有/无 source-time code)都使用同一套评估。每个方法的线性投影只在训练折上用同一片段内的同槽正样本和错槽负样本训练;再在完全留出的 `video_id` 上评价。投影维度为 64,训练 40 个 epoch,不使用情绪标签,也不按留出分数挑选模型。M3/M4 的 D5 时间定位模型在 5 个既有分组折上各训练 500 步、随机种子 42;每折 80 条训练片段和 20 条留出片段,100 条留出预测合计覆盖 37 个 `video_id`。 + +三项核心测量为: + +1. **时间偏移曲线**:计算 `sim(z_i^m, z_(i+Δ)^n)`,`Δ=-10…10`;若同槽内容关系具有迁移性,曲线应在零偏移附近出现峰。 +2. **片段内时序检索**:每个查询只能在同一留出片段的 50 个槽中检索,报告精确 R@1、±1 槽 R@1 和 MASE。 +3. **匹配/错位 AUC**:正样本为同槽配对,负样本来自同一片段且 `|i-j|>2` 的错槽配对。AUC `0.5` 表示无法区分。表中置信区间以 `video_id` 为单位做 2,000 次 bootstrap,避免把同视频片段或时间槽当成独立样本。 + +| 冻结表示 | T–A AUC(95% CI) | T–V AUC | A–V AUC | T→A 精确 R@1 | T→A ±1 R@1 | T→A MASE(槽) | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | +| M1 强制时间 | 0.524 [0.510, 0.538] | 0.499 | 0.499 | 0.028 | 0.075 | 16.35 | +| M2 固定窗口 | 0.531 [0.518, 0.545] | 0.499 | 0.503 | 0.029 | 0.078 | 15.95 | +| M3 无时间码 | **0.728 [0.706, 0.751]** | 0.531 | 0.512 | **0.135** | **0.275** | **9.94** | +| M3 有时间码 | 0.542 [0.527, 0.557] | 0.500 | 0.505 | 0.036 | 0.088 | 16.60 | +| M4 无时间码 | 0.621 [0.602, 0.641] | 0.560 | 0.541 | 0.046 | 0.114 | 11.21 | +| M4 有时间码 | 0.546 [0.517, 0.573] | 0.490 | 0.500 | 0.029 | 0.076 | 17.11 | + +50 槽下,随机检索参考值为精确 R@1 `0.020`、±1 R@1 `0.059`、MASE `16.66`。最清晰的偏移曲线峰出现在 **M3 无时间码的 T–A**:同槽相似度高于错开位置,T→A 检索也优于随机参考。M4 无时间码在三组配对上都有高于机会水平的 AUC,但效应较小;M1/M2 的 T–A 也有较弱的同槽信号。M3/M4 有时间码的结果没有显示同等强度的内容匹配,尤其 M4 有时间码的 T–V 与 A–V 接近机会水平。 + +这个结果必须和时间定位指标一起读。下表是五折 D5 验证片段按 `video_id` 宏平均的时间跨度;置信区间也按原视频分组。KL 越低越符合弱 Gaussian 时间目标。 + +| D5 变体 | Audio 跨度(95% CI) | Vision 跨度(95% CI) | Audio KL | Vision KL | +| --- | ---: | ---: | ---: | ---: | +| M3 无时间码 | 0.007 [-0.005, 0.018] | -0.052 [-0.092, -0.017] | 1.270 | 1.931 | +| M3 有时间码 | 0.708 [0.664, 0.738] | 0.710 [0.678, 0.737] | 0.618 | 0.592 | +| M4 无时间码 | 0.006 [0.001, 0.010] | -0.068 [-0.103, -0.033] | 1.013 | 1.550 | +| M4 有时间码 | 0.816 [0.815, 0.817] | 0.822 [0.819, 0.824] | 0.004 | 0.022 | + +M4 有时间码的 Audio/Vision 时间带清晰,但其 Text 分支 Gaussian KL 仍为 `0.608`,T–A/T–V/A–V 内容对应性也弱。反过来,M3 无时间码的 Audio/Vision 时间轴没有覆盖整段片段,却在 T–A 匹配探针上表现最好。M4 无时间码的 Audio/Vision 轨迹同样塌缩,但三组 AUC 均有一定高于机会水平的统计信号。也就是说,**时间定位与跨模态可匹配性确实是两件不同的事**:零偏移匹配不等于整段视频已经正确对齐;时间带漂亮也不保证槽内内容可匹配。 + +因此目前最稳妥的结论是:M3 无时间码的文本—音频表示具有可迁移的同槽可匹配性,但它没有形成完整时间覆盖;M4 有时间码建立了更好的 Audio/Vision 时间定位,却还没有证明三模态内容对应;M4 无时间码的内容探针结果值得跟进,但其时间轨迹塌缩,不能称为完整时序对齐。投影头本身使用了训练视频的同槽标签,所以这些结果是“冻结表示可被简单探针匹配”的证据,不是无监督模型独立发现的真值,也不证明模态间语义相同。还需要多随机种子和人工事件标注确认。 + +![同槽与错位的跨模态相似度曲线](outputs/correspondence_eval/shifted_similarity_curve.png) + +逐片段结果、视频组 bootstrap 汇总、偏移曲线数据、五折 D5 时间定位汇总、探针训练记录、探针检查点和运行清单分别保存在 [correspondence_clip_metrics.csv](outputs/correspondence_eval/correspondence_clip_metrics.csv)、[metric_summary.csv](outputs/correspondence_eval/metric_summary.csv)、[shift_curve_summary.csv](outputs/correspondence_eval/shift_curve_summary.csv)、[time_localization_summary.csv](outputs/correspondence_eval/time_localization_summary.csv)、[probe_training_history.csv](outputs/correspondence_eval/probe_training_history.csv)、[probe_checkpoints.pt](outputs/correspondence_eval/probe_checkpoints.pt) 和 [run_manifest.json](outputs/correspondence_eval/run_manifest.json)。 + +完整复现(Fedora WSL,Python 环境由 `uv` 管理): + +```bash +cd Q1 +uv run python -m q1.alignment_heldout_debug --device cuda --seed 42 --fold 1 --output-dir outputs/alignment_debug/heldout +uv run python -m q1.alignment_heldout_debug --device cuda --seed 42 --fold 2 --output-dir outputs/alignment_debug/heldout/fold_02 +uv run python -m q1.alignment_heldout_debug --device cuda --seed 42 --fold 3 --output-dir outputs/alignment_debug/heldout/fold_03 +uv run python -m q1.alignment_heldout_debug --device cuda --seed 42 --fold 4 --output-dir outputs/alignment_debug/heldout/fold_04 +uv run python -m q1.alignment_heldout_debug --device cuda --seed 42 --fold 5 --output-dir outputs/alignment_debug/heldout/fold_05 +uv run python -m q1.correspondence_eval --device cuda --epochs 40 --seed 42 +``` + +### M4 Shared Latent Timeline:结构与功能复核 + +M4 的判断不再以三张注意力图是否像对角线为依据,而分三层复核:先比较同一模态中 latent slots 的注意力相似度 (G^m=\hat A^m\hat A^{mT}),再由 (C^{m\to n}=\operatorname{ColNorm}(A^m)^T A^n) 生成模态到模态的转移图,最后用只看聚合内容的对应探针、内容打乱和错位重构检查这些关系是否有功能。此轮复用了五折 D5 `M4_sourceTime` 检查点,没有重新训练 M4 对齐模型。内容对应投影与小型重构器只在各折训练 video_id 上训练,再在留出组上打分;不使用情绪标签。全部 100 个片段各作为一次留出样本,分组覆盖 37 个 video_id。 + +结构指标按 video_id 做宏平均;95% 区间使用 2,000 次视频组 bootstrap。`near_similarity` 按定义包含自身对角线;`near_similarity_offdiag` 和 `d_self_offdiag` 排除自身,以免自相似度 1 掩盖邻近 slot 之间的结构。 + +| 模态 | 近邻相似(排除自身)↑ | 远邻相似 ↓ | (D_{self})(排除自身)↑ | Gram 目标误差 ↓ | 远槽泄漏 ↓ | +| --- | ---: | ---: | ---: | ---: | ---: | +| Text | 0.985 | 0.122 | 0.863 | 0.733 | 0.192 | +| Audio | 0.983 | 0.069 | 0.914 | 0.544 | 0.126 | +| Vision | 0.983 | 0.073 | 0.910 | 0.543 | 0.133 | + +三种模态的 Gram 矩阵都有清晰的局部带:相邻 slots 会看相似区域,远距离 slots 的相似度明显更低。这说明 latent timeline 在各模态内部形成了平滑的时间结构;Text 的远槽相似和 Gram 目标误差仍高于 Audio/Vision。 + +| Pairwise 方向 | 物理时间 MAE ↓ | 时间相关 ↑ | +| --- | ---: | ---: | +| Text → Audio | 0.0841 | 0.928 | +| Text → Vision | 0.0843 | 0.928 | +| Audio → Vision | 0.0248 | 0.996 | + +时间 MAE 使用归一化片段时间,描述由 pairwise map 得到的期望时间是否接近;它不是语义或事件级对齐准确率。完整六个方向见 [pairwise_summary.csv](outputs/m4_shared_latent_eval/pairwise_summary.csv)。回环到 band target 的相对误差分别为 Text–Audio–Text `0.865`、Text–Vision–Text `0.864`、Audio–Vision–Audio `0.719`;对应回环时间 MAE 为 `0.096`、`0.099`、`0.050`。Triangle (T\to A\to V) 与 (T\to V) 的相对 Frobenius 残差为 `0.226`。所以时间轨迹较一致,但 cycle 回环还没有恢复到期望的局部时间带,pairwise 结构尚未完全自洽。 + +功能验证的结果进一步收紧了结论。Content-only probe 输入仅为 M4 的注意力加权 Value 表示;不把 latent query、位置向量或 slot 编号拼入 probe。需要注意,source-time code 仍会影响注意力权重 (A^m),所以时间信息可能通过“选中了哪些 Value”间接保留;内容 shuffle 用来检验槽内内容顺序是否贡献了可匹配信号。探针使用训练折的同槽正例训练,留出时的负例是同片段中相隔超过 2 槽的位置。 + +| 配对 | 匹配/错位 AUC(95% CI) | 左到右精确 R@1 | ±1 槽 R@1 | MASE(槽) | +| --- | ---: | ---: | ---: | ---: | +| Text → Audio | **0.616 [0.583, 0.650]** | 0.037 | 0.108 | 13.64 | +| Text → Vision | 0.504 [0.494, 0.514] | 0.025 | 0.069 | 17.83 | +| Audio → Vision | 0.513 [0.500, 0.530] | 0.024 | 0.062 | 17.66 | + +50 槽随机检索的参考值为精确 R@1 `0.020`、±1 R@1 `0.059`、MASE `16.66`。Text–Audio 的同槽相似曲线在零偏移处达到峰值,AUC 也高于机会水平;打乱槽内内容后 AUC 从 `0.616` 降至 `0.500`,说明这项有限信号依赖实际内容顺序。Text–Vision 与 Audio–Vision 的 AUC 均接近 `0.5`,打乱前后没有实质差别。因此内容层证据只支持较弱的 Text–Audio 对应,没有支持完整三模态内容对齐。 + +Aligned-vs-shifted reconstruction 的目标是另一个模态的 M4 聚合内容向量,而不是原始波形或视频像素;每次只将一个输入伙伴错开,且比较相同目标槽。下表为绝对位移 10 槽时 `MAE_shifted - MAE_aligned` 的估计和视频组 95% 区间: + +| 重构目标 | 增益 (G(10))(95% CI) | +| --- | ---: | +| Audio | 0.000049 [-0.000150, 0.000260] | +| Vision | 0.000176 [-0.000229, 0.000624] | +| Text | 0.000675 [-0.000249, 0.001793] | + +三个区间都包含 0;在 `|Δ|=1,2,5` 时同样没有排除 0。错位越远时 Text/Vision 目标的增益均值略有上升,但这项探针尚未给出稳定的正向重构证据。 + +![M4 的原始共享槽到三模态注意力](outputs/m4_shared_latent_eval/latent_attention_heatmaps.png) + +![M4 各模态 latent-slot Gram 自结构](outputs/m4_shared_latent_eval/self_gram_heatmaps.png) + +![经 shared latent 诱导的三组 pairwise map](outputs/m4_shared_latent_eval/pairwise_heatmaps.png) + +![M4 cycle 与 triangle 结构检查](outputs/m4_shared_latent_eval/cycle_triangle_maps.png) + +![Content-only 同槽与错位相似度曲线](outputs/m4_shared_latent_eval/content_only_shifted_similarity.png) + +![Content shuffle control](outputs/m4_shared_latent_eval/content_shuffle_control.png) + +![错位重构增益](outputs/m4_shared_latent_eval/shifted_reconstruction_gain.png) + +**当前结论:** M4 有明显的 latent 自身时间结构,且 Audio–Vision pair map 在物理时间上接近一致;这与 D5 的 source-time 先验结果相符。可是 cycle band 误差仍大,内容对应主要只在 Text–Audio 上表现为中等信号,Text–Vision/Audio–Vision 接近机会水平,错位重构增益的区间包含 0。由此不能写成“M4 已学到可信的三模态共享语义对齐”。更稳妥的表述是:它建立了时间定位和部分 Text–Audio 内容可匹配性,但现有结果尚未证明完整、可靠的三模态跨模态对应。source-time D5 检查点只用一个对齐训练种子,而且训练中的 Gaussian 时间目标来自时间戳;本轮 bootstrap 只描述视频组采样不确定性,不覆盖训练种子不确定性。人工事件 IoU/中心误差仍需先标注 10–15 条视频的事件区间。 + +逐片段数据、汇总、探针训练记录和权重,以及可直接复查的典型样本矩阵保存在 [outputs/m4_shared_latent_eval](outputs/m4_shared_latent_eval/)。关键文件包括 [self_structure_summary.csv](outputs/m4_shared_latent_eval/self_structure_summary.csv)、[pairwise_summary.csv](outputs/m4_shared_latent_eval/pairwise_summary.csv)、[cycle_triangle_summary.csv](outputs/m4_shared_latent_eval/cycle_triangle_summary.csv)、[content_only_metrics_summary.csv](outputs/m4_shared_latent_eval/content_only_metrics_summary.csv)、[content_shuffle_summary.csv](outputs/m4_shared_latent_eval/content_shuffle_summary.csv)、[shifted_reconstruction_summary.csv](outputs/m4_shared_latent_eval/shifted_reconstruction_summary.csv) 和 [run_manifest.json](outputs/m4_shared_latent_eval/run_manifest.json)。 + +Fedora WSL 复现(复用已有五折 D5 检查点): + +```bash +cd Q1 +uv run python -m q1.m4_shared_latent_eval --device cuda --seed 42 --probe-epochs 40 --decoder-epochs 40 --shuffle-repeats 20 +``` + +### TSFA:冻结时间候选范围与局部内容选择 + +在上述 D5/M4 结果之上,本轮验证“先用时间确定候选范围,再在范围内按内容选择”能否同时改善时间定位和跨模态内容对应。五折 `M4_sourceTime` 检查点保持冻结;每个共享槽的 M4 注意力期望时间作为候选中心,主方案在归一化时间 `±0.10` 的范围内,用文本内容查询音频和视觉内容。局部语义分支只用训练折的同槽正例和相隔 `±2、±3、±5` 槽的难负例训练 40 个 epoch。它的 Q/K 不显式接收源时间码、位置编码或槽编号;M4 选中的内容仍可能间接携带时间。情绪标签没有进入训练。原有 BERT 文本、eGeMAPS 音频和 DeiT 视觉特征均保持不变。 + +比较包括 M3 无/有时间码、冻结 M4、有时间候选的 TSFA 主方案、乘以 M4 时间注意力的变体、20 次同宽度随机候选窗口,以及允许搜索全部源位置的全局变体。全部方法复用相同的 5 个 `video_id` 分组折、训练折归一化、每折相同的评估探针随机种子。100 条样本各作一次留出预测,涉及 37 个原视频。表中 AUC 是 Text–Audio、Text–Vision、Audio–Vision 三组“同槽对错槽”AUC 的逐样本平均,再按 `video_id` 宏平均;`0.5` 为机会水平。时间 MAE 是三个正向跨模态映射在归一化视频时间上的平均,越低越好。 + +| 方法 | 模型输出 AUC ↑ | 统一原始特征 AUC ↑ | 时间 MAE ↓ | +| --- | ---: | ---: | ---: | +| M3 无时间码 | 0.708 | 0.592 | 0.251 | +| M3 有时间码 | 0.565 | 0.516 | 0.099 | +| M4 有时间码 | 0.544 | 0.517 | **0.064** | +| TSFA 主方案 | 0.627 | 0.553 | 0.070 | +| TSFA 乘时间权重 | 0.627 | 0.551 | 0.068 | +| TSFA 随机窗口 | 0.632 | 0.571 | 0.251 | +| TSFA 全局候选 | **0.685** | **0.608** | 0.243 | + +时间轴诊断进一步说明候选范围的作用。MVR 使用相邻槽期望时间倒退超过 `0.02` 的比例;跨度是末槽减首槽的归一化时间。熵只作分布诊断,不能单独排名。 + +| 方法 | Audio MVR ↓ | Vision MVR ↓ | Audio 跨度 ↑ | Vision 跨度 ↑ | Audio 熵 | Vision 熵 | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | +| M4 有时间码 | 0.0000 | 0.0000 | 0.816 | 0.822 | 0.846 | 0.720 | +| TSFA 主方案 | 0.0025 | 0.0004 | 0.796 | 0.821 | 0.538 | 0.510 | +| TSFA 随机窗口 | 0.4650 | 0.4745 | -0.017 | 0.010 | 0.533 | 0.500 | +| TSFA 全局候选 | 0.1406 | 0.0645 | 0.011 | 0.008 | 0.701 | 0.902 | + +主方案的注意力更集中,且仍覆盖约 `99.9%` 的有效源位置;因此时间 MAE 的对照没有靠删除大批难对齐源位置取得优势。随机窗口同样能给出较低的熵,却有严重倒序和近零跨度,再次说明熵低不等于对齐正确。 + +“模型输出”沿用各方法自己的 Value/输出投影;“统一原始特征”把同一折中归一化后的 BERT、音频和 DeiT 源特征分别乘以各方法的对齐矩阵,再训练相同的线性对应探针。后者隔离了“选中哪些源位置”的贡献,更适合判断对齐矩阵本身。两者都只用训练视频拟合探针,留出视频打分。M3 无时间码的模型输出 Text–Audio AUC 达 `0.956`,统一原始特征后为 `0.725`;这说明原生注意力输出的查询相关变换也对它的高分有贡献,不能把原生输出 AUC 全部解释为正确的时间选择。 + +成对比较同一留出样本,并按 `video_id` 做 2,000 次 bootstrap:TSFA 主方案相对 M4 的统一原始特征 AUC 增加 `0.035`,95% 区间 `[0.023, 0.047]`;时间 MAE 增加 `0.0059`,区间 `[0.0053, 0.0065]`,即时间精度略有下降。它的统一原始特征 Text–Audio AUC 为 `0.639`,M4 为 `0.539`;Text–Vision `0.507`、Audio–Vision `0.511` 仍接近机会水平。原生输出的 Text–Audio AUC 为 `0.844`,M4 为 `0.616`;独立打乱留出片段内各模态槽顺序后,TSFA Text–Audio AUC 降至 `0.500`,说明该探针确实依赖槽顺序。 + +随机窗口相对主方案的统一原始特征 AUC 高 `0.018`,全局候选高 `0.055`;同时二者的时间 MAE 分别升至 `0.251` 和 `0.243`。随机窗口使用相同 `δ`,但边界截断使 Audio 平均候选比例为 `19.3%`,主方案为 `20.3%`;这一对照并未做到逐槽候选数量完全相等。因此局部 M4 候选范围的作用主要是**约束时间位置**,现有实验没有证明它能提高内容 AUC。乘时间权重比硬候选主方案把时间 MAE 从 `0.070` 降至 `0.068`,但统一原始特征 AUC 从 `0.553` 降至 `0.551`。这是一条可描述的时间—内容权衡,不宜合成为一个总分。 + +错位重构也只给出有限支持:错开 10 槽时,TSFA 的 Vision 内容重构误差增加 `0.00148`,95% 区间 `[0.00050, 0.00240]`;Audio 和 Text 目标的对应区间都包含 0。重构对象是聚合特征,不是波形或像素。当前最稳妥的判断是:**TSFA 比冻结 M4 保留了更多可匹配的 Text–Audio 内容,且维持了大部分时间结构;它尚未证明可靠的三模态语义对齐。**训练折的同槽标签来自时间/槽约定,M4 的时间先验来自时间戳,均不是人工事件真值;直接的事件 IoU/MATE 仍需人工标注。此轮只有一个对齐训练种子,视频组区间不包含训练种子波动。基于这轮七方法结果,暂不把 `δ`、RoPE 或 latent 长度消融写成已完成实验。 + +![M4 时间先验与 TSFA 局部语义选择](outputs/tsfa/temporal_semantic_attention.png) + +![时间质量与内容对应的权衡](outputs/tsfa/temporal_content_tradeoff.png) + +完整的逐片段指标、训练记录和探针检查点位于 [outputs/tsfa](outputs/tsfa/);可分享的汇总与图在 [report_bundle](outputs/tsfa/report_bundle/)。重点文件为 [七方法主表](outputs/tsfa/ablation_summary.csv)、[统一原始特征主表](outputs/tsfa/alignment_only_ablation_summary.csv)、[统一特征成对差值](outputs/tsfa/alignment_only_paired_contrasts.csv)、[三组配对和双向检索](outputs/tsfa/alignment_only_content_summary.csv)、[MVR/熵/覆盖率汇总](outputs/tsfa/tsfa_temporal_diagnostics_summary.csv)、[随机窗口统计](outputs/tsfa/candidate_window_stats.csv)、[运行清单](outputs/tsfa/run_manifest.json) 与 [统一特征运行清单](outputs/tsfa/alignment_only_run_manifest.json)。 + +Fedora WSL 复现(在 `deep_learning/Q1` 中执行,Python 环境由 `uv` 管理): + +```bash +uv run python -m q1.tsfa_experiment --device cuda --seed 42 +uv run python -m q1.tsfa_alignment_only_eval --device cuda --seed 42 +``` diff --git a/deep_learning/Q1/models/face_landmarker.task b/deep_learning/Q1/models/face_landmarker.task new file mode 100644 index 0000000..c50c845 Binary files /dev/null and b/deep_learning/Q1/models/face_landmarker.task differ diff --git a/deep_learning/Q1/pyproject.toml b/deep_learning/Q1/pyproject.toml new file mode 100644 index 0000000..a4959db --- /dev/null +++ b/deep_learning/Q1/pyproject.toml @@ -0,0 +1,26 @@ +[project] +name = "q1" +version = "0.1.0" +requires-python = ">=3.14" +dependencies = [ + "matplotlib>=3.11.2", + "mediapipe>=1.0.1", + "numpy>=2.5.2", + "opencv-python-headless>=5.0.0.93", + "openpyxl>=3.1.5", + "opensmile>=2.6.0", + "pillow>=12.3.0", + "scikit-learn>=1.9.1", + "soundfile>=0.14.0", + "torch>=2.14.0", + "torchvision>=0.29.0", + "transformers>=5.17.0", +] + +[tool.uv.sources] +torch = { index = "pytorch" } + +[[tool.uv.index]] +name = "pytorch" +url = "https://download.pytorch.org/whl/cu130" +explicit = true diff --git a/deep_learning/Q1/q1/__init__.py b/deep_learning/Q1/q1/__init__.py new file mode 100644 index 0000000..f0d37fb --- /dev/null +++ b/deep_learning/Q1/q1/__init__.py @@ -0,0 +1,14 @@ +"""Core data structures and alignment methods for Q1.""" + +from .alignment import align_fixed_windows, align_forced_timestamps +from .models import SharedLatentTimeline, TextAnchoredCrossAttention +from .types import AlignmentOutput, SequenceBatch + +__all__ = [ + "AlignmentOutput", + "SequenceBatch", + "SharedLatentTimeline", + "TextAnchoredCrossAttention", + "align_fixed_windows", + "align_forced_timestamps", +] diff --git a/deep_learning/Q1/q1/__pycache__/__init__.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..385edf6 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/__init__.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/alignment.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/alignment.cpython-314.pyc new file mode 100644 index 0000000..bc74fdf Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/alignment.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/alignment_debug.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/alignment_debug.cpython-314.pyc new file mode 100644 index 0000000..c026a34 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/alignment_debug.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/alignment_heldout_debug.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/alignment_heldout_debug.cpython-314.pyc new file mode 100644 index 0000000..6ac0290 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/alignment_heldout_debug.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/alignment_key_position_debug.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/alignment_key_position_debug.cpython-314.pyc new file mode 100644 index 0000000..fdd097f Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/alignment_key_position_debug.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/audit.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/audit.cpython-314.pyc new file mode 100644 index 0000000..c81acfc Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/audit.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/compare_methods.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/compare_methods.cpython-314.pyc new file mode 100644 index 0000000..49af590 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/compare_methods.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/correspondence_eval.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/correspondence_eval.cpython-314.pyc new file mode 100644 index 0000000..0a92f4c Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/correspondence_eval.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/experiment_data.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/experiment_data.cpython-314.pyc new file mode 100644 index 0000000..c4e8016 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/experiment_data.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/experiment_probes.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/experiment_probes.cpython-314.pyc new file mode 100644 index 0000000..33fc33b Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/experiment_probes.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/extract_features.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/extract_features.cpython-314.pyc new file mode 100644 index 0000000..2859d5e Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/extract_features.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/losses.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/losses.cpython-314.pyc new file mode 100644 index 0000000..a6e25ff Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/losses.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/m4_shared_latent_eval.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/m4_shared_latent_eval.cpython-314.pyc new file mode 100644 index 0000000..4407c5f Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/m4_shared_latent_eval.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/metrics.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/metrics.cpython-314.pyc new file mode 100644 index 0000000..44b6c66 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/metrics.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/models.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/models.cpython-314.pyc new file mode 100644 index 0000000..2b8e5e3 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/models.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/summarize_alignment_debug.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/summarize_alignment_debug.cpython-314.pyc new file mode 100644 index 0000000..3f35def Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/summarize_alignment_debug.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/synthetic_alignment_sanity.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/synthetic_alignment_sanity.cpython-314.pyc new file mode 100644 index 0000000..501006b Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/synthetic_alignment_sanity.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/train_alignment_variants.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/train_alignment_variants.cpython-314.pyc new file mode 100644 index 0000000..b0f6361 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/train_alignment_variants.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/tsfa_alignment_only_eval.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/tsfa_alignment_only_eval.cpython-314.pyc new file mode 100644 index 0000000..dd4cb03 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/tsfa_alignment_only_eval.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/tsfa_experiment.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/tsfa_experiment.cpython-314.pyc new file mode 100644 index 0000000..c90f9d9 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/tsfa_experiment.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/__pycache__/types.cpython-314.pyc b/deep_learning/Q1/q1/__pycache__/types.cpython-314.pyc new file mode 100644 index 0000000..ad7e457 Binary files /dev/null and b/deep_learning/Q1/q1/__pycache__/types.cpython-314.pyc differ diff --git a/deep_learning/Q1/q1/alignment.py b/deep_learning/Q1/q1/alignment.py new file mode 100644 index 0000000..b0268b3 --- /dev/null +++ b/deep_learning/Q1/q1/alignment.py @@ -0,0 +1,188 @@ +from __future__ import annotations + +from collections.abc import Sequence + +import torch +from torch import Tensor + +from .types import AlignmentOutput, MODALITIES, SequenceBatch + + +def uniform_time_intervals(durations: Tensor, grid_size: int) -> Tensor: + """Return ``[B, K, 2]`` equal-duration windows in seconds.""" + if durations.ndim != 1 or grid_size < 1: + raise ValueError("durations must be [B] and grid_size must be positive") + if bool((durations <= 0).any()) or not bool(torch.isfinite(durations).all()): + raise ValueError("durations must be finite and positive") + edges = torch.linspace( + 0.0, 1.0, grid_size + 1, device=durations.device, dtype=durations.dtype + )[None, :] * durations[:, None] + return torch.stack((edges[:, :-1], edges[:, 1:]), dim=-1) + + +def word_intervals_to_grid(word_intervals: Tensor, grid_size: int) -> Tensor: + """Resample ordered word spans into K consecutive text-order intervals. + + Each grid slot covers an equal share of transcript word order. Its time + boundaries are interpolated from forced-alignment word boundaries, so long + and short words retain their actual duration on the audio/video timeline. + """ + if word_intervals.ndim != 2 or word_intervals.shape[1] != 2: + raise ValueError("word_intervals must have shape [word_count, 2]") + if word_intervals.shape[0] == 0 or grid_size < 1: + raise ValueError("at least one word interval and a positive grid size are required") + intervals = word_intervals.to(dtype=torch.float32) + if not bool(torch.isfinite(intervals).all()): + raise ValueError("word intervals must be finite") + if bool((intervals[:, 1] < intervals[:, 0]).any()): + raise ValueError("word interval end must not precede its start") + if bool((intervals[1:, 0] < intervals[:-1, 0]).any()): + raise ValueError("word intervals must be ordered by start time") + + word_count = intervals.shape[0] + if word_count == 1: + boundaries = torch.cat((intervals[:1, 0], intervals[:1, 1])) + else: + between = (intervals[:-1, 1] + intervals[1:, 0]) / 2 + boundaries = torch.cat((intervals[:1, 0], between, intervals[-1:, 1])) + boundaries = torch.cummax(boundaries, dim=0).values + + positions = torch.linspace( + 0, word_count, grid_size + 1, device=intervals.device, dtype=intervals.dtype + ) + left = positions.floor().long().clamp(max=word_count) + right = (left + 1).clamp(max=word_count) + fraction = (positions - left.to(positions.dtype)).unsqueeze(-1) + time_edges = boundaries[left] + fraction.squeeze(-1) * (boundaries[right] - boundaries[left]) + return torch.stack((time_edges[:-1], time_edges[1:]), dim=-1) + + +def index_alignment(valid: Tensor, grid_size: int) -> tuple[Tensor, int]: + """Map equal ranges of valid sequence order to K grid slots.""" + if valid.ndim != 2 or valid.dtype != torch.bool: + raise ValueError("valid must be a boolean [B, L] tensor") + if grid_size < 1: + raise ValueError("grid_size must be positive") + batch_size, length = valid.shape + result = torch.zeros(batch_size, grid_size, length, device=valid.device, dtype=torch.float32) + fallback_count = 0 + for batch_index in range(batch_size): + positions = torch.nonzero(valid[batch_index], as_tuple=False).flatten() + count = positions.numel() + if count == 0: + raise ValueError("each sample must contain a valid position") + for grid_index in range(grid_size): + start = (grid_index * count) // grid_size + end = ((grid_index + 1) * count) // grid_size + if start == end: + source_index = min(int((grid_index + 0.5) * count / grid_size), count - 1) + result[batch_index, grid_index, positions[source_index]] = 1.0 + fallback_count += 1 + else: + chosen = positions[start:end] + result[batch_index, grid_index, chosen] = 1.0 / chosen.numel() + return result, fallback_count + + +def interval_alignment(times: Tensor, valid: Tensor, intervals: Tensor) -> tuple[Tensor, int]: + """Create row-normalized interval membership weights with nearest-time fallback.""" + if times.ndim != 2 or valid.shape != times.shape or valid.dtype != torch.bool: + raise ValueError("times and valid must have matching [B, L] shapes") + if intervals.ndim != 3 or intervals.shape[0] != times.shape[0] or intervals.shape[2] != 2: + raise ValueError("intervals must have shape [B, K, 2]") + batch_size, length = times.shape + grid_size = intervals.shape[1] + result = torch.zeros(batch_size, grid_size, length, device=times.device, dtype=torch.float32) + fallback_count = 0 + for batch_index in range(batch_size): + valid_positions = torch.nonzero(valid[batch_index], as_tuple=False).flatten() + valid_times = times[batch_index, valid_positions] + for grid_index in range(grid_size): + start, end = intervals[batch_index, grid_index] + is_last = grid_index == grid_size - 1 + in_window = (valid_times >= start) & ( + (valid_times <= end) if is_last else (valid_times < end) + ) + chosen = valid_positions[in_window] + if chosen.numel() > 0: + result[batch_index, grid_index, chosen] = 1.0 / chosen.numel() + else: + center = (start + end) / 2 + nearest = valid_positions[torch.argmin((valid_times - center).abs())] + result[batch_index, grid_index, nearest] = 1.0 + fallback_count += 1 + return result, fallback_count + + +def _output_from_weights( + sequences: dict[str, SequenceBatch], + weights: dict[str, Tensor], + fallbacks: dict[str, int], +) -> AlignmentOutput: + aligned = {name: torch.bmm(weights[name].to(sequences[name].features.dtype), sequences[name].features) + for name in MODALITIES} + output = AlignmentOutput(weights=weights, aligned=aligned, fallback_rows=fallbacks) + output.validate({name: sequences[name].valid for name in MODALITIES}) + return output + + +def align_fixed_windows( + sequences: dict[str, SequenceBatch], durations: Tensor, grid_size: int = 50 +) -> AlignmentOutput: + """M2: average each modality inside the same K equal-duration windows.""" + intervals = uniform_time_intervals(durations, grid_size) + weights: dict[str, Tensor] = {} + fallbacks: dict[str, int] = {} + for name in MODALITIES: + weights[name], fallbacks[name] = interval_alignment( + sequences[name].times, sequences[name].valid, intervals + ) + return _output_from_weights(sequences, weights, fallbacks) + + +def align_forced_timestamps( + sequences: dict[str, SequenceBatch], + word_intervals: Sequence[Tensor], + grid_size: int = 50, +) -> AlignmentOutput: + """M1: use forced word timestamps to define text-ordered grid intervals.""" + batch_size = sequences["text"].features.shape[0] + if len(word_intervals) != batch_size: + raise ValueError("provide one ordered word-interval array per sample") + device = sequences["text"].features.device + intervals = torch.stack( + [word_intervals_to_grid(spans.to(device), grid_size) for spans in word_intervals], dim=0 + ) + weights: dict[str, Tensor] = {} + fallbacks: dict[str, int] = {} + for name in MODALITIES: + weights[name], fallbacks[name] = interval_alignment( + sequences[name].times, sequences[name].valid, intervals + ) + return _output_from_weights(sequences, weights, fallbacks) + + +def make_block_mask( + batch_size: int, + grid_size: int, + ratio: float, + device: torch.device | str, + generator: torch.Generator | None = None, +) -> Tensor: + """Sample one continuous masked interval per sequence on the common grid.""" + if not 0 < ratio < 1: + raise ValueError("ratio must be between zero and one") + if batch_size < 1 or grid_size < 2: + raise ValueError("batch_size must be positive and grid_size at least two") + block_length = min(max(1, round(grid_size * ratio)), grid_size - 1) + mask = torch.zeros(batch_size, grid_size, dtype=torch.bool, device=device) + starts = torch.randint( + 0, + grid_size - block_length + 1, + (batch_size,), + device=device, + generator=generator, + ) + offsets = torch.arange(block_length, device=device) + mask[torch.arange(batch_size, device=device)[:, None], starts[:, None] + offsets] = True + return mask diff --git a/deep_learning/Q1/q1/alignment_debug.py b/deep_learning/Q1/q1/alignment_debug.py new file mode 100644 index 0000000..b8a351c --- /dev/null +++ b/deep_learning/Q1/q1/alignment_debug.py @@ -0,0 +1,776 @@ +from __future__ import annotations + +import argparse +import csv +import json +import math +import platform +import random +import time +from collections import defaultdict +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Mapping, Sequence + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import torch +import torch.nn.functional as F +from torch import Tensor, nn + +from .alignment import make_block_mask +from .compare_methods import AlignmentReconstructor, _write_csv +from .experiment_data import ( + FeatureSample, + FeatureStats, + collate_feature_samples, + fit_feature_stats, + load_feature_samples, +) +from .losses import ( + cross_modal_contrastive_loss, + temporal_span_loss, + weak_temporal_band_loss, +) +from .metrics import ( + alignment_trajectory, + attention_row_similarity, + normalized_attention_entropy, + monotonicity_violation_rate, +) +from .models import SharedLatentTimeline, TextAnchoredCrossAttention +from .types import MODALITIES + + +EXAMPLE_ID = "-tPCytz4rww/12" +SIGMA = 0.10 +GRID_SIZE = 50 +HIDDEN_SIZE = 128 +HEADS = 4 +SINGLE_SAMPLE_STEPS = 1000 +FULL_DATA_STEPS = 500 +BATCH_SIZE = 8 +LEARNING_RATE = 1e-3 +LOG_INTERVAL = 20 + + +def _seed_everything(seed: int) -> None: + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + if torch.cuda.is_available(): + torch.cuda.manual_seed_all(seed) + torch.backends.cudnn.deterministic = True + torch.backends.cudnn.benchmark = False + + +def _model( + method: str, + dimensions: Mapping[str, int], + *, + absolute_position_encoding: bool = False, +) -> nn.Module: + if method == "M3": + return TextAnchoredCrossAttention( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + ) + if method == "M4": + return SharedLatentTimeline( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + absolute_position_encoding=absolute_position_encoding, + ) + raise ValueError(f"unknown method: {method}") + + +def _centers( + method: str, + output: Any, + sequences: Mapping[str, Any], + durations: Tensor, +) -> tuple[dict[str, Tensor], Tensor]: + batch_size = durations.shape[0] + if method == "M3": + text_centers = torch.bmm( + output.weights["text"], sequences["text"].times.unsqueeze(-1) + ).squeeze(-1) + text_centers = text_centers / durations[:, None].clamp_min(1e-8) + return {"audio": text_centers, "vision": text_centers}, text_centers + centers = ( + torch.arange(GRID_SIZE, dtype=durations.dtype, device=durations.device) + 0.5 + ) / GRID_SIZE + centers = centers.unsqueeze(0).expand(batch_size, -1) + return {name: centers for name in MODALITIES}, centers + + +def _gaussian_targets( + method: str, + output: Any, + sequences: Mapping[str, Any], + durations: Tensor, +) -> dict[str, Tensor]: + centers, _ = _centers(method, output, sequences, durations) + target_names = ("audio", "vision") if method == "M3" else MODALITIES + targets: dict[str, Tensor] = {} + for name in target_names: + times = sequences[name].times / durations[:, None].clamp_min(1e-8) + difference = (times[:, None, :] - centers[name][:, :, None]) / SIGMA + logits = -0.5 * difference.square() + logits = logits.masked_fill(~sequences[name].valid[:, None, :], -torch.inf) + targets[name] = torch.softmax(logits, dim=-1) + return targets + + +def _gaussian_alignment_kl(output: Any, targets: Mapping[str, Tensor]) -> Tensor: + losses = [] + for name, target in targets.items(): + predicted = output.weights[name].clamp_min(1e-8) + safe_target = target.clamp_min(1e-12) + row_kl = (safe_target * (safe_target.log() - predicted.log())).sum(dim=-1) + losses.append(row_kl.mean()) + return torch.stack(losses).mean() + + +def _training_components( + experiment: str, + method: str, + output: Any, + sequences: Mapping[str, Any], + durations: Tensor, + *, + decoder: AlignmentReconstructor | None, + block_generator: torch.Generator, +) -> tuple[Tensor, dict[str, Tensor], tuple[str, ...]]: + centers, _ = _centers(method, output, sequences, durations) + coverage_modalities = ("audio", "vision") if method == "M3" else MODALITIES + span = temporal_span_loss( + output, + {name: sequences[name].times for name in MODALITIES}, + durations, + minimum_span=0.7, + modalities=coverage_modalities, + ) + band = weak_temporal_band_loss( + output, + {name: sequences[name].times for name in MODALITIES}, + durations, + centers, + margin=0.1, + ) + targets = _gaussian_targets(method, output, sequences, durations) + align = _gaussian_alignment_kl(output, targets) + reconstruction = align.new_zeros(()) + contrastive = align.new_zeros(()) + + if experiment == "D0": + total = 5.0 * span + 10.0 * band + active = ("span", "band", "total") + elif experiment in {"D1", "D2"}: + total = align + active = ("align", "total") + elif experiment == "D3": + if decoder is None: + raise ValueError("D3 requires the reconstruction decoder") + target_losses = [] + batch_size, grid_size = output.aligned["text"].shape[:2] + for target in MODALITIES: + mask = make_block_mask( + batch_size, + grid_size, + 0.2, + output.aligned[target].device, + generator=block_generator, + ) + prediction = decoder(target, output.aligned, mask) + target_losses.append( + F.smooth_l1_loss(prediction[mask], output.aligned[target][mask]) + ) + reconstruction = torch.stack(target_losses).mean() + contrastive = cross_modal_contrastive_loss(output.aligned) + total = align + reconstruction + contrastive + active = ("align", "reconstruction", "contrastive", "total") + else: + raise ValueError(f"unknown experiment: {experiment}") + + return total, { + "reconstruction": reconstruction, + "contrastive": contrastive, + "span": span, + "band": band, + "align": align, + "total": total, + }, active + + +def _attention_projection_parameters(model: nn.Module, method: str) -> tuple[list[nn.Parameter], nn.Parameter | None]: + if method == "M3": + layers = (model.audio_attention.attention, model.vision_attention.attention) + slot_parameter = None + else: + layers = tuple(model.attention[name].attention for name in MODALITIES) + slot_parameter = model.slots + parameters = [layer.in_proj_weight for layer in layers] + return parameters, slot_parameter + + +def _gradient_norms( + model: nn.Module, + method: str, + component_losses: Mapping[str, Tensor], + active_components: Sequence[str], +) -> dict[str, float | None]: + qk_parameters, slot_parameter = _attention_projection_parameters(model, method) + parameters = [*qk_parameters] + if slot_parameter is not None: + parameters.append(slot_parameter) + hidden_size = HIDDEN_SIZE + values: dict[str, float | None] = {} + for component in active_components: + loss = component_losses[component] + gradients = torch.autograd.grad( + loss, + parameters, + retain_graph=True, + allow_unused=True, + ) + q_sq = torch.zeros((), device=loss.device) + k_sq = torch.zeros((), device=loss.device) + for gradient in gradients[: len(qk_parameters)]: + if gradient is None: + continue + q_sq = q_sq + gradient[:hidden_size].square().sum() + k_sq = k_sq + gradient[hidden_size : 2 * hidden_size].square().sum() + values[f"grad_{component}_WQ"] = float(q_sq.sqrt().item()) + values[f"grad_{component}_WK"] = float(k_sq.sqrt().item()) + if slot_parameter is not None: + slot_gradient = gradients[-1] + values[f"grad_{component}_Z"] = ( + float(slot_gradient.norm().item()) if slot_gradient is not None else 0.0 + ) + else: + values[f"grad_{component}_Z"] = None + return values + + +def _metric_rows( + method: str, + experiment: str, + sample: FeatureSample, + output: Any, + sequences: Mapping[str, Any], + durations: Tensor, + *, + stats: FeatureStats, + device: torch.device, +) -> list[dict[str, Any]]: + targets = _gaussian_targets(method, output, sequences, durations) + rows = [] + for name in MODALITIES: + weights = output.weights[name] + valid = sequences[name].valid + trajectory = alignment_trajectory(weights, sequences[name].times, durations) + entropy = normalized_attention_entropy(weights, valid) + centers, _ = _centers(method, output, sequences, durations) + row: dict[str, Any] = { + "experiment": experiment, + "method": method, + "sample_id": sample.sample_id, + "modality": name, + "mvr": float(monotonicity_violation_rate(trajectory).mean().item()), + "normalized_entropy": float(entropy.mean().item()), + "c_row": float(attention_row_similarity(weights).mean().item()), + "c_far": float(attention_row_similarity(weights, min_separation=6).mean().item()), + "expected_time_start": float(trajectory[0, 0].item()), + "expected_time_end": float(trajectory[0, -1].item()), + "trajectory_span": float((trajectory[0, -1] - trajectory[0, 0]).item()), + "mean_absolute_time_center_error": float( + (trajectory - centers.get(name, trajectory.new_full(trajectory.shape, float("nan")))) + .abs() + .mean() + .item() + ) + if name in centers + else None, + "gaussian_target_kl": None, + } + if name in targets: + target = targets[name].clamp_min(1e-12) + prediction = weights.clamp_min(1e-8) + row["gaussian_target_kl"] = float( + (target * (target.log() - prediction.log())).sum(dim=-1).mean().item() + ) + rows.append(row) + return rows + + +def _example_arrays(sample: FeatureSample, output: Any, sequences: Mapping[str, Any], method: str) -> dict[str, np.ndarray]: + targets = _gaussian_targets(method, output, sequences, torch.tensor([sample.duration_s], device=output.weights["text"].device)) + arrays: dict[str, np.ndarray] = {"sample_id": np.asarray(sample.sample_id)} + for name in MODALITIES: + length = len(sample.times[name]) + arrays[f"weights_{name}"] = output.weights[name][0, :, :length].detach().cpu().numpy() + arrays[f"times_{name}_s"] = sample.times[name].astype(np.float32, copy=False) + arrays[f"valid_{name}"] = sample.valid[name] + trajectory = ( + output.weights[name][0, :, :length] + @ torch.as_tensor(sample.times[name], dtype=torch.float32, device=output.weights[name].device) + / sample.duration_s + ) + arrays[f"trajectory_{name}"] = trajectory.detach().cpu().numpy() + if name in targets: + arrays[f"target_{name}"] = targets[name][0, :, :length].detach().cpu().numpy() + return arrays + + +def _plot_example( + path_prefix: Path, + sample: FeatureSample, + arrays: Mapping[str, np.ndarray], + method: str, + experiment: str, +) -> None: + modalities = ("audio", "vision") if method == "M3" else MODALITIES + fig, axes = plt.subplots(len(modalities), 2, figsize=(12, 4 * len(modalities)), constrained_layout=True) + if len(modalities) == 1: + axes = np.asarray([axes]) + for row, name in enumerate(modalities): + times = arrays[f"times_{name}_s"] / max(sample.duration_s, 1e-8) + extent = (float(times[0]), float(times[-1]), 0.0, 1.0) + prediction = arrays[f"weights_{name}"] + image = axes[row, 0].imshow( + prediction, + origin="lower", + aspect="auto", + interpolation="nearest", + extent=extent, + cmap="magma", + ) + axes[row, 0].set_title(f"{name}: learned A") + axes[row, 0].set_xlabel("source time / clip duration") + axes[row, 0].set_ylabel("slot index / K") + fig.colorbar(image, ax=axes[row, 0], fraction=0.046, pad=0.04) + target_key = f"target_{name}" + if target_key in arrays: + target = arrays[target_key] + image_target = axes[row, 1].imshow( + target, + origin="lower", + aspect="auto", + interpolation="nearest", + extent=extent, + cmap="magma", + ) + axes[row, 1].set_title(f"{name}: Gaussian target P") + fig.colorbar(image_target, ax=axes[row, 1], fraction=0.046, pad=0.04) + else: + axes[row, 1].imshow( + np.zeros_like(prediction), + origin="lower", + aspect="auto", + extent=extent, + cmap="magma", + ) + axes[row, 1].set_title(f"{name}: target not used by M3") + axes[row, 1].set_xlabel("source time / clip duration") + axes[row, 1].set_ylabel("slot index / K") + fig.suptitle(f"{experiment} {method} · {sample.sample_id}") + fig.savefig(path_prefix.with_name(path_prefix.name + "_heatmap.png"), dpi=160) + plt.close(fig) + + fig, ax = plt.subplots(figsize=(8, 5), constrained_layout=True) + x = (np.arange(GRID_SIZE, dtype=np.float32) + 0.5) / GRID_SIZE + for name in MODALITIES: + trajectory = arrays[f"trajectory_{name}"] + ax.plot(x, trajectory, label=f"{name} actual") + if f"target_{name}" in arrays: + target_weights = arrays[f"target_{name}"] + target_time = target_weights @ arrays[f"times_{name}_s"] / max(sample.duration_s, 1e-8) + ax.plot(x, target_time, linestyle="--", alpha=0.7, label=f"{name} target") + ax.plot([0, 1], [0, 1], color="black", linestyle=":", alpha=0.6, label="uniform-time reference") + ax.set(xlim=(0, 1), ylim=(0, 1), xlabel="shared slot position", ylabel="expected normalized source time") + ax.grid(alpha=0.2) + ax.legend(fontsize=8, ncol=2) + ax.set_title(f"{experiment} {method} trajectory · {sample.sample_id}") + fig.savefig(path_prefix.with_name(path_prefix.name + "_trajectory.png"), dpi=160) + plt.close(fig) + + +def _batches(samples: Sequence[FeatureSample], batch_size: int, rng: np.random.Generator): + order = rng.permutation(len(samples)).tolist() + for start in range(0, len(order), batch_size): + yield [samples[index] for index in order[start : start + batch_size]] + + +def _evaluate_samples( + method: str, + experiment: str, + model: nn.Module, + samples: Sequence[FeatureSample], + stats: FeatureStats, + *, + device: torch.device, + batch_size: int, +) -> tuple[list[dict[str, Any]], dict[str, np.ndarray] | None]: + rows: list[dict[str, Any]] = [] + example_arrays: dict[str, np.ndarray] | None = None + model.eval() + rng = np.random.default_rng(0) + with torch.no_grad(): + for batch_samples in _batches(samples, batch_size, rng): + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences) + for index, sample in enumerate(batch_samples): + one_sequences = { + name: type(sequences[name])( + features=sequences[name].features[index : index + 1], + times=sequences[name].times[index : index + 1], + valid=sequences[name].valid[index : index + 1], + ) + for name in MODALITIES + } + one_output = type(output)( + weights={name: output.weights[name][index : index + 1] for name in MODALITIES}, + aligned={name: output.aligned[name][index : index + 1] for name in MODALITIES}, + fallback_rows=output.fallback_rows, + ) + one_duration = durations[index : index + 1] + rows.extend( + _metric_rows( + method, + experiment, + sample, + one_output, + one_sequences, + one_duration, + stats=stats, + device=device, + ) + ) + if sample.sample_id == EXAMPLE_ID: + example_arrays = _example_arrays(sample, one_output, one_sequences, method) + return rows, example_arrays + + +def _run_trial( + experiment: str, + method: str, + tag: str, + train_samples: Sequence[FeatureSample], + eval_samples: Sequence[FeatureSample], + stats: FeatureStats, + output_dir: Path, + *, + device: torch.device, + seed: int, + steps: int, + absolute_position_encoding: bool, + batch_size: int, + include_content_losses: bool, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + _seed_everything(seed) + dimensions = {name: train_samples[0].features[name].shape[1] for name in MODALITIES} + model = _model(method, dimensions, absolute_position_encoding=absolute_position_encoding).to(device) + decoder = AlignmentReconstructor(HIDDEN_SIZE, dropout=0.0).to(device) if include_content_losses else None + parameters = list(model.parameters()) + (list(decoder.parameters()) if decoder is not None else []) + optimizer = torch.optim.AdamW(parameters, lr=LEARNING_RATE, weight_decay=0.0) + block_generator = torch.Generator(device=device) + block_generator.manual_seed(seed + 73) + rng = np.random.default_rng(seed) + order = np.arange(len(train_samples)) + cursor = 0 + history: list[dict[str, Any]] = [] + log_every = LOG_INTERVAL + active_names: tuple[str, ...] | None = None + + print( + f"[{experiment} {tag}] samples={len(train_samples)} steps={steps} " + f"sinusoidal_PE={absolute_position_encoding} lr={LEARNING_RATE}", + flush=True, + ) + model.train() + if decoder is not None: + decoder.train() + for step in range(1, steps + 1): + if len(train_samples) == 1: + batch_samples = [train_samples[0]] + else: + if cursor + batch_size > len(order): + order = rng.permutation(len(train_samples)) + cursor = 0 + indices = order[cursor : cursor + batch_size] + cursor += len(indices) + batch_samples = [train_samples[int(index)] for index in indices] + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences) + total, losses, active_components = _training_components( + experiment, + method, + output, + sequences, + durations, + decoder=decoder, + block_generator=block_generator, + ) + active_names = active_components + if not torch.isfinite(total): + raise FloatingPointError(f"non-finite {experiment}/{tag} loss at step {step}") + + row: dict[str, Any] = { + "experiment": experiment, + "method": method, + "variant": tag, + "step": step, + "epoch": math.ceil(step / max(1, math.ceil(len(train_samples) / batch_size))), + "learning_rate": LEARNING_RATE, + "absolute_position_encoding": absolute_position_encoding, + "L_rec": float(losses["reconstruction"].detach().item()), + "L_con": float(losses["contrastive"].detach().item()), + "L_span": float(losses["span"].detach().item()), + "L_band": float(losses["band"].detach().item()), + "L_align": float(losses["align"].detach().item()), + "L_total": float(total.detach().item()), + } + if step == 1 or step % log_every == 0 or step == steps: + row.update(_gradient_norms(model, method, losses, active_components)) + optimizer.zero_grad(set_to_none=True) + total.backward() + nn.utils.clip_grad_norm_(parameters, 2.0) + optimizer.step() + history.append(row) + if step == 1 or step % log_every == 0 or step == steps: + _write_csv(output_dir / f"{tag}_history.csv", history) + if step % 100 == 0 or step == steps: + diagnostic_component = "band" if experiment == "D0" else "align" + print( + f"[{experiment} {tag} step {step}/{steps}] " + f"total={row['L_total']:.4f} align={row['L_align']:.4f} " + f"span={row['L_span']:.4f} band={row['L_band']:.4f} " + f"grad-{diagnostic_component}(Q/K/Z)=" + f"{row.get(f'grad_{diagnostic_component}_WQ', float('nan')):.3g}/" + f"{row.get(f'grad_{diagnostic_component}_WK', float('nan')):.3g}/" + f"{row.get(f'grad_{diagnostic_component}_Z', float('nan')) if row.get(f'grad_{diagnostic_component}_Z') is not None else 'NA'}", + flush=True, + ) + + output_dir.mkdir(parents=True, exist_ok=True) + _write_csv(output_dir / f"{tag}_history.csv", history) + checkpoint = output_dir / f"{tag}_checkpoint.pt" + torch.save( + { + "experiment": experiment, + "method": method, + "variant": tag, + "seed": seed, + "steps": steps, + "absolute_position_encoding": absolute_position_encoding, + "model_state_dict": model.state_dict(), + "decoder_state_dict": decoder.state_dict() if decoder is not None else None, + "history": history, + }, + checkpoint, + ) + metric_rows, example_arrays = _evaluate_samples( + method, + experiment, + model, + eval_samples, + stats, + device=device, + batch_size=batch_size, + ) + _write_csv(output_dir / f"{tag}_metrics.csv", metric_rows) + if example_arrays is not None: + np.savez_compressed(output_dir / f"{tag}_example_alignment.npz", **example_arrays) + example_sample = next(sample for sample in eval_samples if sample.sample_id == EXAMPLE_ID) + _plot_example(output_dir / tag, example_sample, example_arrays, method, experiment) + del model, decoder + if device.type == "cuda": + torch.cuda.empty_cache() + return history, metric_rows + + +def run(args: argparse.Namespace) -> dict[str, Any]: + started = time.time() + _seed_everything(args.seed) + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is not available") + samples = load_feature_samples(args.feature_dir, args.manifest) + if len(samples) != 100: + raise ValueError(f"debug experiments expect the complete 100-sample set, found {len(samples)}") + sample_by_id = {sample.sample_id: sample for sample in samples} + if EXAMPLE_ID not in sample_by_id: + raise ValueError(f"required debug sample is absent: {EXAMPLE_ID}") + one_sample = sample_by_id[EXAMPLE_ID] + output_root = args.output_dir + output_root.mkdir(parents=True, exist_ok=True) + full_stats = fit_feature_stats(samples) + single_stats = fit_feature_stats([one_sample]) + all_metrics: list[dict[str, Any]] = [] + all_history_summaries: list[dict[str, Any]] = [] + + specifications = [ + ("D0", "M3", "M3", [one_sample], [one_sample], single_stats, SINGLE_SAMPLE_STEPS, False, False), + ("D0", "M4", "M4", [one_sample], [one_sample], single_stats, SINGLE_SAMPLE_STEPS, False, False), + ("D1", "M3", "M3", [one_sample], [one_sample], single_stats, SINGLE_SAMPLE_STEPS, False, False), + ("D1", "M4", "M4_noPE", [one_sample], [one_sample], single_stats, SINGLE_SAMPLE_STEPS, False, False), + ("D1", "M4", "M4_sinPE", [one_sample], [one_sample], single_stats, SINGLE_SAMPLE_STEPS, True, False), + ("D2", "M3", "M3", samples, samples, full_stats, FULL_DATA_STEPS, False, False), + ("D2", "M4", "M4_sinPE", samples, samples, full_stats, FULL_DATA_STEPS, True, False), + ("D3", "M3", "M3", samples, samples, full_stats, FULL_DATA_STEPS, False, True), + ("D3", "M4", "M4_sinPE", samples, samples, full_stats, FULL_DATA_STEPS, True, True), + ] + + for experiment, method, tag, train_set, eval_set, stats, steps, use_pe, content_losses in specifications: + trial_dir = output_root / experiment + trial_dir.mkdir(parents=True, exist_ok=True) + history, metric_rows = _run_trial( + experiment, + method, + tag, + train_set, + eval_set, + stats, + trial_dir, + device=device, + seed=args.seed, + steps=steps, + absolute_position_encoding=use_pe, + batch_size=BATCH_SIZE, + include_content_losses=content_losses, + ) + all_metrics.extend(metric_rows) + selected_steps = [ + row + for row in history + if any(key.startswith("grad_") and value not in (None, "") for key, value in row.items()) + ] + summary: dict[str, Any] = { + "experiment": experiment, + "method": method, + "variant": tag, + "steps": steps, + "absolute_position_encoding": use_pe, + "final_L_total": history[-1]["L_total"], + "final_L_rec": history[-1]["L_rec"], + "final_L_con": history[-1]["L_con"], + "final_L_span": history[-1]["L_span"], + "final_L_band": history[-1]["L_band"], + "final_L_align": history[-1]["L_align"], + } + if selected_steps: + for component in ("span", "band", "align", "reconstruction", "contrastive", "total"): + for parameter in ("WQ", "WK", "Z"): + key = f"grad_{component}_{parameter}" + values = [float(row[key]) for row in selected_steps if row.get(key) not in (None, "")] + if values: + summary[f"mean_{key}"] = float(np.mean(values)) + summary[f"final_{key}"] = values[-1] + summary["final_metric_rows"] = len(metric_rows) + all_history_summaries.append(summary) + print( + f"[done {experiment} {tag}] final total={summary['final_L_total']:.4f} " + f"align={summary['final_L_align']:.4f}; metrics={len(metric_rows)}", + flush=True, + ) + + _write_csv(output_root / "debug_summary.csv", all_history_summaries) + _write_csv(output_root / "per_sample_metrics.csv", all_metrics) + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "sample_count": len(samples), + "diagnostic_sample": EXAMPLE_ID, + "seed": args.seed, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "experiments": [ + { + "name": "D0", + "scope": "single sample; span + barycenter band only", + "steps_per_model": SINGLE_SAMPLE_STEPS, + "loss": "5 * L_span + 10 * L_band", + }, + { + "name": "D1", + "scope": "single sample; Gaussian target KL only", + "steps_per_model": SINGLE_SAMPLE_STEPS, + "sigma_normalized_time": SIGMA, + "M4_control": "no PE versus fixed sinusoidal PE", + }, + { + "name": "D2", + "scope": "all 100 clips; Gaussian target KL only; one seed; in-sample diagnostic", + "steps_per_model": FULL_DATA_STEPS, + "sigma_normalized_time": SIGMA, + "M4_position_encoding": "fixed sinusoidal", + }, + { + "name": "D3", + "scope": "all 100 clips; Gaussian KL + masked reconstruction + contrastive; one seed; in-sample diagnostic", + "steps_per_model": FULL_DATA_STEPS, + "sigma_normalized_time": SIGMA, + "M4_position_encoding": "fixed sinusoidal", + }, + ], + "optimizer": "AdamW", + "learning_rate": LEARNING_RATE, + "dropout": 0.0, + "batch_size": BATCH_SIZE, + "gradient_logging_interval_steps": LOG_INTERVAL, + "gradient_metrics": ["W_Q", "W_K", "M4 latent slots Z"], + "features_changed": False, + "M1_M2_changed": False, + "elapsed_seconds": time.time() - started, + "interpretation_limits": [ + "D0 and D1 overfit one selected sample and diagnose optimization/representability only.", + "D2 and D3 train and evaluate on the same 100 clips; they diagnose whether the target can be optimized, not generalization.", + "Gaussian targets are weak temporal priors constructed from timestamps; they are not human alignment ground truth.", + "M4 absolute sinusoidal encoding is enabled only for D1's PE control and D2/D3; prior M1-M4 and v2 results are unchanged.", + ], + } + (output_root / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + print( + f"[all done] elapsed={manifest['elapsed_seconds']:.1f}s output={output_root}", + flush=True, + ) + return manifest + + +def build_parser() -> argparse.ArgumentParser: + project_dir = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser( + description="Diagnose gradient flow and temporal alignment learnability for M3/M4." + ) + parser.add_argument("--feature-dir", type=Path, default=project_dir / "outputs/q1_features/features") + parser.add_argument("--manifest", type=Path, default=project_dir / "outputs/audit/manifest.csv") + parser.add_argument("--output-dir", type=Path, default=project_dir / "outputs/alignment_debug") + parser.add_argument("--device", default="auto", help="auto, cpu, or a torch device such as cuda:0") + parser.add_argument("--seed", type=int, default=42) + return parser + + +def main() -> int: + args = build_parser().parse_args() + run(args) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/deep_learning/Q1/q1/alignment_heldout_debug.py b/deep_learning/Q1/q1/alignment_heldout_debug.py new file mode 100644 index 0000000..722588a --- /dev/null +++ b/deep_learning/Q1/q1/alignment_heldout_debug.py @@ -0,0 +1,382 @@ +"""Grouped held-out check for learned source-time positional features.""" + +from __future__ import annotations + +import argparse +import csv +import json +import platform +import time +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +import numpy as np +import torch +from torch import nn + +from .alignment_debug import ( + EXAMPLE_ID, + GRID_SIZE, + HEADS, + HIDDEN_SIZE, + LEARNING_RATE, + _example_arrays, + _gaussian_alignment_kl, + _gaussian_targets, + _gradient_norms, + _metric_rows, + _plot_example, + _seed_everything, +) +from .experiment_data import ( + FeatureSample, + FeatureStats, + collate_feature_samples, + fit_feature_stats, + load_feature_samples, +) +from .models import SharedLatentTimeline, TextAnchoredCrossAttention +from .types import MODALITIES + + +BATCH_SIZE = 8 +DEFAULT_STEPS = 500 + + +def _write_csv(path: Path, rows: list[dict[str, Any]]) -> None: + if not rows: + return + path.parent.mkdir(parents=True, exist_ok=True) + fields = list(dict.fromkeys(key for row in rows for key in row)) + with path.open("w", newline="", encoding="utf-8-sig") as handle: + writer = csv.DictWriter(handle, fieldnames=fields) + writer.writeheader() + writer.writerows(rows) + + +def _make_model(method: str, dimensions: dict[str, int], source_time: bool) -> nn.Module: + if method == "M3": + return TextAnchoredCrossAttention( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + source_time_encoding=source_time, + ) + return SharedLatentTimeline( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + absolute_position_encoding=True, + source_time_encoding=source_time, + ) + + +def _batches(samples: list[FeatureSample], rng: np.random.Generator): + order = rng.permutation(len(samples)).tolist() + for start in range(0, len(order), BATCH_SIZE): + yield [samples[index] for index in order[start : start + BATCH_SIZE]] + + +def _train_one( + *, + method: str, + variant: str, + source_time: bool, + train_samples: list[FeatureSample], + validation_samples: list[FeatureSample], + stats: FeatureStats, + example_id: str, + output_dir: Path, + device: torch.device, + steps: int, + seed: int, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]], dict[str, Any]]: + _seed_everything(seed) + dimensions = { + name: train_samples[0].features[name].shape[1] for name in MODALITIES + } + model = _make_model(method, dimensions, source_time).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=LEARNING_RATE, weight_decay=0.0) + rng = np.random.default_rng(seed) + history: list[dict[str, Any]] = [] + print( + f"[D5 {variant}] train={len(train_samples)} heldout={len(validation_samples)} " + f"groups={len({s.group_id for s in train_samples})}/" + f"{len({s.group_id for s in validation_samples})} steps={steps}", + flush=True, + ) + model.train() + for step in range(1, steps + 1): + batch_indices = rng.choice( + len(train_samples), size=min(BATCH_SIZE, len(train_samples)), replace=False + ) + batch_samples = [train_samples[int(index)] for index in batch_indices] + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences, durations) if source_time else model(sequences) + targets = _gaussian_targets(method, output, sequences, durations) + loss = _gaussian_alignment_kl(output, targets) + if not torch.isfinite(loss): + raise FloatingPointError(f"non-finite D5 loss for {variant} at step {step}") + row: dict[str, Any] = { + "experiment": "D5", + "method": method, + "variant": variant, + "step": step, + "L_align": float(loss.detach().item()), + "source_time_encoding": source_time, + } + if step == 1 or step % 20 == 0 or step == steps: + row.update(_gradient_norms(model, method, {"align": loss}, ("align",))) + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 2.0) + optimizer.step() + history.append(row) + if step == 1 or step % 100 == 0 or step == steps: + grad_z = row.get("grad_align_Z") + grad_z_text = f"{grad_z:.3g}" if grad_z is not None else "NA" + print( + f"[D5 {variant} {step}/{steps}] KL={row['L_align']:.5f} " + f"grad_Q/K/Z={row.get('grad_align_WQ', 0):.3g}/" + f"{row.get('grad_align_WK', 0):.3g}/{grad_z_text}", + flush=True, + ) + + output_dir.mkdir(parents=True, exist_ok=True) + _write_csv(output_dir / "history.csv", history) + model.eval() + metric_rows: list[dict[str, Any]] = [] + heldout_arrays: dict[str, np.ndarray] | None = None + with torch.no_grad(): + eval_rng = np.random.default_rng(0) + for batch_samples in _batches(validation_samples, eval_rng): + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences, durations) if source_time else model(sequences) + for index, sample in enumerate(batch_samples): + one_sequences = { + name: type(sequences[name])( + features=sequences[name].features[index : index + 1], + times=sequences[name].times[index : index + 1], + valid=sequences[name].valid[index : index + 1], + ) + for name in MODALITIES + } + one_output = type(output)( + weights={name: output.weights[name][index : index + 1] for name in MODALITIES}, + aligned={name: output.aligned[name][index : index + 1] for name in MODALITIES}, + fallback_rows=output.fallback_rows, + ) + rows = _metric_rows( + method, + "D5", + sample, + one_output, + one_sequences, + durations[index : index + 1], + stats=stats, + device=device, + ) + for metric_row in rows: + metric_row["variant"] = variant + metric_row["source_time_encoding"] = source_time + metric_rows.extend(rows) + if sample.sample_id == example_id: + heldout_arrays = _example_arrays( + sample, one_output, one_sequences, method + ) + + _write_csv(output_dir / "heldout_metrics.csv", metric_rows) + if heldout_arrays is not None: + heldout_sample = next(s for s in validation_samples if s.sample_id == example_id) + np.savez_compressed(output_dir / "heldout_alignment.npz", **heldout_arrays) + _plot_example(output_dir / variant, heldout_sample, heldout_arrays, method, "D5 held-out") + checkpoint = output_dir / "checkpoint.pt" + torch.save( + { + "experiment": "D5", + "method": method, + "variant": variant, + "source_time_encoding": source_time, + "absolute_position_encoding": method == "M4", + "seed": seed, + "steps": steps, + "train_sample_ids": [sample.sample_id for sample in train_samples], + "validation_sample_ids": [sample.sample_id for sample in validation_samples], + "model_state_dict": model.state_dict(), + }, + checkpoint, + ) + training_summary = { + "experiment": "D5", + "method": method, + "variant": variant, + "source_time_encoding": source_time, + "final_training_kl": history[-1]["L_align"], + "heldout_sample_count": len(validation_samples), + "checkpoint": str(checkpoint), + } + del model + if device.type == "cuda": + torch.cuda.empty_cache() + return metric_rows, history, training_summary + + +def run(args: argparse.Namespace) -> dict[str, Any]: + started = time.time() + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is unavailable") + samples = load_feature_samples(args.feature_dir, args.manifest) + by_id = {sample.sample_id: sample for sample in samples} + with args.splits.open("r", encoding="utf-8-sig") as handle: + folds = json.load(handle) + fold = next((item for item in folds if item["fold"] == args.fold), None) + if fold is None: + raise ValueError(f"fold {args.fold} is not present in {args.splits}") + train_samples = [by_id[sample_id] for sample_id in fold["train_sample_ids"]] + validation_samples = [by_id[sample_id] for sample_id in fold["validation_sample_ids"]] + train_groups = {sample.group_id for sample in train_samples} + validation_groups = {sample.group_id for sample in validation_samples} + if train_groups & validation_groups: + raise ValueError("train/validation video_id groups overlap") + example_id = args.example_id or validation_samples[0].sample_id + if example_id not in {sample.sample_id for sample in validation_samples}: + raise ValueError(f"held-out example is not in validation fold: {example_id}") + stats = fit_feature_stats(train_samples) + output_root = args.output_dir + output_root.mkdir(parents=True, exist_ok=True) + + specifications = ( + ("M3", "M3_noSourceTime", False), + ("M3", "M3_sourceTime", True), + ("M4", "M4_noSourceTime", False), + ("M4", "M4_sourceTime", True), + ) + all_metrics: list[dict[str, Any]] = [] + all_history: list[dict[str, Any]] = [] + summaries: list[dict[str, Any]] = [] + for method, variant, source_time in specifications: + metrics, history, summary = _train_one( + method=method, + variant=variant, + source_time=source_time, + train_samples=train_samples, + validation_samples=validation_samples, + stats=stats, + example_id=example_id, + output_dir=output_root / variant, + device=device, + steps=args.steps, + seed=args.seed, + ) + all_metrics.extend(metrics) + all_history.extend(history) + summaries.append(summary) + _write_csv(output_root / "per_sample_metrics.csv", all_metrics) + _write_csv(output_root / "training_history.csv", all_history) + + aggregate_rows: list[dict[str, Any]] = [] + metric_names = ( + "mvr", + "normalized_entropy", + "c_row", + "trajectory_span", + "mean_absolute_time_center_error", + "gaussian_target_kl", + ) + for variant, modality in sorted( + {(row["variant"], row["modality"]) for row in all_metrics} + ): + rows = [row for row in all_metrics if row["variant"] == variant and row["modality"] == modality] + aggregate: dict[str, Any] = { + "variant": variant, + "modality": modality, + "sample_count": len(rows), + } + for name in metric_names: + values = [float(row[name]) for row in rows if row.get(name) not in (None, "")] + aggregate[f"mean_{name}"] = float(np.mean(values)) if values else "" + aggregate_rows.append(aggregate) + _write_csv(output_root / "heldout_summary.csv", aggregate_rows) + _write_csv(output_root / "training_summary.csv", summaries) + + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "experiment": "D5", + "fold": args.fold, + "heldout_example": example_id, + "train_sample_count": len(train_samples), + "heldout_sample_count": len(validation_samples), + "train_video_ids": sorted(train_groups), + "heldout_video_ids": sorted(validation_groups), + "video_id_overlap": sorted(train_groups & validation_groups), + "seed": args.seed, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "grid_size": GRID_SIZE, + "optimizer": "AdamW", + "learning_rate": LEARNING_RATE, + "steps_per_model": args.steps, + "batch_size": BATCH_SIZE, + "loss": "timestamp-derived Gaussian target KL only", + "source_position_encoding": "fixed Fourier time code added to source key only; value remains projected content", + "query_position_encoding": "M3 adds Fourier code at text-time centers; M4 uses fixed absolute sinusoidal slots plus the matching Fourier code at uniform slot centers", + "normalization_fit_on_train_only": True, + "variants": summaries, + "elapsed_seconds": time.time() - started, + "interpretation_limits": [ + "This is one grouped video_id split and one seed; it is a focused held-out diagnostic, not a final method ranking.", + "The Gaussian timestamp target is a weak temporal prior, not human alignment ground truth.", + "The target supplies approximate time location; this experiment tests transfer of the time-conditioned attention mechanism, not semantic correctness by itself.", + ], + } + (output_root / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + print( + f"[D5 done] train={len(train_samples)} heldout={len(validation_samples)} " + f"video_id_groups={len(train_groups)}/{len(validation_groups)} " + f"elapsed={manifest['elapsed_seconds']:.1f}s output={output_root}", + flush=True, + ) + return manifest + + +def build_parser() -> argparse.ArgumentParser: + project = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--steps", type=int, default=DEFAULT_STEPS) + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--fold", type=int, default=1) + parser.add_argument("--example-id", type=str, default=None) + parser.add_argument("--device", choices=("auto", "cpu", "cuda"), default="auto") + parser.add_argument( + "--feature-dir", type=Path, default=project / "outputs/q1_features/features" + ) + parser.add_argument("--manifest", type=Path, default=project / "outputs/audit/manifest.csv") + parser.add_argument( + "--splits", type=Path, default=project / "outputs/method_comparison/splits.json" + ) + parser.add_argument( + "--output-dir", type=Path, default=project / "outputs/alignment_debug/heldout" + ) + return parser + + +def main() -> None: + args = build_parser().parse_args() + run(args) + + +if __name__ == "__main__": + main() diff --git a/deep_learning/Q1/q1/alignment_key_position_debug.py b/deep_learning/Q1/q1/alignment_key_position_debug.py new file mode 100644 index 0000000..f6fcda4 --- /dev/null +++ b/deep_learning/Q1/q1/alignment_key_position_debug.py @@ -0,0 +1,273 @@ +"""Single-clip test of explicit source-time identities in learned alignment.""" + +from __future__ import annotations + +import argparse +import csv +import json +import platform +import time +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +import numpy as np +import torch +from torch import nn + +from .alignment_debug import ( + EXAMPLE_ID, + GRID_SIZE, + HEADS, + HIDDEN_SIZE, + LEARNING_RATE, + SIGMA, + _example_arrays, + _gaussian_alignment_kl, + _gaussian_targets, + _gradient_norms, + _metric_rows, + _plot_example, + _seed_everything, +) +from .experiment_data import fit_feature_stats, load_feature_samples, collate_feature_samples +from .models import SharedLatentTimeline, TextAnchoredCrossAttention +from .types import MODALITIES + + +def _write_csv(path: Path, rows: list[dict[str, Any]]) -> None: + if not rows: + return + path.parent.mkdir(parents=True, exist_ok=True) + fields = list(dict.fromkeys(key for row in rows for key in row)) + with path.open("w", newline="", encoding="utf-8-sig") as handle: + writer = csv.DictWriter(handle, fieldnames=fields) + writer.writeheader() + writer.writerows(rows) + + +def _make_model(method: str, dimensions: dict[str, int], source_time_encoding: bool) -> nn.Module: + if method == "M3": + return TextAnchoredCrossAttention( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + source_time_encoding=source_time_encoding, + ) + return SharedLatentTimeline( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + absolute_position_encoding=True, + source_time_encoding=source_time_encoding, + ) + + +def _run_trial( + *, + method: str, + variant: str, + source_time_encoding: bool, + sample: Any, + stats: Any, + device: torch.device, + steps: int, + seed: int, + output_dir: Path, +) -> tuple[dict[str, Any], list[dict[str, Any]]]: + _seed_everything(seed) + dimensions = {name: sample.features[name].shape[1] for name in MODALITIES} + model = _make_model(method, dimensions, source_time_encoding).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=LEARNING_RATE, weight_decay=0.0) + sequences, durations, _ = collate_feature_samples([sample], stats, device) + history: list[dict[str, Any]] = [] + print( + f"[D4 {variant}] sample={sample.sample_id} steps={steps} " + f"source_time_encoding={source_time_encoding} device={device}", + flush=True, + ) + model.train() + for step in range(1, steps + 1): + output = model(sequences, durations) if source_time_encoding else model(sequences) + targets = _gaussian_targets(method, output, sequences, durations) + loss = _gaussian_alignment_kl(output, targets) + if not torch.isfinite(loss): + raise FloatingPointError(f"non-finite D4 loss at {variant} step {step}") + row: dict[str, Any] = { + "experiment": "D4", + "method": method, + "variant": variant, + "step": step, + "L_align": float(loss.detach().item()), + "source_time_encoding": source_time_encoding, + } + if step == 1 or step % 20 == 0 or step == steps: + row.update(_gradient_norms(model, method, {"align": loss}, ("align",))) + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 2.0) + optimizer.step() + history.append(row) + if step == 1 or step % 100 == 0 or step == steps: + grad_z = row.get("grad_align_Z") + grad_z_text = f"{grad_z:.3g}" if grad_z is not None else "NA" + print( + f"[D4 {variant} {step}/{steps}] KL={row['L_align']:.5f} " + f"grad_Q/K/Z={row.get('grad_align_WQ', 0):.3g}/" + f"{row.get('grad_align_WK', 0):.3g}/" + f"{grad_z_text}", + flush=True, + ) + + output_dir.mkdir(parents=True, exist_ok=True) + _write_csv(output_dir / "history.csv", history) + model.eval() + with torch.no_grad(): + output = model(sequences, durations) if source_time_encoding else model(sequences) + metric_rows = _metric_rows( + method, + "D4", + sample, + output, + sequences, + durations, + stats=stats, + device=device, + ) + arrays = _example_arrays(sample, output, sequences, method) + for row in metric_rows: + row["variant"] = variant + row["source_time_encoding"] = source_time_encoding + _write_csv(output_dir / "metrics.csv", metric_rows) + np.savez_compressed(output_dir / "example_alignment.npz", **arrays) + _plot_example(output_dir / variant, sample, arrays, method, "D4") + checkpoint = output_dir / "checkpoint.pt" + torch.save( + { + "experiment": "D4", + "method": method, + "variant": variant, + "source_time_encoding": source_time_encoding, + "absolute_position_encoding": method == "M4", + "seed": seed, + "steps": steps, + "model_state_dict": model.state_dict(), + }, + checkpoint, + ) + summary = { + "experiment": "D4", + "method": method, + "variant": variant, + "source_time_encoding": source_time_encoding, + "final_training_kl": history[-1]["L_align"], + "checkpoint": str(checkpoint), + } + del model + if device.type == "cuda": + torch.cuda.empty_cache() + return summary, metric_rows + + +def run(args: argparse.Namespace) -> dict[str, Any]: + start = time.time() + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is unavailable") + samples = load_feature_samples(args.feature_dir, args.manifest) + sample_map = {sample.sample_id: sample for sample in samples} + if EXAMPLE_ID not in sample_map: + raise ValueError(f"diagnostic sample is missing: {EXAMPLE_ID}") + sample = sample_map[EXAMPLE_ID] + stats = fit_feature_stats([sample]) + output_root = args.output_dir + output_root.mkdir(parents=True, exist_ok=True) + specifications = ( + ("M3", "M3_noSourceTime", False), + ("M3", "M3_sourceTime", True), + ("M4", "M4_noSourceTime", False), + ("M4", "M4_sourceTime", True), + ) + summaries: list[dict[str, Any]] = [] + all_metrics: list[dict[str, Any]] = [] + for method, variant, use_source_time in specifications: + summary, metrics = _run_trial( + method=method, + variant=variant, + source_time_encoding=use_source_time, + sample=sample, + stats=stats, + device=device, + steps=args.steps, + seed=args.seed, + output_dir=output_root / variant, + ) + summaries.append(summary) + all_metrics.extend(metrics) + _write_csv(output_root / "summary.csv", summaries) + _write_csv(output_root / "per_sample_metrics.csv", all_metrics) + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "experiment": "D4", + "sample": sample.sample_id, + "sample_count": 1, + "seed": args.seed, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "grid_size": GRID_SIZE, + "sigma_normalized_time": SIGMA, + "optimizer": "AdamW", + "learning_rate": LEARNING_RATE, + "steps_per_model": args.steps, + "source_position_encoding": "fixed Fourier time code added to source key only; value remains the projected real feature", + "query_position_encoding": "M3 adds Fourier code at forced text-time centers; M4 keeps its fixed absolute sinusoidal slot code and adds the matching Fourier code at uniform slot centers", + "modalities": ["audio", "vision"], + "variants": summaries, + "elapsed_seconds": time.time() - start, + "interpretation_limits": [ + "This is a one-sample overfit diagnostic, not a held-out accuracy result.", + "The timestamp-derived Gaussian target is a weak temporal prior, not human alignment ground truth.", + "The D4 variants test source/query time identity only; content features and downstream outputs still require separate evaluation.", + ], + } + (output_root / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + print(f"[D4 done] elapsed={manifest['elapsed_seconds']:.1f}s output={output_root}", flush=True) + return manifest + + +def build_parser() -> argparse.ArgumentParser: + project = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--steps", type=int, default=1000) + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--device", choices=("auto", "cpu", "cuda"), default="auto") + parser.add_argument( + "--feature-dir", type=Path, default=project / "outputs/q1_features/features" + ) + parser.add_argument( + "--manifest", type=Path, default=project / "outputs/audit/manifest.csv" + ) + parser.add_argument( + "--output-dir", type=Path, default=project / "outputs/alignment_debug/source_time" + ) + return parser + + +def main() -> None: + args = build_parser().parse_args() + run(args) + + +if __name__ == "__main__": + main() diff --git a/deep_learning/Q1/q1/audit.py b/deep_learning/Q1/q1/audit.py new file mode 100644 index 0000000..95f025d --- /dev/null +++ b/deep_learning/Q1/q1/audit.py @@ -0,0 +1,246 @@ +from __future__ import annotations + +import argparse +import csv +import json +import subprocess +from collections import Counter +from fractions import Fraction +from pathlib import Path +from typing import Any + +from openpyxl import load_workbook + + +def _identifier(value: Any) -> str: + if value is None: + return "" + if isinstance(value, float) and value.is_integer(): + return str(int(value)) + return str(value).strip() + + +def _read_labels(path: Path) -> list[dict[str, Any]]: + workbook = load_workbook(path, read_only=True, data_only=True) + sheet = workbook.active + rows = sheet.iter_rows(values_only=True) + header = next(rows, None) + if header is None: + raise ValueError(f"empty workbook: {path}") + names = [str(value).strip().lower() if value is not None else "" for value in header] + required = ("video_id", "clip_id", "text", "label", "annotation") + missing = set(required) - set(names) + if missing: + raise ValueError(f"missing required label columns: {sorted(missing)}") + indexes = {name: names.index(name) for name in required} + records = [] + for values in rows: + if not values or all(value is None for value in values): + continue + record = {name: values[index] if index < len(values) else None for name, index in indexes.items()} + record["video_id"] = _identifier(record["video_id"]) + record["clip_id"] = _identifier(record["clip_id"]) + record["text"] = "" if record["text"] is None else str(record["text"]).strip() + record["annotation"] = "" if record["annotation"] is None else str(record["annotation"]).strip() + if record["label"] is not None: + try: + record["label"] = float(record["label"]) + except (TypeError, ValueError): + pass + records.append(record) + workbook.close() + return records + + +def _probe_video(path: Path) -> dict[str, Any]: + result = subprocess.run( + [ + "ffprobe", "-v", "error", "-show_entries", + "format=duration:stream=codec_type,codec_name,width,height,avg_frame_rate,r_frame_rate,nb_frames,sample_rate,channels:frame=media_type,best_effort_timestamp_time,pkt_duration_time", + "-show_frames", "-of", "json", str(path), + ], + check=True, + capture_output=True, + text=True, + ) + payload = json.loads(result.stdout) + streams = payload.get("streams", []) + video = next((stream for stream in streams if stream.get("codec_type") == "video"), {}) + audio = next((stream for stream in streams if stream.get("codec_type") == "audio"), {}) + fps_text = video.get("avg_frame_rate") or video.get("r_frame_rate") or "0/1" + try: + fps = float(Fraction(fps_text)) + except (ValueError, ZeroDivisionError): + fps = 0.0 + container_duration = float(payload.get("format", {}).get("duration", 0.0)) + frame_times: dict[str, list[tuple[float, float]]] = {"video": [], "audio": []} + for frame in payload.get("frames", []): + media_type = frame.get("media_type") + timestamp = frame.get("best_effort_timestamp_time") + if media_type not in frame_times or timestamp is None: + continue + try: + start = float(timestamp) + packet_duration = float(frame.get("pkt_duration_time", 0.0) or 0.0) + except (TypeError, ValueError): + continue + frame_times[media_type].append((start, packet_duration)) + + video_times = frame_times["video"] + audio_times = frame_times["audio"] + fallback_frame_duration = 1.0 / fps if fps > 0 else 0.0 + video_start = min((item[0] for item in video_times), default=0.0) + video_end = max((start + (packet_duration or fallback_frame_duration) for start, packet_duration in video_times), default=container_duration) + audio_start = min((item[0] for item in audio_times), default=0.0) + audio_end = max((start + packet_duration for start, packet_duration in audio_times), default=container_duration) + decoded_duration = max(0.0, video_end - video_start) + audio_duration = max(0.0, audio_end - audio_start) + return { + "duration_s": decoded_duration or container_duration, + "container_duration_s": container_duration, + "audio_duration_s": audio_duration, + "video_timeline_start_s": video_start, + "video_timeline_end_s": video_end, + "audio_timeline_start_s": audio_start, + "audio_timeline_end_s": audio_end, + "video_codec": video.get("codec_name", ""), + "width": video.get("width", ""), + "height": video.get("height", ""), + "fps": fps, + "video_frames": len(video_times), + "container_video_frames": video.get("nb_frames", ""), + "audio_codec": audio.get("codec_name", ""), + "audio_sample_rate": audio.get("sample_rate", ""), + "audio_channels": audio.get("channels", ""), + "has_audio": bool(audio), + } + + +def audit_dataset(video_root: Path, label_file: Path, output_dir: Path, expected_count: int = 100) -> dict[str, Any]: + records = _read_labels(label_file) + videos: dict[tuple[str, str], Path] = {} + duplicate_video_files: list[str] = [] + for video in sorted(video_root.rglob("*.mp4")): + key = (video.parent.name, video.stem) + if key in videos: + duplicate_video_files.append(str(video)) + else: + videos[key] = video + + keys = [(str(row["video_id"]), str(row["clip_id"])) for row in records] + counts = Counter(keys) + duplicate_rows = [list(key) for key, count in counts.items() if count > 1] + matched_keys = set(keys) & set(videos) + missing_keys = [key for key in keys if key not in videos] + extra_keys = sorted(set(videos) - set(keys)) + class_mismatches = [] + probe_errors: list[dict[str, str]] = [] + probe_by_key: dict[tuple[str, str], dict[str, Any]] = {} + for key in matched_keys: + try: + probe_by_key[key] = _probe_video(videos[key]) + except (OSError, subprocess.CalledProcessError, json.JSONDecodeError, ValueError) as error: + probe_errors.append({"video_id": key[0], "clip_id": key[1], "error": str(error)}) + + output_dir.mkdir(parents=True, exist_ok=True) + manifest_path = output_dir / "manifest.csv" + with manifest_path.open("w", encoding="utf-8-sig", newline="") as file: + writer = csv.DictWriter( + file, + fieldnames=( + "video_id", "clip_id", "group_id", "text", "label", "annotation", "video_path", + "video_exists", "duration_s", "container_duration_s", "audio_duration_s", + "video_timeline_start_s", "video_timeline_end_s", "audio_timeline_start_s", + "audio_timeline_end_s", "video_codec", "width", "height", "fps", + "video_frames", "container_video_frames", "audio_codec", "audio_sample_rate", + "audio_channels", "has_audio", + ), + ) + writer.writeheader() + for row, key in zip(records, keys): + label = row["label"] + annotation = str(row["annotation"]).strip().lower() + expected_class = "negative" if isinstance(label, (int, float)) and label < 0 else ( + "positive" if isinstance(label, (int, float)) and label > 0 else "neutral" + ) + if annotation in {"negative", "neutral", "positive"} and annotation != expected_class: + class_mismatches.append({"video_id": key[0], "clip_id": key[1], "label": label, "annotation": annotation}) + path = videos.get(key) + probe = probe_by_key.get(key, {}) + writer.writerow({ + "video_id": key[0], + "clip_id": key[1], + "group_id": key[0], + "text": row["text"], + "label": row["label"], + "annotation": row["annotation"], + "video_path": str(path.relative_to(video_root)) if path else "", + "video_exists": bool(path), + **probe, + }) + + durations = [info["duration_s"] for info in probe_by_key.values() if info["duration_s"] > 0] + duration_out_of_range = [ + {"video_id": key[0], "clip_id": key[1], "duration_s": info["duration_s"]} + for key, info in probe_by_key.items() + if not (2.648 <= info["duration_s"] <= 34.567) + ] + audio_missing = [list(key) for key, info in probe_by_key.items() if not info["has_audio"]] + + summary = { + "video_root": str(video_root), + "label_file": str(label_file), + "expected_count": expected_count, + "label_rows": len(records), + "unique_video_clip_pairs": len(set(keys)), + "unique_video_ids": len({key[0] for key in keys}), + "video_files": len(videos), + "matched_samples": len(matched_keys), + "coverage_rate": len(matched_keys) / max(len(records), 1), + "duration_min_s": min(durations) if durations else None, + "duration_max_s": max(durations) if durations else None, + "stated_duration_range_s": [2.648, 34.567], + "duration_out_of_range": duration_out_of_range, + "audio_stream_missing": audio_missing, + "media_probe_errors": probe_errors, + "missing_video_pairs": [list(key) for key in missing_keys], + "unlisted_video_pairs": [list(key) for key in extra_keys], + "duplicate_label_pairs": duplicate_rows, + "duplicate_video_files": duplicate_video_files, + "label_class_mismatches": class_mismatches, + "manifest": str(manifest_path), + } + summary["coverage_status"] = ( + "complete_with_metadata_warnings" if duration_out_of_range else "complete" + ) + summary_path = output_dir / "coverage_summary.json" + summary_path.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8") + return summary + + +def main() -> int: + project_dir = Path(__file__).resolve().parents[1] + repo_dir = project_dir.parent + default_data = repo_dir / "E题数据" / "附件1-数据集原始多模态样本" / "MOSEI数据集部分原始视频-100条" + parser = argparse.ArgumentParser(description="Audit the 100 raw-video Q1 samples and export a manifest.") + parser.add_argument("--video-root", type=Path, default=default_data) + parser.add_argument("--labels", type=Path, default=default_data / "label-100.xlsx") + parser.add_argument("--output-dir", type=Path, default=project_dir / "outputs" / "audit") + parser.add_argument("--expected-count", type=int, default=100) + args = parser.parse_args() + summary = audit_dataset(args.video_root, args.labels, args.output_dir, args.expected_count) + print(json.dumps(summary, ensure_ascii=False, indent=2)) + complete = ( + summary["label_rows"] == args.expected_count + and summary["unique_video_clip_pairs"] == args.expected_count + and summary["matched_samples"] == args.expected_count + and not summary["duplicate_label_pairs"] + and not summary["label_class_mismatches"] + and not summary["audio_stream_missing"] + and not summary["media_probe_errors"] + ) + return 0 if complete else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/deep_learning/Q1/q1/compare_methods.py b/deep_learning/Q1/q1/compare_methods.py new file mode 100644 index 0000000..9787b74 --- /dev/null +++ b/deep_learning/Q1/q1/compare_methods.py @@ -0,0 +1,945 @@ +from __future__ import annotations + +import argparse +import csv +import json +import math +import platform +import random +import statistics +import time +from collections import defaultdict +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Mapping, Sequence + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import torch +from sklearn.model_selection import GroupKFold +from torch import Tensor, nn + +from .alignment import align_fixed_windows, align_forced_timestamps, make_block_mask +from .experiment_data import ( + FeatureSample, + FeatureStats, + collate_feature_samples, + fit_feature_stats, + load_feature_samples, +) +from .experiment_probes import ( + RetrievalProjection, + run_frozen_emotion_probe, + run_reconstruction_probe, + run_retrieval_probe, +) +from .metrics import ( + attention_row_similarity, + alignment_trajectory, + attention_width80, + monotonicity_violation_rate, + normalized_attention_entropy, +) +from .models import SharedLatentTimeline, TextAnchoredCrossAttention +from .types import AlignmentOutput, MODALITIES + + +class AlignmentReconstructor(nn.Module): + """Shared M3/M4 training decoder: predict one stream from the other two.""" + + def __init__(self, hidden_size: int = 128, dropout: float = 0.1) -> None: + super().__init__() + self.decoders = nn.ModuleDict( + { + target: nn.Sequential( + nn.Linear(hidden_size * 2, hidden_size), + nn.GELU(), + nn.Dropout(dropout), + nn.Linear(hidden_size, hidden_size), + ) + for target in MODALITIES + } + ) + + def forward(self, target: str, sources: Mapping[str, Tensor], mask: Tensor) -> Tensor: + values = [ + sources[name].masked_fill(mask.unsqueeze(-1), 0.0) + for name in MODALITIES + if name != target + ] + return self.decoders[target](torch.cat(values, dim=-1)) + + +def _seed_everything(seed: int) -> None: + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + if torch.cuda.is_available(): + torch.cuda.manual_seed_all(seed) + if hasattr(torch.backends, "cudnn"): + torch.backends.cudnn.deterministic = True + torch.backends.cudnn.benchmark = False + + +def _batches( + samples: Sequence[FeatureSample], batch_size: int, *, shuffle: bool, rng: np.random.Generator +) -> list[list[FeatureSample]]: + if shuffle: + order = rng.permutation(len(samples)).tolist() + else: + order = list(range(len(samples))) + return [[samples[index] for index in order[start : start + batch_size]] + for start in range(0, len(order), batch_size)] + + +def _training_objective( + output: AlignmentOutput, + sequences: Mapping[str, Any], + durations: Tensor, + decoder: AlignmentReconstructor, + generator: torch.Generator, + *, + method: str = "M3", + loss_variant: str = "v1", +) -> tuple[Tensor, dict[str, Tensor]]: + reconstruction_terms = [] + batch_size, grid_size = output.aligned["text"].shape[:2] + for target in MODALITIES: + mask = make_block_mask( + batch_size, + grid_size, + 0.2, + output.aligned[target].device, + generator=generator, + ) + prediction = decoder(target, output.aligned, mask) + reconstruction_terms.append( + nn.functional.smooth_l1_loss(prediction[mask], output.aligned[target][mask]) + ) + reconstruction = torch.stack(reconstruction_terms).mean() + times = {name: sequences[name].times for name in MODALITIES} + variant_weights = { + "v1": (0.0, 0.0, 0.0), + "v2_a": (5.0, 0.0, 0.0), + "v2_b": (5.0, 0.5, 0.0), + "v2_c": (5.0, 0.5, 10.0), + } + if loss_variant not in variant_weights: + raise ValueError(f"unknown loss variant: {loss_variant}") + lambda_span, lambda_div, lambda_band = variant_weights[loss_variant] + grid_size = output.weights["text"].shape[1] + if method == "M3": + text_reference = torch.bmm( + output.weights["text"], sequences["text"].times.unsqueeze(-1) + ).squeeze(-1) + text_reference = text_reference / durations[:, None].clamp_min(1e-8) + band_targets = {"audio": text_reference, "vision": text_reference} + diversity_modalities = ("audio", "vision") + else: + centers = ( + torch.arange(grid_size, dtype=durations.dtype, device=durations.device) + 0.5 + ) / grid_size + reference = centers.unsqueeze(0).expand(durations.shape[0], -1) + band_targets = {name: reference for name in MODALITIES} + diversity_modalities = MODALITIES + from .losses import alignment_training_loss + + return alignment_training_loss( + output, + times, + durations, + reconstruction, + lambda_rec=1.0, + lambda_con=1.0, + lambda_mono=0.1, + lambda_span=lambda_span, + lambda_div=lambda_div, + lambda_band=lambda_band, + epsilon=0.02, + minimum_span=0.7, + coverage_modalities=diversity_modalities, + diversity_modalities=diversity_modalities, + diversity_min_separation=6, + band_targets=band_targets, + band_margin=0.1, + ) + + +def _make_learned_model( + method: str, + dimensions: Mapping[str, int], + grid_size: int, + hidden_size: int, + heads: int, + dropout: float, +) -> nn.Module: + if method == "M3": + return TextAnchoredCrossAttention( + dimensions, + grid_size=grid_size, + hidden_size=hidden_size, + heads=heads, + dropout=dropout, + ) + if method == "M4": + return SharedLatentTimeline( + dimensions, + grid_size=grid_size, + hidden_size=hidden_size, + heads=heads, + dropout=dropout, + ) + raise ValueError(f"unknown learned method: {method}") + + +def _fit_learned_model( + method: str, + train_samples: Sequence[FeatureSample], + val_samples: Sequence[FeatureSample], + stats: FeatureStats, + *, + device: torch.device, + seed: int, + grid_size: int, + hidden_size: int, + heads: int, + dropout: float, + batch_size: int, + max_epochs: int, + patience: int, + learning_rate: float, + checkpoint_path: Path, + loss_variant: str = "v1", +) -> tuple[nn.Module, dict[str, Any]]: + _seed_everything(seed) + dimensions = {name: train_samples[0].features[name].shape[1] for name in MODALITIES} + model = _make_learned_model(method, dimensions, grid_size, hidden_size, heads, dropout).to(device) + decoder = AlignmentReconstructor(hidden_size, dropout).to(device) + optimizer = torch.optim.AdamW( + [*model.parameters(), *decoder.parameters()], lr=learning_rate, weight_decay=1e-4 + ) + rng = np.random.default_rng(seed) + train_mask_generator = torch.Generator(device=device) + train_mask_generator.manual_seed(seed + 31) + history: list[dict[str, float]] = [] + best_loss = math.inf + best_epoch = 0 + best_model: dict[str, Tensor] | None = None + best_decoder: dict[str, Tensor] | None = None + patience_used = 0 + + for epoch in range(1, max_epochs + 1): + model.train() + decoder.train() + train_total = 0.0 + train_count = 0 + for batch_samples in _batches(train_samples, batch_size, shuffle=True, rng=rng): + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences) + total, _ = _training_objective( + output, + sequences, + durations, + decoder, + train_mask_generator, + method=method, + loss_variant=loss_variant, + ) + if not torch.isfinite(total): + raise FloatingPointError(f"non-finite {method} objective at epoch {epoch}") + optimizer.zero_grad(set_to_none=True) + total.backward() + nn.utils.clip_grad_norm_([*model.parameters(), *decoder.parameters()], 1.0) + optimizer.step() + train_total += float(total.detach().item()) * len(batch_samples) + train_count += len(batch_samples) + + model.eval() + decoder.eval() + val_generator = torch.Generator(device=device) + val_generator.manual_seed(seed + 99991) + val_total = 0.0 + val_count = 0 + val_metric_sums: dict[str, float] = defaultdict(float) + with torch.no_grad(): + for batch_samples in _batches(val_samples, batch_size, shuffle=False, rng=rng): + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences) + total, parts = _training_objective( + output, + sequences, + durations, + decoder, + val_generator, + method=method, + loss_variant=loss_variant, + ) + count = len(batch_samples) + val_total += float(total.item()) * count + val_count += count + for key, value in parts.items(): + val_metric_sums[key] += float(value.item()) * count + for name in MODALITIES: + val_metric_sums[f"c_row_{name}"] += float( + attention_row_similarity(output.weights[name]).mean().item() + ) * count + val_metric_sums[f"c_far_{name}"] += float( + attention_row_similarity(output.weights[name], min_separation=6) + .mean() + .item() + ) * count + val_mean = val_total / max(val_count, 1) + history.append( + { + "epoch": float(epoch), + "train_total": train_total / max(train_count, 1), + "validation_total": val_mean, + **{ + f"validation_{key}": value / max(val_count, 1) + for key, value in val_metric_sums.items() + }, + } + ) + if val_mean < best_loss - 1e-6: + best_loss = val_mean + best_epoch = epoch + best_model = {key: value.detach().cpu().clone() for key, value in model.state_dict().items()} + best_decoder = { + key: value.detach().cpu().clone() for key, value in decoder.state_dict().items() + } + patience_used = 0 + else: + patience_used += 1 + if patience_used >= patience: + break + + if best_model is None or best_decoder is None: + raise RuntimeError(f"{method} training did not produce a finite checkpoint") + model.load_state_dict(best_model) + decoder.load_state_dict(best_decoder) + model.eval() + decoder.eval() + checkpoint_path.parent.mkdir(parents=True, exist_ok=True) + torch.save( + { + "method": method, + "seed": seed, + "loss_variant": loss_variant, + "best_epoch": best_epoch, + "best_validation_objective": best_loss, + "model_state_dict": best_model, + "training_decoder_state_dict": best_decoder, + "history": history, + }, + checkpoint_path, + ) + return model, { + "best_epoch": best_epoch, + "best_validation_objective": best_loss, + "history": history, + "best_validation_metrics": history[best_epoch - 1], + "checkpoint": str(checkpoint_path), + } + + +def _baseline_output( + method: str, + sequences: Mapping[str, Any], + durations: Tensor, + word_intervals: Sequence[Tensor], + grid_size: int, +) -> AlignmentOutput: + if method == "M1": + return align_forced_timestamps(sequences, word_intervals, grid_size) + if method == "M2": + return align_fixed_windows(sequences, durations, grid_size) + raise ValueError(f"not a fixed baseline: {method}") + + +def _alignment_rows( + method: str, + seed_label: str, + fold: int, + samples: Sequence[FeatureSample], + output: AlignmentOutput, + device: torch.device, + epsilon: float, +) -> list[dict[str, Any]]: + rows = [] + for index, sample in enumerate(samples): + for name in MODALITIES: + length = len(sample.times[name]) + weights = output.weights[name][index : index + 1, :, :length] + times = torch.as_tensor(sample.times[name], dtype=torch.float32, device=device)[None] + valid = torch.as_tensor(sample.valid[name], dtype=torch.bool, device=device)[None] + duration = torch.tensor([sample.duration_s], dtype=torch.float32, device=device) + trajectory = alignment_trajectory(weights, times, duration) + mvr = monotonicity_violation_rate(trajectory, epsilon) + entropy = normalized_attention_entropy(weights, valid) + width = attention_width80(weights) + rows.append( + { + "method": method, + "seed": seed_label, + "fold": fold, + "sample_id": sample.sample_id, + "modality": name, + "mvr": float(mvr[0].item()), + "normalized_entropy": float(entropy.mean().item()), + "width80_source_positions": float(width.float().mean().item()), + "c_row": float(attention_row_similarity(weights).mean().item()), + "c_far": float( + attention_row_similarity(weights, min_separation=6).mean().item() + ), + "expected_time_start_s": float(trajectory[0, 0].item() * sample.duration_s), + "expected_time_end_s": float(trajectory[0, -1].item() * sample.duration_s), + "trajectory_span_fraction": float((trajectory[0, -1] - trajectory[0, 0]).item()), + } + ) + return rows + + +def _collect_representations( + method: str, + samples: Sequence[FeatureSample], + stats: FeatureStats, + *, + device: torch.device, + grid_size: int, + batch_size: int, + model: nn.Module | None = None, +) -> tuple[dict[str, dict[str, np.ndarray]], dict[str, dict[str, np.ndarray]]]: + aligned_by_id: dict[str, dict[str, np.ndarray]] = {} + weights_by_id: dict[str, dict[str, np.ndarray]] = {} + rng = np.random.default_rng(0) + if model is not None: + model.eval() + with torch.no_grad(): + for batch_samples in _batches(samples, batch_size, shuffle=False, rng=rng): + sequences, durations, intervals = collate_feature_samples(batch_samples, stats, device) + if method in {"M1", "M2"}: + output = _baseline_output(method, sequences, durations, intervals, grid_size) + elif model is not None: + output = model(sequences) + else: + raise ValueError(f"a trained model is required for {method}") + for index, sample in enumerate(batch_samples): + aligned: dict[str, np.ndarray] = {} + weights: dict[str, np.ndarray] = {} + for name in MODALITIES: + length = len(sample.features[name]) + matrix = output.weights[name][index, :, :length] + source = sequences[name].features[index, :length] + pooled = matrix.to(source.dtype) @ source + aligned[name] = pooled.detach().cpu().numpy().astype(np.float32, copy=False) + weights[name] = matrix.detach().cpu().numpy().astype(np.float32, copy=False) + aligned_by_id[sample.sample_id] = aligned + weights_by_id[sample.sample_id] = weights + return aligned_by_id, weights_by_id + + +def _save_alignment( + output_dir: Path, + method: str, + seed_label: str, + sample: FeatureSample, + weights: Mapping[str, np.ndarray], +) -> None: + path = output_dir / "alignments" / method / f"seed_{seed_label}" / ( + sample.sample_id.replace("/", "__") + ".npz" + ) + path.parent.mkdir(parents=True, exist_ok=True) + values: dict[str, np.ndarray] = {"sample_id": np.asarray(sample.sample_id)} + for name in MODALITIES: + trajectory = weights[name] @ sample.times[name] / max(sample.duration_s, 1e-8) + values[f"weights_{name}"] = weights[name] + values[f"times_{name}_s"] = sample.times[name].astype(np.float32, copy=False) + values[f"valid_{name}"] = sample.valid[name] + values[f"trajectory_{name}"] = trajectory.astype(np.float32, copy=False) + np.savez_compressed(path, **values) + + +def _write_csv(path: Path, rows: Sequence[Mapping[str, Any]]) -> None: + if not rows: + return + path.parent.mkdir(parents=True, exist_ok=True) + columns = list(dict.fromkeys(key for row in rows for key in row)) + with path.open("w", encoding="utf-8-sig", newline="") as file: + writer = csv.DictWriter(file, fieldnames=columns, extrasaction="ignore") + writer.writeheader() + writer.writerows(rows) + + +def _group_summary( + rows: Sequence[Mapping[str, Any]], group_columns: Sequence[str], metric_columns: Sequence[str] +) -> list[dict[str, Any]]: + groups: dict[tuple[Any, ...], list[Mapping[str, Any]]] = defaultdict(list) + for row in rows: + groups[tuple(row[column] for column in group_columns)].append(row) + output = [] + for key, values in groups.items(): + summary: dict[str, Any] = dict(zip(group_columns, key)) + summary["n"] = len(values) + for metric in metric_columns: + numbers = [float(row[metric]) for row in values if row.get(metric) not in (None, "")] + numbers = [value for value in numbers if math.isfinite(value)] + if numbers: + summary[f"{metric}_mean"] = statistics.fmean(numbers) + summary[f"{metric}_std"] = statistics.stdev(numbers) if len(numbers) > 1 else 0.0 + output.append(summary) + return output + + +def _comparison_table(summaries: Mapping[str, Sequence[Mapping[str, Any]]]) -> list[dict[str, Any]]: + """Make one compact, multi-metric table without inventing a composite score.""" + alignment = {(row["method"], row["modality"]): row for row in summaries["alignment"]} + retrieval = {(row["method"], row["direction"]): row for row in summaries["retrieval"]} + reconstruction = { + (row["method"], row["target_modality"]): row for row in summaries["reconstruction"] + } + emotion = {row["method"]: row for row in summaries["emotion"]} + table: list[dict[str, Any]] = [] + for method in ("M1", "M2", "M3", "M4"): + row: dict[str, Any] = {"method": method} + for modality in MODALITIES: + metrics = alignment[(method, modality)] + row[f"mvr_{modality}"] = metrics.get("mvr_mean") + row[f"entropy_{modality}"] = metrics.get("normalized_entropy_mean") + row[f"trajectory_span_{modality}"] = metrics.get("trajectory_span_fraction_mean") + for direction in ("text_to_audio", "text_to_vision"): + metrics = retrieval[(method, direction)] + row[f"r_at_1_{direction}"] = metrics.get("r_at_1_mean") + row[f"r_at_5_{direction}"] = metrics.get("r_at_5_mean") + for modality in MODALITIES: + metrics = reconstruction[(method, modality)] + row[f"reconstruction_mae_{modality}"] = metrics.get("mae_standardized_mean") + for metric in ("accuracy", "macro_f1", "mae", "pearson"): + row[f"emotion_{metric}"] = emotion[method].get(f"{metric}_mean") + table.append(row) + return table + + +def _make_figures( + output_dir: Path, + example_id: str, + example_sample: FeatureSample, + example_weights: Mapping[str, Mapping[str, np.ndarray]], + grid_size: int, +) -> None: + method_order = ("M1", "M2", "M3", "M4") + fig, axes = plt.subplots(4, 3, figsize=(15, 13), constrained_layout=True) + for row, method in enumerate(method_order): + if method not in example_weights: + continue + for col, name in enumerate(MODALITIES): + ax = axes[row, col] + matrix = example_weights[method][name] + image = ax.imshow(matrix, origin="lower", aspect="auto", interpolation="nearest", cmap="magma") + ax.set_title(f"{method} · {name}") + ax.set_xlabel("source position") + ax.set_ylabel("shared grid slot") + ax.set_yticks(np.linspace(0, grid_size - 1, 5, dtype=int)) + fig.colorbar(image, ax=ax, fraction=0.046, pad=0.04) + fig.suptitle(f"Alignment matrices on held-out sample {example_id}") + fig.savefig(output_dir / "typical_alignment_heatmaps.png", dpi=170) + plt.close(fig) + + fig, axes = plt.subplots(2, 2, figsize=(13, 9), constrained_layout=True) + x = (np.arange(grid_size, dtype=np.float32) + 0.5) / grid_size + for ax, method in zip(axes.flat, method_order): + for name in MODALITIES: + matrix = example_weights[method][name] + duration = example_sample.duration_s + trajectory = matrix @ example_sample.times[name] / max(duration, 1e-8) + ax.plot(x, trajectory, label=name) + ax.plot([0, 1], [0, 1], linestyle="--", color="black", alpha=0.5, label="uniform-time reference") + ax.set_title(method) + ax.set_xlabel("shared-grid position") + ax.set_ylabel("expected source time / clip duration") + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.grid(alpha=0.2) + axes[0, 0].legend(fontsize=8) + fig.suptitle(f"Alignment trajectories on held-out sample {example_id}") + fig.savefig(output_dir / "typical_alignment_trajectories.png", dpi=170) + plt.close(fig) + + +def run(args: argparse.Namespace) -> dict[str, Any]: + start_time = time.time() + _seed_everything(args.seeds[0]) + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is not available in this WSL environment") + + samples = load_feature_samples(args.feature_dir, args.manifest) + if len(samples) != args.expected_samples: + raise ValueError(f"expected {args.expected_samples} samples, found {len(samples)}") + groups = [sample.group_id for sample in samples] + if len(set(groups)) < args.folds: + raise ValueError("fewer video_id groups than requested folds") + split_iter = GroupKFold(n_splits=args.folds).split(np.zeros(len(samples)), groups=groups) + splits = [(train.tolist(), val.tolist()) for train, val in split_iter] + splits_json = [ + { + "fold": fold + 1, + "train_sample_ids": [samples[index].sample_id for index in train], + "validation_sample_ids": [samples[index].sample_id for index in val], + "train_video_ids": sorted({samples[index].group_id for index in train}), + "validation_video_ids": sorted({samples[index].group_id for index in val}), + } + for fold, (train, val) in enumerate(splits) + ] + args.output_dir.mkdir(parents=True, exist_ok=True) + print( + f"[start] samples={len(samples)} groups={len(set(groups))} folds={args.folds} " + f"seeds={args.seeds} device={device}", + flush=True, + ) + (args.output_dir / "splits.json").write_text( + json.dumps(splits_json, ensure_ascii=False, indent=2), encoding="utf-8" + ) + + alignment_rows: list[dict[str, Any]] = [] + retrieval_rows: list[dict[str, Any]] = [] + reconstruction_rows: list[dict[str, Any]] = [] + emotion_rows: list[dict[str, Any]] = [] + training_rows: list[dict[str, Any]] = [] + examples: dict[str, dict[str, Mapping[str, np.ndarray]]] = defaultdict(dict) + sample_by_id = {sample.sample_id: sample for sample in samples} + preferred_example = args.example_id if args.example_id in sample_by_id else samples[0].sample_id + preferred_seed = args.seeds[0] + example_sample = sample_by_id[preferred_example] + + for fold_index, (train_indices, val_indices) in enumerate(splits, start=1): + train_samples = [samples[index] for index in train_indices] + val_samples = [samples[index] for index in val_indices] + stats = fit_feature_stats(train_samples) + fold_output = args.output_dir / f"fold_{fold_index:02d}" + print( + f"[fold {fold_index}/{args.folds}] train={len(train_samples)} validation={len(val_samples)} " + f"train_video_ids={len({sample.group_id for sample in train_samples})} " + f"validation_video_ids={len({sample.group_id for sample in val_samples})}", + flush=True, + ) + + # M1 and M2 are deterministic methods with no learned alignment loss. + for method in ("M1", "M2"): + print(f"[fold {fold_index}] evaluate {method} and train identical probes", flush=True) + train_aligned, _ = _collect_representations( + method, + train_samples, + stats, + device=device, + grid_size=args.grid_size, + batch_size=args.batch_size, + ) + val_aligned, val_weights = _collect_representations( + method, + val_samples, + stats, + device=device, + grid_size=args.grid_size, + batch_size=args.batch_size, + ) + combined = {**train_aligned, **val_aligned} + rng = np.random.default_rng(args.seeds[0] + fold_index) + for batch_samples in _batches(val_samples, args.batch_size, shuffle=False, rng=rng): + sequences, durations, intervals = collate_feature_samples(batch_samples, stats, device) + output = _baseline_output(method, sequences, durations, intervals, args.grid_size) + alignment_rows.extend( + _alignment_rows(method, "fixed", fold_index, batch_samples, output, device, args.mvr_epsilon) + ) + for sample in val_samples: + _save_alignment(args.output_dir, method, "fixed", sample, val_weights[sample.sample_id]) + if sample.sample_id == preferred_example: + examples[sample.sample_id][method] = val_weights[sample.sample_id] + probe_seed = args.seeds[0] + fold_index * 100 + retrieval_rows.extend( + { + "method": method, + "seed": "fixed", + "fold": fold_index, + **row, + } + for row in run_retrieval_probe( + [sample.sample_id for sample in train_samples], + [sample.sample_id for sample in val_samples], + combined, + device=device, + seed=probe_seed, + epochs=args.retrieval_probe_epochs, + batch_size=args.probe_batch_size, + ) + ) + reconstruction_rows.extend( + {"method": method, "seed": "fixed", "fold": fold_index, **row} + for row in run_reconstruction_probe( + [sample.sample_id for sample in train_samples], + [sample.sample_id for sample in val_samples], + combined, + device=device, + seed=probe_seed + 1, + ratio=args.mask_ratio, + epochs=args.reconstruction_probe_epochs, + batch_size=args.probe_batch_size, + ) + ) + emotion_rows.append( + { + "method": method, + "seed": "fixed", + "fold": fold_index, + **run_frozen_emotion_probe(train_samples, val_samples, combined), + } + ) + + # M3/M4 share one unsupervised objective, split, and training budget. + for seed in args.seeds: + for method in ("M3", "M4"): + print(f"[fold {fold_index}] train {method}, seed={seed}", flush=True) + checkpoint = fold_output / f"seed_{seed}" / f"{method}.pt" + model, training_info = _fit_learned_model( + method, + train_samples, + val_samples, + stats, + device=device, + seed=seed + fold_index * 1009, + grid_size=args.grid_size, + hidden_size=args.hidden_size, + heads=args.heads, + dropout=args.dropout, + batch_size=args.batch_size, + max_epochs=args.epochs, + patience=args.patience, + learning_rate=args.learning_rate, + checkpoint_path=checkpoint, + ) + training_rows.append( + { + "method": method, + "seed": seed, + "fold": fold_index, + "best_epoch": training_info["best_epoch"], + "best_validation_objective": training_info["best_validation_objective"], + "checkpoint": training_info["checkpoint"], + } + ) + print( + f"[fold {fold_index}] {method}, seed={seed} best_epoch={training_info['best_epoch']} " + f"val_objective={training_info['best_validation_objective']:.5f}; running frozen probes", + flush=True, + ) + train_aligned, _ = _collect_representations( + method, + train_samples, + stats, + device=device, + grid_size=args.grid_size, + batch_size=args.batch_size, + model=model, + ) + val_aligned, val_weights = _collect_representations( + method, + val_samples, + stats, + device=device, + grid_size=args.grid_size, + batch_size=args.batch_size, + model=model, + ) + combined = {**train_aligned, **val_aligned} + rng = np.random.default_rng(seed + fold_index) + for batch_samples in _batches(val_samples, args.batch_size, shuffle=False, rng=rng): + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences) + alignment_rows.extend( + _alignment_rows(method, str(seed), fold_index, batch_samples, output, device, args.mvr_epsilon) + ) + for sample in val_samples: + _save_alignment(args.output_dir, method, str(seed), sample, val_weights[sample.sample_id]) + if sample.sample_id == preferred_example and seed == preferred_seed: + examples[sample.sample_id][method] = val_weights[sample.sample_id] + + probe_seed = seed + fold_index * 100 + (3 if method == "M3" else 7) + retrieval_rows.extend( + { + "method": method, + "seed": seed, + "fold": fold_index, + **row, + } + for row in run_retrieval_probe( + [sample.sample_id for sample in train_samples], + [sample.sample_id for sample in val_samples], + combined, + device=device, + seed=probe_seed, + epochs=args.retrieval_probe_epochs, + batch_size=args.probe_batch_size, + ) + ) + reconstruction_rows.extend( + {"method": method, "seed": seed, "fold": fold_index, **row} + for row in run_reconstruction_probe( + [sample.sample_id for sample in train_samples], + [sample.sample_id for sample in val_samples], + combined, + device=device, + seed=probe_seed + 1, + ratio=args.mask_ratio, + epochs=args.reconstruction_probe_epochs, + batch_size=args.probe_batch_size, + ) + ) + emotion_rows.append( + { + "method": method, + "seed": seed, + "fold": fold_index, + **run_frozen_emotion_probe(train_samples, val_samples, combined), + } + ) + del model + if device.type == "cuda": + torch.cuda.empty_cache() + + _write_csv(args.output_dir / "alignment_metrics.csv", alignment_rows) + _write_csv(args.output_dir / "retrieval_probe_metrics.csv", retrieval_rows) + _write_csv(args.output_dir / "reconstruction_probe_metrics.csv", reconstruction_rows) + _write_csv(args.output_dir / "frozen_emotion_probe_metrics.csv", emotion_rows) + _write_csv(args.output_dir / "training_summary.csv", training_rows) + + summaries = { + "alignment": _group_summary( + alignment_rows, + ("method", "modality"), + ("mvr", "normalized_entropy", "width80_source_positions", "expected_time_start_s", "expected_time_end_s", "trajectory_span_fraction"), + ), + "retrieval": _group_summary( + retrieval_rows, + ("method", "direction"), + ("r_at_1", "r_at_5", "mrr"), + ), + "reconstruction": _group_summary( + reconstruction_rows, + ("method", "target_modality"), + ("mae_standardized", "smooth_l1_standardized"), + ), + "emotion": _group_summary( + emotion_rows, + ("method",), + ("accuracy", "macro_f1", "mae", "pearson"), + ), + } + (args.output_dir / "summary.json").write_text( + json.dumps(summaries, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + for name, rows in summaries.items(): + _write_csv(args.output_dir / f"{name}_summary.csv", rows) + comparison_table = _comparison_table(summaries) + _write_csv(args.output_dir / "comparison_summary.csv", comparison_table) + + if preferred_example in examples and set(examples[preferred_example]) == {"M1", "M2", "M3", "M4"}: + _make_figures(args.output_dir, preferred_example, example_sample, examples[preferred_example], args.grid_size) + + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "sample_count": len(samples), + "group_count": len(set(groups)), + "folds": args.folds, + "seeds": args.seeds, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "parameters": { + "grid_size": args.grid_size, + "hidden_size": args.hidden_size, + "heads": args.heads, + "dropout": args.dropout, + "batch_size": args.batch_size, + "epochs_max": args.epochs, + "early_stopping_patience": args.patience, + "learning_rate": args.learning_rate, + "mask_ratio": args.mask_ratio, + "retrieval_probe_epochs": args.retrieval_probe_epochs, + "reconstruction_probe_epochs": args.reconstruction_probe_epochs, + "mvr_epsilon": args.mvr_epsilon, + }, + "objective": "masked reconstruction + cross-modal contrastive + temporal monotonicity; emotion labels unused", + "split_rule": "GroupKFold by group_id/video_id", + "example_sample_id": preferred_example, + "elapsed_seconds": time.time() - start_time, + "interpretation_limits": [ + "Grid-index retrieval is a representation-consistency probe, not independent temporal ground truth.", + "Masked reconstruction uses a decoder trained on the training fold and reports standardized-feature errors.", + "The emotion probe is a small-sample downstream utility check, not a claim of generalization to MOSEI.", + "No human event timestamps are available, so human IoU/MATE is not reported.", + ], + } + (args.output_dir / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8" + ) + (args.output_dir / "README.md").write_text( + "# Q1 method comparison\n\n" + "This folder contains grouped cross-validation results for M1–M4. M1/M2 are fixed rules; M3/M4 are trained without emotion labels. " + "All learned models and probes use training-fold-only feature normalization, and folds are grouped by `video_id`.\n\n" + "`alignment_metrics.csv` reports expected-time trajectories, monotonicity, attention entropy, and width diagnostics. " + "`retrieval_probe_metrics.csv` uses a separately trained linear projection probe; its grid-index positives are not independent temporal ground truth. " + "`reconstruction_probe_metrics.csv` reports held-out masked reconstruction error in training-fold standardized feature units. " + "`frozen_emotion_probe_metrics.csv` is a small-sample downstream utility check.\n\n" + "No human event-time annotation is present, so the results cannot establish direct human alignment accuracy. " + "See `run_manifest.json` for parameters, seeds, device, and interpretation limits.\n", + encoding="utf-8", + ) + print( + f"[done] elapsed_seconds={manifest['elapsed_seconds']:.1f} output={args.output_dir}", + flush=True, + ) + return manifest + + +def build_parser() -> argparse.ArgumentParser: + project_dir = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser(description="Compare Q1 M1-M4 alignment methods with grouped CV.") + parser.add_argument("--feature-dir", type=Path, default=project_dir / "outputs/q1_features/features") + parser.add_argument("--manifest", type=Path, default=project_dir / "outputs/audit/manifest.csv") + parser.add_argument("--output-dir", type=Path, default=project_dir / "outputs/method_comparison") + parser.add_argument("--device", default="auto", help="auto, cpu, or a torch device such as cuda:0") + parser.add_argument("--expected-samples", type=int, default=100) + parser.add_argument("--folds", type=int, default=5) + parser.add_argument("--seeds", type=int, nargs="+", default=[42, 3407, 2026]) + parser.add_argument("--grid-size", type=int, default=50) + parser.add_argument("--hidden-size", type=int, default=128) + parser.add_argument("--heads", type=int, default=4) + parser.add_argument("--dropout", type=float, default=0.1) + parser.add_argument("--batch-size", type=int, default=8) + parser.add_argument("--probe-batch-size", type=int, default=16) + parser.add_argument("--epochs", type=int, default=50) + parser.add_argument("--patience", type=int, default=8) + parser.add_argument("--learning-rate", type=float, default=1e-4) + parser.add_argument("--mask-ratio", type=float, default=0.2) + parser.add_argument("--retrieval-probe-epochs", type=int, default=20) + parser.add_argument("--reconstruction-probe-epochs", type=int, default=25) + parser.add_argument("--mvr-epsilon", type=float, default=0.02) + parser.add_argument("--example-id", default="-tPCytz4rww/12") + return parser + + +def main() -> int: + args = build_parser().parse_args() + manifest = run(args) + print(json.dumps(manifest, ensure_ascii=False, indent=2)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/deep_learning/Q1/q1/correspondence_eval.py b/deep_learning/Q1/q1/correspondence_eval.py new file mode 100644 index 0000000..d3f26b7 --- /dev/null +++ b/deep_learning/Q1/q1/correspondence_eval.py @@ -0,0 +1,773 @@ +"""Evaluate same-time cross-modal correspondence against within-clip shifts. + +The alignment model is frozen. A small train-only linear projection probe maps +the aligned raw features into a shared space using diagonal-versus-off-diagonal +InfoNCE within each training clip. All reported correspondence scores are then +computed on held-out video_id groups. +""" + +from __future__ import annotations + +import argparse +import csv +import json +import platform +import random +import time +from collections import defaultdict +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Mapping, Sequence + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import torch +import torch.nn.functional as F +from sklearn.metrics import roc_auc_score +from torch import Tensor, nn + +from .compare_methods import _collect_representations +from .experiment_data import ( + FeatureSample, + FeatureStats, + collate_feature_samples, + fit_feature_stats, + load_feature_samples, +) +from .models import SharedLatentTimeline, TextAnchoredCrossAttention +from .types import MODALITIES + + +GRID_SIZE = 50 +HIDDEN_SIZE = 128 +HEADS = 4 +OUTPUT_SIZE = 64 +PAIRINGS = (("text", "audio"), ("text", "vision"), ("audio", "vision")) +METHODS = ("M1", "M2", "M3_noSourceTime", "M3_sourceTime", "M4_noSourceTime", "M4_sourceTime") +CURVE_MAX_SHIFT = 10 +NEGATIVE_RADIUS = 2 + + +class CorrespondenceProjection(nn.Module): + """Equal-output-size modality heads used only as a frozen-feature probe.""" + + def __init__(self, dimensions: Mapping[str, int], output_size: int = OUTPUT_SIZE) -> None: + super().__init__() + self.projections = nn.ModuleDict( + {name: nn.Linear(dimensions[name], output_size, bias=False) for name in MODALITIES} + ) + + def forward(self, values: Mapping[str, Tensor]) -> dict[str, Tensor]: + return { + name: F.normalize(self.projections[name](values[name]), dim=-1) + for name in MODALITIES + } + + +def _write_csv(path: Path, rows: Sequence[Mapping[str, Any]]) -> None: + if not rows: + return + path.parent.mkdir(parents=True, exist_ok=True) + fields = list(dict.fromkeys(key for row in rows for key in row)) + with path.open("w", newline="", encoding="utf-8-sig") as handle: + writer = csv.DictWriter(handle, fieldnames=fields, extrasaction="ignore") + writer.writeheader() + writer.writerows(rows) + + +def _batches(samples: Sequence[FeatureSample], batch_size: int): + for start in range(0, len(samples), batch_size): + yield list(samples[start : start + batch_size]) + + +def _make_model(method: str, dimensions: Mapping[str, int], source_time: bool) -> nn.Module: + if method == "M3": + return TextAnchoredCrossAttention( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + source_time_encoding=source_time, + ) + return SharedLatentTimeline( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + absolute_position_encoding=True, + source_time_encoding=source_time, + ) + + +def _checkpoint_path(root: Path, fold: int, variant: str) -> Path: + if fold == 1: + return root / variant / "checkpoint.pt" + return root / f"fold_{fold:02d}" / variant / "checkpoint.pt" + + +def _collect_learned_representations( + *, + method_name: str, + fold: int, + train_samples: Sequence[FeatureSample], + validation_samples: Sequence[FeatureSample], + stats: FeatureStats, + checkpoint_root: Path, + device: torch.device, + batch_size: int, +) -> dict[str, dict[str, np.ndarray]]: + method = method_name[:2] + source_time = method_name.endswith("_sourceTime") + checkpoint_path = _checkpoint_path(checkpoint_root, fold, method_name) + if not checkpoint_path.is_file(): + raise FileNotFoundError( + f"missing {method_name} fold {fold} checkpoint: {checkpoint_path}; " + "run q1.alignment_heldout_debug for this fold first" + ) + checkpoint = torch.load(checkpoint_path, map_location=device, weights_only=False) + if checkpoint.get("variant") != method_name: + raise ValueError(f"checkpoint variant does not match {method_name}: {checkpoint_path}") + if bool(checkpoint.get("source_time_encoding")) != source_time: + raise ValueError(f"checkpoint source-time setting does not match {method_name}: {checkpoint_path}") + expected_train = {sample.sample_id for sample in train_samples} + expected_validation = {sample.sample_id for sample in validation_samples} + if set(checkpoint.get("train_sample_ids", [])) != expected_train: + raise ValueError(f"checkpoint training IDs do not match split for {method_name}, fold {fold}") + if set(checkpoint.get("validation_sample_ids", [])) != expected_validation: + raise ValueError(f"checkpoint validation IDs do not match split for {method_name}, fold {fold}") + + dimensions = {name: train_samples[0].features[name].shape[1] for name in MODALITIES} + model = _make_model(method, dimensions, source_time).to(device) + model.load_state_dict(checkpoint["model_state_dict"], strict=True) + model.eval() + result: dict[str, dict[str, np.ndarray]] = {} + with torch.no_grad(): + for batch_samples in _batches([*train_samples, *validation_samples], batch_size): + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences, durations) if source_time else model(sequences) + for index, sample in enumerate(batch_samples): + sample_values: dict[str, np.ndarray] = {} + for name in MODALITIES: + length = len(sample.features[name]) + weights = output.weights[name][index, :, :length] + source = sequences[name].features[index, :length] + pooled = weights.to(source.dtype) @ source + if pooled.shape[0] != GRID_SIZE: + raise ValueError(f"unexpected grid size for {sample.sample_id}/{name}") + sample_values[name] = pooled.detach().cpu().numpy().astype(np.float32, copy=False) + result[sample.sample_id] = sample_values + del model + if device.type == "cuda": + torch.cuda.empty_cache() + return result + + +def _stack_ids( + sample_ids: Sequence[str], + aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], + device: torch.device, +) -> dict[str, Tensor]: + return { + name: torch.as_tensor( + np.stack([aligned_by_id[sample_id][name] for sample_id in sample_ids]), + dtype=torch.float32, + device=device, + ) + for name in MODALITIES + } + + +def _within_clip_infonce( + projected: Mapping[str, Tensor], temperature: float +) -> Tensor: + """Symmetric diagonal-vs-shifted loss; negatives stay inside each clip.""" + batch_size, grid_size = projected["text"].shape[:2] + target = torch.arange(grid_size, device=projected["text"].device).repeat(batch_size) + losses = [] + for left_index, left_name in enumerate(MODALITIES): + for right_name in MODALITIES[left_index + 1 :]: + scores = torch.einsum( + "bkd,bld->bkl", projected[left_name], projected[right_name] + ) / temperature + forward = F.cross_entropy(scores.reshape(-1, grid_size), target) + reverse = F.cross_entropy(scores.transpose(1, 2).reshape(-1, grid_size), target) + losses.append((forward + reverse) / 2) + return torch.stack(losses).mean() + + +def _fit_probe( + train_ids: Sequence[str], + aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], + *, + device: torch.device, + seed: int, + epochs: int, + batch_size: int, + learning_rate: float, + temperature: float, +) -> tuple[CorrespondenceProjection, list[dict[str, Any]]]: + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + if device.type == "cuda": + torch.cuda.manual_seed_all(seed) + train = _stack_ids(train_ids, aligned_by_id, device) + dimensions = {name: int(train[name].shape[-1]) for name in MODALITIES} + model = CorrespondenceProjection(dimensions).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate, weight_decay=1e-4) + rng = np.random.default_rng(seed) + history: list[dict[str, Any]] = [] + model.train() + for epoch in range(1, epochs + 1): + order = rng.permutation(len(train_ids)) + loss_sum = 0.0 + batches = 0 + for start in range(0, len(order), batch_size): + indexes = torch.as_tensor(order[start : start + batch_size], device=device) + batch = {name: value.index_select(0, indexes) for name, value in train.items()} + loss = _within_clip_infonce(model(batch), temperature) + if not torch.isfinite(loss): + raise FloatingPointError(f"non-finite correspondence probe loss at epoch {epoch}") + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + loss_sum += float(loss.detach().item()) + batches += 1 + history.append({"epoch": epoch, "train_loss": loss_sum / max(batches, 1)}) + return model, history + + +def _shifted_scores(scores: np.ndarray, delta: int) -> np.ndarray: + grid_size = scores.shape[0] + if delta >= 0: + indexes = np.arange(0, grid_size - delta) + return scores[indexes, indexes + delta] + indexes = np.arange(-delta, grid_size) + return scores[indexes, indexes + delta] + + +def _sample_metrics( + *, + method: str, + fold: int, + sample: FeatureSample, + projected: Mapping[str, Tensor], + curve_rows: list[dict[str, Any]], +) -> list[dict[str, Any]]: + rows = [] + for left_name, right_name in PAIRINGS: + left = projected[left_name] + right = projected[right_name] + score = (left @ right.T).detach().cpu().numpy() + grid_size = score.shape[0] + if score.shape != (GRID_SIZE, GRID_SIZE): + raise ValueError(f"expected {GRID_SIZE}x{GRID_SIZE} score matrix") + diagonal = np.diag(score) + negative_mask = np.abs(np.arange(grid_size)[:, None] - np.arange(grid_size)[None, :]) > NEGATIVE_RADIUS + auc = float( + roc_auc_score( + np.concatenate((np.ones(grid_size), np.zeros(int(negative_mask.sum())))), + np.concatenate((diagonal, score[negative_mask])), + ) + ) + far_shifts = [ + _shifted_scores(score, delta).mean() + for delta in range(-CURVE_MAX_SHIFT, CURVE_MAX_SHIFT + 1) + if abs(delta) > NEGATIVE_RADIUS + ] + row: dict[str, Any] = { + "method": method, + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "pair": f"{left_name}_{right_name}", + "same_time_similarity": float(diagonal.mean()), + "shifted_far_similarity": float(np.mean(far_shifts)), + "same_minus_shifted_margin": float(diagonal.mean() - np.mean(far_shifts)), + "matched_vs_shifted_auc": auc, + } + for direction, directed_score in ( + (f"{left_name}_to_{right_name}", score), + (f"{right_name}_to_{left_name}", score.T), + ): + prediction = directed_score.argmax(axis=1) + error = np.abs(prediction - np.arange(grid_size)) + row[f"exact_r1_{direction}"] = float(np.mean(error == 0)) + row[f"within_pm1_r1_{direction}"] = float(np.mean(error <= 1)) + row[f"mase_slots_{direction}"] = float(np.mean(error)) + + for delta in range(-CURVE_MAX_SHIFT, CURVE_MAX_SHIFT + 1): + curve_rows.append( + { + "method": method, + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "pair": f"{left_name}_{right_name}", + "delta": delta, + "similarity": float(_shifted_scores(score, delta).mean()), + } + ) + rows.append(row) + return rows + + +def _cluster_bootstrap( + rows: Sequence[Mapping[str, Any]], + metric: str, + *, + seed: int, + repetitions: int = 2000, +) -> tuple[float, float, float, int]: + grouped: dict[str, list[float]] = defaultdict(list) + for row in rows: + value = float(row[metric]) + if np.isfinite(value): + grouped[str(row["video_id"])].append(value) + groups = np.asarray([np.mean(values) for values in grouped.values()], dtype=np.float64) + if groups.size == 0: + return float("nan"), float("nan"), float("nan"), 0 + mean = float(groups.mean()) + if groups.size == 1: + return mean, mean, mean, 1 + rng = np.random.default_rng(seed) + indexes = rng.integers(0, groups.size, size=(repetitions, groups.size)) + boot = groups[indexes].mean(axis=1) + low, high = np.quantile(boot, [0.025, 0.975]) + return mean, float(low), float(high), int(groups.size) + + +def _summaries( + metric_rows: Sequence[Mapping[str, Any]], + curve_rows: Sequence[Mapping[str, Any]], + *, + seed: int, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + metrics = ( + "same_time_similarity", + "shifted_far_similarity", + "same_minus_shifted_margin", + "matched_vs_shifted_auc", + "exact_r1_text_to_audio", + "within_pm1_r1_text_to_audio", + "mase_slots_text_to_audio", + "exact_r1_audio_to_text", + "within_pm1_r1_audio_to_text", + "mase_slots_audio_to_text", + "exact_r1_text_to_vision", + "within_pm1_r1_text_to_vision", + "mase_slots_text_to_vision", + "exact_r1_vision_to_text", + "within_pm1_r1_vision_to_text", + "mase_slots_vision_to_text", + "exact_r1_audio_to_vision", + "within_pm1_r1_audio_to_vision", + "mase_slots_audio_to_vision", + "exact_r1_vision_to_audio", + "within_pm1_r1_vision_to_audio", + "mase_slots_vision_to_audio", + ) + grouped: dict[tuple[str, str], list[Mapping[str, Any]]] = defaultdict(list) + for row in metric_rows: + grouped[(str(row["method"]), str(row["pair"]))].append(row) + summary_rows = [] + for (method, pair), rows in sorted(grouped.items()): + result: dict[str, Any] = { + "method": method, + "pair": pair, + "clip_count": len(rows), + "video_id_count": len({str(row["video_id"]) for row in rows}), + } + for metric_index, metric in enumerate(metrics): + if metric not in rows[0]: + continue + mean, low, high, _ = _cluster_bootstrap( + rows, + metric, + seed=seed + metric_index + sum(ord(character) for character in method + pair), + ) + result[f"{metric}_mean"] = mean + result[f"{metric}_ci95_low"] = low + result[f"{metric}_ci95_high"] = high + curve_for_group = [ + row for row in curve_rows if row["method"] == method and row["pair"] == pair + ] + curve_by_delta: dict[int, list[dict[str, Any]]] = defaultdict(list) + for row in curve_for_group: + curve_by_delta[int(row["delta"])].append(dict(row)) + mean_curve = { + delta: _cluster_bootstrap( + values, + "similarity", + seed=seed + delta + sum(ord(character) for character in method + pair), + )[0] + for delta, values in curve_by_delta.items() + } + if mean_curve: + result["peak_delta"] = max(mean_curve, key=mean_curve.get) + result["peak_similarity"] = mean_curve[result["peak_delta"]] + summary_rows.append(result) + + curve_summary = [] + curve_groups: dict[tuple[str, str, int], list[Mapping[str, Any]]] = defaultdict(list) + for row in curve_rows: + curve_groups[(str(row["method"]), str(row["pair"]), int(row["delta"]))].append(row) + for (method, pair, delta), rows in sorted(curve_groups.items()): + mean, low, high, group_count = _cluster_bootstrap( + rows, + "similarity", + seed=seed + delta + sum(ord(character) for character in method + pair), + ) + curve_summary.append( + { + "method": method, + "pair": pair, + "delta": delta, + "mean_similarity": mean, + "ci95_low": low, + "ci95_high": high, + "video_id_count": group_count, + } + ) + return summary_rows, curve_summary + + +def _summarize_time_localization( + checkpoint_root: Path, fold_count: int, *, seed: int +) -> list[dict[str, Any]]: + grouped: dict[tuple[str, str], list[dict[str, Any]]] = defaultdict(list) + for fold in range(1, fold_count + 1): + metrics_path = ( + checkpoint_root / "per_sample_metrics.csv" + if fold == 1 + else checkpoint_root / f"fold_{fold:02d}" / "per_sample_metrics.csv" + ) + if not metrics_path.is_file(): + raise FileNotFoundError(f"missing D5 per-sample metrics for fold {fold}: {metrics_path}") + with metrics_path.open("r", newline="", encoding="utf-8-sig") as handle: + for source in csv.DictReader(handle): + sample_id = source["sample_id"] + row: dict[str, Any] = { + "video_id": sample_id.split("/", 1)[0], + "sample_id": sample_id, + "variant": source["variant"], + "modality": source["modality"], + } + for metric in ( + "normalized_entropy", + "trajectory_span", + "gaussian_target_kl", + "mean_absolute_time_center_error", + ): + raw = source.get(metric, "") + if raw not in (None, ""): + value = float(raw) + if np.isfinite(value): + row[metric] = value + grouped[(row["variant"], row["modality"])].append(row) + + metric_names = ( + "normalized_entropy", + "trajectory_span", + "gaussian_target_kl", + "mean_absolute_time_center_error", + ) + results = [] + for (variant, modality), rows in sorted(grouped.items()): + result: dict[str, Any] = { + "variant": variant, + "modality": modality, + "clip_count": len(rows), + "video_id_count": len({row["video_id"] for row in rows}), + } + for index, metric in enumerate(metric_names): + values = [row for row in rows if metric in row] + if not values: + continue + mean, low, high, _ = _cluster_bootstrap( + values, + metric, + seed=seed + index + sum(ord(character) for character in variant + modality), + ) + result[f"{metric}_video_macro_mean"] = mean + result[f"{metric}_ci95_low"] = low + result[f"{metric}_ci95_high"] = high + results.append(result) + return results + + +def _plot_curve(curve_rows: Sequence[Mapping[str, Any]], output_path: Path) -> None: + pairs = tuple(f"{left}_{right}" for left, right in PAIRINGS) + colors = { + "M1": "#555555", + "M2": "#9a9a9a", + "M3_noSourceTime": "#2878b5", + "M3_sourceTime": "#f08a24", + "M4_noSourceTime": "#55a868", + "M4_sourceTime": "#c44e52", + } + fig, axes = plt.subplots(1, 3, figsize=(17, 5), sharey=True) + for axis, pair in zip(axes, pairs, strict=True): + for method in METHODS: + rows = [row for row in curve_rows if row["pair"] == pair and row["method"] == method] + if not rows: + continue + deltas = sorted({int(row["delta"]) for row in rows}) + xs, means, lows, highs = [], [], [], [] + for delta in deltas: + subset = [row for row in rows if int(row["delta"]) == delta] + mean, low, high, _ = _cluster_bootstrap( + subset, + "similarity", + seed=9821 + delta + sum(ord(character) for character in method + pair), + repetitions=1000, + ) + xs.append(delta) + means.append(mean) + lows.append(low) + highs.append(high) + axis.plot(xs, means, marker="o", markersize=3, linewidth=1.6, label=method, color=colors[method]) + axis.fill_between(xs, lows, highs, color=colors[method], alpha=0.10, linewidth=0) + axis.axvline(0, color="black", linestyle="--", linewidth=0.9, alpha=0.6) + axis.set_title(pair.replace("_", "–")) + axis.set_xlabel("Temporal shift Δ (slots)") + axis.grid(alpha=0.2) + axes[0].set_ylabel("Cross-modal cosine similarity") + handles, labels = axes[-1].get_legend_handles_labels() + fig.legend(handles, labels, loc="lower center", ncol=3, frameon=False, bbox_to_anchor=(0.5, -0.02)) + fig.suptitle("Same-slot vs shifted cross-modal similarity (95% video_id bootstrap CI)", y=1.02) + fig.tight_layout(rect=(0, 0.08, 1, 0.98)) + output_path.parent.mkdir(parents=True, exist_ok=True) + fig.savefig(output_path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def run(args: argparse.Namespace) -> dict[str, Any]: + started = time.time() + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is unavailable") + + loaded_samples = load_feature_samples(args.feature_dir, args.manifest) + by_id = {sample.sample_id: sample for sample in loaded_samples} + split_rows = json.loads(args.splits.read_text(encoding="utf-8")) + output_dir = args.output_dir + output_dir.mkdir(parents=True, exist_ok=True) + all_metric_rows: list[dict[str, Any]] = [] + all_curve_rows: list[dict[str, Any]] = [] + all_history_rows: list[dict[str, Any]] = [] + saved_probes: dict[str, Any] = {} + fold_manifests = [] + + for split in split_rows: + fold = int(split["fold"]) + train_samples = [by_id[sample_id] for sample_id in split["train_sample_ids"]] + validation_samples = [by_id[sample_id] for sample_id in split["validation_sample_ids"]] + train_groups = {sample.group_id for sample in train_samples} + validation_groups = {sample.group_id for sample in validation_samples} + if train_groups & validation_groups: + raise ValueError(f"video_id leakage in fold {fold}") + stats = fit_feature_stats(train_samples) + print( + f"[correspondence fold {fold}] train={len(train_samples)} heldout={len(validation_samples)} " + f"video_ids={len(train_groups)}/{len(validation_groups)}", + flush=True, + ) + fold_manifests.append( + { + "fold": fold, + "train_count": len(train_samples), + "heldout_count": len(validation_samples), + "train_video_ids": sorted(train_groups), + "heldout_video_ids": sorted(validation_groups), + "overlap": sorted(train_groups & validation_groups), + } + ) + for method_index, method_name in enumerate(METHODS): + if method_name in {"M1", "M2"}: + aligned_train, _ = _collect_representations( + method_name, + train_samples, + stats, + device=device, + grid_size=GRID_SIZE, + batch_size=args.batch_size, + ) + aligned_validation, _ = _collect_representations( + method_name, + validation_samples, + stats, + device=device, + grid_size=GRID_SIZE, + batch_size=args.batch_size, + ) + aligned = {**aligned_train, **aligned_validation} + else: + aligned = _collect_learned_representations( + method_name=method_name, + fold=fold, + train_samples=train_samples, + validation_samples=validation_samples, + stats=stats, + checkpoint_root=args.checkpoint_root, + device=device, + batch_size=args.batch_size, + ) + probe_seed = args.seed + fold * 101 + method_index + probe, history = _fit_probe( + [sample.sample_id for sample in train_samples], + aligned, + device=device, + seed=probe_seed, + epochs=args.epochs, + batch_size=args.batch_size, + learning_rate=args.learning_rate, + temperature=args.temperature, + ) + for row in history: + all_history_rows.append( + {"fold": fold, "method": method_name, "seed": probe_seed, **row} + ) + probe.eval() + with torch.no_grad(): + validation = _stack_ids( + [sample.sample_id for sample in validation_samples], aligned, device + ) + projected = probe(validation) + for sample_index, sample in enumerate(validation_samples): + one = {name: projected[name][sample_index] for name in MODALITIES} + all_metric_rows.extend( + _sample_metrics( + method=method_name, + fold=fold, + sample=sample, + projected=one, + curve_rows=all_curve_rows, + ) + ) + saved_probes[f"fold_{fold:02d}/{method_name}"] = { + "input_dimensions": { + name: int(aligned[train_samples[0].sample_id][name].shape[-1]) + for name in MODALITIES + }, + "state_dict": {key: value.detach().cpu() for key, value in probe.state_dict().items()}, + "seed": probe_seed, + } + print( + f"[correspondence fold {fold} {method_name}] " + f"probe_loss={history[-1]['train_loss']:.4f}", + flush=True, + ) + del probe + if device.type == "cuda": + torch.cuda.empty_cache() + + summary_rows, curve_summary_rows = _summaries( + all_metric_rows, all_curve_rows, seed=args.seed + ) + time_localization_rows = _summarize_time_localization( + args.checkpoint_root, len(split_rows), seed=args.seed + ) + _write_csv(output_dir / "correspondence_clip_metrics.csv", all_metric_rows) + _write_csv(output_dir / "shifted_similarity_by_clip.csv", all_curve_rows) + _write_csv(output_dir / "metric_summary.csv", summary_rows) + _write_csv(output_dir / "shift_curve_summary.csv", curve_summary_rows) + _write_csv(output_dir / "time_localization_summary.csv", time_localization_rows) + _write_csv(output_dir / "probe_training_history.csv", all_history_rows) + _plot_curve(all_curve_rows, output_dir / "shifted_similarity_curve.png") + torch.save(saved_probes, output_dir / "probe_checkpoints.pt") + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "experiment": "Q1-Correspondence Evaluation", + "sample_count": len(loaded_samples), + "fold_count": len(split_rows), + "folds": fold_manifests, + "methods": list(METHODS), + "grid_size": GRID_SIZE, + "probe": { + "type": "one bias-free linear projection per modality, L2 normalized", + "output_dimension": OUTPUT_SIZE, + "training_objective": "symmetric within-clip diagonal-vs-off-diagonal InfoNCE across all three modality pairs", + "negative_source": "same training clip, different grid slots", + "epochs": args.epochs, + "batch_size": args.batch_size, + "learning_rate": args.learning_rate, + "temperature": args.temperature, + "emotion_labels_used": False, + "heldout_groups_used_for_probe_training_or_selection": False, + }, + "evaluation": { + "shift_curve": f"mean cosine sim(z_i^m, z_(i+delta)^n), delta=-{CURVE_MAX_SHIFT}..{CURVE_MAX_SHIFT}", + "temporal_retrieval": "candidate slots restricted to the same held-out clip; report exact R@1, within +/-1 R@1, and MASE slots in both directions", + "matched_vs_shifted_auc": f"per-clip ROC AUC; positives are same-slot pairs, negatives are same-clip pairs with |i-j|>{NEGATIVE_RADIUS}", + "confidence_intervals": "95% percentile bootstrap resampling video_id groups, not clips or slots; 2,000 repetitions for CSV summaries and 1,000 for plot ribbons", + "random_retrieval_reference": { + "exact_r1": 1.0 / GRID_SIZE, + "within_pm1_r1": (3.0 * GRID_SIZE - 2.0) / GRID_SIZE**2, + "expected_mase_slots": (GRID_SIZE**2 - 1) / (3.0 * GRID_SIZE), + }, + }, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "elapsed_seconds": time.time() - started, + "interpretation_limits": [ + "The projection is a supervised diagnostic probe for same-slot matchability, not an alignment model or independent ground truth.", + "A strong result means train-video same-time matchability transfers to held-out video_id groups; it does not establish semantic equivalence between modalities.", + "M3/M4 D5 training used timestamp-derived Gaussian targets; this evaluation tests whether their frozen pooled content representations carry transferable same-time correspondence beyond that temporal target.", + "The effective sample size for confidence intervals is the number of video_id groups, not the number of slots.", + ], + } + (output_dir / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + print( + f"[correspondence done] clips={len(all_metric_rows)} " + f"elapsed={manifest['elapsed_seconds']:.1f}s output={output_dir}", + flush=True, + ) + return manifest + + +def build_parser() -> argparse.ArgumentParser: + project = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--device", choices=("auto", "cpu", "cuda"), default="auto") + parser.add_argument("--batch-size", type=int, default=8) + parser.add_argument("--epochs", type=int, default=40) + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--learning-rate", type=float, default=1e-3) + parser.add_argument("--temperature", type=float, default=0.1) + parser.add_argument( + "--feature-dir", type=Path, default=project / "outputs/q1_features/features" + ) + parser.add_argument("--manifest", type=Path, default=project / "outputs/audit/manifest.csv") + parser.add_argument( + "--splits", type=Path, default=project / "outputs/method_comparison/splits.json" + ) + parser.add_argument( + "--checkpoint-root", type=Path, default=project / "outputs/alignment_debug/heldout" + ) + parser.add_argument( + "--output-dir", type=Path, default=project / "outputs/correspondence_eval" + ) + return parser + + +def main() -> None: + args = build_parser().parse_args() + run(args) + + +if __name__ == "__main__": + main() diff --git a/deep_learning/Q1/q1/experiment_data.py b/deep_learning/Q1/q1/experiment_data.py new file mode 100644 index 0000000..83c38eb --- /dev/null +++ b/deep_learning/Q1/q1/experiment_data.py @@ -0,0 +1,159 @@ +from __future__ import annotations + +import csv +from dataclasses import dataclass +from pathlib import Path +from typing import Mapping, Sequence + +import numpy as np +import torch +from torch import Tensor + +from .types import MODALITIES, SequenceBatch + + +@dataclass(frozen=True) +class FeatureSample: + sample_id: str + group_id: str + duration_s: float + sentiment: float + polarity: int + word_intervals: np.ndarray + features: Mapping[str, np.ndarray] + times: Mapping[str, np.ndarray] + valid: Mapping[str, np.ndarray] + + +@dataclass(frozen=True) +class FeatureStats: + mean: Mapping[str, np.ndarray] + scale: Mapping[str, np.ndarray] + + +def load_feature_samples(feature_dir: Path, manifest_path: Path) -> list[FeatureSample]: + """Read the extracted NPZ files and their source-time/label manifest.""" + with manifest_path.open("r", encoding="utf-8-sig", newline="") as file: + rows = list(csv.DictReader(file)) + if not rows: + raise ValueError(f"sample manifest is empty: {manifest_path}") + + samples: list[FeatureSample] = [] + seen: set[str] = set() + for row in rows: + video_id = row["video_id"] + clip_id = row["clip_id"] + sample_id = f"{video_id}/{clip_id}" + if sample_id in seen: + raise ValueError(f"duplicate sample in manifest: {sample_id}") + seen.add(sample_id) + + path = feature_dir / f"{video_id}__{clip_id}.npz" + if not path.is_file(): + raise FileNotFoundError(f"feature file missing for {sample_id}: {path}") + with np.load(path, allow_pickle=False) as archive: + features = { + "text": np.asarray(archive["text_features"], dtype=np.float32), + "audio": np.asarray(archive["audio_features"], dtype=np.float32), + "vision": np.asarray(archive["vision_features"], dtype=np.float32), + } + times = { + "text": np.asarray(archive["word_intervals_s"], dtype=np.float32).mean(axis=1), + "audio": np.asarray(archive["audio_times_s"], dtype=np.float32), + "vision": np.asarray(archive["vision_times_s"], dtype=np.float32), + } + valid = { + "text": np.ones(features["text"].shape[0], dtype=np.bool_), + "audio": np.asarray(archive["audio_valid"], dtype=np.bool_), + "vision": np.asarray(archive["vision_valid"], dtype=np.bool_), + } + word_intervals = np.asarray(archive["word_intervals_s"], dtype=np.float32) + + for name in MODALITIES: + if features[name].ndim != 2 or times[name].shape != (features[name].shape[0],): + raise ValueError(f"invalid {name} feature/timestamp shape in {sample_id}") + if valid[name].shape != times[name].shape or not valid[name].any(): + raise ValueError(f"{sample_id} has no valid {name} sequence positions") + if not np.isfinite(features[name][valid[name]]).all(): + raise ValueError(f"non-finite valid {name} values in {sample_id}") + if not np.isfinite(times[name][valid[name]]).all(): + raise ValueError(f"non-finite valid {name} timestamps in {sample_id}") + + annotation = row["annotation"].strip().lower() + polarity_by_name = {"negative": 0, "neutral": 1, "positive": 2} + if annotation not in polarity_by_name: + raise ValueError(f"unknown polarity label {annotation!r} in {sample_id}") + samples.append( + FeatureSample( + sample_id=sample_id, + group_id=row.get("group_id") or video_id, + duration_s=float(row["duration_s"]), + sentiment=float(row["label"]), + polarity=polarity_by_name[annotation], + word_intervals=word_intervals, + features=features, + times=times, + valid=valid, + ) + ) + return samples + + +def fit_feature_stats(samples: Sequence[FeatureSample]) -> FeatureStats: + """Fit per-modality z-score parameters using only the training fold.""" + if not samples: + raise ValueError("cannot fit feature statistics on an empty sample list") + means: dict[str, np.ndarray] = {} + scales: dict[str, np.ndarray] = {} + for name in MODALITIES: + values = np.concatenate( + [sample.features[name][sample.valid[name]] for sample in samples], axis=0 + ).astype(np.float64, copy=False) + mean = values.mean(axis=0) + scale = values.std(axis=0) + scale[scale < 1e-6] = 1.0 + means[name] = mean.astype(np.float32) + scales[name] = scale.astype(np.float32) + return FeatureStats(mean=means, scale=scales) + + +def standardized_features(sample: FeatureSample, stats: FeatureStats) -> dict[str, np.ndarray]: + return { + name: ((sample.features[name] - stats.mean[name]) / stats.scale[name]).astype( + np.float32, copy=False + ) + for name in MODALITIES + } + + +def collate_feature_samples( + samples: Sequence[FeatureSample], + stats: FeatureStats, + device: torch.device, +) -> tuple[dict[str, SequenceBatch], Tensor, list[Tensor]]: + """Pad one variable-length batch in memory; padding is masked and never saved.""" + if not samples: + raise ValueError("cannot collate an empty sample list") + batch_size = len(samples) + sequences: dict[str, SequenceBatch] = {} + for name in MODALITIES: + lengths = [sample.features[name].shape[0] for sample in samples] + max_length = max(lengths) + dimension = samples[0].features[name].shape[1] + feature_batch = torch.zeros(batch_size, max_length, dimension, dtype=torch.float32) + time_batch = torch.zeros(batch_size, max_length, dtype=torch.float32) + valid_batch = torch.zeros(batch_size, max_length, dtype=torch.bool) + for index, sample in enumerate(samples): + features = standardized_features(sample, stats)[name] + length = len(features) + feature_batch[index, :length] = torch.from_numpy(features) + time_batch[index, :length] = torch.from_numpy(sample.times[name]) + valid_batch[index, :length] = torch.from_numpy(sample.valid[name]) + sequences[name] = SequenceBatch( + features=feature_batch.to(device), + times=time_batch.to(device), + valid=valid_batch.to(device), + ) + durations = torch.tensor([sample.duration_s for sample in samples], dtype=torch.float32, device=device) + word_intervals = [torch.from_numpy(sample.word_intervals).to(device) for sample in samples] + return sequences, durations, word_intervals diff --git a/deep_learning/Q1/q1/experiment_probes.py b/deep_learning/Q1/q1/experiment_probes.py new file mode 100644 index 0000000..ec45a41 --- /dev/null +++ b/deep_learning/Q1/q1/experiment_probes.py @@ -0,0 +1,462 @@ +from __future__ import annotations + +from collections.abc import Mapping, Sequence + +import numpy as np +import torch +import torch.nn.functional as F +from sklearn.dummy import DummyClassifier +from sklearn.linear_model import LogisticRegression, Ridge +from sklearn.metrics import accuracy_score, f1_score, mean_absolute_error +from sklearn.preprocessing import StandardScaler +from torch import Tensor, nn + +from .alignment import make_block_mask +from .losses import cross_modal_contrastive_loss +from .metrics import retrieval_metrics +from .types import MODALITIES + + +class RetrievalProjection(nn.Module): + """Equal-capacity linear heads for the cross-modal retrieval probe.""" + + def __init__(self, dimensions: Mapping[str, int], output_size: int = 128) -> None: + super().__init__() + self.projections = nn.ModuleDict( + {name: nn.Linear(dimensions[name], output_size, bias=False) for name in MODALITIES} + ) + + def forward(self, aligned: Mapping[str, Tensor]) -> dict[str, Tensor]: + return { + name: F.normalize(self.projections[name](aligned[name]), dim=-1) + for name in MODALITIES + } + + +class MaskedCrossModalDecoder(nn.Module): + """Reconstruct one missing modality from the other aligned streams.""" + + def __init__(self, dimensions: Mapping[str, int], hidden_size: int = 256) -> None: + super().__init__() + self.dimensions = dict(dimensions) + input_size = sum(dimensions.values()) + len(MODALITIES) + self.decoders = nn.ModuleDict( + { + target: nn.Sequential( + nn.Linear(input_size, hidden_size), + nn.GELU(), + nn.Dropout(0.1), + nn.Linear(hidden_size, dimensions[target]), + ) + for target in MODALITIES + } + ) + + def forward(self, aligned: Mapping[str, Tensor], target: str, mask: Tensor) -> Tensor: + values = [] + availability = [] + for name in MODALITIES: + present = torch.ones_like(mask, dtype=aligned[name].dtype) + source = aligned[name] + if name == target: + present = (~mask).to(source.dtype) + source = source.masked_fill(mask.unsqueeze(-1), 0.0) + values.append(source) + availability.append(present.unsqueeze(-1)) + inputs = torch.cat((*values, *availability), dim=-1) + return self.decoders[target](inputs) + + +def _stack_aligned( + sample_ids: Sequence[str], aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], device: torch.device +) -> dict[str, Tensor]: + return { + name: torch.as_tensor( + np.stack([aligned_by_id[sample_id][name] for sample_id in sample_ids]), + dtype=torch.float32, + device=device, + ) + for name in MODALITIES + } + + +def run_retrieval_probe( + train_ids: Sequence[str], + val_ids: Sequence[str], + aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], + *, + device: torch.device, + seed: int, + epochs: int = 20, + batch_size: int = 16, + learning_rate: float = 1e-3, + temperature: float = 0.1, +) -> list[dict[str, float | str]]: + """Fit modality projections on training clips, then score held-out retrieval. + + The positive is a matching common-grid index within a clip. This measures + representation consistency; it is not independent temporal ground truth. + """ + if not train_ids or not val_ids: + raise ValueError("retrieval probe needs non-empty train and validation sets") + device_gen = torch.Generator(device=device) + device_gen.manual_seed(seed) + torch.manual_seed(seed) + train = _stack_aligned(train_ids, aligned_by_id, device) + validation = _stack_aligned(val_ids, aligned_by_id, device) + dimensions = {name: int(train[name].shape[-1]) for name in MODALITIES} + model = RetrievalProjection(dimensions).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate, weight_decay=1e-4) + rng = np.random.default_rng(seed) + model.train() + for _ in range(epochs): + order = rng.permutation(len(train_ids)) + for start in range(0, len(order), batch_size): + indices = torch.as_tensor(order[start : start + batch_size], device=device) + batch = {name: value.index_select(0, indices) for name, value in train.items()} + projected = model(batch) + loss = cross_modal_contrastive_loss(projected, temperature=temperature) + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + + model.eval() + with torch.no_grad(): + projected = model(validation) + directions = (("text", "audio"), ("audio", "text"), ("text", "vision"), + ("vision", "text"), ("audio", "vision"), ("vision", "audio")) + rows: list[dict[str, float | str]] = [] + for query_name, target_name in directions: + values = retrieval_metrics(projected[query_name], projected[target_name]) + rows.append({"direction": f"{query_name}_to_{target_name}", **values}) + return rows + + +def run_within_clip_temporal_retrieval_probe( + train_ids: Sequence[str], + val_ids: Sequence[str], + aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], + *, + device: torch.device, + seed: int, + epochs: int = 20, + batch_size: int = 16, + learning_rate: float = 1e-3, + temperature: float = 0.1, + tolerance: int = 1, + top_k: int = 3, +) -> list[dict[str, float | str]]: + """Fit train-only cross-modal projections, then retrieve slots within each clip. + + Unlike global grid retrieval, each query's candidates are restricted to + the target modality from that same held-out clip. A result is correct if + its slot is within ``tolerance`` of the query slot. + """ + if not train_ids or not val_ids: + raise ValueError("temporal retrieval needs non-empty train and validation sets") + if tolerance < 0 or top_k < 1: + raise ValueError("tolerance must be non-negative and top_k positive") + torch.manual_seed(seed) + train = _stack_aligned(train_ids, aligned_by_id, device) + validation = _stack_aligned(val_ids, aligned_by_id, device) + dimensions = {name: int(train[name].shape[-1]) for name in MODALITIES} + model = RetrievalProjection(dimensions).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate, weight_decay=1e-4) + rng = np.random.default_rng(seed) + model.train() + for _ in range(epochs): + order = rng.permutation(len(train_ids)) + for start in range(0, len(order), batch_size): + indices = torch.as_tensor(order[start : start + batch_size], device=device) + batch = {name: value.index_select(0, indices) for name, value in train.items()} + projected = model(batch) + loss = cross_modal_contrastive_loss(projected, temperature=temperature) + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + + model.eval() + with torch.no_grad(): + projected = model(validation) + directions = ( + ("text", "audio"), + ("audio", "text"), + ("text", "vision"), + ("vision", "text"), + ("audio", "vision"), + ("vision", "audio"), + ) + rows: list[dict[str, float | str]] = [] + for query_name, target_name in directions: + distances_top1 = [] + hits_top1 = [] + hits_topk = [] + for clip_index in range(len(val_ids)): + query = projected[query_name][clip_index] + target = projected[target_name][clip_index] + scores = query @ target.T + count = scores.shape[0] + k = min(top_k, count) + candidates = scores.topk(k=k, dim=-1).indices + slots = torch.arange(count, device=device)[:, None] + distances = (candidates - slots).abs() + distances_top1.append(distances[:, 0].float()) + hits_top1.append((distances[:, 0] <= tolerance).float()) + hits_topk.append((distances <= tolerance).any(dim=-1).float()) + top1_distance = torch.cat(distances_top1) + rows.append( + { + "direction": f"{query_name}_to_{target_name}", + "r_at_1": float(torch.cat(hits_top1).mean().item()), + "r_at_3": float(torch.cat(hits_topk).mean().item()), + "mase_slots": float(top1_distance.mean().item()), + "exact_r_at_1": float((top1_distance == 0).float().mean().item()), + "tolerance_slots": float(tolerance), + "candidate_slots_per_clip": float(projected[query_name].shape[1]), + "queries": float(len(val_ids) * projected[query_name].shape[1]), + } + ) + return rows + + +def _fixed_block_mask( + count: int, grid_size: int, ratio: float, device: torch.device, salt: int +) -> Tensor: + block = min(max(1, round(grid_size * ratio)), grid_size - 1) + starts = torch.tensor( + [(index * 17 + salt * 13) % (grid_size - block + 1) for index in range(count)], + dtype=torch.long, + device=device, + ) + offsets = torch.arange(block, device=device) + mask = torch.zeros(count, grid_size, dtype=torch.bool, device=device) + mask[torch.arange(count, device=device)[:, None], starts[:, None] + offsets] = True + return mask + + +def run_reconstruction_probe( + train_ids: Sequence[str], + val_ids: Sequence[str], + aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], + *, + device: torch.device, + seed: int, + ratio: float = 0.2, + epochs: int = 25, + batch_size: int = 16, + learning_rate: float = 1e-3, +) -> list[dict[str, float | str]]: + """Train the same decoder family on frozen alignments and score held-out clips.""" + if not train_ids or not val_ids: + raise ValueError("reconstruction probe needs non-empty train and validation sets") + torch.manual_seed(seed) + generator = torch.Generator(device=device) + generator.manual_seed(seed) + train = _stack_aligned(train_ids, aligned_by_id, device) + validation = _stack_aligned(val_ids, aligned_by_id, device) + dimensions = {name: int(train[name].shape[-1]) for name in MODALITIES} + model = MaskedCrossModalDecoder(dimensions).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate, weight_decay=1e-4) + rng = np.random.default_rng(seed) + + model.train() + for _ in range(epochs): + order = rng.permutation(len(train_ids)) + for start in range(0, len(order), batch_size): + indices = torch.as_tensor(order[start : start + batch_size], device=device) + batch = {name: value.index_select(0, indices) for name, value in train.items()} + target_losses = [] + for target in MODALITIES: + mask = make_block_mask( + len(indices), + batch[target].shape[1], + ratio, + device, + generator=generator, + ) + prediction = model(batch, target, mask) + target_losses.append(F.smooth_l1_loss(prediction[mask], batch[target][mask])) + loss = torch.stack(target_losses).mean() + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + + model.eval() + rows: list[dict[str, float | str]] = [] + with torch.no_grad(): + for target_index, target in enumerate(MODALITIES): + mask = _fixed_block_mask( + len(val_ids), validation[target].shape[1], ratio, device, target_index + ) + prediction = model(validation, target, mask) + residual = (prediction[mask] - validation[target][mask]).abs() + smooth = F.smooth_l1_loss(prediction[mask], validation[target][mask]) + rows.append( + { + "target_modality": target, + "mask_ratio": ratio, + "mae_standardized": float(residual.mean().item()), + "smooth_l1_standardized": float(smooth.item()), + "masked_values": int(residual.numel()), + } + ) + return rows + + +def run_shuffled_alignment_reconstruction_probe( + train_ids: Sequence[str], + val_ids: Sequence[str], + aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], + *, + device: torch.device, + seed: int, + ratio: float = 0.2, + epochs: int = 25, + batch_size: int = 16, + learning_rate: float = 1e-3, + shuffle_repeats: int = 5, +) -> list[dict[str, float | str]]: + """Compare normal reconstruction with cross-modal slots shuffled at eval. + + The decoder is trained once on aligned training-fold representations. + For the control, the two non-target modalities share a random slot + permutation within each validation clip; the target stream and target + values remain in their original order. Thus the metric isolates how much + correctly matched cross-modal slots help the frozen decoder. + """ + if not train_ids or not val_ids: + raise ValueError("reconstruction needs non-empty train and validation sets") + if shuffle_repeats < 1: + raise ValueError("shuffle_repeats must be positive") + torch.manual_seed(seed) + generator = torch.Generator(device=device) + generator.manual_seed(seed) + train = _stack_aligned(train_ids, aligned_by_id, device) + validation = _stack_aligned(val_ids, aligned_by_id, device) + dimensions = {name: int(train[name].shape[-1]) for name in MODALITIES} + model = MaskedCrossModalDecoder(dimensions).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate, weight_decay=1e-4) + rng = np.random.default_rng(seed) + + model.train() + for _ in range(epochs): + order = rng.permutation(len(train_ids)) + for start in range(0, len(order), batch_size): + indices = torch.as_tensor(order[start : start + batch_size], device=device) + batch = {name: value.index_select(0, indices) for name, value in train.items()} + target_losses = [] + for target in MODALITIES: + mask = make_block_mask( + len(indices), batch[target].shape[1], ratio, device, generator=generator + ) + prediction = model(batch, target, mask) + target_losses.append(F.smooth_l1_loss(prediction[mask], batch[target][mask])) + loss = torch.stack(target_losses).mean() + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + + model.eval() + rows: list[dict[str, float | str]] = [] + with torch.no_grad(): + for target_index, target in enumerate(MODALITIES): + mask = _fixed_block_mask( + len(val_ids), validation[target].shape[1], ratio, device, target_index + ) + aligned_prediction = model(validation, target, mask) + aligned_error = (aligned_prediction[mask] - validation[target][mask]).abs().mean() + + shuffle_errors = [] + permutation_rng = np.random.default_rng(seed + 1709 + target_index) + slot_count = validation[target].shape[1] + for _ in range(shuffle_repeats): + permutations = np.stack( + [permutation_rng.permutation(slot_count) for _ in val_ids] + ) + permutation_tensor = torch.as_tensor(permutations, dtype=torch.long, device=device) + shuffled = {} + for name, values in validation.items(): + if name == target: + shuffled[name] = values + else: + gather_indices = permutation_tensor.unsqueeze(-1).expand_as(values) + shuffled[name] = values.gather(1, gather_indices) + shuffled_prediction = model(shuffled, target, mask) + shuffled_error = ( + shuffled_prediction[mask] - validation[target][mask] + ).abs().mean() + shuffle_errors.append(float(shuffled_error.item())) + shuffled_mean = float(np.mean(shuffle_errors)) + rows.append( + { + "target_modality": target, + "mask_ratio": ratio, + "mae_aligned": float(aligned_error.item()), + "mae_shuffled_mean": shuffled_mean, + "mae_shuffled_std": float(np.std(shuffle_errors, ddof=1)) + if shuffle_repeats > 1 + else 0.0, + "gain_align": shuffled_mean - float(aligned_error.item()), + "shuffle_repeats": float(shuffle_repeats), + "masked_values": int(mask.sum().item() * dimensions[target]), + } + ) + return rows + + +def _emotion_features( + sample_ids: Sequence[str], aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], bins: int = 5 +) -> np.ndarray: + outputs = [] + for sample_id in sample_ids: + combined = np.concatenate([aligned_by_id[sample_id][name] for name in MODALITIES], axis=-1) + segments = np.array_split(combined, bins, axis=0) + outputs.append(np.concatenate([segment.mean(axis=0) for segment in segments])) + return np.stack(outputs).astype(np.float32, copy=False) + + +def run_frozen_emotion_probe( + train_samples: Sequence[object], + val_samples: Sequence[object], + aligned_by_id: Mapping[str, Mapping[str, np.ndarray]], +) -> dict[str, float | int]: + """Evaluate a regularized five-bin linear probe on frozen aligned features.""" + train_ids = [sample.sample_id for sample in train_samples] + val_ids = [sample.sample_id for sample in val_samples] + x_train = _emotion_features(train_ids, aligned_by_id) + x_val = _emotion_features(val_ids, aligned_by_id) + y_train = np.asarray([sample.polarity for sample in train_samples], dtype=np.int64) + y_val = np.asarray([sample.polarity for sample in val_samples], dtype=np.int64) + target_train = np.asarray([sample.sentiment for sample in train_samples], dtype=np.float64) + target_val = np.asarray([sample.sentiment for sample in val_samples], dtype=np.float64) + + scaler = StandardScaler() + x_train = scaler.fit_transform(x_train) + x_val = scaler.transform(x_val) + if np.unique(y_train).size > 1: + classifier = LogisticRegression( + C=0.1, class_weight="balanced", max_iter=2000, solver="lbfgs", random_state=0 + ) + else: + classifier = DummyClassifier(strategy="most_frequent") + classifier.fit(x_train, y_train) + predicted_class = classifier.predict(x_val) + regressor = Ridge(alpha=10.0) + regressor.fit(x_train, target_train) + predicted_score = regressor.predict(x_val) + if len(target_val) > 1 and np.std(predicted_score) > 0 and np.std(target_val) > 0: + pearson = float(np.corrcoef(predicted_score, target_val)[0, 1]) + else: + pearson = float("nan") + return { + "accuracy": float(accuracy_score(y_val, predicted_class)), + "macro_f1": float(f1_score(y_val, predicted_class, average="macro", zero_division=0)), + "mae": float(mean_absolute_error(target_val, predicted_score)), + "pearson": pearson, + "n_train": len(train_samples), + "n_validation": len(val_samples), + } diff --git a/deep_learning/Q1/q1/extract_features.py b/deep_learning/Q1/q1/extract_features.py new file mode 100644 index 0000000..a837b8e --- /dev/null +++ b/deep_learning/Q1/q1/extract_features.py @@ -0,0 +1,1082 @@ +from __future__ import annotations + +import argparse +import csv +import hashlib +import importlib.metadata +import json +import logging +import math +import platform +import re +import shutil +import subprocess +import sys +import time +import urllib.request +from dataclasses import dataclass +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +import cv2 +import mediapipe as mp +import numpy as np +import opensmile +import torch +from PIL import Image +from transformers import AutoImageProcessor, AutoModel, AutoModelForCTC, AutoTokenizer + +from .audit import _read_labels + + +TEXT_MODEL_ID = "google-bert/bert-base-uncased" +CTC_MODEL_ID = "facebook/wav2vec2-base-960h" +VISION_MODEL_ID = "facebook/deit-tiny-patch16-224" +FACE_MODEL_URL = ( + "https://storage.googleapis.com/mediapipe-models/face_landmarker/" + "face_landmarker/float16/latest/face_landmarker.task" +) +AUDIO_SAMPLE_RATE = 16_000 +VISION_FPS = 5.0 +VISION_DIM = 52 +VISION_GLOBAL_DIM = 192 + +LOGGER = logging.getLogger("q1.extract") + + +@dataclass +class ExtractedSample: + arrays: dict[str, np.ndarray] + info: dict[str, Any] + + +def _package_version(name: str) -> str: + try: + return importlib.metadata.version(name) + except importlib.metadata.PackageNotFoundError: + return "not-installed" + + +def _tool_version(executable: str) -> str: + candidate = shutil.which(executable) + if candidate is None and executable == "uv": + local_uv = Path.home() / ".local" / "bin" / "uv" + candidate = str(local_uv) if local_uv.is_file() else None + if candidate is None: + return "not-found" + try: + flag = "--version" if executable == "uv" else "-version" + result = subprocess.run([candidate, flag], capture_output=True, text=True, check=True) + output = result.stdout or result.stderr + return output.splitlines()[0].strip() if output else "unknown" + except (OSError, subprocess.CalledProcessError) as error: + return f"unavailable: {type(error).__name__}" + + +def _safe_id(value: str) -> str: + return re.sub(r"[^A-Za-z0-9_.-]+", "_", value) + + +def _ffprobe_duration(video_path: Path) -> float: + result = subprocess.run( + [ + "ffprobe", "-v", "error", "-show_entries", "format=duration", + "-of", "default=noprint_wrappers=1:nokey=1", str(video_path), + ], + check=True, + capture_output=True, + text=True, + ) + try: + return max(float(result.stdout.strip()), 0.0) + except ValueError: + return 0.0 + + +def _read_audio(video_path: Path) -> np.ndarray: + command = [ + "ffmpeg", "-nostdin", "-v", "error", "-i", str(video_path), "-vn", + "-ac", "1", "-ar", str(AUDIO_SAMPLE_RATE), "-f", "f32le", "pipe:1", + ] + result = subprocess.run(command, check=True, capture_output=True) + waveform = np.frombuffer(result.stdout, dtype=" dict[str, np.ndarray]: + return { + "text_words": np.empty((0,), dtype="U1"), + "text_features": np.empty((0, hidden_size), dtype=np.float16), + } + + +def _ctc_viterbi( + log_probs: np.ndarray, + targets: list[int], + blank_id: int, +) -> tuple[np.ndarray, float] | None: + """Viterbi-decode a CTC target into a frame-to-extended-target path.""" + if not targets or log_probs.ndim != 2: + return None + if log_probs.shape[0] < len(targets): + return None + extended = np.full(2 * len(targets) + 1, blank_id, dtype=np.int64) + extended[1::2] = np.asarray(targets, dtype=np.int64) + states = extended.size + frames = log_probs.shape[0] + previous = np.full(states, -np.inf, dtype=np.float32) + previous[0] = log_probs[0, blank_id] + previous[1] = log_probs[0, extended[1]] + back = np.zeros((frames, states), dtype=np.uint8) + back[0, 1] = 1 + state_indices = np.arange(states) + for frame in range(1, frames): + candidates = np.full((3, states), -np.inf, dtype=np.float32) + candidates[0] = previous + candidates[1, 1:] = previous[:-1] + skip_allowed = (state_indices >= 2) & (extended != blank_id) + skip_allowed[2:] &= extended[2:] != extended[:-2] + candidates[2, skip_allowed] = previous[state_indices[skip_allowed] - 2] + choice = candidates.argmax(axis=0).astype(np.uint8) + best = candidates[choice, state_indices] + previous = best + log_probs[frame, extended] + back[frame] = choice + + final_state = states - 1 + if states > 1 and previous[-2] > previous[-1]: + final_state -= 1 + final_score = float(previous[final_state]) + if not math.isfinite(final_score): + return None + path = np.empty(frames, dtype=np.int32) + state = final_state + path[-1] = state + for frame in range(frames - 1, 0, -1): + state -= int(back[frame, state]) + path[frame - 1] = state + return path, final_score / frames + + +class FeatureModels: + def __init__(self, device: torch.device, vision_model_path: Path, cache_dir: Path | None = None): + self.device = device + LOGGER.info("Loading text model %s", TEXT_MODEL_ID) + self.text_tokenizer = AutoTokenizer.from_pretrained( + TEXT_MODEL_ID, use_fast=True, cache_dir=str(cache_dir) if cache_dir else None + ) + self.text_model = AutoModel.from_pretrained( + TEXT_MODEL_ID, cache_dir=str(cache_dir) if cache_dir else None + ).to(device).eval() + self.text_dim = int(self.text_model.config.hidden_size) + + LOGGER.info("Loading CTC model %s", CTC_MODEL_ID) + self.ctc_tokenizer = AutoTokenizer.from_pretrained( + CTC_MODEL_ID, cache_dir=str(cache_dir) if cache_dir else None + ) + self.ctc_model = AutoModelForCTC.from_pretrained( + CTC_MODEL_ID, cache_dir=str(cache_dir) if cache_dir else None + ).to(device).eval() + self.blank_id = int(self.ctc_tokenizer.pad_token_id) + self.delimiter_id = int( + self.ctc_tokenizer.convert_tokens_to_ids( + self.ctc_tokenizer.word_delimiter_token or "|" + ) + ) + self.ctc_vocab = self.ctc_tokenizer.get_vocab() + self.stride_samples = int(np.prod(self.ctc_model.config.conv_stride)) + self.receptive_samples = self._receptive_field( + self.ctc_model.config.conv_kernel, + self.ctc_model.config.conv_stride, + ) + + LOGGER.info("Loading general vision model %s", VISION_MODEL_ID) + self.vision_processor = AutoImageProcessor.from_pretrained( + VISION_MODEL_ID, cache_dir=str(cache_dir) if cache_dir else None + ) + self.vision_model = AutoModel.from_pretrained( + VISION_MODEL_ID, cache_dir=str(cache_dir) if cache_dir else None + ).to(device).eval() + self.vision_dim = int(self.vision_model.config.hidden_size) + if self.vision_dim != VISION_GLOBAL_DIM: + raise ValueError(f"expected {VISION_GLOBAL_DIM}-dimensional DeiT features, received {self.vision_dim}") + + self.vision_model_path = vision_model_path + self._ensure_vision_model() + LOGGER.info("Feature models are ready on %s", device) + + @staticmethod + def _receptive_field(kernels: list[int], strides: list[int]) -> int: + receptive, jump = 1, 1 + for kernel, stride in zip(kernels, strides): + receptive += (kernel - 1) * jump + jump *= stride + return receptive + + def _ensure_vision_model(self) -> None: + self.vision_model_path.parent.mkdir(parents=True, exist_ok=True) + if self.vision_model_path.exists() and self.vision_model_path.stat().st_size > 1_000_000: + return + LOGGER.info("Downloading MediaPipe Face Landmarker model") + temporary = self.vision_model_path.with_suffix(self.vision_model_path.suffix + ".tmp") + urllib.request.urlretrieve(FACE_MODEL_URL, temporary) + if temporary.stat().st_size < 1_000_000: + temporary.unlink(missing_ok=True) + raise RuntimeError("downloaded Face Landmarker model is unexpectedly small") + temporary.replace(self.vision_model_path) + + def text_features(self, transcript: str) -> tuple[list[str], np.ndarray]: + words = transcript.split() + if not words: + return [], np.empty((0, self.text_dim), dtype=np.float32) + embeddings = np.zeros((len(words), self.text_dim), dtype=np.float32) + # Chunk by original words so every supplied transcript token is retained. + chunk_size = 180 + with torch.inference_mode(): + for offset in range(0, len(words), chunk_size): + chunk = words[offset:offset + chunk_size] + encoded = self.text_tokenizer( + chunk, + is_split_into_words=True, + add_special_tokens=True, + truncation=False, + return_tensors="pt", + ) + word_ids = encoded.word_ids(batch_index=0) + model_inputs = {key: value.to(self.device) for key, value in encoded.items()} + hidden = self.text_model(**model_inputs).last_hidden_state[0].float().cpu().numpy() + bins: list[list[int]] = [[] for _ in chunk] + for token_index, word_index in enumerate(word_ids): + if word_index is not None and 0 <= word_index < len(chunk): + bins[word_index].append(token_index) + for local_word_index, token_indices in enumerate(bins): + if token_indices: + embeddings[offset + local_word_index] = hidden[token_indices].mean(axis=0) + return words, embeddings + + def force_align(self, words: list[str], waveform: np.ndarray, duration_s: float) -> tuple[np.ndarray, np.ndarray, np.ndarray, bool]: + count = len(words) + if count == 0: + return ( + np.empty((0, 2), dtype=np.float32), + np.empty((0,), dtype=np.float32), + np.empty((0,), dtype=np.bool_), + False, + ) + normalized = [re.sub(r"[^a-z']", "", word.lower().replace("’", "'")) for word in words] + targets: list[int] = [] + target_word: list[int] = [] + word_target_indices: list[list[int]] = [[] for _ in words] + for word_index, word in enumerate(normalized): + if word_index: + targets.append(self.delimiter_id) + target_word.append(-1) + for character in word: + token_id = self.ctc_vocab.get(character) + if token_id is None: + token_id = int(self.ctc_tokenizer.unk_token_id) + word_target_indices[word_index].append(len(targets)) + targets.append(int(token_id)) + target_word.append(word_index) + + valid = np.zeros(count, dtype=np.bool_) + confidence = np.zeros(count, dtype=np.float32) + intervals = np.zeros((count, 2), dtype=np.float32) + ctc_success = False + if targets and waveform.size: + with torch.inference_mode(): + input_values = torch.from_numpy(waveform).to(self.device).unsqueeze(0) + logits = self.ctc_model(input_values=input_values).logits[0] + log_probs = torch.log_softmax(logits.float(), dim=-1).cpu().numpy() + decoded = _ctc_viterbi(log_probs, targets, self.blank_id) + if decoded is not None: + path, _ = decoded + ctc_success = True + frame_s = self.stride_samples / AUDIO_SAMPLE_RATE + center_s = self.receptive_samples / (2 * AUDIO_SAMPLE_RATE) + for word_index, target_indices in enumerate(word_target_indices): + states = np.asarray([2 * index + 1 for index in target_indices], dtype=np.int32) + frame_indices = np.flatnonzero(np.isin(path, states)) + if frame_indices.size: + first, last = int(frame_indices[0]), int(frame_indices[-1]) + start = first * frame_s + center_s - frame_s / 2 + end = (last + 1) * frame_s + center_s - frame_s / 2 + intervals[word_index] = (max(0.0, start), min(duration_s, max(start, end))) + valid[word_index] = True + char_scores = [] + for target_index in target_indices: + char_frames = np.flatnonzero(path == 2 * target_index + 1) + if char_frames.size: + token_id = targets[target_index] + char_scores.extend(log_probs[char_frames, token_id].tolist()) + if char_scores: + confidence[word_index] = float(np.exp(np.mean(char_scores))) + + if not bool(valid.all()): + good = np.flatnonzero(valid) + if not good.size: + centers = (np.arange(count, dtype=np.float32) + 0.5) * duration_s / count + for index, center in enumerate(centers): + intervals[index] = (center, center) + else: + cursor = 0 + while cursor < count: + if valid[cursor]: + cursor += 1 + continue + run_start = cursor + while cursor < count and not valid[cursor]: + cursor += 1 + run_end = cursor - 1 + left = float(intervals[run_start - 1, 1]) if run_start > 0 else 0.0 + right = float(intervals[cursor, 0]) if cursor < count else duration_s + right = max(left, right) + run_length = run_end - run_start + 1 + centers = np.linspace(left, right, run_length + 2, dtype=np.float32)[1:-1] + for index, center in zip(range(run_start, run_end + 1), centers): + # A point fallback preserves order without inventing a word duration. + # The false validity mask makes the fallback explicit downstream. + intervals[index] = (center, center) + # Keep returned token order monotone even if low-confidence CTC spans touch. + intervals[:, 0] = np.clip(intervals[:, 0], 0.0, duration_s) + intervals[:, 1] = np.clip(np.maximum(intervals[:, 1], intervals[:, 0]), 0.0, duration_s) + intervals[:, 0] = np.maximum.accumulate(intervals[:, 0]) + intervals[:, 1] = np.maximum.accumulate(np.maximum(intervals[:, 1], intervals[:, 0])) + return intervals, confidence, valid, ctc_success + + @staticmethod + def audio_features(waveform: np.ndarray) -> tuple[np.ndarray, np.ndarray, list[str]]: + smile = opensmile.Smile( + feature_set=opensmile.FeatureSet.eGeMAPSv02, + feature_level=opensmile.FeatureLevel.LowLevelDescriptors, + sampling_rate=AUDIO_SAMPLE_RATE, + ) + frame = smile.process_signal(waveform, sampling_rate=AUDIO_SAMPLE_RATE) + values = frame.to_numpy(dtype=np.float32, copy=True) + valid = np.isfinite(values).all(axis=1) + values = np.nan_to_num(values, nan=0.0, posinf=0.0, neginf=0.0) + index = frame.index + if getattr(index, "nlevels", 1) >= 2: + starts = index.get_level_values(0) + ends = index.get_level_values(1) + starts_s = np.asarray([item.total_seconds() for item in starts], dtype=np.float32) + ends_s = np.asarray([item.total_seconds() for item in ends], dtype=np.float32) + times = (starts_s + ends_s) / 2 + else: + times = np.asarray([item.total_seconds() for item in index], dtype=np.float32) + return times, values, list(map(str, frame.columns)), valid + + def vision_features( + self, video_path: Path + ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, list[str], int]: + base_options = mp.tasks.BaseOptions(model_asset_path=str(self.vision_model_path)) + options = mp.tasks.vision.FaceLandmarkerOptions( + base_options=base_options, + running_mode=mp.tasks.vision.RunningMode.VIDEO, + num_faces=1, + output_face_blendshapes=True, + output_facial_transformation_matrixes=False, + ) + cap = cv2.VideoCapture(str(video_path)) + if not cap.isOpened(): + raise RuntimeError(f"OpenCV could not open {video_path}") + fps = float(cap.get(cv2.CAP_PROP_FPS) or 0.0) + if not math.isfinite(fps) or fps <= 0: + fps = 30.0 + stride_frames = max(1, int(round(fps / VISION_FPS))) + features: list[np.ndarray] = [] + times: list[float] = [] + valid: list[bool] = [] + names: list[str] = [] + sampled_rgb: list[np.ndarray] = [] + frames_seen = 0 + last_timestamp_ms = -1 + with mp.tasks.vision.FaceLandmarker.create_from_options(options) as landmarker: + while True: + ok, bgr = cap.read() + if not ok: + break + frame_index = frames_seen + frames_seen += 1 + if frame_index % stride_frames != 0: + continue + timestamp_s = float(cap.get(cv2.CAP_PROP_POS_MSEC)) / 1000.0 + if not math.isfinite(timestamp_s) or timestamp_s < 0: + timestamp_s = frame_index / fps + timestamp_ms = max(last_timestamp_ms + 1, int(round(timestamp_s * 1000))) + last_timestamp_ms = timestamp_ms + rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) + sampled_rgb.append(rgb) + image = mp.Image(image_format=mp.ImageFormat.SRGB, data=np.ascontiguousarray(rgb)) + result = landmarker.detect_for_video(image, timestamp_ms) + categories = result.face_blendshapes[0] if result.face_blendshapes else [] + if categories: + current_names = [category.category_name for category in categories] + if not names: + names = current_names + lookup = {category.category_name: float(category.score) for category in categories} + vector = np.asarray([lookup.get(name, 0.0) for name in names], dtype=np.float32) + features.append(vector) + valid.append(True) + else: + if not names: + names = [f"blendshape_{index:02d}" for index in range(VISION_DIM)] + features.append(np.zeros((len(names),), dtype=np.float32)) + valid.append(False) + times.append(timestamp_s) + cap.release() + if not features: + return ( + np.empty((0,), dtype=np.float32), + np.empty((0, VISION_DIM), dtype=np.float32), + np.empty((0,), dtype=np.bool_), + np.empty((0, self.vision_dim), dtype=np.float32), + np.empty((0,), dtype=np.bool_), + [f"blendshape_{index:02d}" for index in range(VISION_DIM)], + frames_seen, + ) + matrix = np.stack(features).astype(np.float32, copy=False) + if matrix.shape[1] != VISION_DIM: + raise ValueError(f"expected {VISION_DIM} MediaPipe blendshapes, received {matrix.shape[1]}") + image_embeddings: list[np.ndarray] = [] + with torch.inference_mode(): + for start in range(0, len(sampled_rgb), 16): + batch_images = [Image.fromarray(frame) for frame in sampled_rgb[start:start + 16]] + encoded = self.vision_processor(images=batch_images, return_tensors="pt") + encoded = {key: value.to(self.device) for key, value in encoded.items()} + hidden = self.vision_model(**encoded).last_hidden_state[:, 0, :] + image_embeddings.append(hidden.float().cpu().numpy()) + global_features = np.concatenate(image_embeddings, axis=0).astype(np.float32, copy=False) + return ( + np.asarray(times, dtype=np.float32), matrix, np.asarray(valid, dtype=np.bool_), + global_features, np.ones((len(times),), dtype=np.bool_), names, frames_seen, + ) + + +def _mean_by_intervals( + times: np.ndarray, + values: np.ndarray, + valid: np.ndarray, + intervals: np.ndarray, +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + dimensions = values.shape[1] if values.ndim == 2 else 0 + aligned = np.zeros((len(intervals), dimensions), dtype=np.float32) + aligned_valid = np.zeros((len(intervals),), dtype=np.bool_) + fallback = np.zeros((len(intervals),), dtype=np.bool_) + valid_positions = np.flatnonzero(valid) + if not valid_positions.size: + return aligned, aligned_valid, fallback + for index, (start, end) in enumerate(intervals): + inside = valid_positions[(times[valid_positions] >= start) & (times[valid_positions] < end)] + if inside.size: + aligned[index] = values[inside].mean(axis=0) + aligned_valid[index] = True + else: + center = (start + end) / 2 + nearest = valid_positions[int(np.argmin(np.abs(times[valid_positions] - center)))] + aligned[index] = values[nearest] + aligned_valid[index] = True + fallback[index] = True + return aligned, aligned_valid, fallback + + +def extract_sample(models: FeatureModels, video_path: Path, record: dict[str, Any]) -> ExtractedSample: + duration_s = _ffprobe_duration(video_path) + errors: dict[str, str] = {} + warnings: list[str] = [] + waveform = np.empty((0,), dtype=np.float32) + try: + waveform = _read_audio(video_path) + except Exception as error: # Keep the sample row and report modality failure. + errors["audio_decode"] = f"{type(error).__name__}: {error}" + + try: + words, text_values = models.text_features(str(record.get("text") or "")) + except Exception as error: + errors["text_features"] = f"{type(error).__name__}: {error}" + words, text_values = [], np.empty((0, models.text_dim), dtype=np.float32) + if not words: + warnings.append("transcript_empty_or_unreadable") + + try: + word_intervals, word_confidence, word_align_valid, ctc_success = models.force_align( + words, waveform, duration_s + ) + except Exception as error: + errors["forced_alignment"] = f"{type(error).__name__}: {error}" + word_intervals = np.empty((len(words), 2), dtype=np.float32) + if words: + edges = np.linspace(0.0, duration_s, len(words) + 1, dtype=np.float32) + word_intervals = np.column_stack((edges[:-1], edges[1:])) + word_confidence = np.zeros((len(words),), dtype=np.float32) + word_align_valid = np.zeros((len(words),), dtype=np.bool_) + ctc_success = False + if words and not bool(word_align_valid.all()): + warnings.append(f"ctc_words_fallback:{int((~word_align_valid).sum())}") + + audio_columns: list[str] = [] + try: + if waveform.size: + audio_times, audio_values, audio_columns, audio_valid = models.audio_features(waveform) + else: + raise ValueError("no decoded audio waveform") + except Exception as error: + errors["audio_features"] = f"{type(error).__name__}: {error}" + audio_times = np.empty((0,), dtype=np.float32) + audio_values = np.empty((0, 0), dtype=np.float32) + audio_valid = np.empty((0,), dtype=np.bool_) + + try: + ( + vision_times, face_values, face_valid, vision_values, vision_valid, + vision_names, decoded_frames, + ) = models.vision_features(video_path) + except Exception as error: + errors["vision_features"] = f"{type(error).__name__}: {error}" + vision_times = np.empty((0,), dtype=np.float32) + face_values = np.empty((0, VISION_DIM), dtype=np.float32) + face_valid = np.empty((0,), dtype=np.bool_) + vision_values = np.empty((0, models.vision_dim), dtype=np.float32) + vision_valid = np.empty((0,), dtype=np.bool_) + vision_names = [f"blendshape_{index:02d}" for index in range(VISION_DIM)] + decoded_frames = 0 + + if words and word_intervals.shape[0] == len(words): + if audio_values.shape[1] if audio_values.ndim == 2 else 0: + audio_word, audio_word_valid, audio_word_fallback = _mean_by_intervals( + audio_times, audio_values, audio_valid, word_intervals + ) + else: + audio_word = np.empty((len(words), 0), dtype=np.float32) + audio_word_valid = np.zeros((len(words),), dtype=np.bool_) + audio_word_fallback = np.zeros((len(words),), dtype=np.bool_) + vision_word, vision_word_valid, vision_word_fallback = _mean_by_intervals( + vision_times, vision_values, vision_valid, word_intervals + ) + face_word, face_word_valid, face_word_fallback = _mean_by_intervals( + vision_times, face_values, face_valid, word_intervals + ) + else: + audio_word = np.empty((0, audio_values.shape[1] if audio_values.ndim == 2 else 0), dtype=np.float32) + audio_word_valid = np.empty((0,), dtype=np.bool_) + audio_word_fallback = np.empty((0,), dtype=np.bool_) + vision_word = np.empty((0, models.vision_dim), dtype=np.float32) + vision_word_valid = np.empty((0,), dtype=np.bool_) + vision_word_fallback = np.empty((0,), dtype=np.bool_) + face_word = np.empty((0, VISION_DIM), dtype=np.float32) + face_word_valid = np.empty((0,), dtype=np.bool_) + face_word_fallback = np.empty((0,), dtype=np.bool_) + + if not np.any(face_valid): + warnings.append("no_face_blendshapes_detected") + sample_key = f"{record['video_id']}/{record['clip_id']}" + arrays = { + "text_words": np.asarray(words, dtype=f"U{max((len(word) for word in words), default=1)}"), + "text_features": text_values.astype(np.float16), + "word_intervals_s": word_intervals.astype(np.float32), + "word_alignment_confidence": word_confidence.astype(np.float32), + "word_alignment_valid": word_align_valid.astype(np.bool_), + "audio_times_s": audio_times.astype(np.float32), + "audio_features": audio_values.astype(np.float16), + "audio_valid": audio_valid.astype(np.bool_), + "audio_feature_names": np.asarray(audio_columns, dtype="U96"), + "vision_times_s": vision_times.astype(np.float32), + "vision_features": vision_values.astype(np.float16), + "vision_valid": vision_valid.astype(np.bool_), + "vision_feature_names": np.asarray([f"vit_cls_{index:03d}" for index in range(models.vision_dim)], dtype="U32"), + "face_blendshape_features": face_values.astype(np.float16), + "face_blendshape_valid": face_valid.astype(np.bool_), + "face_blendshape_names": np.asarray(vision_names, dtype="U64"), + "audio_word_features": audio_word.astype(np.float16), + "audio_word_valid": audio_word_valid.astype(np.bool_), + "audio_word_nearest_fallback": audio_word_fallback.astype(np.bool_), + "vision_word_features": vision_word.astype(np.float16), + "vision_word_valid": vision_word_valid.astype(np.bool_), + "vision_word_nearest_fallback": vision_word_fallback.astype(np.bool_), + "face_word_features": face_word.astype(np.float16), + "face_word_valid": face_word_valid.astype(np.bool_), + "face_word_nearest_fallback": face_word_fallback.astype(np.bool_), + } + info = { + "sample_id": sample_key, + "video_id": str(record["video_id"]), + "clip_id": str(record["clip_id"]), + "text": str(record.get("text") or ""), + "label": record.get("label"), + "annotation": str(record.get("annotation") or ""), + "video_path": str(video_path), + "duration_s": duration_s, + "ctc_inference_succeeded": ctc_success, + "word_count": len(words), + "word_alignment_valid_count": int(word_align_valid.sum()), + "audio_raw_length": int(len(audio_times)), + "audio_valid_length": int(audio_valid.sum()), + "audio_feature_dim": int(audio_values.shape[1]) if audio_values.ndim == 2 else 0, + "vision_raw_length": int(len(vision_times)), + "vision_valid_length": int(vision_valid.sum()), + "vision_feature_dim": models.vision_dim, + "face_blendshape_valid_length": int(face_valid.sum()), + "face_blendshape_feature_dim": VISION_DIM, + "vision_decoded_source_frames": int(decoded_frames), + "text_feature_dim": models.text_dim, + "alignment_granularity": "transcript word; Audio/Vision pooled over forced CTC word interval", + "errors": errors, + "warnings": warnings, + } + return ExtractedSample(arrays=arrays, info=info) + + +def _save_npz(path: Path, arrays: dict[str, np.ndarray]) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + temporary = path.with_suffix(path.suffix + ".tmp") + with temporary.open("wb") as file: + np.savez_compressed(file, **arrays) + temporary.replace(path) + + +def _sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as file: + for chunk in iter(lambda: file.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def _write_csv(path: Path, rows: list[dict[str, Any]], fieldnames: list[str]) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("w", encoding="utf-8-sig", newline="") as file: + writer = csv.DictWriter(file, fieldnames=fieldnames, extrasaction="ignore") + writer.writeheader() + writer.writerows(rows) + + +def _create_typical_figure( + info: dict[str, Any], npz_path: Path, video_path: Path, output_path: Path +) -> None: + import matplotlib + matplotlib.use("Agg") + import matplotlib.pyplot as plt + + with np.load(npz_path, allow_pickle=False) as data: + words = data["text_words"].astype(str) + intervals = data["word_intervals_s"].astype(np.float32) + audio_times = data["audio_times_s"].astype(np.float32) + audio = data["audio_features"].astype(np.float32) + audio_names = data["audio_feature_names"].astype(str) + vision_times = data["vision_times_s"].astype(np.float32) + vision_valid = data["vision_valid"].astype(bool) + if not len(words): + return + mid = len(words) // 2 + start_word = max(0, mid - 6) + end_word = min(len(words), start_word + 12) + start_word = max(0, end_word - 12) + chosen = np.arange(start_word, end_word) + if not chosen.size: + return + left = float(intervals[chosen[0], 0]) + right = float(intervals[chosen[-1], 1]) + if right <= left: + left, right = 0.0, max(info["duration_s"], 0.1) + + figure = plt.figure(figsize=(15, 10), constrained_layout=True) + layout = figure.add_gridspec(3, 1, height_ratios=(1.0, max(2.0, len(chosen) * 0.25), 1.5)) + audio_axis = figure.add_subplot(layout[0, 0]) + word_axis = figure.add_subplot(layout[1, 0], sharex=audio_axis) + frame_axis = figure.add_subplot(layout[2, 0]) + + if audio.shape[0] and audio.shape[1]: + keep = (audio_times >= left) & (audio_times <= right) + selected_audio = audio[keep] + selected_times = audio_times[keep] + if selected_audio.size: + normalized = (selected_audio - np.nanmedian(selected_audio, axis=0, keepdims=True)) + scales = np.nanstd(normalized, axis=0, keepdims=True) + normalized = normalized / np.where(scales < 1e-6, 1.0, scales) + count = min(12, normalized.shape[1]) + image = audio_axis.imshow( + normalized[:, :count].T, + aspect="auto", origin="lower", interpolation="nearest", + extent=(float(selected_times[0]), float(selected_times[-1]), -0.5, count - 0.5), + cmap="coolwarm", vmin=-2.5, vmax=2.5, + ) + labels = audio_names[:count] + audio_axis.set_yticks(np.arange(count), labels=labels, fontsize=7) + figure.colorbar(image, ax=audio_axis, label="per-clip z-score", fraction=0.02, pad=0.01) + audio_axis.set_xlim(left, right) + audio_axis.set_title("eGeMAPSv02 low-level speech features on the selected word interval") + audio_axis.set_ylabel("audio descriptor") + audio_axis.tick_params(axis="x", labelbottom=True) + + word_axis.set_ylim(-0.7, len(chosen) - 0.3) + word_axis.set_yticks(chosen - chosen[0], labels=[words[index] for index in chosen], fontsize=8) + for row_index, word_index in enumerate(chosen): + word_start, word_end = intervals[word_index] + word_axis.broken_barh( + [(float(word_start), max(0.015, float(word_end - word_start)))], + (row_index - 0.32, 0.64), + facecolors="#2878B5", alpha=0.8, + ) + word_axis.text(float(word_start), row_index, f" {word_start:.2f}–{word_end:.2f}s", va="center", fontsize=7) + word_axis.set_xlim(left, right) + word_axis.set_xlabel("time from clip start (seconds)") + word_axis.set_title("Transcript words mapped to their forced CTC audio intervals") + word_axis.grid(axis="x", alpha=0.25) + + cap = cv2.VideoCapture(str(video_path)) + candidate_times = vision_times[(vision_times >= left) & (vision_times <= right)] + if not candidate_times.size: + candidate_times = np.linspace(left, right, min(6, max(1, len(chosen)))) + if candidate_times.size > 6: + candidate_times = candidate_times[np.linspace(0, len(candidate_times) - 1, 6).round().astype(int)] + frame_images: list[tuple[float, np.ndarray]] = [] + for timestamp in candidate_times: + cap.set(cv2.CAP_PROP_POS_MSEC, float(timestamp) * 1000) + ok, bgr = cap.read() + if ok: + rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) + frame_images.append((float(timestamp), rgb)) + cap.release() + frame_axis.axis("off") + if frame_images: + subgrid = layout[2, 0].subgridspec(1, len(frame_images), wspace=0.03) + for index, (timestamp, image) in enumerate(frame_images): + axis = figure.add_subplot(subgrid[0, index]) + axis.imshow(image) + axis.set_title(f"video t={timestamp:.2f}s", fontsize=9) + axis.axis("off") + else: + frame_axis.text(0.5, 0.5, "No decodable video frames in this interval", ha="center", va="center") + figure.suptitle( + f"Q1 typical sample: {info['sample_id']}\n" + f"Transcript snippet: {' '.join(words[chosen])}\n" + "Text words → forced speech intervals → sampled video frames", + fontsize=13, + ) + output_path.parent.mkdir(parents=True, exist_ok=True) + figure.savefig(output_path, dpi=160) + plt.close(figure) + + +def run_extraction( + video_root: Path, + label_file: Path, + output_dir: Path, + model_dir: Path, + cache_dir: Path | None, + start: int = 0, + limit: int | None = None, + resume: bool = False, +) -> dict[str, Any]: + records = _read_labels(label_file) + selected = records[start:] if limit is None else records[start:start + limit] + if not selected: + raise ValueError("the requested sample range is empty") + features_dir = output_dir / "features" + logs_dir = output_dir / "logs" + reports_dir = output_dir / "reports" + features_dir.mkdir(parents=True, exist_ok=True) + logs_dir.mkdir(parents=True, exist_ok=True) + reports_dir.mkdir(parents=True, exist_ok=True) + log_path = logs_dir / "extraction.log" + LOGGER.setLevel(logging.INFO) + LOGGER.handlers.clear() + formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s") + stream = logging.StreamHandler(sys.stdout) + stream.setFormatter(formatter) + file_handler = logging.FileHandler(log_path, encoding="utf-8") + file_handler.setFormatter(formatter) + LOGGER.addHandler(stream) + LOGGER.addHandler(file_handler) + + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + LOGGER.info("Using %s", device) + models = FeatureModels(device, model_dir / "face_landmarker.task", cache_dir=cache_dir) + log_jsonl_path = logs_dir / "samples.jsonl" + existing: dict[str, dict[str, Any]] = {} + if resume and log_jsonl_path.exists(): + for line in log_jsonl_path.read_text(encoding="utf-8").splitlines(): + try: + entry = json.loads(line) + existing[entry["sample_id"]] = entry + except (json.JSONDecodeError, KeyError): + continue + completed: list[dict[str, Any]] = [] + sample_log = log_jsonl_path.open("a" if resume else "w", encoding="utf-8") + try: + for index, record in enumerate(selected, start=start): + video_id, clip_id = str(record["video_id"]), str(record["clip_id"]) + sample_id = f"{video_id}/{clip_id}" + output_path = features_dir / f"{_safe_id(video_id)}__{_safe_id(clip_id)}.npz" + if resume and sample_id in existing and output_path.exists(): + info = existing[sample_id] + completed.append(info) + LOGGER.info("[%d/%d] resume existing %s", index + 1, len(records), sample_id) + continue + video_path = video_root / video_id / f"{clip_id}.mp4" + begin = time.perf_counter() + if not video_path.is_file(): + info = { + "sample_id": sample_id, "video_id": video_id, "clip_id": clip_id, + "text": str(record.get("text") or ""), "label": record.get("label"), + "annotation": str(record.get("annotation") or ""), "video_path": str(video_path), + "duration_s": 0.0, "errors": {"input": "source video file missing"}, + "warnings": [], "text_feature_dim": models.text_dim, + "audio_feature_dim": 0, "vision_feature_dim": models.vision_dim, + "face_blendshape_valid_length": 0, "face_blendshape_feature_dim": VISION_DIM, + "word_count": 0, "word_alignment_valid_count": 0, + "audio_raw_length": 0, "audio_valid_length": 0, + "vision_raw_length": 0, "vision_valid_length": 0, + "alignment_granularity": "transcript word; Audio/Vision pooled over forced CTC word interval", + } + empty = { + **_empty_text_arrays(models.text_dim), + "word_intervals_s": np.empty((0, 2), dtype=np.float32), + "word_alignment_confidence": np.empty((0,), dtype=np.float32), + "word_alignment_valid": np.empty((0,), dtype=np.bool_), + "audio_times_s": np.empty((0,), dtype=np.float32), + "audio_features": np.empty((0, 0), dtype=np.float16), + "audio_valid": np.empty((0,), dtype=np.bool_), + "audio_feature_names": np.empty((0,), dtype="U1"), + "vision_times_s": np.empty((0,), dtype=np.float32), + "vision_features": np.empty((0, models.vision_dim), dtype=np.float16), + "vision_valid": np.empty((0,), dtype=np.bool_), + "vision_feature_names": np.asarray([f"vit_cls_{i:03d}" for i in range(models.vision_dim)], dtype="U32"), + "face_blendshape_features": np.empty((0, VISION_DIM), dtype=np.float16), + "face_blendshape_valid": np.empty((0,), dtype=np.bool_), + "face_blendshape_names": np.asarray([f"blendshape_{i:02d}" for i in range(VISION_DIM)], dtype="U32"), + "audio_word_features": np.empty((0, 0), dtype=np.float16), + "audio_word_valid": np.empty((0,), dtype=np.bool_), + "audio_word_nearest_fallback": np.empty((0,), dtype=np.bool_), + "vision_word_features": np.empty((0, models.vision_dim), dtype=np.float16), + "vision_word_valid": np.empty((0,), dtype=np.bool_), + "vision_word_nearest_fallback": np.empty((0,), dtype=np.bool_), + "face_word_features": np.empty((0, VISION_DIM), dtype=np.float16), + "face_word_valid": np.empty((0,), dtype=np.bool_), + "face_word_nearest_fallback": np.empty((0,), dtype=np.bool_), + } + _save_npz(output_path, empty) + else: + try: + extracted = extract_sample(models, video_path, record) + info = extracted.info + _save_npz(output_path, extracted.arrays) + except Exception as error: + LOGGER.exception("Sample-level extraction failed for %s", sample_id) + info = { + "sample_id": sample_id, "video_id": video_id, "clip_id": clip_id, + "text": str(record.get("text") or ""), "label": record.get("label"), + "annotation": str(record.get("annotation") or ""), "video_path": str(video_path), + "duration_s": 0.0, "errors": {"sample": f"{type(error).__name__}: {error}"}, + "warnings": [], "text_feature_dim": models.text_dim, + "audio_feature_dim": 0, "vision_feature_dim": models.vision_dim, + "face_blendshape_valid_length": 0, "face_blendshape_feature_dim": VISION_DIM, + "word_count": 0, "word_alignment_valid_count": 0, + "audio_raw_length": 0, "audio_valid_length": 0, + "vision_raw_length": 0, "vision_valid_length": 0, + "alignment_granularity": "transcript word; Audio/Vision pooled over forced CTC word interval", + } + # A failed sample still has a corresponding record instead of being omitted. + _save_npz(output_path, { + **_empty_text_arrays(models.text_dim), + "word_intervals_s": np.empty((0, 2), dtype=np.float32), + "word_alignment_confidence": np.empty((0,), dtype=np.float32), + "word_alignment_valid": np.empty((0,), dtype=np.bool_), + "audio_times_s": np.empty((0,), dtype=np.float32), + "audio_features": np.empty((0, 0), dtype=np.float16), + "audio_valid": np.empty((0,), dtype=np.bool_), + "audio_feature_names": np.empty((0,), dtype="U1"), + "vision_times_s": np.empty((0,), dtype=np.float32), + "vision_features": np.empty((0, models.vision_dim), dtype=np.float16), + "vision_valid": np.empty((0,), dtype=np.bool_), + "vision_feature_names": np.asarray([f"vit_cls_{i:03d}" for i in range(models.vision_dim)], dtype="U32"), + "face_blendshape_features": np.empty((0, VISION_DIM), dtype=np.float16), + "face_blendshape_valid": np.empty((0,), dtype=np.bool_), + "face_blendshape_names": np.asarray([f"blendshape_{i:02d}" for i in range(VISION_DIM)], dtype="U32"), + "audio_word_features": np.empty((0, 0), dtype=np.float16), + "audio_word_valid": np.empty((0,), dtype=np.bool_), + "audio_word_nearest_fallback": np.empty((0,), dtype=np.bool_), + "vision_word_features": np.empty((0, models.vision_dim), dtype=np.float16), + "vision_word_valid": np.empty((0,), dtype=np.bool_), + "vision_word_nearest_fallback": np.empty((0,), dtype=np.bool_), + "face_word_features": np.empty((0, VISION_DIM), dtype=np.float16), + "face_word_valid": np.empty((0,), dtype=np.bool_), + "face_word_nearest_fallback": np.empty((0,), dtype=np.bool_), + }) + info["processing_seconds"] = round(time.perf_counter() - begin, 3) + info["feature_file"] = str(output_path) + info["feature_file_bytes"] = output_path.stat().st_size + info["feature_file_sha256"] = _sha256(output_path) + sample_log.write(json.dumps(info, ensure_ascii=False, default=str) + "\n") + sample_log.flush() + completed.append(info) + errors = info.get("errors", {}) + LOGGER.info( + "[%d/%d] %s duration=%.3fs words=%d audio=%d vision=%d errors=%s time=%.1fs", + index + 1, len(records), sample_id, info.get("duration_s", 0.0), + info.get("word_count", 0), info.get("audio_raw_length", 0), + info.get("vision_raw_length", 0), ",".join(errors) or "none", + info["processing_seconds"], + ) + finally: + sample_log.close() + + detailed_rows: list[dict[str, Any]] = [] + for info in completed: + for modality in ("text", "audio", "vision"): + if modality == "text": + length, valid_length, dimension = ( + info.get("word_count", 0), info.get("word_alignment_valid_count", 0), info.get("text_feature_dim", 0) + ) + granularity = "transcript word" + elif modality == "audio": + length, valid_length, dimension = ( + info.get("audio_raw_length", 0), info.get("audio_valid_length", 0), info.get("audio_feature_dim", 0) + ) + granularity = "eGeMAPSv02 LLD frame (~10 ms)" + else: + length, valid_length, dimension = ( + info.get("vision_raw_length", 0), info.get("vision_valid_length", 0), info.get("vision_feature_dim", VISION_DIM) + ) + granularity = f"sampled frame ({VISION_FPS:g} fps), ViT CLS; optional 52-d face blendshape" + detailed_rows.append({ + "sample_id": info.get("sample_id"), "video_id": info.get("video_id"), + "clip_id": info.get("clip_id"), "modality": modality, + "effective_duration_s": info.get("duration_s", 0.0), + "feature_dimension": dimension, "sequence_length": length, + "valid_length": valid_length, "padding_rule": "no on-disk padding; per-sample variable length", + "alignment_granularity": granularity, + "source_time_mapping": "seconds from clip start; text tokens map to word_intervals_s", + "feature_file": info.get("feature_file", ""), + "status": "error" if info.get("errors") else "ok_with_warning" if info.get("warnings") else "ok", + "errors": json.dumps(info.get("errors", {}), ensure_ascii=False), + "warnings": json.dumps(info.get("warnings", []), ensure_ascii=False), + }) + _write_csv( + reports_dir / "feature_summary_100x3.csv", detailed_rows, + ["sample_id", "video_id", "clip_id", "modality", "effective_duration_s", "feature_dimension", + "sequence_length", "valid_length", "padding_rule", "alignment_granularity", "source_time_mapping", + "feature_file", "status", "errors", "warnings"], + ) + _write_csv( + reports_dir / "sample_summary.csv", completed, + ["sample_id", "video_id", "clip_id", "duration_s", "word_count", "word_alignment_valid_count", + "text_feature_dim", "audio_raw_length", "audio_valid_length", "audio_feature_dim", "vision_raw_length", + "vision_valid_length", "vision_feature_dim", "face_blendshape_valid_length", "face_blendshape_feature_dim", + "ctc_inference_succeeded", "alignment_granularity", + "feature_file", "feature_file_bytes", "errors", "warnings"], + ) + + manifest = { + "created_at_utc": datetime.now(timezone.utc).isoformat(), + "command": sys.argv, + "python": sys.version, + "platform": platform.platform(), + "uv_version": _tool_version("uv"), + "device": str(device), + "cuda_available": bool(torch.cuda.is_available()), + "torch_cuda_build": torch.version.cuda, + "cudnn_version": torch.backends.cudnn.version(), + "gpu_name": torch.cuda.get_device_name(0) if torch.cuda.is_available() else None, + "external_tools": { + "ffmpeg": _tool_version("ffmpeg"), + "ffprobe": _tool_version("ffprobe"), + }, + "package_versions": { + name: _package_version(name) for name in ( + "torch", "torchvision", "transformers", "tokenizers", "mediapipe", "opencv-python-headless", + "opensmile", "numpy", "soundfile", "openpyxl", "matplotlib", "Pillow", + ) + }, + "models": { + "text": { + "id": TEXT_MODEL_ID, + "revision": getattr(models.text_model.config, "_commit_hash", None), + "representation": "mean of final-layer BERT subtokens per supplied whitespace token", + }, + "forced_alignment": { + "id": CTC_MODEL_ID, + "revision": getattr(models.ctc_model.config, "_commit_hash", None), + "algorithm": "CTC Viterbi over supplied transcript; clip-relative seconds", + }, + "audio": {"set": "eGeMAPSv02", "level": "LowLevelDescriptors", "sample_rate_hz": AUDIO_SAMPLE_RATE}, + "vision": { + "model": VISION_MODEL_ID, + "revision": getattr(models.vision_model.config, "_commit_hash", None), + "representation": "DeiT final-layer CLS embedding for every sampled frame", + "sample_rate_fps": VISION_FPS, + "supplemental_face_feature": "MediaPipe Face Landmarker 52 blendshape scores with face_blendshape_valid mask", + }, + }, + "alignment": { + "granularity": "word-level", + "primary_rule": "forced CTC transcript word intervals; mean Audio LLD and DeiT frame embeddings inside interval", + "empty_window_rule": "nearest valid source frame; fallback flags are retained in NPZ", + "missing_face_rule": "DeiT frame embeddings remain valid; face blendshapes are zero with face_blendshape_valid=false", + "storage": "compressed NPZ; values float16, times float32, masks bool; no padding in per-sample files", + }, + "face_landmarker_asset": { + "path": str(models.vision_model_path), + "sha256": _sha256(models.vision_model_path), + "size_bytes": models.vision_model_path.stat().st_size, + }, + "inputs": {"video_root": str(video_root), "label_file": str(label_file), "label_sha256": _sha256(label_file)}, + "outputs": {"feature_dir": str(features_dir), "summary": str(reports_dir / "feature_summary_100x3.csv"), "sample_table": str(reports_dir / "sample_summary.csv"), "sample_log": str(log_jsonl_path)}, + "requested_sample_range": {"start": start, "limit": limit, "selected_count": len(selected)}, + "completed_count": len(completed), + "sample_errors": sum(bool(item.get("errors")) for item in completed), + "sample_warnings": sum(bool(item.get("warnings")) for item in completed), + "aggregate_feature_bytes": sum(int(item.get("feature_file_bytes", 0)) for item in completed), + } + manifest_path = reports_dir / "run_manifest.json" + manifest_path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2, default=str), encoding="utf-8") + + candidates = [ + item for item in completed + if item.get("vision_valid_length", 0) > 0 and item.get("word_alignment_valid_count", 0) > 0 + ] + if candidates: + typical = max( + candidates, + key=lambda item: ( + min(item.get("vision_valid_length", 0), 12) + min(item.get("word_alignment_valid_count", 0), 12), + -abs(item.get("duration_s", 0.0) - 12.0), + ), + ) + _create_typical_figure( + typical, + Path(typical["feature_file"]), + Path(typical["video_path"]), + reports_dir / f"typical_sample_{_safe_id(typical['video_id'])}__{_safe_id(typical['clip_id'])}.png", + ) + manifest["typical_sample_id"] = typical["sample_id"] + manifest_path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2, default=str), encoding="utf-8") + return manifest + + +def main() -> int: + project_dir = Path(__file__).resolve().parents[1] + repo_dir = project_dir.parent + default_video_root = repo_dir / "E题数据" / "附件1-数据集原始多模态样本" / "MOSEI数据集部分原始视频-100条" + parser = argparse.ArgumentParser(description="Extract timestamped Q1 Text, Audio, and Vision features from Attachment 1.") + parser.add_argument("--video-root", type=Path, default=default_video_root) + parser.add_argument("--labels", type=Path, default=default_video_root / "label-100.xlsx") + parser.add_argument("--output-dir", type=Path, default=project_dir / "outputs") + parser.add_argument("--model-dir", type=Path, default=project_dir / "models") + parser.add_argument("--cache-dir", type=Path, default=None) + parser.add_argument("--start", type=int, default=0, help="zero-based row offset in label workbook") + parser.add_argument("--limit", type=int, default=None, help="number of rows; omit for all remaining rows") + parser.add_argument("--resume", action="store_true", help="reuse already completed sample files/log entries") + args = parser.parse_args() + manifest = run_extraction( + args.video_root, args.labels, args.output_dir, args.model_dir, args.cache_dir, + start=args.start, limit=args.limit, resume=args.resume, + ) + print(json.dumps(manifest, ensure_ascii=False, indent=2, default=str)) + return 0 if manifest["sample_errors"] == 0 else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/deep_learning/Q1/q1/losses.py b/deep_learning/Q1/q1/losses.py new file mode 100644 index 0000000..ddd04f9 --- /dev/null +++ b/deep_learning/Q1/q1/losses.py @@ -0,0 +1,175 @@ +from __future__ import annotations + +from collections.abc import Mapping + +import torch +import torch.nn.functional as F +from torch import Tensor + +from .metrics import attention_row_similarity +from .types import AlignmentOutput, MODALITIES + + +def temporal_monotonicity_loss( + output: AlignmentOutput, + times: Mapping[str, Tensor], + durations: Tensor, + epsilon: float = 0.02, +) -> Tensor: + """Penalize backward motion on the normalized clip timeline.""" + if epsilon < 0: + raise ValueError("epsilon must be non-negative") + losses = [] + for name in MODALITIES: + mu = torch.bmm(output.weights[name], times[name].unsqueeze(-1)).squeeze(-1) + mu = mu / durations[:, None].clamp_min(torch.finfo(mu.dtype).eps) + backward = F.relu(mu[:, :-1] - mu[:, 1:] - epsilon) + losses.append(backward.square().mean()) + return torch.stack(losses).mean() + + +def cross_modal_contrastive_loss( + aligned: Mapping[str, Tensor], temperature: float = 0.1 +) -> Tensor: + """Symmetric in-batch InfoNCE over same-sample, same-grid-slot positives.""" + if temperature <= 0: + raise ValueError("temperature must be positive") + if set(aligned) != set(MODALITIES): + raise ValueError(f"aligned must contain exactly {MODALITIES}") + pair_losses = [] + for left_index, left_name in enumerate(MODALITIES): + for right_name in MODALITIES[left_index + 1 :]: + left = F.normalize(aligned[left_name].flatten(0, 1), dim=-1) + right = F.normalize(aligned[right_name].flatten(0, 1), dim=-1) + if left.shape != right.shape: + raise ValueError("contrastive representations must share [B, K, D]") + logits = left @ right.T / temperature + labels = torch.arange(logits.shape[0], device=logits.device) + pair_losses.append( + (F.cross_entropy(logits, labels) + F.cross_entropy(logits.T, labels)) / 2 + ) + return torch.stack(pair_losses).mean() + + +def masked_reconstruction_loss(prediction: Tensor, target: Tensor, mask: Tensor) -> Tensor: + """Smooth-L1 loss over masked grid slots only.""" + if prediction.shape != target.shape: + raise ValueError("prediction and target must have the same shape") + if mask.shape != target.shape[:2] or mask.dtype != torch.bool: + raise ValueError("mask must be boolean with shape [B, K]") + if not bool(mask.any()): + raise ValueError("mask must select at least one target slot") + element_loss = F.smooth_l1_loss(prediction, target, reduction="none") + return element_loss[mask].mean() + + +def temporal_span_loss( + output: AlignmentOutput, + times: Mapping[str, Tensor], + durations: Tensor, + minimum_span: float = 0.7, + modalities: tuple[str, ...] = MODALITIES, +) -> Tensor: + """Penalize an expected-time path that does not cover enough of a clip.""" + if not 0.0 <= minimum_span <= 1.0: + raise ValueError("minimum_span must be in [0, 1]") + if not modalities or any(name not in MODALITIES for name in modalities): + raise ValueError("modalities must be a non-empty subset of MODALITIES") + losses = [] + for name in modalities: + mu = torch.bmm(output.weights[name], times[name].unsqueeze(-1)).squeeze(-1) + mu = mu / durations[:, None].clamp_min(torch.finfo(mu.dtype).eps) + span = mu[:, -1] - mu[:, 0] + losses.append(F.relu(minimum_span - span).square().mean()) + return torch.stack(losses).mean() + + +def attention_diversity_loss( + output: AlignmentOutput, + modalities: tuple[str, ...] = MODALITIES, + min_separation: int = 6, +) -> Tensor: + """Penalize similar attention rows for slots far apart on the grid.""" + if min_separation < 1: + raise ValueError("min_separation must be at least one") + if not modalities or any(name not in MODALITIES for name in modalities): + raise ValueError("modalities must be a non-empty subset of MODALITIES") + return torch.stack( + [attention_row_similarity(output.weights[name], min_separation).mean() for name in modalities] + ).mean() + + +def weak_temporal_band_loss( + output: AlignmentOutput, + times: Mapping[str, Tensor], + durations: Tensor, + targets: Mapping[str, Tensor], + margin: float = 0.1, +) -> Tensor: + """Allow soft alignment while keeping expected times near weak slot anchors.""" + if margin < 0: + raise ValueError("margin must be non-negative") + if not targets: + return next(iter(output.weights.values())).sum() * 0.0 + losses = [] + for name, target in targets.items(): + if name not in MODALITIES: + raise ValueError(f"unknown modality in temporal targets: {name}") + mu = torch.bmm(output.weights[name], times[name].unsqueeze(-1)).squeeze(-1) + mu = mu / durations[:, None].clamp_min(torch.finfo(mu.dtype).eps) + if target.shape != mu.shape: + raise ValueError(f"band target for {name} must have shape {tuple(mu.shape)}") + distance = (mu - target).abs() + losses.append(F.relu(distance - margin).square().mean()) + return torch.stack(losses).mean() + + +def alignment_training_loss( + output: AlignmentOutput, + times: Mapping[str, Tensor], + durations: Tensor, + reconstruction: Tensor, + *, + lambda_rec: float = 1.0, + lambda_con: float = 1.0, + lambda_mono: float = 0.1, + lambda_span: float = 0.0, + lambda_div: float = 0.0, + lambda_band: float = 0.0, + epsilon: float = 0.02, + minimum_span: float = 0.7, + coverage_modalities: tuple[str, ...] = MODALITIES, + diversity_modalities: tuple[str, ...] = MODALITIES, + diversity_min_separation: int = 6, + band_targets: Mapping[str, Tensor] | None = None, + band_margin: float = 0.1, +) -> tuple[Tensor, dict[str, Tensor]]: + """Shared M3/M4 training objective; emotion labels are deliberately unused.""" + contrastive = cross_modal_contrastive_loss(output.aligned) + monotonicity = temporal_monotonicity_loss(output, times, durations, epsilon) + span = temporal_span_loss( + output, times, durations, minimum_span, modalities=coverage_modalities + ) + diversity = attention_diversity_loss( + output, diversity_modalities, min_separation=diversity_min_separation + ) + band = weak_temporal_band_loss( + output, times, durations, band_targets or {}, margin=band_margin + ) + total = ( + lambda_rec * reconstruction + + lambda_con * contrastive + + lambda_mono * monotonicity + + lambda_span * span + + lambda_div * diversity + + lambda_band * band + ) + return total, { + "reconstruction": reconstruction, + "contrastive": contrastive, + "monotonicity": monotonicity, + "span": span, + "diversity": diversity, + "band": band, + "total": total, + } diff --git a/deep_learning/Q1/q1/m4_shared_latent_eval.py b/deep_learning/Q1/q1/m4_shared_latent_eval.py new file mode 100644 index 0000000..2bdb044 --- /dev/null +++ b/deep_learning/Q1/q1/m4_shared_latent_eval.py @@ -0,0 +1,1204 @@ +"""Re-evaluate frozen M4 Shared Latent Timeline checkpoints structurally and functionally. + +No alignment model is trained here. The five grouped D5 M4_sourceTime +checkpoints are evaluated with self-structure, induced pairwise maps, cycle and +triangle consistency, content-only probes, content shuffling, and shifted +reconstruction controls. +""" + +from __future__ import annotations + +import argparse +import csv +import json +import platform +import time +from collections import defaultdict +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Mapping, Sequence + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import torch +import torch.nn.functional as F +from sklearn.metrics import roc_auc_score +from torch import Tensor, nn + +from .correspondence_eval import ( + CorrespondenceProjection, + _cluster_bootstrap, + _fit_probe, + _sample_metrics, + _stack_ids, + _write_csv, +) +from .experiment_data import ( + FeatureSample, + FeatureStats, + collate_feature_samples, + fit_feature_stats, + load_feature_samples, +) +from .models import SharedLatentTimeline +from .types import MODALITIES + + +GRID_SIZE = 50 +HIDDEN_SIZE = 128 +HEADS = 4 +PAIRINGS = (("text", "audio"), ("text", "vision"), ("audio", "vision")) +STRUCTURE_RADIUS = 2 +FAR_RADIUS = 10 +SIGMA_SELF = 0.08 +SIGMA_CYCLE = 0.05 +SHIFTS = (1, 2, 5, 10) +DECODER_TARGETS = { + "audio": ("text", "vision", "vision"), + "vision": ("text", "audio", "audio"), + "text": ("audio", "vision", "vision"), +} + + +class ContentReconstructionProbe(nn.Module): + """Small decoder that sees two content streams and no slot/position code.""" + + def __init__(self, dimension: int = HIDDEN_SIZE) -> None: + super().__init__() + self.decoders = nn.ModuleDict( + { + target: nn.Sequential( + nn.Linear(dimension * 2, dimension * 2), + nn.GELU(), + nn.Linear(dimension * 2, dimension), + ) + for target in MODALITIES + } + ) + + def forward(self, target: str, left: Tensor, right: Tensor) -> Tensor: + return self.decoders[target](torch.cat((left, right), dim=-1)) + + +def _bootstrap_summary( + rows: Sequence[Mapping[str, Any]], + group_keys: Sequence[str], + metric_names: Sequence[str], + *, + seed: int, + repetitions: int = 2000, +) -> list[dict[str, Any]]: + grouped: dict[tuple[Any, ...], list[Mapping[str, Any]]] = defaultdict(list) + for row in rows: + grouped[tuple(row[key] for key in group_keys)].append(row) + output: list[dict[str, Any]] = [] + for key, values in sorted(grouped.items(), key=lambda item: tuple(str(x) for x in item[0])): + result: dict[str, Any] = dict(zip(group_keys, key)) + result["clip_count"] = len({row.get("sample_id") for row in values}) + result["video_id_count"] = len({str(row["video_id"]) for row in values}) + for metric_index, metric in enumerate(metric_names): + selected = [row for row in values if row.get(metric) not in (None, "")] + if not selected: + continue + mean, low, high, group_count = _cluster_bootstrap( + selected, + metric, + seed=seed + metric_index + sum(ord(char) for char in str(key)), + repetitions=repetitions, + ) + result[f"{metric}_video_macro_mean"] = mean + result[f"{metric}_ci95_low"] = low + result[f"{metric}_ci95_high"] = high + result["video_id_count"] = group_count + output.append(result) + return output + + +def _normalize_attention( + weights: np.ndarray, valid: np.ndarray +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """Return source-position-to-slot probabilities and supported source indices.""" + matrix = np.asarray(weights, dtype=np.float64) + valid_indices = np.flatnonzero(valid) + column_mass = matrix[:, valid_indices].sum(axis=0) + supported = column_mass > 1e-12 + indices = valid_indices[supported] + if len(indices) == 0: + raise ValueError("attention has no source positions supported by any latent slot") + normalized = matrix[:, indices] / column_mass[supported][None, :] + return normalized, indices, column_mass + + +def _pair_map( + source_weights: np.ndarray, + source_valid: np.ndarray, + destination_weights: np.ndarray, + destination_valid: np.ndarray, +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """Construct C^(source->destination) after column-normalizing source attention.""" + source_to_slot, source_indices, _ = _normalize_attention(source_weights, source_valid) + destination_indices = np.flatnonzero(destination_valid) + slot_to_destination = np.asarray(destination_weights, dtype=np.float64)[:, destination_indices] + mapping = source_to_slot.T @ slot_to_destination + row_mass = mapping.sum(axis=1, keepdims=True) + mapping = mapping / np.maximum(row_mass, 1e-12) + return mapping.astype(np.float32), source_indices, destination_indices + + +def _self_structure( + weights: np.ndarray, *, sigma: float = SIGMA_SELF +) -> tuple[np.ndarray, dict[str, float]]: + normalized = weights / np.maximum(np.linalg.norm(weights, axis=1, keepdims=True), 1e-12) + gram = normalized @ normalized.T + positions = (np.arange(gram.shape[0], dtype=np.float64) + 0.5) / gram.shape[0] + distances = np.abs(positions[:, None] - positions[None, :]) + near = distances <= STRUCTURE_RADIUS / GRID_SIZE + far = distances >= FAR_RADIUS / GRID_SIZE + far_leakage = distances > FAR_RADIUS / GRID_SIZE + near_off_diagonal = near & ~np.eye(len(gram), dtype=bool) + target = np.exp(-(distances**2) / (2 * sigma**2)) + near_mean = float(gram[near].mean()) + far_mean = float(gram[far].mean()) + near_off_diagonal_mean = float(gram[near_off_diagonal].mean()) + result = { + # Keep the literal <= r definition from the task, and report an + # off-diagonal version so the trivial unit diagonal cannot dominate. + "near_similarity": near_mean, + "near_similarity_offdiag": near_off_diagonal_mean, + "far_similarity": far_mean, + "d_self": float(near_mean - far_mean), + "d_self_offdiag": float(near_off_diagonal_mean - far_mean), + "gram_target_error": float(np.linalg.norm(gram - target) / max(np.linalg.norm(target), 1e-12)), + "far_slot_leakage": float(gram[far_leakage].sum() / max(gram.sum(), 1e-12)), + "c_row_offdiag": float(gram[~np.eye(len(gram), dtype=bool)].mean()), + } + return gram.astype(np.float32), result + + +def _pair_metrics( + mapping: np.ndarray, + source_times: np.ndarray, + destination_times: np.ndarray, +) -> dict[str, float]: + row_sums = mapping.sum(axis=1) + predicted = (mapping @ destination_times) / np.maximum(row_sums, 1e-12) + error = predicted - source_times + return { + "pairwise_time_mae": float(np.abs(error).mean()), + "pairwise_signed_lag": float(error.mean()), + "pairwise_time_corr": float(np.corrcoef(source_times, predicted)[0, 1]) + if len(source_times) > 1 and np.std(predicted) > 1e-12 and np.std(source_times) > 1e-12 + else 0.0, + "source_position_count": int(len(source_times)), + "destination_position_count": int(len(destination_times)), + } + + +def _band_target(times: np.ndarray, sigma: float) -> np.ndarray: + distances = times[:, None] - times[None, :] + target = np.exp(-(distances**2) / (2 * sigma**2)) + return target / np.maximum(target.sum(axis=1, keepdims=True), 1e-12) + + +def _cycle_triangle_metrics( + maps: Mapping[str, tuple[np.ndarray, np.ndarray, np.ndarray]], + normalized_times: Mapping[str, np.ndarray], +) -> tuple[list[dict[str, Any]], dict[str, np.ndarray]]: + cycle_rows = [] + cycles: dict[str, np.ndarray] = {} + for left, right in PAIRINGS: + forward_key = f"{left}_{right}" + reverse_key = f"{right}_{left}" + forward, source_idx, destination_idx = maps[forward_key] + reverse, reverse_source_idx, reverse_destination_idx = maps[reverse_key] + if not np.array_equal(destination_idx, reverse_source_idx) or not np.array_equal( + source_idx, reverse_destination_idx + ): + raise ValueError(f"pair map source supports disagree for {forward_key}/{reverse_key}") + cycle = forward @ reverse + times = normalized_times[left][source_idx] + target = _band_target(times, SIGMA_CYCLE) + pred_times = cycle @ times + cycle_rows.append( + { + "kind": f"cycle_{left}_{right}_{left}", + "cycle_band_error": float(np.linalg.norm(cycle - target) / max(np.linalg.norm(target), 1e-12)), + "cycle_time_mae": float(np.abs(pred_times - times).mean()), + } + ) + cycles[f"cycle_{left}_{right}_{left}"] = cycle.astype(np.float32) + + c_ta = maps["text_audio"][0] + c_av = maps["audio_vision"][0] + c_tv = maps["text_vision"][0] + if c_ta.shape[1] != c_av.shape[0] or c_ta.shape[0] != c_tv.shape[0] or c_av.shape[1] != c_tv.shape[1]: + raise ValueError("T-A, A-V, and T-V supports disagree; cannot calculate triangle consistency") + path = c_ta @ c_av + triangle_residual = path - c_tv + cycles["triangle_TAV_residual"] = triangle_residual.astype(np.float32) + cycle_rows.append( + { + "kind": "triangle_TAV", + "triangle_relative_error": float( + np.linalg.norm(triangle_residual) / max(np.linalg.norm(c_tv), 1e-12) + ), + "triangle_mean_absolute_residual": float(np.abs(triangle_residual).mean()), + } + ) + return cycle_rows, cycles + + +def _checkpoint_path(root: Path, fold: int) -> Path: + if fold == 1: + return root / "M4_sourceTime" / "checkpoint.pt" + return root / f"fold_{fold:02d}" / "M4_sourceTime" / "checkpoint.pt" + + +def _collect_fold( + *, + fold: int, + train_samples: Sequence[FeatureSample], + validation_samples: Sequence[FeatureSample], + stats: FeatureStats, + checkpoint_root: Path, + device: torch.device, + batch_size: int, +) -> tuple[dict[str, dict[str, np.ndarray]], dict[str, dict[str, np.ndarray]]]: + checkpoint_path = _checkpoint_path(checkpoint_root, fold) + if not checkpoint_path.is_file(): + raise FileNotFoundError(f"missing M4_sourceTime checkpoint for fold {fold}: {checkpoint_path}") + checkpoint = torch.load(checkpoint_path, map_location=device, weights_only=False) + if checkpoint.get("variant") != "M4_sourceTime" or not checkpoint.get("source_time_encoding"): + raise ValueError(f"checkpoint is not M4_sourceTime: {checkpoint_path}") + if set(checkpoint.get("train_sample_ids", [])) != {sample.sample_id for sample in train_samples}: + raise ValueError(f"M4 checkpoint training IDs do not match fold {fold}") + if set(checkpoint.get("validation_sample_ids", [])) != {sample.sample_id for sample in validation_samples}: + raise ValueError(f"M4 checkpoint validation IDs do not match fold {fold}") + + dimensions = {name: train_samples[0].features[name].shape[1] for name in MODALITIES} + model = SharedLatentTimeline( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + absolute_position_encoding=True, + source_time_encoding=True, + ).to(device) + model.load_state_dict(checkpoint["model_state_dict"], strict=True) + model.eval() + weights_by_id: dict[str, dict[str, np.ndarray]] = {} + content_by_id: dict[str, dict[str, np.ndarray]] = {} + with torch.no_grad(): + samples = [*train_samples, *validation_samples] + for start in range(0, len(samples), batch_size): + batch_samples = samples[start : start + batch_size] + sequences, durations, _ = collate_feature_samples(batch_samples, stats, device) + output = model(sequences, durations) + for index, sample in enumerate(batch_samples): + weights: dict[str, np.ndarray] = {} + content: dict[str, np.ndarray] = {} + for name in MODALITIES: + length = len(sample.features[name]) + weights[name] = output.weights[name][index, :, :length].detach().cpu().numpy().astype(np.float32) + # M4's returned values are A^m V^m: content values pooled by attention. + # Positional/query vectors are not concatenated into this representation. + content[name] = output.aligned[name][index].detach().cpu().numpy().astype(np.float32) + weights_by_id[sample.sample_id] = weights + content_by_id[sample.sample_id] = content + del model + if device.type == "cuda": + torch.cuda.empty_cache() + return weights_by_id, content_by_id + + +def _pairwise_for_sample( + sample: FeatureSample, + weights: Mapping[str, np.ndarray], +) -> tuple[dict[str, tuple[np.ndarray, np.ndarray, np.ndarray]], dict[str, np.ndarray], list[dict[str, Any]], dict[str, np.ndarray]]: + normalized_times = { + name: np.asarray(sample.times[name], dtype=np.float64) / max(sample.duration_s, 1e-8) + for name in MODALITIES + } + pair_maps: dict[str, tuple[np.ndarray, np.ndarray, np.ndarray]] = {} + pair_rows: list[dict[str, Any]] = [] + self_grams: dict[str, np.ndarray] = {} + for name in MODALITIES: + gram, metrics = _self_structure(weights[name]) + self_grams[name] = gram + pair_rows.append( + {"kind": "self", "modality": name, **metrics} + ) + directions = (*PAIRINGS, *((right, left) for left, right in PAIRINGS)) + for left, right in directions: + mapping, source_idx, destination_idx = _pair_map( + weights[left], sample.valid[left], weights[right], sample.valid[right] + ) + key = f"{left}_{right}" + pair_maps[key] = (mapping, source_idx, destination_idx) + source_times = normalized_times[left][source_idx] + destination_times = normalized_times[right][destination_idx] + pair_rows.append( + { + "kind": "pairwise", + "direction": f"{left}_to_{right}", + **_pair_metrics(mapping, source_times, destination_times), + } + ) + cycle_rows, cycle_maps = _cycle_triangle_metrics(pair_maps, normalized_times) + for row in cycle_rows: + row["kind_group"] = "cycle_triangle" + pair_rows.append(row) + return pair_maps, normalized_times, pair_rows, {**self_grams, **cycle_maps} + + +def _fit_reconstruction_probe( + train_ids: Sequence[str], + content_by_id: Mapping[str, Mapping[str, np.ndarray]], + *, + device: torch.device, + seed: int, + epochs: int, + batch_size: int, + learning_rate: float, +) -> tuple[ContentReconstructionProbe, list[dict[str, Any]]]: + torch.manual_seed(seed) + if device.type == "cuda": + torch.cuda.manual_seed_all(seed) + train = _stack_ids(train_ids, content_by_id, device) + model = ContentReconstructionProbe(train["text"].shape[-1]).to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=learning_rate, weight_decay=1e-4) + rng = np.random.default_rng(seed) + history = [] + model.train() + for epoch in range(1, epochs + 1): + order = rng.permutation(len(train_ids)) + losses = [] + for start in range(0, len(order), batch_size): + indexes = torch.as_tensor(order[start : start + batch_size], device=device) + batch = {name: value.index_select(0, indexes) for name, value in train.items()} + targets = [] + for target in MODALITIES: + left, right, _ = DECODER_TARGETS[target] + prediction = model(target, batch[left], batch[right]) + targets.append(F.smooth_l1_loss(prediction, batch[target])) + loss = torch.stack(targets).mean() + if not torch.isfinite(loss): + raise FloatingPointError(f"non-finite content reconstruction loss at epoch {epoch}") + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 1.0) + optimizer.step() + losses.append(float(loss.detach().item())) + history.append({"epoch": epoch, "train_loss": float(np.mean(losses))}) + return model, history + + +def _content_pair_metrics( + scores: np.ndarray, + *, + method: str, + fold: int, + sample: FeatureSample, + pair: str, + control: str, + shuffle_id: int | None = None, +) -> dict[str, Any]: + k = scores.shape[0] + diag = np.diag(scores) + indexes = np.arange(k) + negative_mask = np.abs(indexes[:, None] - indexes[None, :]) > 2 + auc = roc_auc_score( + np.r_[np.ones(k), np.zeros(int(negative_mask.sum()))], + np.r_[diag, scores[negative_mask]], + ) + row_pred = scores.argmax(axis=1) + col_pred = scores.T.argmax(axis=1) + row_err = np.abs(row_pred - indexes) + col_err = np.abs(col_pred - indexes) + result: dict[str, Any] = { + "method": method, + "control": control, + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "pair": pair, + "same_time_similarity": float(diag.mean()), + "shifted_far_similarity": float( + np.mean( + [scores[indexes[: k - d], indexes[d:]].mean() for d in range(3, 11)] + + [scores[indexes[d:], indexes[: k - d]].mean() for d in range(3, 11)] + ) + ), + "same_minus_shifted_margin": float( + diag.mean() + - np.mean( + [scores[indexes[: k - d], indexes[d:]].mean() for d in range(3, 11)] + + [scores[indexes[d:], indexes[: k - d]].mean() for d in range(3, 11)] + ) + ), + "matched_vs_shifted_auc": float(auc), + "exact_r1_left_to_right": float(np.mean(row_err == 0)), + "within_pm1_r1_left_to_right": float(np.mean(row_err <= 1)), + "mase_slots_left_to_right": float(row_err.mean()), + "exact_r1_right_to_left": float(np.mean(col_err == 0)), + "within_pm1_r1_right_to_left": float(np.mean(col_err <= 1)), + "mase_slots_right_to_left": float(col_err.mean()), + } + if shuffle_id is not None: + result["shuffle_id"] = shuffle_id + return result + + +def _fit_and_score_content( + *, + fold: int, + train_samples: Sequence[FeatureSample], + validation_samples: Sequence[FeatureSample], + content_by_id: Mapping[str, Mapping[str, np.ndarray]], + device: torch.device, + args: argparse.Namespace, + probe_seeds: dict[str, Any], +) -> tuple[list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]], dict[str, Any]]: + train_ids = [sample.sample_id for sample in train_samples] + val_ids = [sample.sample_id for sample in validation_samples] + probe_seed = args.seed + fold * 101 + projector, projection_history = _fit_probe( + train_ids, + content_by_id, + device=device, + seed=probe_seed, + epochs=args.probe_epochs, + batch_size=args.batch_size, + learning_rate=args.learning_rate, + temperature=args.temperature, + ) + for row in projection_history: + probe_seeds.setdefault("history", []).append( + {"fold": fold, "probe": "content_projection", "seed": probe_seed, **row} + ) + projector.eval() + with torch.no_grad(): + validation = _stack_ids(val_ids, content_by_id, device) + projected = projector(validation) + + normal_rows: list[dict[str, Any]] = [] + curve_rows: list[dict[str, Any]] = [] + for index, sample in enumerate(validation_samples): + one = {name: projected[name][index] for name in MODALITIES} + normal_rows.extend( + _sample_metrics( + method="M4_sourceTime_content", + fold=fold, + sample=sample, + projected=one, + curve_rows=curve_rows, + ) + ) + + rng = np.random.default_rng(probe_seed + 17) + shuffle_rows = [] + with torch.no_grad(): + for shuffle_id in range(args.shuffle_repeats): + for index, sample in enumerate(validation_samples): + permuted = {} + for name in MODALITIES: + permutation = torch.as_tensor(rng.permutation(GRID_SIZE), device=device) + permuted[name] = projected[name][index].index_select(0, permutation) + for left, right in PAIRINGS: + scores = (permuted[left] @ permuted[right].T).detach().cpu().numpy() + shuffle_rows.append( + _content_pair_metrics( + scores, + method="M4_sourceTime_content", + fold=fold, + sample=sample, + pair=f"{left}_{right}", + control="independent_within_clip_permutation", + shuffle_id=shuffle_id, + ) + ) + + probe_seeds[f"fold_{fold:02d}/content_projection"] = { + "seed": probe_seed, + "state_dict": {key: value.detach().cpu() for key, value in projector.state_dict().items()}, + } + del projector + if device.type == "cuda": + torch.cuda.empty_cache() + return normal_rows, curve_rows, shuffle_rows, probe_seeds + + +def _fit_and_score_reconstruction( + *, + fold: int, + train_samples: Sequence[FeatureSample], + validation_samples: Sequence[FeatureSample], + content_by_id: Mapping[str, Mapping[str, np.ndarray]], + device: torch.device, + args: argparse.Namespace, + checkpoint_store: dict[str, Any], + history_store: list[dict[str, Any]], +) -> list[dict[str, Any]]: + seed = args.seed + fold * 211 + decoder, history = _fit_reconstruction_probe( + [sample.sample_id for sample in train_samples], + content_by_id, + device=device, + seed=seed, + epochs=args.decoder_epochs, + batch_size=args.batch_size, + learning_rate=args.decoder_learning_rate, + ) + history_store.extend( + {"fold": fold, "probe": "content_reconstruction", "seed": seed, **row} + for row in history + ) + decoder.eval() + validation = _stack_ids([sample.sample_id for sample in validation_samples], content_by_id, device) + rows = [] + with torch.no_grad(): + for target, (left, right, shifted_modality) in DECODER_TARGETS.items(): + for sample_index, sample in enumerate(validation_samples): + left_values = validation[left][sample_index] + right_values = validation[right][sample_index] + target_values = validation[target][sample_index] + for delta in (*(-value for value in SHIFTS), *SHIFTS): + source_indices = np.arange(max(0, -delta), min(GRID_SIZE, GRID_SIZE - delta)) + shifted_indices = source_indices + delta + target_idx = torch.as_tensor(source_indices, device=device) + shifted_idx = torch.as_tensor(shifted_indices, device=device) + left_eval = left_values.index_select(0, target_idx) + right_aligned = right_values.index_select(0, target_idx) + right_shifted = ( + right_values.index_select(0, shifted_idx) + if shifted_modality == right + else right_aligned + ) + left_shifted = ( + left_values.index_select(0, shifted_idx) + if shifted_modality == left + else left_eval + ) + aligned_pred = decoder(target, left_eval, right_aligned) + shifted_pred = decoder(target, left_shifted, right_shifted) + target_eval = target_values.index_select(0, target_idx) + aligned_mae = float((aligned_pred - target_eval).abs().mean().item()) + shifted_mae = float((shifted_pred - target_eval).abs().mean().item()) + rows.append( + { + "method": "M4_sourceTime", + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "target_modality": target, + "shifted_modality": shifted_modality, + "delta": delta, + "abs_delta": abs(delta), + "aligned_mae_same_support": aligned_mae, + "shifted_mae": shifted_mae, + "gain_shift_minus_aligned": shifted_mae - aligned_mae, + } + ) + checkpoint_store[f"fold_{fold:02d}/content_reconstruction"] = { + "seed": seed, + "state_dict": {key: value.detach().cpu() for key, value in decoder.state_dict().items()}, + } + del decoder + if device.type == "cuda": + torch.cuda.empty_cache() + return rows + + +def _plot_self_gram(grams: Mapping[str, np.ndarray], path: Path) -> None: + fig, axes = plt.subplots(1, 3, figsize=(13, 4.4), sharex=True, sharey=True, constrained_layout=True) + for axis, name in zip(axes, MODALITIES, strict=True): + image = axis.imshow(grams[name], origin="lower", aspect="equal", vmin=0, vmax=1, cmap="magma") + axis.set_title(name.title()) + axis.set_xlabel("Latent slot k") + axis.set_xticks([0, 9, 19, 29, 39, 49]) + axis.set_yticks([0, 9, 19, 29, 39, 49]) + axes[0].set_ylabel("Latent slot i") + fig.colorbar(image, ax=axes, fraction=0.025, pad=0.02, label="Cosine similarity of attention rows") + fig.suptitle("M4 self-structure: pairwise similarity between latent slots") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _time_cell_edges(times: np.ndarray) -> np.ndarray: + """Convert ordered sample centers to physical-time cell boundaries.""" + times = np.asarray(times, dtype=np.float64) + if len(times) == 0: + raise ValueError("cannot plot an empty time axis") + if len(times) == 1: + return np.array([times[0] - 0.005, times[0] + 0.005]) + if np.any(np.diff(times) < 0): + raise ValueError("feature times must be ordered for time-faithful heatmaps") + midpoints = (times[:-1] + times[1:]) / 2 + first = times[0] - (midpoints[0] - times[0]) + last = times[-1] + (times[-1] - midpoints[-1]) + return np.concatenate(([first], midpoints, [last])) + + +def _plot_attention( + weights: Mapping[str, np.ndarray], + times: Mapping[str, np.ndarray], + valid: Mapping[str, np.ndarray], + path: Path, +) -> None: + fig, axes = plt.subplots(1, 3, figsize=(15, 4.8), sharey=True, constrained_layout=True) + slot_edges = np.arange(GRID_SIZE + 1, dtype=np.float64) - 0.5 + for axis, name in zip(axes, MODALITIES, strict=True): + mask = np.asarray(valid[name], dtype=bool) + source_times = np.asarray(times[name], dtype=np.float64)[mask] + matrix = np.asarray(weights[name], dtype=np.float64)[:, mask] + image = axis.pcolormesh( + _time_cell_edges(source_times), + slot_edges, + matrix, + shading="flat", + cmap="magma", + ) + axis.set_title(name.title()) + axis.set_xlabel(f"{name.title()} normalized source time") + axis.set_yticks([0, 9, 19, 29, 39, 49]) + axes[0].set_ylabel("Shared latent slot") + fig.colorbar(image, ax=axes, fraction=0.025, pad=0.02, label="Attention weight") + fig.suptitle("M4 latent slots attending to each modality's source timeline") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_pairwise( + maps: Mapping[str, tuple[np.ndarray, np.ndarray, np.ndarray]], + times: Mapping[str, np.ndarray], + path: Path, +) -> None: + directions = (("text", "audio"), ("text", "vision"), ("audio", "vision")) + fig, axes = plt.subplots(1, 3, figsize=(16, 4.8), constrained_layout=True) + for axis, (left, right) in zip(axes, directions, strict=True): + matrix, source_idx, destination_idx = maps[f"{left}_{right}"] + source_times = times[left][source_idx] + destination_times = times[right][destination_idx] + image = axis.pcolormesh( + _time_cell_edges(destination_times), + _time_cell_edges(source_times), + matrix, + shading="flat", + cmap="magma", + ) + axis.set_title(f"{left.title()} → {right.title()}") + axis.set_xlabel(f"{right.title()} normalized time") + axis.set_ylabel(f"{left.title()} normalized time") + fig.colorbar(image, ax=axes, fraction=0.025, pad=0.02, label="Pairwise transition probability") + fig.suptitle("M4 modality-to-modality maps induced through the shared latent timeline") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_pair_trajectories( + maps: Mapping[str, tuple[np.ndarray, np.ndarray, np.ndarray]], + times: Mapping[str, np.ndarray], + path: Path, +) -> None: + fig, axes = plt.subplots(1, 3, figsize=(15, 4.6), sharex=True, sharey=True) + for axis, (left, right) in zip(axes, (("text", "audio"), ("text", "vision"), ("audio", "vision")), strict=True): + matrix, source_idx, destination_idx = maps[f"{left}_{right}"] + x = times[left][source_idx] + y = matrix @ times[right][destination_idx] + axis.plot(x, y, color="#2673b8", linewidth=1.2, marker=".", markersize=2) + axis.plot([0, 1], [0, 1], color="black", linestyle="--", linewidth=1) + axis.set_title(f"{left.title()} → {right.title()}") + axis.set_xlabel(f"{left.title()} source time") + axis.grid(alpha=0.2) + axes[0].set_ylabel("Expected destination time") + fig.suptitle("Pairwise temporal trajectories; diagonal indicates equal physical time") + fig.tight_layout() + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_cycles(cycles: Mapping[str, np.ndarray], path: Path) -> None: + names = ("cycle_text_audio_text", "cycle_text_vision_text", "cycle_audio_vision_audio") + fig, axes = plt.subplots(1, 4, figsize=(17, 4.4), constrained_layout=True) + for axis, name in zip(axes[:3], names, strict=True): + image = axis.imshow(cycles[name], origin="lower", aspect="auto", cmap="magma") + axis.set_title(name.replace("cycle_", "").replace("_", "→")) + axis.set_xlabel("Source position") + axis.set_ylabel("Source position") + residual = np.abs(cycles["triangle_TAV_residual"]) + image = axes[3].imshow(residual, origin="lower", aspect="auto", cmap="viridis") + axes[3].set_title("|T→A→V − T→V|") + axes[3].set_xlabel("Vision position") + axes[3].set_ylabel("Text position") + fig.colorbar(image, ax=axes, fraction=0.024, pad=0.02, label="Return / path residual") + fig.suptitle("Cycle transition maps and triangle-path residual") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_content_curve(rows: Sequence[Mapping[str, Any]], path: Path) -> None: + colors = {"text_audio": "#2878b5", "text_vision": "#e1812c", "audio_vision": "#55a868"} + fig, axes = plt.subplots(1, 3, figsize=(14, 4.3), sharey=True) + for axis, pair in zip(axes, colors, strict=True): + xs, means, lows, highs = [], [], [], [] + for delta in range(-10, 11): + selected = [row for row in rows if row["pair"] == pair and int(row["delta"]) == delta] + if not selected: + continue + mean, low, high, _ = _cluster_bootstrap( + selected, + "similarity", + seed=7301 + delta + sum(ord(char) for char in pair), + repetitions=1000, + ) + xs.append(delta) + means.append(mean) + lows.append(low) + highs.append(high) + axis.plot(xs, means, color=colors[pair], linewidth=1.1, marker="o", markersize=3) + axis.fill_between(xs, lows, highs, color=colors[pair], alpha=0.16) + axis.axvline(0, color="black", linestyle="--", linewidth=0.8) + axis.set_title(pair.replace("_", "–")) + axis.set_xlabel("Temporal shift Δ (slots)") + axis.grid(alpha=0.2) + axes[0].set_ylabel("Content-only cosine similarity") + fig.suptitle("M4 content-only same-slot vs shifted similarity (video_id bootstrap CI)") + fig.tight_layout() + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_shuffle(normal: Sequence[Mapping[str, Any]], shuffled: Sequence[Mapping[str, Any]], path: Path) -> None: + pairs = [f"{left}_{right}" for left, right in PAIRINGS] + normal_means = [] + shuffle_means = [] + for pair in pairs: + nr = [row for row in normal if row["pair"] == pair] + sr = [row for row in shuffled if row["pair"] == pair] + normal_means.append(_cluster_bootstrap(nr, "matched_vs_shifted_auc", seed=921)[0]) + shuffle_means.append(_cluster_bootstrap(sr, "matched_vs_shifted_auc", seed=922)[0]) + positions = np.arange(len(pairs)) + fig, axis = plt.subplots(figsize=(8, 4.6)) + width = 0.34 + axis.bar(positions - width / 2, normal_means, width, label="Content as aligned", color="#2878b5") + axis.bar(positions + width / 2, shuffle_means, width, label="Independent slot shuffle", color="#c44e52") + axis.axhline(0.5, color="black", linestyle="--", linewidth=0.9, label="Chance AUC") + axis.set_xticks(positions, [pair.replace("_", "–") for pair in pairs]) + axis.set_ylim(0.35, 0.8) + axis.set_ylabel("Matched-vs-shifted AUC") + axis.set_title("Content shuffle control") + axis.legend(frameon=False) + axis.grid(axis="y", alpha=0.2) + fig.tight_layout() + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_reconstruction_gain(rows: Sequence[Mapping[str, Any]], path: Path) -> None: + targets = ("audio", "vision", "text") + colors = {"audio": "#2878b5", "vision": "#e1812c", "text": "#55a868"} + fig, axis = plt.subplots(figsize=(8, 5)) + for target in targets: + selected = [row for row in rows if row["target_modality"] == target] + by_abs: dict[int, list[dict[str, Any]]] = defaultdict(list) + for row in selected: + by_abs[int(row["abs_delta"])].append(dict(row)) + xs = sorted(by_abs) + means, lows, highs = [], [], [] + for distance in xs: + mean, low, high, _ = _cluster_bootstrap( + by_abs[distance], + "gain_shift_minus_aligned", + seed=991 + distance + sum(ord(char) for char in target), + repetitions=1000, + ) + means.append(mean) + lows.append(low) + highs.append(high) + axis.plot(xs, means, marker="o", color=colors[target], label=f"Reconstruct {target}") + axis.fill_between(xs, lows, highs, color=colors[target], alpha=0.15) + axis.axhline(0, color="black", linestyle="--", linewidth=0.9) + axis.set_xlabel("Absolute temporal shift |Δ| (slots)") + axis.set_ylabel("MAE(shifted) − MAE(aligned)") + axis.set_title("Does the aligned partner help reconstruct the target content?") + axis.legend(frameon=False) + axis.grid(alpha=0.2) + fig.tight_layout() + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def run(args: argparse.Namespace) -> dict[str, Any]: + started = time.time() + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is unavailable") + samples = load_feature_samples(args.feature_dir, args.manifest) + by_id = {sample.sample_id: sample for sample in samples} + splits = json.loads(args.splits.read_text(encoding="utf-8")) + output_dir = args.output_dir + output_dir.mkdir(parents=True, exist_ok=True) + + self_rows: list[dict[str, Any]] = [] + pair_rows: list[dict[str, Any]] = [] + cycle_triangle_rows: list[dict[str, Any]] = [] + content_rows: list[dict[str, Any]] = [] + content_curve_rows: list[dict[str, Any]] = [] + shuffle_rows: list[dict[str, Any]] = [] + reconstruction_rows: list[dict[str, Any]] = [] + probe_history: list[dict[str, Any]] = [] + probe_checkpoints: dict[str, Any] = {} + fold_manifests = [] + example_id = args.example_id + example_arrays: dict[str, np.ndarray] | None = None + example_times: dict[str, np.ndarray] | None = None + example_pair_maps: dict[str, tuple[np.ndarray, np.ndarray, np.ndarray]] | None = None + example_self_grams: dict[str, np.ndarray] | None = None + example_cycles: dict[str, np.ndarray] | None = None + example_weights: dict[str, np.ndarray] | None = None + example_valid: dict[str, np.ndarray] | None = None + + for split in splits: + fold = int(split["fold"]) + train_samples = [by_id[sample_id] for sample_id in split["train_sample_ids"]] + validation_samples = [by_id[sample_id] for sample_id in split["validation_sample_ids"]] + train_groups = {sample.group_id for sample in train_samples} + validation_groups = {sample.group_id for sample in validation_samples} + if train_groups & validation_groups: + raise ValueError(f"video_id leakage in fold {fold}") + if example_id is not None and example_id not in {sample.sample_id for sample in validation_samples} and fold == 1: + # The requested example can be left out; evaluation still covers all held-out clips. + example_id = None + stats = fit_feature_stats(train_samples) + weights_by_id, content_by_id = _collect_fold( + fold=fold, + train_samples=train_samples, + validation_samples=validation_samples, + stats=stats, + checkpoint_root=args.checkpoint_root, + device=device, + batch_size=args.batch_size, + ) + fold_manifests.append( + { + "fold": fold, + "train_count": len(train_samples), + "heldout_count": len(validation_samples), + "train_video_ids": sorted(train_groups), + "heldout_video_ids": sorted(validation_groups), + "overlap": sorted(train_groups & validation_groups), + } + ) + print( + f"[M4 evaluation fold {fold}] train={len(train_samples)} heldout={len(validation_samples)} " + f"video_ids={len(train_groups)}/{len(validation_groups)}", + flush=True, + ) + + for sample in validation_samples: + maps, normalized_times, sample_rows, arrays = _pairwise_for_sample( + sample, weights_by_id[sample.sample_id] + ) + for row in sample_rows: + row.update({"method": "M4_sourceTime", "fold": fold, "sample_id": sample.sample_id, "video_id": sample.group_id}) + if row["kind"] == "self": + self_rows.append(row) + elif row["kind"] == "pairwise": + pair_rows.append(row) + else: + cycle_triangle_rows.append(row) + if example_id == sample.sample_id or (example_id is None and sample.sample_id == "-3g5yACwYnA/13"): + example_id = sample.sample_id + example_pair_maps = maps + example_times = normalized_times + example_self_grams = {name: arrays[name] for name in MODALITIES} + example_cycles = {name: arrays[name] for name in arrays if name.startswith("cycle_") or name.startswith("triangle_")} + example_weights = weights_by_id[sample.sample_id] + example_valid = {name: np.asarray(sample.valid[name], dtype=bool) for name in MODALITIES} + example_arrays = {} + for left, right in (*PAIRINGS, *((right, left) for left, right in PAIRINGS)): + mapping, source_idx, destination_idx = maps[f"{left}_{right}"] + example_arrays[f"C_{left}_{right}"] = mapping + example_arrays[f"source_indices_{left}_{right}"] = source_idx + example_arrays[f"destination_indices_{left}_{right}"] = destination_idx + for name in MODALITIES: + example_arrays[f"G_{name}"] = arrays[name] + example_arrays[f"A_{name}"] = weights_by_id[sample.sample_id][name] + example_arrays[f"tau_{name}"] = normalized_times[name] + example_arrays[f"valid_{name}"] = np.asarray(sample.valid[name], dtype=bool) + example_arrays.update(example_cycles) + + normal, curves, shuffled, probe_checkpoints = _fit_and_score_content( + fold=fold, + train_samples=train_samples, + validation_samples=validation_samples, + content_by_id=content_by_id, + device=device, + args=args, + probe_seeds=probe_checkpoints, + ) + content_rows.extend(normal) + content_curve_rows.extend(curves) + shuffle_rows.extend(shuffled) + probe_history.extend(probe_checkpoints.pop("history", [])) + reconstruction_rows.extend( + _fit_and_score_reconstruction( + fold=fold, + train_samples=train_samples, + validation_samples=validation_samples, + content_by_id=content_by_id, + device=device, + args=args, + checkpoint_store=probe_checkpoints, + history_store=probe_history, + ) + ) + print( + f"[M4 evaluation fold {fold}] content_probe={len(normal)} pair rows; " + f"shuffle repeats={args.shuffle_repeats}; reconstruction rows={len(reconstruction_rows)}", + flush=True, + ) + del weights_by_id, content_by_id + if device.type == "cuda": + torch.cuda.empty_cache() + + if example_arrays is not None: + np.savez_compressed(output_dir / "example_m4_shared_latent_maps.npz", **example_arrays) + assert example_pair_maps is not None and example_times is not None + assert example_self_grams is not None and example_cycles is not None + assert example_weights is not None and example_valid is not None + _plot_attention(example_weights, example_times, example_valid, output_dir / "latent_attention_heatmaps.png") + _plot_self_gram(example_self_grams, output_dir / "self_gram_heatmaps.png") + _plot_pairwise(example_pair_maps, example_times, output_dir / "pairwise_heatmaps.png") + _plot_pair_trajectories(example_pair_maps, example_times, output_dir / "pairwise_trajectories.png") + _plot_cycles(example_cycles, output_dir / "cycle_triangle_maps.png") + + self_summary = _bootstrap_summary( + self_rows, + ("method", "modality"), + ("near_similarity", "near_similarity_offdiag", "far_similarity", "d_self", "d_self_offdiag", "gram_target_error", "far_slot_leakage", "c_row_offdiag"), + seed=args.seed, + ) + pair_summary = _bootstrap_summary( + pair_rows, + ("method", "direction"), + ("pairwise_time_mae", "pairwise_signed_lag", "pairwise_time_corr"), + seed=args.seed + 1, + ) + cycle_triangle_summary = _bootstrap_summary( + cycle_triangle_rows, + ("method", "kind"), + ("cycle_band_error", "cycle_time_mae", "triangle_relative_error", "triangle_mean_absolute_residual"), + seed=args.seed + 2, + ) + content_summary, content_curve_summary = _content_summary(content_rows, content_curve_rows, args.seed + 3) + shuffle_summary = _bootstrap_summary( + shuffle_rows, + ("method", "control", "pair"), + ("same_time_similarity", "same_minus_shifted_margin", "matched_vs_shifted_auc", + "exact_r1_left_to_right", "within_pm1_r1_left_to_right", "mase_slots_left_to_right"), + seed=args.seed + 4, + ) + reconstruction_summary = _bootstrap_summary( + reconstruction_rows, + ("method", "target_modality", "shifted_modality", "abs_delta"), + ("aligned_mae_same_support", "shifted_mae", "gain_shift_minus_aligned"), + seed=args.seed + 5, + ) + + _write_csv(output_dir / "self_structure_by_clip.csv", self_rows) + _write_csv(output_dir / "self_structure_summary.csv", self_summary) + _write_csv(output_dir / "pairwise_by_clip.csv", pair_rows) + _write_csv(output_dir / "pairwise_summary.csv", pair_summary) + _write_csv(output_dir / "cycle_triangle_by_clip.csv", cycle_triangle_rows) + _write_csv(output_dir / "cycle_triangle_summary.csv", cycle_triangle_summary) + _write_csv(output_dir / "content_only_metrics_by_clip.csv", content_rows) + _write_csv(output_dir / "content_only_metrics_summary.csv", content_summary) + _write_csv(output_dir / "content_shift_curve_by_clip.csv", content_curve_rows) + _write_csv(output_dir / "content_shift_curve_summary.csv", content_curve_summary) + _write_csv(output_dir / "content_shuffle_by_clip.csv", shuffle_rows) + _write_csv(output_dir / "content_shuffle_summary.csv", shuffle_summary) + _write_csv(output_dir / "shifted_reconstruction_by_clip.csv", reconstruction_rows) + _write_csv(output_dir / "shifted_reconstruction_summary.csv", reconstruction_summary) + _write_csv(output_dir / "probe_training_history.csv", probe_history) + torch.save(probe_checkpoints, output_dir / "content_probe_checkpoints.pt") + + _plot_content_curve(content_curve_rows, output_dir / "content_only_shifted_similarity.png") + _plot_shuffle(content_rows, shuffle_rows, output_dir / "content_shuffle_control.png") + _plot_reconstruction_gain(reconstruction_rows, output_dir / "shifted_reconstruction_gain.png") + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "experiment": "M4 Shared Latent Timeline re-evaluation", + "alignment_model_retrained": False, + "checkpoint_variant": "M4_sourceTime", + "sample_count": len(samples), + "fold_count": len(splits), + "folds": fold_manifests, + "example_sample_id": example_id, + "parameters": { + "seed": args.seed, + "batch_size": args.batch_size, + "grid_size": GRID_SIZE, + "hidden_size": HIDDEN_SIZE, + "heads": HEADS, + "sigma_self_normalized_time": SIGMA_SELF, + "near_radius_slots": STRUCTURE_RADIUS, + "far_radius_slots": FAR_RADIUS, + "sigma_cycle_normalized_time": SIGMA_CYCLE, + "content_projection_dimension": 64, + "content_probe_epochs": args.probe_epochs, + "content_probe_learning_rate": args.learning_rate, + "contrastive_temperature": args.temperature, + "content_shuffle_repeats": args.shuffle_repeats, + "reconstruction_probe_epochs": args.decoder_epochs, + "reconstruction_probe_learning_rate": args.decoder_learning_rate, + "reconstruction_shifts_slots": list(SHIFTS), + "probe_seed_rule": "seed + fold * 101", + "reconstruction_seed_rule": "seed + fold * 211", + }, + "input_paths": { + "feature_dir": str(args.feature_dir.resolve()), + "feature_manifest": str(args.manifest.resolve()), + "grouped_splits": str(args.splits.resolve()), + "checkpoint_root": str(args.checkpoint_root.resolve()), + "alignment_checkpoints": [ + str(_checkpoint_path(args.checkpoint_root, int(split["fold"])).resolve()) + for split in splits + ], + }, + "content_only_definition": "M4 output.aligned = attention weights times projected source values; no latent query vector or positional embedding is concatenated into the probe input", + "functional_protocol": { + "probe_training": "train-fold only, symmetric within-clip same-slot InfoNCE; no emotion labels", + "shuffle": "independently permute each modality's 50 content rows within each held-out clip; keep row/slot index labels fixed; 20 permutations", + "reconstruction": "train-fold decoder predicts one M4 value stream from the other two; at evaluation shift one partner stream by signed offsets +/-1,2,5,10 and compare MAE on identical valid target slots", + "confidence_intervals": "95% cluster bootstrap over video_id groups, 2,000 repetitions for CSV summaries; 1,000 for figure ribbons", + }, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "elapsed_seconds": time.time() - started, + "interpretation_limits": [ + "Self Gram, pairwise maps, cycle, and triangle are structural consistency checks, not independent semantic ground truth.", + "The content projection and reconstruction decoder are learned on training video groups and evaluated on held-out groups; their results measure transferable probe utility.", + "The time-code M4 alignment checkpoint was trained with a timestamp-derived Gaussian prior, so its attention can still encode a position shortcut.", + "Human event IoU and center-error validation remain unavailable until event intervals are annotated.", + "The D5 alignment checkpoints use one alignment training seed; bootstrap intervals describe video-group sampling uncertainty, not seed uncertainty.", + ], + } + (output_dir / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + print( + f"[M4 evaluation complete] samples={len(samples)} folds={len(splits)} " + f"elapsed={manifest['elapsed_seconds']:.1f}s output={output_dir}", + flush=True, + ) + return manifest + + +def _content_summary( + rows: Sequence[Mapping[str, Any]], + curves: Sequence[Mapping[str, Any]], + seed: int, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + metrics = ( + "same_time_similarity", + "shifted_far_similarity", + "same_minus_shifted_margin", + "matched_vs_shifted_auc", + "exact_r1_text_to_audio", + "within_pm1_r1_text_to_audio", + "mase_slots_text_to_audio", + "exact_r1_text_to_vision", + "within_pm1_r1_text_to_vision", + "mase_slots_text_to_vision", + "exact_r1_audio_to_vision", + "within_pm1_r1_audio_to_vision", + "mase_slots_audio_to_vision", + ) + grouped: dict[str, list[Mapping[str, Any]]] = defaultdict(list) + for row in rows: + grouped[str(row["pair"])].append(row) + summary = [] + for pair, values in grouped.items(): + output: dict[str, Any] = { + "method": "M4_sourceTime_content", + "pair": pair, + "clip_count": len(values), + "video_id_count": len({str(row["video_id"]) for row in values}), + } + for i, metric in enumerate(metrics): + if metric not in values[0]: + continue + mean, low, high, count = _cluster_bootstrap( + values, metric, seed=seed + i + sum(ord(char) for char in pair) + ) + output[f"{metric}_video_macro_mean"] = mean + output[f"{metric}_ci95_low"] = low + output[f"{metric}_ci95_high"] = high + output["video_id_count"] = count + summary.append(output) + curve_groups: dict[tuple[str, int], list[Mapping[str, Any]]] = defaultdict(list) + for row in curves: + curve_groups[(str(row["pair"]), int(row["delta"]))].append(row) + curve_summary = [] + for (pair, delta), values in sorted(curve_groups.items()): + mean, low, high, count = _cluster_bootstrap( + values, "similarity", seed=seed + delta + sum(ord(char) for char in pair) + ) + curve_summary.append( + { + "method": "M4_sourceTime_content", + "pair": pair, + "delta": delta, + "mean_similarity_video_macro": mean, + "ci95_low": low, + "ci95_high": high, + "video_id_count": count, + } + ) + return summary, curve_summary + + +def build_parser() -> argparse.ArgumentParser: + project = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--device", choices=("auto", "cpu", "cuda"), default="auto") + parser.add_argument("--batch-size", type=int, default=8) + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--probe-epochs", type=int, default=40) + parser.add_argument("--shuffle-repeats", type=int, default=20) + parser.add_argument("--decoder-epochs", type=int, default=40) + parser.add_argument("--learning-rate", type=float, default=1e-3) + parser.add_argument("--temperature", type=float, default=0.1) + parser.add_argument("--decoder-learning-rate", type=float, default=1e-3) + parser.add_argument("--example-id", type=str, default="-3g5yACwYnA/13") + parser.add_argument( + "--feature-dir", type=Path, default=project / "outputs/q1_features/features" + ) + parser.add_argument("--manifest", type=Path, default=project / "outputs/audit/manifest.csv") + parser.add_argument("--splits", type=Path, default=project / "outputs/method_comparison/splits.json") + parser.add_argument( + "--checkpoint-root", type=Path, default=project / "outputs/alignment_debug/heldout" + ) + parser.add_argument( + "--output-dir", type=Path, default=project / "outputs/m4_shared_latent_eval" + ) + return parser + + +def main() -> None: + args = build_parser().parse_args() + run(args) + + +if __name__ == "__main__": + main() diff --git a/deep_learning/Q1/q1/metrics.py b/deep_learning/Q1/q1/metrics.py new file mode 100644 index 0000000..6796b10 --- /dev/null +++ b/deep_learning/Q1/q1/metrics.py @@ -0,0 +1,146 @@ +from __future__ import annotations + +import numpy as np +import torch +import torch.nn.functional as F +from torch import Tensor + +from .types import MODALITIES + + +def alignment_trajectory(weights: Tensor, times: Tensor, durations: Tensor) -> Tensor: + """Return expected normalized source time at each common-grid position.""" + if weights.ndim != 3 or times.shape != (weights.shape[0], weights.shape[2]): + raise ValueError("weights [B,K,L] and times [B,L] must agree") + if durations.shape != (weights.shape[0],): + raise ValueError("durations must have shape [B]") + expected_seconds = torch.bmm(weights, times.unsqueeze(-1)).squeeze(-1) + return expected_seconds / durations[:, None].clamp_min(torch.finfo(expected_seconds.dtype).eps) + + +def monotonicity_violation_rate(trajectory: Tensor, epsilon: float = 0.02) -> Tensor: + """Per-sample fraction of adjacent grid pairs that move backwards by epsilon.""" + if trajectory.ndim != 2 or trajectory.shape[1] < 2: + raise ValueError("trajectory must have shape [B, K] with K >= 2") + if epsilon < 0: + raise ValueError("epsilon must be non-negative") + return ((trajectory[:, :-1] - trajectory[:, 1:]) > epsilon).float().mean(dim=1) + + +def normalized_attention_entropy(weights: Tensor, valid: Tensor) -> Tensor: + """Per-row entropy normalized by the number of valid source positions.""" + if weights.ndim != 3 or valid.shape != (weights.shape[0], weights.shape[2]): + raise ValueError("weights [B,K,L] and valid [B,L] must agree") + safe = weights.clamp_min(torch.finfo(weights.dtype).tiny) + entropy = -(weights * safe.log()).sum(dim=-1) + counts = valid.sum(dim=-1).clamp_min(1) + denominator = counts.float().log().clamp_min(torch.finfo(torch.float32).eps) + normalized = entropy / denominator[:, None] + return torch.where(counts[:, None] > 1, normalized, torch.zeros_like(normalized)) + + +def attention_row_similarity(weights: Tensor, min_separation: int = 1) -> Tensor: + """Mean cosine similarity between attention rows, per sample. + + ``min_separation=1`` compares every distinct pair (the C_row collapse + score). A value of 6 compares only pairs more than five slots apart, + matching the training diversity loss. Scores near one mean that slots + attend to nearly the same source distribution. + """ + if weights.ndim != 3: + raise ValueError("weights must have shape [B, K, L]") + if min_separation < 1: + raise ValueError("min_separation must be at least one") + batch_size, grid_size, _ = weights.shape + if grid_size <= min_separation: + return torch.zeros(batch_size, dtype=weights.dtype, device=weights.device) + normalized = F.normalize(weights, p=2, dim=-1, eps=1e-12) + similarities = torch.bmm(normalized, normalized.transpose(1, 2)) + pair_mask = torch.triu( + torch.ones(grid_size, grid_size, dtype=torch.bool, device=weights.device), + diagonal=min_separation, + ) + return similarities[:, pair_mask].mean(dim=-1) + + +def attention_width80(weights: Tensor, threshold: float = 0.8) -> Tensor: + """Shortest contiguous source-index span containing the requested mass. + + Returns integer widths with shape ``[B, K]``. This is a diagnostic, not a + score to maximize or minimize on its own. + """ + if weights.ndim != 3 or not 0 < threshold <= 1: + raise ValueError("weights must be [B,K,L] and threshold in (0, 1]") + rows = weights.detach().to(device="cpu", dtype=torch.float64).numpy() + widths = np.empty(rows.shape[:2], dtype=np.int64) + for batch_index in range(rows.shape[0]): + for grid_index in range(rows.shape[1]): + row = rows[batch_index, grid_index] + left = 0 + mass = 0.0 + best = len(row) + for right, value in enumerate(row): + mass += float(value) + while left <= right and mass - float(row[left]) >= threshold: + mass -= float(row[left]) + left += 1 + if mass + 1e-12 >= threshold: + best = min(best, right - left + 1) + widths[batch_index, grid_index] = best + return torch.from_numpy(widths) + + +def retrieval_metrics(query: Tensor, target: Tensor, chunk_size: int = 256) -> dict[str, float]: + """Grid-slot retrieval; same flattened sample/slot index is the positive. + + Use only as a representation-consistency probe. It is not independent + temporal ground truth; report human-labeled temporal scores separately. + """ + if query.ndim != 3 or target.ndim != 3 or query.shape != target.shape: + raise ValueError("query and target must have matching [N, K, D] shapes") + if query.shape[0] * query.shape[1] < 1: + raise ValueError("retrieval requires at least one grid position") + q = F.normalize(query.flatten(0, 1), dim=-1) + t = F.normalize(target.flatten(0, 1), dim=-1) + total = q.shape[0] + ranks = torch.empty(total, dtype=torch.long, device=q.device) + for start in range(0, total, chunk_size): + stop = min(start + chunk_size, total) + scores = q[start:stop] @ t.T + positives = scores[torch.arange(stop - start, device=q.device), + torch.arange(start, stop, device=q.device)] + ranks[start:stop] = 1 + (scores > positives[:, None]).sum(dim=1) + ranks_f = ranks.float() + return { + "r_at_1": float((ranks <= 1).float().mean().item()), + "r_at_5": float((ranks <= min(5, total)).float().mean().item()), + "mrr": float((1.0 / ranks_f).mean().item()), + "queries": float(total), + } + + +def summarize_alignment( + weights: dict[str, Tensor], + times: dict[str, Tensor], + valid: dict[str, Tensor], + durations: Tensor, + epsilon: float = 0.02, +) -> dict[str, dict[str, float]]: + """Produce sample-aggregated E1-E3 diagnostics for each modality.""" + summary: dict[str, dict[str, float]] = {} + for name in MODALITIES: + trajectory = alignment_trajectory(weights[name], times[name], durations) + mvr = monotonicity_violation_rate(trajectory, epsilon) + entropy = normalized_attention_entropy(weights[name], valid[name]) + width = attention_width80(weights[name]) + summary[name] = { + "mvr": float(mvr.mean().item()), + "normalized_entropy": float(entropy.mean().item()), + "width80_indices": float(width.float().mean().item()), + "mean_time_start": float(trajectory[:, 0].mean().item()), + "mean_time_end": float(trajectory[:, -1].mean().item()), + "trajectory_span_fraction": float( + (trajectory[:, -1] - trajectory[:, 0]).mean().item() + ), + } + return summary diff --git a/deep_learning/Q1/q1/models.py b/deep_learning/Q1/q1/models.py new file mode 100644 index 0000000..7de6193 --- /dev/null +++ b/deep_learning/Q1/q1/models.py @@ -0,0 +1,247 @@ +from __future__ import annotations + +from collections.abc import Mapping + +import torch +from torch import Tensor, nn + +from .alignment import index_alignment +from .types import AlignmentOutput, MODALITIES, SequenceBatch + + +def _sinusoidal_position_encoding(length: int, dimension: int) -> Tensor: + """Build a fixed, small-amplitude sinusoidal code for ordered slots.""" + positions = torch.arange(length, dtype=torch.float32).unsqueeze(1) + frequencies = torch.exp( + torch.arange(0, dimension, 2, dtype=torch.float32) + * (-torch.log(torch.tensor(10000.0)) / dimension) + ) + encoding = torch.zeros(length, dimension, dtype=torch.float32) + encoding[:, 0::2] = torch.sin(positions * frequencies) + odd_width = encoding[:, 1::2].shape[1] + if odd_width: + encoding[:, 1::2] = torch.cos(positions * frequencies[:odd_width]) + return encoding * (dimension**-0.5) + + +def _temporal_position_encoding(times: Tensor, dimension: int) -> Tensor: + """Encode normalized source times with a fixed Fourier feature bank.""" + half_width = (dimension + 1) // 2 + frequencies = torch.logspace( + 0.0, + 1.6989700043360187, + steps=half_width, + device=times.device, + dtype=times.dtype, + ) + angles = (2.0 * torch.pi) * times.unsqueeze(-1) * frequencies + encoding = torch.empty(*times.shape, dimension, device=times.device, dtype=times.dtype) + encoding[..., 0::2] = torch.sin(angles) + if dimension > 1: + encoding[..., 1::2] = torch.cos(angles[..., : encoding[..., 1::2].shape[-1]]) + return encoding * (dimension**-0.25) + + +def _validate_inputs(sequences: Mapping[str, SequenceBatch], grid_size: int) -> int: + if set(sequences) != set(MODALITIES): + raise ValueError(f"sequences must contain exactly {MODALITIES}") + batch_sizes = {sequences[name].features.shape[0] for name in MODALITIES} + if len(batch_sizes) != 1: + raise ValueError("all modalities must have the same batch size") + if grid_size < 1: + raise ValueError("grid_size must be positive") + return batch_sizes.pop() + + +class _CrossAttention(nn.Module): + def __init__(self, dimension: int, heads: int, dropout: float) -> None: + super().__init__() + if dimension % heads != 0: + raise ValueError("dimension must be divisible by heads") + self.attention = nn.MultiheadAttention( + # Keep the returned alignment matrix row-stochastic during training. + # PyTorch applies attention dropout to returned weights when it is + # nonzero, which breaks the shared AlignmentOutput contract. + embed_dim=dimension, num_heads=heads, dropout=0.0, batch_first=True + ) + self.input_dropout = nn.Dropout(dropout) + + def forward( + self, + query: Tensor, + source: Tensor, + valid: Tensor, + *, + source_position: Tensor | None = None, + ) -> tuple[Tensor, Tensor]: + key = source if source_position is None else source + source_position + values, weights = self.attention( + self.input_dropout(query), + self.input_dropout(key), + self.input_dropout(source), + key_padding_mask=~valid, + need_weights=True, + average_attn_weights=True, + ) + return values, weights + + +class TextAnchoredCrossAttention(nn.Module): + """M3: transcript-order text slots query Audio and Vision sequences.""" + + def __init__( + self, + dimensions: Mapping[str, int], + grid_size: int = 50, + hidden_size: int = 128, + heads: int = 4, + dropout: float = 0.1, + source_time_encoding: bool = False, + ) -> None: + super().__init__() + if set(dimensions) != set(MODALITIES): + raise ValueError(f"dimensions must contain exactly {MODALITIES}") + self.grid_size = grid_size + self.source_time_encoding = source_time_encoding + self.hidden_size = hidden_size + self.projections = nn.ModuleDict( + {name: nn.Linear(dimensions[name], hidden_size) for name in MODALITIES} + ) + self.audio_attention = _CrossAttention(hidden_size, heads, dropout) + self.vision_attention = _CrossAttention(hidden_size, heads, dropout) + + def forward( + self, sequences: Mapping[str, SequenceBatch], durations: Tensor | None = None + ) -> AlignmentOutput: + _validate_inputs(sequences, self.grid_size) + if self.source_time_encoding: + if durations is None or durations.shape != (sequences["text"].features.shape[0],): + raise ValueError("durations with shape [B] are required for source time encoding") + durations = durations.to(device=sequences["text"].times.device).clamp_min(1e-8) + projected = { + name: self.projections[name](sequences[name].features) for name in MODALITIES + } + text_weights, text_fallbacks = index_alignment(sequences["text"].valid, self.grid_size) + text_query = torch.bmm(text_weights.to(projected["text"].dtype), projected["text"]) + + source_positions: dict[str, Tensor] = {} + if self.source_time_encoding: + assert durations is not None + text_centers = torch.bmm( + text_weights.to(sequences["text"].times.dtype), + sequences["text"].times.unsqueeze(-1), + ).squeeze(-1) / durations[:, None] + text_query = text_query + _temporal_position_encoding( + text_centers, self.hidden_size + ).to(text_query.dtype) + for name in ("audio", "vision"): + normalized_times = sequences[name].times / durations[:, None] + source_positions[name] = _temporal_position_encoding( + normalized_times, self.hidden_size + ).to(projected[name].dtype) + + audio_values, audio_weights = self.audio_attention( + text_query, + projected["audio"], + sequences["audio"].valid, + source_position=source_positions.get("audio"), + ) + vision_values, vision_weights = self.vision_attention( + text_query, + projected["vision"], + sequences["vision"].valid, + source_position=source_positions.get("vision"), + ) + output = AlignmentOutput( + weights={"text": text_weights, "audio": audio_weights, "vision": vision_weights}, + aligned={"text": text_query, "audio": audio_values, "vision": vision_values}, + fallback_rows={"text": text_fallbacks, "audio": 0, "vision": 0}, + ) + output.validate({name: sequences[name].valid for name in MODALITIES}) + return output + + +class SharedLatentTimeline(nn.Module): + """M4: K learned shared slots attend independently to all three modalities.""" + + def __init__( + self, + dimensions: Mapping[str, int], + grid_size: int = 50, + hidden_size: int = 128, + heads: int = 4, + dropout: float = 0.1, + absolute_position_encoding: bool = False, + source_time_encoding: bool = False, + ) -> None: + super().__init__() + if set(dimensions) != set(MODALITIES): + raise ValueError(f"dimensions must contain exactly {MODALITIES}") + if hidden_size % heads != 0: + raise ValueError("hidden_size must be divisible by heads") + self.grid_size = grid_size + self.hidden_size = hidden_size + self.absolute_position_encoding = absolute_position_encoding + self.source_time_encoding = source_time_encoding + self.register_buffer( + "sinusoidal_positions", + _sinusoidal_position_encoding(grid_size, hidden_size), + persistent=False, + ) + self.projections = nn.ModuleDict( + {name: nn.Linear(dimensions[name], hidden_size) for name in MODALITIES} + ) + self.slots = nn.Parameter(torch.empty(grid_size, hidden_size)) + nn.init.normal_(self.slots, mean=0.0, std=hidden_size**-0.5) + self.attention = nn.ModuleDict( + {name: _CrossAttention(hidden_size, heads, dropout) for name in MODALITIES} + ) + + def forward( + self, sequences: Mapping[str, SequenceBatch], durations: Tensor | None = None + ) -> AlignmentOutput: + batch_size = _validate_inputs(sequences, self.grid_size) + if self.source_time_encoding: + if durations is None or durations.shape != (batch_size,): + raise ValueError("durations with shape [B] are required for source time encoding") + durations = durations.to(device=sequences["text"].times.device).clamp_min(1e-8) + latent_queries = self.slots.unsqueeze(0).expand(batch_size, -1, -1) + if self.absolute_position_encoding: + latent_queries = latent_queries + self.sinusoidal_positions.unsqueeze(0) + if self.source_time_encoding: + centers = ( + torch.arange( + self.grid_size, + dtype=sequences["text"].times.dtype, + device=sequences["text"].times.device, + ) + + 0.5 + ) / self.grid_size + centers = centers.unsqueeze(0).expand(batch_size, -1) + latent_queries = latent_queries + _temporal_position_encoding( + centers, self.hidden_size + ).to(latent_queries.dtype) + weights: dict[str, Tensor] = {} + aligned: dict[str, Tensor] = {} + for name in MODALITIES: + source = self.projections[name](sequences[name].features) + source_position = None + if self.source_time_encoding: + assert durations is not None + normalized_times = sequences[name].times / durations[:, None] + source_position = _temporal_position_encoding( + normalized_times, self.hidden_size + ).to(source.dtype) + aligned[name], weights[name] = self.attention[name]( + latent_queries, + source, + sequences[name].valid, + source_position=source_position, + ) + output = AlignmentOutput( + weights=weights, + aligned=aligned, + fallback_rows={name: 0 for name in MODALITIES}, + ) + output.validate({name: sequences[name].valid for name in MODALITIES}) + return output diff --git a/deep_learning/Q1/q1/summarize_alignment_debug.py b/deep_learning/Q1/q1/summarize_alignment_debug.py new file mode 100644 index 0000000..8f28078 --- /dev/null +++ b/deep_learning/Q1/q1/summarize_alignment_debug.py @@ -0,0 +1,194 @@ +"""Summarize the saved D0-D3 alignment-diagnostic metrics without retraining.""" + +from __future__ import annotations + +import argparse +import csv +from collections import defaultdict +from pathlib import Path +import shutil +from statistics import mean +from typing import Any + + +METRICS = ( + "mvr", + "normalized_entropy", + "c_row", + "trajectory_span", + "mean_absolute_time_center_error", + "gaussian_target_kl", +) + + +def merge_trial_metrics(run_dir: Path, destination: Path) -> None: + """Rebuild the combined file with a variant label for PE controls.""" + rows: list[dict[str, str]] = [] + fields: list[str] | None = None + for experiment in ("D0", "D1", "D2", "D3"): + for path in sorted((run_dir / experiment).glob("*_metrics.csv")): + variant = path.name.removesuffix("_metrics.csv") + with path.open(newline="", encoding="utf-8-sig") as handle: + reader = csv.DictReader(handle) + if fields is None: + fields = ["experiment", "method", "variant"] + [ + name for name in (reader.fieldnames or []) + if name not in {"experiment", "method", "variant"} + ] + for row in reader: + row["variant"] = variant + rows.append(row) + if not fields: + raise FileNotFoundError(f"no per-trial metric CSV files found under {run_dir}") + destination.parent.mkdir(parents=True, exist_ok=True) + with destination.open("w", newline="", encoding="utf-8-sig") as handle: + writer = csv.DictWriter(handle, fieldnames=fields) + writer.writeheader() + writer.writerows(rows) + + +def summarize(source: Path, destination: Path) -> list[dict[str, Any]]: + groups: dict[tuple[str, str, str], list[dict[str, str]]] = defaultdict(list) + with source.open(newline="", encoding="utf-8-sig") as handle: + for row in csv.DictReader(handle): + if row["experiment"] in {"D2", "D3"}: + groups[(row["experiment"], row["method"], row["modality"])].append(row) + + summaries: list[dict[str, Any]] = [] + for (experiment, method, modality), rows in sorted(groups.items()): + summary: dict[str, Any] = { + "experiment": experiment, + "method": method, + "modality": modality, + "sample_count": len(rows), + } + for metric in METRICS: + values = [float(row[metric]) for row in rows if row.get(metric, "") != ""] + summary[f"mean_{metric}"] = mean(values) if values else "" + summary[f"n_{metric}"] = len(values) + summaries.append(summary) + + destination.parent.mkdir(parents=True, exist_ok=True) + with destination.open("w", newline="", encoding="utf-8-sig") as handle: + writer = csv.DictWriter(handle, fieldnames=list(summaries[0])) + writer.writeheader() + writer.writerows(summaries) + return summaries + + +def build_report_bundle(run_dir: Path) -> Path: + """Copy compact diagnostic evidence, leaving large checkpoints local.""" + bundle = run_dir / "report_bundle" + bundle.mkdir(parents=True, exist_ok=True) + for name in ( + "debug_summary.csv", + "metric_summary.csv", + "per_sample_metrics.csv", + "run_manifest.json", + "experiment.log", + ): + source = run_dir / name + if source.exists(): + shutil.copy2(source, bundle / name) + for experiment in ("D0", "D1", "D2", "D3"): + source_dir = run_dir / experiment + target_dir = bundle / experiment + target_dir.mkdir(exist_ok=True) + for pattern in ("*_history.csv", "*_metrics.csv", "*_heatmap.png", "*_trajectory.png"): + for source in source_dir.glob(pattern): + shutil.copy2(source, target_dir / source.name) + synthetic_source = run_dir / "synthetic" + synthetic_target = bundle / "synthetic" + synthetic_target.mkdir(exist_ok=True) + for name in ("metrics.csv", "training_history.csv", "run_manifest.json"): + source = synthetic_source / name + if source.exists(): + shutil.copy2(source, synthetic_target / name) + for source in synthetic_source.rglob("*.png"): + target = synthetic_target / source.relative_to(synthetic_source) + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(source, target) + source_time_dir = run_dir / "source_time" + source_time_target = bundle / "source_time" + source_time_target.mkdir(exist_ok=True) + for name in ("summary.csv", "per_sample_metrics.csv", "run_manifest.json"): + source = source_time_dir / name + if source.exists(): + shutil.copy2(source, source_time_target / name) + for variant_dir in source_time_dir.glob("M*"): + target_dir = source_time_target / variant_dir.name + target_dir.mkdir(exist_ok=True) + for pattern in ("history.csv", "metrics.csv", "*_heatmap.png", "*_trajectory.png"): + for source in variant_dir.glob(pattern): + shutil.copy2(source, target_dir / source.name) + heldout_dir = run_dir / "heldout" + heldout_target = bundle / "heldout" + heldout_target.mkdir(exist_ok=True) + for name in ( + "heldout_summary.csv", + "per_sample_metrics.csv", + "training_summary.csv", + "training_history.csv", + "run_manifest.json", + ): + source = heldout_dir / name + if source.exists(): + shutil.copy2(source, heldout_target / name) + for variant_dir in heldout_dir.glob("M*"): + target_dir = heldout_target / variant_dir.name + target_dir.mkdir(exist_ok=True) + for pattern in ("history.csv", "heldout_metrics.csv", "*_heatmap.png", "*_trajectory.png"): + for source in variant_dir.glob(pattern): + shutil.copy2(source, target_dir / source.name) + readme = """# Q1 M3/M4 可学习性诊断结果包 + +本包包含 D0–D3 诊断的汇总表、运行清单、日志、各试验的损失历史、逐样本指标和代表性图像。PyTorch 检查点与逐样本 `.npz` 注意力矩阵留在上级 `outputs/alignment_debug/`,因此结果包较轻。 + +- D0/D1:单样本过拟合诊断。 +- D1-S:输入仅为合成时间坐标;M3/M4 都能把 Gaussian 目标拟合至约 1e-4 KL。 +- D2/D3:100 条样本上的同集训练/评价诊断,单个随机种子,不用于声称泛化。 +- D4:真实单样本加入显式时间 key/query 特征后,Audio 注意力形成局部时间带。 +- D5:按 `video_id` 留出 20 条样本;M4 的 Audio/Vision 时间带能迁移,M3 有改善但仍未充分贴近目标。 +- Gaussian 时间目标是根据源时间戳生成的弱先验,不是人工对齐真值。 +- M3 的 Gaussian KL 取 Audio/Vision 平均,M4 取 Text/Audio/Vision 平均;KL 数值仅用于各自的优化诊断,不可作为方法排名。 +- D1 真实特征上 Text/Vision 能拟合,Audio 仍失败;合成对照成功,提示真实源特征的显式时间身份值得优先验证。 +- 全数据 Q/K 梯度仍非零,但学习到的注意力没有稳定形成局部时间带;加入重构和对比目标后 Audio 塌缩更明显。 +- 环境:Fedora WSL,`uv`,NVIDIA GeForce RTX 5070 Ti,Python 3.14.7,PyTorch 2.14.0+cu130。 + +详细解释见项目根目录的 `RESULTS.md`。 +""" + (bundle / "README.md").write_text(readme, encoding="utf-8") + return bundle + + +def main() -> None: + project = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--input", + type=Path, + default=project / "outputs/alignment_debug/per_sample_metrics.csv", + ) + parser.add_argument( + "--output", + type=Path, + default=project / "outputs/alignment_debug/metric_summary.csv", + ) + args = parser.parse_args() + merge_trial_metrics(args.input.parent, args.input) + for row in summarize(args.input, args.output): + values = " ".join( + f"{name}={row[f'mean_{name}']:.4f}" + for name in METRICS + if row[f"mean_{name}"] != "" + ) + print( + f"{row['experiment']} {row['method']} {row['modality']} " + f"n={row['sample_count']} {values}" + ) + print(f"Wrote {args.output}") + print(f"Built report bundle at {build_report_bundle(args.input.parent)}") + + +if __name__ == "__main__": + main() diff --git a/deep_learning/Q1/q1/synthetic_alignment_sanity.py b/deep_learning/Q1/q1/synthetic_alignment_sanity.py new file mode 100644 index 0000000..45f8978 --- /dev/null +++ b/deep_learning/Q1/q1/synthetic_alignment_sanity.py @@ -0,0 +1,338 @@ +"""Fit Gaussian time bands with synthetic time-only inputs as an attention control.""" + +from __future__ import annotations + +import argparse +import csv +import json +import platform +import random +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import torch +from torch import Tensor, nn + +from .metrics import alignment_trajectory, normalized_attention_entropy +from .models import SharedLatentTimeline, TextAnchoredCrossAttention +from .types import MODALITIES, SequenceBatch + + +GRID_SIZE = 50 +HIDDEN_SIZE = 128 +SIGMA = 0.10 +SEED = 42 +MODALITY_LENGTHS = {"text": GRID_SIZE, "audio": 256, "vision": 100} + + +def _seed(seed: int) -> None: + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + if torch.cuda.is_available(): + torch.cuda.manual_seed_all(seed) + torch.backends.cudnn.deterministic = True + torch.backends.cudnn.benchmark = False + + +def _synthetic_sequence(length: int, device: torch.device) -> SequenceBatch: + times = torch.linspace(0.0, 1.0, length, device=device).unsqueeze(0) + # These features contain only the source's synthetic time coordinate. + features = torch.stack( + (times, times.square(), torch.ones_like(times)), dim=-1 + ) + valid = torch.ones_like(times, dtype=torch.bool) + return SequenceBatch(features=features, times=times, valid=valid) + + +def _targets( + sequences: dict[str, SequenceBatch], method: str, device: torch.device +) -> dict[str, Tensor]: + centers = (torch.arange(GRID_SIZE, device=device, dtype=torch.float32) + 0.5) / GRID_SIZE + names = ("audio", "vision") if method == "M3" else MODALITIES + targets: dict[str, Tensor] = {} + for name in names: + times = sequences[name].times + logits = -0.5 * ((times[:, None, :] - centers[None, :, None]) / SIGMA).square() + targets[name] = torch.softmax(logits, dim=-1) + return targets + + +def _loss(output: Any, targets: dict[str, Tensor]) -> Tensor: + losses = [] + for name, target in targets.items(): + predicted = output.weights[name].clamp_min(1e-8) + safe_target = target.clamp_min(1e-12) + losses.append((safe_target * (safe_target.log() - predicted.log())).sum(-1).mean()) + return torch.stack(losses).mean() + + +def _attention_layers(model: nn.Module, method: str) -> list[nn.MultiheadAttention]: + if method == "M3": + return [model.audio_attention.attention, model.vision_attention.attention] + return [model.attention[name].attention for name in MODALITIES] + + +def _gradient_summary( + model: nn.Module, method: str, loss: Tensor +) -> dict[str, float]: + layers = _attention_layers(model, method) + params = [layer.in_proj_weight for layer in layers] + if method == "M4": + params.append(model.slots) + gradients = torch.autograd.grad(loss, params, retain_graph=True) + q_sq = torch.zeros((), device=loss.device) + k_sq = torch.zeros((), device=loss.device) + for grad in gradients[: len(layers)]: + q_sq += grad[:HIDDEN_SIZE].square().sum() + k_sq += grad[HIDDEN_SIZE : 2 * HIDDEN_SIZE].square().sum() + result = {"grad_WQ": float(q_sq.sqrt().item()), "grad_WK": float(k_sq.sqrt().item())} + if method == "M4": + result["grad_Z"] = float(gradients[-1].norm().item()) + return result + + +def _write_csv(path: Path, rows: list[dict[str, Any]]) -> None: + if not rows: + return + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("w", newline="", encoding="utf-8-sig") as handle: + fields = list(dict.fromkeys(key for row in rows for key in row)) + writer = csv.DictWriter(handle, fieldnames=fields) + writer.writeheader() + writer.writerows(rows) + + +def _save_plots( + folder: Path, + method: str, + variant: str, + output: Any, + targets: dict[str, Tensor], + sequences: dict[str, SequenceBatch], + duration: float = 1.0, +) -> list[dict[str, Any]]: + names = ("audio", "vision") if method == "M3" else MODALITIES + rows: list[dict[str, Any]] = [] + fig, axes = plt.subplots(len(names), 2, figsize=(11, 3.4 * len(names)), constrained_layout=True) + if len(names) == 1: + axes = np.asarray([axes]) + fig_traj, ax_traj = plt.subplots(figsize=(8, 5), constrained_layout=True) + grid = (np.arange(GRID_SIZE, dtype=np.float32) + 0.5) / GRID_SIZE + for row_index, name in enumerate(names): + weights = output.weights[name][0].detach().cpu().numpy() + target = targets[name][0].detach().cpu().numpy() + times = sequences[name].times[0].detach().cpu().numpy() + entropy = normalized_attention_entropy( + output.weights[name], sequences[name].valid + ).mean().item() + trajectory = alignment_trajectory( + output.weights[name], sequences[name].times, torch.tensor([duration], device=output.weights[name].device) + )[0] + trajectory_np = trajectory.detach().cpu().numpy() + span = float(trajectory_np[-1] - trajectory_np[0]) + kl = float( + (targets[name] * (targets[name].clamp_min(1e-12).log() - output.weights[name].clamp_min(1e-8).log())) + .sum(-1) + .mean() + .item() + ) + rows.append( + { + "method": method, + "variant": variant, + "modality": name, + "normalized_entropy": entropy, + "trajectory_span": span, + "mean_absolute_time_center_error": float( + np.mean(np.abs(trajectory_np - grid)) + ), + "gaussian_target_kl": kl, + } + ) + extent = (float(times[0]), float(times[-1]), 0.0, 1.0) + image = axes[row_index, 0].imshow( + weights, origin="lower", aspect="auto", interpolation="nearest", extent=extent, cmap="magma" + ) + axes[row_index, 0].set_title(f"{name}: learned A") + axes[row_index, 0].set_xlabel("synthetic source time") + axes[row_index, 0].set_ylabel("slot / K") + fig.colorbar(image, ax=axes[row_index, 0], fraction=0.046, pad=0.04) + image_target = axes[row_index, 1].imshow( + target, origin="lower", aspect="auto", interpolation="nearest", extent=extent, cmap="magma" + ) + axes[row_index, 1].set_title(f"{name}: Gaussian target P") + axes[row_index, 1].set_xlabel("synthetic source time") + axes[row_index, 1].set_ylabel("slot / K") + fig.colorbar(image_target, ax=axes[row_index, 1], fraction=0.046, pad=0.04) + ax_traj.plot(grid, trajectory_np, label=f"{name} learned") + ax_traj.plot([0, 1], [0, 1], "k:", label="uniform-time reference") + ax_traj.set(xlim=(0, 1), ylim=(0, 1), xlabel="slot position", ylabel="expected source time") + ax_traj.grid(alpha=0.2) + ax_traj.legend() + ax_traj.set_title(f"{method} {variant}: synthetic alignment trajectory") + folder.mkdir(parents=True, exist_ok=True) + fig.savefig(folder / f"{variant}_heatmap.png", dpi=160) + fig_traj.savefig(folder / f"{variant}_trajectory.png", dpi=160) + plt.close(fig) + plt.close(fig_traj) + return rows + + +def _run_trial( + method: str, + variant: str, + *, + device: torch.device, + steps: int, + seed: int, + output_dir: Path, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]], dict[str, Any]]: + _seed(seed) + dimensions = {name: 3 for name in MODALITIES} + if method == "M3": + model: nn.Module = TextAnchoredCrossAttention( + dimensions, grid_size=GRID_SIZE, hidden_size=HIDDEN_SIZE, heads=4, dropout=0.0 + ) + use_pe = False + else: + use_pe = variant == "M4_sinPE" + model = SharedLatentTimeline( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=4, + dropout=0.0, + absolute_position_encoding=use_pe, + ) + model.to(device) + sequences = { + name: _synthetic_sequence(MODALITY_LENGTHS[name], device) for name in MODALITIES + } + targets = _targets(sequences, method, device) + optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=0.0) + history: list[dict[str, Any]] = [] + output = None + print(f"[{variant}] synthetic time-only inputs, steps={steps}, device={device}", flush=True) + for step in range(1, steps + 1): + model.train() + output = model(sequences) + loss = _loss(output, targets) + if not torch.isfinite(loss): + raise FloatingPointError(f"non-finite synthetic alignment loss for {variant} at step {step}") + row: dict[str, Any] = {"method": method, "variant": variant, "step": step, "L_align": float(loss.item())} + if step == 1 or step % 100 == 0 or step == steps: + row.update(_gradient_summary(model, method, loss)) + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(model.parameters(), 2.0) + optimizer.step() + history.append(row) + if step == 1 or step % 100 == 0 or step == steps: + print( + f"[{variant} {step}/{steps}] KL={row['L_align']:.5f} " + f"grad_Q/K/Z={row.get('grad_WQ', 0):.3g}/{row.get('grad_WK', 0):.3g}/" + f"{row.get('grad_Z', float('nan')):.3g}", + flush=True, + ) + assert output is not None + model.eval() + with torch.no_grad(): + output = model(sequences) + metric_rows = _save_plots( + output_dir / variant, method, variant, output, targets, sequences + ) + history_rows = history + checkpoint = output_dir / f"{variant}_checkpoint.pt" + torch.save( + { + "method": method, + "variant": variant, + "seed": seed, + "steps": steps, + "absolute_position_encoding": use_pe, + "model_state_dict": model.state_dict(), + "synthetic_only": True, + }, + checkpoint, + ) + return metric_rows, history_rows, {"checkpoint": str(checkpoint), "final_loss": history[-1]["L_align"]} + + +def run(args: argparse.Namespace) -> dict[str, Any]: + output_dir = args.output_dir + output_dir.mkdir(parents=True, exist_ok=True) + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is unavailable") + variants = [("M3", "M3"), ("M4", "M4_noPE"), ("M4", "M4_sinPE")] + all_metrics: list[dict[str, Any]] = [] + all_history: list[dict[str, Any]] = [] + model_summaries: list[dict[str, Any]] = [] + for method, variant in variants: + metrics, history, summary = _run_trial( + method, variant, device=device, steps=args.steps, seed=args.seed, output_dir=output_dir + ) + all_metrics.extend(metrics) + all_history.extend(history) + model_summaries.append({"method": method, "variant": variant, **summary}) + _write_csv(output_dir / "metrics.csv", all_metrics) + _write_csv(output_dir / "training_history.csv", all_history) + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "purpose": "Check whether the existing M3/M4 attention implementation can fit a time band when all inputs encode only synthetic time.", + "sample_count": 1, + "synthetic_only": True, + "seed": args.seed, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "grid_size": GRID_SIZE, + "sigma_normalized_time": SIGMA, + "feature_rule": "[t, t^2, 1] per source position; no extracted text/audio/video content is used", + "sequence_lengths": MODALITY_LENGTHS, + "optimizer": "AdamW", + "learning_rate": 1e-3, + "steps_per_variant": args.steps, + "variants": model_summaries, + "interpretation_limits": [ + "This is an implementation/optimization control only; it does not evaluate real features or alignment accuracy.", + "The time-only features deliberately provide source-position information that the real feature inputs may not contain.", + ], + } + (output_dir / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + print(f"[all done] wrote synthetic control to {output_dir}", flush=True) + return manifest + + +def build_parser() -> argparse.ArgumentParser: + project = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--steps", type=int, default=1000) + parser.add_argument("--seed", type=int, default=SEED) + parser.add_argument("--device", choices=("auto", "cpu", "cuda"), default="auto") + parser.add_argument( + "--output-dir", type=Path, default=project / "outputs/alignment_debug/synthetic" + ) + return parser + + +def main() -> None: + args = build_parser().parse_args() + run(args) + + +if __name__ == "__main__": + main() diff --git a/deep_learning/Q1/q1/train_alignment_variants.py b/deep_learning/Q1/q1/train_alignment_variants.py new file mode 100644 index 0000000..02d5b37 --- /dev/null +++ b/deep_learning/Q1/q1/train_alignment_variants.py @@ -0,0 +1,647 @@ +from __future__ import annotations + +import argparse +import json +import math +import platform +import statistics +import time +from collections import defaultdict +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Mapping, Sequence + +import numpy as np +import torch +from sklearn.model_selection import GroupKFold + +from .compare_methods import ( + _alignment_rows, + _batches, + _baseline_output, + _collect_representations, + _fit_learned_model, + _make_figures, + _save_alignment, + _seed_everything, + _write_csv, +) +from .experiment_data import ( + FeatureSample, + collate_feature_samples, + fit_feature_stats, + load_feature_samples, +) +from .experiment_probes import ( + run_shuffled_alignment_reconstruction_probe, + run_within_clip_temporal_retrieval_probe, +) +from .types import MODALITIES + + +VARIANTS = ("v2_a", "v2_b", "v2_c") +METRIC_COLUMNS = { + "alignment": ( + "mvr", + "normalized_entropy", + "width80_source_positions", + "trajectory_span_fraction", + "c_row", + "c_far", + ), + "retrieval": ("r_at_1", "r_at_3", "mase_slots", "exact_r_at_1"), + "reconstruction": ( + "mae_aligned", + "mae_shuffled_mean", + "mae_shuffled_std", + "gain_align", + ), +} + + +def _summarize( + rows: Sequence[Mapping[str, Any]], group_keys: Sequence[str], metrics: Sequence[str] +) -> list[dict[str, Any]]: + grouped: dict[tuple[Any, ...], list[Mapping[str, Any]]] = defaultdict(list) + for row in rows: + grouped[tuple(row[key] for key in group_keys)].append(row) + results = [] + for key, values in grouped.items(): + summary: dict[str, Any] = dict(zip(group_keys, key)) + summary["n"] = len(values) + for metric in metrics: + numbers = [float(row[metric]) for row in values if row.get(metric) not in (None, "")] + numbers = [number for number in numbers if math.isfinite(number)] + if numbers: + summary[f"{metric}_mean"] = statistics.fmean(numbers) + summary[f"{metric}_std"] = statistics.stdev(numbers) if len(numbers) > 1 else 0.0 + results.append(summary) + return results + + +def _comparison_table(summaries: Mapping[str, Sequence[Mapping[str, Any]]]) -> list[dict[str, Any]]: + alignment = {(row["method"], row["modality"]): row for row in summaries["alignment"]} + retrieval = {(row["method"], row["direction"]): row for row in summaries["retrieval"]} + reconstruction = { + (row["method"], row["target_modality"]): row for row in summaries["reconstruction"] + } + rows = [] + for method in ("M1", "M2", "M3", "M4"): + row: dict[str, Any] = {"method": method} + for modality in MODALITIES: + metrics = alignment[(method, modality)] + for key in ("mvr", "normalized_entropy", "trajectory_span_fraction", "c_row", "c_far"): + row[f"{key}_{modality}"] = metrics.get(f"{key}_mean") + for direction in ("text_to_audio", "text_to_vision", "audio_to_vision"): + metrics = retrieval[(method, direction)] + for key in ("r_at_1", "r_at_3", "mase_slots", "exact_r_at_1"): + row[f"{key}_{direction}"] = metrics.get(f"{key}_mean") + for modality in MODALITIES: + metrics = reconstruction[(method, modality)] + for key in ("mae_aligned", "mae_shuffled_mean", "gain_align"): + row[f"{key}_{modality}"] = metrics.get(f"{key}_mean") + rows.append(row) + return rows + + +def _folds_from_baseline( + samples: Sequence[FeatureSample], baseline_splits: Path, requested_folds: int +) -> list[tuple[list[FeatureSample], list[FeatureSample], dict[str, Any]]]: + by_id = {sample.sample_id: sample for sample in samples} + if baseline_splits.is_file(): + split_rows = json.loads(baseline_splits.read_text(encoding="utf-8")) + else: + groups = [sample.group_id for sample in samples] + splitter = GroupKFold(n_splits=requested_folds) + split_rows = [] + for fold, (train, validation) in enumerate( + splitter.split(np.zeros(len(samples)), groups=groups), start=1 + ): + split_rows.append( + { + "fold": fold, + "train_sample_ids": [samples[index].sample_id for index in train], + "validation_sample_ids": [samples[index].sample_id for index in validation], + "train_video_ids": sorted({samples[index].group_id for index in train}), + "validation_video_ids": sorted( + {samples[index].group_id for index in validation} + ), + } + ) + if len(split_rows) != requested_folds: + raise ValueError( + f"baseline split file has {len(split_rows)} folds; expected {requested_folds}" + ) + folds = [] + seen_validation: list[str] = [] + for row in split_rows: + train_ids = row["train_sample_ids"] + validation_ids = row["validation_sample_ids"] + if set(train_ids) & set(validation_ids): + raise ValueError(f"sample leakage in fold {row['fold']}") + train_samples = [by_id[sample_id] for sample_id in train_ids] + val_samples = [by_id[sample_id] for sample_id in validation_ids] + train_groups = {sample.group_id for sample in train_samples} + val_groups = {sample.group_id for sample in val_samples} + if train_groups & val_groups: + raise ValueError(f"video_id leakage in fold {row['fold']}") + seen_validation.extend(validation_ids) + folds.append((train_samples, val_samples, row)) + if len(seen_validation) != len(samples) or set(seen_validation) != set(by_id): + raise ValueError("baseline folds do not cover the current complete sample manifest") + return folds + + +def _evaluate_fixed_methods( + args: argparse.Namespace, + samples: Sequence[FeatureSample], + folds: Sequence[tuple[list[FeatureSample], list[FeatureSample], dict[str, Any]]], + device: torch.device, + output_dir: Path, +) -> tuple[dict[str, list[dict[str, Any]]], dict[str, dict[str, Mapping[str, np.ndarray]]]]: + output_dir.mkdir(parents=True, exist_ok=True) + rows: dict[str, list[dict[str, Any]]] = { + "alignment": [], + "retrieval": [], + "reconstruction": [], + } + example_weights: dict[str, dict[str, Mapping[str, np.ndarray]]] = defaultdict(dict) + sample_by_id = {sample.sample_id: sample for sample in samples} + example_id = args.example_id if args.example_id in sample_by_id else samples[0].sample_id + + for fold_index, (train_samples, val_samples, split_row) in enumerate(folds, start=1): + stats = fit_feature_stats(train_samples) + print( + f"[fixed fold {fold_index}/{len(folds)}] train={len(train_samples)} " + f"validation={len(val_samples)}; evaluating unchanged M1/M2", + flush=True, + ) + for method in ("M1", "M2"): + train_aligned, _ = _collect_representations( + method, + train_samples, + stats, + device=device, + grid_size=args.grid_size, + batch_size=args.batch_size, + ) + val_aligned, val_weights = _collect_representations( + method, + val_samples, + stats, + device=device, + grid_size=args.grid_size, + batch_size=args.batch_size, + ) + combined = {**train_aligned, **val_aligned} + for batch_samples in _batches( + val_samples, + args.batch_size, + shuffle=False, + rng=np.random.default_rng(args.seeds[0] + fold_index), + ): + sequences, durations, intervals = collate_feature_samples( + batch_samples, stats, device + ) + output = _baseline_output(method, sequences, durations, intervals, args.grid_size) + rows["alignment"].extend( + _alignment_rows( + method, + "fixed", + fold_index, + batch_samples, + output, + device, + args.mvr_epsilon, + ) + ) + for sample in val_samples: + _save_alignment(output_dir, method, "fixed", sample, val_weights[sample.sample_id]) + if sample.sample_id == example_id: + example_weights[sample.sample_id][method] = val_weights[sample.sample_id] + + probe_seed = args.seeds[0] + fold_index * 100 + rows["retrieval"].extend( + {"method": method, "seed": "fixed", "fold": fold_index, **row} + for row in run_within_clip_temporal_retrieval_probe( + [sample.sample_id for sample in train_samples], + [sample.sample_id for sample in val_samples], + combined, + device=device, + seed=probe_seed, + epochs=args.retrieval_probe_epochs, + batch_size=args.probe_batch_size, + tolerance=args.retrieval_tolerance, + top_k=3, + ) + ) + rows["reconstruction"].extend( + {"method": method, "seed": "fixed", "fold": fold_index, **row} + for row in run_shuffled_alignment_reconstruction_probe( + [sample.sample_id for sample in train_samples], + [sample.sample_id for sample in val_samples], + combined, + device=device, + seed=probe_seed + 1, + ratio=args.mask_ratio, + epochs=args.reconstruction_probe_epochs, + batch_size=args.probe_batch_size, + shuffle_repeats=args.shuffle_repeats, + ) + ) + + for key, values in rows.items(): + _write_csv(output_dir / f"{key}_metrics.csv", values) + (output_dir / "README.md").write_text( + "# Fixed M1/M2 reference probes\n\n" + "M1 and M2 are recomputed from the same saved video-grouped folds and unchanged. " + "The within-clip retrieval projection is fitted on each training fold; held-out candidates " + "come only from the same clip. The reconstruction decoder is trained on aligned training " + "representations, then compared with a control that shuffles the two non-target streams.\n", + encoding="utf-8", + ) + return rows, example_weights + + +def _write_stage_summary( + stage_dir: Path, + fixed_rows: Mapping[str, Sequence[dict[str, Any]]], + learned_rows: Mapping[str, Sequence[dict[str, Any]]], +) -> dict[str, list[dict[str, Any]]]: + all_rows = { + key: [*fixed_rows[key], *learned_rows[key]] + for key in ("alignment", "retrieval", "reconstruction") + } + group_columns = { + "alignment": ("method", "modality"), + "retrieval": ("method", "direction"), + "reconstruction": ("method", "target_modality"), + } + summaries = { + key: _summarize(rows, group_columns[key], METRIC_COLUMNS[key]) + for key, rows in all_rows.items() + } + for key, rows in all_rows.items(): + _write_csv(stage_dir / f"{key}_metrics_with_fixed.csv", rows) + _write_csv(stage_dir / f"{key}_summary.csv", summaries[key]) + _write_csv(stage_dir / "comparison_summary.csv", _comparison_table(summaries)) + (stage_dir / "summary.json").write_text( + json.dumps(summaries, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + return summaries + + +def _run_variant( + variant: str, + args: argparse.Namespace, + samples: Sequence[FeatureSample], + folds: Sequence[tuple[list[FeatureSample], list[FeatureSample], dict[str, Any]]], + fixed_rows: Mapping[str, Sequence[dict[str, Any]]], + fixed_examples: Mapping[str, Mapping[str, Mapping[str, np.ndarray]]], + device: torch.device, +) -> dict[str, Any]: + start_time = time.time() + stage_dir = args.output_dir / variant + stage_dir.mkdir(parents=True, exist_ok=True) + (stage_dir / "splits.json").write_text( + json.dumps([row for _, _, row in folds], ensure_ascii=False, indent=2), encoding="utf-8" + ) + learned_rows: dict[str, list[dict[str, Any]]] = { + "alignment": [], + "retrieval": [], + "reconstruction": [], + } + training_summary: list[dict[str, Any]] = [] + training_history: list[dict[str, Any]] = [] + example_weights: dict[str, dict[str, Mapping[str, np.ndarray]]] = defaultdict(dict) + sample_by_id = {sample.sample_id: sample for sample in samples} + example_id = args.example_id if args.example_id in sample_by_id else samples[0].sample_id + example_sample = sample_by_id[example_id] + if example_id in fixed_examples: + example_weights[example_id].update(fixed_examples[example_id]) + + for fold_index, (train_samples, val_samples, _) in enumerate(folds, start=1): + stats = fit_feature_stats(train_samples) + fold_dir = stage_dir / f"fold_{fold_index:02d}" + print( + f"[{variant} fold {fold_index}/{len(folds)}] training M3/M4 with " + f"{len(train_samples)} train and {len(val_samples)} validation clips", + flush=True, + ) + for seed in args.seeds: + for method in ("M3", "M4"): + checkpoint = fold_dir / f"seed_{seed}" / f"{method}.pt" + model, info = _fit_learned_model( + method, + train_samples, + val_samples, + stats, + device=device, + seed=seed + fold_index * 1009, + grid_size=args.grid_size, + hidden_size=args.hidden_size, + heads=args.heads, + dropout=args.dropout, + batch_size=args.batch_size, + max_epochs=args.epochs, + patience=args.patience, + learning_rate=args.learning_rate, + checkpoint_path=checkpoint, + loss_variant=variant, + ) + training_summary.append( + { + "loss_variant": variant, + "method": method, + "seed": seed, + "fold": fold_index, + "best_epoch": info["best_epoch"], + "best_validation_objective": info["best_validation_objective"], + **{ + key: value + for key, value in info["best_validation_metrics"].items() + if key not in {"epoch", "train_total"} + }, + "checkpoint": info["checkpoint"], + } + ) + training_history.extend( + { + "loss_variant": variant, + "method": method, + "seed": seed, + "fold": fold_index, + **epoch, + } + for epoch in info["history"] + ) + print( + f"[{variant} fold {fold_index}] {method} seed={seed} " + f"best_epoch={info['best_epoch']} " + f"val={info['best_validation_objective']:.4f} " + f"C_row(audio/vision)=" + f"{info['best_validation_metrics']['validation_c_row_audio']:.3f}/" + f"{info['best_validation_metrics']['validation_c_row_vision']:.3f}", + flush=True, + ) + train_aligned, _ = _collect_representations( + method, + train_samples, + stats, + device=device, + grid_size=args.grid_size, + batch_size=args.batch_size, + model=model, + ) + val_aligned, val_weights = _collect_representations( + method, + val_samples, + stats, + device=device, + grid_size=args.grid_size, + batch_size=args.batch_size, + model=model, + ) + combined = {**train_aligned, **val_aligned} + for batch_samples in _batches( + val_samples, + args.batch_size, + shuffle=False, + rng=np.random.default_rng(seed + fold_index), + ): + sequences, durations, _ = collate_feature_samples( + batch_samples, stats, device + ) + output = model(sequences) + learned_rows["alignment"].extend( + _alignment_rows( + method, + str(seed), + fold_index, + batch_samples, + output, + device, + args.mvr_epsilon, + ) + ) + for sample in val_samples: + _save_alignment(stage_dir, method, str(seed), sample, val_weights[sample.sample_id]) + if sample.sample_id == example_id and seed == args.seeds[0]: + example_weights[sample.sample_id][method] = val_weights[sample.sample_id] + + probe_seed = seed + fold_index * 100 + (3 if method == "M3" else 7) + learned_rows["retrieval"].extend( + { + "method": method, + "seed": seed, + "fold": fold_index, + **row, + } + for row in run_within_clip_temporal_retrieval_probe( + [sample.sample_id for sample in train_samples], + [sample.sample_id for sample in val_samples], + combined, + device=device, + seed=probe_seed, + epochs=args.retrieval_probe_epochs, + batch_size=args.probe_batch_size, + tolerance=args.retrieval_tolerance, + top_k=3, + ) + ) + learned_rows["reconstruction"].extend( + { + "method": method, + "seed": seed, + "fold": fold_index, + **row, + } + for row in run_shuffled_alignment_reconstruction_probe( + [sample.sample_id for sample in train_samples], + [sample.sample_id for sample in val_samples], + combined, + device=device, + seed=probe_seed + 1, + ratio=args.mask_ratio, + epochs=args.reconstruction_probe_epochs, + batch_size=args.probe_batch_size, + shuffle_repeats=args.shuffle_repeats, + ) + ) + del model + if device.type == "cuda": + torch.cuda.empty_cache() + + _write_csv(stage_dir / "training_summary.csv", training_summary) + _write_csv(stage_dir / "training_history.csv", training_history) + for key, rows in learned_rows.items(): + _write_csv(stage_dir / f"{key}_metrics_learned_only.csv", rows) + + summaries = _write_stage_summary(stage_dir, fixed_rows, learned_rows) + _write_csv(stage_dir / "training_summary.csv", training_summary) + _write_csv(stage_dir / "training_history.csv", training_history) + if example_id in example_weights and set(example_weights[example_id]) == {"M1", "M2", "M3", "M4"}: + _make_figures(stage_dir, example_id, example_sample, example_weights[example_id], args.grid_size) + manifest = { + "variant": variant, + "loss_coefficients": { + "lambda_reconstruction": 1.0, + "lambda_contrastive": 1.0, + "lambda_monotonicity": 0.1, + "lambda_span": 5.0, + "lambda_diversity": 0.5 if variant in {"v2_b", "v2_c"} else 0.0, + "lambda_band": 10.0 if variant == "v2_c" else 0.0, + "coverage_floor": 0.7, + "diversity_slot_separation": 6, + "band_margin": 0.1, + }, + "sample_count": len(samples), + "video_group_folds": len(folds), + "seeds": args.seeds, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "elapsed_seconds": time.time() - start_time, + "probes": { + "within_clip_retrieval_tolerance_slots": args.retrieval_tolerance, + "retrieval_top_k": 3, + "shuffled_reconstruction_repeats": args.shuffle_repeats, + "masked_block_ratio": args.mask_ratio, + }, + "limits": [ + "Retrieval projections are fitted on training-fold grid-slot positives; test candidates are restricted to the same held-out clip.", + "The reconstruction control shuffles the two non-target modality slot streams and preserves the target stream.", + "No human event timestamps are available, so temporal probes do not replace manual annotation.", + "Slot-regularization losses impose weak temporal structure and must be interpreted alongside the unregularized M1/M2 reference.", + ], + } + (stage_dir / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + (stage_dir / "README.md").write_text( + f"# {variant} M3/M4 alignment variant\n\n" + "M1/M2 rows in the comparison files are fixed references recomputed on the original grouped folds. " + "Only M3/M4 training losses changed. See `training_history.csv` for per-epoch loss components and row-collapse scores. " + "`retrieval_metrics_learned_only.csv` restricts candidates to the same clip. " + "`reconstruction_metrics_learned_only.csv` contrasts aligned and shuffled non-target streams. " + "The experiment does not include RoPE, Gaussian bias, or latent-length changes.\n", + encoding="utf-8", + ) + print( + f"[{variant} done] elapsed={manifest['elapsed_seconds']:.1f}s " + f"output={stage_dir}; summary rows={sum(len(rows) for rows in summaries.values())}", + flush=True, + ) + return manifest + + +def run(args: argparse.Namespace) -> dict[str, Any]: + start_time = time.time() + _seed_everything(args.seeds[0]) + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is not available") + samples = load_feature_samples(args.feature_dir, args.manifest) + if len(samples) != args.expected_samples: + raise ValueError(f"expected {args.expected_samples} samples, found {len(samples)}") + folds = _folds_from_baseline( + samples, args.baseline_dir / "splits.json", args.folds + ) + args.output_dir.mkdir(parents=True, exist_ok=True) + print( + f"[start] samples={len(samples)} folds={len(folds)} seeds={args.seeds} " + f"device={device} variants={','.join(VARIANTS)}", + flush=True, + ) + fixed_rows, fixed_examples = _evaluate_fixed_methods( + args, + samples, + folds, + device, + args.output_dir / "fixed_baselines", + ) + stage_manifests = [] + for variant in VARIANTS: + stage_manifests.append( + _run_variant( + variant, + args, + samples, + folds, + fixed_rows, + fixed_examples, + device, + ) + ) + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "sample_count": len(samples), + "group_count": len({sample.group_id for sample in samples}), + "folds": len(folds), + "seeds": args.seeds, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "feature_dir": str(args.feature_dir), + "baseline_dir": str(args.baseline_dir), + "variants": stage_manifests, + "elapsed_seconds": time.time() - start_time, + "fixed_methods_unchanged": ["M1", "M2"], + "feature_extraction_changed": False, + } + (args.output_dir / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + print( + f"[all done] elapsed={manifest['elapsed_seconds']:.1f}s output={args.output_dir}", + flush=True, + ) + return manifest + + +def build_parser() -> argparse.ArgumentParser: + project_dir = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser( + description="Train staged M3/M4 alignment-loss variants and stronger temporal probes." + ) + parser.add_argument("--feature-dir", type=Path, default=project_dir / "outputs/q1_features/features") + parser.add_argument("--manifest", type=Path, default=project_dir / "outputs/audit/manifest.csv") + parser.add_argument("--baseline-dir", type=Path, default=project_dir / "outputs/method_comparison") + parser.add_argument("--output-dir", type=Path, default=project_dir / "outputs/alignment_v2") + parser.add_argument("--device", default="auto", help="auto, cpu, or a torch device such as cuda:0") + parser.add_argument("--expected-samples", type=int, default=100) + parser.add_argument("--folds", type=int, default=5) + parser.add_argument("--seeds", type=int, nargs="+", default=[42, 3407, 2026]) + parser.add_argument("--grid-size", type=int, default=50) + parser.add_argument("--hidden-size", type=int, default=128) + parser.add_argument("--heads", type=int, default=4) + parser.add_argument("--dropout", type=float, default=0.1) + parser.add_argument("--batch-size", type=int, default=8) + parser.add_argument("--probe-batch-size", type=int, default=16) + parser.add_argument("--epochs", type=int, default=50) + parser.add_argument("--patience", type=int, default=8) + parser.add_argument("--learning-rate", type=float, default=1e-4) + parser.add_argument("--mask-ratio", type=float, default=0.2) + parser.add_argument("--retrieval-probe-epochs", type=int, default=20) + parser.add_argument("--reconstruction-probe-epochs", type=int, default=25) + parser.add_argument("--retrieval-tolerance", type=int, default=1) + parser.add_argument("--shuffle-repeats", type=int, default=5) + parser.add_argument("--mvr-epsilon", type=float, default=0.02) + parser.add_argument("--example-id", default="-tPCytz4rww/12") + return parser + + +def main() -> int: + args = build_parser().parse_args() + manifest = run(args) + print(json.dumps(manifest, ensure_ascii=False, indent=2)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/deep_learning/Q1/q1/tsfa_alignment_only_eval.py b/deep_learning/Q1/q1/tsfa_alignment_only_eval.py new file mode 100644 index 0000000..926585c --- /dev/null +++ b/deep_learning/Q1/q1/tsfa_alignment_only_eval.py @@ -0,0 +1,353 @@ +"""Evaluate TSFA attention maps using identical raw source content for every method. + +This probe pools the same train-fold-standardized BERT, audio, and DeiT features +with each method's alignment matrix. It excludes native model value/output +projections from the representation being scored. +""" + +from __future__ import annotations + +import csv +import json +import shutil +import time +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Mapping, Sequence + +import numpy as np +import torch + +from .correspondence_eval import _cluster_bootstrap, _write_csv +from .experiment_data import ( + FeatureSample, + collate_feature_samples, + fit_feature_stats, + load_feature_samples, +) +from .m4_shared_latent_eval import _bootstrap_summary +from .tsfa_experiment import ( + ALL_METHODS, + BASELINE_VARIANTS, + GRID_SIZE, + TSFA_VARIANTS, + _ablation_summary, + _collect_fold_features, + _content_summary, + _evaluate_fixed_projector, + _fit_method_probe, + _generate_tsfa_outputs, + _load_semantic_checkpoint, + build_parser, +) +from .types import MODALITIES + + +def _pool_same_raw_features( + samples: Sequence[FeatureSample], + feature_stats: Any, + weights_by_id: Mapping[str, Mapping[str, np.ndarray]], + device: torch.device, + batch_size: int, +) -> dict[str, dict[str, np.ndarray]]: + content: dict[str, dict[str, np.ndarray]] = {} + with torch.no_grad(): + for start in range(0, len(samples), batch_size): + batch_samples = list(samples[start : start + batch_size]) + sequences, _, _ = collate_feature_samples(batch_samples, feature_stats, device) + for index, sample in enumerate(batch_samples): + content[sample.sample_id] = {} + for modality in MODALITIES: + length = len(sample.features[modality]) + weights = torch.as_tensor( + weights_by_id[sample.sample_id][modality], + dtype=torch.float32, + device=device, + ) + if weights.shape != (GRID_SIZE, length): + raise ValueError(f"unexpected alignment shape for {sample.sample_id}/{modality}") + source = sequences[modality].features[index, :length] + content[sample.sample_id][modality] = ( + (weights @ source).cpu().numpy().astype(np.float32, copy=False) + ) + return content + + +def _paired_summary(rows: Sequence[Mapping[str, Any]], seed: int) -> list[dict[str, Any]]: + by_key = {(row["method"], row["sample_id"]): row for row in rows} + sample_ids = sorted({row["sample_id"] for row in rows}) + contrasts = ( + ("TSFA-main", "M4_sourceTime"), + ("TSFA-main", "TSFA-random"), + ("TSFA-main", "TSFA-global"), + ("TSFA-multiply", "TSFA-main"), + ("TSFA-main", "M3_noSourceTime"), + ) + output = [] + for contrast_index, (left, right) in enumerate(contrasts): + for metric_index, metric in enumerate(( + "content_auc_mean", "canonical_pairwise_time_mae_mean" + )): + differences = [] + for sample_id in sample_ids: + left_row = by_key[(left, sample_id)] + right_row = by_key[(right, sample_id)] + if left_row["video_id"] != right_row["video_id"]: + raise ValueError(f"video group mismatch for {sample_id}") + differences.append({ + "video_id": left_row["video_id"], + "difference": float(left_row[metric]) - float(right_row[metric]), + }) + mean, low, high, groups = _cluster_bootstrap( + differences, + "difference", + seed=seed + contrast_index * 101 + metric_index, + repetitions=2000, + ) + output.append({ + "left_method": left, + "right_method": right, + "metric": metric, + "clip_count": len(differences), + "video_id_count": groups, + "left_minus_right_video_macro_mean": mean, + "ci95_low": low, + "ci95_high": high, + }) + return output + + +def _temporal_diagnostic_rows( + method: str, + fold: int, + sample: FeatureSample, + weights: Mapping[str, np.ndarray], + draw: int = 0, +) -> list[dict[str, Any]]: + output = [] + for modality in MODALITIES: + valid = np.asarray(sample.valid[modality], dtype=bool) + attention = np.asarray(weights[modality], dtype=np.float64)[:, valid] + times = np.asarray(sample.times[modality], dtype=np.float64)[valid] / max(sample.duration_s, 1e-8) + centers = attention @ times + backward = centers[:-1] - centers[1:] + entropy = -(attention * np.log(np.maximum(attention, 1e-12))).sum(axis=1) + output.append({ + "method": method, + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "draw": draw, + "modality": modality, + "mvr_epsilon_0_01": float(np.mean(backward > 0.01)), + "mvr_epsilon_0_02": float(np.mean(backward > 0.02)), + "mvr_epsilon_0_05": float(np.mean(backward > 0.05)), + "time_span_ratio": float(centers[-1] - centers[0]), + "normalized_entropy_mean": float(entropy.mean() / max(np.log(attention.shape[1]), 1e-12)), + "source_coverage_rate": float(np.mean(attention.sum(axis=0) > 1e-12)), + }) + return output + + +def run(args: Any) -> None: + started = time.time() + device = torch.device( + ("cuda" if torch.cuda.is_available() else "cpu") if args.device == "auto" else args.device + ) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA is unavailable") + samples = load_feature_samples(args.feature_dir, args.manifest) + samples_by_id = {sample.sample_id: sample for sample in samples} + splits = json.loads(args.splits.read_text(encoding="utf-8")) + if len(splits) != 5: + raise ValueError("expected five grouped folds") + store = torch.load(args.output_dir / "probe_checkpoints.pt", map_location="cpu", weights_only=False) + content_rows: list[dict[str, Any]] = [] + curve_rows: list[dict[str, Any]] = [] + temporal_diagnostic_rows: list[dict[str, Any]] = [] + history_rows: list[dict[str, Any]] = [] + probe_store: dict[str, Any] = {} + heldout_ids = [] + + for split in splits: + fold = int(split["fold"]) + train = [samples_by_id[sample_id] for sample_id in split["train_sample_ids"]] + validation = [samples_by_id[sample_id] for sample_id in split["validation_sample_ids"]] + if {sample.group_id for sample in train} & {sample.group_id for sample in validation}: + raise ValueError(f"video_id leakage in fold {fold}") + heldout_ids.extend(sample.sample_id for sample in validation) + feature_stats = fit_feature_stats(train) + _, baseline_weights, temporal_by_id = _collect_fold_features( + fold=fold, + train_samples=train, + validation_samples=validation, + feature_stats=feature_stats, + checkpoint_root=args.checkpoint_root, + device=device, + batch_size=args.batch_size, + ) + branch = _load_semantic_checkpoint(store, fold, device) + all_samples = [*train, *validation] + all_ids = [sample.sample_id for sample in all_samples] + fold_weights = {method: baseline_weights[method] for method in BASELINE_VARIANTS} + for method in TSFA_VARIANTS: + _, weights, _ = _generate_tsfa_outputs( + method=method, + fold=fold, + sample_ids=all_ids, + samples_by_id=samples_by_id, + temporal_by_id=temporal_by_id, + branch=branch, + device=device, + delta=args.delta, + seed=args.seed, + draw=0, + batch_size=args.batch_size, + ) + fold_weights[method] = weights + + for method in ALL_METHODS: + pooled = _pool_same_raw_features( + all_samples, feature_stats, fold_weights[method], device, args.batch_size + ) + metrics, curves, _ = _fit_method_probe( + method=method, + fold=fold, + train_samples=train, + validation_samples=validation, + content_by_id=pooled, + device=device, + args=args, + history_rows=history_rows, + checkpoint_store=probe_store, + ) + content_rows.extend(metrics) + curve_rows.extend(curves) + for sample in validation: + temporal_diagnostic_rows.extend(_temporal_diagnostic_rows( + method, fold, sample, fold_weights[method][sample.sample_id] + )) + if method == "TSFA-random": + for draw in range(1, args.random_window_repeats): + _, random_weights, _ = _generate_tsfa_outputs( + method=method, + fold=fold, + sample_ids=[sample.sample_id for sample in validation], + samples_by_id=samples_by_id, + temporal_by_id=temporal_by_id, + branch=branch, + device=device, + delta=args.delta, + seed=args.seed, + draw=draw, + batch_size=args.batch_size, + ) + random_pooled = _pool_same_raw_features( + validation, feature_stats, random_weights, device, args.batch_size + ) + repeated_metrics, repeated_curves, _ = _evaluate_fixed_projector( + method=method, + fold=fold, + validation_samples=validation, + content_by_id=random_pooled, + projector_state=probe_store[ + f"fold_{fold:02d}/{method}/correspondence_probe" + ]["state_dict"], + device=device, + ) + content_rows.extend({**row, "draw": draw} for row in repeated_metrics) + curve_rows.extend({**row, "draw": draw} for row in repeated_curves) + for sample in validation: + temporal_diagnostic_rows.extend(_temporal_diagnostic_rows( + method, fold, sample, random_weights[sample.sample_id], draw + )) + print(f"[TSFA alignment-only fold {fold}] heldout={len(validation)}", flush=True) + del branch, baseline_weights, temporal_by_id, fold_weights + if device.type == "cuda": + torch.cuda.empty_cache() + + if len(heldout_ids) != 100 or len(set(heldout_ids)) != 100: + raise ValueError("held-out fold coverage is not exactly 100 distinct samples") + output_dir = args.output_dir + content_summary, curve_summary = _content_summary(content_rows, curve_rows, args.seed + 901) + with (output_dir / "temporal_metrics_by_clip.csv").open( + newline="", encoding="utf-8-sig" + ) as handle: + temporal_rows = list(csv.DictReader(handle)) + ablation_summary, ablation_by_clip = _ablation_summary( + content_rows, temporal_rows, args.seed + 902 + ) + paired = _paired_summary(ablation_by_clip, args.seed + 903) + temporal_diagnostic_summary = _bootstrap_summary( + temporal_diagnostic_rows, + ("method", "modality"), + ( + "mvr_epsilon_0_01", "mvr_epsilon_0_02", "mvr_epsilon_0_05", + "time_span_ratio", "normalized_entropy_mean", "source_coverage_rate", + ), + seed=args.seed + 904, + ) + _write_csv(output_dir / "alignment_only_content_by_clip.csv", content_rows) + _write_csv(output_dir / "alignment_only_content_summary.csv", content_summary) + _write_csv(output_dir / "alignment_only_shift_curve_summary.csv", curve_summary) + _write_csv(output_dir / "alignment_only_ablation_by_clip.csv", ablation_by_clip) + _write_csv(output_dir / "alignment_only_ablation_summary.csv", ablation_summary) + _write_csv(output_dir / "alignment_only_paired_contrasts.csv", paired) + _write_csv(output_dir / "alignment_only_probe_training_history.csv", history_rows) + _write_csv(output_dir / "tsfa_temporal_diagnostics_by_clip.csv", temporal_diagnostic_rows) + _write_csv(output_dir / "tsfa_temporal_diagnostics_summary.csv", temporal_diagnostic_summary) + torch.save(probe_store, output_dir / "alignment_only_probe_checkpoints.pt") + run_manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "experiment": "TSFA shared raw-content alignment-only probe", + "sample_count": len(samples), + "heldout_count": len(heldout_ids), + "video_id_count": len({sample.group_id for sample in samples}), + "fold_count": len(splits), + "seed": args.seed, + "delta": args.delta, + "probe_epochs": args.probe_epochs, + "random_window_repeats": args.random_window_repeats, + "feature_protocol": "Within each fold, feature normalization is fitted on 80 training clips. For every method and modality, the same normalized raw source feature matrix is pooled using that method's A^m; native M3/M4/TSFA value and output projections are excluded from scored features.", + "probe_protocol": "One 64-dimensional linear projector per modality, trained on 80 training clips with the same within-clip InfoNCE protocol and identical fold seed across methods. Scores use only 20 held-out clips per fold.", + "interpretation_limit": "A same-slot positive is a timestamp/slot convention, not independently annotated semantic ground truth. Source-time attention can still encode time through selected raw values.", + "device": str(device), + "elapsed_seconds": time.time() - started, + } + (output_dir / "alignment_only_run_manifest.json").write_text( + json.dumps(run_manifest, ensure_ascii=False, indent=2), encoding="utf-8" + ) + bundle = output_dir / "report_bundle" + for name in ( + "alignment_only_content_summary.csv", "alignment_only_ablation_summary.csv", + "alignment_only_paired_contrasts.csv", "alignment_only_run_manifest.json", + "tsfa_temporal_diagnostics_summary.csv", + ): + shutil.copy2(output_dir / name, bundle / name) + bundle_readme = bundle / "README.md" + note = ( + "\nThe `alignment_only_*` summaries pool identical train-fold-standardized " + "raw source features through each method's alignment matrix. They isolate " + "source selection from native model value/output projections.\n" + ) + current = bundle_readme.read_text(encoding="utf-8") + if "The `alignment_only_*` summaries" not in current: + bundle_readme.write_text(current + note, encoding="utf-8") + print( + f"[TSFA alignment-only complete] samples={len(heldout_ids)} " + f"elapsed={run_manifest['elapsed_seconds']:.1f}s output={output_dir}", + flush=True, + ) + + +def main() -> None: + args = build_parser().parse_args() + if args.finalize_existing: + raise ValueError("--finalize-existing belongs to q1.tsfa_experiment") + if not 0 < args.delta <= 1: + raise ValueError("--delta must be in (0,1]") + run(args) + + +if __name__ == "__main__": + main() diff --git a/deep_learning/Q1/q1/tsfa_experiment.py b/deep_learning/Q1/q1/tsfa_experiment.py new file mode 100644 index 0000000..d8fd475 --- /dev/null +++ b/deep_learning/Q1/q1/tsfa_experiment.py @@ -0,0 +1,1774 @@ +"""Grouped five-fold TSFA coarse-to-fine alignment experiment. + +The M4 source-time model is frozen and supplies temporal candidate windows. +Only a content-only local semantic branch is trained. No emotion labels or +positional/time codes enter that branch. +""" + +from __future__ import annotations + +import argparse +import csv +import hashlib +import json +import math +import platform +import random +import shutil +import time +from collections import defaultdict +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Mapping, Sequence + +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import numpy as np +import torch +import torch.nn.functional as F +from torch import Tensor, nn + +from .correspondence_eval import ( + CorrespondenceProjection, + _cluster_bootstrap, + _fit_probe, + _sample_metrics, + _stack_ids, + _write_csv, +) +from .experiment_data import ( + FeatureSample, + collate_feature_samples, + fit_feature_stats, + load_feature_samples, +) +from .m4_shared_latent_eval import ( + ContentReconstructionProbe, + DECODER_TARGETS, + PAIRINGS, + SHIFTS, + _bootstrap_summary, + _content_pair_metrics, + _cycle_triangle_metrics, + _normalize_attention, + _pair_metrics, + _self_structure, +) +from .models import SharedLatentTimeline, TextAnchoredCrossAttention +from .types import MODALITIES + + +GRID_SIZE = 50 +HIDDEN_SIZE = 128 +HEADS = 4 +BASELINE_VARIANTS = ("M3_noSourceTime", "M3_sourceTime", "M4_sourceTime") +TSFA_VARIANTS = ("TSFA-main", "TSFA-multiply", "TSFA-random", "TSFA-global") +ALL_METHODS = (*BASELINE_VARIANTS, *TSFA_VARIANTS) +HARD_NEGATIVE_OFFSETS = (-5, -3, -2, 2, 3, 5) +RECONSTRUCTION_METHODS = ("M4_sourceTime", "TSFA-main") +SHUFFLE_METHODS = ("M4_sourceTime", "TSFA-main") + + +class TSFASemanticBranch(nn.Module): + """Content-only Text-to-Audio/Vision attention with no positional input.""" + + def __init__(self, dimension: int = HIDDEN_SIZE, match_dimension: int = 64) -> None: + super().__init__() + self.query = nn.Linear(dimension, dimension, bias=False) + self.keys = nn.ModuleDict( + {name: nn.Linear(dimension, dimension, bias=False) for name in ("audio", "vision")} + ) + self.values = nn.ModuleDict( + {name: nn.Linear(dimension, dimension, bias=False) for name in ("audio", "vision")} + ) + self.match = nn.ModuleDict( + {name: nn.Linear(dimension, match_dimension, bias=False) for name in MODALITIES} + ) + + def attend( + self, + text_content: Tensor, + source_content: Tensor, + modality: str, + candidate_mask: Tensor, + temporal_prior: Tensor | None = None, + ) -> tuple[Tensor, Tensor]: + query = self.query(text_content) + keys = self.keys[modality](source_content) + scores = torch.bmm(query, keys.transpose(1, 2)) / math.sqrt(query.shape[-1]) + if temporal_prior is not None: + scores = scores + temporal_prior.clamp_min(1e-8).log() + scores = scores.masked_fill(~candidate_mask, torch.finfo(scores.dtype).min) + weights = torch.softmax(scores, dim=-1) + values = self.values[modality](source_content) + return weights, torch.bmm(weights, values) + + def match_embedding(self, modality: str, content: Tensor) -> Tensor: + return F.normalize(self.match[modality](content), dim=-1) + + +def _checkpoint_path(root: Path, variant: str, fold: int) -> Path: + if fold == 1: + return root / variant / "checkpoint.pt" + return root / f"fold_{fold:02d}" / variant / "checkpoint.pt" + + +def _instantiate_alignment_model( + variant: str, dimensions: Mapping[str, int] +) -> nn.Module: + if variant.startswith("M3_"): + return TextAnchoredCrossAttention( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + source_time_encoding=variant == "M3_sourceTime", + ) + return SharedLatentTimeline( + dimensions, + grid_size=GRID_SIZE, + hidden_size=HIDDEN_SIZE, + heads=HEADS, + dropout=0.0, + absolute_position_encoding=True, + source_time_encoding=True, + ) + + +def _collect_fold_features( + *, + fold: int, + train_samples: Sequence[FeatureSample], + validation_samples: Sequence[FeatureSample], + feature_stats: Any, + checkpoint_root: Path, + device: torch.device, + batch_size: int, +) -> tuple[ + dict[str, dict[str, dict[str, np.ndarray]]], + dict[str, dict[str, dict[str, np.ndarray]]], + dict[str, dict[str, np.ndarray]], +]: + """Return baseline content/weights and frozen M4 temporal tensors.""" + dimensions = {name: train_samples[0].features[name].shape[1] for name in MODALITIES} + all_samples = [*train_samples, *validation_samples] + all_ids = [sample.sample_id for sample in all_samples] + content_by_method: dict[str, dict[str, dict[str, np.ndarray]]] = {} + weights_by_method: dict[str, dict[str, dict[str, np.ndarray]]] = {} + temporal_by_id: dict[str, dict[str, np.ndarray]] = {} + + for variant in BASELINE_VARIANTS: + checkpoint_path = _checkpoint_path(checkpoint_root, variant, fold) + if not checkpoint_path.is_file(): + raise FileNotFoundError(f"missing {variant} fold {fold} checkpoint: {checkpoint_path}") + checkpoint = torch.load(checkpoint_path, map_location=device, weights_only=False) + if checkpoint.get("variant") != variant: + raise ValueError(f"checkpoint variant mismatch at {checkpoint_path}") + if set(checkpoint.get("train_sample_ids", [])) != {s.sample_id for s in train_samples}: + raise ValueError(f"checkpoint training IDs do not match fold {fold}: {variant}") + if set(checkpoint.get("validation_sample_ids", [])) != {s.sample_id for s in validation_samples}: + raise ValueError(f"checkpoint held-out IDs do not match fold {fold}: {variant}") + + model = _instantiate_alignment_model(variant, dimensions).to(device) + model.load_state_dict(checkpoint["model_state_dict"], strict=True) + model.eval() + method_content: dict[str, dict[str, np.ndarray]] = {} + method_weights: dict[str, dict[str, np.ndarray]] = {} + with torch.no_grad(): + for start in range(0, len(all_samples), batch_size): + batch_samples = all_samples[start : start + batch_size] + sequences, durations, _ = collate_feature_samples(batch_samples, feature_stats, device) + output = model(sequences, durations) + projected_sources = { + name: model.projections[name](sequences[name].features) for name in MODALITIES + } + for index, sample in enumerate(batch_samples): + one_content: dict[str, np.ndarray] = {} + one_weights: dict[str, np.ndarray] = {} + for name in MODALITIES: + length = len(sample.features[name]) + weights = output.weights[name][index, :, :length] + if variant.startswith("M3_") and name == "text": + # M3's returned text query contains a timestamp PE + # residual in the source-time setting. Keep only + # attention-pooled text content for this probe. + pooled = torch.matmul( + weights, projected_sources[name][index, :length] + ) + else: + # The actual attention output includes MHA value + # and output projections. Using A@pre-attention + # features would change the frozen baseline. + pooled = output.aligned[name][index] + one_content[name] = pooled.cpu().numpy().astype(np.float32, copy=False) + one_weights[name] = weights.cpu().numpy().astype(np.float32, copy=False) + method_content[sample.sample_id] = one_content + method_weights[sample.sample_id] = one_weights + if variant == "M4_sourceTime": + temporal_by_id[sample.sample_id] = { + "weights": one_weights, + "values": { + name: projected_sources[name][index, : len(sample.features[name])] + .cpu() + .numpy() + .astype(np.float32, copy=False) + for name in MODALITIES + }, + "times": { + name: (sample.times[name] / max(sample.duration_s, 1e-8)).astype( + np.float32, copy=False + ) + for name in MODALITIES + }, + "valid": {name: sample.valid[name].copy() for name in MODALITIES}, + "content": one_content, + } + content_by_method[variant] = method_content + weights_by_method[variant] = method_weights + del model, checkpoint + if device.type == "cuda": + torch.cuda.empty_cache() + + if set(temporal_by_id) != set(all_ids): + raise ValueError("frozen M4 temporal features are incomplete") + return content_by_method, weights_by_method, temporal_by_id + + +def _stable_seed(seed: int, *parts: str | int) -> int: + payload = "|".join([str(seed), *(str(part) for part in parts)]).encode("utf-8") + return int.from_bytes(hashlib.sha256(payload).digest()[:8], "little") % (2**32) + + +def _random_centers( + record: Mapping[str, Any], modality: str, *, seed: int, draw: int +) -> np.ndarray: + valid = np.asarray(record["valid"][modality], dtype=bool) + times = np.asarray(record["times"][modality], dtype=np.float64) + if not valid.any(): + raise ValueError(f"no valid time positions for random candidate window: {modality}") + rng = np.random.default_rng(_stable_seed(seed, record.get("sample_id", ""), modality, draw)) + low, high = float(times[valid].min()), float(times[valid].max()) + if high <= low: + return np.full(GRID_SIZE, low, dtype=np.float32) + return rng.uniform(low, high, size=GRID_SIZE).astype(np.float32) + + +def _candidate_mask( + times: Tensor, + valid: Tensor, + centers: Tensor, + *, + delta: float, + mode: str, +) -> tuple[Tensor, Tensor]: + if mode == "global": + mask = valid[:, None, :].expand(-1, GRID_SIZE, -1).clone() + else: + mask = (times[:, None, :] - centers[:, :, None]).abs() <= delta + mask &= valid[:, None, :] + empty = ~mask.any(dim=-1) + if empty.any(): + distance = (times[:, None, :] - centers[:, :, None]).abs() + distance = distance.masked_fill(~valid[:, None, :], torch.inf) + nearest = distance.argmin(dim=-1) + batch_index, slot_index = empty.nonzero(as_tuple=True) + mask[batch_index, slot_index, nearest[batch_index, slot_index]] = True + return mask, empty + + +def _collate_temporal( + sample_ids: Sequence[str], + temporal_by_id: Mapping[str, Mapping[str, Any]], + device: torch.device, +) -> dict[str, Any]: + batch_size = len(sample_ids) + dimensions = {name: temporal_by_id[sample_ids[0]]["values"][name].shape[1] for name in MODALITIES} + tensors: dict[str, Any] = { + "text_content": torch.from_numpy( + np.stack([temporal_by_id[sample_id]["content"]["text"] for sample_id in sample_ids]) + ).to(device), + "values": {}, + "times": {}, + "valid": {}, + "weights": {}, + "centers": {}, + } + for name in MODALITIES: + max_length = max(len(temporal_by_id[sample_id]["times"][name]) for sample_id in sample_ids) + values = torch.zeros(batch_size, max_length, dimensions[name], dtype=torch.float32, device=device) + times = torch.zeros(batch_size, max_length, dtype=torch.float32, device=device) + valid = torch.zeros(batch_size, max_length, dtype=torch.bool, device=device) + weights = torch.zeros(batch_size, GRID_SIZE, max_length, dtype=torch.float32, device=device) + for index, sample_id in enumerate(sample_ids): + record = temporal_by_id[sample_id] + length = len(record["times"][name]) + values[index, :length] = torch.from_numpy(record["values"][name]).to(device) + times[index, :length] = torch.from_numpy(record["times"][name]).to(device) + valid[index, :length] = torch.from_numpy(record["valid"][name]).to(device) + weights[index, :, :length] = torch.from_numpy(record["weights"][name]).to(device) + centers = (weights * times[:, None, :]).sum(dim=-1) + tensors["values"][name] = values + tensors["times"][name] = times + tensors["valid"][name] = valid + tensors["weights"][name] = weights + tensors["centers"][name] = centers + return tensors + + +def _local_contrastive_loss( + branch: TSFASemanticBranch, + text_content: Tensor, + audio_content: Tensor, + vision_content: Tensor, + *, + temperature: float, +) -> Tensor: + offsets = HARD_NEGATIVE_OFFSETS + anchor_indices = torch.arange(5, GRID_SIZE - 5, device=text_content.device) + labels = torch.zeros(anchor_indices.numel(), dtype=torch.long, device=text_content.device) + + def directed(query: Tensor, target: Tensor) -> Tensor: + candidates = torch.stack( + [target.index_select(1, anchor_indices + offset) for offset in (0, *offsets)], dim=2 + ) + anchors = query.index_select(1, anchor_indices) + logits = (anchors.unsqueeze(2) * candidates).sum(dim=-1) / temperature + return F.cross_entropy(logits.reshape(-1, logits.shape[-1]), labels.repeat(query.shape[0])) + + text_embedding = branch.match_embedding("text", text_content) + audio_embedding = branch.match_embedding("audio", audio_content) + vision_embedding = branch.match_embedding("vision", vision_content) + loss_ta = (directed(text_embedding, audio_embedding) + directed(audio_embedding, text_embedding)) / 2 + loss_tv = (directed(text_embedding, vision_embedding) + directed(vision_embedding, text_embedding)) / 2 + return (loss_ta + loss_tv) / 2 + + +def _fit_semantic_branch( + *, + fold: int, + train_samples: Sequence[FeatureSample], + temporal_by_id: Mapping[str, Mapping[str, Any]], + device: torch.device, + seed: int, + epochs: int, + batch_size: int, + learning_rate: float, + temperature: float, + delta: float, +) -> tuple[TSFASemanticBranch, list[dict[str, Any]]]: + fold_seed = seed + fold * 101 + random.seed(fold_seed) + np.random.seed(fold_seed) + torch.manual_seed(fold_seed) + if device.type == "cuda": + torch.cuda.manual_seed_all(fold_seed) + branch = TSFASemanticBranch(HIDDEN_SIZE).to(device) + optimizer = torch.optim.AdamW(branch.parameters(), lr=learning_rate, weight_decay=1e-4) + rng = np.random.default_rng(fold_seed) + train_ids = [sample.sample_id for sample in train_samples] + history = [] + branch.train() + for epoch in range(1, epochs + 1): + order = rng.permutation(len(train_ids)) + losses = [] + for start in range(0, len(order), batch_size): + ids = [train_ids[int(index)] for index in order[start : start + batch_size]] + batch = _collate_temporal(ids, temporal_by_id, device) + audio_mask, empty_audio = _candidate_mask( + batch["times"]["audio"], + batch["valid"]["audio"], + batch["centers"]["audio"], + delta=delta, + mode="local", + ) + vision_mask, empty_vision = _candidate_mask( + batch["times"]["vision"], + batch["valid"]["vision"], + batch["centers"]["vision"], + delta=delta, + mode="local", + ) + audio_weights, audio_content = branch.attend( + batch["text_content"], batch["values"]["audio"], "audio", audio_mask + ) + vision_weights, vision_content = branch.attend( + batch["text_content"], batch["values"]["vision"], "vision", vision_mask + ) + loss = _local_contrastive_loss( + branch, + batch["text_content"], + audio_content, + vision_content, + temperature=temperature, + ) + if not torch.isfinite(loss): + raise FloatingPointError(f"non-finite TSFA local contrastive loss at fold {fold}, epoch {epoch}") + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(branch.parameters(), 1.0) + optimizer.step() + losses.append(float(loss.detach().item())) + history.append( + { + "fold": fold, + "epoch": epoch, + "seed": fold_seed, + "train_loss": float(np.mean(losses)), + "candidate_empty_audio_rows": int(empty_audio.sum().item()), + "candidate_empty_vision_rows": int(empty_vision.sum().item()), + "attention_row_sum_error_audio": float((audio_weights.sum(-1) - 1).abs().max().item()), + "attention_row_sum_error_vision": float((vision_weights.sum(-1) - 1).abs().max().item()), + } + ) + branch.eval() + return branch, history + + +def _candidate_statistics( + *, + method: str, + fold: int, + sample: FeatureSample, + modality: str, + candidate_mask: Tensor, + temporal_weights: Tensor, + times: Tensor, + centers: Tensor, + draw: int, +) -> dict[str, Any]: + mask = candidate_mask[0].to(torch.float32) + weights = temporal_weights[0] + times_row = times[0] + counts = mask.sum(dim=-1) + candidate_mean_times = (mask * times_row[None, :]).sum(dim=-1) / counts.clamp_min(1) + valid_count = int(sample.valid[modality].sum()) + return { + "method": method, + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "modality": modality, + "draw": draw, + "candidate_count_mean": float(counts.mean().item()), + "candidate_count_min": int(counts.min().item()), + "candidate_count_max": int(counts.max().item()), + "candidate_fraction_valid_mean": float((counts / max(valid_count, 1)).mean().item()), + "temporal_prior_mass_mean": float((weights * mask).sum(dim=-1).mean().item()), + "candidate_mean_center_error": float((candidate_mean_times - centers[0]).abs().mean().item()), + } + + +def _generate_tsfa_outputs( + *, + method: str, + fold: int, + sample_ids: Sequence[str], + samples_by_id: Mapping[str, FeatureSample], + temporal_by_id: Mapping[str, Mapping[str, Any]], + branch: TSFASemanticBranch, + device: torch.device, + delta: float, + seed: int, + draw: int = 0, + batch_size: int = 8, +) -> tuple[ + dict[str, dict[str, np.ndarray]], + dict[str, dict[str, np.ndarray]], + list[dict[str, Any]], +]: + content_by_id: dict[str, dict[str, np.ndarray]] = {} + weights_by_id: dict[str, dict[str, np.ndarray]] = {} + candidate_rows: list[dict[str, Any]] = [] + mode = "global" if method == "TSFA-global" else "local" + use_random_centers = method == "TSFA-random" + use_prior = method == "TSFA-multiply" + branch.eval() + with torch.no_grad(): + for start in range(0, len(sample_ids), batch_size): + ids = list(sample_ids[start : start + batch_size]) + batch = _collate_temporal(ids, temporal_by_id, device) + variant_masks: dict[str, Tensor] = {} + variant_centers: dict[str, Tensor] = {} + empty_rows: dict[str, Tensor] = {} + for modality in ("audio", "vision"): + centers = batch["centers"][modality] + if use_random_centers: + centers = torch.from_numpy( + np.stack( + [ + _random_centers( + {**temporal_by_id[sample_id], "sample_id": sample_id}, + modality, + seed=seed + fold * 1009, + draw=draw, + ) + for sample_id in ids + ] + ) + ).to(device) + candidate_mask, empty = _candidate_mask( + batch["times"][modality], + batch["valid"][modality], + centers, + delta=delta, + mode=mode, + ) + variant_masks[modality] = candidate_mask + variant_centers[modality] = centers + empty_rows[modality] = empty + prior_audio = batch["weights"]["audio"] if use_prior else None + prior_vision = batch["weights"]["vision"] if use_prior else None + audio_weights, audio_content = branch.attend( + batch["text_content"], + batch["values"]["audio"], + "audio", + variant_masks["audio"], + temporal_prior=prior_audio, + ) + vision_weights, vision_content = branch.attend( + batch["text_content"], + batch["values"]["vision"], + "vision", + variant_masks["vision"], + temporal_prior=prior_vision, + ) + for index, sample_id in enumerate(ids): + sample = samples_by_id[sample_id] + record = temporal_by_id[sample_id] + content_by_id[sample_id] = { + "text": record["content"]["text"], + "audio": audio_content[index].cpu().numpy().astype(np.float32, copy=False), + "vision": vision_content[index].cpu().numpy().astype(np.float32, copy=False), + } + weights_by_id[sample_id] = { + "text": record["weights"]["text"], + "audio": audio_weights[index, :, : len(sample.features["audio"])] + .cpu() + .numpy() + .astype(np.float32, copy=False), + "vision": vision_weights[index, :, : len(sample.features["vision"])] + .cpu() + .numpy() + .astype(np.float32, copy=False), + } + for modality in ("audio", "vision"): + length = len(sample.features[modality]) + candidate_rows.append( + _candidate_statistics( + method=method, + fold=fold, + sample=sample, + modality=modality, + candidate_mask=variant_masks[modality][index : index + 1, :, :length], + temporal_weights=batch["weights"][modality][index : index + 1, :, :length], + times=batch["times"][modality][index : index + 1, :length], + centers=variant_centers[modality][index : index + 1], + draw=draw, + ) + ) + return content_by_id, weights_by_id, candidate_rows + + +def _record_temporal_metrics( + *, + method: str, + fold: int, + sample: FeatureSample, + weights: Mapping[str, np.ndarray], + draw: int = 0, +) -> list[dict[str, Any]]: + normalized_times = { + name: np.asarray(sample.times[name], dtype=np.float64) / max(sample.duration_s, 1e-8) + for name in MODALITIES + } + # A hard TSFA window can leave valid source positions with exactly zero + # attention. Use the same supported positions in both directions so cycle + # and triangle maps have compatible shapes. + source_to_slot = {} + source_indices = {} + rows: list[dict[str, Any]] = [] + for modality in MODALITIES: + source_to_slot[modality], source_indices[modality], _ = _normalize_attention( + weights[modality], sample.valid[modality] + ) + _, self_metrics = _self_structure(weights[modality]) + rows.append({"kind": "self", "modality": modality, **self_metrics}) + pair_maps = {} + directions = (*PAIRINGS, *((right, left) for left, right in PAIRINGS)) + for left, right in directions: + mapping = source_to_slot[left].T @ np.asarray( + weights[right][:, source_indices[right]], dtype=np.float64 + ) + mapping /= np.maximum(mapping.sum(axis=1, keepdims=True), 1e-12) + mapping = mapping.astype(np.float32) + pair_maps[f"{left}_{right}"] = ( + mapping, source_indices[left], source_indices[right] + ) + rows.append({ + "kind": "pairwise", + "direction": f"{left}_to_{right}", + **_pair_metrics( + mapping, + normalized_times[left][source_indices[left]], + normalized_times[right][source_indices[right]], + ), + }) + cycle_rows, _ = _cycle_triangle_metrics(pair_maps, normalized_times) + for row in cycle_rows: + rows.append({"kind": "cycle_triangle", "cycle_kind": row["kind"], **{ + key: value for key, value in row.items() if key != "kind" + }}) + output = [] + for row in rows: + output.append( + { + **row, + "method": method, + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "draw": draw, + } + ) + for modality in MODALITIES: + mu = np.asarray(weights[modality], dtype=np.float64) @ normalized_times[modality] + output.append( + { + "kind": "span", + "method": method, + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "draw": draw, + "modality": modality, + "span_ratio": float(mu[-1] - mu[0]), + "span_abs": float(abs(mu[-1] - mu[0])), + } + ) + return output + + +def _fit_method_probe( + *, + method: str, + fold: int, + train_samples: Sequence[FeatureSample], + validation_samples: Sequence[FeatureSample], + content_by_id: Mapping[str, Mapping[str, np.ndarray]], + device: torch.device, + args: argparse.Namespace, + history_rows: list[dict[str, Any]], + checkpoint_store: dict[str, Any], +) -> tuple[list[dict[str, Any]], list[dict[str, Any]], dict[str, Tensor]]: + train_ids = [sample.sample_id for sample in train_samples] + validation_ids = [sample.sample_id for sample in validation_samples] + probe_seed = args.seed + fold * 101 + projector, history = _fit_probe( + train_ids, + content_by_id, + device=device, + seed=probe_seed, + epochs=args.probe_epochs, + batch_size=args.batch_size, + learning_rate=args.probe_learning_rate, + temperature=args.probe_temperature, + ) + history_rows.extend( + {"fold": fold, "method": method, "probe": "crossmodal_correspondence", "seed": probe_seed, **row} + for row in history + ) + projector.eval() + with torch.no_grad(): + validation = _stack_ids(validation_ids, content_by_id, device) + projected = projector(validation) + metrics: list[dict[str, Any]] = [] + curves: list[dict[str, Any]] = [] + for index, sample in enumerate(validation_samples): + one = {name: projected[name][index] for name in MODALITIES} + metrics.extend( + _sample_metrics( + method=method, + fold=fold, + sample=sample, + projected=one, + curve_rows=curves, + ) + ) + checkpoint_store[f"fold_{fold:02d}/{method}/correspondence_probe"] = { + "seed": probe_seed, + "state_dict": {key: value.detach().cpu() for key, value in projector.state_dict().items()}, + } + del projector + if device.type == "cuda": + torch.cuda.empty_cache() + return metrics, curves, projected + + +def _shuffle_control_rows( + *, + method: str, + fold: int, + validation_samples: Sequence[FeatureSample], + projected: Mapping[str, Tensor], + repeats: int, + seed: int, + device: torch.device, +) -> list[dict[str, Any]]: + rng = np.random.default_rng(seed + fold * 997) + rows = [] + with torch.no_grad(): + for index, sample in enumerate(validation_samples): + for repeat in range(repeats): + permuted = { + name: projected[name][index].index_select( + 0, torch.as_tensor(rng.permutation(GRID_SIZE), device=device) + ) + for name in MODALITIES + } + for left, right in PAIRINGS: + scores = (permuted[left] @ permuted[right].T).cpu().numpy() + rows.append( + _content_pair_metrics( + scores, + method=method, + fold=fold, + sample=sample, + pair=f"{left}_{right}", + control="independent_within_clip_permutation", + shuffle_id=repeat, + ) + ) + return rows + + +def _fit_and_score_decoder( + *, + method: str, + fold: int, + train_samples: Sequence[FeatureSample], + validation_samples: Sequence[FeatureSample], + content_by_id: Mapping[str, Mapping[str, np.ndarray]], + device: torch.device, + args: argparse.Namespace, + history_rows: list[dict[str, Any]], + checkpoint_store: dict[str, Any], +) -> list[dict[str, Any]]: + seed = args.seed + fold * 211 + torch.manual_seed(seed) + if device.type == "cuda": + torch.cuda.manual_seed_all(seed) + train = _stack_ids([sample.sample_id for sample in train_samples], content_by_id, device) + decoder = ContentReconstructionProbe(train["text"].shape[-1]).to(device) + optimizer = torch.optim.AdamW(decoder.parameters(), lr=args.decoder_learning_rate, weight_decay=1e-4) + rng = np.random.default_rng(seed) + decoder.train() + for epoch in range(1, args.decoder_epochs + 1): + order = rng.permutation(len(train_samples)) + losses = [] + for start in range(0, len(order), args.batch_size): + indexes = torch.as_tensor(order[start : start + args.batch_size], device=device) + batch = {name: value.index_select(0, indexes) for name, value in train.items()} + loss_rows = [] + for target in MODALITIES: + left, right, _ = DECODER_TARGETS[target] + prediction = decoder(target, batch[left], batch[right]) + loss_rows.append(F.smooth_l1_loss(prediction, batch[target])) + loss = torch.stack(loss_rows).mean() + optimizer.zero_grad(set_to_none=True) + loss.backward() + nn.utils.clip_grad_norm_(decoder.parameters(), 1.0) + optimizer.step() + losses.append(float(loss.detach().item())) + history_rows.append( + {"fold": fold, "method": method, "probe": "shifted_reconstruction", "seed": seed, + "epoch": epoch, "train_loss": float(np.mean(losses))} + ) + decoder.eval() + validation = _stack_ids([sample.sample_id for sample in validation_samples], content_by_id, device) + rows = [] + with torch.no_grad(): + for target, (left, right, shifted_modality) in DECODER_TARGETS.items(): + for sample_index, sample in enumerate(validation_samples): + left_values = validation[left][sample_index] + right_values = validation[right][sample_index] + target_values = validation[target][sample_index] + for delta in (*(-value for value in SHIFTS), *SHIFTS): + source_indices = np.arange(max(0, -delta), min(GRID_SIZE, GRID_SIZE - delta)) + shifted_indices = source_indices + delta + target_idx = torch.as_tensor(source_indices, device=device) + shifted_idx = torch.as_tensor(shifted_indices, device=device) + left_eval = left_values.index_select(0, target_idx) + right_aligned = right_values.index_select(0, target_idx) + right_shifted = ( + right_values.index_select(0, shifted_idx) + if shifted_modality == right + else right_aligned + ) + left_shifted = ( + left_values.index_select(0, shifted_idx) + if shifted_modality == left + else left_eval + ) + aligned_prediction = decoder(target, left_eval, right_aligned) + shifted_prediction = decoder(target, left_shifted, right_shifted) + target_eval = target_values.index_select(0, target_idx) + aligned_mae = float((aligned_prediction - target_eval).abs().mean().item()) + shifted_mae = float((shifted_prediction - target_eval).abs().mean().item()) + rows.append( + { + "method": method, + "fold": fold, + "sample_id": sample.sample_id, + "video_id": sample.group_id, + "target_modality": target, + "shifted_modality": shifted_modality, + "delta": delta, + "abs_delta": abs(delta), + "aligned_mae_same_support": aligned_mae, + "shifted_mae": shifted_mae, + "gain_shift_minus_aligned": shifted_mae - aligned_mae, + } + ) + checkpoint_store[f"fold_{fold:02d}/{method}/reconstruction_probe"] = { + "seed": seed, + "state_dict": {key: value.detach().cpu() for key, value in decoder.state_dict().items()}, + } + del decoder + if device.type == "cuda": + torch.cuda.empty_cache() + return rows + + +def _content_summary( + rows: Sequence[Mapping[str, Any]], + curves: Sequence[Mapping[str, Any]], + seed: int, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + metric_names = ( + "same_time_similarity", "shifted_far_similarity", "same_minus_shifted_margin", + "matched_vs_shifted_auc", "exact_r1_text_to_audio", "within_pm1_r1_text_to_audio", + "mase_slots_text_to_audio", "exact_r1_audio_to_text", "within_pm1_r1_audio_to_text", + "mase_slots_audio_to_text", "exact_r1_text_to_vision", "within_pm1_r1_text_to_vision", + "mase_slots_text_to_vision", "exact_r1_vision_to_text", "within_pm1_r1_vision_to_text", + "mase_slots_vision_to_text", "exact_r1_audio_to_vision", "within_pm1_r1_audio_to_vision", + "mase_slots_audio_to_vision", "exact_r1_vision_to_audio", "within_pm1_r1_vision_to_audio", + "mase_slots_vision_to_audio", + ) + grouped: dict[tuple[str, str], list[Mapping[str, Any]]] = defaultdict(list) + for row in rows: + grouped[(str(row["method"]), str(row["pair"]))].append(row) + summary = [] + for (method, pair), values in sorted(grouped.items()): + item: dict[str, Any] = { + "method": method, + "pair": pair, + "clip_count": len({row["sample_id"] for row in values}), + "draw_count": len(values) / max(len({row["sample_id"] for row in values}), 1), + } + for metric_index, metric in enumerate(metric_names): + if metric not in values[0] or values[0][metric] in ("", None): + continue + mean, low, high, groups = _cluster_bootstrap( + values, + metric, + seed=seed + metric_index + sum(ord(char) for char in method + pair), + repetitions=2000, + ) + item[f"{metric}_video_macro_mean"] = mean + item[f"{metric}_ci95_low"] = low + item[f"{metric}_ci95_high"] = high + item["video_id_count"] = groups + summary.append(item) + curve_groups: dict[tuple[str, str, int], list[Mapping[str, Any]]] = defaultdict(list) + for row in curves: + curve_groups[(str(row["method"]), str(row["pair"]), int(row["delta"]))].append(row) + curve_summary = [] + for (method, pair, delta), values in sorted(curve_groups.items()): + mean, low, high, groups = _cluster_bootstrap( + values, + "similarity", + seed=seed + delta + sum(ord(char) for char in method + pair), + repetitions=2000, + ) + curve_summary.append( + { + "method": method, + "pair": pair, + "delta": delta, + "mean_similarity_video_macro": mean, + "ci95_low": low, + "ci95_high": high, + "video_id_count": groups, + } + ) + return summary, curve_summary + + +def _temporal_summary(rows: Sequence[Mapping[str, Any]], seed: int) -> list[dict[str, Any]]: + specifications = ( + ("span", ("method", "modality"), ("span_ratio", "span_abs")), + ("pairwise", ("method", "direction"), ("pairwise_time_mae", "pairwise_signed_lag", "pairwise_time_corr")), + ("self", ("method", "modality"), ("near_similarity_offdiag", "far_similarity", "d_self_offdiag", "gram_target_error", "far_slot_leakage")), + ("cycle_triangle", ("method", "cycle_kind"), ("cycle_band_error", "cycle_time_mae", "triangle_relative_error", "triangle_mean_absolute_residual")), + ) + output = [] + for index, (kind, group_keys, metrics) in enumerate(specifications): + selected = [row for row in rows if row.get("kind") == kind] + for item in _bootstrap_summary(selected, group_keys, metrics, seed=seed + index): + item["metric_family"] = kind + output.append(item) + return output + + +def _ablation_summary( + content_rows: Sequence[Mapping[str, Any]], + temporal_rows: Sequence[Mapping[str, Any]], + seed: int, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + per_sample_content: dict[tuple[str, str, str], list[float]] = defaultdict(list) + for row in content_rows: + per_sample_content[(str(row["method"]), str(row["sample_id"]), str(row["video_id"]))].append( + float(row["matched_vs_shifted_auc"]) + ) + per_sample_time: dict[tuple[str, str, str], list[float]] = defaultdict(list) + for row in temporal_rows: + if row.get("kind") == "pairwise" and row.get("direction") in { + "text_to_audio", "text_to_vision", "audio_to_vision" + }: + per_sample_time[(str(row["method"]), str(row["sample_id"]), str(row["video_id"]))].append( + float(row["pairwise_time_mae"]) + ) + by_method_rows: list[dict[str, Any]] = [] + for key, aucs in per_sample_content.items(): + time_values = per_sample_time.get(key, []) + if not time_values: + continue + by_method_rows.append( + { + "method": key[0], + "sample_id": key[1], + "video_id": key[2], + "content_auc_mean": float(np.mean(aucs)), + "canonical_pairwise_time_mae_mean": float(np.mean(time_values)), + "temporal_quality_1_minus_mae": float(1 - np.mean(time_values)), + } + ) + summary = [] + for method in ALL_METHODS: + values = [row for row in by_method_rows if row["method"] == method] + if not values: + continue + result: dict[str, Any] = { + "method": method, + "clip_count": len(values), + "video_id_count": len({row["video_id"] for row in values}), + } + for index, metric in enumerate(("content_auc_mean", "canonical_pairwise_time_mae_mean", "temporal_quality_1_minus_mae")): + mean, low, high, groups = _cluster_bootstrap( + values, metric, seed=seed + index + sum(ord(char) for char in method), repetitions=2000 + ) + result[f"{metric}_video_macro_mean"] = mean + result[f"{metric}_ci95_low"] = low + result[f"{metric}_ci95_high"] = high + result["video_id_count"] = groups + summary.append(result) + return summary, by_method_rows + + +def _finalize_existing_outputs(output_dir: Path, seed: int) -> None: + """Make paired held-out comparisons and a compact shareable result bundle.""" + def read_csv(name: str) -> list[dict[str, str]]: + with (output_dir / name).open(newline="", encoding="utf-8-sig") as handle: + return list(csv.DictReader(handle)) + + def sha256_file(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + manifest_path = output_dir / "run_manifest.json" + manifest = json.loads(manifest_path.read_text(encoding="utf-8")) + paths = manifest["input_paths"] + feature_files = sorted(Path(paths["feature_dir"]).glob("*.npz")) + if len(feature_files) != manifest["sample_count"]: + raise ValueError("feature file count disagrees with TSFA sample count") + feature_digest = hashlib.sha256() + for feature_file in feature_files: + feature_digest.update(feature_file.name.encode("utf-8")) + feature_digest.update(sha256_file(feature_file).encode("ascii")) + checkpoint_root = Path(paths["checkpoint_root"]) + manifest["input_sha256"] = { + "feature_manifest": sha256_file(Path(paths["feature_manifest"])), + "grouped_splits": sha256_file(Path(paths["grouped_splits"])), + "uv_lock": sha256_file(Path(__file__).resolve().parents[1] / "uv.lock"), + "features_combined": feature_digest.hexdigest(), + "feature_file_count": len(feature_files), + "frozen_alignment_checkpoints": { + f"fold_{fold:02d}/{variant}": sha256_file(_checkpoint_path(checkpoint_root, variant, fold)) + for fold in range(1, 6) + for variant in BASELINE_VARIANTS + }, + } + manifest_path.write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + + ablation_rows = read_csv("ablation_by_clip.csv") + content_rows = read_csv("content_metrics_by_clip.csv") + curve_rows = read_csv("shifted_similarity_by_clip.csv") + content_summary, curve_summary = _content_summary(content_rows, curve_rows, seed + 301) + _write_csv(output_dir / "content_metrics_summary.csv", content_summary) + _write_csv(output_dir / "shifted_similarity_summary.csv", curve_summary) + contrasts = ( + ("TSFA-main", "M4_sourceTime"), + ("TSFA-main", "TSFA-random"), + ("TSFA-main", "TSFA-global"), + ("TSFA-multiply", "TSFA-main"), + ("TSFA-main", "M3_noSourceTime"), + ) + ablation_by_key = { + (row["method"], row["sample_id"]): row for row in ablation_rows + } + content_by_key: dict[tuple[str, str, str], list[float]] = defaultdict(list) + for row in content_rows: + content_by_key[(row["method"], row["sample_id"], row["pair"])].append( + float(row["matched_vs_shifted_auc"]) + ) + sample_ids = sorted({row["sample_id"] for row in ablation_rows}) + paired_rows = [] + metrics = ( + ("overall", "all_pairs", "content_auc_mean"), + ("overall", "all_pairs", "canonical_pairwise_time_mae_mean"), + *(("content_pair", pair, "matched_vs_shifted_auc") for pair in ( + "text_audio", "text_vision", "audio_vision" + )), + ) + for contrast_index, (left_method, right_method) in enumerate(contrasts): + for metric_index, (family, pair, metric) in enumerate(metrics): + differences = [] + for sample_id in sample_ids: + left_row = ablation_by_key[(left_method, sample_id)] + right_row = ablation_by_key[(right_method, sample_id)] + if left_row["video_id"] != right_row["video_id"]: + raise ValueError(f"paired video_id mismatch for {sample_id}") + if family == "overall": + left_value = float(left_row[metric]) + right_value = float(right_row[metric]) + else: + left_value = float(np.mean(content_by_key[(left_method, sample_id, pair)])) + right_value = float(np.mean(content_by_key[(right_method, sample_id, pair)])) + differences.append({ + "video_id": left_row["video_id"], + "difference": left_value - right_value, + }) + mean, low, high, video_count = _cluster_bootstrap( + differences, + "difference", + seed=seed + 307 + contrast_index * 101 + metric_index, + repetitions=2000, + ) + paired_rows.append({ + "left_method": left_method, + "right_method": right_method, + "metric_family": family, + "pair": pair, + "metric": metric, + "clip_count": len(differences), + "video_id_count": video_count, + "left_minus_right_video_macro_mean": mean, + "ci95_low": low, + "ci95_high": high, + }) + _write_csv(output_dir / "paired_contrasts.csv", paired_rows) + + bundle = output_dir / "report_bundle" + bundle.mkdir(parents=True, exist_ok=True) + names = ( + "run_manifest.json", "tsfa_config.json", "ablation_summary.csv", + "paired_contrasts.csv", "content_metrics_summary.csv", + "temporal_metrics_summary.csv", "candidate_window_stats.csv", + "content_shuffle_summary.csv", "shifted_reconstruction_summary.csv", + "temporal_semantic_attention.png", "typical_sample_tsfa.png", + "temporal_content_tradeoff.png", "content_shuffle_control.png", + "shifted_similarity_curve.png", "shifted_reconstruction_gain.png", + ) + for name in names: + shutil.copy2(output_dir / name, bundle / name) + (bundle / "README.md").write_text( + "# TSFA five-fold result bundle\n\n" + "Seven frozen-alignment comparisons on 100 held-out clips from 37 video IDs. " + "All Python runs use the project uv environment. Read `run_manifest.json` " + "for the complete protocol and limitations. `paired_contrasts.csv` reports " + "left minus right with video-ID-cluster bootstrap confidence intervals. " + "The full `outputs/tsfa/` directory retains per-clip CSVs and probe checkpoints.\n\n" + "The `alignment_only_*` summaries pool identical train-fold-standardized " + "raw source features through each method's alignment matrix. They isolate " + "source selection from native model value/output projections. " + "`tsfa_temporal_diagnostics_summary.csv` reports MVR, span, entropy, and " + "source coverage.\n", + encoding="utf-8", + ) + + +def _time_edges(times: np.ndarray) -> np.ndarray: + values = np.asarray(times, dtype=np.float64) + if len(values) == 1: + return np.array([values[0] - 0.005, values[0] + 0.005]) + centers = (values[:-1] + values[1:]) / 2 + return np.concatenate(([values[0] - (centers[0] - values[0])], centers, [values[-1] + (values[-1] - centers[-1])])) + + +def _plot_temporal_semantic( + example: Mapping[str, Any], path: Path +) -> None: + fig, axes = plt.subplots(2, 2, figsize=(13, 8), constrained_layout=True) + matrices = ( + ("M4 temporal prior: Audio", "audio", example["temporal_weights"]["audio"]), + ("M4 temporal prior: Vision", "vision", example["temporal_weights"]["vision"]), + ("TSFA semantic: Text→Audio", "audio", example["tsfa_weights"]["audio"]), + ("TSFA semantic: Text→Vision", "vision", example["tsfa_weights"]["vision"]), + ) + image = None + slot_edges = np.arange(GRID_SIZE + 1, dtype=np.float64) - 0.5 + for axis, (title, modality, matrix) in zip(axes.flat, matrices, strict=True): + mask = np.asarray(example["valid"][modality], dtype=bool) + times = np.asarray(example["times"][modality], dtype=np.float64)[mask] + image = axis.pcolormesh( + _time_edges(times), slot_edges, np.asarray(matrix)[:, mask], shading="flat", cmap="magma" + ) + axis.set_title(title) + axis.set_xlabel(f"{modality.title()} normalized source time") + axis.set_ylabel("Shared slot i") + assert image is not None + fig.colorbar(image, ax=axes, fraction=0.03, pad=0.02, label="Attention probability") + fig.suptitle(f"Temporal prior and content-only semantic attention — {example['sample_id']}") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_typical_trajectory(example: Mapping[str, Any], path: Path) -> None: + fig, axes = plt.subplots(1, 2, figsize=(12, 4.8), sharex=True, sharey=True, constrained_layout=True) + x = (np.arange(GRID_SIZE) + 0.5) / GRID_SIZE + for axis, modality in zip(axes, ("audio", "vision"), strict=True): + prior = example["temporal_weights"][modality] @ example["times"][modality] + semantic = example["tsfa_weights"][modality] @ example["times"][modality] + axis.plot(x, prior, label="M4 coarse center", color="#2878b5", linewidth=1.4) + axis.plot(x, semantic, label="TSFA content-selected time", color="#e1812c", linewidth=1.1) + axis.plot([0, 1], [0, 1], color="black", linestyle="--", linewidth=0.8) + axis.set_title(modality.title()) + axis.set_xlabel("Shared slot time") + axis.grid(alpha=0.2) + axes[0].set_ylabel("Expected normalized source time") + axes[0].legend(frameon=False) + fig.suptitle(f"Temporal prior vs semantic selection — {example['sample_id']}") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_tradeoff(rows: Sequence[Mapping[str, Any]], path: Path) -> None: + fig, axis = plt.subplots(figsize=(8, 6), constrained_layout=True) + colors = { + "M3_noSourceTime": "#777777", + "M3_sourceTime": "#a8a8a8", + "M4_sourceTime": "#2878b5", + "TSFA-main": "#d62728", + "TSFA-multiply": "#ff7f0e", + "TSFA-random": "#9467bd", + "TSFA-global": "#8c564b", + } + for row in rows: + axis.scatter( + row["temporal_quality_1_minus_mae_video_macro_mean"], + row["content_auc_mean_video_macro_mean"], + s=70, + color=colors.get(str(row["method"]), "black"), + ) + axis.annotate(str(row["method"]), + (row["temporal_quality_1_minus_mae_video_macro_mean"], row["content_auc_mean_video_macro_mean"]), + xytext=(5, 5), textcoords="offset points", fontsize=8) + axis.axhline(0.5, color="black", linestyle="--", linewidth=0.8) + axis.set_xlabel("Temporal quality: 1 − mean pairwise normalized-time MAE") + axis.set_ylabel("Mean content-only matched-vs-shifted AUC") + axis.set_title("Temporal quality vs content correspondence (descriptive axes, no composite score)") + axis.grid(alpha=0.2) + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_shuffle( + normal_rows: Sequence[Mapping[str, Any]], shuffle_rows: Sequence[Mapping[str, Any]], path: Path +) -> None: + methods = SHUFFLE_METHODS + pairs = [f"{left}_{right}" for left, right in PAIRINGS] + fig, axes = plt.subplots(1, 3, figsize=(13, 4.5), sharey=True, constrained_layout=True) + colors = {"M4_sourceTime": "#2878b5", "TSFA-main": "#d62728"} + for axis, pair in zip(axes, pairs, strict=True): + x = np.arange(len(methods)) + width = 0.32 + for index, method in enumerate(methods): + normal = [row for row in normal_rows if row["method"] == method and row["pair"] == pair] + shuffled = [row for row in shuffle_rows if row["method"] == method and row["pair"] == pair] + mean_normal = _cluster_bootstrap(normal, "matched_vs_shifted_auc", seed=127 + index)[0] + mean_shuffle = _cluster_bootstrap(shuffled, "matched_vs_shifted_auc", seed=227 + index)[0] + axis.bar(index - width / 2, mean_normal, width, color=colors[method], label=f"{method}: aligned") + axis.bar(index + width / 2, mean_shuffle, width, color=colors[method], alpha=0.35, hatch="//", + label=f"{method}: shuffled") + axis.axhline(0.5, color="black", linestyle="--", linewidth=0.8) + axis.set_xticks(x, ["M4", "TSFA"]) + axis.set_title(pair.replace("_", "–")) + axis.set_ylim(0.35, 0.8) + axis.grid(axis="y", alpha=0.2) + axes[0].set_ylabel("Matched-vs-shifted AUC") + handles, labels = axes[0].get_legend_handles_labels() + fig.legend(handles, labels, loc="outside lower center", ncol=4, frameon=False) + fig.suptitle("Content shuffle control") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_shift_curve(rows: Sequence[Mapping[str, Any]], path: Path) -> None: + selected_methods = ("M4_sourceTime", "TSFA-main") + color_map = {"M4_sourceTime": "#2878b5", "TSFA-main": "#d62728"} + pairs = [f"{left}_{right}" for left, right in PAIRINGS] + fig, axes = plt.subplots(1, 3, figsize=(14, 4.5), sharey=True, constrained_layout=True) + for axis, pair in zip(axes, pairs, strict=True): + for method in selected_methods: + xs, means, lows, highs = [], [], [], [] + for delta in range(-10, 11): + values = [row for row in rows if row["method"] == method and row["pair"] == pair and int(row["delta"]) == delta] + if not values: + continue + mean, low, high, _ = _cluster_bootstrap( + values, "similarity", seed=811 + delta + sum(ord(char) for char in method + pair), repetitions=1000 + ) + xs.append(delta) + means.append(mean) + lows.append(low) + highs.append(high) + axis.plot(xs, means, color=color_map[method], label=method, linewidth=1.4) + axis.fill_between(xs, lows, highs, color=color_map[method], alpha=0.12) + axis.axvline(0, color="black", linestyle="--", linewidth=0.8) + axis.set_title(pair.replace("_", "–")) + axis.set_xlabel("Slot shift Δ") + axis.grid(alpha=0.2) + axes[0].set_ylabel("Content-only cosine similarity") + axes[0].legend(frameon=False) + fig.suptitle("Content correspondence under temporal shift") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def _plot_reconstruction(rows: Sequence[Mapping[str, Any]], path: Path) -> None: + colors = {"M4_sourceTime": "#2878b5", "TSFA-main": "#d62728"} + fig, axes = plt.subplots(1, 3, figsize=(14, 4.5), sharey=True, constrained_layout=True) + for axis, target in zip(axes, MODALITIES, strict=True): + for method in RECONSTRUCTION_METHODS: + xs, means, lows, highs = [], [], [], [] + for distance in SHIFTS: + values = [ + row for row in rows + if row["method"] == method and row["target_modality"] == target and int(row["abs_delta"]) == distance + ] + if not values: + continue + mean, low, high, _ = _cluster_bootstrap( + values, + "gain_shift_minus_aligned", + seed=1009 + distance + sum(ord(char) for char in method + target), + repetitions=1000, + ) + xs.append(distance) + means.append(mean) + lows.append(low) + highs.append(high) + axis.plot(xs, means, marker="o", color=colors[method], label=method) + axis.fill_between(xs, lows, highs, color=colors[method], alpha=0.14) + axis.axhline(0, color="black", linestyle="--", linewidth=0.8) + axis.set_title(f"Reconstruct {target}") + axis.set_xlabel("Absolute shift |Δ| (slots)") + axis.grid(alpha=0.2) + axes[0].set_ylabel("MAE(shifted) − MAE(aligned)") + axes[0].legend(frameon=False) + fig.suptitle("Aligned-vs-shifted reconstruction gain") + fig.savefig(path, dpi=180, bbox_inches="tight") + plt.close(fig) + + +def run(args: argparse.Namespace) -> dict[str, Any]: + started = time.time() + if args.device == "auto": + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + else: + device = torch.device(args.device) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError("CUDA was requested but is unavailable") + samples = load_feature_samples(args.feature_dir, args.manifest) + samples_by_id = {sample.sample_id: sample for sample in samples} + splits = json.loads(args.splits.read_text(encoding="utf-8")) + if len(splits) != 5: + raise ValueError(f"TSFA requires the existing five grouped folds, found {len(splits)}") + heldout_ids = [sample_id for split in splits for sample_id in split["validation_sample_ids"]] + if len(heldout_ids) != len(set(heldout_ids)) or set(heldout_ids) != set(samples_by_id): + raise ValueError("five-fold validation partitions must cover every sample exactly once") + output_dir = args.output_dir + output_dir.mkdir(parents=True, exist_ok=True) + + content_rows: list[dict[str, Any]] = [] + curve_rows: list[dict[str, Any]] = [] + temporal_rows: list[dict[str, Any]] = [] + candidate_rows: list[dict[str, Any]] = [] + shuffle_rows: list[dict[str, Any]] = [] + reconstruction_rows: list[dict[str, Any]] = [] + history_rows: list[dict[str, Any]] = [] + checkpoint_store: dict[str, Any] = {} + fold_manifest = [] + example_payload: dict[str, Any] | None = None + + for split in splits: + fold = int(split["fold"]) + train_samples = [samples_by_id[sample_id] for sample_id in split["train_sample_ids"]] + validation_samples = [samples_by_id[sample_id] for sample_id in split["validation_sample_ids"]] + train_groups = {sample.group_id for sample in train_samples} + validation_groups = {sample.group_id for sample in validation_samples} + if train_groups & validation_groups: + raise ValueError(f"video_id leakage in fold {fold}: {sorted(train_groups & validation_groups)}") + feature_stats = fit_feature_stats(train_samples) + baseline_content, baseline_weights, temporal_by_id = _collect_fold_features( + fold=fold, + train_samples=train_samples, + validation_samples=validation_samples, + feature_stats=feature_stats, + checkpoint_root=args.checkpoint_root, + device=device, + batch_size=args.batch_size, + ) + all_ids = [sample.sample_id for sample in [*train_samples, *validation_samples]] + all_ids_by_id = {sample.sample_id: sample for sample in [*train_samples, *validation_samples]} + branch, semantic_history = _fit_semantic_branch( + fold=fold, + train_samples=train_samples, + temporal_by_id=temporal_by_id, + device=device, + seed=args.seed, + epochs=args.semantic_epochs, + batch_size=args.batch_size, + learning_rate=args.semantic_learning_rate, + temperature=args.local_temperature, + delta=args.delta, + ) + history_rows.extend(semantic_history) + checkpoint_store[f"fold_{fold:02d}/TSFA-semantic"] = { + "seed": args.seed + fold * 101, + "state_dict": {key: value.detach().cpu() for key, value in branch.state_dict().items()}, + } + + fold_content: dict[str, dict[str, dict[str, np.ndarray]]] = { + method: baseline_content[method] for method in BASELINE_VARIANTS + } + fold_weights: dict[str, dict[str, dict[str, np.ndarray]]] = { + method: baseline_weights[method] for method in BASELINE_VARIANTS + } + fold_candidate_rows: dict[str, list[dict[str, Any]]] = {} + for method in TSFA_VARIANTS: + generated_content, generated_weights, generated_candidates = _generate_tsfa_outputs( + method=method, + fold=fold, + sample_ids=all_ids, + samples_by_id=all_ids_by_id, + temporal_by_id=temporal_by_id, + branch=branch, + device=device, + delta=args.delta, + seed=args.seed, + draw=0, + batch_size=args.batch_size, + ) + fold_content[method] = generated_content + fold_weights[method] = generated_weights + fold_candidate_rows[method] = generated_candidates + for method in TSFA_VARIANTS: + candidate_rows.extend( + row for row in fold_candidate_rows[method] if row["sample_id"] in {s.sample_id for s in validation_samples} + ) + + for method in ALL_METHODS: + method_metrics, method_curves, projected = _fit_method_probe( + method=method, + fold=fold, + train_samples=train_samples, + validation_samples=validation_samples, + content_by_id=fold_content[method], + device=device, + args=args, + history_rows=history_rows, + checkpoint_store=checkpoint_store, + ) + content_rows.extend(method_metrics) + curve_rows.extend(method_curves) + for sample in validation_samples: + temporal_rows.extend( + _record_temporal_metrics( + method=method, + fold=fold, + sample=sample, + weights=fold_weights[method][sample.sample_id], + ) + ) + if method in SHUFFLE_METHODS: + shuffle_rows.extend( + _shuffle_control_rows( + method=method, + fold=fold, + validation_samples=validation_samples, + projected=projected, + repeats=args.shuffle_repeats, + seed=args.seed, + device=device, + ) + ) + if method in RECONSTRUCTION_METHODS: + reconstruction_rows.extend( + _fit_and_score_decoder( + method=method, + fold=fold, + train_samples=train_samples, + validation_samples=validation_samples, + content_by_id=fold_content[method], + device=device, + args=args, + history_rows=history_rows, + checkpoint_store=checkpoint_store, + ) + ) + if method == "TSFA-random": + for draw in range(1, args.random_window_repeats): + random_content, random_weights, random_candidate = _generate_tsfa_outputs( + method=method, + fold=fold, + sample_ids=[sample.sample_id for sample in validation_samples], + samples_by_id=samples_by_id, + temporal_by_id=temporal_by_id, + branch=branch, + device=device, + delta=args.delta, + seed=args.seed, + draw=draw, + batch_size=args.batch_size, + ) + candidate_rows.extend(random_candidate) + random_metrics, random_curves, _ = _evaluate_fixed_projector( + method=method, + fold=fold, + validation_samples=validation_samples, + content_by_id=random_content, + projector_state=checkpoint_store[f"fold_{fold:02d}/{method}/correspondence_probe"]["state_dict"], + device=device, + ) + content_rows.extend({**row, "draw": draw} for row in random_metrics) + curve_rows.extend({**row, "draw": draw} for row in random_curves) + for sample in validation_samples: + temporal_rows.extend( + _record_temporal_metrics( + method=method, + fold=fold, + sample=sample, + weights=random_weights[sample.sample_id], + draw=draw, + ) + ) + if example_payload is None: + example_id = args.example_id + if example_id not in samples_by_id or example_id not in fold_weights["M4_sourceTime"]: + example_id = validation_samples[0].sample_id + if example_id in fold_weights["M4_sourceTime"]: + example_payload = { + "sample_id": example_id, + "temporal_weights": fold_weights["M4_sourceTime"][example_id], + "tsfa_weights": fold_weights["TSFA-main"][example_id], + "times": temporal_by_id[example_id]["times"], + "valid": temporal_by_id[example_id]["valid"], + "fold": fold, + } + del projected + fold_manifest.append( + { + "fold": fold, + "train_count": len(train_samples), + "heldout_count": len(validation_samples), + "train_video_id_count": len(train_groups), + "heldout_video_id_count": len(validation_groups), + "video_id_overlap": sorted(train_groups & validation_groups), + "validation_sample_ids": [sample.sample_id for sample in validation_samples], + } + ) + print( + f"[TSFA fold {fold}] frozen M3/M4 baselines loaded; semantic epochs={args.semantic_epochs}; " + f"train={len(train_samples)} heldout={len(validation_samples)}; " + f"content rows={len(content_rows)} temporal rows={len(temporal_rows)}", + flush=True, + ) + del branch, baseline_content, baseline_weights, temporal_by_id, fold_content, fold_weights + if device.type == "cuda": + torch.cuda.empty_cache() + + if example_payload is None: + raise RuntimeError("no held-out example was collected") + example_id = example_payload["sample_id"] + # The stored example maps need to be from the same fold as the sample. + example_fold = int(example_payload["fold"]) + example_split = next(split for split in splits if int(split["fold"]) == example_fold) + example_train = [samples_by_id[sample_id] for sample_id in example_split["train_sample_ids"]] + example_val = [samples_by_id[sample_id] for sample_id in example_split["validation_sample_ids"]] + example_stats = fit_feature_stats(example_train) + _, _, example_temporal = _collect_fold_features( + fold=example_fold, + train_samples=example_train, + validation_samples=example_val, + feature_stats=example_stats, + checkpoint_root=args.checkpoint_root, + device=device, + batch_size=args.batch_size, + ) + example_split_samples = {sample.sample_id: sample for sample in [*example_train, *example_val]} + example_fold_content, example_fold_weights, _ = _generate_tsfa_outputs( + method="TSFA-main", + fold=example_fold, + sample_ids=[example_id], + samples_by_id=samples_by_id, + temporal_by_id=example_temporal, + branch=_load_semantic_checkpoint(checkpoint_store, example_fold, device), + device=device, + delta=args.delta, + seed=args.seed, + draw=0, + batch_size=1, + ) + example_payload["temporal_weights"] = example_temporal[example_id]["weights"] + example_payload["tsfa_weights"] = example_fold_weights[example_id] + example_payload["times"] = example_temporal[example_id]["times"] + example_payload["valid"] = example_temporal[example_id]["valid"] + np.savez_compressed( + output_dir / "typical_sample_tsfa_maps.npz", + sample_id=np.asarray(example_id), + **{f"A_tau_{name}": example_payload["temporal_weights"][name] for name in MODALITIES}, + **{f"A_final_{name}": example_payload["tsfa_weights"][name] for name in MODALITIES}, + **{f"tau_{name}": example_payload["times"][name] for name in MODALITIES}, + **{f"valid_{name}": example_payload["valid"][name] for name in MODALITIES}, + ) + _plot_temporal_semantic(example_payload, output_dir / "temporal_semantic_attention.png") + _plot_typical_trajectory(example_payload, output_dir / "typical_sample_tsfa.png") + + content_summary, curve_summary = _content_summary(content_rows, curve_rows, args.seed + 301) + temporal_summary = _temporal_summary(temporal_rows, args.seed + 302) + shuffle_summary = _bootstrap_summary( + shuffle_rows, + ("method", "control", "pair"), + ("matched_vs_shifted_auc", "same_minus_shifted_margin", "exact_r1_left_to_right", "within_pm1_r1_left_to_right"), + seed=args.seed + 303, + ) + reconstruction_summary = _bootstrap_summary( + reconstruction_rows, + ("method", "target_modality", "shifted_modality", "abs_delta"), + ("aligned_mae_same_support", "shifted_mae", "gain_shift_minus_aligned"), + seed=args.seed + 304, + ) + candidate_summary = _bootstrap_summary( + candidate_rows, + ("method", "modality"), + ("candidate_count_mean", "candidate_fraction_valid_mean", "temporal_prior_mass_mean", "candidate_mean_center_error"), + seed=args.seed + 305, + ) + ablation_summary, ablation_by_clip = _ablation_summary(content_rows, temporal_rows, args.seed + 306) + + _write_csv(output_dir / "content_metrics_by_clip.csv", content_rows) + _write_csv(output_dir / "content_metrics_summary.csv", content_summary) + _write_csv(output_dir / "shifted_similarity_by_clip.csv", curve_rows) + _write_csv(output_dir / "shifted_similarity_summary.csv", curve_summary) + _write_csv(output_dir / "temporal_metrics_by_clip.csv", temporal_rows) + _write_csv(output_dir / "temporal_metrics_summary.csv", temporal_summary) + _write_csv(output_dir / "content_shuffle_by_clip.csv", shuffle_rows) + _write_csv(output_dir / "content_shuffle_summary.csv", shuffle_summary) + _write_csv(output_dir / "shifted_reconstruction_by_clip.csv", reconstruction_rows) + _write_csv(output_dir / "shifted_reconstruction_summary.csv", reconstruction_summary) + _write_csv(output_dir / "candidate_window_by_clip.csv", candidate_rows) + _write_csv(output_dir / "candidate_window_stats.csv", candidate_summary) + _write_csv(output_dir / "ablation_by_clip.csv", ablation_by_clip) + _write_csv(output_dir / "ablation_summary.csv", ablation_summary) + _write_csv(output_dir / "probe_training_history.csv", history_rows) + torch.save(checkpoint_store, output_dir / "probe_checkpoints.pt") + + _plot_tradeoff(ablation_summary, output_dir / "temporal_content_tradeoff.png") + _plot_shuffle(content_rows, shuffle_rows, output_dir / "content_shuffle_control.png") + _plot_shift_curve(curve_rows, output_dir / "shifted_similarity_curve.png") + _plot_reconstruction(reconstruction_rows, output_dir / "shifted_reconstruction_gain.png") + + manifest = { + "created_utc": datetime.now(timezone.utc).isoformat(), + "experiment": "TSFA: Temporal-Semantic Factorized Alignment", + "sample_count": len(samples), + "fold_count": len(splits), + "heldout_partition_count": len(heldout_ids), + "unique_video_id_count": len({sample.group_id for sample in samples}), + "folds": fold_manifest, + "alignment_models_retrained": False, + "temporal_branch": "frozen M4_sourceTime D5 checkpoint per grouped fold", + "semantic_branch_trained": True, + "emotion_labels_used_for_alignment": False, + "feature_extractors_changed": False, + "feature_encoder_note": "Existing BERT text and DeiT image features are reused unchanged.", + "example_sample_id": example_id, + "parameters": { + "seed": args.seed, + "grid_size": GRID_SIZE, + "hidden_size": HIDDEN_SIZE, + "heads_in_frozen_alignment": HEADS, + "delta_normalized_time": args.delta, + "hard_negative_offsets_slots": list(HARD_NEGATIVE_OFFSETS), + "semantic_epochs": args.semantic_epochs, + "semantic_learning_rate": args.semantic_learning_rate, + "local_contrastive_temperature": args.local_temperature, + "content_probe_epochs": args.probe_epochs, + "content_probe_temperature": args.probe_temperature, + "reconstruction_probe_epochs": args.decoder_epochs, + "shuffle_repeats": args.shuffle_repeats, + "random_window_repeats": args.random_window_repeats, + "window_ablation_status": "delta sweep and 80-percent attention-mass window deferred until the seven-method MVP is reviewed", + }, + "methods": list(ALL_METHODS), + "protocol": { + "semantic_query_key_inputs": "Frozen M4 attention-pooled text value output is the semantic query input; M4 pre-attention projected Audio/Vision content is the semantic key/value input. No explicit source-time code, absolute PE, slot ID, or latent positional vector is passed to semantic Q/K. Temporal selection can still encode time indirectly.", + "baseline_content_values": "M4 and M3 Audio/Vision use each checkpoint's actual MHA attention output. M3 Text uses attention-pooled pre-attention text features to remove its source-time query residual.", + "temporal_role": "Frozen M4 attention supplies candidate masks; TSFA-multiply additionally multiplies semantic probabilities by M4 temporal attention", + "local_contrastive": "same-slot positives with within-clip slot-offset negatives at +/-2, +/-3, +/-5; symmetric Text-Audio and Text-Vision loss", + "random_candidate": "same delta-width windows with independently sampled centers at inference; 20 held-out random draws, one train draw for the train-only probe", + "global_candidate": "all valid source positions available to semantic attention", + "content_probe": "same train-only symmetric within-clip InfoNCE probe applied to each method; held-out negatives are positions more than two slots away", + "content_shuffle": "independently permute each modality's 50 projected content rows within each held-out clip; M4 and TSFA-main", + "reconstruction": "fold-train decoder predicts one aligned content representation from the other two; shift one partner by signed offsets +/-1,2,5,10 on identical target support", + "confidence_intervals": "95-percent video_id-cluster bootstrap; 2,000 repetitions for CSV summaries", + }, + "input_paths": { + "feature_dir": str(args.feature_dir.resolve()), + "feature_manifest": str(args.manifest.resolve()), + "grouped_splits": str(args.splits.resolve()), + "checkpoint_root": str(args.checkpoint_root.resolve()), + "m3_m4_checkpoint_variants": list(BASELINE_VARIANTS), + }, + "device": str(device), + "gpu_name": torch.cuda.get_device_name(device) if device.type == "cuda" else None, + "python": platform.python_version(), + "torch": torch.__version__, + "elapsed_seconds": time.time() - started, + "interpretation_limits": [ + "Same-slot labels are a temporal training convention, not independent semantic ground truth.", + "Frozen M4 temporal attention was trained with a timestamp-derived Gaussian prior; time may enter content indirectly through candidate selection.", + "AUC, retrieval, and shifted similarity measure within-clip content matchability, not human event alignment.", + "Reconstruction predicts M4/TSFA pooled content values, not raw waveform or image pixels.", + "Five folds use one alignment-model seed; bootstrap intervals quantify video-group sampling uncertainty, not seed uncertainty.", + "Human event IoU/center error remains pending event annotation.", + ], + } + (output_dir / "tsfa_config.json").write_text( + json.dumps(manifest["parameters"] | manifest["protocol"] | {"methods": list(ALL_METHODS)}, + ensure_ascii=False, indent=2, allow_nan=False), + encoding="utf-8", + ) + (output_dir / "run_manifest.json").write_text( + json.dumps(manifest, ensure_ascii=False, indent=2, allow_nan=False), encoding="utf-8" + ) + _finalize_existing_outputs(output_dir, args.seed) + print( + f"[TSFA complete] samples={len(samples)} folds={len(splits)} " + f"elapsed={manifest['elapsed_seconds']:.1f}s output={output_dir}", + flush=True, + ) + return manifest + + +def _evaluate_fixed_projector( + *, + method: str, + fold: int, + validation_samples: Sequence[FeatureSample], + content_by_id: Mapping[str, Mapping[str, np.ndarray]], + projector_state: Mapping[str, Tensor], + device: torch.device, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]], dict[str, Tensor]]: + ids = [sample.sample_id for sample in validation_samples] + raw = _stack_ids(ids, content_by_id, device) + dimensions = {name: int(raw[name].shape[-1]) for name in MODALITIES} + projector = CorrespondenceProjection(dimensions).to(device) + projector.load_state_dict(projector_state, strict=True) + projector.eval() + with torch.no_grad(): + projected = projector(raw) + metrics = [] + curves = [] + for index, sample in enumerate(validation_samples): + one = {name: projected[name][index] for name in MODALITIES} + metrics.extend( + _sample_metrics(method=method, fold=fold, sample=sample, projected=one, curve_rows=curves) + ) + del projector + if device.type == "cuda": + torch.cuda.empty_cache() + return metrics, curves, projected + + +def _load_semantic_checkpoint( + store: Mapping[str, Any], fold: int, device: torch.device +) -> TSFASemanticBranch: + key = f"fold_{fold:02d}/TSFA-semantic" + branch = TSFASemanticBranch(HIDDEN_SIZE).to(device) + branch.load_state_dict(store[key]["state_dict"], strict=True) + branch.eval() + return branch + + +def build_parser() -> argparse.ArgumentParser: + project = Path(__file__).resolve().parents[1] + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--device", choices=("auto", "cpu", "cuda"), default="auto") + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--delta", type=float, default=0.10) + parser.add_argument("--semantic-epochs", type=int, default=40) + parser.add_argument("--semantic-learning-rate", type=float, default=1e-3) + parser.add_argument("--local-temperature", type=float, default=0.1) + parser.add_argument("--batch-size", type=int, default=8) + parser.add_argument("--probe-epochs", type=int, default=40) + parser.add_argument("--probe-learning-rate", type=float, default=1e-3) + parser.add_argument("--probe-temperature", type=float, default=0.1) + parser.add_argument("--decoder-epochs", type=int, default=40) + parser.add_argument("--decoder-learning-rate", type=float, default=1e-3) + parser.add_argument("--shuffle-repeats", type=int, default=20) + parser.add_argument("--random-window-repeats", type=int, default=20) + parser.add_argument("--example-id", type=str, default="-3g5yACwYnA/13") + parser.add_argument("--feature-dir", type=Path, default=project / "outputs/q1_features/features") + parser.add_argument("--manifest", type=Path, default=project / "outputs/audit/manifest.csv") + parser.add_argument("--splits", type=Path, default=project / "outputs/method_comparison/splits.json") + parser.add_argument("--checkpoint-root", type=Path, default=project / "outputs/alignment_debug/heldout") + parser.add_argument("--output-dir", type=Path, default=project / "outputs/tsfa") + parser.add_argument("--finalize-existing", action="store_true", help="summarize an existing completed run without retraining") + return parser + + +def main() -> None: + args = build_parser().parse_args() + if args.finalize_existing: + _finalize_existing_outputs(args.output_dir, args.seed) + print(f"[TSFA finalize] output={args.output_dir}", flush=True) + return + if not 0 < args.delta <= 1: + raise ValueError("--delta must be in (0,1]") + if args.random_window_repeats < 1: + raise ValueError("--random-window-repeats must be at least 1") + run(args) + + +if __name__ == "__main__": + main() diff --git a/deep_learning/Q1/q1/types.py b/deep_learning/Q1/q1/types.py new file mode 100644 index 0000000..0dd501b --- /dev/null +++ b/deep_learning/Q1/q1/types.py @@ -0,0 +1,86 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import Mapping + +import torch +from torch import Tensor + +MODALITIES = ("text", "audio", "vision") + + +@dataclass +class SequenceBatch: + """A padded batch of timed feature sequences. + + ``features`` has shape ``[batch, length, dimension]``; ``times`` and + ``valid`` have shape ``[batch, length]``. Times are seconds from the start + of each clip. Padding positions must be false in ``valid``. + """ + + features: Tensor + times: Tensor + valid: Tensor + + def __post_init__(self) -> None: + if self.features.ndim != 3: + raise ValueError("features must have shape [batch, length, dimension]") + expected = self.features.shape[:2] + if tuple(self.times.shape) != tuple(expected): + raise ValueError("times must match the batch and sequence dimensions") + if tuple(self.valid.shape) != tuple(expected): + raise ValueError("valid must match the batch and sequence dimensions") + if self.valid.dtype != torch.bool: + raise TypeError("valid must be a boolean tensor") + if self.features.device != self.times.device or self.features.device != self.valid.device: + raise ValueError("features, times, and valid must be on the same device") + if not bool(self.valid.any(dim=1).all()): + raise ValueError("every sample must contain at least one valid feature") + if not bool(torch.isfinite(self.features[self.valid]).all()): + raise ValueError("valid features must be finite") + if not bool(torch.isfinite(self.times[self.valid]).all()): + raise ValueError("valid timestamps must be finite") + + +@dataclass +class AlignmentOutput: + """Unified alignment result for Text, Audio, and Vision. + + Each ``weights[m]`` is a row-stochastic matrix with shape ``[B, K, L_m]``. + ``aligned[m]`` is the resulting common-grid representation ``[B, K, D_m]``. + """ + + weights: Mapping[str, Tensor] + aligned: Mapping[str, Tensor] + fallback_rows: Mapping[str, int] | None = None + + def validate(self, valid: Mapping[str, Tensor] | None = None, atol: float = 1e-4) -> None: + if set(self.weights) != set(MODALITIES) or set(self.aligned) != set(MODALITIES): + raise ValueError(f"weights and aligned must contain exactly {MODALITIES}") + + batch_size: int | None = None + grid_size: int | None = None + for modality in MODALITIES: + matrix = self.weights[modality] + values = self.aligned[modality] + if matrix.ndim != 3 or values.ndim != 3: + raise ValueError(f"{modality} alignment and values must be rank 3") + if matrix.shape[:2] != values.shape[:2]: + raise ValueError(f"{modality} weights and aligned values disagree on [B, K]") + if batch_size is None: + batch_size, grid_size = matrix.shape[:2] + elif matrix.shape[0] != batch_size or matrix.shape[1] != grid_size: + raise ValueError("all modalities must use the same batch and grid sizes") + if not bool(torch.isfinite(matrix).all()) or bool((matrix < -atol).any()): + raise ValueError(f"{modality} weights must be finite and non-negative") + if not torch.allclose( + matrix.sum(dim=-1), + torch.ones_like(matrix.sum(dim=-1)), + atol=atol, + rtol=0, + ): + raise ValueError(f"{modality} alignment rows must sum to one") + if valid is not None: + allowed = valid[modality][:, None, :] + if bool((matrix.masked_select(~allowed.expand_as(matrix)).abs() > atol).any()): + raise ValueError(f"{modality} alignment assigns weight to padding") diff --git a/deep_learning/Q1/uv.lock b/deep_learning/Q1/uv.lock new file mode 100644 index 0000000..cc2ee09 --- /dev/null +++ b/deep_learning/Q1/uv.lock @@ -0,0 +1,1765 @@ +version = 1 +revision = 3 +requires-python = ">=3.14" +resolution-markers = [ + "sys_platform == 'win32'", + "sys_platform == 'emscripten'", + "sys_platform != 'emscripten' and sys_platform != 'win32'", +] + +[[package]] +name = "absl-py" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/4f/d79676ab82f2e42fc3611618139f13a9c4c31d0cff4b486982047679a802/absl_py-2.5.0.tar.gz", hash = "sha256:0c996f25c0490700fadabe6351630f6111534fa0ae252cc6d2014ea3b141135f", size = 118119, upload-time = "2026-07-03T10:57:48.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/0a/a10b45aab35b175aded078a462dc8d0c698f5b13946e7cb0869097b78bb6/absl_py-2.5.0-py3-none-any.whl", hash = "sha256:0f17b89f2a4eaaedc4f28c622998aa690564b3012a396a4ffad0821007fe03ba", size = 137410, upload-time = "2026-07-03T10:57:46.735Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758, upload-time = "2026-07-28T13:50:58.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302, upload-time = "2026-07-28T13:50:57.239Z" }, +] + +[[package]] +name = "anyio" +version = "4.15.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.15'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/d2/f4d173e22df740bc37b1db102b386ba719b66e95b0f0d751f556b387e6d2/anyio-4.15.1.tar.gz", hash = "sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94", size = 276966, upload-time = "2026-09-05T10:42:39.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b8/4bd346e22b28902df4d651910f5242c28d84e4a5c2435ca5c3f797ed7e2e/anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101", size = 132079, upload-time = "2026-09-05T10:42:37.923Z" }, +] + +[[package]] +name = "asttokens" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/1e/faf0f247f6f881b98fc4d6d07e14085cb89d13665084e6d6ac1dc2c03d0b/asttokens-3.0.2.tar.gz", hash = "sha256:3ecdbd8f2cc195f53ccada3a613538bb5f9ef6f6869129f13e03c30a677b8fe2", size = 63136, upload-time = "2026-07-12T03:31:49.084Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/2b/04b8a15f3a1c77bc79ddf5c73875327f34b4fa75982df2b76e45e402d364/asttokens-3.0.2-py3-none-any.whl", hash = "sha256:9da13157f5b28becde0bd374fc677dcd3c290614264eff096f167c469cd9f933", size = 28702, upload-time = "2026-07-12T03:31:47.542Z" }, +] + +[[package]] +name = "audeer" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/e4/e8d38f8606079509388e145270d9e212a9ee0f6f767432155bf64bbc2699/audeer-2.6.0.tar.gz", hash = "sha256:abb974c4ebb5096f7032fead5f0b9f335bf780ce4874daacb186dbdaa26a73d3", size = 64129, upload-time = "2026-09-03T14:18:09.175Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/d1/4906ddec292f2c8d5de9a64f1195470a142dd5a0c17cf14df6f0b9b0f47b/audeer-2.6.0-py3-none-any.whl", hash = "sha256:6ea3d11d232ebf8320cfbce355d69f818ed09bfc2b27a28d506f5f98c7186680", size = 33595, upload-time = "2026-09-03T14:18:07.83Z" }, +] + +[[package]] +name = "audformat" +version = "1.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "audeer" }, + { name = "audiofile" }, + { name = "iso3166" }, + { name = "iso639-lang" }, + { name = "oyaml" }, + { name = "pandas" }, + { name = "pyarrow" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/62/da/85114b01d160b2db42b740783754a7e90a9360b0980986150291975db36b/audformat-1.4.2.tar.gz", hash = "sha256:75190ad71821600dd8c12a6bec8fbeefc17feeeb9d7f8530c43e16cf16f4d13a", size = 158300, upload-time = "2026-05-12T13:14:07.621Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/3b/f50d547b7e7aab4c4a215f0b8a3c9cb3710a64d90bcf6e7115188196904e/audformat-1.4.2-py3-none-any.whl", hash = "sha256:3a90c37923406e11be60ec22783b710461799df3be6068f9c12716a52a27021b", size = 74855, upload-time = "2026-05-12T13:14:06.003Z" }, +] + +[[package]] +name = "audinterface" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "audeer" }, + { name = "audformat" }, + { name = "audiofile" }, + { name = "audmath" }, + { name = "audresample" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/07/68b19114db50ea0635fefb343fcf19b3ae5cfe6a7137b80c4b410e3215fa/audinterface-1.4.0.tar.gz", hash = "sha256:ed4e4583cf2a3ed789a01d00f772f9e7b333b8489f2f8002b29737790aa346ac", size = 78197, upload-time = "2026-07-24T08:06:51.189Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/a2/955c30982f5acea82ba1a3390dae86a5efbc114767254eb1d78ac5db6ef0/audinterface-1.4.0-py3-none-any.whl", hash = "sha256:eb8fa27249c1478dc488e89654e7d1c239dbd7a7f3aec216cdaf7fc2eb630783", size = 37505, upload-time = "2026-07-24T08:06:49.919Z" }, +] + +[[package]] +name = "audiofile" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "audeer" }, + { name = "audmath" }, + { name = "numpy" }, + { name = "soundfile" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/11/3a/8c16c340c7b5000ab8f78636eec28f1982b8502f6226709d714cf0f82117/audiofile-1.6.1.tar.gz", hash = "sha256:6d941d216c16e3ead2fe3b80d8b7e349f0f11f2b727ed5acd0123831edd46b41", size = 1215418, upload-time = "2026-05-20T09:13:13.685Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/8e/601e50ace82cd3bbb1f320c788c2324ad30e94906416002f4cc8b45d6f1a/audiofile-1.6.1-py3-none-any.whl", hash = "sha256:8c50e5afa49b50c4f6101cb7c74c8016c7ae691c2de214b22b84f0d5f8b2cb76", size = 14511, upload-time = "2026-05-20T09:13:12.298Z" }, +] + +[[package]] +name = "audmath" +version = "1.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/26/af/d69a2a9a3ce7f6608ad8752b440528f0c5344949177123632669e3748e80/audmath-1.4.4.tar.gz", hash = "sha256:ff5f0b6786b8013a9a3c54ef8d442cf10c455a026a4030b3d014143e0e02622d", size = 23717, upload-time = "2025-10-13T18:06:12.188Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/f3/da2ded0ca8f9c8db0bcf4255463112156ece371449856ebeca46de5fbfef/audmath-1.4.4-py3-none-any.whl", hash = "sha256:0556e5a595cf71660c958ffe2e4c3869316ec8b15eeb86f0ea0243b06f8ab7d5", size = 22396, upload-time = "2025-10-13T18:06:10.832Z" }, +] + +[[package]] +name = "audobject" +version = "0.7.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "audeer" }, + { name = "oyaml" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/c7/0e6defb23ac15a7ae9921f75a06bb6a20b2474bda5c9d5fadf0a54c95629/audobject-0.7.13.tar.gz", hash = "sha256:4debf544834f68b52c7bafec613ba95db54aa87e3245ba3bc68ffbec39be1535", size = 45490, upload-time = "2026-04-15T19:49:46.218Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/fa/0f60d4bf0f6e96eb35f9ffdea4ce1bbd96698251a4ebb3ef67f9560eb122/audobject-0.7.13-py3-none-any.whl", hash = "sha256:c6ed7d658df279f8c29e234e0b8674e8f40c3cfb21d5b90a16ced8e5dac1284b", size = 23773, upload-time = "2026-04-15T19:49:44.854Z" }, +] + +[[package]] +name = "audresample" +version = "1.3.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1a/ca/c9a4c633eaa83359f185ae172f2165d34459f33d45453cd8f2b93b34e439/audresample-1.3.6.tar.gz", hash = "sha256:d5e987f3a54297351c27fd530fed6ce90fd3dfec24ff9ae690f286bc160b7126", size = 1928713, upload-time = "2026-04-15T12:38:35.503Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/58/67bfb1439cfa79938fe1b4a391da9289bafa8bb950b50065851d22b70a4f/audresample-1.3.6-py3-none-macosx_10_4_x86_64.whl", hash = "sha256:18b5140b64279b6e2181c4c32fdf7a304c9a3e9d9dec1f25995173a7006a01e4", size = 123291, upload-time = "2026-04-15T12:38:26.824Z" }, + { url = "https://files.pythonhosted.org/packages/e7/63/90d2c23a34b030bb894c959b7c43b443439c93dc6b19381c391c490c116d/audresample-1.3.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:064d1aaf7c816fb8282d10a90350dd539da20b4f22ce6a2abdaca10472e17e1b", size = 79510, upload-time = "2026-04-15T12:38:28.37Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e7/cd6591981230ad67f590a51bfb150bbc4459b518599ab1c01b896b554515/audresample-1.3.6-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:c26d14c3dffaf7c2939c8bfd8a5b5b913991d8d1d9e4854430cf7826c6e980f2", size = 115628, upload-time = "2026-04-15T12:38:29.508Z" }, + { url = "https://files.pythonhosted.org/packages/22/e1/85a4375e53e46def594efced46893e0a4296e8cb2741733f62fd903803d6/audresample-1.3.6-py3-none-manylinux_2_17_armv7l.whl", hash = "sha256:fcdd1829503a7c83e2c6040983202a818b69f6a1aacafc5300a48eb533dee249", size = 96447, upload-time = "2026-04-15T12:38:31.624Z" }, + { url = "https://files.pythonhosted.org/packages/55/5e/292d33d313c7ce6c692e7675fa701392210017501a03af21055954df9c3a/audresample-1.3.6-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:a300469b49da306f43abfe291de85a540de54d9a0c61d240ab7667cabe408875", size = 133696, upload-time = "2026-04-15T12:38:32.786Z" }, + { url = "https://files.pythonhosted.org/packages/d6/d4/afb8a45bbb27f1c9277a58ed4d4a959f8f88f90a9493cdf78cc43639ebca/audresample-1.3.6-py3-none-win_amd64.whl", hash = "sha256:6e455c3c2e291dfc8e83ccfd3eaf2a69cc8c25c6c404c735591917135081dac3", size = 181702, upload-time = "2026-04-15T12:38:33.934Z" }, +] + +[[package]] +name = "certifi" +version = "2026.7.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" }, +] + +[[package]] +name = "cffi" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/7b/d6bbf82b8b96e7391438898c42f5bd96dd02030fd5b64937d248220003e2/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c", size = 194064, upload-time = "2026-08-03T21:20:17.148Z" }, + { url = "https://files.pythonhosted.org/packages/94/e6/bcc91b283be94735e268487a054004f0aa19947b6348fa367db53230abc8/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb", size = 196720, upload-time = "2026-08-03T21:20:18.268Z" }, + { url = "https://files.pythonhosted.org/packages/d9/99/c4b0c17cacdc9c3b8f280026286a9826d6a208c0f047591a3c3ce99b91fd/cffi-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54", size = 184964, upload-time = "2026-08-03T21:20:19.708Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a9/9db617d05d7367c1ad0ab00b3aa6e6f9281edd689b4ee9ea0e5a84e89c97/cffi-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72", size = 184962, upload-time = "2026-08-03T21:20:20.833Z" }, + { url = "https://files.pythonhosted.org/packages/67/b8/b42132ca113dc567d37684437b46ca1dafc885902b02a110a02d5b511857/cffi-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1", size = 222328, upload-time = "2026-08-03T21:20:22.118Z" }, + { url = "https://files.pythonhosted.org/packages/80/10/c5c0cbf0a657aecf59ef511409734230bf556f05a0d6c9eed7aa5c0a0166/cffi-2.1.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062", size = 209985, upload-time = "2026-08-03T21:20:23.401Z" }, + { url = "https://files.pythonhosted.org/packages/d5/6c/bfa0b87b03b9238148beca990292843c9396ba069b54496596594173de7b/cffi-2.1.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03", size = 208530, upload-time = "2026-08-03T21:20:24.628Z" }, + { url = "https://files.pythonhosted.org/packages/e9/02/4e7d553a7ac4b4238b38b3c1b80d486e9d4436f8d2acbf87a0997fe3f402/cffi-2.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96", size = 221525, upload-time = "2026-08-03T21:20:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/82/1d/a4aaf9babd75acb4d5f223bff71533bee748dd770a382619a798960ee9ba/cffi-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527", size = 225053, upload-time = "2026-08-03T21:20:26.985Z" }, + { url = "https://files.pythonhosted.org/packages/81/10/5dc0e7bdd18e22107054288283380fc97a06ae3f1656a106908d666a3c88/cffi-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13", size = 223213, upload-time = "2026-08-03T21:20:28.277Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e9/d0061c364cde06ee43168a0d076ac1da512cbc380d44767b844ba34fe2b6/cffi-2.1.1-cp314-cp314-win32.whl", hash = "sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c", size = 177682, upload-time = "2026-08-03T21:20:44.288Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1c3e01e3ba14c39f6d10bfbac52753b7e22259e38088e5cfe1d704918690/cffi-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48", size = 187949, upload-time = "2026-08-03T21:20:45.623Z" }, + { url = "https://files.pythonhosted.org/packages/87/5b/da4e39efe18eeb89cf580ea9cfc66b6a7c3eadb808fc0cc1d3a295cb5a5d/cffi-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836", size = 182947, upload-time = "2026-08-03T21:20:46.955Z" }, + { url = "https://files.pythonhosted.org/packages/23/59/40338bf421c5accea1d45158170c87006ef1cd371b05c077e76476949728/cffi-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3", size = 188504, upload-time = "2026-08-03T21:20:29.495Z" }, + { url = "https://files.pythonhosted.org/packages/7d/47/5ecf1023850036e674c77ec4de86182d309ae344e39e7cba984b7df5d647/cffi-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2", size = 188259, upload-time = "2026-08-03T21:20:31.291Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9c/92934c3bea9f785b23eba304538c0b4d37a2a96d2431eb3a1bc87a11aa19/cffi-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94", size = 223864, upload-time = "2026-08-03T21:20:32.571Z" }, + { url = "https://files.pythonhosted.org/packages/4d/45/ba4c93527bc38616a8bd36488acb69a2212d60486794f0c1f318949bbb76/cffi-2.1.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc", size = 211538, upload-time = "2026-08-03T21:20:33.808Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/b6ef565e452acb932fb0cb5443f44a78efbd1233e566f02b5a83855e9115/cffi-2.1.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29", size = 210688, upload-time = "2026-08-03T21:20:34.974Z" }, + { url = "https://files.pythonhosted.org/packages/9a/95/eff5f0cee78d2eabc7eebffec40d3fc1876b5f3c95582e018bb4b99601f2/cffi-2.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676", size = 223803, upload-time = "2026-08-03T21:20:36.564Z" }, + { url = "https://files.pythonhosted.org/packages/fa/01/579d39fb8bef00a335a23d83757b44feb24cd6345a2c451b64cb67b9c362/cffi-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e", size = 226763, upload-time = "2026-08-03T21:20:37.816Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b0/0b44f47c60b01b57b6e2bbd92343f13a85a1d93bc46ccf6e47e244acd99c/cffi-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f", size = 225688, upload-time = "2026-08-03T21:20:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d2/3b7176cb570a1d3e27faf67b72f591af508036e0d8b2be2ef9af9e8c84bb/cffi-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4", size = 182868, upload-time = "2026-08-03T21:20:40.388Z" }, + { url = "https://files.pythonhosted.org/packages/56/78/31f00c1bcd97c9bbf55f1bfdf5bc809a5de8887473e90bb9960dca825e80/cffi-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e", size = 194104, upload-time = "2026-08-03T21:20:41.725Z" }, + { url = "https://files.pythonhosted.org/packages/7b/1b/58496f2ed0a35de575250c02a43ab3cc2c04d494a88fed31c1cabc0fd176/cffi-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5", size = 186402, upload-time = "2026-08-03T21:20:43.042Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8f/9ebe220eab48a093d1a5a5e339ab0dc7316eef3bb04d63c42f0251b61f50/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d", size = 194043, upload-time = "2026-08-03T21:20:48.179Z" }, + { url = "https://files.pythonhosted.org/packages/ff/69/844bad3ece306c4782c2ecb93597035b6690d48704b803914c199da1e8b3/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b", size = 196737, upload-time = "2026-08-03T21:20:49.457Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8a/af668013284634733f02d683458a0728739c7d6ddb5e14cb0c20832266fe/cffi-2.1.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4", size = 184933, upload-time = "2026-08-03T21:20:50.639Z" }, + { url = "https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8", size = 185002, upload-time = "2026-08-03T21:20:52.173Z" }, + { url = "https://files.pythonhosted.org/packages/e2/31/9e1313b0a6e30e91b3b3d3fff51ae99c857c07738e3afcce1f7334e1b7ab/cffi-2.1.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6", size = 222271, upload-time = "2026-08-03T21:20:53.462Z" }, + { url = "https://files.pythonhosted.org/packages/50/e3/f6234a833e6e08c7007003074723c406559eecf9b48dfc97471e5a8eb7a0/cffi-2.1.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80", size = 209919, upload-time = "2026-08-03T21:20:54.783Z" }, + { url = "https://files.pythonhosted.org/packages/0d/fc/5f74e293fced6edb51af3a46c4ccf6c23c9943774ecb375ddbd522c76add/cffi-2.1.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779", size = 208529, upload-time = "2026-08-03T21:20:56.066Z" }, + { url = "https://files.pythonhosted.org/packages/44/16/29e6d01b388bef055ecd6ca8244b3f4d336bd09e92d5d892187b9601084e/cffi-2.1.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399", size = 221630, upload-time = "2026-08-03T21:20:57.336Z" }, + { url = "https://files.pythonhosted.org/packages/a4/18/fa7f1f6857d5eb88a4ca99ffcbfb7c387a287ccc154c64a73e86314745d7/cffi-2.1.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688", size = 225134, upload-time = "2026-08-03T21:20:58.675Z" }, + { url = "https://files.pythonhosted.org/packages/e0/9f/e8e3dfa04a1b4c241f8c91faacad872b4d4efd051d49764ad4e2fd4b9fea/cffi-2.1.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7", size = 223197, upload-time = "2026-08-03T21:20:59.968Z" }, + { url = "https://files.pythonhosted.org/packages/f8/7e/8debeb04f1ab9fe2a6963964cd6f1aaf7192627b83926586a6a4e089c9fa/cffi-2.1.1-cp315-cp315-win32.whl", hash = "sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac", size = 177683, upload-time = "2026-08-03T21:21:14.901Z" }, + { url = "https://files.pythonhosted.org/packages/e0/31/5158704cc474ab65c1647932e88be78dc0873f47130e253be38bcaf13d01/cffi-2.1.1-cp315-cp315-win_amd64.whl", hash = "sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960", size = 187897, upload-time = "2026-08-03T21:21:16.108Z" }, + { url = "https://files.pythonhosted.org/packages/cc/4b/b3a2da8570c704ffc0f9762cdc3ec0f02c8573798e0b5cf7f11c82bbb70f/cffi-2.1.1-cp315-cp315-win_arm64.whl", hash = "sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1", size = 182935, upload-time = "2026-08-03T21:21:17.271Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ef/5443574510a1207e6f6bc38ba6e1f1de36cb48fef07b2728bb896a21f430/cffi-2.1.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc", size = 188464, upload-time = "2026-08-03T21:21:01.163Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ae/a56fa8c4686ad50e148fcbc8d3ae0d03915ff5c30d795058988c24118cef/cffi-2.1.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab", size = 188262, upload-time = "2026-08-03T21:21:02.382Z" }, + { url = "https://files.pythonhosted.org/packages/53/b2/6187f46f2912276a3ae284076109cc5c8680482f11f766ccf26db4a86427/cffi-2.1.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e", size = 223779, upload-time = "2026-08-03T21:21:03.553Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f6/c3ad28bd19f77047a03084424fbd4cbe997303267c14423737324be0385d/cffi-2.1.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358", size = 211520, upload-time = "2026-08-03T21:21:04.863Z" }, + { url = "https://files.pythonhosted.org/packages/a0/cd/ccac9013a5bd9fd764de118674ab9c805b5ca10c19270d90ee273f8b2240/cffi-2.1.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231", size = 210673, upload-time = "2026-08-03T21:21:06.223Z" }, + { url = "https://files.pythonhosted.org/packages/52/86/2976131c639aead931c5bee5aba67e4b09fbeb8018b6f282f70803f923a7/cffi-2.1.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6", size = 223835, upload-time = "2026-08-03T21:21:07.539Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0c/33a7aeab2f9c76918c52e084beb39c570db3588133412929e8ec06fab90b/cffi-2.1.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94", size = 226705, upload-time = "2026-08-03T21:21:08.774Z" }, + { url = "https://files.pythonhosted.org/packages/e3/26/2cde30fdde421130bfc18f70395731a6e6b2053c6a1978a5258ff04e72fa/cffi-2.1.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5", size = 225539, upload-time = "2026-08-03T21:21:09.911Z" }, + { url = "https://files.pythonhosted.org/packages/6d/cd/a361394c94b2129d604bb846f624a8e88255a3ee33129c434a00d715e64f/cffi-2.1.1-cp315-cp315t-win32.whl", hash = "sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66", size = 182707, upload-time = "2026-08-03T21:21:11.226Z" }, + { url = "https://files.pythonhosted.org/packages/9b/b5/ba2b299993c26577d529b6ae29841f9e15b9fcf004d65f423f4fcf94ade9/cffi-2.1.1-cp315-cp315t-win_amd64.whl", hash = "sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3", size = 193772, upload-time = "2026-08-03T21:21:12.39Z" }, + { url = "https://files.pythonhosted.org/packages/aa/29/35e016098c814cd93de9cd320c66b5bfba14dc6ecedd3cb518fa7c408c69/cffi-2.1.1-cp315-cp315t-win_arm64.whl", hash = "sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692", size = 186360, upload-time = "2026-08-03T21:21:13.636Z" }, +] + +[[package]] +name = "click" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235, upload-time = "2026-08-26T13:33:14.56Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251, upload-time = "2026-08-26T13:33:12.928Z" }, +] + +[[package]] +name = "cloudpickle" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/27/fb/576f067976d320f5f0114a8d9fa1215425441bb35627b1993e5afd8111e5/cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414", size = 22330, upload-time = "2025-11-03T09:25:26.604Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a", size = 22228, upload-time = "2025-11-03T09:25:25.534Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "contourpy" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/5a/a55177dd22553a277388e8a1b3220e92de91bacb28356cdc73caa240121d/contourpy-1.4.0.tar.gz", hash = "sha256:20156f5a1ac4f8ce02656e39a61e82164a3d359796dc8026f75b062783d500e1", size = 13323726, upload-time = "2026-09-11T19:05:05.808Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/b0/b548628c8dddf6e5e0a981b7fa8e4c008024df09c7d17c6a9e271edfa0b3/contourpy-1.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a3e67bc1a6a4618a1dac7c3053a9ffece5ddfa2046b2670b342cf430bb0b87d1", size = 297354, upload-time = "2026-09-11T19:03:35.017Z" }, + { url = "https://files.pythonhosted.org/packages/04/5a/513484208742f65af2648c519f0b7ab034616e183c4403538024c136a1ab/contourpy-1.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:072a702e2e178f4fcf96f04775d0c059e4c917925abf0d3208ebb6865df3c23d", size = 283729, upload-time = "2026-09-11T19:03:36.818Z" }, + { url = "https://files.pythonhosted.org/packages/35/da/5a6562febc994b2c4bf9d01e57a50458ef8a2051bb3e7b35a00333e0fc26/contourpy-1.4.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:404dbcd9233513dfd1323b66ea593fef90e899f658f6b8a9ed8e93bd0ca669db", size = 357819, upload-time = "2026-09-11T19:03:39.058Z" }, + { url = "https://files.pythonhosted.org/packages/6d/99/7b358ce888aaa426f755daa096c99c59d17c352037344e836f20e5d3b957/contourpy-1.4.0-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:61624f6722480aa7e168fd746164e7bfdf48f8ccb6542f1613741200dc37e2b1", size = 407795, upload-time = "2026-09-11T19:03:41.293Z" }, + { url = "https://files.pythonhosted.org/packages/be/02/34d7548adf08c60967435d79d7a90882eacc84f5093435287974c7e99943/contourpy-1.4.0-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2e741a39dfc96babe1722561e81351aeec104526c57dbe91c167c1db606c2d55", size = 408552, upload-time = "2026-09-11T19:03:42.728Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8c/9677dad226e5aaac5b823d5b09d881ebc32ff1648af417597649841e516c/contourpy-1.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e439ab450c93455feb0218532ded3e946ec7a9b5f459069f122cfa44b89229f6", size = 384850, upload-time = "2026-09-11T19:03:44.402Z" }, + { url = "https://files.pythonhosted.org/packages/08/f5/e3fbeaa489c223629fbb434737cb3de4ecaca9cae4825e77b92490f640f8/contourpy-1.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:417be048f7e122cefbe2a34c51a1f2b0410f8eb35796f794d45475ddb7872d9d", size = 1357601, upload-time = "2026-09-11T19:03:46.746Z" }, + { url = "https://files.pythonhosted.org/packages/88/be/55fec293d342c222ed58a5d4056df4362e192af2e59527a3d5d822de8828/contourpy-1.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:43d80072a32299bf945de0a6dd4e034ea0162e832261de2e07a274a5adbba9c9", size = 1427340, upload-time = "2026-09-11T19:03:48.745Z" }, + { url = "https://files.pythonhosted.org/packages/86/40/0faabf453edf59b0e3633381d7ca72c3414fb9b72b5cbb08b06ed792d3e5/contourpy-1.4.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:fa1b787362a3856e63dd2b89449f6c384d55ee1beb8f94f4bcc871b40f02462c", size = 118355, upload-time = "2026-09-11T19:03:50.047Z" }, + { url = "https://files.pythonhosted.org/packages/38/0c/7ea75aa3559ae8a6805015e15a19c92b6480752ecc92526361e5776e88c5/contourpy-1.4.0-cp314-cp314-win32.whl", hash = "sha256:738c44fa71735a617f36da58e32810512407d283d5d1bb5b1cecb00d7eeba7cf", size = 356977, upload-time = "2026-09-11T19:04:11.401Z" }, + { url = "https://files.pythonhosted.org/packages/15/41/3df8cc14bb572c8b447f9dfbc876703f0f2f2896058285b5c87a1d4a638d/contourpy-1.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:181bea01bc742734ae672fa00c717d855dd35e1f029536406538c52e7b0cd73d", size = 240101, upload-time = "2026-09-11T19:04:12.772Z" }, + { url = "https://files.pythonhosted.org/packages/66/01/ee6830a5aa4565662a345172f6f35eeeed625d20f1c9d4ecd35318fe4ade/contourpy-1.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:64039341e2d8804f1a13bda8c69083eab935167bbd7e856cf096241f17d5bd45", size = 576359, upload-time = "2026-09-11T19:04:14.983Z" }, + { url = "https://files.pythonhosted.org/packages/51/af/49ee9c9cf012699e505c1b63c531cc99f19df50f205173092c4d541e3ec7/contourpy-1.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ef47fef9a912c77e3d84b014f701e5a9340f25703e9ed3bcebe37f91fb69dc49", size = 313601, upload-time = "2026-09-11T19:03:51.452Z" }, + { url = "https://files.pythonhosted.org/packages/ad/59/ce411ab2be0f805038626d8f4ca9ce563487ff51ff6c363e7512271564ed/contourpy-1.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:96019f059bcb3774acc0104be3360a57b36d33eaaa2e1d7f77c800ca8e07618b", size = 302812, upload-time = "2026-09-11T19:03:53.022Z" }, + { url = "https://files.pythonhosted.org/packages/95/b0/390915f9af14c1e2d3b2a9ad99d85b98df4352346a51e368cbb825f813c3/contourpy-1.4.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ddf5a2596d716fd3793434844caf31abc7a40b1e8718431420c89858268fb909", size = 348996, upload-time = "2026-09-11T19:03:54.594Z" }, + { url = "https://files.pythonhosted.org/packages/c7/85/e0952576d54322f3e9983b1e049a7a31f42ce82c5c29d01821e6dd3780d7/contourpy-1.4.0-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dd59df9e2fb0aff8bd7fd1adb9f349b7c835245a9d0f18c2f2deeb537190f2b1", size = 400272, upload-time = "2026-09-11T19:03:56.822Z" }, + { url = "https://files.pythonhosted.org/packages/d6/7d/f13543a5e1598e4a4ad01d9d5e2d65f9c09c37660616429913d606c5977d/contourpy-1.4.0-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b7794ea07cab575633daad8d6e963b662053391022294d3aacc1d9ba9ef54114", size = 412895, upload-time = "2026-09-11T19:03:58.487Z" }, + { url = "https://files.pythonhosted.org/packages/c5/a8/6e5eaff53507dfd2dfc428240eecda32453067277d4b3e7ca71210b2d611/contourpy-1.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a1c8a74744fa746eeaa12f0f9ed7f8b4add9d8f1b14d95e3b5e133675eac888f", size = 377060, upload-time = "2026-09-11T19:04:00.122Z" }, + { url = "https://files.pythonhosted.org/packages/16/a3/d00e44d35511b3cead5bd794ee672d4eecf30d9de4ceac57a49d6204064f/contourpy-1.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:107ec46f7aa1664266d69b1181aadc953d58d39f7d8d648fa5b795d4a060b0de", size = 1345688, upload-time = "2026-09-11T19:04:02.705Z" }, + { url = "https://files.pythonhosted.org/packages/1e/01/1e533b0cae32c8edd63fe40435ec3b29345dab87321afcd28722d7f957d1/contourpy-1.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5a4c89c7f38a0d7a94356d74e3391073c4325c4d47ad2fd065c3fe7dbae16c0c", size = 1416140, upload-time = "2026-09-11T19:04:04.77Z" }, + { url = "https://files.pythonhosted.org/packages/6d/0c/4ee66759f00d6a5d6909782f14f441d639fa18a4a43142e334351efc47f8/contourpy-1.4.0-cp314-cp314t-win32.whl", hash = "sha256:912c6afaa106e2f74ba22b30416b77ef7eb94e3bdc5a4df51ab147845dba9b6d", size = 371982, upload-time = "2026-09-11T19:04:06.233Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ac/b3e5324138c3e3741f526663f4f265f4f69dfdf26415a39428940864a5f6/contourpy-1.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:ef9440f6f8506246269a82734f5ff9e2e4c5e775b3996fc883cc491c5257eca6", size = 262907, upload-time = "2026-09-11T19:04:07.882Z" }, + { url = "https://files.pythonhosted.org/packages/19/37/c9aa45e47819dc15a38fc5c81a2fb987fde55e9d3b991fbde514e3b6b5f5/contourpy-1.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:fc9feef8f1f001c5b87decadc67c4a5d1eebb62ca39c4763d1237ff62cf2b707", size = 587071, upload-time = "2026-09-11T19:04:09.898Z" }, + { url = "https://files.pythonhosted.org/packages/cc/74/66d4e6fbea3bcb3fd4e5ae21c039ba31b8fc408b35884b4bc09b88016dce/contourpy-1.4.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:79b06c60d5e569ce12c5da8f0c51217cdc484386e2349fa717c30fafb56d2871", size = 297358, upload-time = "2026-09-11T19:04:16.718Z" }, + { url = "https://files.pythonhosted.org/packages/2e/8d/8f7f25e71d73f15d7859943189900d2d348e740388c9ef52a0180d284762/contourpy-1.4.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:6f963ea9f0d68d2b6a02d861e3c0aae09ae25ba21f243fcf281e9fed468b078d", size = 283732, upload-time = "2026-09-11T19:04:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/f0/90/957549e3b03c407c670e3e191db63f4aef60dab6605bc967af3a806b543e/contourpy-1.4.0-cp315-cp315-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5545ff38229c15d11d822fc6f7415b932da9f4975f53e305b7b96ebfb01f889c", size = 357820, upload-time = "2026-09-11T19:04:20.077Z" }, + { url = "https://files.pythonhosted.org/packages/56/4c/fa8de87d907b41b05d03f4945a51675cd67319650d01b4c927d209ffa6ee/contourpy-1.4.0-cp315-cp315-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:630d32f06cedf37b7f1dd2b6a12e4492826bd477a4c9c7b2e2fee6ce3a2cea76", size = 407804, upload-time = "2026-09-11T19:04:21.781Z" }, + { url = "https://files.pythonhosted.org/packages/04/e7/96bd4f4a4ae285727befbdb4b332d53a2654cc5da4585d2525b47a063e1f/contourpy-1.4.0-cp315-cp315-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:be85d160e7c795113c2a93254dde2fc7e86b375322570eee78b420969426973c", size = 408559, upload-time = "2026-09-11T19:04:23.432Z" }, + { url = "https://files.pythonhosted.org/packages/ae/94/39660e8dc309f96bf7971eb4ec5659f272f84e42b34c9990a96ecce8442c/contourpy-1.4.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:018227e134b73090b06f911e773a526c77c9af426be29065500ce096a5accd4c", size = 384861, upload-time = "2026-09-11T19:04:25.198Z" }, + { url = "https://files.pythonhosted.org/packages/ab/7b/411dccbf73d5d19da49bf7735786b3baf4ddb1456412d48ae4d4ab1fc761/contourpy-1.4.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:4bffcb2e8cc5c0e837631acab59dd04265fdac376550e7c3e310523877c68cb7", size = 1357612, upload-time = "2026-09-11T19:04:27.614Z" }, + { url = "https://files.pythonhosted.org/packages/a0/39/bf2442130e7d5aae75a4de4504f0c8aca3ef3da3feac3940ee27ca985d83/contourpy-1.4.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:cc87f2ffa84a49a77d76cb792f28a48ff3b05a222aa0b2bddbd839ba78e1d5ca", size = 1427345, upload-time = "2026-09-11T19:04:29.646Z" }, + { url = "https://files.pythonhosted.org/packages/96/60/e5d9196dd83ccd7dd103762982b10ef19a4f72e8ef67ae7157699b9be0bb/contourpy-1.4.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:c8be3392b84cf43373a488874dc1ebf46f60784a70977f92586e18019d71c7ed", size = 118157, upload-time = "2026-09-11T19:04:31.091Z" }, + { url = "https://files.pythonhosted.org/packages/1a/b2/ae3d90f08ba2ed82189d93b55ffbd41e559760e89af4f9ef54d51869f41d/contourpy-1.4.0-cp315-cp315-win32.whl", hash = "sha256:618137ec5778fb76d494c9ec854b104a377fddba0d128bef7136cce2c3bf0df8", size = 356982, upload-time = "2026-09-11T19:04:52.913Z" }, + { url = "https://files.pythonhosted.org/packages/02/a0/36648fff407dcf8b8482985d33367ffc0fe90be72383869312cd0bd00a1b/contourpy-1.4.0-cp315-cp315-win_amd64.whl", hash = "sha256:ea09dc704029930cbd097f75cb0cc1db9852adbcf1a151fac7e9559f7bcbfd19", size = 240101, upload-time = "2026-09-11T19:04:54.587Z" }, + { url = "https://files.pythonhosted.org/packages/07/09/49e987a96706b8f877596cee00d558d7880793a833addc6b33f80805e5dc/contourpy-1.4.0-cp315-cp315-win_arm64.whl", hash = "sha256:a5e2bb871b90cd7a52bdee63bf80ef7acb46398d27efc66d7679240016efc5aa", size = 576375, upload-time = "2026-09-11T19:04:56.515Z" }, + { url = "https://files.pythonhosted.org/packages/e3/18/820ba24a070fe2a834af73e52245c501960746f5c1777ebc64ec0c0dec12/contourpy-1.4.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:432e89f835cf01f8d2123a130a3126b17ee6e0348e4d62c0973872b30aa873bf", size = 313543, upload-time = "2026-09-11T19:04:32.582Z" }, + { url = "https://files.pythonhosted.org/packages/d3/4c/f61a63d8107e0c1c3fa47d30ce45abad90b2ad48a1a9a4510332db7e0176/contourpy-1.4.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3e0a2392533e5e2abdf277c951047516acc8d2f3c42b2dd9dc34c907c9ebabf2", size = 302702, upload-time = "2026-09-11T19:04:34.257Z" }, + { url = "https://files.pythonhosted.org/packages/9d/93/5af95cb5113ecc6e780ca0c6c79756a2cea8833f971bbae112dd4ad73ded/contourpy-1.4.0-cp315-cp315t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:758e7496cec3195fc28a28945eab3ceef348c47fb95c7afc2eca2f3901209c8c", size = 354370, upload-time = "2026-09-11T19:04:36.158Z" }, + { url = "https://files.pythonhosted.org/packages/47/75/5a9942446647202beb7b4d150891bfcb78fb112c73862484bbe4cc031092/contourpy-1.4.0-cp315-cp315t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bee6ff96653e0807cd0f8eaef00174a031e3a2effa5c20f49a5a8d574b05af23", size = 402340, upload-time = "2026-09-11T19:04:37.914Z" }, + { url = "https://files.pythonhosted.org/packages/c3/4f/bfdb0c67775a584f957211936661289789c4d0ec3e988bca2c8c02f8090e/contourpy-1.4.0-cp315-cp315t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a58b5f130afec61a093d743cdda435cc4047748b6791627e34a68f41ec3a9b07", size = 410721, upload-time = "2026-09-11T19:04:39.925Z" }, + { url = "https://files.pythonhosted.org/packages/65/d3/dddf13d6bb26e145c99debd1f2695018b5f3e24452dd9bfc9904c9d2ec89/contourpy-1.4.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9dc493e7924e5aa32d89d0b8e50986280f3d4b284968a792787bd7bcffd3cad", size = 382604, upload-time = "2026-09-11T19:04:41.793Z" }, + { url = "https://files.pythonhosted.org/packages/37/b4/89f0a5f6c6ccd322eae2704c7e933c82a4e594a61773933b4b0a18646866/contourpy-1.4.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:c927ec747633e68c9920bcaad48b0bcefe648812b822f18c34e2d0e2270a3d2a", size = 1354996, upload-time = "2026-09-11T19:04:43.856Z" }, + { url = "https://files.pythonhosted.org/packages/5d/29/fc91cc1ac6f3b591a269f4357b656d6ed0c39eb17c148f41f6da2f9729b9/contourpy-1.4.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:80c7fc8e7ac217777ce7ba2db3cf8478652b5a4b335283111012ff9eaac9d842", size = 1425030, upload-time = "2026-09-11T19:04:45.981Z" }, + { url = "https://files.pythonhosted.org/packages/d8/b8/bb129f524210c5d3eb8616876e02af280fba8b5554e0ac1afad80b51e06b/contourpy-1.4.0-cp315-cp315t-win32.whl", hash = "sha256:90feb8da006803a95ba573fddc9536357d0c3faddc3a4c9e22816ca49af52878", size = 371854, upload-time = "2026-09-11T19:04:48.106Z" }, + { url = "https://files.pythonhosted.org/packages/d8/b1/bc774d9d200cfc4f073bba78b1bb1cb3b55bf1c8c345eae41fc2db510459/contourpy-1.4.0-cp315-cp315t-win_amd64.whl", hash = "sha256:de503609fdb71f597634ca64fb4bd2f13d27c97f140e912b1e8ed93544840df0", size = 262450, upload-time = "2026-09-11T19:04:49.502Z" }, + { url = "https://files.pythonhosted.org/packages/54/bf/eb4ff492e1c3d027617b5a20e4e6d63a035b41b8cf77a95950159556a3a5/contourpy-1.4.0-cp315-cp315t-win_arm64.whl", hash = "sha256:78ed5c5f962b3e156109f0531b174a65ba80d13cc681a70227b12524c162e184", size = 587064, upload-time = "2026-09-11T19:04:51.148Z" }, +] + +[[package]] +name = "cuda-bindings" +version = "13.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-pathfinder" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/81/bff68ce829999c1e4209c761bbf903b1c06ec570416ddb25020864ad5907/cuda_bindings-13.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ab2f74ed65bfef4163ba07a8db16f1085e0729291db12a2423aff84ee8278b8", size = 6013639, upload-time = "2026-05-29T23:12:03.509Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e0/c8a1f0c8f9ffdea4f5fe6dbab89b326cef4d85caf489dad39e209da89416/cuda_bindings-13.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd4c814d311ec08c981f6dded1dbe7d4b371067ee4f6c14cccec4bde9590f80", size = 6534419, upload-time = "2026-05-29T23:12:05.633Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/83b1f563925b290f2d11a01a77a84013ba56052fe3653a5bef3ccfbb43d6/cuda_bindings-13.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3c772dfff49681541d59630c90f858e173ac926b9c593a2b7123f2a1043cc76", size = 5809771, upload-time = "2026-05-29T23:12:10.422Z" }, + { url = "https://files.pythonhosted.org/packages/12/20/e79b4bfe98f075195afb6343d41c498f9dbd2d161d7021d4d28bceb83581/cuda_bindings-13.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:36febb7c1079d68a981dbbd8d5a67235b399802b82075c9388624719607e52b9", size = 6358584, upload-time = "2026-05-29T23:12:12.767Z" }, +] + +[[package]] +name = "cuda-pathfinder" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/b4/d088047afe39827556df21118cac9ffd20cc3f968c99a7681494d1eb333c/cuda_pathfinder-1.6.0-py3-none-any.whl", hash = "sha256:1503af579d8379c24bdd65528379bc57039b0455be9f5f9686cf8e473a1fce51", size = 54591, upload-time = "2026-07-21T15:03:56.224Z" }, +] + +[[package]] +name = "cuda-toolkit" +version = "13.0.3.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c7/a79086a62c98befcdb8349656c6f114e2db3b8b2422f6e25c97a7f2a9a3c/cuda_toolkit-13.0.3.0-py2.py3-none-any.whl", hash = "sha256:d693caaa261214ddd7dbb60d68e71cbed884e68c2be7509778f3051da0b91c3f", size = 2512, upload-time = "2026-04-14T00:50:08.173Z" }, +] + +[package.optional-dependencies] +cublas = [ + { name = "nvidia-cublas", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, + { name = "nvidia-cuda-nvrtc", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +cudart = [ + { name = "nvidia-cuda-runtime", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +cufft = [ + { name = "nvidia-cufft", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, + { name = "nvidia-nvjitlink", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +cufile = [ + { name = "nvidia-cufile", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +cupti = [ + { name = "nvidia-cuda-cupti", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +curand = [ + { name = "nvidia-curand", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +cusolver = [ + { name = "nvidia-cublas", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, + { name = "nvidia-cusolver", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, + { name = "nvidia-cusparse", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, + { name = "nvidia-nvjitlink", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +cusparse = [ + { name = "nvidia-cusparse", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, + { name = "nvidia-nvjitlink", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +nvjitlink = [ + { name = "nvidia-nvjitlink", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +nvrtc = [ + { name = "nvidia-cuda-nvrtc", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] +nvtx = [ + { name = "nvidia-nvtx", marker = "platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + +[[package]] +name = "et-xmlfile" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" }, +] + +[[package]] +name = "filelock" +version = "3.32.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/64/a02e6765de08964ed371eca577870593245afc9dfac16d037de7c10d18e6/filelock-3.32.3.tar.gz", hash = "sha256:0ffa185a3540854c95caa7fa76b76cb219d907415e2c5dc9af25fd970563487f", size = 218135, upload-time = "2026-08-13T16:00:05.577Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/8e/50f46a9c0ce8d2861a394c1347caae037ea0431d2f67d7feb151cbc4649a/filelock-3.32.3-py3-none-any.whl", hash = "sha256:7f0ca4bcc0e181c60dbbd8aa9ab5b120ebb99e4e064e83636340056f833a1f09", size = 98901, upload-time = "2026-08-13T16:00:03.974Z" }, +] + +[[package]] +name = "flatbuffers" +version = "25.12.19" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/2d/d2a548598be01649e2d46231d151a6c56d10b964d94043a335ae56ea2d92/flatbuffers-25.12.19-py2.py3-none-any.whl", hash = "sha256:7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4", size = 26661, upload-time = "2025-12-19T23:16:13.622Z" }, +] + +[[package]] +name = "fonttools" +version = "4.65.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/77/51/d63c7e52163ac14393a35bd14bd7c0da95f8f74be5d7cc988092f9965129/fonttools-4.65.0.tar.gz", hash = "sha256:762ba5431358d0dbd4a01982484a1d494fb267e91f974cdcf20b80eab8560f6f", size = 3674467, upload-time = "2026-09-10T15:35:54.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/29/606365ef601668bfebed14cfe3dc72bb7fcd1e23011bbb2833f17fea3065/fonttools-4.65.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:dc87a9f846bec83c3795804f62b4632716d46e3522869a3dd9cd44a5d245b006", size = 3098393, upload-time = "2026-09-10T15:34:28.472Z" }, + { url = "https://files.pythonhosted.org/packages/c7/61/11412939d6b7abf5ac7ce0d61d7f94a0a4fbabc9f1ab0a04fa622e0fc11c/fonttools-4.65.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aa50dd7b9baf75e2bbd43401fc0d237f7a94a8ad2e0c57ea97160fc631af5eb0", size = 2585766, upload-time = "2026-09-10T15:34:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/db/17/734921d8aee8309801da42590375d32d4d46f771b73373ec9520d5d4220b/fonttools-4.65.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0d2a9892fdb3b7e2d0f4174e3b907d226ff83698249762eeefce08ec5b2de1dd", size = 5380679, upload-time = "2026-09-10T15:34:33.933Z" }, + { url = "https://files.pythonhosted.org/packages/cf/eb/2a4d78d60d978e694cfa04c98e4d8ddbf7f028fd768ddef470bb9da5d69e/fonttools-4.65.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6d815734e7fede0ad1f233f23f0f191cbe8fc64762ff041e589bc0f78e0b2397", size = 5321833, upload-time = "2026-09-10T15:34:36.295Z" }, + { url = "https://files.pythonhosted.org/packages/d9/ca/1cd48b5c11ef9658732787bf2362e1bf3871dad5945d2f6cc8f675ca769c/fonttools-4.65.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:71e4c67b6196a2f447f46476fd2302604721617f5e0a21b0988bdd87b6bb9687", size = 5320938, upload-time = "2026-09-10T15:34:38.992Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0d/90e6051bded926cccabe9dd0bce3b6ca012f4d5779d61167afbf4989ceb6/fonttools-4.65.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b11d8a4a0c3ca74bbd4c105b7ef82501945c939e6096d9934ec7d288cdf5aaa9", size = 5451747, upload-time = "2026-09-10T15:34:41.387Z" }, + { url = "https://files.pythonhosted.org/packages/18/74/23e0268e48029ff0752083f69312c49b738163d5af919add9dc4ac81e907/fonttools-4.65.0-cp314-cp314-win32.whl", hash = "sha256:8e44a34d91b3c793879767eb115867ced74d2eb94974e64e72fe9e2eea71cf1a", size = 2434246, upload-time = "2026-09-10T15:34:44.385Z" }, + { url = "https://files.pythonhosted.org/packages/a1/2d/ee69affecd4bc81cb932a213438d4199fb48bf8ca6d664438ccc7f623c2a/fonttools-4.65.0-cp314-cp314-win_amd64.whl", hash = "sha256:0aa8901db22875c831d6a91796549590d7e747da37438f38b69d771b668be445", size = 2486706, upload-time = "2026-09-10T15:34:46.842Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9c/edee5f785198ce3327e1ddeace91c773122d47f086a67e0a84b800f4a940/fonttools-4.65.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:2e4a380ca40d3a5372e31b340f0da0d53b4583aadbb8e41f6a516afa69c509a4", size = 3172027, upload-time = "2026-09-10T15:34:49.269Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c6/252ec9884381089bc30da75978b072593920249de60219817f16cbc9145f/fonttools-4.65.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:661bd91c4be13721408b2d4b67a9b3fa7736713adc9a6c9780c9c60fc7959f90", size = 2619020, upload-time = "2026-09-10T15:34:51.453Z" }, + { url = "https://files.pythonhosted.org/packages/42/79/f71b0d202b8473bb45b07876c08a474de9fe560ed2c0cde642812a81e22a/fonttools-4.65.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62c5e42c79449def957adf8a9a65a43018efa7e2a6bc6baa3afe955e0d5fb2ab", size = 5545942, upload-time = "2026-09-10T15:34:54.804Z" }, + { url = "https://files.pythonhosted.org/packages/4a/bd/52e1bf33e0aebfe22ecc9a85c634db707c1dd9f6b1b438efeed98c55b959/fonttools-4.65.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:36fca8efc46b5adfca327c666e739fc05b7a7a6ef17840230f81b22f53230f61", size = 5351477, upload-time = "2026-09-10T15:34:57.514Z" }, + { url = "https://files.pythonhosted.org/packages/5c/76/8c6b2ad20beec95cd446f3a8bdc753c7e4a4fd69ef3e66704c0f7c8cb0b5/fonttools-4.65.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8aa1291e4c767abf1b0b79ca2d6895f7c0b661d9d95d03b5791c883a9d1e1f08", size = 5412271, upload-time = "2026-09-10T15:35:00.895Z" }, + { url = "https://files.pythonhosted.org/packages/79/49/fadbf11bbbd2d699d88a5498a0634280206e01e3bd5da9a4e0c504953ce9/fonttools-4.65.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fcf39949f56911348514b466714efa9118bec3d2be249e1c487263f7cda6edab", size = 5446450, upload-time = "2026-09-10T15:35:03.369Z" }, + { url = "https://files.pythonhosted.org/packages/df/77/5fda646d3a6d5ee26465865c00319cc0925cf484a3b42dd8232d5b39f973/fonttools-4.65.0-cp314-cp314t-win32.whl", hash = "sha256:ffc918702661f1d74d2fbb2f5551036b64f6d2d743139e105289b694bcd16f54", size = 2467858, upload-time = "2026-09-10T15:35:05.744Z" }, + { url = "https://files.pythonhosted.org/packages/ae/0f/afa0f3de70ebe02bba46b32cccb30b1de52624472b14ac2e7cd403d08db9/fonttools-4.65.0-cp314-cp314t-win_amd64.whl", hash = "sha256:5a977e3645dbffaee924209828aa702a215f7ff68bc08010740c10c723787e62", size = 2518248, upload-time = "2026-09-10T15:35:07.846Z" }, + { url = "https://files.pythonhosted.org/packages/86/54/b273cf5712b36a381c13284fbf244e811e1e1d7081aed20f200f0a191ffa/fonttools-4.65.0-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:7aa0518b45ff5286ad56f063938db3add3816e899aab58d782b3f9a252523caa", size = 3092770, upload-time = "2026-09-10T15:35:10.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/1d/d3e4511475954d4ec4f3c254e81f0fcc1ade504cb7381eeca48b8c44b8a6/fonttools-4.65.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:673e2b3ac4ac8e4f3607d390ecc5a606e5db5c4e88fb4cb2999593efb65afea2", size = 2584364, upload-time = "2026-09-10T15:35:13.54Z" }, + { url = "https://files.pythonhosted.org/packages/e5/3f/7cfaba467bdd1d3d04be21ba7b5bd75c6ca58ba280e0519707ca96a43c4d/fonttools-4.65.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a03cff943b204a90bf3d1c04c97b9509a8aa0ee99e2e544084ca43ad995975b", size = 5377819, upload-time = "2026-09-10T15:35:15.839Z" }, + { url = "https://files.pythonhosted.org/packages/25/17/a68d9b19a97bb2ee37e8098fea50657073df97c7e5392afbe1b9d7c0c581/fonttools-4.65.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:41f684ee6212e411196ab054f8308faf6605f154950e6f4686fb8f2103d624b0", size = 5341296, upload-time = "2026-09-10T15:35:18.527Z" }, + { url = "https://files.pythonhosted.org/packages/ad/8d/d744653ed607a241339015d4af6743ca3d85a74a2045a02cc06ea0383c71/fonttools-4.65.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:52ea9d2a8385075770db74d5e5718fa80b2222bb4fc62856a377dd2865ca8848", size = 5315310, upload-time = "2026-09-10T15:35:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/f0/c8/1ca6dc69cbaa0e394ff70d9e266777124d3ce3c6433026a6b4de50b890ae/fonttools-4.65.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:d0d25027ade65ec46b13c0436e51bcb7c5171a4ea255a5e7a8d0d1d3ab4cffd7", size = 5463840, upload-time = "2026-09-10T15:35:24.022Z" }, + { url = "https://files.pythonhosted.org/packages/07/97/d374df38a14f2ac04ba9ed96bca89d4988e7d63aa5ed85c54fd8f2badd7d/fonttools-4.65.0-cp315-cp315-win32.whl", hash = "sha256:22cb846d35d278235ef3b7e947c6040b2057d72e8305a314f21d5342eca49040", size = 2433149, upload-time = "2026-09-10T15:35:26.59Z" }, + { url = "https://files.pythonhosted.org/packages/62/c5/eb8f7506faf6a70c5a8f2eccbeea3cd826c748a6fd78c7b4b3effb5a3a11/fonttools-4.65.0-cp315-cp315-win_amd64.whl", hash = "sha256:aecc899fdbf9ecbf728f8977977e2e1043ee4d70c257124c8fa4cbcf796fcd83", size = 2485725, upload-time = "2026-09-10T15:35:28.945Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a4/2df0d97514feb8d857d5de854cd8d660d9a7ee1fd081bc98497124f515a8/fonttools-4.65.0-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:6275863dad195ee34b6e0ca3fc61c74096bc37e5d6fb8e049f4d68d65865a2b7", size = 3164065, upload-time = "2026-09-10T15:35:31.197Z" }, + { url = "https://files.pythonhosted.org/packages/15/33/e09661c09e6c8a3b0bd50da0e72918df7576dede31f39c948cc245011434/fonttools-4.65.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:d8ffd2f62b402180b0edae8f86a071f583970e2177143117db5cf4c52da60079", size = 2615195, upload-time = "2026-09-10T15:35:33.569Z" }, + { url = "https://files.pythonhosted.org/packages/64/d7/114b05f4193679d0935272220083ec43de7f918b5a777018c5ac5c1ae39e/fonttools-4.65.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:830f91327ca83bfc1278e7060068a498938f84d05dc4869675486f84f55d4fe1", size = 5521239, upload-time = "2026-09-10T15:35:36.291Z" }, + { url = "https://files.pythonhosted.org/packages/ba/10/67d615939f859ffe75663a67bca3593966febbcd0109ec72f20f73cbb4cc/fonttools-4.65.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9db2cb95847c18eef74a4ef0fe257a893ae3f4b0395f4866e2f426ab07f3d804", size = 5343802, upload-time = "2026-09-10T15:35:38.82Z" }, + { url = "https://files.pythonhosted.org/packages/d1/06/faa793a806da03acce862fbed353f76026b28103d43860d69be9a6a1f0fd/fonttools-4.65.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:be9b9a95ed0af03375e99020e921c4bc6b41fad10e053dea7acad370521a3c46", size = 5388482, upload-time = "2026-09-10T15:35:41.616Z" }, + { url = "https://files.pythonhosted.org/packages/53/d2/eb7258df60e634db60c9a8cd72bc9eaf8dea409d1b1ceec3b9fb49531ad2/fonttools-4.65.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:bbd9faf777a9deb6790df4f2b0be611857c45fe86605e840d7154a028d828af7", size = 5435088, upload-time = "2026-09-10T15:35:44.639Z" }, + { url = "https://files.pythonhosted.org/packages/00/6a/58597f16e1265fe9205de3069e338a339e3eef0b1daf049ee08269458091/fonttools-4.65.0-cp315-cp315t-win32.whl", hash = "sha256:c779d838815b91889c95ed64c9be5950ad5a683279f91aeb23384cb757ddc6a3", size = 2464925, upload-time = "2026-09-10T15:35:47.224Z" }, + { url = "https://files.pythonhosted.org/packages/4b/95/122fc172006db747f4968e08c710f52a94f55eb007173b859b3f80b5b810/fonttools-4.65.0-cp315-cp315t-win_amd64.whl", hash = "sha256:d9484b7ee1b49b6b8a0231c849f3983723dec29e3a7366d9b1b02f4036f71944", size = 2513945, upload-time = "2026-09-10T15:35:49.895Z" }, + { url = "https://files.pythonhosted.org/packages/e6/35/f894ceb867118c0261d0f69a9bd516b045a3754238f76c88a49513ac7a83/fonttools-4.65.0-py3-none-any.whl", hash = "sha256:3060b8c1fc2329fa20265b7c138614143ea7c1624e26c5c180c76aeb74deae6f", size = 1196441, upload-time = "2026-09-10T15:35:52.347Z" }, +] + +[[package]] +name = "fsspec" +version = "2026.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/78/f34251dadb8f3921264a1d9b8946f5e542014ee2614b285261b4e40e6775/fsspec-2026.7.0.tar.gz", hash = "sha256:c803c40f4cf860b49dea58ee3e1c33cb9c790520e233537e1340049f89b82a88", size = 317040, upload-time = "2026-07-28T16:34:51.052Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/3c/6a2bf344106328fd04963664a60b9bb6496fc25df8e962fcdc1367285fb9/fsspec-2026.7.0-py3-none-any.whl", hash = "sha256:b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279", size = 206583, upload-time = "2026-07-28T16:34:49.538Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "hf-xet" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/ab/522a2ab67f27971a9d48ca666d4fca85ef7d5282d142e31fd087e27b1bbe/hf_xet-1.6.0.tar.gz", hash = "sha256:2e58454a340b3556dfa4972d5451aff4fba8dd42a236600ba1a1d2b1514f0fef", size = 920527, upload-time = "2026-08-03T22:33:13.243Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/62/3c062f593bd92ef4e77a0ef39541e3d82a0a1d3947c8a777a02a13a27828/hf_xet-1.6.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:70cbb9c896901600128cb9b6f06e132954fbede1db30f31f7c6c63f84cb7c31d", size = 4074584, upload-time = "2026-08-03T22:32:47.364Z" }, + { url = "https://files.pythonhosted.org/packages/bb/1e/c0ad437dd267a8e435bef594acf781bbc3874ff0b6435b4962d03ecf7cc4/hf_xet-1.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:23379c2f9ec8696d952b16414a2bae72cad86a52df869b050698ba60f538c675", size = 3867381, upload-time = "2026-08-03T22:32:49.049Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ee/7c0d7b6ab336167531b1c30af2af003f054af4c749becbd7209ae33a77c3/hf_xet-1.6.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f2f7278c05c22fd60cb436cda1269649b3e81db65ecdc8496e5e164aa4143e7b", size = 4453982, upload-time = "2026-08-03T22:32:50.568Z" }, + { url = "https://files.pythonhosted.org/packages/63/06/ad8eab1c9525246650cbaa821caa3cdbaca734ab1a5b8c91bea09cbd8d69/hf_xet-1.6.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:948f15d3a9545cfe5932f6bd8b440f6ae630aee108f14b7bd6c561f7c2dcc522", size = 4249445, upload-time = "2026-08-03T22:32:52.391Z" }, + { url = "https://files.pythonhosted.org/packages/d8/26/1eee8aedb0dafc1ab9717dc9ac602cde33361b232dc06803f1f6ed18b58c/hf_xet-1.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5153e6bb103ad49d6ea9f1b2e230db5a2ea32551ad09a706d2f61d7c7c80d80e", size = 4451099, upload-time = "2026-08-03T22:32:54.114Z" }, + { url = "https://files.pythonhosted.org/packages/67/57/0b88af1f194ab6c9c650547d9cc06bfeaab836ae4dcdb331676bfb8be95a/hf_xet-1.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:35cec30d75c6f9eb9c16a77cef68e85a103b72e24d4b473714ec9ff06428bab9", size = 4664712, upload-time = "2026-08-03T22:32:55.547Z" }, + { url = "https://files.pythonhosted.org/packages/53/a0/26b717a9d1840e8abf48dcec64b5ed8fbe472671d38ad28d30e147132b33/hf_xet-1.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:5789835d7c6bc9436962853192082374297fb72d7eff7e7762ec25ceb7e25338", size = 4025906, upload-time = "2026-08-03T22:32:57.391Z" }, + { url = "https://files.pythonhosted.org/packages/49/f6/4a9966633c6fef83af997e2cff68ec1963676d412bdfd096df2a93b8e185/hf_xet-1.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:75765820ce4700db3750c94acc8fe27c5fae4c9ec000a0dbac3ca082acf97765", size = 3849221, upload-time = "2026-08-03T22:32:59.123Z" }, + { url = "https://files.pythonhosted.org/packages/a2/50/7afa2c9c787405864fc47a0d1bbc02c62e9101947ed43c1f43899fc7d91d/hf_xet-1.6.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:633dc0cd71d32da58ab8c03ad38e2fac452c15c2b0a2866ebf6ededfe0a5061d", size = 4071729, upload-time = "2026-08-03T22:33:00.721Z" }, + { url = "https://files.pythonhosted.org/packages/4b/69/55b8dcf636142ae660fec1869fcac14c4da2e8412e14d6eee1523be77e9f/hf_xet-1.6.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:f0906082d9932ae0c0057fa194041c22b4e2cdb46b2592ef3b91f020d62a081a", size = 3876287, upload-time = "2026-08-03T22:33:02.251Z" }, + { url = "https://files.pythonhosted.org/packages/67/4e/a28359bf1c1ecf11eba22123168c138698f7cb576ac678f5a2e16cd5da08/hf_xet-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d62671bb130879cef0ee4c9ebe47a14af6c66ec53e6d84dc15936e5ffdfac82f", size = 4464663, upload-time = "2026-08-03T22:33:03.802Z" }, + { url = "https://files.pythonhosted.org/packages/9a/69/1f0cbc2fb22ae6082d094f743d1b8945a3f36f6089cb95f42b7ee348cda7/hf_xet-1.6.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0e6e21fa3cdfcdcd76748564bf593870a5e013f47d97cf10aed63aa222cff5b7", size = 4262538, upload-time = "2026-08-03T22:33:05.287Z" }, + { url = "https://files.pythonhosted.org/packages/d1/3a/4f4f2301ade26e404462d3336fa11f7958d914cabbabdd6e03c3c5d5658c/hf_xet-1.6.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4fc74352a17015bd0ee90038bc9efe38db894cde45f268b6712b04fce8cd0acb", size = 4460520, upload-time = "2026-08-03T22:33:06.81Z" }, + { url = "https://files.pythonhosted.org/packages/ab/5f/311725e2a905534dfee2dcb5b08414f249147f1f12252bfc2bd24caa075c/hf_xet-1.6.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4f71cba6129110c3374a33f919001ff130488fc23553698e34cc1c2a1198c", size = 4675937, upload-time = "2026-08-03T22:33:08.616Z" }, + { url = "https://files.pythonhosted.org/packages/98/b7/8c59a66d15205024662f1d66968136f13893f96df1ddc5087e2e281fc95f/hf_xet-1.6.0-cp38-abi3-win_amd64.whl", hash = "sha256:fb4fadde1b2b70bf4c0c14a6dccbe7194b1c28947fefd5bbe3fed9d940676c3b", size = 4033128, upload-time = "2026-08-03T22:33:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/73/63/ca511b6f802f28cf3489b280fe77475bcca8de85e81a6299d7916b5b5555/hf_xet-1.6.0-cp38-abi3-win_arm64.whl", hash = "sha256:3dc3e35441ba395006af5aaacc40ef2e603c51ef46c3530b9156185f00935ea3", size = 3859359, upload-time = "2026-08-03T22:33:11.725Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "huggingface-hub" +version = "1.32.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "httpx" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/0f/e83fdd856da8fca26bf78d71709ebd120432a0ce535e72b9597cab1eb5bf/huggingface_hub-1.32.0.tar.gz", hash = "sha256:ed70a45498abe86039df7c2f4e5f7575de524be908d3840e8f828d5525eafd6a", size = 1038662, upload-time = "2026-09-17T10:27:48.049Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/cf/d98dd561d6d0d7b7d7a64d1563f8aaaa7c235daee41c1c9bcc3da62420ed/huggingface_hub-1.32.0-py3-none-any.whl", hash = "sha256:b0c7c80561969d9cdacdd55fce67ba9584cca0b9d4ea80957a3a5c1445fac5c8", size = 842906, upload-time = "2026-09-17T10:27:46.102Z" }, +] + +[[package]] +name = "idna" +version = "3.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/08/8eea9d4b8302028f3abb2c0813953f7aec26d33b7a8960ed760e65ff29fa/idna-3.20.tar.gz", hash = "sha256:a7db850025b95ded1eae8a46181a1a6c56c92c96f0e2b005d9ff8dc0210cab44", size = 216463, upload-time = "2026-09-17T14:11:04.752Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/a2/bb081bab032533a855d44de1d56f8e8426114ff1ba5d1f07a438a0a654f8/idna-3.20-py3-none-any.whl", hash = "sha256:ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c", size = 69583, upload-time = "2026-09-17T14:11:03.168Z" }, +] + +[[package]] +name = "iso3166" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/e7/4997ca315143cf3dc54ec116070c108b621677fa80083a499b50643237c4/iso3166-3.0.0.tar.gz", hash = "sha256:e567b55d169211d4d499c73307350da15df5d38248e60bae559609570c42ef55", size = 10295, upload-time = "2026-09-03T02:54:43.795Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/99/8e10f81806db750ee6acf11c980207c45feddd36066cb708328e5c5aceea/iso3166-3.0.0-py3-none-any.whl", hash = "sha256:990b1e6a433ffd89d67da8ca16f40a2af107aba1660b255a38dbd36ad221090b", size = 8949, upload-time = "2026-09-03T02:54:42.854Z" }, +] + +[[package]] +name = "iso639-lang" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9b/5a/49bbf16d155192255e7bb37e403b2ac360144992d0d112a865afc62e457f/iso639_lang-2.6.3.tar.gz", hash = "sha256:078ddb7cd0182dcc04367691acc8022ddf7158b6cb09f08f798af823fa864265", size = 319391, upload-time = "2025-07-23T09:04:53.568Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/c7/f6fd3db6c33a164631c39dce2ca26a3794e3abf91b875cc99a43a5565d88/iso639_lang-2.6.3-py3-none-any.whl", hash = "sha256:a6c2fb9f739dca180dc7f48b098880f303bcce2cdf93a4ca3152ed8bbbb94fbb", size = 324990, upload-time = "2025-07-23T09:04:52.221Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "joblib" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cloudpickle" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/1d/537ab090f302b838943a1b56497dd53059b9a9b46a074936470173a2e207/joblib-1.6.0.tar.gz", hash = "sha256:2ccc96785b12046c08fd6d55839c12857831b54a3c1673ffadd2f04bfc4eda03", size = 327903, upload-time = "2026-08-31T09:39:04.122Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/53/84099323c2ec4be98d935f63c033ac4151ee83836ca1050ede3b3aadf155/joblib-1.6.0-py3-none-any.whl", hash = "sha256:3dbbf9f6e4b592a2357b854608e980fe6390d131d7a82f011a377ef2ebef7aba", size = 306115, upload-time = "2026-08-31T09:39:02.298Z" }, +] + +[[package]] +name = "kiwisolver" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/07/bd78e6a8fae171ea041ef5bba3ed21a003522fa088834b069b1909981f30/kiwisolver-1.5.1.tar.gz", hash = "sha256:f1303ef2eec81262a4b708c3e858afe58d7c75ad91c1c05266eda7673369859a", size = 104395, upload-time = "2026-08-28T10:28:27.153Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/87/2d5dfad0daf17dcc18d98c48ed2332fc3f051cf599e60be6182a30dd4cf1/kiwisolver-1.5.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0324cd2567259b7a095f6cf18a52b0ffc6f3de9e69528ff1bc0e7a37bd43ff1a", size = 62337, upload-time = "2026-08-28T10:26:18.778Z" }, + { url = "https://files.pythonhosted.org/packages/08/c8/83e1624f15d6262b470dbcc80b09979fd4d5b2ea3ddfc6b6e3327e235726/kiwisolver-1.5.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:74ea337e0ec3f6f342a36a4f1b5cd94dd9affddcd28ba9aae2905af932ee8c6b", size = 64513, upload-time = "2026-08-28T10:26:19.909Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2d/827ec30eb07f528c08d8459ffb318ae91a56d793ee8acbea8b491f0ff906/kiwisolver-1.5.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ee9df1f0d77b9c6e94f4ac0fec533fbddd5ea3a327807f18d7b069ae019ded80", size = 66287, upload-time = "2026-08-28T10:26:21.078Z" }, + { url = "https://files.pythonhosted.org/packages/53/11/5c43a562529dad8def4b81e5e1877c612a7e0298105a5939b3b409d2079c/kiwisolver-1.5.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fc271a6f0a2126958f4090e5507b9da5848927dae331f8f763bd4aa642b3d2cd", size = 123940, upload-time = "2026-08-28T10:26:22.475Z" }, + { url = "https://files.pythonhosted.org/packages/64/db/9bd6c505c95128c258a55236bfbb3a7a3fb6023f863316b6d7d9f3c69052/kiwisolver-1.5.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9b3092d8992a1d69b7a59c3e39f35e1b9be327a17f68a7c35fc17329e337d6f2", size = 66493, upload-time = "2026-08-28T10:26:23.743Z" }, + { url = "https://files.pythonhosted.org/packages/e1/f4/b3007a3ed5c9be73f81161140684cf7d9bdb9c4b632f5f484d2a1c713fb9/kiwisolver-1.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c2306e8bb53601979fcb3fa09cc65e031876d9ae01eff2fcbcd7a84ef94d5bc1", size = 64720, upload-time = "2026-08-28T10:26:24.95Z" }, + { url = "https://files.pythonhosted.org/packages/a1/13/08188f0cafa3a800403e4ff62b9aad4e7a17f9c4c7e080dc8f18c64794cf/kiwisolver-1.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:18a0cfb124546a4c2e6087c5f3029c7f44b37c85b142e0ced71f73a7599ac208", size = 1475867, upload-time = "2026-08-28T10:26:26.393Z" }, + { url = "https://files.pythonhosted.org/packages/8a/3e/053bdc3c9abdb8f2606225eda398adca25c0c91ab90add8222a69db65ee0/kiwisolver-1.5.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34ec467940442c9943016fb2d4c81d1ba84351eeca2f1a78f8bc87f1ba0d414c", size = 1282865, upload-time = "2026-08-28T10:26:28.118Z" }, + { url = "https://files.pythonhosted.org/packages/5e/64/a44c341b36b610588cc2f1e89b3cae072a3119aa8be578e90987cd640751/kiwisolver-1.5.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a83ee7107df13abe42a54a6654670eef9bb39425cf2e27f65e0007465e1286ab", size = 1300865, upload-time = "2026-08-28T10:26:30.125Z" }, + { url = "https://files.pythonhosted.org/packages/60/5e/7e7d716dca38c714478b741257a5b4a321d9932b8d851551a136dcaf3984/kiwisolver-1.5.1-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bebb89489b279b2f5661bbbb2abcc87bcd4a46607bb4a5c966f04f1db6b8df9a", size = 1348071, upload-time = "2026-08-28T10:26:31.829Z" }, + { url = "https://files.pythonhosted.org/packages/10/1a/2b98fdda8bf45b7be317e48ed12393d44334394d315c74b81f4a14c0e31b/kiwisolver-1.5.1-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:509735237ae0d849e8a843551d423d2500d2e0a9ac1611a145658b29c0fb9f85", size = 992191, upload-time = "2026-08-28T10:26:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/b6/55/d893f5ede0e50f9e3fcf01f6015f42ec7d9cd221e26772701fe4a98745f9/kiwisolver-1.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:824c3d763a05ea9e9003610145186b0e9848c7584a5575c79bac5a8e7cd80bad", size = 2233854, upload-time = "2026-08-28T10:26:35.282Z" }, + { url = "https://files.pythonhosted.org/packages/b1/82/f85f6279555a6ee1639fef7bfe83adb037a03e11a6fc9eaa54b8d0380339/kiwisolver-1.5.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1fff05e239575b1481b6ed1a782f6fad616efbf1f0b1f44e6e85c4dfe426e483", size = 2330621, upload-time = "2026-08-28T10:26:36.9Z" }, + { url = "https://files.pythonhosted.org/packages/56/31/e11aea078f66fc2fffcc179d38ca90d9da97652a241b64519169742ba46a/kiwisolver-1.5.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0627b9bceb9c3cdcf12b8a18655eedfed2692b038df27423383c120d0b7dc2d6", size = 1982848, upload-time = "2026-08-28T10:26:39.01Z" }, + { url = "https://files.pythonhosted.org/packages/af/ea/2956b63bf5140ca46aa2c2818e6aa03e2d5754dd2fa41db1c6b28922940c/kiwisolver-1.5.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:8a708a47ade1fe19e8371d5da076bac0dd4b0a5a7985ad6c637f7f7e361b6baa", size = 2494850, upload-time = "2026-08-28T10:26:40.837Z" }, + { url = "https://files.pythonhosted.org/packages/11/d1/3829542258d8b3fc0898d221e7ef0e2c83eca0d348709bb8dbe54f3d4005/kiwisolver-1.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:007a5553dfc4f4e8d184f588a0200e2cd4b63a59cc8796df3c39909e679dc7a0", size = 2298067, upload-time = "2026-08-28T10:26:42.803Z" }, + { url = "https://files.pythonhosted.org/packages/4e/0e/49522e1ab5788cbaf63a26fbd3b851f9028616828c961b8a31b35cb96df8/kiwisolver-1.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:f4167e87b397f273dc2356fcf1eaf50a6bac51e6105f45103ef7129c8efb0255", size = 72282, upload-time = "2026-08-28T10:26:44.268Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b6/22e7ca5315d363e6f81c9f37c9472e12e7b298731e77c0428e6a911a2c39/kiwisolver-1.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:5c490db2168a508088f59140dd392556a54b8bd1048fc6383c8baff13c359673", size = 69855, upload-time = "2026-08-28T10:26:45.725Z" }, + { url = "https://files.pythonhosted.org/packages/30/8c/03a9cfbe871964c8758a816eb03ac96c806da2795a9a7cd9bf9648bfb594/kiwisolver-1.5.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:4d4ca09bf13cff792b1884f64b98ee6c2467930d632233be25c56b442d99f10e", size = 126289, upload-time = "2026-08-28T10:26:47.023Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e3/14ce3041ca79dff9c9d884ca00c7bf32374e76028a865a9ecd99b4f5a517/kiwisolver-1.5.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:44b8faef94f1857e77fa0238f3390ff1ac51d2ea20a487e2e452a59fd2b5f5ca", size = 67709, upload-time = "2026-08-28T10:26:48.268Z" }, + { url = "https://files.pythonhosted.org/packages/af/c4/45030471a66ec8ef042e9f96ffe1d522c9ab12da180186a0898966fc1385/kiwisolver-1.5.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2ae70bc59790d2af72a3f76f24b272403e135070340281108b447cb77ea70819", size = 65909, upload-time = "2026-08-28T10:26:49.523Z" }, + { url = "https://files.pythonhosted.org/packages/42/73/17dce073a6ae259bb32cf9d686c4079d2e538868bc45967462bf33df914a/kiwisolver-1.5.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:43844c1a7ad6d723d5b5b4c4fc7f5bd399c40e288120d16257c7c9e8765c6e85", size = 1584907, upload-time = "2026-08-28T10:26:50.933Z" }, + { url = "https://files.pythonhosted.org/packages/8c/84/ae3c75909f507283cbfcc7e916c7e822579ef962020b97e6882b27b4478f/kiwisolver-1.5.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22d5e5aaad6be121f2515765e3b1c444352cb8eb4c86510801db8f2e50757316", size = 1392474, upload-time = "2026-08-28T10:26:52.638Z" }, + { url = "https://files.pythonhosted.org/packages/34/31/8bcc83caad5bce8fa4577152389848bf6bc110e51e573a2b4e7c2aa34c89/kiwisolver-1.5.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3fa5855898f6d3d01b72ccd48a2d65cbdee301251603fefe34e2025bddba219c", size = 1405246, upload-time = "2026-08-28T10:26:54.248Z" }, + { url = "https://files.pythonhosted.org/packages/55/72/220345537d790cf4ae54f8acfff4b5cc2468e0702a384d651cf7a771c63e/kiwisolver-1.5.1-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d66a64dd5dec136040ec2ae94aa026a912ee60fdd45bc28d3db30037fd809e88", size = 1456099, upload-time = "2026-08-28T10:26:56.042Z" }, + { url = "https://files.pythonhosted.org/packages/cd/10/3725fd2398f66d18c34b4e0f81a8d03764cd4f4f089f58a527f0b4428086/kiwisolver-1.5.1-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:9e51c119992ea8820706871c30a4642ec76de20ae82f9b50b9a45517d8e9f810", size = 1073695, upload-time = "2026-08-28T10:26:57.658Z" }, + { url = "https://files.pythonhosted.org/packages/86/cb/28d6e09e66b93e4588b2e6b7d84d020ccefea09e2f4de788510a07efeab7/kiwisolver-1.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:70ed9a45c7484d2b30cdacf60d220f494a1763b9fec1ad03285c6553fa0889f2", size = 2335355, upload-time = "2026-08-28T10:26:59.202Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b3/a0f31d5e4e40af7dc97c36b8a74fdd3a36cf3c8bbd098da9a23466ff6a94/kiwisolver-1.5.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:98b208a7cc42c803445ef551d6753cc42a5ea13e9cab1ee66cd8b9cb70195330", size = 2426524, upload-time = "2026-08-28T10:27:01.181Z" }, + { url = "https://files.pythonhosted.org/packages/2f/c9/728f63bd58c72cafdc79fc306abeeac7391bec03b757a48dadeb30906521/kiwisolver-1.5.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c6834b92dd2428e2dd85ef3d85f723d3c12f20aaf43a2ddd4f944ca25d833408", size = 2063430, upload-time = "2026-08-28T10:27:03.06Z" }, + { url = "https://files.pythonhosted.org/packages/84/df/ce188b96f92f9a2c958231da140768918cba53c9713dc887b82f85462118/kiwisolver-1.5.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:5d142e352eb13facc7dd047489aebdff6ba78576c239f1ea04931979caaf0567", size = 2597513, upload-time = "2026-08-28T10:27:05.072Z" }, + { url = "https://files.pythonhosted.org/packages/69/d6/76947c8203768968382e5bd74d9cc95654746703a61ea53015f2c74a2e06/kiwisolver-1.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f9b1c4900736e489a812c529100de4b8fb617d4db075e931e213c57424b83d9b", size = 2394488, upload-time = "2026-08-28T10:27:07.423Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d4/14b21e4eb203c4d15425e8b6a2c625a320b4a1f2f7557eead63ffc30ffb7/kiwisolver-1.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:5978c3340f16a35c30f8ab2fa7bcf559973c55f1a5ef6970e1f621acf3c4db13", size = 75404, upload-time = "2026-08-28T10:27:08.892Z" }, + { url = "https://files.pythonhosted.org/packages/cb/f5/53157899fc7f45f76421b77b99eb1639dd0f83f26ff9d76300c96bb4a3b0/kiwisolver-1.5.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ca307d6c259e5c98d3cb9ade55342b47a6839762caf2536f3d7b46ee660cc82e", size = 72946, upload-time = "2026-08-28T10:27:10.944Z" }, + { url = "https://files.pythonhosted.org/packages/75/62/f786c3a27f181fa339d851a77e266d208e776b9883cabc40a5b041a31b5a/kiwisolver-1.5.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:bb7c99f0673c03017a3ee01e54a5c2617a05468b11eabe513b0080e063ed95b1", size = 62420, upload-time = "2026-08-28T10:27:12.308Z" }, + { url = "https://files.pythonhosted.org/packages/02/cd/58a91ed25fbad0facdf503297b03768efab04bdf3141e5e3b49a34be7443/kiwisolver-1.5.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:0d8924877ce22e17326a99a418c3c82037da078df3c6a260b13eca677444e6e7", size = 64577, upload-time = "2026-08-28T10:27:13.502Z" }, + { url = "https://files.pythonhosted.org/packages/f6/5c/d501ef5a0958b226eac28306d24d5e5f114be0ace50e19cabae7b6b3b197/kiwisolver-1.5.1-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:534f02c1abb31ed6dbd3515545285c330b2f12d00fdb1fdb71658b9ca5a13a6a", size = 66284, upload-time = "2026-08-28T10:27:14.813Z" }, + { url = "https://files.pythonhosted.org/packages/a3/a6/8fbecaf4fc18c02f31f05e47a84c010a80e3ec391ed2f0bdade1d62b5954/kiwisolver-1.5.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:cea20da04494e662b83c872683bf4ff2345206043d036315ed0e924b652e7294", size = 124031, upload-time = "2026-08-28T10:27:16.193Z" }, + { url = "https://files.pythonhosted.org/packages/7c/c6/bf3090d2983b4204347cbdbe952116e7c3b2abf62b4e33e50167a13e75ee/kiwisolver-1.5.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:7fd82debf43c6acd0a94359d232f6bb516ee13f269a7993736a9ac9f988bb5d9", size = 66489, upload-time = "2026-08-28T10:27:17.506Z" }, + { url = "https://files.pythonhosted.org/packages/85/de/562dddef55fdd7c291da8626d6619e72b5fc0870e6ccca0e149a5731e7f3/kiwisolver-1.5.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:18170a77ddfecf40ec60d0928268dc95880c881864e015a8f34094ed18b9b9ad", size = 64806, upload-time = "2026-08-28T10:27:18.673Z" }, + { url = "https://files.pythonhosted.org/packages/89/b1/ba7b9c0164ce1cf62bf2872db63b8483289cf0f3110d6f9390eb09e409ed/kiwisolver-1.5.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ca7f6fe0f37ca978a1e5eb7a3a68e6413f417e78e838324947ffd420202b198b", size = 1482211, upload-time = "2026-08-28T10:27:20.039Z" }, + { url = "https://files.pythonhosted.org/packages/13/dc/34da54efb4976616d45c20aae32d70e89d6e7395ed908029154d1609ef22/kiwisolver-1.5.1-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5b973887ff782cfd6b67c9904ad8ca542e0bc5e4961503408b423b5a688b4d38", size = 1283739, upload-time = "2026-08-28T10:27:21.82Z" }, + { url = "https://files.pythonhosted.org/packages/5a/3a/30ffb62bee646e266e98a1b5cd276d9c75b6116fbfcb87c1190838c1b6df/kiwisolver-1.5.1-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f76fc85bd054c806960f917ec0f329e24e436f1712267d90588e4c39890caa63", size = 1301681, upload-time = "2026-08-28T10:27:23.876Z" }, + { url = "https://files.pythonhosted.org/packages/a9/8d/13c70be22a8506880b35fdc38dca36629613bc493405c79f4037f2cd2bb9/kiwisolver-1.5.1-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:828f75af2b0080c8a972e75f649ab46af008e92c6104a57a759157200b835b75", size = 1349159, upload-time = "2026-08-28T10:27:25.899Z" }, + { url = "https://files.pythonhosted.org/packages/82/0e/993972b8ec6767f47cd69818fb3a5ff14510557d29f7d1a839be7574fa1b/kiwisolver-1.5.1-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:431dc224a1a92a5c8f582d96e505196a3b5997a7271076678da2dfde67b77e9a", size = 997613, upload-time = "2026-08-28T10:27:27.507Z" }, + { url = "https://files.pythonhosted.org/packages/36/82/ca26eddd2eda2420dfc56693449c1f821f78b485da9cbde9904c03af3f93/kiwisolver-1.5.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:61e9a64c7635095a6bfe483e2ff055d437c59bd45f3617a228b37277f0185d62", size = 2235109, upload-time = "2026-08-28T10:27:30.113Z" }, + { url = "https://files.pythonhosted.org/packages/c7/84/97d920881e10840b8d7c7185620298e3e4c88820b05514e3a15a258b08a6/kiwisolver-1.5.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:3c24cd69455e1b00ddf770c13b6e2c33e07d6dc3f2d34add0bf9277c5c6bbd46", size = 2331207, upload-time = "2026-08-28T10:27:32.795Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ce/34d74b8f25acc58800f4c09268371e8d6159cf0f1206f1e4dc7835629b48/kiwisolver-1.5.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:27add358abe374ebaa3b8763ef380bc99051b5a4b18d94878366a9e4f59efef0", size = 1986696, upload-time = "2026-08-28T10:27:34.628Z" }, + { url = "https://files.pythonhosted.org/packages/0e/01/f892644014612527aef7031d3306a2ffc60b3cb044f802c1561f8e5e14f3/kiwisolver-1.5.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:255605693a483db7bd5c79f60437f7bf658f7f520d61aa42722e32257c941951", size = 2496400, upload-time = "2026-08-28T10:27:36.818Z" }, + { url = "https://files.pythonhosted.org/packages/32/6d/d8284e66e697026536e5f418b9cfe56567bffd3c775e3ecfbae373605854/kiwisolver-1.5.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:7d38b0c279c3032e8c9cc013b405c6df8e1668dbf15465779aa7f15f61201812", size = 2302967, upload-time = "2026-08-28T10:27:38.803Z" }, + { url = "https://files.pythonhosted.org/packages/46/0a/69a355e27f32ba50d5b6369949b6a1702e122f5277c89bc76d452b81c1c4/kiwisolver-1.5.1-cp315-cp315-win_amd64.whl", hash = "sha256:958254518717542d02d0688d0d20cbf771da5e415e6f49543f92481c850a4540", size = 72283, upload-time = "2026-08-28T10:27:40.491Z" }, + { url = "https://files.pythonhosted.org/packages/ef/d8/7a95be90c33dcdd52204d4aa6384d731443225b887283bbd8b61e7931f6c/kiwisolver-1.5.1-cp315-cp315-win_arm64.whl", hash = "sha256:da3275833be0edbaf4830fae08bae3dc7219f40ce0c37eaa6c25825957e06612", size = 69860, upload-time = "2026-08-28T10:27:41.835Z" }, + { url = "https://files.pythonhosted.org/packages/31/f8/9bc493e7f5707788ba7f621902c68f82dc3a7ba03c78fbd337b026cef1ed/kiwisolver-1.5.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:470d420f98d368d6f010633a20659b544c5fdfa5329e6b70219f2ef08fd4a7ef", size = 126336, upload-time = "2026-08-28T10:27:43.379Z" }, + { url = "https://files.pythonhosted.org/packages/d1/82/3aea86b3f99712db825e9ac5631bf99571e818a8b8961ff98cebd798413e/kiwisolver-1.5.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:83f78128fa28705fa85d01c59771c72fe81c11bd0e6155edbb9f818983a7d761", size = 67698, upload-time = "2026-08-28T10:27:44.613Z" }, + { url = "https://files.pythonhosted.org/packages/84/7d/8daafc5d2e7f9c47a4f78f8865d86d2a9cf399c2a85f86c44a993594410c/kiwisolver-1.5.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:9506e892bcc3b409831d363c6f53e5985e1c8d1f6f6b0256d00358684ff85378", size = 65945, upload-time = "2026-08-28T10:27:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/3d/c9/51dc974d9130da70a8c47a96160123443d387ffe1b6b833d6f91d9429339/kiwisolver-1.5.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cea90547bfd93807e0013a004dc76552be44fad3bc1cc2b38610a9e889ed098f", size = 1588030, upload-time = "2026-08-28T10:27:47.678Z" }, + { url = "https://files.pythonhosted.org/packages/e6/86/f3e1a730e7a995149d8d3ff9e313b6d8a17b2cf1d98a8eff139dc30463fb/kiwisolver-1.5.1-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e8e4d953faaded9ec7ede36824e9814082d22d4c7b1eafbfa079ecba8cd0d076", size = 1390760, upload-time = "2026-08-28T10:27:49.676Z" }, + { url = "https://files.pythonhosted.org/packages/4f/3b/8ba25a2b5a0d2375e046f1b72de5179513f0be95aba6e7b094c89303929f/kiwisolver-1.5.1-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e9c01d3dd7ceba4d1d436cc021d40d592466e40b9bc7f5d83dc4e98a5c9cd8c", size = 1403279, upload-time = "2026-08-28T10:27:51.242Z" }, + { url = "https://files.pythonhosted.org/packages/18/d0/278d5cb8be812740027d5ca0a7eda0c375488a88d6dce0fa60fcc2591ad2/kiwisolver-1.5.1-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:37f801b5d7cc0e5a548921308e059fd2b057bb42972b591cfa3049f95423c4ed", size = 1454429, upload-time = "2026-08-28T10:27:53.213Z" }, + { url = "https://files.pythonhosted.org/packages/94/37/bcbab41063ec284c1d200efe5087cf087798c2f8916960aa8a20dd303290/kiwisolver-1.5.1-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:e68e151428b5384f766cd25739bf77c7e4a3dc93b5ded7a12118d9fbfdf78ab6", size = 1073225, upload-time = "2026-08-28T10:27:55.089Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c5/ab79dcdf5ae28909a51210ae0a1c579e97ff997b3466414f0d04c0994583/kiwisolver-1.5.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:8f8fddb8e323bd6eee4e54e69a39243beab22689070f4c66b472c4cc88bb89d8", size = 2334335, upload-time = "2026-08-28T10:27:56.78Z" }, + { url = "https://files.pythonhosted.org/packages/8d/8e/71d047468a189041d9c93f3b76844b924f9793b188c44bd149fa258912da/kiwisolver-1.5.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:3cc210010fd2f438a3ed430b45f1b501fd13a8618bf984dc2c5ce5b69b78752e", size = 2424982, upload-time = "2026-08-28T10:27:58.639Z" }, + { url = "https://files.pythonhosted.org/packages/7d/37/1347461bbea6d0e1f0580b94ef603b18e72c2be5f667fa1653867361a00b/kiwisolver-1.5.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:b5664603a253efd3a75716d793d1d3a6a82723b61dc6db767b2460bbbeec4c0f", size = 2062857, upload-time = "2026-08-28T10:28:00.407Z" }, + { url = "https://files.pythonhosted.org/packages/1f/87/c7f0976c9cd0d127643351bc0c9929e0b8899d7f49d4ec238cd909e39c42/kiwisolver-1.5.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:a7b85b2cc6ea45e5f7e8c9a30bc9fabd47cda09106cbb4b967335c3e6c43b69d", size = 2596022, upload-time = "2026-08-28T10:28:02.183Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9a/59a6f6ae6f938c15076be2c21b6cedea973d71bb1349ec84fa485fab82cf/kiwisolver-1.5.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:ab620eb663952455271ac37f9aaad86b73c969c02f11f53cea405b38e96a4300", size = 2395634, upload-time = "2026-08-28T10:28:03.977Z" }, + { url = "https://files.pythonhosted.org/packages/e9/2d/8982c1fb7926da5bb7ed60318c3665b5c3f941447271ac982960a11b8637/kiwisolver-1.5.1-cp315-cp315t-win_amd64.whl", hash = "sha256:cb6fae641357ed2f6e533c0d3c6504a4a5703621a50c89459e46051d56b61140", size = 75379, upload-time = "2026-08-28T10:28:06.307Z" }, + { url = "https://files.pythonhosted.org/packages/07/78/ba7b6dfa1708b82b373ac056928a30c545d5c1a627df9839dcec3c6c1881/kiwisolver-1.5.1-cp315-cp315t-win_arm64.whl", hash = "sha256:b390aec180a7c054919c04898835e1c77bced23ea8383eb2c570213bf25d1a86", size = 73011, upload-time = "2026-08-28T10:28:07.578Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "matplotlib" +version = "3.11.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/c8/9aa712a0afb882649424dd8de8ad9aa6235e796e84c6052e8f6dc1598d0d/matplotlib-3.11.2.tar.gz", hash = "sha256:cec596316640f2b394b8f0daa0ea61a8eae82d017b620b9f202befb972a59ea4", size = 32660610, upload-time = "2026-09-11T19:05:31.214Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/b4/4facdb700bc236e4c676495ca3798d8134ab8668cbfe0f6b2e9ebf962a38/matplotlib-3.11.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c9721f81275499da1feeb36a2cf8192ea086283b3bd16b7dc4c9d7aedb7396d6", size = 9478976, upload-time = "2026-09-11T19:04:00.12Z" }, + { url = "https://files.pythonhosted.org/packages/4c/a0/bba05f0a25bfeb0475c2f2a87958b31103aa6b7a5386017afb1a96212825/matplotlib-3.11.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1a3040b209f3968b4e84161df7b174f07a9fad33b0f2d7e48ea3bbd3075e2863", size = 9307932, upload-time = "2026-09-11T19:04:02.976Z" }, + { url = "https://files.pythonhosted.org/packages/d4/42/81d5cba4bb39b41b0998efc880e129f2d7cdb94256ca49678fdcd9c21be5/matplotlib-3.11.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf3fe71fbfb8ec0e310e0bc8537c3405a01f38f25f9394ed2135e6202fed542b", size = 10674370, upload-time = "2026-09-11T19:04:06.912Z" }, + { url = "https://files.pythonhosted.org/packages/29/5e/52f56f93d5b20815ee0ae352f7a38eff25580edb180b4fa7df87cfeba68f/matplotlib-3.11.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8c8255de28f986d935a64c9ca71c0ec2d2f41d355691f5ea684725dc91413f71", size = 10954597, upload-time = "2026-09-11T19:04:09.948Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ae/f8918a1b564db49c53cd603eb3c8748c5767e4ce0fb2cf1d7c38653e4c5d/matplotlib-3.11.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a8756cc73d9af9a7fe0deb54ea2e75ef73b01d9e575877e72acad5458e660943", size = 10812583, upload-time = "2026-09-11T19:04:12.887Z" }, + { url = "https://files.pythonhosted.org/packages/ea/61/4315ef0d63937fe56f451887b4a0be3b8e8b22cf1d92a8d157caac54570d/matplotlib-3.11.2-cp314-cp314-win_amd64.whl", hash = "sha256:ecea603dd2fbf8242fd31a305a8b12a4ece2de28096870c65fdd0d1e35b8d9a6", size = 9505972, upload-time = "2026-09-11T19:04:15.788Z" }, + { url = "https://files.pythonhosted.org/packages/d5/00/02398b0a1a62ef73d9af0a957fe1773363eec9a6ca7e433c72ae2790fbce/matplotlib-3.11.2-cp314-cp314-win_arm64.whl", hash = "sha256:01dc8eaaab5a9fce9ff615eca82345728f289e4715b186ee10c6d85272fc26bb", size = 9184534, upload-time = "2026-09-11T19:04:18.691Z" }, + { url = "https://files.pythonhosted.org/packages/ec/c5/1e6ca10baa7e04f113c37856aadb4adc3dbb1c55fc7da6dc830bba1292d7/matplotlib-3.11.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:79a258f58253dfa025af80a9e9bb228d75fced007f0e93ae7423fefbde81a74d", size = 9526415, upload-time = "2026-09-11T19:04:21.39Z" }, + { url = "https://files.pythonhosted.org/packages/e0/93/7561727af07ccc84747953c6a33eee3981cc436d04f465032e707ca0e429/matplotlib-3.11.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c0b83f044ce10a98027b105b3931548719a6e8c7ef986b4362651e0b5367c8dc", size = 9361064, upload-time = "2026-09-11T19:04:24.107Z" }, + { url = "https://files.pythonhosted.org/packages/c1/40/ce270ef2a6794d94a409fe28b8dabedffc07c07f9e5dbb89e0f605bd157d/matplotlib-3.11.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e43b188f0a5b75447bcc197728258166aa64365770ed1caa36595a5e1ca4bbba", size = 10684626, upload-time = "2026-09-11T19:04:27.201Z" }, + { url = "https://files.pythonhosted.org/packages/45/46/396e0307dbf1c1f2d0a3654caa6dbc780dd5379f5f11257369cf8d21d9fe/matplotlib-3.11.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3304eb5a59442a8867f6920d484591c0fa09ffc29e9260be2feec3351e25869", size = 10960602, upload-time = "2026-09-11T19:04:30.254Z" }, + { url = "https://files.pythonhosted.org/packages/1c/97/4defb84695477340aa88b27c9482cc1ca4de11f36f66b6c8c0ddd685def1/matplotlib-3.11.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:02329432ae5c6af87cf208ee575b701d698bdf0b1a3bb28cc6d53c36e967e575", size = 10822603, upload-time = "2026-09-11T19:04:32.964Z" }, + { url = "https://files.pythonhosted.org/packages/7d/e7/eab54551c1ec6b72dcd678a078b6c6da8d4c85ec1ff0016e81fe52866304/matplotlib-3.11.2-cp314-cp314t-win_amd64.whl", hash = "sha256:f2ac30cf5eb5dff1b584627ae0b0e1186551a4f69ae3c75073911da497a29170", size = 9551206, upload-time = "2026-09-11T19:04:35.811Z" }, + { url = "https://files.pythonhosted.org/packages/4e/0e/04698032cb4d8fb1e30d8ffec5ded20f6f582b03c8c58b2385c95245f158/matplotlib-3.11.2-cp314-cp314t-win_arm64.whl", hash = "sha256:cf41ecd1b0c0b6f7177ed965a54c2afbe888715c7cf6054dc12d53bc1494002c", size = 9234977, upload-time = "2026-09-11T19:04:38.972Z" }, + { url = "https://files.pythonhosted.org/packages/44/a9/ca827c184b87364378964e36e7c0ae23651d146fdbc4000635205490cf82/matplotlib-3.11.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:894a9cbbecbe30ae6787d464df2e8fc7a8d475cfc68f87c3029f7c11152899b3", size = 9478997, upload-time = "2026-09-11T19:04:41.914Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/01aaafc9c3159f3fae9a65bbcddaa4a6d4d72b0aeffdd636d7f6d00a5c8d/matplotlib-3.11.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:bbf1062991d826ed27e2144f3afa4461afbb8ff56e8f703043e191a8163b1ee9", size = 9307947, upload-time = "2026-09-11T19:04:44.834Z" }, + { url = "https://files.pythonhosted.org/packages/1e/a0/6aa72c7cd7cf4dfac652744d7a3310007cec3ce8e5ab9be607bec7096471/matplotlib-3.11.2-cp315-cp315-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:399fef672f7046ef7d6a57572b2a6f9845f3f5afcff04e7b2df7a363a9f42190", size = 10674370, upload-time = "2026-09-11T19:04:47.745Z" }, + { url = "https://files.pythonhosted.org/packages/a1/97/d7e90225ac145046787a2ee0fa4cdc7e4d5cb6772ea232130b10f8a4095a/matplotlib-3.11.2-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc82dde2a0d3e3ad472edce04897ad7146b8d8bfd1df8a32992eebb81af18fdc", size = 10954581, upload-time = "2026-09-11T19:04:50.712Z" }, + { url = "https://files.pythonhosted.org/packages/58/18/89cf056a9d2cae01f4b8baf01c7e809d613244fcdfa2a2acf28c1e0d79fa/matplotlib-3.11.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:930efb28f59fda124e39265d177bab302625297bb147d2910de725a2fc2aef54", size = 10812605, upload-time = "2026-09-11T19:04:53.552Z" }, + { url = "https://files.pythonhosted.org/packages/9d/4d/c61b9f4c34af802d4d84e58803e009013d626b5f468bafe1416131863b5b/matplotlib-3.11.2-cp315-cp315-win_amd64.whl", hash = "sha256:3da3bc0cbf7245e7db72cc6d29d12c5abef72cb73059c73b945f14e3545f3eb2", size = 9506068, upload-time = "2026-09-11T19:04:56.519Z" }, + { url = "https://files.pythonhosted.org/packages/03/7b/047f2fa8708d47430d8e7fa45e9fffb0aee5d4e300f978e087be2ee11fbc/matplotlib-3.11.2-cp315-cp315-win_arm64.whl", hash = "sha256:f25446b2981717dca9786bac841cb3fd7efb568e3e3c755dd980481c5cb9228d", size = 9184576, upload-time = "2026-09-11T19:04:59.318Z" }, + { url = "https://files.pythonhosted.org/packages/03/6e/ad9c5989950785a98642667df265a47c6637e924cb69b5dcf68c3299ae7c/matplotlib-3.11.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:fea03cf56568cc1cba08b470be6a0559e71c3a5b688d54b7179bb35ba23d0821", size = 9525988, upload-time = "2026-09-11T19:05:02.304Z" }, + { url = "https://files.pythonhosted.org/packages/a6/c3/25c61701fb655dd412428b15eee2591ce554cdd593e39a045a153373f428/matplotlib-3.11.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:254d4ddb2fa8df3b4c689c0c306063aee10521df82cfb438185e499c75fe37c1", size = 9360774, upload-time = "2026-09-11T19:05:05.092Z" }, + { url = "https://files.pythonhosted.org/packages/58/5a/4552878fce8f9d249a5e264c16f5c267c27eac08fb039fa3e207a06feff5/matplotlib-3.11.2-cp315-cp315t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e60cf3047a51edecdc4535a9196bbd6a732936b8e9f8184aabf4d16165884aaf", size = 10685892, upload-time = "2026-09-11T19:05:07.686Z" }, + { url = "https://files.pythonhosted.org/packages/af/dd/b3b19ec0124fc4aafd8a4b3bae859c562a7ff0fd8ae3b2099947f78bde19/matplotlib-3.11.2-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eb3712dc9b464793de0a4e42a7313d50293c751f94bddaf7332a1bc71bccdda9", size = 10964946, upload-time = "2026-09-11T19:05:10.943Z" }, + { url = "https://files.pythonhosted.org/packages/7b/30/687ccce22f66a57fed85942450e88062773bcbf1a42914e70c7148ec71dc/matplotlib-3.11.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:75b6d88402770e181b5d06a67dda4129c31da7d05004d63a21c310ec78d1b83c", size = 10824960, upload-time = "2026-09-11T19:05:13.9Z" }, + { url = "https://files.pythonhosted.org/packages/d3/34/117fe35a8d05054b4b34d2d29287099927c24c3841d36e06d9fa2f20c1cf/matplotlib-3.11.2-cp315-cp315t-win_amd64.whl", hash = "sha256:a6939df7567114b6bac7f4c5e06c84a67f197c1b2f2e4b234d4eecb3bfec9482", size = 9551204, upload-time = "2026-09-11T19:05:16.48Z" }, + { url = "https://files.pythonhosted.org/packages/63/5a/9f440e7bec8b80d0af2a65d1165b2f4e718982dad785531f62255d9ff19b/matplotlib-3.11.2-cp315-cp315t-win_arm64.whl", hash = "sha256:d480038c83691532ed52ff3147db51fa902fc78cb2d8349993a1cdb684435bff", size = 9233946, upload-time = "2026-09-11T19:05:19.063Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mediapipe" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "absl-py" }, + { name = "certifi" }, + { name = "flatbuffers" }, + { name = "matplotlib" }, + { name = "numpy" }, + { name = "opencv-contrib-python" }, + { name = "sounddevice" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/56/911762884caba685dc8156d0136c58196a228c2b447023cfa0cfdb32f6c5/mediapipe-1.0.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0a9fb67957f7d28e84f485e9c6716a43367b3f6f07170f31c3f72cac1addd031", size = 33662903, upload-time = "2026-08-14T18:23:54.891Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/515c6ebc98db21484b2b93b7403464d08fb7861b6430752801bc75d29372/mediapipe-1.0.1-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:d6050e773dc6698eb86324090f61af1ccab28a6f1e9f77d98fe0611cef707997", size = 35841411, upload-time = "2026-08-14T18:23:58.093Z" }, + { url = "https://files.pythonhosted.org/packages/2a/58/bdd5bada89d7a132375df05e962bf702c148b47043dca98d820d9395152b/mediapipe-1.0.1-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:121522251afc3c135e4b7b0c341dd5e050ad1ec87631127484f3c389ae385044", size = 37881482, upload-time = "2026-08-14T18:24:01.091Z" }, + { url = "https://files.pythonhosted.org/packages/22/71/42365b0aec2a96dfbeb3441220fe8dccd9a833f36adfecf3aa9f211c449b/mediapipe-1.0.1-py3-none-win_amd64.whl", hash = "sha256:96dc9de6bd04a6315ef424fda5c48e0929f2d78317295e75bc32c0bceeab517b", size = 20103114, upload-time = "2026-08-14T18:24:03.861Z" }, + { url = "https://files.pythonhosted.org/packages/49/47/8a901eade7352051ae4d7b0b070ad8a84bde9cbf3092afd69088982842bb/mediapipe-1.0.1-py3-none-win_arm64.whl", hash = "sha256:4bbbb3838a99f7fdcd3cb0e071560120df45ddc48c1ad097ef1457f8600e0e77", size = 17700960, upload-time = "2026-08-14T18:24:06.172Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "narwhals" +version = "2.26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/68/5351e34623d253423240ea7de3f8fc74fa8ab14b1ab3c0ec4ac8997413c9/narwhals-2.26.0.tar.gz", hash = "sha256:6b9cadca82f375c7e4cf584fdc86ca25da54827307a9c58f94547ee6104b82dd", size = 686970, upload-time = "2026-09-08T13:32:08.964Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/b5/1b84b2c784db76d69442334bc8b8748c840f13ca53be086f4f250ad4a0bc/narwhals-2.26.0-py3-none-any.whl", hash = "sha256:29326d74f107c347fd1009bd58e38d9f7c7c5b51e6de97bc93dbc325d9038b54", size = 474034, upload-time = "2026-09-08T13:32:07.159Z" }, +] + +[[package]] +name = "networkx" +version = "3.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, +] + +[[package]] +name = "numpy" +version = "2.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/80/db0b4559e57ec36362bedbb05530a87fafbcb6067708c946967a41d449e7/numpy-2.5.2.tar.gz", hash = "sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860", size = 20773161, upload-time = "2026-08-09T13:48:27.962Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/f8/c3b222bf075b50afd8e949a07a15c4b312a4a84bd8102a332bcd953cbbb4/numpy-2.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1", size = 16885180, upload-time = "2026-08-09T13:46:03.939Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/2c1d4b1987795a92b5bbf7c24fe249ab96aa2573ab0d7604802c189d7b86/numpy-2.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8", size = 11907878, upload-time = "2026-08-09T13:46:07.045Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ee/d08226fc858044355983a6e5b94f08ff6f3969e0a2b160a4a89f0ddb3445/numpy-2.5.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323", size = 5354922, upload-time = "2026-08-09T13:46:10.04Z" }, + { url = "https://files.pythonhosted.org/packages/94/f0/6d3d933056440ebbc5e6bad92065fc6c26a48a84a36b1208580e94eea76c/numpy-2.5.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e", size = 6679168, upload-time = "2026-08-09T13:46:12.275Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3b/ecd49dd90033cceb2704d88ca905d4d7d89b0e8c739608754ffd325fa820/numpy-2.5.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65", size = 15624501, upload-time = "2026-08-09T13:46:15.322Z" }, + { url = "https://files.pythonhosted.org/packages/c7/99/461bd36dbdfac6c1c53efa370bd55a83227542d0d118f1677dbf1a3dacd5/numpy-2.5.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee", size = 16713701, upload-time = "2026-08-09T13:46:18.949Z" }, + { url = "https://files.pythonhosted.org/packages/f9/9c/2b251df9e8a5d647b62b0cbc1b90a91850c1cf4859ecb532fd0b4eacff6c/numpy-2.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68", size = 16986065, upload-time = "2026-08-09T13:46:23.006Z" }, + { url = "https://files.pythonhosted.org/packages/8f/25/20de43f53ff1390534a124475055a19f01fe10c920a0fd11b8e18d6d6052/numpy-2.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb", size = 18470031, upload-time = "2026-08-09T13:46:27.102Z" }, + { url = "https://files.pythonhosted.org/packages/56/5e/0c577ca308d6da5eb79b546ba10bbe5b60148192194e2da060913b1de4f1/numpy-2.5.2-cp314-cp314-win32.whl", hash = "sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98", size = 6121028, upload-time = "2026-08-09T13:46:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/15/5c/7bcbd5b11f94199073320410cddcbb80cee62415bfeb540874b265c2d922/numpy-2.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d", size = 12597627, upload-time = "2026-08-09T13:46:32.886Z" }, + { url = "https://files.pythonhosted.org/packages/87/bc/4d0b06fba0da90ccc75af62823cb9dcedb6c9ea0cffa058cb2c9ee773a77/numpy-2.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf", size = 10680414, upload-time = "2026-08-09T13:46:36.036Z" }, + { url = "https://files.pythonhosted.org/packages/cd/17/f429aac9dc08833a0d0f188eba38c532a751b1a1f2ca6018a37b455cb321/numpy-2.5.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1", size = 12026967, upload-time = "2026-08-09T13:46:39.084Z" }, + { url = "https://files.pythonhosted.org/packages/ca/9f/d0849de96a2a4ceaa16662f18ee13eaa9c0aa418269fdc8c4857c56b11da/numpy-2.5.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f", size = 5473874, upload-time = "2026-08-09T13:46:42.075Z" }, + { url = "https://files.pythonhosted.org/packages/89/3c/8df216d4a4a5422a3de045301cf7df8ea47286d76f5cb7160b0128ac26b7/numpy-2.5.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf", size = 6789276, upload-time = "2026-08-09T13:46:44.387Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3a/20d7e9891c4ddfadd6ff8d95bf4b29f353d8e1770553de2099880551dfb9/numpy-2.5.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4", size = 15659154, upload-time = "2026-08-09T13:46:47.538Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d6/f3aa3d2688bf501b858835c6bd087ae9b51a56ae6fca8e2b0990abd177af/numpy-2.5.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce", size = 16748909, upload-time = "2026-08-09T13:46:51.442Z" }, + { url = "https://files.pythonhosted.org/packages/7d/8f/1c5cae8d2baf86ab802ae97a00be55bc7e21ebc11b12bbc33376c5f05342/numpy-2.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26", size = 17027685, upload-time = "2026-08-09T13:46:55.095Z" }, + { url = "https://files.pythonhosted.org/packages/5c/27/71d3467404aedc1c24ce79610f91b52b0b0f466c43a701aa56fc75c145ab/numpy-2.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac", size = 18501181, upload-time = "2026-08-09T13:46:59.09Z" }, + { url = "https://files.pythonhosted.org/packages/14/2f/42921d27c40aea7e077f4a423ae509fd9220b028cd787bafefd8ab2b3a5f/numpy-2.5.2-cp314-cp314t-win32.whl", hash = "sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba", size = 6271085, upload-time = "2026-08-09T13:47:01.903Z" }, + { url = "https://files.pythonhosted.org/packages/75/e6/bad5f5d56de9b1971bac959963dda276d35c40f1854475005434bbe08692/numpy-2.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884", size = 12787971, upload-time = "2026-08-09T13:47:04.963Z" }, + { url = "https://files.pythonhosted.org/packages/df/05/f608795cb34391acd67e38d94a3c36abd8d8576293a3a80727d7595c372c/numpy-2.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e", size = 10750306, upload-time = "2026-08-09T13:47:07.976Z" }, + { url = "https://files.pythonhosted.org/packages/33/c6/28de0191c5f82b7d42a0a51390ba98587048aa93a39fafb05bdbe6e8d00c/numpy-2.5.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f", size = 16885274, upload-time = "2026-08-09T13:47:11.439Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d1/973ca116000d244897e468ea1aff30b589e5022e3c8744b71706fe33bd57/numpy-2.5.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842", size = 11907846, upload-time = "2026-08-09T13:47:15.128Z" }, + { url = "https://files.pythonhosted.org/packages/78/d9/8c4b3937ef204cb2fd88d389ccd0f265a2ffb11f35a01d2064cf46714bd6/numpy-2.5.2-cp315-cp315-macosx_14_0_arm64.whl", hash = "sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6", size = 5354892, upload-time = "2026-08-09T13:47:18.07Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/b6ee65ea2999fdb7023935e108e6fb776ee4082aa15f159acfa857e578c8/numpy-2.5.2-cp315-cp315-macosx_14_0_x86_64.whl", hash = "sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8", size = 6679309, upload-time = "2026-08-09T13:47:20.456Z" }, + { url = "https://files.pythonhosted.org/packages/43/f3/acb18d8b137a393c8e7803a8c994c9e64bde3930692a69d826993113a159/numpy-2.5.2-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69", size = 15625850, upload-time = "2026-08-09T13:47:24.365Z" }, + { url = "https://files.pythonhosted.org/packages/a9/bf/a8e9bb0db815a0e265b5744ebedd3af0bd5faad8604e5b50a1cd012f3c91/numpy-2.5.2-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab", size = 16713664, upload-time = "2026-08-09T13:47:27.965Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c3/6e913736b3dd6582344af32418b5fb9dab34282e8a8174ae1d54ceb0fc13/numpy-2.5.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514", size = 16986749, upload-time = "2026-08-09T13:47:31.541Z" }, + { url = "https://files.pythonhosted.org/packages/80/09/7d3b23eff5c7428ef6c01e6f7052bb60d504c4d33e317b36b8959c24ad97/numpy-2.5.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710", size = 18470495, upload-time = "2026-08-09T13:47:35.364Z" }, + { url = "https://files.pythonhosted.org/packages/a5/a4/68a321d825374f6eb677ffe8ef8c6b9a328304e6fd2e39d9530822776607/numpy-2.5.2-cp315-cp315-win32.whl", hash = "sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617", size = 6120696, upload-time = "2026-08-09T13:47:38.561Z" }, + { url = "https://files.pythonhosted.org/packages/c8/23/deafbb1700f79fae9cd1e91220f133d124cc267de1b584da3fbf6db2f6cd/numpy-2.5.2-cp315-cp315-win_amd64.whl", hash = "sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7", size = 12597324, upload-time = "2026-08-09T13:47:41.401Z" }, + { url = "https://files.pythonhosted.org/packages/33/cd/3272ba105e3bbbdaeb11357eda31e7a6825ffe159e8171665660299a948f/numpy-2.5.2-cp315-cp315-win_arm64.whl", hash = "sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788", size = 10680466, upload-time = "2026-08-09T13:47:44.873Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0e/58370637b1bb70a5c9ce2b43f4b521ccb224e36ccb76a6596b17ae4b447c/numpy-2.5.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b", size = 16993947, upload-time = "2026-08-09T13:47:48.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/93/2abcb807712b289d6d60fe4cf30532f98974a8396d885650f3ba5a13026e/numpy-2.5.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e", size = 12025331, upload-time = "2026-08-09T13:47:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3a/2898e003a5fbaf87e76c039b4ee1f5eb390471b4ffe74887c1f34c4e791e/numpy-2.5.2-cp315-cp315t-macosx_14_0_arm64.whl", hash = "sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a", size = 5472336, upload-time = "2026-08-09T13:47:55.403Z" }, + { url = "https://files.pythonhosted.org/packages/61/a5/23f69d07c544597b29758b31b55c27dc9d541012a2c1496189fef702aec2/numpy-2.5.2-cp315-cp315t-macosx_14_0_x86_64.whl", hash = "sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8", size = 6788387, upload-time = "2026-08-09T13:47:58.192Z" }, + { url = "https://files.pythonhosted.org/packages/15/ea/c0dbdbcf22f43782510a3e492dd3da73c6112b69cac8929d16d127536fc4/numpy-2.5.2-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc", size = 15667096, upload-time = "2026-08-09T13:48:01.562Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5e/29c73c31748cdb0f7566642125ba17fd5b56780cddf891b085dab27e4466/numpy-2.5.2-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec", size = 16751730, upload-time = "2026-08-09T13:48:05.706Z" }, + { url = "https://files.pythonhosted.org/packages/47/95/02501e8454796bb58dadf7a99d3181e0b464bf264e1003039572f9779fac/numpy-2.5.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0", size = 17038686, upload-time = "2026-08-09T13:48:09.627Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b5/53a681d91b5c82687067d8ea5035e02d917b5509d6f334cb06484a954714/numpy-2.5.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2", size = 18507727, upload-time = "2026-08-09T13:48:13.744Z" }, + { url = "https://files.pythonhosted.org/packages/42/06/6e11443f7b64ee376c860506091103bf68f92d2cab9e8d96d4501babf07c/numpy-2.5.2-cp315-cp315t-win32.whl", hash = "sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251", size = 6269775, upload-time = "2026-08-09T13:48:17.543Z" }, + { url = "https://files.pythonhosted.org/packages/f1/18/195d6b86cd72dbbc501edfa778005fa6b87afd34c153e46028cd3a0938f4/numpy-2.5.2-cp315-cp315t-win_amd64.whl", hash = "sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12", size = 12782559, upload-time = "2026-08-09T13:48:21.023Z" }, + { url = "https://files.pythonhosted.org/packages/b4/07/458c344f0f0c178f4481dad5cca790626ffe4c34eabf9467069d06ee4999/numpy-2.5.2-cp315-cp315t-win_arm64.whl", hash = "sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e", size = 10748103, upload-time = "2026-08-09T13:48:24.21Z" }, +] + +[[package]] +name = "nvidia-cublas" +version = "13.1.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cuda-nvrtc" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/a1/0bd24ee8c8d03adac032fd2909426a00c88f8c57961b1277ded97f91119f/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b7a210458267ac818974c53038fbec2e969d5c99f305ab15c72522fa9f001dd5", size = 542848918, upload-time = "2026-04-08T18:46:22.985Z" }, + { url = "https://files.pythonhosted.org/packages/3b/cd/154ca20c38269e05eff77c1464e6c1da89f50a6390b565e9d82e06bc11e1/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:37936a16db8fe4ac1f065c2139360608a543a09275cb1a1af612e08cfa065436", size = 423138758, upload-time = "2026-04-08T18:46:58.655Z" }, +] + +[[package]] +name = "nvidia-cuda-cupti" +version = "13.0.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/2a/80353b103fc20ce05ef51e928daed4b6015db4aaa9162ed0997090fe2250/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_aarch64.whl", hash = "sha256:796bd679890ee55fb14a94629b698b6db54bcfd833d391d5e94017dd9d7d3151", size = 10310827, upload-time = "2025-09-04T08:26:42.012Z" }, + { url = "https://files.pythonhosted.org/packages/33/6d/737d164b4837a9bbd202f5ae3078975f0525a55730fe871d8ed4e3b952b0/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_x86_64.whl", hash = "sha256:4eb01c08e859bf924d222250d2e8f8b8ff6d3db4721288cf35d14252a4d933c8", size = 10715597, upload-time = "2025-09-04T08:26:51.312Z" }, +] + +[[package]] +name = "nvidia-cuda-nvrtc" +version = "13.0.88" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/68/483a78f5e8f31b08fb1bb671559968c0ca3a065ac7acabfc7cee55214fd6/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:ad9b6d2ead2435f11cbb6868809d2adeeee302e9bb94bcf0539c7a40d80e8575", size = 90215200, upload-time = "2025-09-04T08:28:44.204Z" }, + { url = "https://files.pythonhosted.org/packages/b7/dc/6bb80850e0b7edd6588d560758f17e0550893a1feaf436807d64d2da040f/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d27f20a0ca67a4bb34268a5e951033496c5b74870b868bacd046b1b8e0c3267b", size = 43015449, upload-time = "2025-09-04T08:28:20.239Z" }, +] + +[[package]] +name = "nvidia-cuda-runtime" +version = "13.0.96" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/4f/17d7b9b8e285199c58ce28e31b5c5bbaa4d8271af06a89b6405258245de2/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ef9bcbe90493a2b9d810e43d249adb3d02e98dd30200d86607d8d02687c43f55", size = 2261060, upload-time = "2025-10-09T08:55:15.78Z" }, + { url = "https://files.pythonhosted.org/packages/2e/24/d1558f3b68b1d26e706813b1d10aa1d785e4698c425af8db8edc3dced472/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f82250d7782aa23b6cfe765ecc7db554bd3c2870c43f3d1821f1d18aebf0548", size = 2243632, upload-time = "2025-10-09T08:55:36.117Z" }, +] + +[[package]] +name = "nvidia-cudnn-cu13" +version = "9.24.0.43" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/30/7c257e3d5cb4fecb147b93895c66e29c93f8e76d74b45bb418ff0587c4ec/nvidia_cudnn_cu13-9.24.0.43-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:a6812a554a1ff0413e9c52b84c26c050380649ab9615f9c16bded368ce9f421f", size = 650976863, upload-time = "2026-07-02T16:23:39.248Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/791cffd048fe5b044e620df55267e3e95c0e6e07d50b41e377c03dfc910f/nvidia_cudnn_cu13-9.24.0.43-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:71f181cd810e90f9b6023b01186fe82d13d65f0ec098581ee201d39fad769e4b", size = 553099438, upload-time = "2026-07-02T16:27:42.58Z" }, +] + +[[package]] +name = "nvidia-cufft" +version = "12.0.0.61" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554, upload-time = "2025-09-04T08:31:38.196Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2f/7b57e29836ea8714f81e9898409196f47d772d5ddedddf1592eadb8ab743/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c44f692dce8fd5ffd3e3df134b6cdb9c2f72d99cf40b62c32dde45eea9ddad3", size = 214085489, upload-time = "2025-09-04T08:31:56.044Z" }, +] + +[[package]] +name = "nvidia-cufile" +version = "1.15.1.6" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/70/4f193de89a48b71714e74602ee14d04e4019ad36a5a9f20c425776e72cd6/nvidia_cufile-1.15.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08a3ecefae5a01c7f5117351c64f17c7c62efa5fffdbe24fc7d298da19cd0b44", size = 1223672, upload-time = "2025-09-04T08:32:22.779Z" }, + { url = "https://files.pythonhosted.org/packages/ab/73/cc4a14c9813a8a0d509417cf5f4bdaba76e924d58beb9864f5a7baceefbf/nvidia_cufile-1.15.1.6-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:bdc0deedc61f548bddf7733bdc216456c2fdb101d020e1ab4b88d232d5e2f6d1", size = 1136992, upload-time = "2025-09-04T08:32:14.119Z" }, +] + +[[package]] +name = "nvidia-curand" +version = "10.4.0.35" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/72/7c2ae24fb6b63a32e6ae5d241cc65263ea18d08802aaae087d9f013335a2/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:133df5a7509c3e292aaa2b477afd0194f06ce4ea24d714d616ff36439cee349a", size = 61962106, upload-time = "2025-08-04T10:21:41.128Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9f/be0a41ca4a4917abf5cb9ae0daff1a6060cc5de950aec0396de9f3b52bc5/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:1aee33a5da6e1db083fe2b90082def8915f30f3248d5896bcec36a579d941bfc", size = 59544258, upload-time = "2025-08-04T10:22:03.992Z" }, +] + +[[package]] +name = "nvidia-cusolver" +version = "12.0.4.66" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas" }, + { name = "nvidia-cusparse" }, + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760, upload-time = "2025-09-04T08:33:04.222Z" }, + { url = "https://files.pythonhosted.org/packages/5f/67/cba3777620cdacb99102da4042883709c41c709f4b6323c10781a9c3aa34/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:0a759da5dea5c0ea10fd307de75cdeb59e7ea4fcb8add0924859b944babf1112", size = 200941980, upload-time = "2025-09-04T08:33:22.767Z" }, +] + +[[package]] +name = "nvidia-cusparse" +version = "12.6.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568, upload-time = "2025-09-04T08:33:42.864Z" }, + { url = "https://files.pythonhosted.org/packages/fa/18/623c77619c31d62efd55302939756966f3ecc8d724a14dab2b75f1508850/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2b3c89c88d01ee0e477cb7f82ef60a11a4bcd57b6b87c33f789350b59759360b", size = 145942937, upload-time = "2025-09-04T08:33:58.029Z" }, +] + +[[package]] +name = "nvidia-cusparselt-cu13" +version = "0.8.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/e1/cdc1797eadf82d3a9a575a19b33fdc871a97edbec42c00b5b5e914f4aff4/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:4dca476c50bf4780d46cd0bfbd82e2bc10a08e4fef7950917ce8d7578d22a23f", size = 221051344, upload-time = "2025-09-05T18:49:51.289Z" }, + { url = "https://files.pythonhosted.org/packages/34/7d/2661f2fb3ac4302f3a246f5fc030213ac60c1fe0bce84f9783dbd831dbb7/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:786ce87568c303fadb5afcc7102d454cd3040d75f6f8626f5db460d1871f4dd0", size = 170148586, upload-time = "2025-09-05T18:50:50.248Z" }, +] + +[[package]] +name = "nvidia-nccl-cu13" +version = "2.30.7" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/21/a73174c6157101bdf1ffc22b517f76ff0082613989dd9bc8f43e8034caac/nvidia_nccl_cu13-2.30.7-py3-none-manylinux_2_18_aarch64.whl", hash = "sha256:ca786ffa5a647c75d4d1f5cc72a6c4f537947e2ba8823d7c8aaf768e7a7b9f77", size = 215983881, upload-time = "2026-06-09T03:23:15.633Z" }, + { url = "https://files.pythonhosted.org/packages/3f/34/c500f90c7ae641b8e0f98965b36b8a7ac79cc8b296e8d251fe3eb592ee54/nvidia_nccl_cu13-2.30.7-py3-none-manylinux_2_18_x86_64.whl", hash = "sha256:cefa7fdb9710efd0f39c5f1be1d61ff6fc9a996c451265bd7fbdcf9455ed4b50", size = 215965170, upload-time = "2026-06-09T03:23:39.73Z" }, +] + +[[package]] +name = "nvidia-nvjitlink" +version = "13.3.33" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/ee/580ca6f29dcab0221db8706badca1bbbb084f1975c4d4e83329c3a7e31f0/nvidia_nvjitlink-13.3.33-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:26a6de7fb4c8fdaa7703d3dad720d6d427ddfea5c48a528fd97c11733ad830e5", size = 40742423, upload-time = "2026-05-26T16:54:51.613Z" }, + { url = "https://files.pythonhosted.org/packages/69/30/45414e35ff2eee7db3da037e5707037ccf9d2b5218ffbdb055ea4d5aa98a/nvidia_nvjitlink-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ce48b37dfeb3cb1eae4cf85adacb47d7a6539ea2272870c9a3628ce275c2037e", size = 39168635, upload-time = "2026-05-26T16:54:13.906Z" }, +] + +[[package]] +name = "nvidia-nvshmem-cu13" +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/0f/05cc9c720236dcd2db9c1ab97fff629e96821be2e63103569da0c9b72f19/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dc2a197f38e5d0376ad52cd1a2a3617d3cdc150fd5966f4aee9bcebb1d68fe9", size = 60215947, upload-time = "2025-09-06T00:32:20.022Z" }, + { url = "https://files.pythonhosted.org/packages/3c/35/a9bf80a609e74e3b000fef598933235c908fcefcef9026042b8e6dfde2a9/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:290f0a2ee94c9f3687a02502f3b9299a9f9fe826e6d0287ee18482e78d495b80", size = 60412546, upload-time = "2025-09-06T00:32:41.564Z" }, +] + +[[package]] +name = "nvidia-nvtx" +version = "13.0.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/f3/d86c845465a2723ad7e1e5c36dcd75ddb82898b3f53be47ebd429fb2fa5d/nvidia_nvtx-13.0.85-py3-none-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4936d1d6780fbe68db454f5e72a42ff64d1fd6397df9f363ae786930fd5c1cd4", size = 148047, upload-time = "2025-09-04T08:29:01.761Z" }, + { url = "https://files.pythonhosted.org/packages/a8/64/3708a90d1ebe202ffdeb7185f878a3c84d15c2b2c31858da2ce0583e2def/nvidia_nvtx-13.0.85-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb7780edb6b14107373c835bf8b72e7a178bac7367e23da7acb108f973f157a6", size = 148878, upload-time = "2025-09-04T08:28:53.627Z" }, +] + +[[package]] +name = "opencv-contrib-python" +version = "5.0.0.93" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/89/e8/7882cbecf8c81129b0b808690cac9ba3015b0ced02ab329bf4a781c7f8ca/opencv_contrib_python-5.0.0.93.tar.gz", hash = "sha256:da0ba61096b08c63cb4440d8fd6f323835cbb78b714c5ba22a39e1db68c83166", size = 154110105, upload-time = "2026-07-02T06:57:59.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/5c/ca1c31afec1a1dc3ff6e1cc94091ac288d0fa8663567398809372fec73b9/opencv_contrib_python-5.0.0.93-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:3ebb8e0506573f36f54038116321a086c97aeda8ef154198931f3ea18b435cc7", size = 55653098, upload-time = "2026-07-02T05:50:29.816Z" }, + { url = "https://files.pythonhosted.org/packages/9c/5f/1ec2b7bc3a2ef169f9acd643c7279bc3208a83240f03ba7fe4e12683272c/opencv_contrib_python-5.0.0.93-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:45a1ce7c68828907348e649edd471a7dc5244d3d0ac21989e67c63d2f4fa629a", size = 42828002, upload-time = "2026-07-02T05:51:35.32Z" }, + { url = "https://files.pythonhosted.org/packages/73/76/011d759d3c8f2a43e8a435d1e39be4a24ed9fb8c14d6c610d72b9ac2124e/opencv_contrib_python-5.0.0.93-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cac609c9a4fce67feb287837c671a2c4da9467df8e47fa0cce7bdc453d12a529", size = 57890569, upload-time = "2026-07-02T06:49:13.356Z" }, + { url = "https://files.pythonhosted.org/packages/60/82/e82b0e3b02617af8bcaff0ff29c75992e916dc7b34daaaef3e0f805967de/opencv_contrib_python-5.0.0.93-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:29b916da864002a921c79b6df4cfb2dcf79870f166ddf3ce1179b558bc7313d7", size = 79172364, upload-time = "2026-07-02T06:49:44.204Z" }, + { url = "https://files.pythonhosted.org/packages/71/dc/85ed9767f52425dc811a3a8288d2c643cc0c1341a3b4bdd3166410c77669/opencv_contrib_python-5.0.0.93-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:b84f0b0fcdbd2421b5819e517542463e71eed7f41e0a0c4ec280ed88b7269a66", size = 57856049, upload-time = "2026-07-02T06:50:07.911Z" }, + { url = "https://files.pythonhosted.org/packages/8b/39/f87d154d2dca8e9815ca9e4f925aee41e5931162da730d17f3200e7786f3/opencv_contrib_python-5.0.0.93-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:8427dcb0561dc3ba32f3771c627f52b87c29932c265bea28ffcb54804c3c3fec", size = 82057630, upload-time = "2026-07-02T06:50:54.022Z" }, + { url = "https://files.pythonhosted.org/packages/25/6d/31fee2843aef301252f6fa54bafe6bc2500fab80b152c5850ed3cbc2b7ef/opencv_contrib_python-5.0.0.93-cp37-abi3-win32.whl", hash = "sha256:dd8a80a04a8610c033757135b7846ad2027ba2d3bf9faf2f83f3dc6ed9e3814a", size = 44362046, upload-time = "2026-07-02T05:50:05.275Z" }, + { url = "https://files.pythonhosted.org/packages/09/29/6985260569ee3c7f6fcae252bc06e2a843e5b90eed665a2936bdd26fa283/opencv_contrib_python-5.0.0.93-cp37-abi3-win_amd64.whl", hash = "sha256:461622db95c964652d4d8fda171034961c3de270f78a6095aaad31050771774a", size = 53822579, upload-time = "2026-07-02T05:50:02.092Z" }, +] + +[[package]] +name = "opencv-python-headless" +version = "5.0.0.93" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/99/76b7c80252aa83c1af16393454aafd125a0287101afe8deb0a6821af0e30/opencv_python_headless-5.0.0.93.tar.gz", hash = "sha256:b82f9831daab90b725c7c1ee1b36cb5732c367096ac76d119e64e14eb70d5f3c", size = 81817738, upload-time = "2026-07-02T07:01:06.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/7c/8c8097891c509d98cd128493835c95631c80be6a8f37ed9d25716c2e16f1/opencv_python_headless-5.0.0.93-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:030ca5e0837a2963ab36ef896baa9767eb8d2b83353fb28af5a521e40dd8756f", size = 48322581, upload-time = "2026-07-02T05:50:34.207Z" }, + { url = "https://files.pythonhosted.org/packages/90/8c/eab2ad388c3cbab2a350c10c2ef19ce6bd099240afc31789032c996bab52/opencv_python_headless-5.0.0.93-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:1e55af3abfb462eeeabe5c775f12bdb36216d8a93a3583d69e6bd6e1d6ba7d00", size = 34782894, upload-time = "2026-07-02T05:51:39.856Z" }, + { url = "https://files.pythonhosted.org/packages/ec/78/afca939f40ffe2b2380bfa86f812b2f7d4acc5a27b27dc41b49cad7ce7b4/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:10818d91510e05c04568ae12b5cd120779c70c01bf897b001a6221fe430df80f", size = 36521085, upload-time = "2026-07-02T06:55:24.429Z" }, + { url = "https://files.pythonhosted.org/packages/2b/97/8170e9819764c47e436c130d3ff6cfb73b58f923eae9d3a03d8982b04aec/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:09a872a157c1376ab922a69bbf22f9a95bcc7b658a9d8b436a60212b02b2eeb4", size = 56563598, upload-time = "2026-07-02T06:55:47.355Z" }, + { url = "https://files.pythonhosted.org/packages/3a/98/1a28a7101e31801042b3098871a74b76c61581d328ef40774ff4edb53a56/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:840bd717c21e5c11cadadc022a823315ea417f961213d06b4df010e019eb16f4", size = 39648433, upload-time = "2026-07-02T06:56:04.255Z" }, + { url = "https://files.pythonhosted.org/packages/9b/21/f6ef335f6e65724aa78b8d792b48d40a48c381715f1e62f5a5049e09d07e/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ed709fdf9aa0bd1f2ed8549e71d19449b03a675bb581eb292285f6861953be37", size = 61204038, upload-time = "2026-07-02T06:56:41.823Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8f/b8756467ea991449a293797f6b3fa80fcfdd29598a0a60d1cd5715b96e61/opencv_python_headless-5.0.0.93-cp37-abi3-win32.whl", hash = "sha256:c6bcd96b185975ea240d22cfdb15a1f6d080cc95264cfbe2621f21bb144d89b9", size = 35411237, upload-time = "2026-07-02T05:50:12.901Z" }, + { url = "https://files.pythonhosted.org/packages/b8/88/763b967f7efd7226b82c9fae16d560cba049b1f0c036647e65c610fd636e/opencv_python_headless-5.0.0.93-cp37-abi3-win_amd64.whl", hash = "sha256:829717b6a95554f273e49e357cee3b3a2a26b6f4842fbc1bed2b45bdd8f87e0e", size = 43825962, upload-time = "2026-07-02T05:50:09.627Z" }, +] + +[[package]] +name = "openpyxl" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "et-xmlfile" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" }, +] + +[[package]] +name = "opensmile" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "audinterface" }, + { name = "audobject" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/0d/13e2c3ea007e514eea3fd37ea97050ed5fd6177e70def758c8d98f6f830c/opensmile-2.6.0.tar.gz", hash = "sha256:03d2faae9f3a7a9a7d8ababfe32e290454b1dce3dc5179de38c0be29a27465b5", size = 9325366, upload-time = "2025-07-31T08:55:39.847Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/83/c83d5a282b0780d70247e779e9bf247816a3ee8e04bf02f3c50c53617fa2/opensmile-2.6.0-py3-none-macosx_10_4_x86_64.whl", hash = "sha256:fd17585ad147879dac3da640fcaac46dc38aa42db4364d8025ff40bf55edf9aa", size = 800463, upload-time = "2025-07-31T08:55:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/20/a2/8e8746c8b1aed80d103afd5be8400828a71677a75cc853af0d7d671f7d18/opensmile-2.6.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:572843aa36d0ab61efc5516bec0eec3bb11b66f22050a34014dd7c996c4c112e", size = 732012, upload-time = "2025-07-31T08:55:31.827Z" }, + { url = "https://files.pythonhosted.org/packages/82/d5/a6de0b46c2beb8549e2149c5084393aa90eb181248fd4c6fbb7056ea8db3/opensmile-2.6.0-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:98b2dd93075a1966c53d04cddadf1b9290b0933e35af176a8466998704341e15", size = 915897, upload-time = "2025-07-31T08:55:34.26Z" }, + { url = "https://files.pythonhosted.org/packages/d8/14/1235eab75c4216e109e41e110f295388336a16ea2985fd2d16ce8b2c8f94/opensmile-2.6.0-py3-none-manylinux_2_17_armv7l.whl", hash = "sha256:faf81435f169d378136337e66bfbe5537a71feeae2f9ea16bcb90e1e91350ca6", size = 849353, upload-time = "2025-07-31T08:55:35.531Z" }, + { url = "https://files.pythonhosted.org/packages/ec/09/a68af9ea0a241ddf52f12eab3d991b049ec416f5e1e58140d9d9c57c3685/opensmile-2.6.0-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:717ae9ad8c042ec000546b590a20a4a6c50b946d3c339936e10720dc57bcaa6f", size = 1021980, upload-time = "2025-07-31T08:55:37.128Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c2/4bbe5b762266907166945435588b77503a2d63a18bd223e53d6c744a0c64/opensmile-2.6.0-py3-none-win_amd64.whl", hash = "sha256:4377d53cc678c119015b7771df00d88a835d9fec946982efc23717b54cf5320d", size = 819424, upload-time = "2025-07-31T08:55:38.47Z" }, +] + +[[package]] +name = "oyaml" +version = "1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/71/c721b9a524f6fe6f73469c90ec44784f0b2b1b23c438da7cc7daac1ede76/oyaml-1.0.tar.gz", hash = "sha256:ed8fc096811f4763e1907dce29c35895d6d5936c4d0400fe843a91133d4744ed", size = 2914, upload-time = "2020-08-18T04:37:43.397Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/aa/111610d8bf5b1bb7a295a048fc648cec346347a8b0be5881defd2d1b4a52/oyaml-1.0-py2.py3-none-any.whl", hash = "sha256:3a378747b7fb2425533d1ce41962d6921cda075d46bb480a158d45242d156323", size = 2992, upload-time = "2020-08-18T04:37:38.263Z" }, +] + +[[package]] +name = "packaging" +version = "24.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788, upload-time = "2024-06-09T23:19:24.956Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985, upload-time = "2024-06-09T23:19:21.909Z" }, +] + +[[package]] +name = "pandas" +version = "3.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/17/d7b106e05bfa642e8694451e7d3d759c6a241c5386a5d962e4f66c047e06/pandas-3.0.6.tar.gz", hash = "sha256:66b07ef7315a31bfe1089cd3d71a7de781c9dca986762d0b4fe7c0ef17465d10", size = 4667686, upload-time = "2026-09-17T23:23:18.345Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/55/1a8875395b05ccd572cbca0b9255dcd2db6e6508e632a558c1a6884b39ad/pandas-3.0.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ee913a91669056c1de1a6b733fbfeab711de9e54e3bee2dfa5fe79d9457247d1", size = 10492213, upload-time = "2026-09-17T23:21:40.746Z" }, + { url = "https://files.pythonhosted.org/packages/35/61/47ae13476995cc8a40cd609e93e7cf11f273d8692925c2903cb6d38aa0d1/pandas-3.0.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ff51a4459ed036e93d1eb1bb5e6e7b28685d3cb6b7c12b91c05b31024e234729", size = 10156618, upload-time = "2026-09-17T23:21:44.142Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f2/cc5f2adb8d6e86a85d9fb5128f8cf205a61189336f70d1f7faf0d1b53ec9/pandas-3.0.6-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:654aae059295dbba6ecd2328ca12712a2cf1676214c8699f1c29213f7ccf9c34", size = 10375479, upload-time = "2026-09-17T23:21:47.159Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ba/ffdcb19be4ff6bfe7d969e7cef2c567c633df5a3a1cc1053394ad053bca8/pandas-3.0.6-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f51d7f651c8054c5e82a69265c98082e795d1442df7ca6edc3a545d61214b1", size = 10783244, upload-time = "2026-09-17T23:21:50.367Z" }, + { url = "https://files.pythonhosted.org/packages/77/5b/e150075b2c6eb69fae896f2d9239bc6ed07db97735971d53d66de6553460/pandas-3.0.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:22172a92e7ee678ec0140c7af4fc9366b55413834a1cd86af78b3caa0b0574de", size = 11382223, upload-time = "2026-09-17T23:21:53.355Z" }, + { url = "https://files.pythonhosted.org/packages/d6/8a/b441c587dc7355bf6e1f68a91b4f76a6c29740f0c23be3acc5d4ebbeea6d/pandas-3.0.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:583be68728a31d0d750d5b8d9e00f02b153df0d4655f858bde93cb84cfc4227c", size = 11854881, upload-time = "2026-09-17T23:21:56.342Z" }, + { url = "https://files.pythonhosted.org/packages/b7/e9/f43410fada510b43fec09993c08f552086c3d247d3ee801a678f3cb10ea5/pandas-3.0.6-cp314-cp314-win_amd64.whl", hash = "sha256:77ccbe5057aece6fc172b9b77f19c04335af6882bc2e10c8f3ee4e6bfb3da553", size = 9791672, upload-time = "2026-09-17T23:21:59.332Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9e/db14c059c21f9baa1907d436f8bf30e0c76c6288225c5e8b79a08ba8b2c5/pandas-3.0.6-cp314-cp314-win_arm64.whl", hash = "sha256:fb625f426b375bcc96e3a04c5d5d266cd7be6ae5d6866e0e703382ab5164068c", size = 9121246, upload-time = "2026-09-17T23:22:02.123Z" }, + { url = "https://files.pythonhosted.org/packages/67/ba/bad0f8dac020ab38a8637fddab01a57a82da7a496a6e6f19590aad53ab62/pandas-3.0.6-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9e492cd4bdba6778de4fe0df7f4590c012161ebcf9902dce01b01dc683105514", size = 10920612, upload-time = "2026-09-17T23:22:05.404Z" }, + { url = "https://files.pythonhosted.org/packages/c4/a9/b500982e9aac6d52a58da4ad3f11e14168a315b06906b3f397c427878065/pandas-3.0.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d7dcd21238cbb4828ff148481ba01cac8946dc5121457b5aeba28636f8f99a60", size = 10570213, upload-time = "2026-09-17T23:22:08.44Z" }, + { url = "https://files.pythonhosted.org/packages/4b/fa/e6ecd0073c98be8f840ac3125b955272835d7d9fd69f5944383b164deb5e/pandas-3.0.6-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ff482fa91fa2bafd92e8fe66ce3645c851824310f295c1f0a2f96e928fc4541", size = 10252356, upload-time = "2026-09-17T23:22:11.302Z" }, + { url = "https://files.pythonhosted.org/packages/04/f5/001e230a7a7803590d9275a1a3f7e1bb605e3a495cfe5e8d3a532090621b/pandas-3.0.6-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:db7ec631f26223beee8e5c9e0b8f23c24d8197bbd1d982421d4e3188bea51965", size = 10655952, upload-time = "2026-09-17T23:22:14.283Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ab/bab587148a3852c96aae26c4b5f9e04ce2221801ad94e166b4fbf969ede0/pandas-3.0.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd75ed0c840f709fc2ae26ddd9534ac77ca1a48ac0cce521a74acaa85f3340a7", size = 11274177, upload-time = "2026-09-17T23:22:17.352Z" }, + { url = "https://files.pythonhosted.org/packages/f3/32/74b48d87df2b80892d713c149abfe36d5db4de41b4eccb042a2bc07dafc1/pandas-3.0.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ef738d71d1059245b6bb03e312be06d8b3821326a83486c1ad03b9aba3710e44", size = 11719041, upload-time = "2026-09-17T23:22:20.227Z" }, + { url = "https://files.pythonhosted.org/packages/f6/c6/d64b72d64d7eb0fad9fe424d34138e45dee70ddbea1360dcd0adf30e28f6/pandas-3.0.6-cp314-cp314t-win_amd64.whl", hash = "sha256:429d9df32731ab01383ed98f2baa7a60368090d1a94fc06019a12062510e8630", size = 10191388, upload-time = "2026-09-17T23:22:23.524Z" }, + { url = "https://files.pythonhosted.org/packages/7a/30/5e5b2ccabeca73ae2b03fc82bca3eabb7466cf43737f05ac08d591665d47/pandas-3.0.6-cp314-cp314t-win_arm64.whl", hash = "sha256:a4dbd4dc65cbe645b92b8785d0f96dd7311010dc6606cf620e51b07b8788a12a", size = 9387796, upload-time = "2026-09-17T23:22:26.64Z" }, + { url = "https://files.pythonhosted.org/packages/b6/77/47c5fb0be8bdd00116814c2c40d9ec42dbeb943865ef95130fe58a898226/pandas-3.0.6-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:50c44cbf5820b6b91a5f74aae04972472aefadd3cd9fbd1010409d85528bd570", size = 10483960, upload-time = "2026-09-17T23:22:30.071Z" }, + { url = "https://files.pythonhosted.org/packages/09/08/a310cb2fefe6d2b4623ab2150da818d93d4e73e33b58e4d163bb74243c5a/pandas-3.0.6-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:eb6900de08ac85f93ac4948aa6b80842eba555875337b8359035ac9c43e92d34", size = 10149432, upload-time = "2026-09-17T23:22:32.818Z" }, + { url = "https://files.pythonhosted.org/packages/54/36/6af478ec3a26d7754555cd62c3101c589c0931b1d85398e4fa5403910a1c/pandas-3.0.6-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e25e2e1adee99ddfada6f7206a79ae8e9c8a8861b0e3eaaba165006d3eef18e", size = 10360981, upload-time = "2026-09-17T23:22:35.621Z" }, + { url = "https://files.pythonhosted.org/packages/43/20/5ece0e9cb79a6473216620db6a90546f578001c2bd857b77c444b27acad1/pandas-3.0.6-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4ff44b2cb51cbd691c91f92c4ea6c71e34003f239ebd67c2e857dc898466b49c", size = 10776585, upload-time = "2026-09-17T23:22:38.427Z" }, + { url = "https://files.pythonhosted.org/packages/2f/b6/cd3038f31ade5e8d2b4e1c9549d4b31e4d598469562f47142b2ad9171c0a/pandas-3.0.6-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:5edd0a7abb0986ecce1ac81f56d99b6763f86aa6946dceb6c661224f90af5a19", size = 11385249, upload-time = "2026-09-17T23:22:41.18Z" }, + { url = "https://files.pythonhosted.org/packages/0a/87/05bb3003737f80375d7311774916a24d161e2e591abe8c672aed7813defc/pandas-3.0.6-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:1bcb3e9ed29e74a7439cedff9e2aefd3ea65de84d7de9ccb6c194192541bd60e", size = 11848595, upload-time = "2026-09-17T23:22:44.207Z" }, + { url = "https://files.pythonhosted.org/packages/c0/30/1c0d46acf236d19ef975e9cdd5d1e0dd54924b03f0ed8287096ad4a18152/pandas-3.0.6-cp315-cp315-win_amd64.whl", hash = "sha256:253e12cb9081b0afbac607920f6142975966bc315135e09de275fdbaa415d2de", size = 9783810, upload-time = "2026-09-17T23:22:47.097Z" }, + { url = "https://files.pythonhosted.org/packages/87/03/df3304a9c2833c4810e7f1c887b04105b24731f9deef8b5d5d04522a375b/pandas-3.0.6-cp315-cp315-win_arm64.whl", hash = "sha256:97274c9adf6255bb48c620cd6959805efa7f09ea2167f0e0ae006a448cd2fca7", size = 9116820, upload-time = "2026-09-17T23:22:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/47/25/d5f6cce5efa17c38e4f752a875b4a26d66cfadd529cb8c81672f0376d6a6/pandas-3.0.6-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:265f562fdd1079f69f3de96dd425c3405224038c0af4f920c54bd240ee2c4640", size = 10894614, upload-time = "2026-09-17T23:22:53.223Z" }, + { url = "https://files.pythonhosted.org/packages/ea/8b/e1876bfdc1df06bafc022d33202b5663bd86c81df2a6140aacafd0344669/pandas-3.0.6-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:c6e4aae3e9bea26c6c9a20d88d96c86ec4a99b4db5fd516bcb4e829ab2c0ee36", size = 10546973, upload-time = "2026-09-17T23:22:56.155Z" }, + { url = "https://files.pythonhosted.org/packages/e9/27/e0a27a5a5c27f7db66657b44def9e93121fd0ad4f0808355b9898fcbf204/pandas-3.0.6-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a77a1a44e4d88f1c6a2a64d3eb12efec8420875722e14279800b173a7c7c2804", size = 10239717, upload-time = "2026-09-17T23:22:59.603Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4f/4eadb7d86a921c1e8bc70916cfe601ed667c4169118d17d69958611c21f8/pandas-3.0.6-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86fa853a12e0b70927e2b1ee00d56d2224ec9cbb4b9d58348b5ad52d2f21150e", size = 10641275, upload-time = "2026-09-17T23:23:02.81Z" }, + { url = "https://files.pythonhosted.org/packages/c7/d1/eba72e9d905e84e79aefeefdcc6bc1abe15d9077973566643f4211636966/pandas-3.0.6-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:c826e9babb7790142c399f58599d8de679bea059d7b39c5b6efa2096fac37266", size = 11262919, upload-time = "2026-09-17T23:23:06.038Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8a/1c5bd2642b450e374b6191189f47c49538fe41f82348a66de6f647e6ab59/pandas-3.0.6-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:8fe77b408d82e2615674dfed62533b95e18a03610573877422aada4f625d4947", size = 11709148, upload-time = "2026-09-17T23:23:09.082Z" }, + { url = "https://files.pythonhosted.org/packages/73/3d/1b142bd0d0f1326a5d98c91c955b923cd1e06b5eecb428cd9d8817fa01c0/pandas-3.0.6-cp315-cp315t-win_amd64.whl", hash = "sha256:83e91d15738d7783c050197cef2f2cf82fc6353dae9865aa87ed1fa16aa4d55a", size = 10161518, upload-time = "2026-09-17T23:23:12.365Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a3/6419c14da2adc1f09a6a183b8f91d7494d325b287f4ca984ac04f663638a/pandas-3.0.6-cp315-cp315t-win_arm64.whl", hash = "sha256:963ca21199097a84c7827c4678b04e30833084fbf8ef44fde3fa7180a29f8fa0", size = 9364529, upload-time = "2026-09-17T23:23:15.274Z" }, +] + +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, + { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, + { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, + { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, + { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, + { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, +] + +[[package]] +name = "pyarrow" +version = "25.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/e3/27f57f80141379d60defe6703eb50a707325706f07fedfd1312c7a751995/pyarrow-25.0.1.tar.gz", hash = "sha256:9150a83248bfed9813ea3c3af74c3856c1984d444aa28e58bf7733b9750ddf6a", size = 1201653, upload-time = "2026-08-10T12:40:53.904Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/4c/b525824ad3094076919273cd97db61fb3d78252dee76fa3b8dc8f76774aa/pyarrow-25.0.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:bf0b672390cdcb640d7288f96b826d71ff4e9abb254a86c89890baf51a29cee6", size = 35885255, upload-time = "2026-08-10T12:39:32.366Z" }, + { url = "https://files.pythonhosted.org/packages/08/62/448bb0e940de41aec31d1a956e63ad9c54afdf122a103cc3ab20c2a3ce33/pyarrow-25.0.1-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:38a9a4b4b9613380e200641891495a56c3d5a98a092db4a870af9975e220471d", size = 37644461, upload-time = "2026-08-10T12:39:38.142Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9a/13587e38bd4806fd218f50fd13b8903fab60588a699ff0c406372e5b4043/pyarrow-25.0.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:0b726ad7e7b669be982b0c71c07fe4b037d654354130da79a7902a669e93a66b", size = 46877146, upload-time = "2026-08-10T12:39:43.722Z" }, + { url = "https://files.pythonhosted.org/packages/8d/61/1c5d1229fa21da4cff5365e41e57177aaac57c563c727f35419b8513d1c1/pyarrow-25.0.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:9171748cdf796972d85a4b60157c279913e242992e350c90c7450182a9838b2a", size = 50131616, upload-time = "2026-08-10T12:39:49.304Z" }, + { url = "https://files.pythonhosted.org/packages/43/20/291e1d65cc0b09aa19f03cf25cf51a2f5fa94b5db315178f2d254ed5cad4/pyarrow-25.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b7a296aac7a71fa0886c08e155ddb6c636a50013f801f6178daafa0f9e726188", size = 50008879, upload-time = "2026-08-10T12:39:56.891Z" }, + { url = "https://files.pythonhosted.org/packages/8b/7c/1b7c9ec28e76576337e4f97b31141c9a181b89b6d1d6221e9d8205621a58/pyarrow-25.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0fe7c8b6c03969b49c8c66182e4a18e3819ab92d07cfab5d8370c531b9369ef0", size = 53170864, upload-time = "2026-08-10T12:40:04.918Z" }, + { url = "https://files.pythonhosted.org/packages/b7/75/f3d789dc06011a765d14d86bda799cf72ac1d715b6a6edecaa0d73d95062/pyarrow-25.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:f729cfdbd36fd99d543b67a914d2de044c84ebe45be8b34902b299b608c15c8f", size = 28620729, upload-time = "2026-08-10T12:40:51.41Z" }, + { url = "https://files.pythonhosted.org/packages/fc/05/647a8ee6f7c2662feb6921315617bc04dcd6034763fb61b1199720bf6162/pyarrow-25.0.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:59a2de54c0cbd954da861eee4d1d330f8e909c45b53455baef696380f2c55033", size = 36130288, upload-time = "2026-08-10T12:40:11.014Z" }, + { url = "https://files.pythonhosted.org/packages/93/f8/c9ee997554d7bea94520667dd1933f109ac1da3ee3556d2b49381e023484/pyarrow-25.0.1-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:35935cd5de130aa5cf4dea052a63e6bf2e17006c35c3a468194242b9b2bf5956", size = 37762187, upload-time = "2026-08-10T12:40:16.592Z" }, + { url = "https://files.pythonhosted.org/packages/a2/08/a28c01c7fe9e96e8233ce2d13df1d402f4f999f848f51d2daacd6bb4c036/pyarrow-25.0.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:f3831aaa25c67a99f99dc8b05873cb9d64560390372e2aa197ce9dd4a3f06a44", size = 46888003, upload-time = "2026-08-10T12:40:23.242Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b9/58612e977d28dc58c878448866838369ee8da2f1e7cc8ed2c84b952aafee/pyarrow-25.0.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6a1fdfc6659b6b19022f2e50627fb5cf7156a66c46bf4299379955cbe742382a", size = 50079036, upload-time = "2026-08-10T12:40:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/72/13/66e1402dcc860e1dc2760b1e0292c9a569b62b3bccab69def1b3e907d006/pyarrow-25.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:169d3429d5be7c752125890620f75a60776d38b0035eddae939651640822332e", size = 50040226, upload-time = "2026-08-10T12:40:35.186Z" }, + { url = "https://files.pythonhosted.org/packages/78/10/3f1a5497a7ef732ab0f03ecca3e66d89d9c0f57fdc61b4794c456b781f01/pyarrow-25.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:119297a6dc197e45d9c6d4415f7814a67ffa36c180d26f68c154c58067ae782d", size = 53149035, upload-time = "2026-08-10T12:40:41.454Z" }, + { url = "https://files.pythonhosted.org/packages/93/c0/37d4a7e8e2f7a6076283673d5298018ca26478b934c6ee369e10505ab32c/pyarrow-25.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4288f27577352d608ca08553b0865e4a9b3aa14820c5d95b53337218d609835b", size = 28753071, upload-time = "2026-08-10T12:40:46.623Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + +[[package]] +name = "pygments" +version = "2.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/11/b213bebff182584360cb8d17c72c1677fec5c5c228de439e63bcf8ab1c8f/pyparsing-3.3.3.tar.gz", hash = "sha256:928ae7e20211f3b6f3915a72f06a0cfd29ab9d24279dd6346b6b1a7146397d36", size = 1050487, upload-time = "2026-09-20T20:59:05.609Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/bb/d215ee7c73b61497b28a5503f9f53523f294fcc936762b7caf90e0c1c2b5/pyparsing-3.3.3-py3-none-any.whl", hash = "sha256:ece8c00a69cf01b45d0b1dedabb469c90d8caf996d4fda40f147627a122849a4", size = 126420, upload-time = "2026-09-20T20:59:04.025Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "q1" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "matplotlib" }, + { name = "mediapipe" }, + { name = "numpy" }, + { name = "opencv-python-headless" }, + { name = "openpyxl" }, + { name = "opensmile" }, + { name = "pillow" }, + { name = "scikit-learn" }, + { name = "soundfile" }, + { name = "torch" }, + { name = "torchvision" }, + { name = "transformers" }, +] + +[package.metadata] +requires-dist = [ + { name = "matplotlib", specifier = ">=3.11.2" }, + { name = "mediapipe", specifier = ">=1.0.1" }, + { name = "numpy", specifier = ">=2.5.2" }, + { name = "opencv-python-headless", specifier = ">=5.0.0.93" }, + { name = "openpyxl", specifier = ">=3.1.5" }, + { name = "opensmile", specifier = ">=2.6.0" }, + { name = "pillow", specifier = ">=12.3.0" }, + { name = "scikit-learn", specifier = ">=1.9.1" }, + { name = "soundfile", specifier = ">=0.14.0" }, + { name = "torch", specifier = ">=2.14.0", index = "https://download.pytorch.org/whl/cu130" }, + { name = "torchvision", specifier = ">=0.29.0" }, + { name = "transformers", specifier = ">=5.17.0" }, +] + +[[package]] +name = "regex" +version = "2026.9.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/5c/f403115361de25809e8f785686ec7096e30fef73be9ae35aa51da4e80abb/regex-2026.9.10.tar.gz", hash = "sha256:1e321e2c84f0e52c457f5ea5944f796d6e8e09cb99738ea98dcc1bfe402a128d", size = 417072, upload-time = "2026-09-09T21:00:21.521Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/ed/98e9b07d8bb9c765d07774f0b2c19b301b96d51f44630fea48951051c94e/regex-2026.9.10-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fd6bd89b9fc06018d35851cab0240adb7dd84d51941b19f6574ac90cd54e3ae5", size = 496662, upload-time = "2026-09-09T20:58:05.118Z" }, + { url = "https://files.pythonhosted.org/packages/ee/a8/9dfe9be48378b47c5a8f04b0f200ea225f9ee0f8e93f010433f661a37878/regex-2026.9.10-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ef4c0a9dfdc90581b90b1b95a8c3d1557f8ff8f5a2a53536d26314de699d1468", size = 297115, upload-time = "2026-09-09T20:58:06.822Z" }, + { url = "https://files.pythonhosted.org/packages/2b/e4/5d1f005a3825ec49842ad349061c1c26e6d42f47ccf105e6e5aa6aeed392/regex-2026.9.10-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:14caa05ce39ec70437af5aac8814c50ee6628f4a90353871c059692f448a164f", size = 291896, upload-time = "2026-09-09T20:58:08.675Z" }, + { url = "https://files.pythonhosted.org/packages/be/15/44ce83fca50c6058f42b62fa8300a8030eea7e4e5a973a2dd33db0f557fb/regex-2026.9.10-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3264132d576847ab5f88bb83e7debe67854bf165b3ea613bd467312b6099536a", size = 800534, upload-time = "2026-09-09T20:58:10.339Z" }, + { url = "https://files.pythonhosted.org/packages/af/6e/a62e070a5a033643b287489576f02ae6a9c584c337d62349e340a2b4d001/regex-2026.9.10-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5cef9f3d14796500ea834c41dbe688f1f6b23c7024dc23e8a794d7ebaf5d71d0", size = 872038, upload-time = "2026-09-09T20:58:12.186Z" }, + { url = "https://files.pythonhosted.org/packages/f3/06/8b8e2483949b1329df10c5b615e85d332066deb426b11332b799629b9201/regex-2026.9.10-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d278ad30ec83b6b9202685b0f80b741a51ea3ca7f0595ebda96e7628b6398876", size = 918927, upload-time = "2026-09-09T20:58:13.903Z" }, + { url = "https://files.pythonhosted.org/packages/bb/64/9b56f69100d3afdbc9c4fa6e302764f9cb717fbc06a9d50558d98ca89cd2/regex-2026.9.10-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05fb018cfe7144585fc83882405906ff84994a2d154afc2509ecc7752c51f864", size = 803694, upload-time = "2026-09-09T20:58:15.949Z" }, + { url = "https://files.pythonhosted.org/packages/07/43/d00d59a7c8fd0e070ae8457a8743597f45ad9682b100f57b9c9c405fbdfd/regex-2026.9.10-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6fd555fc9abef50c530869690b2daca054c8811a7aff632d11f9a7b2590b2742", size = 777770, upload-time = "2026-09-09T20:58:17.628Z" }, + { url = "https://files.pythonhosted.org/packages/46/6b/a11d0446484efbc9eb67abec133f254c6d66a1568b8f3fb36d39a73a1129/regex-2026.9.10-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8d5c4518235a2ec1611e57af85fa488d529c1106aacff12adadcedf8687012cd", size = 791234, upload-time = "2026-09-09T20:58:19.476Z" }, + { url = "https://files.pythonhosted.org/packages/12/09/bcd24e78b373fd4f98090caa43eade439223f6703b909be79b9efd9ab0ab/regex-2026.9.10-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:175cf49ce7a994c88b8f15e3cb17cdb66a48ebb2d36de736b8205033db950f89", size = 866259, upload-time = "2026-09-09T20:58:21.683Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c6/c57ba5e94222a813260af4c17ced92d40cdb44737eb6b50979688310b6a3/regex-2026.9.10-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:b71649169a9fcf30b395ee01047fa7ad6654a4c900ca75b23c04dedcce6a1f8c", size = 768219, upload-time = "2026-09-09T20:58:23.842Z" }, + { url = "https://files.pythonhosted.org/packages/7b/a2/3820037587d00901ace96c5864335c2cd1b899d5263ea0dd2261359e0bee/regex-2026.9.10-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:8ba1f78bd4fef2d8f84b894ec28ac3481afe6cc07aaa253ad4717ef7b3fe6bcb", size = 858582, upload-time = "2026-09-09T20:58:25.607Z" }, + { url = "https://files.pythonhosted.org/packages/47/f0/f9a838ca6219ae4821de0175e4548db73ef56de5ec08d032fb427732fa07/regex-2026.9.10-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:217e98ba5fc8908ed8ffd4ebac04753a0c831067cbfb495b9821b94cc61eaa76", size = 791405, upload-time = "2026-09-09T20:58:27.406Z" }, + { url = "https://files.pythonhosted.org/packages/f7/bf/67d71cc4e13ae2e0022d21243ca069e0868701a99eb29cdecd13d356e694/regex-2026.9.10-cp314-cp314-win32.whl", hash = "sha256:b298cdc33c5cc6969ff07f0fba19cc73e0fd8576373c50935feadaca2f6b4405", size = 272702, upload-time = "2026-09-09T20:58:29.116Z" }, + { url = "https://files.pythonhosted.org/packages/c1/38/40a93e72703a741235115ed1b1e5f6b869917677b7643005034ce1611d70/regex-2026.9.10-cp314-cp314-win_amd64.whl", hash = "sha256:c32818b28bcd153b25b63038348a9fe9b9fbcddb60df43f204c3ab55eeb57f77", size = 281170, upload-time = "2026-09-09T20:58:30.899Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ac/e95387f00617c16bb41b786d900bacd17eab88afa81b4f263df532b3a731/regex-2026.9.10-cp314-cp314-win_arm64.whl", hash = "sha256:75242f44a3e283106077be4ab717bc535e4701c9d54ad69e195945c22f137a1d", size = 281511, upload-time = "2026-09-09T20:58:32.594Z" }, + { url = "https://files.pythonhosted.org/packages/39/e5/a4b12262edc488a8a7a95b672db317dd8aa9bf2fab98297f9c91bb11ad4d/regex-2026.9.10-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:2dd9286093c71afc8f55ef035c5b9d2776641fd72c6535f1febc92d0b0be9666", size = 501128, upload-time = "2026-09-09T20:58:34.306Z" }, + { url = "https://files.pythonhosted.org/packages/55/c8/9ca31c0fa5197ded8614c8ae0e105bcff2d979025ffa3c75580baa334e2f/regex-2026.9.10-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:71879292c9c7ac67b1680345b16daba1be937cb027362cfa04e68f65db2dcfdd", size = 299428, upload-time = "2026-09-09T20:58:36.296Z" }, + { url = "https://files.pythonhosted.org/packages/2b/d1/ee7662561735f90475443c3ca1977e5cecaeaa8f29620dec75580aebc839/regex-2026.9.10-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5ccd139b2061132e7b265cfb4b4721baeb9f8928b81415304abf1ec7e3181c26", size = 294494, upload-time = "2026-09-09T20:58:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b1/333168e45ed6cfe71f6d17e21e5f54725f44d171f84edd12469a2f739227/regex-2026.9.10-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e7327795089ddb44912dce1434e1d7244be2e9fb48fcc2d6782936af7a3062db", size = 814925, upload-time = "2026-09-09T20:58:40.438Z" }, + { url = "https://files.pythonhosted.org/packages/bc/a5/df1b38536d0a3b24a030eb4130ce98b403cc925220ff530f5313a7c436eb/regex-2026.9.10-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ff4d7b14ea19e50c8d9d6d83f45bd9b45cbb624c07ac1fa54db0a019049abed7", size = 873323, upload-time = "2026-09-09T20:58:42.349Z" }, + { url = "https://files.pythonhosted.org/packages/93/ea/aa71fe62dd63a8336bbdec1ff002a6c53b40ccfca95961c18ee4f09bf03c/regex-2026.9.10-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f0407474ffac8e5e89d93ca41d60891e29f0ab8423eb66ff292d850a86a0843", size = 923080, upload-time = "2026-09-09T20:58:44.488Z" }, + { url = "https://files.pythonhosted.org/packages/86/38/49f8d6fd34fc1a9c75b5b96364ebdde702a8144e5ed63d2213c58d454c27/regex-2026.9.10-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ad10a135fa0b4e4a462a61d07c6654d7518cfdb5cb8da08f9ff7d61384af1fe", size = 821284, upload-time = "2026-09-09T20:58:46.56Z" }, + { url = "https://files.pythonhosted.org/packages/32/45/91a977c96d4be13d1ade8208c260c26841c836d4c91745e1828a30589070/regex-2026.9.10-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9fbd2e5d8002dc49a6129fb321ec51c57a025e752ed525ddce0ba9223c4350a7", size = 789256, upload-time = "2026-09-09T20:58:48.473Z" }, + { url = "https://files.pythonhosted.org/packages/2d/79/4d110bf01bf9651bf9b3f88a6d9fa7e643e0586921a18432b25a478edbfa/regex-2026.9.10-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4a761ea45f2ad74c575ef5850ea514cef97302a552d3c7c9d1a1a870d4661d6c", size = 803722, upload-time = "2026-09-09T20:58:50.286Z" }, + { url = "https://files.pythonhosted.org/packages/e7/67/b587a0d3bbac2635309ed9c40c197120c39e1ec0afb8813cbed1338fdd75/regex-2026.9.10-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:75aa39d3f4f1650eea84e46b0d8cefe77dd5478c10e3d0aaf0b0f00493475a7a", size = 870085, upload-time = "2026-09-09T20:58:52.224Z" }, + { url = "https://files.pythonhosted.org/packages/07/fc/0827bca20ddba1d70fa5111a2a64e6b6b38bfdab43fc435022b54172a111/regex-2026.9.10-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f5c629df03adec31ee505dda3c8988f106c9390e4cbd343600036eb8b3d6724f", size = 776970, upload-time = "2026-09-09T20:58:54.478Z" }, + { url = "https://files.pythonhosted.org/packages/9b/03/ab9d08d30568ca868791bfb99551db60b947f05e2e65dcd1261e87083c21/regex-2026.9.10-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3a66e40a1a20de96a2fee00ed67e11012b62d85b277688258677fd19997addb7", size = 863611, upload-time = "2026-09-09T20:58:56.432Z" }, + { url = "https://files.pythonhosted.org/packages/5e/6d/8063ae86b543ae878a7d6e7ba21ebf0af4af06161230e0012e2d652320c6/regex-2026.9.10-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:968c1e33edd9a104d1bf24c8d476c72de7e3839ae7f894b37e9e4f4739fdeeca", size = 804064, upload-time = "2026-09-09T20:58:59.066Z" }, + { url = "https://files.pythonhosted.org/packages/c5/63/b19305c4b8d3d7867699f7d83c43550273d91a2f31793452d87edb1d259f/regex-2026.9.10-cp314-cp314t-win32.whl", hash = "sha256:fbc4e2f3cb7ce8436154e6483079e7d35eeb321a952fa936e180300630d8b873", size = 274607, upload-time = "2026-09-09T20:59:00.942Z" }, + { url = "https://files.pythonhosted.org/packages/32/b8/1695072a512a49060294024e23b945eeb87675b02c06e53a92a1b42b0bfd/regex-2026.9.10-cp314-cp314t-win_amd64.whl", hash = "sha256:c37fa93bf18bf4f90b01c0fa9f11ea567ee4b7dd8bf96e63663e5edc37aa38cf", size = 283944, upload-time = "2026-09-09T20:59:02.876Z" }, + { url = "https://files.pythonhosted.org/packages/a9/9f/65bac17f39991a67e22f8b3c849fdc02a56147c97029b5351494341959b4/regex-2026.9.10-cp314-cp314t-win_arm64.whl", hash = "sha256:ffc2da104e43db716ce30cef9f28049a1faa6aca385dd8771b033268d0730b07", size = 283780, upload-time = "2026-09-09T20:59:05.009Z" }, + { url = "https://files.pythonhosted.org/packages/67/ca/1d1f83bc2f8fff4f186266ac82d73254e686565530cec9ab5228fb5c63dc/regex-2026.9.10-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:6afcad14310f1311d077553ed374b42a5e538f85a8c884b4e38e52de091c8077", size = 496869, upload-time = "2026-09-09T20:59:07.051Z" }, + { url = "https://files.pythonhosted.org/packages/33/42/4217510286501a2ebcd372b781b4754ac961e043fa13ef8dce803c44d89c/regex-2026.9.10-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:3fb4ae8cf83ef4e9addd43b2da31a9f45be816a8036fae8af59c8998b72718e2", size = 297121, upload-time = "2026-09-09T20:59:09.007Z" }, + { url = "https://files.pythonhosted.org/packages/55/a7/595468ed0bbccd94be92c6b5d67736ba128b204d942429a8485c2693914d/regex-2026.9.10-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f7d4656e17ab736e9415a6442a345bfc97bb8b7dcce47884bb74a37f70f08d0c", size = 292139, upload-time = "2026-09-09T20:59:10.859Z" }, + { url = "https://files.pythonhosted.org/packages/29/1c/ac92c123e0ab9bea75a904272171b356940bd6139e4a35de44f2254dca8f/regex-2026.9.10-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35ba3bab0c45079735f55ac61526774de1d84bc4a0333cc554e1a4ab74913924", size = 802375, upload-time = "2026-09-09T20:59:12.823Z" }, + { url = "https://files.pythonhosted.org/packages/8d/16/d349f6fa9f908162359004e4f067353a0146e8074d24989490778244be44/regex-2026.9.10-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ff6b3267318661dfddf6b3628663e00e5946bd0a5c8fa678537a1401f0388f91", size = 872328, upload-time = "2026-09-09T20:59:15.352Z" }, + { url = "https://files.pythonhosted.org/packages/df/81/251b5aef23147057e926346fdb7c8c352d0568f65a492e4e9eb6120f6446/regex-2026.9.10-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:030fa9e23624e39b3b94e46b90a5abd1a1678eb2f58fcdd3fd6c27526bf91c7e", size = 919594, upload-time = "2026-09-09T20:59:17.31Z" }, + { url = "https://files.pythonhosted.org/packages/d0/6e/1f25319dc1b9cf4b7ffa303f3d16ca53260fe92aff45e81aa1b3c6c7cba2/regex-2026.9.10-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fbc8314436353e097c050e11b01a6c11433579437ed0579730157676ef59e2f", size = 807394, upload-time = "2026-09-09T20:59:19.328Z" }, + { url = "https://files.pythonhosted.org/packages/cc/fc/3da6b3dffddf12d5e96cbbe6f5e65ebcd64f92e3388a6690a53e0878232d/regex-2026.9.10-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7e6c0b5ec6ddee4032247585dc491b0fa58627745b66a705728703a3f0331231", size = 786018, upload-time = "2026-09-09T20:59:21.592Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6f/1cc86dafddc912ef44c5ccd4f729060be8c6735600932664eb6d0e25469b/regex-2026.9.10-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:bf29611e5376fec8f795879bb5c6153a76c3a292573d173c26784042b01eb840", size = 793504, upload-time = "2026-09-09T20:59:23.734Z" }, + { url = "https://files.pythonhosted.org/packages/b1/cb/11692e29388d006211163627fcefa0c79917ab9f94d46a1b2254fe5efc81/regex-2026.9.10-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:ec8855f08c17895a26fbf5f19ed829722e19b34a96629e49a43c92974924026b", size = 866766, upload-time = "2026-09-09T20:59:25.798Z" }, + { url = "https://files.pythonhosted.org/packages/5d/78/3631df969830f94d83fcfc5fc71a7b39caad905e18f7b17350a94135d625/regex-2026.9.10-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:94c5ce3bc41d226b4eb89ca3f842b2e28c031487fb1f34eb2153d98235831325", size = 775825, upload-time = "2026-09-09T20:59:28.51Z" }, + { url = "https://files.pythonhosted.org/packages/4e/8a/762892a8e3e21d119eacaffde848aa247e6cf4e1d90c46011671e86b1b9e/regex-2026.9.10-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:9ce239acb15843ab03976626af810a4424b0409689ec2bbc52088ab5479ab487", size = 858901, upload-time = "2026-09-09T20:59:30.656Z" }, + { url = "https://files.pythonhosted.org/packages/3f/f0/78048fada5c2f61d795efb26ea24f820a5564c4aa26574920284d45cd656/regex-2026.9.10-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:c22df8dd6373bbe3898e77429ffc85594300e39d752fd0e68a31e59d37899376", size = 796208, upload-time = "2026-09-09T20:59:32.852Z" }, + { url = "https://files.pythonhosted.org/packages/aa/58/632681f7b9aaa3d83b40e5862ba46364a453c8eb2bc7d43fece3dc31f972/regex-2026.9.10-cp315-cp315-win32.whl", hash = "sha256:1aa309ab7ba89a62d6cf70dbd38d4176440bce3c7001ab86256704cf4c18c6eb", size = 272704, upload-time = "2026-09-09T20:59:34.927Z" }, + { url = "https://files.pythonhosted.org/packages/5d/64/81cce28754c37037b1fe740b6d7a556d51d97cf935ea4547bfab104f43f7/regex-2026.9.10-cp315-cp315-win_amd64.whl", hash = "sha256:58da726d3e766c0b3f5a3997dfaf0275898a1107b8191cdd6b0437fe45fd817d", size = 281182, upload-time = "2026-09-09T20:59:36.86Z" }, + { url = "https://files.pythonhosted.org/packages/33/28/5a13a340c9c759e863a0e7f765d323601d03d6538c8a627ed628662e083b/regex-2026.9.10-cp315-cp315-win_arm64.whl", hash = "sha256:75f9297b16fcb588a1f8d8a55dabef3c0c20b0c7bac43c87ceaaaf1a825c12f4", size = 281512, upload-time = "2026-09-09T20:59:38.875Z" }, + { url = "https://files.pythonhosted.org/packages/f7/38/a3caebcd5105be90708071db20bd261b0961b8ea4fe5e8be45c2632519b5/regex-2026.9.10-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:1270cdec69248592bbe38a0b263ed58d907b891bd2b93703e225c317e421bda1", size = 501336, upload-time = "2026-09-09T20:59:40.987Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b5/ec8887b2658bf0a5df143c7c1fcd562b0abd2fa208c04ebf15c6607c9bb2/regex-2026.9.10-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:681ed38664b64c6617d3c3c332018d1948c77e139c5ea667c1886efa671e426f", size = 299318, upload-time = "2026-09-09T20:59:43.039Z" }, + { url = "https://files.pythonhosted.org/packages/d5/58/84724a9eccf6e8cd46f7e4534576093e2476a5eeb55e2453aa6606e86059/regex-2026.9.10-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:8e127d9a80cbf1c3276bb465c6d047e8705e97b58c2b8f2f0c0a69c336b44b37", size = 294847, upload-time = "2026-09-09T20:59:44.954Z" }, + { url = "https://files.pythonhosted.org/packages/50/03/70ccc5e53905984abf8eab63eebd3ce740522ef8c8d392622b64d79ef290/regex-2026.9.10-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:990797e765d89a423880052c68b61c31afe701de94a8c060f61c40605ca6c727", size = 814359, upload-time = "2026-09-09T20:59:47.194Z" }, + { url = "https://files.pythonhosted.org/packages/29/53/40f7a11ec547e4a947883c9d5e8a075f6d4f59af2b8dbcaa8bf5b504aca0/regex-2026.9.10-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e5e4a6e0734a685d13b9685622bb503bdbb2927f8b0df025a5085f0ea067475b", size = 875586, upload-time = "2026-09-09T20:59:49.537Z" }, + { url = "https://files.pythonhosted.org/packages/0b/9d/83f3e022d99ce601727c4ef5f7b527753901ce4509ed89a1bb6a2263380a/regex-2026.9.10-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:63bb62cf62217dc38c8a6b2b61b165b0e4eb8fa93b0aba12139251c0986a8fa3", size = 920990, upload-time = "2026-09-09T20:59:51.776Z" }, + { url = "https://files.pythonhosted.org/packages/b2/64/dfdb367d8f4f5c9b8ccb4b59789c2ce996f2c69c3b8192aa986fe7d92ec4/regex-2026.9.10-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cb76a9c4e07a6a47849726af0ed14c41741a182f097f134a8cf29c1bc0f4dde8", size = 818660, upload-time = "2026-09-09T20:59:54.428Z" }, + { url = "https://files.pythonhosted.org/packages/88/a6/fb7d0b64487913845834f319aa84f8377d55305958a5db7e19c128798366/regex-2026.9.10-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:31e4df2b11d48f61d511019bc1ee9b477055f17c352b68fe72db7a98b14d603c", size = 794976, upload-time = "2026-09-09T20:59:56.799Z" }, + { url = "https://files.pythonhosted.org/packages/3e/1c/23484edaae387ea0d31f4d414463211e3516c8aa210ce8d0640f5aff3502/regex-2026.9.10-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:cf377960d2ac37d987394a9dbaa75e91338c41a46d41e1d25e90125e7b3ee2dc", size = 804081, upload-time = "2026-09-09T20:59:59.39Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e1/e30d138f13aecec99ea9aecef7e31563de6ec6a2f5ce1d65fc506aee33fe/regex-2026.9.10-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:c8fbd9cb30c68c1686b94029b9ef845d5870d3d65baf66cb126b676849b9d72b", size = 870430, upload-time = "2026-09-09T21:00:03.304Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/81f9ce86f7ae4f57901543597c95751fa01c41a672ec1636dd913f8a000a/regex-2026.9.10-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:53e182b6b04d0011909b47d51a2d72d908de07c7b1c7f16b3adda2204d723bc1", size = 783327, upload-time = "2026-09-09T21:00:05.68Z" }, + { url = "https://files.pythonhosted.org/packages/a9/1b/d7bf8f91534740f6a8ca17e5ac9c5337903baf527c8de240fbac1bbedfd0/regex-2026.9.10-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:0aa7589394230e0f0a422ab6b90841ff12c87e855e7aaf75d192a54a5f124548", size = 860874, upload-time = "2026-09-09T21:00:08.41Z" }, + { url = "https://files.pythonhosted.org/packages/9a/1d/52cc88364aca7c9013dfe9abe0fea67f8d394efe384d07798300a6e2f27d/regex-2026.9.10-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1b891f77554bff991804cee24b78b40789f7d5993a24c7907bc7025fd2a70c8d", size = 806705, upload-time = "2026-09-09T21:00:10.768Z" }, + { url = "https://files.pythonhosted.org/packages/cb/51/37a194df7707f92f33173260ba7b221d4ec376419a53babaec50019a2804/regex-2026.9.10-cp315-cp315t-win32.whl", hash = "sha256:5bef622850cf760154719d4e0d74b0a855962432995168e250069899ae12fe8f", size = 274780, upload-time = "2026-09-09T21:00:14.003Z" }, + { url = "https://files.pythonhosted.org/packages/77/12/3227a52970d90908b230f15b2c86df903f49ac72c9eedf4f6e8b5bb5e1a7/regex-2026.9.10-cp315-cp315t-win_amd64.whl", hash = "sha256:07b45ba5c94b8fcb30cb6c56a11f715c57533a3017964504322ea52690a27b72", size = 283936, upload-time = "2026-09-09T21:00:16.275Z" }, + { url = "https://files.pythonhosted.org/packages/f3/bc/c567c5a61671f04d30e83f20b496b465432879196574d051007285576205/regex-2026.9.10-cp315-cp315t-win_arm64.whl", hash = "sha256:f70b9f0e39c2dba1d9da6bf7ef7c377cad7277f8440e9a69be05ede529ff024c", size = 283747, upload-time = "2026-09-09T21:00:19.113Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "safetensors" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/06/f955dbbb1859e3bd23c8ac6141af5106e7ad5fedec4a3a6e3d60f94b7001/safetensors-0.8.0.tar.gz", hash = "sha256:fabaf3e0f18a6618d9b36560682562157f77c2b71fcffc7b432be2baed9d753d", size = 325846, upload-time = "2026-06-09T07:52:25.563Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/a0/f718cda65b05407d228f97602cf60dca269c979867aa5beb25410de26cd3/safetensors-0.8.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c554f85858e05226d3c2828e32395e677434685d6d94594a41643361c5e837f0", size = 473568, upload-time = "2026-06-09T07:52:18.829Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b1/fa7c600e7dceae12e9606c7578cbc9ff1e1ed55844883ee5c92205e86226/safetensors-0.8.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:c80201d22cbf405b80647a60ada77bba06c8fba2da2743ba1e89cdcc39a81f25", size = 484562, upload-time = "2026-06-09T07:52:17.518Z" }, + { url = "https://files.pythonhosted.org/packages/09/7d/65a7de0af421317bb36a067241e4235fff194eed60b961ed6d3f59a3fc60/safetensors-0.8.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a46e5ff292c356d6991e60942ba7f79817682d3a2cef0702136448cb9c4d235", size = 502844, upload-time = "2026-06-09T07:52:07.624Z" }, + { url = "https://files.pythonhosted.org/packages/91/4f/3175c9d75634e0e0dda0082794193521035edd7c70a6f212bf33ca06ddf4/safetensors-0.8.0-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4124502b78f03534117c848f87a39b8f31e577b15eff423bf8bfb95f2a8c30d0", size = 511823, upload-time = "2026-06-09T07:52:09.565Z" }, + { url = "https://files.pythonhosted.org/packages/20/87/846c289e7aa2299eff406335717cf43ce8777194ece8aad75772e0411615/safetensors-0.8.0-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc0a787ba8a35be368ee3574edfa2b1ad389eebd0a72e482ae275490e3f6c98", size = 633461, upload-time = "2026-06-09T07:52:11.128Z" }, + { url = "https://files.pythonhosted.org/packages/76/22/8d64d9df2c45d5ded401df889d0ad90882804ca172d79ec4f0df8f727fe0/safetensors-0.8.0-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040070828e36dc8e122178bbbd5830ff9e97920affb84cbe0f46442497bed358", size = 545148, upload-time = "2026-06-09T07:52:13.603Z" }, + { url = "https://files.pythonhosted.org/packages/28/50/f203ff3a3ddfe19308efc83c5a3a29ed02bf786732ec35e68bf9162f3365/safetensors-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6f3f93c9a0a7cc2788ee63fb763353d4bd2e89b0751bc78fcf7dda00bea774", size = 516040, upload-time = "2026-06-09T07:52:16.29Z" }, + { url = "https://files.pythonhosted.org/packages/46/fb/cdaed17ceb2948784fd9c36b6fd3e951b608547cea81a48e8ee6f8cfdfcb/safetensors-0.8.0-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:fcdd41ec4628fee5799f807c73c353629130fbd942aa23d83c623dd6c9d52d78", size = 513832, upload-time = "2026-06-09T07:52:12.37Z" }, + { url = "https://files.pythonhosted.org/packages/0d/49/1e15de264dcc3b77943d2d0c56a95809956883b1c2d6d585c792523f180b/safetensors-0.8.0-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e9f537aa183a38ace122d27303dcd986b26bd2a7591f9181d7f0c396f4677ca", size = 559930, upload-time = "2026-06-09T07:52:14.743Z" }, + { url = "https://files.pythonhosted.org/packages/2a/43/bf38443278eab4b1be1fce2931e2b012ad9cb7df52ada751d0aab8f7659a/safetensors-0.8.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:87eec7ffed2b809f05a398a8becb7d013f19f7837cd15d9748580d6cf30dbaf4", size = 678670, upload-time = "2026-06-09T07:52:20.032Z" }, + { url = "https://files.pythonhosted.org/packages/72/e3/68cd3fa5b48488e84add63e04cb12f3bc28ae4638c06d4508c6e88823d0e/safetensors-0.8.0-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:4a95ae2b05d7726d751da4ebf626a2ca782b706e101bd894c95bc2450b1cffcc", size = 786679, upload-time = "2026-06-09T07:52:21.322Z" }, + { url = "https://files.pythonhosted.org/packages/29/4b/1c19c509d56e01f4fbb3d0a2e597450f6cc04d1d56cf52defb0a62dfd715/safetensors-0.8.0-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:3ae091f16662658bdc019a4ff6cb4c085bb7d725eb5978b183ffd265863b6d2d", size = 765683, upload-time = "2026-06-09T07:52:22.594Z" }, + { url = "https://files.pythonhosted.org/packages/27/43/41c1621732edd934d868a00d1b891584c892a7b62a9aab82ea5a0a5623ee/safetensors-0.8.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8e080062fcde23be189565e1c3305d16751a218ecf9412c8601e64204eb6f846", size = 722361, upload-time = "2026-06-09T07:52:23.924Z" }, + { url = "https://files.pythonhosted.org/packages/8e/3f/73ccf82579412b4a71c4ca673f10b5f1f888d7cf5af7fe24f27d30307be4/safetensors-0.8.0-cp310-abi3-win32.whl", hash = "sha256:2ddf52eac562eda224f99acfa7889d02968c1fd59a5b011ae7d8137c37e9c02d", size = 342401, upload-time = "2026-06-09T07:52:28.895Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6d/3fba214c1e5e0f69991677ec3bc17023f0421776975e1de0c682dca475e2/safetensors-0.8.0-cp310-abi3-win_amd64.whl", hash = "sha256:096ec1a98435df7beb08853bb5aa9081a84f23d0adc67ed1a0a10550f608373f", size = 355540, upload-time = "2026-06-09T07:52:27.832Z" }, + { url = "https://files.pythonhosted.org/packages/8d/fc/7eedc3510d97878876e32774eebbeb61c43f148a96e915c84229a3e967aa/safetensors-0.8.0-cp310-abi3-win_arm64.whl", hash = "sha256:f7838e5135a406ad3e02efdcb8cf2e5397d368b0154537c4fec682dbc544d452", size = 340500, upload-time = "2026-06-09T07:52:26.745Z" }, +] + +[[package]] +name = "scikit-learn" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "narwhals" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d2/eb/eaf5e07fcc0da7149b0e084f24e54edd7441b9a89ce7e034032ae97fe3a0/scikit_learn-1.9.1.tar.gz", hash = "sha256:629cada3e33e2b9bf376cdc7614a47a4140b8aedc1d836579e359736fbd82977", size = 7786908, upload-time = "2026-09-10T18:34:04.679Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/e3/b58e45082dcf3dcf0eb1192ee03545ec43d8c98441dfe20e88afca8442ce/scikit_learn-1.9.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d5d117952769b563067656784e03c75a2d8235a7a05cf7fffa78a311e75aac08", size = 8747414, upload-time = "2026-09-10T18:33:10.698Z" }, + { url = "https://files.pythonhosted.org/packages/9b/ed/d68115577c8b42b0442ebd8180945d4008880a33176094640e00b585128e/scikit_learn-1.9.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:8893bc6331f60f18d4ac75e12ed356e2dcf6a564bf767918b5b7ca54c8c8be49", size = 8279175, upload-time = "2026-09-10T18:33:12.846Z" }, + { url = "https://files.pythonhosted.org/packages/c4/6c/06c7eb61a438e389cbf3f7210897069bec5a883dbe03c189ae792781e11a/scikit_learn-1.9.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5492cf2df5226691c32611de8734bcf42148c6547ae53c7f4e6b847793addc0", size = 8881706, upload-time = "2026-09-10T18:33:14.741Z" }, + { url = "https://files.pythonhosted.org/packages/86/4e/0bab75490ca4b85fad8388739c7ebc71d9db553f8c69e39943ee8db0aaae/scikit_learn-1.9.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:993d332ff80e62efae9e39603b7e872297c418d780f01a01855269a3489c950f", size = 9152030, upload-time = "2026-09-10T18:33:17.436Z" }, + { url = "https://files.pythonhosted.org/packages/9a/13/31c6f8ba1b7eecef9dd9558576c752d2ec5785fd0e456bb9fc59305be23f/scikit_learn-1.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:ca9051447455dae341d4d591eece7deb2d8e3d1020298fc87a81fc51e4da8f53", size = 8377024, upload-time = "2026-09-10T18:33:19.941Z" }, + { url = "https://files.pythonhosted.org/packages/62/e6/6d3cb8a45f5228f915acd66b819dd6b8232ccbe24532f51d278e3991df31/scikit_learn-1.9.1-cp314-cp314-win_arm64.whl", hash = "sha256:90de6573f733a9fb79476ff1371af52a397d41c8b35f9146e20923db010d67b6", size = 8014196, upload-time = "2026-09-10T18:33:22.126Z" }, + { url = "https://files.pythonhosted.org/packages/66/6e/6befb2d5961490d18d9dbc16a5df37aa121d08bc9893316a6a363977a903/scikit_learn-1.9.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7b5cad1624de8b75e5b9ccb7b0ce1ff1d01306340a3efc56d5529c5ba92392eb", size = 9066066, upload-time = "2026-09-10T18:33:24.396Z" }, + { url = "https://files.pythonhosted.org/packages/cb/18/11271f2f7db337db01f598e358721b1e83989407131272e5dd64214c28a8/scikit_learn-1.9.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:d137ce8a6142029fb5c35bd82f470c40cd9e760e5e2f7694b362c497c4ab3fa2", size = 8647654, upload-time = "2026-09-10T18:33:26.649Z" }, + { url = "https://files.pythonhosted.org/packages/e7/04/9c15d201e1b6a2e81b8215865df7646c5a360f560831769c8dc92ac1ab9a/scikit_learn-1.9.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66f852f7325b5070bc28329005aca76055a2def78faac039548ae889aeaa45a6", size = 8889070, upload-time = "2026-09-10T18:33:28.95Z" }, + { url = "https://files.pythonhosted.org/packages/1a/5a/4cb6c85160af4a639e87a3b7bf8b1c25cfc3b504c5af710ca416a6dcfc5f/scikit_learn-1.9.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:748bcb0a4cc04aec470652c9e5ec68450948e867387e7dfade647107ade68d25", size = 9131227, upload-time = "2026-09-10T18:33:31.008Z" }, + { url = "https://files.pythonhosted.org/packages/00/0e/361440972ae3d19b90ea88a84791138a51de0e8432a770ba741b2c8d9ced/scikit_learn-1.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:38cd925e893e5539be704d5edc64dbe081aacdab6b89d8c2977c1f6a7a453ce5", size = 8683001, upload-time = "2026-09-10T18:33:33.188Z" }, + { url = "https://files.pythonhosted.org/packages/e2/8f/a9f405c5c0e2df6f343a871b40c97fb32969e3ccc38e3033dd118f3c261e/scikit_learn-1.9.1-cp314-cp314t-win_arm64.whl", hash = "sha256:b01e5b01735d38474127ca3f49319b592506225a87793b27559816b5c75cea39", size = 8257996, upload-time = "2026-09-10T18:33:35.343Z" }, + { url = "https://files.pythonhosted.org/packages/e5/c5/74a83ea39cef7cd07f53e06cc1cf51e79f35df74f81db956835d59ec34b1/scikit_learn-1.9.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:8dec64f31a6e0ec826aca6c1b39a51e16d946e400d4c0904316f3ca72ccfb825", size = 8747991, upload-time = "2026-09-10T18:33:37.4Z" }, + { url = "https://files.pythonhosted.org/packages/64/c9/cc93e8a7fe204e43d70e96e5eb89871643be20025eea05eb4fdaf19afe39/scikit_learn-1.9.1-cp315-cp315-macosx_12_0_arm64.whl", hash = "sha256:e1b468241f4a7a9a7a0d6479ad3cc47681cc151a4046c530f2777c3d68f08942", size = 8279340, upload-time = "2026-09-10T18:33:39.705Z" }, + { url = "https://files.pythonhosted.org/packages/a2/61/0c6080f0d356fb966053009e7f25e9bff6cf74b0b16195ccf0c3757d1ae8/scikit_learn-1.9.1-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ca869d0080a5723cde2d5a8b54a2da1ff7e68735a9e9adb3da1243183a0fa01", size = 8881917, upload-time = "2026-09-10T18:33:41.912Z" }, + { url = "https://files.pythonhosted.org/packages/47/bb/98a31f10fffbd39edcc2f8bf4119b29652248bb110b7d45c84e68aa293ab/scikit_learn-1.9.1-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6754b7cabfc3df0b1f7b38f7a344f559bbae9d82f0ac5e3d48cccbd19fdcefdf", size = 9152805, upload-time = "2026-09-10T18:33:44.23Z" }, + { url = "https://files.pythonhosted.org/packages/f6/48/858ceff52213cfd97c0a069362071756bcb70b9fac9771b38d87c4cf7f17/scikit_learn-1.9.1-cp315-cp315-win_amd64.whl", hash = "sha256:52cfdb1fed3a34362dbc0bd96f2e761a66fd5724d6901629f5a558f1f3bd9849", size = 8376719, upload-time = "2026-09-10T18:33:46.492Z" }, + { url = "https://files.pythonhosted.org/packages/2a/1e/5337a871bdea53effbd154b61429df048f2665653251de74a3bd8a6dea9e/scikit_learn-1.9.1-cp315-cp315-win_arm64.whl", hash = "sha256:ae6571a4828c6f5019bcd2b4125e5b18c0af3dbc9c99726c891f45f41335ec8e", size = 8014341, upload-time = "2026-09-10T18:33:48.762Z" }, + { url = "https://files.pythonhosted.org/packages/0e/35/150383a42d83ec4c7b39f9c50bd68408ecf04c19fc30ea5198fa42e67d9c/scikit_learn-1.9.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:48fefd8eb42bd4eec3e2d348149368ccd6d71987e20c30706a56a24eb86a6e73", size = 9059953, upload-time = "2026-09-10T18:33:50.951Z" }, + { url = "https://files.pythonhosted.org/packages/9f/dd/aa0d738808540f7eaacfab93e01982db8ef1c1c7473ef0ad38193e6aebd1/scikit_learn-1.9.1-cp315-cp315t-macosx_12_0_arm64.whl", hash = "sha256:09f4d73049cd63575157f6b1060e06a8c83a4bd3488dbfaeedf35ccba7aad712", size = 8646602, upload-time = "2026-09-10T18:33:53.23Z" }, + { url = "https://files.pythonhosted.org/packages/7e/cc/687ae4214c2f598906c3b9fa5f86fbaf834b35e20360625528ff1b713f06/scikit_learn-1.9.1-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3da53831534214322d9cb240fa6f390b36cf69eba727a6d4bd3238677630d70", size = 8880366, upload-time = "2026-09-10T18:33:55.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/03/82215cb78ad1c513a4498777571fb28444621ad26ef636287551767b7732/scikit_learn-1.9.1-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caae15634feceafa2612566b109a3082d3293167fac388eedaf77bff66b51983", size = 9129640, upload-time = "2026-09-10T18:33:58.186Z" }, + { url = "https://files.pythonhosted.org/packages/d4/90/4b7af4efd7909a4a0524a9f18457e4eb2eb60616eff2c7627eda8e3cdceb/scikit_learn-1.9.1-cp315-cp315t-win_amd64.whl", hash = "sha256:ffbcbbbb44202fbe9bc64bced25a145759adb9ef010b3d37a8064958ac13df2a", size = 8678083, upload-time = "2026-09-10T18:34:00.354Z" }, + { url = "https://files.pythonhosted.org/packages/31/27/068e484d4b83004302e0d9cfc1faca69bcc010d76fbb66a642446095af1b/scikit_learn-1.9.1-cp315-cp315t-win_arm64.whl", hash = "sha256:800dd22dd87fe97dcea484c24e85dd93cf1734d86bd74e668ad18f7967f4d1b5", size = 8259434, upload-time = "2026-09-10T18:34:02.678Z" }, +] + +[[package]] +name = "scipy" +version = "1.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7e/74/66de6258867beb2ef08f35f9f2ac017a52cacd5081714d239ff1a442d458/scipy-1.18.1.tar.gz", hash = "sha256:52c4b7422442aba924d03ad4019852b08a92e64ea187b933135687bfe2747307", size = 30781235, upload-time = "2026-08-21T23:28:50.599Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/d5/d8eb4e280ddb56a4ab2c6f02ee49b56b23f6e977cf0802fd6d68dbef14f5/scipy-1.18.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:83de5453a7799afc9048b4616bd085cef126e36412f0ea2f6370c36a2a3a51e7", size = 31090936, upload-time = "2026-08-21T23:25:28.686Z" }, + { url = "https://files.pythonhosted.org/packages/2a/49/59ea385dc3a62ff498ddf3cfff7c2b41b0f9f9d3c4122b3f1dcb6d6327fe/scipy-1.18.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:9554bcc6d715ee87a633a3cc8e7703c6628b100dd29cb8a2efc4c0533c7ff729", size = 28725221, upload-time = "2026-08-21T23:25:33.244Z" }, + { url = "https://files.pythonhosted.org/packages/70/e8/6b0c288c50942d78193696c9f15f9a0874f5178aa0ddf40f83d9924b3e8d/scipy-1.18.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:011413b7426b75012840e35649e00fe0a2c3bae89fed433876e3a99251572efc", size = 20466839, upload-time = "2026-08-21T23:25:37.516Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e0/54fd3793c729e3b936782f181b59cbb1205bf250ab605a16cb1ba61cdd5e/scipy-1.18.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:88f0e784020649f88ea48c9f5ddfa403bf9205820667c0914740b392035afb82", size = 23089121, upload-time = "2026-08-21T23:25:42.019Z" }, + { url = "https://files.pythonhosted.org/packages/0b/56/030af62bea3cf878e0028515dff78c123b01633606a879b63f42d2db99cc/scipy-1.18.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d3ab0e8c69a17dd3559eab8cbb88f258e285c94d572c2719033f90f83290c89", size = 34053851, upload-time = "2026-08-21T23:25:47.998Z" }, + { url = "https://files.pythonhosted.org/packages/6b/89/2a844506d49651e9aa1af6ef95b6bd8031cb1d5a4375edec6155037e04cf/scipy-1.18.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac0333bdf38309aa3dcbe7e3fa7ea29e7a2c37c6ea306a757b700ded8e4596ad", size = 35329183, upload-time = "2026-08-21T23:25:53.522Z" }, + { url = "https://files.pythonhosted.org/packages/eb/56/c7370c3640e92ac9613cbf26cb3f729f9b12ddf1727b55b94b53b24d6f48/scipy-1.18.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:911de823097db8b63f034299d12662db93344e6ffa0b881cbb57748974b70168", size = 35672551, upload-time = "2026-08-21T23:25:59.387Z" }, + { url = "https://files.pythonhosted.org/packages/24/16/ec8536f351421f8bf60a1120930638f83790f4710b8230446aca3d6159d4/scipy-1.18.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:95298364e251be3e60249facbeeca03631d3bb7584f85879516ec55ac717b81f", size = 37469416, upload-time = "2026-08-21T23:26:05.432Z" }, + { url = "https://files.pythonhosted.org/packages/52/94/d73da0d28f16c45bb9b0a5691b91610b0275c5ef0eb5e43c87cf2dc1bf31/scipy-1.18.1-cp314-cp314-win_amd64.whl", hash = "sha256:78a0d7c918e74a232394117160e7e3db503377572a45bcef8826e4ab8a35feba", size = 37362755, upload-time = "2026-08-21T23:26:11.366Z" }, + { url = "https://files.pythonhosted.org/packages/89/25/e996e4dc74e10e227b1e14db5eaf6608bb6dd33884a64851c38f18dd4249/scipy-1.18.1-cp314-cp314-win_arm64.whl", hash = "sha256:cbf38d043c1aa4ab306e1ada6ab6eddacc3322a20b7af1b30bc93254b366fe09", size = 25036090, upload-time = "2026-08-21T23:26:15.887Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c9/c00213f92309d753b48903e6a451b87eb52ff5b7a16e789d1568bbf221c4/scipy-1.18.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0fcb3c93519f27bb4f0c4b0f7802cdcaca7fcf93267b75edda2e9f4e8a55cbd7", size = 31485550, upload-time = "2026-08-21T23:26:20.776Z" }, + { url = "https://files.pythonhosted.org/packages/74/b2/e3067c487982d4eeab2938928529410370c06fea84a4d3f4925e7d96647d/scipy-1.18.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:ddef79fb382df40104a19bb7151b3b23e57c1778fcf857c71ceecd9bd264513f", size = 29174642, upload-time = "2026-08-21T23:26:25.395Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ab/374c9fe2d1ec014e576c781a4b5d8e1ba340e8f6b4638c16f711d2b194f0/scipy-1.18.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0e82073ecc7acc6436fac4b31674109c7e1d3e596789767eda01258a8c9e8123", size = 20916357, upload-time = "2026-08-21T23:26:30.112Z" }, + { url = "https://files.pythonhosted.org/packages/90/38/223915c88a17317cafbf8ca2a42b11c265a9fb1e804aa665544132b5fe8a/scipy-1.18.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8bcf3c1ba5d6456e2effd30fcbd3459b044d683fcdac79a2e6830f0bdf7de487", size = 23482611, upload-time = "2026-08-21T23:26:34.846Z" }, + { url = "https://files.pythonhosted.org/packages/c4/d1/db0948da8ca57a80b36520ef0a768b967d99f3af65f4b6f1bf6362ad4dd4/scipy-1.18.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cfbf154f2ba187f2ed6cce2639efff7d105f1140573642c0161615b6d91d6a87", size = 34143202, upload-time = "2026-08-21T23:26:40.4Z" }, + { url = "https://files.pythonhosted.org/packages/87/53/39d046cc7574ed6acacb6bd5723e220107ece80bff12faaf3efc4ddeede4/scipy-1.18.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a1d33a7836f7ddc1993427966a0823468ec41bcbdb1a9f9942d1d7e57f803ba3", size = 35380876, upload-time = "2026-08-21T23:26:46.1Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/32e0e799d875a85ca57d9bde6c78148afcc0e38276df683d95854eadc8c3/scipy-1.18.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7f4b8bc363b6d65ee2152bec57568e3c52639bb34c46057b09857a307ed5e21d", size = 35770885, upload-time = "2026-08-21T23:26:51.533Z" }, + { url = "https://files.pythonhosted.org/packages/88/2e/f97a666d362fee68b18f41c9c30ed502ca5c98b549749bfcb52a8b74d1eb/scipy-1.18.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:11c423f1049c5755ad4409af52a9ada1cff96fe9b50795d4af3619f292901239", size = 37525424, upload-time = "2026-08-21T23:26:56.751Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d5/a9e765a84654ebba8479a1fd1b059ced1af72b168a3b2a3a46540ea38d20/scipy-1.18.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c24acac1e18912761c4700239bbc1fd32f615af690f1584d49b35859be51324d", size = 37416961, upload-time = "2026-08-21T23:27:01.546Z" }, + { url = "https://files.pythonhosted.org/packages/ee/16/e79e0d1c63ef698879d85439d37e9fb434e3b804e506a6991038d086ebd9/scipy-1.18.1-cp314-cp314t-win_arm64.whl", hash = "sha256:9f2897bf7737392ad0d5213ea7b6add72a4edf5679b3153106aeb88b6507b3b9", size = 25331848, upload-time = "2026-08-21T23:27:05.884Z" }, + { url = "https://files.pythonhosted.org/packages/be/4f/1bd37c883b67163e2ca1f60977a399500e6879c15defecac62831c8d078d/scipy-1.18.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:eb0dfcf4e28a99c12c999744a2ff67c9b06200e20401c7c88186e33552a46331", size = 31091484, upload-time = "2026-08-21T23:27:11.051Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c5/ba929d7feb9b2332f96827c12e0e924b61973b59b4dea383b603372c65ce/scipy-1.18.1-cp315-cp315-macosx_12_0_arm64.whl", hash = "sha256:30f464bee641fa8e282577c7dce027308403213c6ca8270bba73285c91024bc5", size = 28725057, upload-time = "2026-08-21T23:27:15.9Z" }, + { url = "https://files.pythonhosted.org/packages/a4/19/68f1c50f609d955d230e66d25d02bd3e1e167ec540232135354fb9a4b9e3/scipy-1.18.1-cp315-cp315-macosx_14_0_arm64.whl", hash = "sha256:1bca3b943fc2567ea49cd02c99abde49da4d5178ec46f624bd8255cda8755beb", size = 20466734, upload-time = "2026-08-21T23:27:20.044Z" }, + { url = "https://files.pythonhosted.org/packages/ef/6d/319fa29b73d1802fa80b32a6eaf3f5be456ef81526da2716a9493bcb5501/scipy-1.18.1-cp315-cp315-macosx_14_0_x86_64.whl", hash = "sha256:c9d18a33309122074ea483dd92dd444189166b8b2ec429fe9ed5ac73c7a0aa23", size = 23089664, upload-time = "2026-08-21T23:27:24.345Z" }, + { url = "https://files.pythonhosted.org/packages/b7/db/30992f9b51a63de671daf3888ffd18378b6cb9ec9f2c972264238ffa7fd6/scipy-1.18.1-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82f201b4c878551d48558337aab270d3c6cca5507b8737c8d8a608d234cccde0", size = 34054035, upload-time = "2026-08-21T23:27:29.409Z" }, + { url = "https://files.pythonhosted.org/packages/91/d4/bf3e735dc0b9d5a8ff45079d2540e17d3aff7a2f0048dd8f552ffd031d2b/scipy-1.18.1-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ac49ea97594532dd44b7136094d35f5440fa06e6d9c6384a74c01764df388c5", size = 35333883, upload-time = "2026-08-21T23:27:34.293Z" }, + { url = "https://files.pythonhosted.org/packages/19/93/12d78ce9f871fe945fca588d32644e6e63f553c2a35c564d73f3b22a3313/scipy-1.18.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:ceb30a00ce7c92d459819443d29ca486d882b83fb6738bdcbb2a1cce94ac5daa", size = 35673124, upload-time = "2026-08-21T23:27:39.059Z" }, + { url = "https://files.pythonhosted.org/packages/70/cd/886219313a1012a48e6ae0ec4f302c837151beb92e1ff0d709ef8fdfc488/scipy-1.18.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:f29633129f9fa7e88a3f0fca835de2d030bfc9643f7799e1a0c46cee24d38fc7", size = 37470753, upload-time = "2026-08-21T23:27:44.435Z" }, + { url = "https://files.pythonhosted.org/packages/17/6c/a776888ce618bee54fbde26172f0f46ac1da70d27b63861797fe78e1904b/scipy-1.18.1-cp315-cp315-win_amd64.whl", hash = "sha256:92c14f5bdbfb6216315ce33e78080474082de8b3830122ba97809bfbe65f75c0", size = 37361483, upload-time = "2026-08-21T23:27:49.334Z" }, + { url = "https://files.pythonhosted.org/packages/ab/09/97b651691322ebee97999b017ffc18a15a0b815103844c97e8da9d469731/scipy-1.18.1-cp315-cp315-win_arm64.whl", hash = "sha256:e402cf31eb68f453dbb2d36fc6d722b33f24a55d68b2ae1d92fa6305ca71c298", size = 25035883, upload-time = "2026-08-21T23:27:53.596Z" }, + { url = "https://files.pythonhosted.org/packages/ed/0f/9ec20467bbabd0d44e2a77d0fd3d124f884b4d67df92af82c91d2d6a486f/scipy-1.18.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:2a0b02f9fc46f8520330c23d45e6560db7e3a0d927232139427637f98943e11d", size = 31474926, upload-time = "2026-08-21T23:27:57.993Z" }, + { url = "https://files.pythonhosted.org/packages/8a/58/dcb79161e56efbedc50079fcd2f5fe427a0ebb53022eb476aa73c015ad8f/scipy-1.18.1-cp315-cp315t-macosx_12_0_arm64.whl", hash = "sha256:1d73131e358976663dd969e1fb4ed1404b815cd977eaaedc3b3a133ba2d81c35", size = 29164940, upload-time = "2026-08-21T23:28:03.062Z" }, + { url = "https://files.pythonhosted.org/packages/71/d3/1eeea80c817fcb8ef7bd4a05a58824977a0e57a375cfc3d7ea7c911c01ad/scipy-1.18.1-cp315-cp315t-macosx_14_0_arm64.whl", hash = "sha256:bff0b729edd992766136b34e39cc76bc2fad905aa58897ee72a9cd000a6d8443", size = 20906742, upload-time = "2026-08-21T23:28:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/54/46/e59350428b6099301a20128108c995e2eb175a43f383af9a346e38824f9b/scipy-1.18.1-cp315-cp315t-macosx_14_0_x86_64.whl", hash = "sha256:10ac20c69d880f77f375db44c22e3e6a644f9fefa291d4cd2fb9790a89fc99fd", size = 23472183, upload-time = "2026-08-21T23:28:12.109Z" }, + { url = "https://files.pythonhosted.org/packages/89/31/cc91623fa98f0621766a0f0aaaadb2c66de74a7ea7e3837164f6e4354260/scipy-1.18.1-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33a834464fdabc0f26a45508df31b3cc5d028e04dbf6c5ed398541418e0a12fe", size = 34130796, upload-time = "2026-08-21T23:28:17.906Z" }, + { url = "https://files.pythonhosted.org/packages/fc/3e/8572ef536957ddb8aa81bb4090d9e25f257e3b4e05d97deb54319deb8a3a/scipy-1.18.1-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49023963c193dacee096301452f223ee24d86ec5807f8df93c0f7221d119e305", size = 35374253, upload-time = "2026-08-21T23:28:23.732Z" }, + { url = "https://files.pythonhosted.org/packages/b5/c6/59fdeffb4f1435299f93d9dc8140b43ad2916e6cfc944be6c3041fcec86d/scipy-1.18.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:d84a09d0dad90ba6525d8ac1c2334b33e64bf3ccfe9e841f02feb867a22681e4", size = 35758543, upload-time = "2026-08-21T23:28:29.431Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d9/135be205d9de8783193aff9cc3bf483a03a38e4b29432c954e8cb66ac14e/scipy-1.18.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:179ce34a8d0fe273d8883ba59e17e052247d08973dfcb743ca52bb1cce2d60b0", size = 37521946, upload-time = "2026-08-21T23:28:35.245Z" }, + { url = "https://files.pythonhosted.org/packages/5c/a2/5b7d5270621ab7cfa3f7766067bf95dc360b5efb6394694e8143b4156e2b/scipy-1.18.1-cp315-cp315t-win_amd64.whl", hash = "sha256:5632e3ae3d09197c446310cd5187de63e28448ce22f0f67b2b93d97503c0c230", size = 37408295, upload-time = "2026-08-21T23:28:40.724Z" }, + { url = "https://files.pythonhosted.org/packages/63/ad/741c19fcb66755ff953daf9243af8480e4bf3d7fbe57583c178c7d2b6b51/scipy-1.18.1-cp315-cp315t-win_arm64.whl", hash = "sha256:eda632a7981f69730d6281f451db9c1c370993a2c0d7ddb43e2a809a2862b83a", size = 25319710, upload-time = "2026-08-21T23:28:45.713Z" }, +] + +[[package]] +name = "setuptools" +version = "78.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/5a/0db4da3bc908df06e5efae42b44e75c81dd52716e10192ff36d0c1c8e379/setuptools-78.1.0.tar.gz", hash = "sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54", size = 1367827, upload-time = "2025-03-25T22:49:35.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/21/f43f0a1fa8b06b32812e0975981f4677d28e0f3271601dc88ac5a5b83220/setuptools-78.1.0-py3-none-any.whl", hash = "sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8", size = 1256108, upload-time = "2025-03-25T22:49:33.13Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "sounddevice" +version = "0.5.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ec/db/0c890e2d9aab9ba284021efc02e1d3aebfecab1b611762d7434602209bcf/sounddevice-0.5.6.tar.gz", hash = "sha256:8ec9fbfde2e32f020b167e348f3ab3bac6625a5f15af524d790108ac7147a410", size = 1120094, upload-time = "2026-08-17T07:55:05.048Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/1f/62eef605172bddc1017508469a12f75bc7c4194ece35c734f822795f53b1/sounddevice-0.5.6-py3-none-any.whl", hash = "sha256:de099612311ad81e55d31ccbd83f43ea6bf4d87b48f9b6ea55a1fbcde0eee4e0", size = 32793, upload-time = "2026-08-17T07:54:57.507Z" }, + { url = "https://files.pythonhosted.org/packages/b6/84/85e719d49cf98b2f406d9ac9c338892286c4448eb42ef0b2625ccf159616/sounddevice-0.5.6-py3-none-macosx_10_6_x86_64.macosx_10_6_universal2.whl", hash = "sha256:e3aef00ad8b1d1740eb66d9a7671eab88a4d2b8fa4ab33498d742e63b65c309c", size = 1009647, upload-time = "2026-08-17T07:54:58.814Z" }, + { url = "https://files.pythonhosted.org/packages/c5/6f/6292145099f72a153a710245f46ae43e5fb6c77bec1b6086cb76c12dc280/sounddevice-0.5.6-py3-none-win32.whl", hash = "sha256:b36b807eb02abd257198bf84b2af05e4fea199a9d2f0019014169c7136d45e9c", size = 1009627, upload-time = "2026-08-17T07:55:00.401Z" }, + { url = "https://files.pythonhosted.org/packages/8d/3e/cbc593c31a5f0d817b3fe97e64aa8461bd0f55cb07b67ce1b776296ae336/sounddevice-0.5.6-py3-none-win_amd64.whl", hash = "sha256:7f4162f514f007b0bf25a3ccfed3f1705bc2ec311888a90232729eec4f57a4f4", size = 1009630, upload-time = "2026-08-17T07:55:02.088Z" }, + { url = "https://files.pythonhosted.org/packages/60/a4/b0c21c9f215a6fd9606b8f8748c21212dc098e5d5a2d93068c50edcf19b4/sounddevice-0.5.6-py3-none-win_arm64.whl", hash = "sha256:c8ae19173e5f27f8c12d4b5eee2dbfe542cee125d591e663e0fb4dfb75246d45", size = 1009630, upload-time = "2026-08-17T07:55:03.689Z" }, +] + +[[package]] +name = "soundfile" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, + { name = "numpy" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d2/db/949331952a6fb1c5b12e9de80fd08747966c2039d1a61db4764fbd3981c2/soundfile-0.14.0.tar.gz", hash = "sha256:ba1c1a2d618bca5c406647c83b89f07cc8810fa506a50622a6993ba130c1de11", size = 47842, upload-time = "2026-06-06T08:58:47.869Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/d1/5e338af9ca6ed0786cd5bb03f6d60de1c325728c1189014f3b59aae7403c/soundfile-0.14.0-py2.py3-none-any.whl", hash = "sha256:8ba81ae3a89fd5ab3bef8a8eb481fbbe794e806309675a89b4df48b8d31908a8", size = 26799, upload-time = "2026-06-06T08:58:33.269Z" }, + { url = "https://files.pythonhosted.org/packages/7e/72/c6b21e58d3113596e7e8de0a08d6f1d95173492cfbca0a4db14148cbba2a/soundfile-0.14.0-py2.py3-none-macosx_10_9_x86_64.whl", hash = "sha256:19be05428da76ed61a4cad29b8e4bcf43a3e5c100089d2ec81dc961eed1b0dd4", size = 1144568, upload-time = "2026-06-06T08:58:35.231Z" }, + { url = "https://files.pythonhosted.org/packages/63/7a/dfdd6f8c748988427119f75eb860a3cedd858d1aea1fe28f39ad8559ef22/soundfile-0.14.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:d828d35a059626da52f1415b5faee610aeab393319cb3fc4a9aef47b619fc14c", size = 1103726, upload-time = "2026-06-06T08:58:37.948Z" }, + { url = "https://files.pythonhosted.org/packages/4a/f8/fc39fad6f879633461d27394cd1ddaf1f769ffa0597dca35872f51b16461/soundfile-0.14.0-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:e85724a90bc99a6e8062c0b4ddf725f53b2a3b70afd4da875e9d2cfc4e92f377", size = 1238050, upload-time = "2026-06-06T08:58:39.932Z" }, + { url = "https://files.pythonhosted.org/packages/7b/a2/70fd4432b924684c372df8b0a45708c36c057ef3596c9eb53e0a806b980b/soundfile-0.14.0-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:1e38bac1853412871318e82a1ba69a8be677619b56025bbfcccdb41b6cafe82d", size = 1315963, upload-time = "2026-06-06T08:58:41.716Z" }, + { url = "https://files.pythonhosted.org/packages/d9/34/c9e80783d83eab739a9531fdee03675d53e0bf1b2ccb4bb3af5844675046/soundfile-0.14.0-py2.py3-none-win32.whl", hash = "sha256:0a6ae43c50c71b4e020cc55382925cb89451c1ed1a0c3d0f5d802da269226849", size = 902199, upload-time = "2026-06-06T08:58:43.289Z" }, + { url = "https://files.pythonhosted.org/packages/ed/97/b39c18ac1df45e755ca22b8b00e872929da5d107998a207a5e4ac831bfda/soundfile-0.14.0-py2.py3-none-win_amd64.whl", hash = "sha256:299491d3499460fb1b74bb4bd78b57ffc2d243a5fafa7b6ec1b264875c78453e", size = 1021480, upload-time = "2026-06-06T08:58:45.016Z" }, + { url = "https://files.pythonhosted.org/packages/f4/83/55c65e61cf457805ce2ec157c1c6ae17715d0851aa2374422de0538838ca/soundfile-0.14.0-py2.py3-none-win_arm64.whl", hash = "sha256:e090704718e124e7c844695236f1fce8d18a5e761eaf7c82dfcd124620805f98", size = 888858, upload-time = "2026-06-06T08:58:46.593Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "threadpoolctl" +version = "3.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/dc/6c58154c1c65f758ea979e7139cb76993a9cfc662d14e9be3c4a667cfb77/threadpoolctl-3.7.0.tar.gz", hash = "sha256:61348cfb77d53b9242e0017029244b559b810c142ced65b4e21eeca1843959a7", size = 31961, upload-time = "2026-09-15T15:46:20.263Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/3f/f88a53f60a472b46f4023f56d204dd7de33d34c5d2acbfa0d70a674e639e/threadpoolctl-3.7.0-py3-none-any.whl", hash = "sha256:cd8b60b5641b45c67bbf73c64c843235fc2d8a480c87389f52f5dbee893b86be", size = 26362, upload-time = "2026-09-15T15:46:19.168Z" }, +] + +[[package]] +name = "tokenizers" +version = "0.23.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/1e/bc6587c5ab643b2e17776cace9070a2ae73549c86bffac9934a600bf3c31/tokenizers-0.23.2.tar.gz", hash = "sha256:7f0f085686b9de0d0079e6f874ae053600db64c5d13049e0bbc0119926d25aac", size = 385745, upload-time = "2026-09-03T08:55:42.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/ed/8a443528baa6fac8dfe8c3b75b038c63ac92bb539bcabe311e227c718173/tokenizers-0.23.2-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:85a9a357a3764aecc904ee76bdaf8cf1ad8e5a67a1b929a487c4a39b49ed0e90", size = 3148852, upload-time = "2026-09-03T08:55:30.874Z" }, + { url = "https://files.pythonhosted.org/packages/67/49/22da045a91732384d3a3771816bf188dc5a1f702c32e635afa7c679c0bef/tokenizers-0.23.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:986670e43691469dcee610ea0f846f91a8f84e91fc6f7a48d4c064414c0ec2bf", size = 3101593, upload-time = "2026-09-03T08:55:28.587Z" }, + { url = "https://files.pythonhosted.org/packages/2e/4d/8f569ed49372a3ed8e57099bd515055fd48d7c95912c4307cda6973c2168/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a37039b5dfc4af84eb3ef0a92f4307e28936c8f9adccba2629d36f652e9bf7a2", size = 3516830, upload-time = "2026-09-03T08:55:14.741Z" }, + { url = "https://files.pythonhosted.org/packages/2a/de/e2f14c8919d5bf51874051d00d6c7b7e0e8bde6c6a2dbeddda7f642896ff/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b7e37ba198f24150f523e1242e83c4970de4a525480586be5dcc24d9add32c5", size = 3407975, upload-time = "2026-09-03T08:55:16.842Z" }, + { url = "https://files.pythonhosted.org/packages/c5/bd/93c69152d02ef06ce47aed8b2bf4952dcf733c935a62791873932b2934d9/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43e4f2071e3cc8d5d86421c874aebc82659bb51a68bcdef5a0da75ee89511ccb", size = 3748165, upload-time = "2026-09-03T08:55:24.769Z" }, + { url = "https://files.pythonhosted.org/packages/2d/b7/56b84b80bc96942bba8eb23751a9e8a1fce4faaf4390425e7083f721c98c/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:325fee2e0418a9dc6c9ecf736a5f5f0db7875183ace9549ae339da76f7a1fbb7", size = 4024165, upload-time = "2026-09-03T08:55:18.806Z" }, + { url = "https://files.pythonhosted.org/packages/9b/8a/0175e216f005c2fe08238292663aa41e4c802b216e71047a69a0e9fc6fa3/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:950d7c9426fa72406a0ffeacdbc0bb9985f5db20eb8b263f29c79aaf83105703", size = 3591899, upload-time = "2026-09-03T08:55:22.752Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ca/ca6b93c7820df123b2662a9469e8facc826ccc94e98fdd0d615f6431e73a/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41c2f84d172449b4dadb9cdc508e3e364076613c35b16e76ecfe47a60d1e3305", size = 3386843, upload-time = "2026-09-03T08:55:26.584Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a4/4f9106d317b14a80aefea9f0e3a8d07ef25f856a7607eb7f5ab894281fcb/tokenizers-0.23.2-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:12f0835dc2ee694746a76adf7b1567d4346a4a502ebe93fb1f5f80ea49799b78", size = 3577314, upload-time = "2026-09-03T08:55:20.825Z" }, + { url = "https://files.pythonhosted.org/packages/8d/6a/1552b70fb0d9ab074fd3fc961435d01364e79c9058481822c3af6e8d402c/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:eb2f9c8a24da020ea8c11a01a19c1c2547912d92121ae4a01cfbca46125dee40", size = 9967367, upload-time = "2026-09-03T08:55:33.188Z" }, + { url = "https://files.pythonhosted.org/packages/06/01/3ccb3a956c7528b2507b8a9714155c4baf86af593039db6ea375dd0c96c3/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:f486f402f6f9abee5bb032553736813af0c710a86b2e0ca592634c55cea1f835", size = 9811886, upload-time = "2026-09-03T08:55:35.642Z" }, + { url = "https://files.pythonhosted.org/packages/fa/73/7038e612d48bda1599457f712f6bd3854eae1a9dc9c13aa47f835349db48/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:bef235815a067b2648caf6dcc7a71091b0b0fff9ee8057f6451eb9335fae52ef", size = 10146224, upload-time = "2026-09-03T08:55:38.391Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d8/8e9e4e0b287a338d8f88976729628c9d22e8a54cfaf9777018a7f7cb58a0/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5c56bda1511921587789163e524d196ed8284174ac23abd7685d5ea8da6c4718", size = 10256304, upload-time = "2026-09-03T08:55:40.977Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1f/c79a01f671a49728ebb0b61f7ff9ea45663b66cab40bc0858e9859b25c16/tokenizers-0.23.2-cp310-abi3-win32.whl", hash = "sha256:debf978920d93ba9c219bd67cc4bbfaf912c9039e41e7a28b91ec15e3728c95a", size = 2592809, upload-time = "2026-09-03T08:55:48.02Z" }, + { url = "https://files.pythonhosted.org/packages/db/f7/0a69ac6b82dbccf3f71add938a161c497952749294b8dd6dfe03a819dc40/tokenizers-0.23.2-cp310-abi3-win_amd64.whl", hash = "sha256:2e96f5699d5249c9c64aa8412e044f727aae3a4098cf830f9901ec1afc361cde", size = 2863236, upload-time = "2026-09-03T08:55:46.193Z" }, + { url = "https://files.pythonhosted.org/packages/d7/b0/dee84cb44175be1b4c35bd2f770727494e78f0bb38e571a623ade94dbebb/tokenizers-0.23.2-cp310-abi3-win_arm64.whl", hash = "sha256:e49c394456dd9985787fec76132438ba3fb8911f857b1bf3d40119f9292d41aa", size = 2729352, upload-time = "2026-09-03T08:55:44.345Z" }, +] + +[[package]] +name = "torch" +version = "2.14.0+cu130" +source = { registry = "https://download.pytorch.org/whl/cu130" } +dependencies = [ + { name = "cuda-bindings", marker = "python_full_version < '3.15' and sys_platform == 'linux'" }, + { name = "cuda-toolkit", extra = ["cublas", "cudart", "cufft", "cufile", "cupti", "curand", "cusolver", "cusparse", "nvjitlink", "nvrtc", "nvtx"], marker = "sys_platform == 'linux'" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cudnn-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu13", marker = "sys_platform == 'linux'" }, + { name = "setuptools" }, + { name = "sympy" }, + { name = "triton", marker = "python_full_version < '3.15' and sys_platform == 'linux'" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:9af4e8f3933c3d515d1949befad551262cdb3f195cbbdb4674369585c55ec342", upload-time = "2026-09-02T18:54:18Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:12b09f9e9f91347596393a6ddb95e9bc0aa003227eb6c7cd7f20c144eac62442", upload-time = "2026-09-02T18:54:33Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp314-cp314-win_amd64.whl", hash = "sha256:78ab64d12e478c8baedc4d90e662f6ffca2b6cb8a872a02b734a8aa3e00277eb", upload-time = "2026-09-02T18:55:09Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:6c6f734dc5bd126316a9e6320cff848b0e21afc1702118dd504fa45512c0d2d5", upload-time = "2026-09-02T18:55:47Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9a5dfdca3375869ae89803ae79d44531b706af9352a77066b8bdf134de0e09d4", upload-time = "2026-09-02T18:56:03Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp314-cp314t-win_amd64.whl", hash = "sha256:7db94ac0c41f1e0c10efd532ab43150c681edfc823cd5332c307644573403840", upload-time = "2026-09-02T18:56:39Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp315-cp315-manylinux_2_28_aarch64.whl", hash = "sha256:b82c5857f2c397a285027b65093dc8c89c7b45a69535786a69dae462bf67fd07", upload-time = "2026-09-02T18:57:13Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp315-cp315-manylinux_2_28_x86_64.whl", hash = "sha256:9e91cca5c03701158d783fb91fc1c5651469f466a3a3bcb4df5bcbff36cfd371", upload-time = "2026-09-02T18:57:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp315-cp315-win_amd64.whl", hash = "sha256:fca94b3181939ca5bdfc1f7d108a79888dec750f3683f922bda40dc4e78d6eaa", upload-time = "2026-09-02T18:57:59Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp315-cp315t-manylinux_2_28_aarch64.whl", hash = "sha256:16171adcc338c0827fbc28e448b96071638f4733743ee144b9692ec43477d821", upload-time = "2026-09-02T18:58:34Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp315-cp315t-manylinux_2_28_x86_64.whl", hash = "sha256:9e68cd6d619325acf1d94fc0c0a819e7a19dd95d226744be20acf7b7aff3ac8a", upload-time = "2026-09-02T18:58:46Z" }, + { url = "https://download-r2.pytorch.org/whl/cu130/torch-2.14.0%2Bcu130-cp315-cp315t-win_amd64.whl", hash = "sha256:c9d9ebc6c552c9e1b1779838b3c236f22e34fac2bcd441c1db8c939dd15f6fff", upload-time = "2026-09-02T18:59:19Z" }, +] + +[[package]] +name = "torchvision" +version = "0.29.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pillow" }, + { name = "torch" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/6a/ccdf22f6ee57e862aed41ab70e735f6302b8330bf304d8125f60d84413ba/torchvision-0.29.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:01a029fa1b2eacac27e1e4f9e0dba24d112bcbd523261b294e4b4a1c7f8330bc", size = 1813734, upload-time = "2026-09-02T13:47:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/3a/7e/3cffb013454af4c126a40e97cff7ac91dff692b749bcf80754ae97ada225/torchvision-0.29.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:f9e9627d5036cac8e6de76aeb2f1acc67841ff5ff4b63c4cf78ff954efeb073e", size = 7523354, upload-time = "2026-09-02T13:47:13.833Z" }, + { url = "https://files.pythonhosted.org/packages/97/90/ae1d76e76c5d97b70539cd38df309777d66020d33b346301e79a7a8c132a/torchvision-0.29.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:e8fdf234d76dca6fc47bc5f4af86ecf1ef57fab6285a7b21681bdcbb494e4c1b", size = 7430722, upload-time = "2026-09-02T13:47:21.359Z" }, + { url = "https://files.pythonhosted.org/packages/ac/dd/f5571d0c2aedc3d363f9b818de8fbb810a0d2b2ab0293de6003f4291ce15/torchvision-0.29.0-cp314-cp314-win_amd64.whl", hash = "sha256:bb74d08d65785b51c61d4d4ec167bfa50a5ea644b57555a33ba2f4435b0d05dd", size = 1376792, upload-time = "2026-09-02T13:47:18.279Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f0/bc564a8ed409db4d7ce72215a676c3cbda9559779a53e8ecc477ad11d2c5/torchvision-0.29.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:80789f9b50f5277302e7020c8128344e0269b12f6e3b5855034e56bb7081b874", size = 1813737, upload-time = "2026-09-02T13:47:22.801Z" }, + { url = "https://files.pythonhosted.org/packages/80/55/b39dba8e3d574428e7f00f212a3ee5a2c2d0ab5a25a95338a7c724a87850/torchvision-0.29.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:9b99a7385da8d706f2dc14cacffb8cbf653d48fc37013a38c41a36659acc3731", size = 7523376, upload-time = "2026-09-02T13:47:19.631Z" }, + { url = "https://files.pythonhosted.org/packages/84/b3/67692c3785702c24d6c9c95026a558791366f2dc48823aec2321f23a0858/torchvision-0.29.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:2428a13706a354ee3901fd63e3f1ef8c2a59f6e20d24cce13210b4e61be08f7a", size = 7430679, upload-time = "2026-09-02T13:47:24.3Z" }, + { url = "https://files.pythonhosted.org/packages/07/8e/0e3682cad7f6b2aba93585bc3b792f8087e4e3fb916c0f6638eacdb3170c/torchvision-0.29.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bd12e152640d1024fca15deaf6f39c53702e12eb398db4b2b038a5a97ab85f7f", size = 1376794, upload-time = "2026-09-02T13:47:25.923Z" }, +] + +[[package]] +name = "tqdm" +version = "4.70.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/ea/b2a5bd54b28a324dae8211928b2d730b6547500342c7e6c6dea08bd0a485/tqdm-4.70.1.tar.gz", hash = "sha256:cefd0eca11b2a37a3aee776544d4f4ae913f02688135b5556b8788dfa474afc4", size = 171846, upload-time = "2026-09-11T07:25:16.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/03/921a3d3c75785aca9ebfbfcabfbc3a1be12e2ab5265deb026d55a5a3f83e/tqdm-4.70.1-py3-none-any.whl", hash = "sha256:c293e525e6fef9c20e8728fd4612df02a0aa31bb5fe91ecd93e123b1b7bffa73", size = 80199, upload-time = "2026-09-11T07:25:14.599Z" }, +] + +[[package]] +name = "transformers" +version = "5.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "regex" }, + { name = "safetensors" }, + { name = "tokenizers" }, + { name = "tqdm" }, + { name = "typer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/9e/750649904a065007a838981785b2bd8d9ff26154c6c341ac67d0b7f82c68/transformers-5.17.0.tar.gz", hash = "sha256:a153be279169b55b92d8000bf4af294aed684503d091cca7804da2dd8a9de000", size = 9817878, upload-time = "2026-09-09T15:39:56.886Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/d0/c502b60d684adbd98a8dc7d5bb866842772b816ac4354e4608be240041ae/transformers-5.17.0-py3-none-any.whl", hash = "sha256:78ec1ce21579b38dfb83950a0658cd119f87212a2fcfdff478096ce9d6c03801", size = 12295140, upload-time = "2026-09-09T15:39:53.746Z" }, +] + +[[package]] +name = "triton" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/59/bf0e9493118bb353ab59a5d6a65db3618d9b314417cc1459f0121e0ec5c9/triton-3.8.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f6b48d0591929a3867973acac3dccd4e058585f91bfb41022de496c9ffab304", size = 226488654, upload-time = "2026-08-28T16:08:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/93/d9/08c75f3459f19ad00425b564058e40efa4bcd79b816064cf27499303ea42/triton-3.8.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:387dae4cb0089a7b6ba1a428ae0782b65c4c58f57d94617cb22ca8593d8ccbca", size = 247972313, upload-time = "2026-08-28T15:56:14.007Z" }, + { url = "https://files.pythonhosted.org/packages/7c/34/429c5592181cfb7361a0a8e0bff218e7224b726709d75da2472b3e819f70/triton-3.8.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b84e7d512490ba529111260fa6f7cad8b254a6bb5fbdf41d5ef9a5e57f52d0a", size = 226591133, upload-time = "2026-08-28T16:09:02.271Z" }, + { url = "https://files.pythonhosted.org/packages/fe/d1/aa8a3e935c37efee7945984fdb64d7e0851bf6d920afd97b2d21f9d23360/triton-3.8.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74217bb56ed8692759227758e4c4b3bd2d608a209c1a7a081bf361fb4c2c1bf9", size = 248077577, upload-time = "2026-08-28T15:56:24.94Z" }, +] + +[[package]] +name = "typer" +version = "0.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/f7/57713ba479fd405eb76de31404b2c744c289e336b2d999511ebf51e496f7/typer-0.27.2.tar.gz", hash = "sha256:269b7eb9d3c202ca84b4bc9618cb04ebb43d3d4d1e567e4c768607232c05f945", size = 204045, upload-time = "2026-08-28T10:26:55.046Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/bf/205d0004930ede8f542fb58f601526fccf4ae7626075ca1e6c4de5d3d652/typer-0.27.2-py3-none-any.whl", hash = "sha256:b3a5fc4342d5fc8fda8fc3010b1cf117e9249aab7fae800c2eff62fd3842d97d", size = 123130, upload-time = "2026-08-28T10:26:53.752Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "tzdata" +version = "2026.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/31/3d74fa778a63b98b7374323befcc0be5ab3bd94afd4096a0124e7379152c/tzdata-2026.4.tar.gz", hash = "sha256:f1b8bd365d8d210c55353f4d7f8d6d8561c0ba50d704b700d195a9424bba0d79", size = 199350, upload-time = "2026-09-12T12:56:03.251Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/bc/8737e8d54cf51106118039b83f485a4783112fab49ea9d044b234978a46e/tzdata-2026.4-py2.py3-none-any.whl", hash = "sha256:c2169a8b0a7a5e9674da5a135ccdfb2b3e671b333ed9fed17b41f73c34476e81", size = 347494, upload-time = "2026-09-12T12:56:01.67Z" }, +] diff --git a/deep_learning/Q1/方法说明_零基础版.md b/deep_learning/Q1/方法说明_零基础版.md new file mode 100644 index 0000000..05dc61b --- /dev/null +++ b/deep_learning/Q1/方法说明_零基础版.md @@ -0,0 +1,136 @@ +# Q1 特征提取方法说明(零基础版) + +这份说明介绍本次已经完成的 100 条视频处理过程。目标是把文字、声音和画面变成电脑能处理的数字,并让这三种数字都能回到原视频的时间位置。 + +## 先用一句话理解 + +把每条视频想成一段带字幕的短片: + +- 把字幕切成一个个词,为每个词生成一组数字; +- 把声音切成许多很短的小段,为每段记录音高、响度等声音特征; +- 每隔一小段时间取一帧画面,为每帧生成一组画面数字; +- 再估计每个字幕词在声音里出现的时间,把同一时间附近的声音和画面对到一起。 + +这些数字就是“特征”。它们不是视频本身,也不是情感结论,而是模型后续可以读取的数字表示。 + +## 整体流程 + +```mermaid +flowchart LR + A[100条原始视频 + 原始字幕] --> B[文字:每个词生成向量] + A --> C[声音:提取逐帧声学特征] + A --> D[画面:每秒抽取约5帧并生成特征] + B --> E[用字幕和声音估计词级时间戳] + C --> E + E --> F[按词的时间段汇总声音和画面特征] + D --> F + F --> G[100个样本文件 + 汇总表 + 对应关系图] +``` + +## 什么叫“对齐” + +一段视频里,字幕、声音和画面各有自己的节奏。比如字幕中的词“happy”可能在 1.2 秒左右说出,那个时刻的视频画面里也可能出现说话人的表情变化。 + +“对齐”就是给不同模态的内容标上共同的时间位置,便于回答: + +> 这个词出现时,声音有什么变化?同一时刻画面里有什么? + +本次时间统一使用“从这条短视频开始算起的秒数”。例如 1.2 秒就是片段开始后 1.2 秒。电脑估出来的时间是模型估计值,不是人工逐帧标注的真值。 + +## 文字是怎么处理的 + +1. 直接读取题目提供的英文 transcript(字幕文本),保留原文顺序和内容,不用模型改写或纠错。 +2. 按空格切成词。像 `unbelievable` 这样的词,文字模型内部可能会再拆成更小的片段。 +3. 使用预训练的 BERT 英文模型,为这些更小的片段生成数字向量,再把同一个词的片段向量取平均,得到这个词的一组数字。 + +可以把 BERT 理解成一个读过大量英文材料的编码器:它把每个词放进一组 768 个数字里。词的向量不是情感分数,也不代表某一维就等于某种具体情绪。 + +## 声音是怎么处理的 + +声音分成两个用途不同的步骤。 + +### 1. 找每个词大约在什么时候说出 + +使用预训练的 Wav2Vec2 英语语音模型,并把题目提供的 transcript 当作已知文本。模型根据实际声音,为字幕里的字母和词寻找最可能的时间位置。这种做法叫“强制对齐”:文本固定,模型估计它在声音中的时间。 + +这一步不会验证字幕是不是完全正确,也不会把它当成精确的人工真值。若字幕和录音差异较大,时间估计可能不准。 + +### 2. 记录声音本身的变化 + +用 FFmpeg 把视频里的声音转成单声道、每秒 16,000 个采样点的音频,再使用 openSMILE 的 eGeMAPSv02 特征配置。它大约每 0.01 秒输出一行、每行 25 个数字,记录响度、音高、频谱形状等声音信息。 + +这些数值描述“声音怎么变化”,不等同于文字内容,也不是情感类别。 + +## 画面是怎么处理的 + +视频不会把每一帧都存成特征。本次每秒大约抽取 5 帧,也就是平均约每 0.2 秒取一帧。 + +- DeiT-Tiny 图像模型为每帧生成 192 个数字,作为通用画面特征。这组数字能表示画面信息,但单独一个数字通常没有容易读懂的名称。 +- 另外,MediaPipe Face Landmarker 会尝试检测人脸,并输出 52 个脸部动作系数,例如眉毛、眼睑和嘴部的运动。这些系数描述可见的脸部动作,不是“高兴/悲伤”等情绪标签。 + +有 13 条视频在抽样帧中没有检测到人脸,所以这些样本没有有效的人脸动作系数;它们仍然保留了 DeiT 通用画面特征,视觉模态没有因此缺失。 + +## 三种特征怎样对应到词 + +对齐完成后,每个字幕词都有一个起止时间。例如(下面只是示意): + +| 字幕词 | 估计时间 | 对应的声音 | 对应的画面 | +| --- | --- | --- | --- | +| happy | 1.20–1.55 秒 | 取这个时间段内的声学帧并求平均 | 取这个时间段内的视频帧特征并求平均 | + +声音特征比较密,通常一个词时间段里会有多行;视频每秒只有约 5 帧,所以有些很短的词时间段里可能没有正好落入的画面帧。这种情况下,程序取时间最近的一帧,并把“使用了最近帧”的标记一并保存。 + +本次有 12 个词无法直接从 CTC 对齐路径中获得时间,分布在 9 条样本里。它们被放在相邻有效词之间的一个时间点上,区间长度为零,并标记 `word_alignment_valid=false`。程序没有把估计不出的词伪装成可靠的起止时间;下游对应特征通过最近的有效声音帧或画面帧取得,并保留回退标记。 + +## 文件里存了什么 + +每条视频有一个压缩的 `.npz` 文件,变长序列按原长存储,不在文件里填充到同一长度。主要数组包括: + +| 内容 | 形状示例 | 含义 | +| --- | --- | --- | +| `text_features` | 词数 × 768 | 每个 transcript 词的 BERT 向量 | +| `audio_features` | 音频帧数 × 25 | 逐帧 eGeMAPS 声学特征 | +| `vision_features` | 画面帧数 × 192 | 逐帧 DeiT 通用画面特征 | +| `face_blendshape_features` | 画面帧数 × 52 | 人脸动作系数;是否有效由独立掩码表示 | +| `word_intervals_s` | 词数 × 2 | 每个词的起止时间,单位秒 | +| `audio_word_features` | 词数 × 25 | 按词的时间段汇总后的声音特征 | +| `vision_word_features` | 词数 × 192 | 按词的时间段汇总后的视频特征 | + +时间戳以 32 位浮点数保存,特征值以 16 位浮点数保存以节省空间,掩码使用布尔值。掩码就是一张有效性清单:`true` 表示该位置有可用数据,`false` 表示缺失或使用了需要谨慎处理的回退结果。 + +## 本次处理得到的汇总 + +- 原始样本:100 条;标签表里的 100 个样本与视频文件一一对应,未删除或替换样本。 +- 文本:1,932 个词,768 维词向量。 +- 声音:77,261 个有效帧,25 维声学特征。 +- 画面:3,948 帧,192 维通用视觉特征,覆盖 100/100 条样本。 +- 人脸动作:87/100 条检测到有效人脸帧;其余 13 条仍有通用视觉特征。 +- CTC 词级时间:1,920/1,932 个词直接对齐,12 个词带回退标记。 +- 抽取错误:0 条;完整特征与报告约 10.5 MB。 + +审计还发现两段原始视频短于题面给出的 2.648 秒下限:`-mJ2ud6oKI8/6` 约 2.2356 秒,`-s9qJ7ATP7w/6` 约 2.4667 秒。它们按原样保留,时长差异记录在审计文件中。 + +## 如何复现 + +在 `deep_learning` 目录中运行: + +```bash +cd Q1 +uv sync +uv run python -m q1.audit +uv run python -m q1.extract_features --output-dir outputs/q1_features +``` + +`uv.lock` 固定了 Python 依赖版本;运行清单记录了模型名称与修订号、参数、工具版本、GPU 信息和输出文件哈希。特征文件、汇总表、运行清单及典型样本图位于 `Q1/outputs/q1_features/`。 + +## 这次结果的边界 + +本说明讲的是“怎么从原始视频得到三模态特征,以及如何按时间组织它们”。最初的 M3/M4 版本曾把注意力摊得很平均;后来的时间码实验使 M4 找到了较稳定的时间位置,但“找到了同一时刻”仍不能保证文字、声音、画面的具体内容相互对应。情绪 Probe 也只是 100 条小样本上的检查,不能当作一般情绪识别准确率。CTC 时间、模型生成的向量和人脸动作系数都应当视为算法输出;要确认某个词和某段声音、画面是否真的对应,仍需要人工标注一些时间片段做独立核验。 + +## 后续的 TSFA 实验:为什么还要再对齐一次 + +可以把一段视频想成一条从头到尾的路。M4 根据时间先告诉我们:“第 20 个位置大约在这条路的中段。”TSFA 在中段附近再比较文字与声音、画面的内容,选择更像当前文字的片段。实验把每条视频组织成 50 个位置;“附近”在主方案中指整段视频时长的前后各 10%。如果窗口里没有可用的声音或画面位置,就取最近的有效位置,并保留这项规则。 + +为了知道“附近”是否真的有用,还做了两种对照:一种把同样宽的窗口随机放置,另一种让模型看完整段视频。七种方法使用相同的 100 条视频、相同的 BERT 文字特征、音频特征和 DeiT 图像特征;同一原视频的片段在同一折里一起作为训练或留出数据。总共做 5 折,每条样本都轮到一次留出评价。 + +结果显示,TSFA 比只用 M4 时更容易把同一位置的**文字与声音**对应起来,但画面相关的改善很小。随机窗口和看完整段视频的方案在“内容相似度”指标上甚至更高,却经常把视频前后位置弄乱。TSFA 的局部时间窗口主要帮助模型保持先后顺序。这里的“同一位置”由时间槽定义,还不是人工确认的同一事件,因此目前不能说三种模态已经准确理解了彼此。详细数字与图见 [RESULTS.md](RESULTS.md) 的 TSFA 小节。 diff --git a/deep_learning/README.md b/deep_learning/README.md new file mode 100644 index 0000000..1e61b50 --- /dev/null +++ b/deep_learning/README.md @@ -0,0 +1,652 @@ +# 复杂场景下多模态情感预测:数学建模与算法设计 + +> 2026 年中国研究生数学建模竞赛 E 题 +> **复杂场景下多模态情感预测的数学建模与算法设计** + +--- + +## 1. 项目概述 + +本项目基于 CMU-MOSEI 英文多模态情感数据,研究复杂场景下文本(Text)、语音(Audio)和视觉(Vision)三种模态的联合情感预测。 + +赛题主要包含三个逐层递进的问题: + +1. **Q1:多模态情感特征提取与时序对齐** +2. **Q2:模态局部缺失条件下的鲁棒情感预测** +3. **Q3:可解释性多模态情感预测** + +整体逻辑可以概括为: + +\[ +\boxed{ +\text{原始视频} +\rightarrow +\text{多模态特征} +\rightarrow +\text{跨模态时序对齐} +\rightarrow +\text{缺失感知鲁棒融合} +\rightarrow +\text{情感预测} +\rightarrow +\text{预测解释} +} +\] + +本项目现阶段不预先指定某一种方案为最终方案,而采用: + +\[ +\boxed{\text{多方案全部实现 + 统一实验协议 + 系统对比}} +\] + +最终根据: + +- 基础预测性能; +- 缺失情况下的鲁棒性; +- 解释可信度; +- 模型复杂度; +- 可复现性; + +共同确定最终建模方案。 + +--- + +# 2. 赛题核心任务 + +## 2.1 Q1:多模态特征提取与时序对齐 + +从原始视频中分别提取: + +- 文本语义特征; +- 语音情感特征; +- 视觉情感特征; + +并解决三种模态: + +- 采样频率不同; +- 序列长度不同; +- 时间尺度不同; + +造成的时序不一致问题。 + +Q1 不以最终情感分类为主要目标,而应产生: + +\[ +\boxed{ +\text{结构化、可追溯、可核验的多模态时序特征} +} +\] + +同时记录: + +- 原始视频 ID; +- 模态; +- 时间位置; +- 有效长度; +- padding; +- 原始视频时间映射; +- 特征维度; +- 对齐关系。 + +--- + +## 2.2 Q2:局部模态缺失下的鲁棒情感预测 + +题目中的“模态缺失”不是简单的: + +> 整个 Audio / Vision / Text 完全不存在。 + +而是: + +\[ +\boxed{\text{一个或多个模态中出现随机的连续局部缺失区间}} +\] + +例如: + +\[ +X^A = +[a_1,a_2,a_3, +\underbrace{0,0,0,0}_{\text{局部缺失}}, +a_8,\ldots]. +\] + +模型需要同时预测: + +### 情感极性 + +\[ +\hat c \in +\{ +\text{Negative}, +\text{Neutral}, +\text{Positive} +\} +\] + +### 连续情感强度 + +\[ +\hat y\in[-3,3] +\] + +同时研究: + +\[ +\boxed{ +\text{缺失模态类型} ++ +\text{缺失位置} ++ +\text{缺失长度} +} +\] + +对预测性能的影响。 + +--- + +## 2.3 Q3:可解释性情感预测 + +在三模态信息完整条件下,不仅预测: + +\[ +(\hat c,\hat y) +\] + +还需要解释: + +1. 主要参考了哪种模态; +2. 不同模态的作用程度; +3. 哪些局部文本、音频和视觉片段最重要; +4. 关键证据对应原始视频的什么时间位置。 + +因此 Q3 的核心不是简单画 Attention,而是: + +\[ +\boxed{ +\text{定位证据} ++ +\text{量化贡献} ++ +\text{验证解释} ++ +\text{回溯原始素材} +} +\] + +--- + +# 3. 数据集说明 + +--- + +## 3.1 附件 1:100 条原始视频 + +附件 1 包含从 CMU-MOSEI 中筛选的: + +\[ +100 +\] + +条英文视频样本。 + +共有: + +\[ +37 +\] + +个 `video_id` 子文件夹。 + +样本由: + +```text +video_id + clip_id +``` + +共同唯一确定。 + +视频长度范围: + +\[ +2.648s \sim 34.567s +\] + +配套文件: + +```text +label-100.xlsx +``` + +包含字段: + +| 字段 | 含义 | +|---|---| +| video_id | 原视频编号 | +| clip_id | 视频片段编号 | +| text | 英文转写文本 | +| label | 连续情感强度 | +| annotation | Negative / Neutral / Positive | + +连续情感标签: + +\[ +y\in[-3,3] +\] + +定义: + +\[ +[-3,0)\Rightarrow Negative +\] + +\[ +0\Rightarrow Neutral +\] + +\[ +(0,3]\Rightarrow Positive +\] + +注意: + +\[ +\boxed{0\text{ 只属于 Neutral}} +\] + +--- + +# 4. 附件 2:标准化多模态特征 + +附件 2 包含两套特征: + +```text +aligned_50.pkl +unaligned_50.pkl +``` + +每套包含约: + +\[ +4850 +\] + +条有效样本,并按照: + +```python +train +valid +test +``` + +划分。 + +--- + +## 4.1 Pickle 数据组织方式 + +整体结构为: + +```text +data +├── train +│ ├── id +│ ├── raw_text +│ ├── text +│ ├── text_bert +│ ├── audio +│ ├── vision +│ ├── annotations +│ ├── classification_labels +│ ├── regression_labels +│ └── ... +├── valid +└── test +``` + +正确读取方式: + +```python +data["train"]["audio"][j] +``` + +而不是: + +```python +data["train"][j]["audio"] +``` + +--- + +# 5. aligned / unaligned 数据格式 + +## 5.1 aligned_50.pkl + +\[ +X^T\in\mathbb R^{N\times50\times768} +\] + +\[ +X^A\in\mathbb R^{N\times50\times74} +\] + +\[ +X^V\in\mathbb R^{N\times50\times35} +\] + +三个模态已经被组织为: + +\[ +50 +\] + +个相互对应的位置。 + +可以理解为: + +\[ +T_i\leftrightarrow A_i\leftrightarrow V_i. +\] + +--- + +## 5.2 unaligned_50.pkl + +文本: + +\[ +X^T\in\mathbb R^{N\times50\times768} +\] + +音频: + +\[ +X^A\in\mathbb R^{N\times500\times74} +\] + +视觉: + +\[ +X^V\in\mathbb R^{N\times500\times35} +\] + +同时提供: + +```text +audio_lengths +vision_lengths +``` + +记录实际有效长度。 + +因此 unaligned 数据保留了: + +\[ +\boxed{ +\text{文本较粗语义轴} ++ +\text{音频细粒度时序} ++ +\text{视觉细粒度时序} +} +\] + +这为学习式 Cross-Attention 对齐提供了空间。 + +--- + +# 6. 附件 3:模态局部缺失测试集 + +附件 3: + +- 无标签; +- 已处理多模态特征; +- 包含随机局部模态缺失; +- 缺失区间表现为连续位置全部置零。 + +用于 Q2 最终预测。 + +--- + +# 7. 附件 4:可解释性专项测试集 + +附件 4: + +- 无标签; +- 三模态完整; +- 同时提供原始真实场景视频; +- 特征组织形式与附件 2 一致。 + +用于: + +\[ +\boxed{ +\text{预测} ++ +\text{模态贡献} ++ +\text{关键证据定位} +} +\] + +可以根据 Q1 保存的时间映射将关键位置重新定位到: + +- 原始文本; +- 音频时间段; +- 视频关键帧。 + +--- + +# 8. 统一数学符号 + +一个样本记为: + +\[ +\mathcal X_i= +(X_i^T,X_i^A,X_i^V) +\] + +其中: + +- \(T\):Text +- \(A\):Audio +- \(V\):Vision + +原始模态序列: + +\[ +X^m= +[x_1^m,\ldots,x_{L_m}^m], +\qquad +m\in\{T,A,V\}. +\] + +--- + +## 8.1 基础符号 + +| 符号 | 含义 | +|---|---| +| \(x_j^m\) | 模态 \(m\) 原始第 \(j\) 个位置特征 | +| \(\tilde x_i^m\) | 软对齐到文本位置 \(i\) 后的特征 | +| \(h_i^m\) | 模态编码器生成的隐藏表示 | +| \(M_j^m\) | 原始位置是否有效 | +| \(A_{ij}^m\) | Cross-Attention 对齐权重 | +| \(R_i^m\) | 对齐后的局部模态可靠度 | +| \(\alpha_i^m\) | 融合时模态权重 | +| \(z_i\) | 第 \(i\) 个位置的多模态融合表示 | +| \(\beta_i\) | 第 \(i\) 个位置对整段情绪的时间重要性 | +| \(g\) | 整条视频最终表示 | +| \(\hat y\) | 情感强度预测 | +| \(\hat c\) | 情感极性预测 | + +--- + +## Q1 +@Q1.md + +--- + +# 可能使用的开源库、工具与模型 + +| 类别 | 工具 / 模型 | 用途 | 优先级 | +|---|---|---|---| +| 深度学习 | PyTorch | 网络、训练、Cross-Attention | 必须 | +| GPU | CUDA / cuDNN | GPU 加速 | 必须 | +| 数值计算 | NumPy | 数值运算 | 必须 | +| 数据 | Pandas | CSV / XLSX / 表格 | 必须 | +| 科学计算 | SciPy | Pearson / 统计分析 | 必须 | +| ML | scikit-learn | F1、Accuracy、MAE 等 | 必须 | +| 配置 | PyYAML | 实验配置 | 推荐 | +| 配置 | Hydra / OmegaConf | 多实验管理 | 推荐 | +| 日志 | TensorBoard | loss / metric | 推荐 | +| 日志 | MLflow | 系统实验管理 | 可选 | +| 调参 | Optuna | 超参数搜索 | 推荐 | +| 视频 | FFmpeg | 拆音频、转码 | 必须 | +| 视频 | OpenCV | 抽帧与时间映射 | 必须 | +| 文本 | Hugging Face Transformers | BERT 等 | 高 | +| 文本 | BERT-base-uncased | 768 维表示 | 高 | +| ASR/时间戳 | WhisperX | 词级时间定位 | 推荐 | +| 强制对齐 | Montreal Forced Aligner | transcript-audio alignment | 推荐 | +| 音频 | openSMILE | 声学/韵律特征 | 高 | +| 音频 | librosa | 基础信号处理 | 推荐 | +| 音频 | torchaudio | PyTorch 音频 | 推荐 | +| 音频 PLM | wav2vec 2.0 | 深层语音表示 | 可选 | +| 音频 PLM | WavLM | 深层语音表示 | 可选 | +| 音频 PLM | HuBERT | 深层语音表示 | 可选 | +| 视觉 | OpenFace 2.0 | AU / gaze / pose | 高 | +| 视觉 | MediaPipe | landmark / blendshape | 可选 | +| 视觉 | torchvision | 图像处理 | 推荐 | +| 多模态 | CMU-MultimodalSDK | MOSEI 数据参考 | 高 | +| 多模态 | MultiBench | baseline / multimodal benchmark | 高 | +| 解释 | Captum | IG / Occlusion / Ablation | 高 | +| 解释 | SHAP | Shapley 解释 | 可选 | +| 可视化 | Matplotlib | 曲线 / 热图 | 必须 | +| 可视化 | Plotly | 交互可视化 | 可选 | +| 统计 | statsmodels | 回归 / 显著性分析 | 推荐 | + +--- + +# 模型候选汇总 + +| 模块 | 候选 | +|---|---| +| Text Encoder | BERT | +| Audio Feature | openSMILE | +| Audio Encoder | BiGRU / Transformer | +| Audio PLM | Wav2Vec2 / WavLM | +| Vision Feature | OpenFace | +| Vision Encoder | BiGRU / Transformer | +| Alignment | Hard Alignment | +| Alignment | Fixed Window | +| Alignment | Cross-Attention | +| Fusion | Concatenation | +| Fusion | TFN | +| Fusion | LMF | +| Fusion | MAG | +| Fusion | MulT | +| Representation | MISA | +| Missing Model | MMIN | +| Missing Model | CMAD | +| Missing Model | P-RMF | +| Experts | EMOE | +| Diffusion | HyperEF | +| Factorization | FUSE-Net | +| Distribution Alignment | CaReFlow | +| Robust Representation | CmIR | +| Attribution | Integrated Gradients | +| Attribution | Occlusion | +| Attribution | Feature Ablation | +| Attribution | SHAP | + +--- + +# 参考文献 + +> 下表优先使用论文官方会议/期刊入口。 +> README 中记录 DOI、ACL Anthology ID、arXiv ID 或官方论文标题,避免引用二手博客作为正式论文来源。 + +| # | 文献 | 会议/期刊 | 年份 | 与本项目关系 | 官方标识 | +|---|---|---|---:|---|---| +| 1 | Zhang et al., *Deep learning-based multimodal emotion recognition from audio, visual, and text modalities: A systematic review of recent advancements and future prospects* | Expert Systems with Applications | 2024 | 多模态情感综述 | DOI: 10.1016/j.eswa.2023.121692 | +| 2 | Bagher Zadeh et al., *Multimodal Language Analysis in the Wild: CMU-MOSEI Dataset and Interpretable Dynamic Fusion Graph* | ACL | 2018 | CMU-MOSEI | ACL: P18-1208 | +| 3 | Vaswani et al., *Attention Is All You Need* | NeurIPS | 2017 | Transformer / Attention | NeurIPS 2017 | +| 4 | Devlin et al., *BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding* | NAACL | 2019 | 文本特征 | ACL: N19-1423 | +| 5 | Eyben et al., *openSMILE: The Munich Versatile and Fast Open-Source Audio Feature Extractor* | ACM Multimedia | 2010 | 音频特征 | ACM MM 2010 | +| 6 | Baltrušaitis et al., *OpenFace 2.0: Facial Behavior Analysis Toolkit* | FG | 2018 | 视觉特征 | DOI: 10.1109/FG.2018.00019 | +| 7 | Bain et al., *WhisperX: Time-Accurate Speech Transcription of Long-Form Audio* | arXiv | 2023 | 词级时间戳 | arXiv:2303.00747 | +| 8 | Tsai et al., *Multimodal Transformer for Unaligned Multimodal Language Sequences* | ACL | 2019 | unaligned + Cross-Attention | ACL: P19-1656 | +| 9 | Rahman et al., *Integrating Multimodal Information in Large Pretrained Transformers* | ACL | 2020 | MAG-BERT / 文本中心融合 | DOI:10.18653/v1/2020.acl-main.214 | +| 10 | Zadeh et al., *Tensor Fusion Network for Multimodal Sentiment Analysis* | EMNLP | 2017 | TFN baseline | ACL: D17-1115 | +| 11 | Liu et al., *Efficient Low-rank Multimodal Fusion With Modality-Specific Factors* | ACL | 2018 | LMF baseline | ACL: P18-1209 | +| 12 | Hazarika et al., *MISA: Modality-Invariant and -Specific Representations for Multimodal Sentiment Analysis* | ACM MM | 2020 | shared / private representation | DOI:10.1145/3394171.3413678 | +| 13 | Neverova et al., *ModDrop: Adaptive Multi-Modal Gesture Recognition* | TPAMI | 2016 | 模态随机丢失 | DOI:10.1109/TPAMI.2015.2461544 | +| 14 | Pham et al., *Found in Translation: Learning Robust Joint Representations by Cyclic Translations between Modalities* | AAAI | 2019 | 跨模态重构 | DOI:10.1609/aaai.v33i01.33016892 | +| 15 | Zhao et al., *Missing Modality Imagination Network for Emotion Recognition with Uncertain Missing Modalities* | ACL-IJCNLP | 2021 | MMIN | ACL:2021.acl-long.203 | +| 16 | 王楠、王淇、欧阳丹彤,《基于知识蒸馏与动态调整机制的多模态情感分析模型》 | 计算机学报 | 2025 | AUMDF / 动态权重 / 缺失 | 48(8):1923–1942 | +| 17 | Fang et al., *EMOE: Modality-Specific Enhanced Dynamic Emotion Experts* | CVPR | 2025 | Mixture of Experts | CVPR 2025 | +| 18 | Zhuang et al., *CMAD: Correlation-Aware and Modalities-Aware Distillation for Multimodal Sentiment Analysis with Missing Modalities* | ICCV | 2025 | 缺失模态蒸馏 | ICCV 2025 | +| 19 | Zhu et al., *Proxy-Driven Robust Multimodal Sentiment Analysis with Incomplete Data* | ACL | 2025 | P-RMF / 不确定性 | DOI:10.18653/v1/2025.acl-long.1075 | +| 20 | Qiu et al., *Beyond Missing Modalities: Hypergraph Conditioned Diffusion for Uncertainty-Aware Multimodal Emotion Recognition* | CVPR | 2026 | Diffusion / uncertainty | CVPR 2026 | +| 21 | Yang & Li, *Factorize, Reconstruct, Enhance: A Unified Framework for Multimodal Sentiment Analysis* | CVPR | 2026 | shared/specific/noise + reconstruction | CVPR 2026 | +| 22 | Mai & Han, *Learning Invariant Modality Representation for Robust Multimodal Learning from a Causal Inference Perspective* | ACL | 2026 | CmIR / causal invariance | DOI:10.18653/v1/2026.acl-long.2119 | +| 23 | Mai & Han, *CaReFlow: Cyclic Adaptive Rectified Flow for Multimodal Fusion* | CVPR | 2026 | 模态分布对齐 | arXiv:2602.19140 | +| 24 | Wan et al., *Locate and Explain: Joint Multimodal Emotion Cause Extraction and Summarization in Conversation* | ACL | 2026 | 关键证据定位 | DOI:10.18653/v1/2026.acl-long.2012 | +| 25 | Sundararajan et al., *Axiomatic Attribution for Deep Networks* | ICML | 2017 | Integrated Gradients | PMLR 70 | +| 26 | Jain & Wallace, *Attention is not Explanation* | NAACL | 2019 | Attention 解释局限 | DOI:10.18653/v1/N19-1357 | +| 27 | Lundberg & Lee, *A Unified Approach to Interpreting Model Predictions* | NeurIPS | 2017 | SHAP | NeurIPS 2017 | +| 28 | Adebayo et al., *Sanity Checks for Saliency Maps* | NeurIPS | 2018 | 解释可信性验证 | NeurIPS 2018 | +| 29 | Zeiler & Fergus, *Visualizing and Understanding Convolutional Networks* | ECCV | 2014 | Occlusion 思想 | DOI:10.1007/978-3-319-10590-1_53 | +| 30 | Wachter et al., *Counterfactual Explanations without Opening the Black Box* | arXiv / HILDA | 2017 | 反事实解释 | arXiv:1711.00399 | + +--- + +# 最终原则 + +本项目当前不采用: + +> “先选一个看起来高级的模型,然后证明它最好。” + +而采用: + +\[ +\boxed{ +\text{提出多个机制假设} +\rightarrow +\text{设计公平实验} +\rightarrow +\text{观察数据} +\rightarrow +\text{解释规律} +\rightarrow +\text{确定最终模型} +} +\] + +重点不只是得到最高指标,还要回答: + +1. 为什么某种对齐方式更好? +2. 哪种模态最怕局部缺失? +3. 缺失的位置是否比缺失比例更重要? +4. Cross-Attention 能否帮助判断缺失信息的重要程度? +5. 动态可靠度是否真的提高鲁棒性? +6. 重构和“降低信任”哪种策略更有效? +7. Attention 权重是否真的对应模型决策依据? +8. 哪种解释方法最能经受反事实验证? + +最终目标是形成: + +\[ +\boxed{ +\text{有性能} ++ +\text{有机制} ++ +\text{有数学分析} ++ +\text{有可解释性} +} +\] + +的完整多模态情感预测建模方案。 \ No newline at end of file diff --git a/images/Q1/image.png b/images/Q1/image.png new file mode 100644 index 0000000..a80eeec Binary files /dev/null and b/images/Q1/image.png differ diff --git a/math/README.md b/math/README.md new file mode 100644 index 0000000..1b60029 --- /dev/null +++ b/math/README.md @@ -0,0 +1,44 @@ +# 问题一模型对比 + +本目录实现问题一 PDF 第 4.8.3 节的 B0–B4 单因素对照。代码从附件一的 100 条原始视频和标签表开始,先生成统一的文本、语音、视觉特征,再在 0.1 秒主时间网格上进行五折 `video_id` 留组评估。 + +## 运行 + +在仓库根目录执行: + +```bash +cd math +uv sync +uv run python compare_models.py +``` + +默认使用 CUDA(如果可用),需要可访问 Hugging Face 下载 BERT 与 Wav2Vec2 权重;MediaPipe Face Landmarker 权重会保存在 `math/cache/`。可用 `--device cpu` 指定 CPU。缓存保存在 `math/cache/native/`,中断后重跑会继续使用已完成样本。只有传入 `--force-extract` 才会重算全部原始特征。 + +## 对照定义 + +- **B0**:冻结 BERT 词向量、冻结 CTC Viterbi 词边界、物理时间区间投影;训练折均值/标准差缩放。 +- **B1**:B0 加训练折中位数/MAD 稳健缩放,并对面部旋转使用 SO(3) 均值、对视线代理使用单位向量均值。 +- **B2**:B1 只替换文本时间投影,使用 CTC 固定转写状态图的前向–后向词占据后验。音频/视频的 PTS 不变。 +- **B3**:B1 加音频 log-F0/能量和面部 jaw-open/嘴部开合率的一、二阶时间增广路径签名。缺测处会断开路径。 +- **B4**:B1 加冻结 Wav2Vec2-base-960h 最后四层的时间投影表示。 + +每个模型以相同的五段时间池化探针评价极性和强度。分类器为固定 C=0.05 的逻辑回归,回归器为固定 alpha=25 的 Ridge;参数不按留出折调节。归一化器只使用训练折观测值。95% 差值区间以 `video_id` 为单位做 2,000 次配对 Bootstrap。 + +文本维度为 768(BERT 最后四层、词内子词平均);语音为 74 维(40 log-Mel、13 MFCC、13 ΔMFCC、8 韵律/谱量);视觉为 35 维(17 个 MediaPipe blendshape 代理、6 维头姿、6 维近似视线、6 维面部比例几何)。MediaPipe blendshape 分数不等于 OpenFace AU 强度,视线为基于虹膜偏移的代理量;本次实现记录了实际所用索引与定义,没有将代理量称为 OpenFace 特征。 + +硬边界质量由 CTC 发射分数得到,但不视为校准概率。聚合时按样本内有效词的中位分数归一化,并截断到 [0.25, 4],仅作为相对质量权重。物理覆盖率仍以实际区间交叠计算。B2 的文本后验占据率是期望词活动质量,不能与物理覆盖率互换。 + +没有人工词边界标注,因此结果不报告边界误差、IoU/MATE 或后验经验校准率。情感探针分数只检查当前特征视图保留标签信息的程度,不是对齐正确性的真值。 + +## 结果文件 + +完整结果在 [`results/model_comparison/`](results/model_comparison/): + +- `report.md`:实验设置、主要结果和限制。 +- `comparison_summary.csv`、`fold_metrics.csv`:总体和分折指标。 +- `group_bootstrap_deltas.csv`:相对 B1 的视频组配对 Bootstrap 区间。 +- `oof_predictions.csv`:100 条留组预测。 +- `sample_alignment_summary.csv`、`modality_summary.csv`:100 行样本汇总与 300 行模态明细。 +- `word_alignment_posterior.csv`:逐词硬边界、未校准对齐分数、实际相对质量权重与模型内部边界区间。 +- `split_assignments.csv`、`run_manifest.json`:折号、文件哈希、模型 revision、运行环境和参数。 +- `comparison.png`:OOF 指标图。 diff --git a/math/compare_models.py b/math/compare_models.py new file mode 100644 index 0000000..5fc9267 --- /dev/null +++ b/math/compare_models.py @@ -0,0 +1,1921 @@ +from __future__ import annotations + +import argparse +import csv +import hashlib +import importlib.metadata +import json +import math +import platform +import re +import subprocess +import sys +import time +import urllib.request +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Iterable + +import cv2 +import matplotlib + +matplotlib.use("Agg") +import matplotlib.pyplot as plt +import mediapipe as mp +import numpy as np +import torch +from openpyxl import load_workbook +from scipy.fft import dct, irfft, rfft +from scipy.spatial.transform import Rotation +from sklearn.linear_model import LogisticRegression, Ridge +from sklearn.metrics import accuracy_score, f1_score, mean_absolute_error +from sklearn.model_selection import GroupKFold +from transformers import AutoModel, AutoModelForCTC, AutoTokenizer + + +ROOT = Path(__file__).resolve().parents[1] +MATH_DIR = Path(__file__).resolve().parent +DATA_DIR = ROOT / "E题数据" / "附件1-数据集原始多模态样本" / "MOSEI数据集部分原始视频-100条" +LABEL_FILE = DATA_DIR / "label-100.xlsx" +OUTPUT_DIR = MATH_DIR / "results" / "model_comparison" +CACHE_DIR = MATH_DIR / "cache" / "native" +FACE_MODEL_PATH = MATH_DIR / "cache" / "face_landmarker.task" + +TEXT_MODEL_ID = "google-bert/bert-base-uncased" +SPEECH_MODEL_ID = "facebook/wav2vec2-base-960h" +SAMPLE_RATE = 16_000 +FRAME_LENGTH = 400 +FRAME_STEP = 160 +N_FFT = 512 +MEL_COUNT = 40 +GRID_STEP_S = 0.1 +VISION_RATE_HZ = 5.0 +CTC_FRAME_STEP_S = 320 / SAMPLE_RATE +CTC_RECEPTIVE_SAMPLES = 400 +SEED = 20260923 +N_FOLDS = 5 + +ACTION_NAMES = ( + "browDownLeft", "browDownRight", "browInnerUp", "browOuterUpLeft", + "browOuterUpRight", "eyeBlinkLeft", "eyeBlinkRight", "eyeSquintLeft", + "eyeSquintRight", "eyeWideLeft", "eyeWideRight", "jawOpen", + "mouthFrownLeft", "mouthFrownRight", "mouthPucker", "mouthSmileLeft", + "mouthSmileRight", +) +VISION_NAMES = ( + *[f"mp_blendshape_{name}" for name in ACTION_NAMES], + "pose_rotvec_x", "pose_rotvec_y", "pose_rotvec_z", + "pose_translation_x", "pose_translation_y", "pose_translation_z", + "gaze_left_x", "gaze_left_y", "gaze_left_z", + "gaze_right_x", "gaze_right_y", "gaze_right_z", + "eye_aperture_left", "eye_aperture_right", "mouth_aperture", + "mouth_width_face_ratio", "brow_eye_distance_left", "brow_eye_distance_right", +) +AUDIO_NAMES = ( + *[f"logmel_{index:02d}" for index in range(40)], + *[f"mfcc_{index:02d}" for index in range(13)], + *[f"delta_mfcc_{index:02d}" for index in range(13)], + "log_energy", "log_f0_hz", "voicing_strength", "spectral_centroid_hz", + "spectral_bandwidth_hz", "spectral_flux", "zero_crossing_rate", "hnr_db", +) + + +@dataclass +class Sample: + sample_id: str + video_id: str + clip_id: str + duration_s: float + sentiment: float + polarity: int + text_words: list[str] + text_features: np.ndarray + text_valid: np.ndarray + hard_intervals: np.ndarray + hard_valid: np.ndarray + hard_quality: np.ndarray + audio_times: np.ndarray + audio_features: np.ndarray + audio_observed: np.ndarray + vision_times: np.ndarray + vision_features: np.ndarray + vision_observed: np.ndarray + ctc_times: np.ndarray + ctc_occupancy: np.ndarray + speech_features: np.ndarray + boundary_summary: list[dict[str, float]] + video_sha256: str + + +@dataclass +class View: + features: dict[str, np.ndarray] + observed: dict[str, np.ndarray] + coverage: dict[str, np.ndarray] + edges: np.ndarray + + +def _sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as stream: + for chunk in iter(lambda: stream.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def _version(package: str) -> str: + try: + return importlib.metadata.version(package) + except importlib.metadata.PackageNotFoundError: + return "not-installed" + + +def _safe_name(value: str) -> str: + return re.sub(r"[^A-Za-z0-9_.-]+", "_", value) + + +def _str_id(value: Any) -> str: + if isinstance(value, float) and value.is_integer(): + return str(int(value)) + return str(value).strip() + + +def _read_labels(path: Path) -> list[dict[str, Any]]: + workbook = load_workbook(path, read_only=True, data_only=True) + sheet = workbook.active + rows = sheet.iter_rows(values_only=True) + header = [str(value).strip() if value is not None else "" for value in next(rows)] + index = {name: position for position, name in enumerate(header)} + required = {"video_id", "clip_id", "text", "label", "annotation"} + missing = required - set(index) + if missing: + raise ValueError(f"label workbook lacks columns: {sorted(missing)}") + records: list[dict[str, Any]] = [] + seen: set[str] = set() + for row_number, row in enumerate(rows, start=2): + video_id = _str_id(row[index["video_id"]]) + clip_id = _str_id(row[index["clip_id"]]) + sample_id = f"{video_id}/{clip_id}" + if sample_id in seen: + raise ValueError(f"duplicate source key in label workbook: {sample_id}") + seen.add(sample_id) + label = float(row[index["label"]]) + annotation = str(row[index["annotation"]]).strip().lower() + polarity = 0 if label < 0 else 1 if label == 0 else 2 + expected = {"negative": 0, "neutral": 1, "positive": 2}.get(annotation) + records.append({ + "row_number": row_number, + "sample_id": sample_id, + "video_id": video_id, + "clip_id": clip_id, + "text": str(row[index["text"]] or ""), + "sentiment": label, + "polarity": polarity, + "annotation": annotation, + "label_consistent": expected == polarity, + }) + workbook.close() + if len(records) != 100: + raise ValueError(f"expected 100 label rows, received {len(records)}") + return records + + +def _decode_audio(path: Path) -> np.ndarray: + result = subprocess.run( + [ + "ffmpeg", "-nostdin", "-v", "error", "-i", str(path), "-vn", + "-ac", "1", "-ar", str(SAMPLE_RATE), "-f", "f32le", "pipe:1", + ], + check=True, + capture_output=True, + ) + audio = np.frombuffer(result.stdout, dtype=" float: + result = subprocess.run( + [ + "ffprobe", "-v", "error", "-show_entries", "format=duration", + "-of", "default=noprint_wrappers=1:nokey=1", str(path), + ], + check=True, + capture_output=True, + text=True, + ) + value = float(result.stdout.strip()) + if not math.isfinite(value) or value <= 0: + raise ValueError(f"invalid duration for {path}: {value}") + return value + + +def _mel_filterbank(sample_rate: int, n_fft: int, count: int) -> np.ndarray: + def to_mel(freq: np.ndarray | float) -> np.ndarray | float: + return 2595.0 * np.log10(1.0 + np.asarray(freq) / 700.0) + + def from_mel(mel: np.ndarray) -> np.ndarray: + return 700.0 * (10.0 ** (mel / 2595.0) - 1.0) + + mel_points = np.linspace(to_mel(0.0), to_mel(sample_rate / 2), count + 2) + hz_points = from_mel(mel_points) + bins_hz = np.fft.rfftfreq(n_fft, 1 / sample_rate) + bank = np.zeros((count, len(bins_hz)), dtype=np.float32) + for band in range(count): + left, center, right = hz_points[band:band + 3] + bank[band] = np.maximum( + 0.0, + np.minimum((bins_hz - left) / max(center - left, 1e-9), + (right - bins_hz) / max(right - center, 1e-9)), + ) + return bank + + +def _audio_features(audio: np.ndarray, duration_s: float) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + starts = np.arange(0, max(len(audio), 1), FRAME_STEP, dtype=np.int64) + frames = np.zeros((len(starts), FRAME_LENGTH), dtype=np.float32) + for index, start in enumerate(starts): + chunk = audio[start:start + FRAME_LENGTH] + frames[index, :len(chunk)] = chunk + window = np.hanning(FRAME_LENGTH).astype(np.float32) + windowed = frames * window[None, :] + spectrum = np.abs(rfft(windowed, n=N_FFT, axis=1)).astype(np.float32) + power = spectrum ** 2 + mel = power @ _mel_filterbank(SAMPLE_RATE, N_FFT, MEL_COUNT).T + log_mel = np.log(np.maximum(mel, 1e-8)).astype(np.float32) + mfcc = dct(log_mel, type=2, norm="ortho", axis=1)[:, :13].astype(np.float32) + delta = np.zeros_like(mfcc) + if len(mfcc) > 1: + for frame in range(len(mfcc)): + left, right = max(0, frame - 2), min(len(mfcc), frame + 3) + offsets = np.arange(left, right, dtype=np.float32) - frame + denominator = float(np.square(offsets).sum()) + if denominator > 0: + delta[frame] = (offsets[:, None] * mfcc[left:right]).sum(axis=0) / denominator + + frequencies = np.fft.rfftfreq(N_FFT, 1 / SAMPLE_RATE).astype(np.float32) + magnitude_sum = np.maximum(spectrum.sum(axis=1), 1e-8) + centroid = (spectrum * frequencies[None, :]).sum(axis=1) / magnitude_sum + bandwidth = np.sqrt( + (spectrum * (frequencies[None, :] - centroid[:, None]) ** 2).sum(axis=1) + / magnitude_sum + ) + normalized_spectrum = spectrum / magnitude_sum[:, None] + flux = np.zeros(len(frames), dtype=np.float32) + if len(frames) > 1: + flux[1:] = np.square(normalized_spectrum[1:] - normalized_spectrum[:-1]).sum(axis=1) + zcr = (np.diff(np.signbit(frames), axis=1) != 0).mean(axis=1).astype(np.float32) + energy = np.mean(np.square(frames), axis=1) + + log_f0 = np.zeros(len(frames), dtype=np.float32) + voicing = np.zeros(len(frames), dtype=np.float32) + hnr = np.zeros(len(frames), dtype=np.float32) + voiced = np.zeros(len(frames), dtype=np.bool_) + min_lag, max_lag = int(SAMPLE_RATE / 400), int(SAMPLE_RATE / 60) + for frame_index, frame in enumerate(windowed): + if energy[frame_index] < 1e-7: + continue + autocorr = irfft(np.abs(rfft(frame, n=1024)) ** 2, n=1024)[:max_lag + 1] + if autocorr[0] <= 1e-10: + continue + autocorr /= autocorr[0] + region = autocorr[min_lag:max_lag + 1] + if not len(region): + continue + lag = min_lag + int(np.argmax(region)) + strength = float(np.clip(autocorr[lag], 0.0, 1.0)) + voicing[frame_index] = strength + voiced[frame_index] = strength >= 0.30 + if voiced[frame_index]: + log_f0[frame_index] = math.log(SAMPLE_RATE / lag) + hnr[frame_index] = 10.0 * math.log10(max(strength, 1e-5) / max(1.0 - strength, 1e-5)) + + prosody = np.column_stack(( + np.log(np.maximum(energy, 1e-8)), log_f0, voicing, centroid, bandwidth, + flux, zcr, hnr, + )).astype(np.float32) + features = np.column_stack((log_mel, mfcc, delta, prosody)).astype(np.float32) + if features.shape[1] != 74: + raise AssertionError(f"internal audio dimension error: {features.shape}") + observed = np.isfinite(features) + observed[:, 67] = voiced + observed[:, 73] = voiced + if len(frames) < 2: + observed[:, 53:66] = False + features = np.nan_to_num(features, nan=0.0, posinf=0.0, neginf=0.0) + times = np.minimum((starts + FRAME_LENGTH / 2) / SAMPLE_RATE, duration_s).astype(np.float32) + return times, features, observed + + +def _text_features(words: list[str], tokenizer: Any, model: Any, device: torch.device) -> tuple[np.ndarray, np.ndarray]: + output = np.zeros((len(words), int(model.config.hidden_size)), dtype=np.float32) + valid = np.zeros(len(words), dtype=np.bool_) + if not words: + return output, valid + token_ids: list[int] = [] + word_ids: list[int] = [] + for word_index, word in enumerate(words): + word_tokens = tokenizer(word, add_special_tokens=False)["input_ids"] + token_ids.extend(int(value) for value in word_tokens) + word_ids.extend([word_index] * len(word_tokens)) + token_sums = np.zeros((len(token_ids), output.shape[1]), dtype=np.float64) + token_weights = np.zeros(len(token_ids), dtype=np.float64) + window_size, stride = 510, 384 + offsets = range(0, max(len(token_ids), 1), stride) + with torch.inference_mode(): + for offset in offsets: + end = min(len(token_ids), offset + window_size) + if offset >= end: + break + content = token_ids[offset:end] + special_content = [int(tokenizer.cls_token_id), *content, int(tokenizer.sep_token_id)] + encoded = { + "input_ids": torch.tensor([special_content], dtype=torch.long, device=device), + "attention_mask": torch.ones((1, len(special_content)), dtype=torch.long, device=device), + } + hidden_states = model(**encoded, output_hidden_states=True).hidden_states + hidden = torch.stack(tuple(hidden_states[-4:]), dim=0).mean(dim=0)[0, 1:1 + len(content)] + values = hidden.float().cpu().numpy() + for local_index, value in enumerate(values): + global_index = offset + local_index + edge_weight = float(min(local_index + 1, len(content) - local_index)) + token_sums[global_index] += edge_weight * value + token_weights[global_index] += edge_weight + accum = np.zeros_like(output, dtype=np.float64) + counts = np.zeros(len(words), dtype=np.float64) + for token_index, word_index in enumerate(word_ids): + if word_index is None or not (0 <= word_index < len(words)) or token_weights[token_index] <= 0: + continue + accum[word_index] += token_sums[token_index] / token_weights[token_index] + counts[word_index] += 1.0 + valid = counts > 0 + output[valid] = (accum[valid] / counts[valid, None]).astype(np.float32) + return output, valid + + +def _ctc_targets(words: list[str], tokenizer: Any) -> tuple[list[int], list[list[int]]]: + vocab = tokenizer.get_vocab() + delimiter_id = int(tokenizer.convert_tokens_to_ids(tokenizer.word_delimiter_token or "|")) + unknown_id = int(tokenizer.unk_token_id) + targets: list[int] = [] + per_word: list[list[int]] = [[] for _ in words] + for word_index, raw_word in enumerate(words): + if word_index: + targets.append(delimiter_id) + normalized = re.sub(r"[^a-z']", "", raw_word.lower().replace("’", "'")) + for char in normalized: + per_word[word_index].append(len(targets)) + targets.append(int(vocab.get(char, unknown_id))) + return targets, per_word + + +def _ctc_path_and_posterior(log_probs: np.ndarray, targets: list[int], blank_id: int) -> tuple[np.ndarray | None, np.ndarray | None, float]: + if not targets or log_probs.ndim != 2: + return None, None, -math.inf + target = np.asarray(targets, dtype=np.int64) + states = np.full(2 * len(target) + 1, blank_id, dtype=np.int64) + states[1::2] = target + frames, state_count = log_probs.shape[0], len(states) + if frames == 0 or frames < len(target): + return None, None, -math.inf + alpha = np.full((frames, state_count), -np.inf, dtype=np.float64) + alpha[0, 0] = float(log_probs[0, blank_id]) + alpha[0, 1] = float(log_probs[0, states[1]]) + skip_ok = np.zeros(state_count, dtype=np.bool_) + if state_count > 2: + indices = np.arange(state_count) + skip_ok[2:] = (states[2:] != blank_id) & (states[2:] != states[:-2]) + for frame in range(1, frames): + prev = alpha[frame - 1] + incoming = prev.copy() + incoming[1:] = np.logaddexp(incoming[1:], prev[:-1]) + valid_skip = np.flatnonzero(skip_ok) + if len(valid_skip): + incoming[valid_skip] = np.logaddexp(incoming[valid_skip], prev[valid_skip - 2]) + alpha[frame] = incoming + log_probs[frame, states] + log_z = float(np.logaddexp(alpha[-1, -1], alpha[-1, -2])) + if not math.isfinite(log_z): + return None, None, -math.inf + + beta = np.full((frames, state_count), -np.inf, dtype=np.float64) + beta[-1, -1] = 0.0 + beta[-1, -2] = 0.0 + for frame in range(frames - 2, -1, -1): + nxt = beta[frame + 1] + log_probs[frame + 1, states] + # A CTC state may stay active for any number of frames. Start with the + # same-state transition, then add transitions to the next states. + values = nxt.copy() + values[:-1] = np.logaddexp(values[:-1], nxt[1:]) + if state_count > 2: + dest = np.flatnonzero(skip_ok) + values[dest - 2] = np.logaddexp(values[dest - 2], nxt[dest]) + beta[frame] = values + posterior = np.exp(np.clip(alpha + beta - log_z, -745.0, 0.0)).astype(np.float32) + + back = np.zeros((frames, state_count), dtype=np.uint8) + previous = np.full(state_count, -np.inf, dtype=np.float64) + previous[0] = float(log_probs[0, blank_id]) + previous[1] = float(log_probs[0, states[1]]) + for frame in range(1, frames): + stay = previous + one = np.full(state_count, -np.inf, dtype=np.float64) + one[1:] = previous[:-1] + two = np.full(state_count, -np.inf, dtype=np.float64) + two[skip_ok] = previous[np.flatnonzero(skip_ok) - 2] + candidates = np.stack((stay, one, two), axis=0) + choice = candidates.argmax(axis=0).astype(np.uint8) + previous = candidates[choice, np.arange(state_count)] + log_probs[frame, states] + back[frame] = choice + state = state_count - 1 if previous[-1] >= previous[-2] else state_count - 2 + path = np.empty(frames, dtype=np.int32) + path[-1] = state + for frame in range(frames - 1, 0, -1): + state -= int(back[frame, state]) + path[frame - 1] = state + return path, posterior, log_z + + +def _entry_distribution(log_probs: np.ndarray, states: np.ndarray, alpha: np.ndarray, beta: np.ndarray, log_z: float, state: int) -> np.ndarray: + frames = len(log_probs) + mass = np.zeros(frames, dtype=np.float64) + if state == 1: + mass[0] = math.exp(float(log_probs[0, states[state]] + beta[0, state] - log_z)) + predecessors = [state - 1] + if state >= 2 and states[state] != states[state - 2]: + predecessors.append(state - 2) + for frame in range(1, frames): + terms = [alpha[frame - 1, prev] for prev in predecessors if prev >= 0] + if terms: + log_mass = float(np.logaddexp.reduce(terms) + log_probs[frame, states[state]] + beta[frame, state] - log_z) + mass[frame] = math.exp(max(-745.0, min(log_mass, 0.0))) + return mass + + +def _exit_distribution(log_probs: np.ndarray, states: np.ndarray, alpha: np.ndarray, beta: np.ndarray, log_z: float, state: int) -> np.ndarray: + frames = len(log_probs) + mass = np.zeros(frames + 1, dtype=np.float64) + successors = [state + 1] + if state + 2 < len(states) and states[state] != states[state + 2]: + successors.append(state + 2) + for frame in range(1, frames): + terms = [ + alpha[frame - 1, state] + log_probs[frame, states[nxt]] + beta[frame, nxt] + for nxt in successors if nxt < len(states) + ] + if terms: + mass[frame] = math.exp(max(-745.0, min(float(np.logaddexp.reduce(terms) - log_z), 0.0))) + if state == len(states) - 2: + mass[frames] = math.exp(max(-745.0, min(float(alpha[-1, state] - log_z), 0.0))) + return mass + + +def _weighted_quantile(values: np.ndarray, weights: np.ndarray, quantile: float) -> float: + if not len(values) or float(weights.sum()) <= 0: + return math.nan + order = np.argsort(values) + values, weights = values[order], weights[order] + cumulative = np.cumsum(weights) / weights.sum() + return float(values[min(int(np.searchsorted(cumulative, quantile, side="left")), len(values) - 1)]) + + +def _ctc_boundaries( + log_probs: np.ndarray, targets: list[int], word_targets: list[list[int]], + blank_id: int, duration_s: float, center_s: float, +) -> tuple[np.ndarray, list[dict[str, float]], np.ndarray]: + path, posterior, log_z = _ctc_path_and_posterior(log_probs, targets, blank_id) + occupancy = np.zeros((len(log_probs), len(word_targets)), dtype=np.float32) + summaries: list[dict[str, float]] = [ + {"start_mean_s": math.nan, "end_mean_s": math.nan, + "start_p05_s": math.nan, "start_p95_s": math.nan, + "end_p05_s": math.nan, "end_p95_s": math.nan, + "start_width90_s": math.nan, "end_width90_s": math.nan} + for _ in word_targets + ] + if path is None or posterior is None: + return np.empty((0, len(word_targets)), dtype=np.float32), summaries, path if path is not None else np.empty((0,), dtype=np.int32) + state_ids = np.full(2 * len(targets) + 1, blank_id, dtype=np.int64) + state_ids[1::2] = np.asarray(targets, dtype=np.int64) + # Recompute the dynamic-programming tables for boundary transition marginals. + frames, count = len(log_probs), len(state_ids) + alpha = np.full((frames, count), -np.inf, dtype=np.float64) + alpha[0, 0] = log_probs[0, blank_id] + alpha[0, 1] = log_probs[0, state_ids[1]] + skip = np.zeros(count, dtype=np.bool_) + if count > 2: + skip[2:] = (state_ids[2:] != blank_id) & (state_ids[2:] != state_ids[:-2]) + for frame in range(1, frames): + incoming = alpha[frame - 1].copy() + incoming[1:] = np.logaddexp(incoming[1:], alpha[frame - 1, :-1]) + skip_states = np.flatnonzero(skip) + if len(skip_states): + incoming[skip_states] = np.logaddexp(incoming[skip_states], alpha[frame - 1, skip_states - 2]) + alpha[frame] = incoming + log_probs[frame, state_ids] + beta = np.full((frames, count), -np.inf, dtype=np.float64) + beta[-1, -1] = beta[-1, -2] = 0.0 + for frame in range(frames - 2, -1, -1): + nxt = beta[frame + 1] + log_probs[frame + 1, state_ids] + current = nxt.copy() + current[:-1] = np.logaddexp(current[:-1], nxt[1:]) + skip_states = np.flatnonzero(skip) + if len(skip_states): + current[skip_states - 2] = np.logaddexp(current[skip_states - 2], nxt[skip_states]) + beta[frame] = current + frame_step = CTC_FRAME_STEP_S + first_edge = max(0.0, center_s - frame_step / 2) + frame_edges = np.clip(first_edge + np.arange(frames + 1, dtype=np.float64) * frame_step, 0.0, duration_s) + for word_index, token_indices in enumerate(word_targets): + if not token_indices: + continue + char_states = np.asarray([2 * target_index + 1 for target_index in token_indices], dtype=np.int64) + occupancy[:, word_index] = posterior[:, char_states].sum(axis=1) + start_mass = _entry_distribution(log_probs, state_ids, alpha, beta, log_z, int(char_states[0])) + end_mass = _exit_distribution(log_probs, state_ids, alpha, beta, log_z, int(char_states[-1])) + start_total = float(start_mass.sum()) + end_total = float(end_mass.sum()) + if not math.isclose(start_total, 1.0, rel_tol=2e-4, abs_tol=2e-4): + raise FloatingPointError(f"CTC start-boundary marginal sums to {start_total:.6g}, expected 1") + if not math.isclose(end_total, 1.0, rel_tol=2e-4, abs_tol=2e-4): + raise FloatingPointError(f"CTC end-boundary marginal sums to {end_total:.6g}, expected 1") + start_times = frame_edges[:-1] + end_times = frame_edges + start_p05 = _weighted_quantile(start_times, start_mass, 0.05) + start_p95 = _weighted_quantile(start_times, start_mass, 0.95) + end_p05 = _weighted_quantile(end_times, end_mass, 0.05) + end_p95 = _weighted_quantile(end_times, end_mass, 0.95) + summaries[word_index] = { + "start_mean_s": float(np.sum(start_mass * start_times) / start_total), + "end_mean_s": float(np.sum(end_mass * end_times) / end_total), + "start_p05_s": start_p05, + "start_p95_s": start_p95, + "end_p05_s": end_p05, + "end_p95_s": end_p95, + "start_width90_s": start_p95 - start_p05, + "end_width90_s": end_p95 - end_p05, + } + return occupancy, summaries, path + + +def _posterior_hard_intervals( + log_probs: np.ndarray, + path: np.ndarray | None, + targets: list[int], + word_targets: list[list[int]], + duration_s: float, + frame_step: float, + center_s: float, +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + intervals = np.zeros((len(word_targets), 2), dtype=np.float32) + valid = np.zeros(len(word_targets), dtype=np.bool_) + quality = np.zeros(len(word_targets), dtype=np.float32) + if path is None or not len(path): + return intervals, valid, quality + for word_index, target_indices in enumerate(word_targets): + if not target_indices: + continue + char_states = np.asarray([2 * index + 1 for index in target_indices], dtype=np.int32) + frame_indices = np.flatnonzero(np.isin(path, char_states)) + if not len(frame_indices): + continue + first, last = int(frame_indices[0]), int(frame_indices[-1]) + start = max(0.0, first * frame_step + center_s - frame_step / 2) + end = min(duration_s, (last + 1) * frame_step + center_s - frame_step / 2) + if end <= start: + continue + intervals[word_index] = (start, end) + valid[word_index] = True + scores = [] + for target_index in target_indices: + selected = np.flatnonzero(path == 2 * target_index + 1) + if len(selected): + scores.extend(log_probs[selected, targets[target_index]].tolist()) + quality[word_index] = float(np.exp(np.mean(scores))) if scores else 0.0 + return intervals, valid, quality + + +def _landmark_points(landmarks: Iterable[Any]) -> np.ndarray: + return np.asarray([[item.x, item.y, item.z] for item in landmarks], dtype=np.float32) + + +def _distance(points: np.ndarray, left: int, right: int) -> float: + return float(np.linalg.norm(points[left] - points[right])) + + +def _gaze_proxy(points: np.ndarray, left_eye: bool) -> np.ndarray | None: + if points.shape[0] < 478: + return None + if left_eye: + corner_a, corner_b, upper, lower = 33, 133, 159, 145 + iris_ids = np.arange(468, 473) + else: + corner_a, corner_b, upper, lower = 362, 263, 386, 374 + iris_ids = np.arange(473, 478) + horizontal = points[corner_b] - points[corner_a] + width = float(np.linalg.norm(horizontal)) + vertical = points[upper] - points[lower] + height = float(np.linalg.norm(vertical)) + if width <= 1e-6 or height <= 1e-6: + return None + u = horizontal / width + v = vertical - float(np.dot(vertical, u)) * u + v_norm = float(np.linalg.norm(v)) + if v_norm <= 1e-6: + return None + v /= v_norm + eye_center = (points[corner_a] + points[corner_b]) / 2 + iris_center = points[iris_ids].mean(axis=0) + delta = iris_center - eye_center + gx = float(np.dot(delta, u) / width) + gy = float(np.dot(delta, v) / width) + # Face-relative iris offset plus a fixed forward component; this is a gaze proxy. + direction = np.asarray([-gx, -gy, -1.0], dtype=np.float32) + norm = float(np.linalg.norm(direction)) + if norm <= 1e-8: + return None + return direction / norm + + +def _pose_from_matrix(matrix_obj: Any) -> tuple[np.ndarray, np.ndarray] | None: + raw = np.asarray(matrix_obj.data, dtype=np.float64) + rows = int(getattr(matrix_obj, "rows", 4) or 4) + cols = int(getattr(matrix_obj, "cols", 4) or 4) + if raw.size != rows * cols or rows < 3 or cols < 4: + return None + matrix = raw.reshape(rows, cols) + rotation_raw = matrix[:3, :3] + if not np.isfinite(rotation_raw).all() or not np.isfinite(matrix[:3, 3]).all(): + return None + u, _, vh = np.linalg.svd(rotation_raw) + rotation_matrix = u @ vh + if np.linalg.det(rotation_matrix) < 0: + u[:, -1] *= -1 + rotation_matrix = u @ vh + return Rotation.from_matrix(rotation_matrix).as_rotvec().astype(np.float32), matrix[:3, 3].astype(np.float32) + + +def _vision_frame_features(landmarks: list[Any], blendshapes: list[Any], matrix_obj: Any | None) -> tuple[np.ndarray, np.ndarray]: + features = np.zeros(35, dtype=np.float32) + observed = np.zeros(35, dtype=np.bool_) + shape_lookup = {category.category_name: float(category.score) for category in blendshapes} + for index, name in enumerate(ACTION_NAMES): + if name in shape_lookup and math.isfinite(shape_lookup[name]): + features[index] = shape_lookup[name] + observed[index] = True + + if matrix_obj is not None: + pose = _pose_from_matrix(matrix_obj) + if pose is not None: + features[17:20] = pose[0] + features[20:23] = pose[1] + observed[17:23] = True + + points = _landmark_points(landmarks) + for eye_index, is_left in enumerate((True, False)): + gaze = _gaze_proxy(points, is_left) + if gaze is not None: + start = 23 + eye_index * 3 + features[start:start + 3] = gaze + observed[start:start + 3] = True + if points.shape[0] >= 455: + face_width = _distance(points, 234, 454) + left_eye_width = _distance(points, 33, 133) + right_eye_width = _distance(points, 362, 263) + mouth_width = _distance(points, 61, 291) + if min(face_width, left_eye_width, right_eye_width, mouth_width) > 1e-6: + ratios = np.asarray(( + _distance(points, 159, 145) / left_eye_width, + _distance(points, 386, 374) / right_eye_width, + _distance(points, 13, 14) / mouth_width, + mouth_width / face_width, + _distance(points, 105, 159) / left_eye_width, + _distance(points, 334, 386) / right_eye_width, + ), dtype=np.float32) + features[29:35] = ratios + observed[29:35] = np.isfinite(ratios) + return features, observed + + +def _ensure_face_model() -> str: + FACE_MODEL_PATH.parent.mkdir(parents=True, exist_ok=True) + if not FACE_MODEL_PATH.is_file() or FACE_MODEL_PATH.stat().st_size < 1_000_000: + url = ( + "https://storage.googleapis.com/mediapipe-models/face_landmarker/" + "face_landmarker/float16/latest/face_landmarker.task" + ) + temporary = FACE_MODEL_PATH.with_suffix(".task.tmp") + urllib.request.urlretrieve(url, temporary) + if temporary.stat().st_size < 1_000_000: + temporary.unlink(missing_ok=True) + raise RuntimeError("downloaded Face Landmarker model is unexpectedly small") + temporary.replace(FACE_MODEL_PATH) + return _sha256(FACE_MODEL_PATH) + + +def _vision_features(path: Path, duration_s: float, face_model_path: Path) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + options = mp.tasks.vision.FaceLandmarkerOptions( + base_options=mp.tasks.BaseOptions(model_asset_path=str(face_model_path)), + running_mode=mp.tasks.vision.RunningMode.VIDEO, + num_faces=1, + output_face_blendshapes=True, + output_facial_transformation_matrixes=True, + ) + capture = cv2.VideoCapture(str(path)) + if not capture.isOpened(): + raise RuntimeError(f"OpenCV cannot decode video: {path}") + fps = float(capture.get(cv2.CAP_PROP_FPS) or 0.0) + if not math.isfinite(fps) or fps <= 0: + fps = 30.0 + timestamps: list[float] = [] + values: list[np.ndarray] = [] + masks: list[np.ndarray] = [] + next_time = 0.0 + frame_index = 0 + last_timestamp_ms = -1 + with mp.tasks.vision.FaceLandmarker.create_from_options(options) as landmarker: + while True: + ok, bgr = capture.read() + if not ok: + break + reported_ms = float(capture.get(cv2.CAP_PROP_POS_MSEC)) + timestamp = reported_ms / 1000.0 + previous_timestamp = timestamps[-1] if timestamps else -1.0 + if not math.isfinite(timestamp) or (frame_index > 0 and timestamp <= previous_timestamp): + timestamp = frame_index / fps + frame_index += 1 + if timestamp + 1e-6 < next_time: + continue + while next_time <= timestamp: + next_time += 1.0 / VISION_RATE_HZ + timestamp = min(max(timestamp, 0.0), duration_s) + timestamp_ms = max(last_timestamp_ms + 1, int(round(timestamp * 1000))) + last_timestamp_ms = timestamp_ms + rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) + image = mp.Image(image_format=mp.ImageFormat.SRGB, data=np.ascontiguousarray(rgb)) + result = landmarker.detect_for_video(image, timestamp_ms) + timestamps.append(timestamp) + faces = result.face_landmarks + if not faces: + values.append(np.zeros(35, dtype=np.float32)) + masks.append(np.zeros(35, dtype=np.bool_)) + continue + blendshapes = result.face_blendshapes[0] if result.face_blendshapes else [] + matrix = result.facial_transformation_matrixes[0] if result.facial_transformation_matrixes else None + vector, mask = _vision_frame_features(faces[0], blendshapes, matrix) + values.append(vector) + masks.append(mask) + capture.release() + if not timestamps: + return np.empty(0, np.float32), np.empty((0, 35), np.float32), np.empty((0, 35), np.bool_) + return np.asarray(timestamps, np.float32), np.stack(values), np.stack(masks) + + +def _load_models(device: torch.device) -> tuple[Any, Any, Any, Any, dict[str, Any]]: + text_tokenizer = AutoTokenizer.from_pretrained(TEXT_MODEL_ID, use_fast=True) + text_model = AutoModel.from_pretrained(TEXT_MODEL_ID, output_hidden_states=True).to(device).eval() + speech_tokenizer = AutoTokenizer.from_pretrained(SPEECH_MODEL_ID) + speech_model = AutoModelForCTC.from_pretrained(SPEECH_MODEL_ID).to(device).eval() + config = speech_model.config + stride_samples = int(np.prod(config.conv_stride)) + receptive = 1 + jump = 1 + for kernel, stride in zip(config.conv_kernel, config.conv_stride): + receptive += (int(kernel) - 1) * jump + jump *= int(stride) + info = { + "text_id": TEXT_MODEL_ID, + "text_revision": getattr(text_model.config, "_commit_hash", None), + "speech_id": SPEECH_MODEL_ID, + "speech_revision": getattr(config, "_commit_hash", None), + "speech_stride_samples": stride_samples, + "speech_receptive_field_samples": receptive, + } + return text_tokenizer, text_model, speech_tokenizer, speech_model, info + + +def _extract_native_sample( + record: dict[str, Any], + models: tuple[Any, Any, Any, Any, dict[str, Any]], + device: torch.device, + face_model_path: Path, + video_sha256: str, +) -> Sample: + text_tokenizer, text_model, ctc_tokenizer, speech_model, model_info = models + video_path = DATA_DIR / record["video_id"] / f"{record['clip_id']}.mp4" + duration_s = _duration(video_path) + words = record["text"].split() + text_vectors, text_valid = _text_features(words, text_tokenizer, text_model, device) + waveform = _decode_audio(video_path) + audio_times, audio_vectors, audio_observed = _audio_features(waveform, duration_s) + vision_times, vision_vectors, vision_observed = _vision_features(video_path, duration_s, face_model_path) + targets, word_targets = _ctc_targets(words, ctc_tokenizer) + blank_id = int(ctc_tokenizer.pad_token_id) + if targets: + with torch.inference_mode(): + input_values = torch.from_numpy(waveform).to(device).unsqueeze(0) + output = speech_model(input_values=input_values, output_hidden_states=True) + logits = output.logits[0].float() + log_probs = torch.log_softmax(logits, dim=-1).cpu().numpy().astype(np.float32) + deep_states = torch.stack(tuple(output.hidden_states[-4:]), dim=0).mean(dim=0)[0].float().cpu().numpy() + else: + log_probs = np.empty((0, len(ctc_tokenizer)), dtype=np.float32) + deep_states = np.empty((0, int(speech_model.config.hidden_size)), dtype=np.float32) + stride_samples = int(model_info["speech_stride_samples"]) + frame_step = stride_samples / SAMPLE_RATE + center_s = float(model_info["speech_receptive_field_samples"]) / (2 * SAMPLE_RATE) + if len(log_probs) and targets: + occupancy, boundary_summary, path = _ctc_boundaries( + log_probs, targets, word_targets, blank_id, duration_s, center_s + ) + hard_intervals, hard_valid, hard_quality = _posterior_hard_intervals( + log_probs, path, targets, word_targets, duration_s, frame_step, center_s + ) + else: + occupancy = np.zeros((len(log_probs), len(words)), dtype=np.float32) + boundary_summary = [ + {"start_mean_s": math.nan, "end_mean_s": math.nan, + "start_p05_s": math.nan, "start_p95_s": math.nan, + "end_p05_s": math.nan, "end_p95_s": math.nan, + "start_width90_s": math.nan, "end_width90_s": math.nan} + for _ in words + ] + hard_intervals = np.zeros((len(words), 2), dtype=np.float32) + hard_valid = np.zeros(len(words), dtype=np.bool_) + hard_quality = np.zeros(len(words), dtype=np.float32) + ctc_frame_times = (np.arange(len(log_probs), dtype=np.float32) * frame_step + center_s).clip(0.0, duration_s) + return Sample( + sample_id=record["sample_id"], + video_id=record["video_id"], + clip_id=record["clip_id"], + duration_s=duration_s, + sentiment=record["sentiment"], + polarity=record["polarity"], + text_words=words, + text_features=text_vectors.astype(np.float16), + text_valid=text_valid, + hard_intervals=hard_intervals, + hard_valid=hard_valid, + hard_quality=hard_quality, + audio_times=audio_times, + audio_features=audio_vectors.astype(np.float16), + audio_observed=audio_observed, + vision_times=vision_times, + vision_features=vision_vectors.astype(np.float16), + vision_observed=vision_observed, + ctc_times=ctc_frame_times, + ctc_occupancy=occupancy.astype(np.float16), + speech_features=deep_states.astype(np.float16), + boundary_summary=boundary_summary, + video_sha256=video_sha256, + ) + + +def _save_cache(path: Path, sample: Sample, cache_schema: str) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + temporary = path.with_suffix(".npz.tmp") + with temporary.open("wb") as stream: + np.savez_compressed( + stream, + cache_schema=np.asarray(cache_schema), + sample_id=np.asarray(sample.sample_id), + video_id=np.asarray(sample.video_id), + clip_id=np.asarray(sample.clip_id), + duration_s=np.asarray(sample.duration_s, dtype=np.float32), + sentiment=np.asarray(sample.sentiment, dtype=np.float32), + polarity=np.asarray(sample.polarity, dtype=np.int8), + text_words=np.asarray(sample.text_words, dtype="U160"), + text_features=sample.text_features.astype(np.float16), + text_valid=sample.text_valid, + hard_intervals=sample.hard_intervals.astype(np.float32), + hard_valid=sample.hard_valid, + hard_quality=sample.hard_quality.astype(np.float32), + audio_times=sample.audio_times.astype(np.float32), + audio_features=sample.audio_features.astype(np.float16), + audio_observed=sample.audio_observed, + vision_times=sample.vision_times.astype(np.float32), + vision_features=sample.vision_features.astype(np.float16), + vision_observed=sample.vision_observed, + ctc_times=sample.ctc_times.astype(np.float32), + ctc_occupancy=sample.ctc_occupancy.astype(np.float16), + speech_features=sample.speech_features.astype(np.float16), + boundary_summary=json.dumps(sample.boundary_summary, ensure_ascii=False), + video_sha256=np.asarray(sample.video_sha256), + ) + temporary.replace(path) + + +def _load_cache(path: Path, record: dict[str, Any], source_hash: str, cache_schema: str) -> Sample: + with np.load(path, allow_pickle=False) as data: + if str(data["cache_schema"].item()) != cache_schema: + raise ValueError("feature cache schema mismatch") + if str(data["sample_id"].item()) != record["sample_id"]: + raise ValueError("feature cache sample key mismatch") + if str(data["video_sha256"].item()) != source_hash: + raise ValueError("feature cache source hash mismatch") + return Sample( + sample_id=record["sample_id"], video_id=record["video_id"], clip_id=record["clip_id"], + duration_s=float(data["duration_s"]), sentiment=float(data["sentiment"]), polarity=int(data["polarity"]), + text_words=data["text_words"].astype(str).tolist(), text_features=np.asarray(data["text_features"], dtype=np.float16), + text_valid=np.asarray(data["text_valid"], dtype=np.bool_), hard_intervals=np.asarray(data["hard_intervals"], dtype=np.float32), + hard_valid=np.asarray(data["hard_valid"], dtype=np.bool_), hard_quality=np.asarray(data["hard_quality"], dtype=np.float32), + audio_times=np.asarray(data["audio_times"], dtype=np.float32), audio_features=np.asarray(data["audio_features"], dtype=np.float16), + audio_observed=np.asarray(data["audio_observed"], dtype=np.bool_), vision_times=np.asarray(data["vision_times"], dtype=np.float32), + vision_features=np.asarray(data["vision_features"], dtype=np.float16), vision_observed=np.asarray(data["vision_observed"], dtype=np.bool_), + ctc_times=np.asarray(data["ctc_times"], dtype=np.float32), ctc_occupancy=np.asarray(data["ctc_occupancy"], dtype=np.float16), + speech_features=np.asarray(data["speech_features"], dtype=np.float16), + boundary_summary=json.loads(str(data["boundary_summary"].item())), video_sha256=source_hash, + ) + + +def _voronoi_intervals(times: np.ndarray, duration_s: float) -> np.ndarray: + if not len(times): + return np.empty((0, 2), dtype=np.float32) + centers = np.clip(np.asarray(times, dtype=np.float64), 0.0, duration_s) + if np.any(np.diff(centers) < -1e-7): + order = np.argsort(centers) + centers = centers[order] + else: + order = np.arange(len(centers)) + # Duplicate PTS values are coalesced to a tiny increasing interval for assignment. + for index in range(1, len(centers)): + if centers[index] <= centers[index - 1]: + centers[index] = min(duration_s, centers[index - 1] + 1e-6) + edges = np.empty(len(centers) + 1, dtype=np.float64) + edges[0], edges[-1] = 0.0, duration_s + if len(centers) > 1: + edges[1:-1] = (centers[:-1] + centers[1:]) / 2 + edges = np.maximum.accumulate(np.clip(edges, 0.0, duration_s)) + intervals = np.column_stack((edges[:-1], edges[1:])).astype(np.float32) + if len(order) != len(intervals) or not np.array_equal(order, np.arange(len(order))): + restored = np.zeros_like(intervals) + restored[order] = intervals + return restored + return intervals + + +def _grid_edges(duration_s: float) -> np.ndarray: + count = max(1, int(math.ceil(duration_s / GRID_STEP_S))) + edges = np.arange(count + 1, dtype=np.float64) * GRID_STEP_S + edges[-1] = duration_s + return edges + + +def _project_rows( + values: np.ndarray, + observed: np.ndarray, + source_intervals: np.ndarray, + qualities: np.ndarray, + target_edges: np.ndarray, +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + dim = values.shape[1] if values.ndim == 2 else 0 + count = len(target_edges) - 1 + output = np.zeros((count, dim), dtype=np.float32) + mask = np.zeros((count, dim), dtype=np.bool_) + coverage = np.zeros((count, dim), dtype=np.float32) + if not dim or not len(source_intervals): + return output, mask, coverage + intervals = np.asarray(source_intervals, dtype=np.float64) + qualities = np.maximum(np.asarray(qualities, dtype=np.float64), 0.0) + values64 = np.asarray(values, dtype=np.float64) + for target_index, (left, right) in enumerate(zip(target_edges[:-1], target_edges[1:])): + if right <= left: + continue + overlap = np.maximum( + 0.0, + np.minimum(intervals[:, 1], right) - np.maximum(intervals[:, 0], left), + ) * qualities + candidate = np.flatnonzero(overlap > 0) + if not len(candidate): + continue + local_mask = observed[candidate] + local_weight = overlap[candidate, None] * local_mask + denominator = local_weight.sum(axis=0) + physical_coverage = (overlap[candidate, None] * local_mask).sum(axis=0) + good = denominator > 0 + if good.any(): + output[target_index, good] = ( + (values64[candidate] * local_weight).sum(axis=0)[good] / denominator[good] + ).astype(np.float32) + mask[target_index, good] = True + coverage[target_index, good] = np.minimum(1.0, physical_coverage[good] / (right - left)).astype(np.float32) + return output, mask, coverage + + +def _so3_weighted_mean(rotvecs: np.ndarray, weights: np.ndarray) -> np.ndarray | None: + positive = weights > 0 + if not positive.any(): + return None + rotations = Rotation.from_rotvec(np.asarray(rotvecs[positive], dtype=np.float64)) + local_weights = np.asarray(weights[positive], dtype=np.float64) + local_weights /= local_weights.sum() + matrices = rotations.as_matrix() + mean_matrix = np.einsum("n,nij->ij", local_weights, matrices) + u, _, vh = np.linalg.svd(mean_matrix) + mean_matrix = u @ vh + if np.linalg.det(mean_matrix) < 0: + u[:, -1] *= -1 + mean_matrix = u @ vh + mean_rotation = Rotation.from_matrix(mean_matrix) + for _ in range(30): + residual = (mean_rotation.inv() * rotations).as_rotvec() + delta = np.einsum("n,nd->d", local_weights, residual) + if np.linalg.norm(delta) < 1e-8: + break + mean_rotation = mean_rotation * Rotation.from_rotvec(delta) + return mean_rotation.as_rotvec().astype(np.float32) + + +def _project_vision_geometry(sample: Sample, target_edges: np.ndarray, geometry_aware: bool) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + intervals = _voronoi_intervals(sample.vision_times, sample.duration_s) + quality = np.ones(len(intervals), dtype=np.float32) + values, masks, coverage = _project_rows( + sample.vision_features.astype(np.float32), sample.vision_observed, intervals, quality, target_edges + ) + if not geometry_aware or not len(intervals): + return values, masks, coverage + raw = sample.vision_features.astype(np.float32) + for target_index, (left, right) in enumerate(zip(target_edges[:-1], target_edges[1:])): + overlap = np.maximum(0.0, np.minimum(intervals[:, 1], right) - np.maximum(intervals[:, 0], left)) + if not np.any(overlap > 0): + continue + pose_rows = (overlap > 0) & sample.vision_observed[:, 17:20].all(axis=1) + if pose_rows.any(): + vector = _so3_weighted_mean(raw[pose_rows, 17:20], overlap[pose_rows]) + if vector is not None: + values[target_index, 17:20] = vector + masks[target_index, 17:20] = True + for start in (23, 26): + valid_rows = (overlap > 0) & sample.vision_observed[:, start:start + 3].all(axis=1) + if valid_rows.any(): + weights = overlap[valid_rows].astype(np.float64) + vector = np.average(raw[valid_rows, start:start + 3], axis=0, weights=weights) + norm = float(np.linalg.norm(vector)) + if norm > 1e-6: + values[target_index, start:start + 3] = vector / norm + masks[target_index, start:start + 3] = True + else: + values[target_index, start:start + 3] = 0.0 + masks[target_index, start:start + 3] = False + return values, masks, coverage + + +def _project_posterior_text(sample: Sample, target_edges: np.ndarray) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + words, dim = sample.text_features.shape + output = np.zeros((len(target_edges) - 1, dim), dtype=np.float32) + mask = np.zeros((len(target_edges) - 1, dim), dtype=np.bool_) + coverage = np.zeros((len(target_edges) - 1, dim), dtype=np.float32) + if not words or not len(sample.ctc_times): + return output, mask, coverage + frame_step = CTC_FRAME_STEP_S + first_edge = max(0.0, float(sample.ctc_times[0]) - frame_step / 2) + frame_edges = np.clip( + first_edge + np.arange(len(sample.ctc_times) + 1, dtype=np.float64) * frame_step, + 0.0, + sample.duration_s, + ) + occupancy = sample.ctc_occupancy.astype(np.float64) + for target_index, (left, right) in enumerate(zip(target_edges[:-1], target_edges[1:])): + overlap = np.maximum(0.0, np.minimum(frame_edges[1:], right) - np.maximum(frame_edges[:-1], left)) + if not np.any(overlap > 0): + continue + alpha = (occupancy * overlap[:, None]).sum(axis=0) + alpha *= sample.text_valid + total = float(alpha.sum()) + if total <= 0: + continue + output[target_index] = (alpha @ sample.text_features.astype(np.float64) / total).astype(np.float32) + mask[target_index] = True + coverage[target_index] = min(1.0, total / max(right - left, 1e-8)) + return output, mask, coverage + + +def _normalized_hard_quality(sample: Sample) -> np.ndarray: + text_quality = np.zeros_like(sample.hard_quality, dtype=np.float32) + valid_quality = sample.hard_valid & (sample.hard_quality > 0) + if valid_quality.any(): + quality_reference = float(np.median(sample.hard_quality[valid_quality])) + text_quality[valid_quality] = np.clip( + sample.hard_quality[valid_quality].astype(np.float64) / quality_reference, 0.25, 4.0 + ) + return text_quality + + +def _make_views(sample: Sample) -> tuple[View, View, View]: + edges = _grid_edges(sample.duration_s) + hard_text_observed = np.broadcast_to(sample.text_valid[:, None], sample.text_features.shape).copy() + text_quality = _normalized_hard_quality(sample) + text_hard = _project_rows( + sample.text_features.astype(np.float32), hard_text_observed, + sample.hard_intervals, text_quality, edges, + ) + audio = _project_rows( + sample.audio_features.astype(np.float32), sample.audio_observed, + _voronoi_intervals(sample.audio_times, sample.duration_s), + np.ones(len(sample.audio_times), dtype=np.float32), edges, + ) + vision_b0 = _project_vision_geometry(sample, edges, geometry_aware=False) + vision_b1 = _project_vision_geometry(sample, edges, geometry_aware=True) + speech = _project_rows( + sample.speech_features.astype(np.float32), + np.ones(sample.speech_features.shape, dtype=np.bool_), + _voronoi_intervals(sample.ctc_times, sample.duration_s), + np.ones(len(sample.ctc_times), dtype=np.float32), edges, + ) + post_text = _project_posterior_text(sample, edges) + view_b0 = View( + features={"text": text_hard[0], "audio": audio[0], "vision": vision_b0[0], "speech": speech[0]}, + observed={"text": text_hard[1], "audio": audio[1], "vision": vision_b0[1], "speech": speech[1]}, + coverage={"text": text_hard[2], "audio": audio[2], "vision": vision_b0[2], "speech": speech[2]}, + edges=edges, + ) + view_b1 = View( + features={"text": text_hard[0], "audio": audio[0], "vision": vision_b1[0], "speech": speech[0]}, + observed={"text": text_hard[1], "audio": audio[1], "vision": vision_b1[1], "speech": speech[1]}, + coverage={"text": text_hard[2], "audio": audio[2], "vision": vision_b1[2], "speech": speech[2]}, + edges=edges, + ) + # B2 changes only text's time projection; media timestamps and their masks stay fixed. + view_b2 = View( + features={**view_b1.features, "text": post_text[0]}, + observed={**view_b1.observed, "text": post_text[1]}, + coverage={**view_b1.coverage, "text": post_text[2]}, + edges=edges, + ) + return view_b0, view_b1, view_b2 + + +def _fit_feature_scaler(samples: list[Sample], views: list[View], indices: np.ndarray, mode: str) -> dict[str, tuple[np.ndarray, np.ndarray]]: + modalities = ("text", "audio", "vision", "speech") + scalers: dict[str, tuple[np.ndarray, np.ndarray]] = {} + for modality in modalities: + dims = views[int(indices[0])].features[modality].shape[1] + columns: list[np.ndarray] = [] + for dim in range(dims): + values = [ + views[int(index)].features[modality][:, dim][views[int(index)].observed[modality][:, dim]] + for index in indices + ] + nonempty = [array for array in values if len(array)] + columns.append(np.concatenate(nonempty).astype(np.float64) if nonempty else np.empty(0, dtype=np.float64)) + center = np.zeros(dims, dtype=np.float64) + scale = np.ones(dims, dtype=np.float64) + for dim, values in enumerate(columns): + if not len(values): + continue + if mode == "robust": + center[dim] = np.median(values) + mad = 1.4826 * np.median(np.abs(values - center[dim])) + std = np.std(values) + scale[dim] = mad if mad > 1e-8 else std if std > 1e-8 else 1.0 + else: + center[dim] = np.mean(values) + std = np.std(values) + scale[dim] = std if std > 1e-8 else 1.0 + scalers[modality] = (center.astype(np.float32), scale.astype(np.float32)) + return scalers + + +def _scaled_view(view: View, scalers: dict[str, tuple[np.ndarray, np.ndarray]], clip: bool) -> View: + features: dict[str, np.ndarray] = {} + for modality, value in view.features.items(): + center, scale = scalers[modality] + transformed = (value - center[None, :]) / scale[None, :] + if clip: + transformed = np.clip(transformed, -8.0, 8.0) + transformed = np.where(view.observed[modality], transformed, 0.0) + features[modality] = transformed.astype(np.float32) + return View(features=features, observed=view.observed, coverage=view.coverage, edges=view.edges) + + +def _path_signature(times: np.ndarray, values: np.ndarray) -> np.ndarray: + # Time-augmented piecewise-linear path; return first level and antisymmetric area. + dimension = values.shape[1] + 1 + if len(times) < 3: + return np.zeros(dimension + dimension * (dimension - 1) // 2, dtype=np.float32) + local_time = (times - times[0]) / max(times[-1] - times[0], 1e-8) + path = np.column_stack((local_time, values)).astype(np.float64) + increments = np.diff(path, axis=0) + first = increments.sum(axis=0) + areas: list[float] = [] + for left in range(dimension): + for right in range(left + 1, dimension): + prefix_left = np.cumsum(increments[:, left]) - increments[:, left] + prefix_right = np.cumsum(increments[:, right]) - increments[:, right] + areas.append(float(0.5 * np.sum(prefix_left * increments[:, right] - prefix_right * increments[:, left]))) + return np.concatenate((first, np.asarray(areas, dtype=np.float64))).astype(np.float32) + + +def _signature_for_segment( + times: np.ndarray, values: np.ndarray, valid: np.ndarray, left: float, right: float, +) -> tuple[np.ndarray, float]: + dim = values.shape[1] + output_dim = (dim + 1) + (dim + 1) * dim // 2 + selected = (times >= left) & (times < right) & valid + indices = np.flatnonzero(selected) + if len(indices) < 3: + return np.zeros(output_dim, dtype=np.float32), 0.0 + # Split at every missing source position; never connect across a missing interval. + chunks = np.split(indices, np.flatnonzero(np.diff(indices) > 1) + 1) + signatures: list[np.ndarray] = [] + weights: list[float] = [] + for chunk in chunks: + if len(chunk) < 3: + continue + duration = float(max(times[chunk[-1]] - times[chunk[0]], 0.0)) + if duration <= 0: + continue + signatures.append(_path_signature(times[chunk], values[chunk])) + weights.append(duration) + if not weights: + return np.zeros(output_dim, dtype=np.float32), 0.0 + weight_array = np.asarray(weights, dtype=np.float64) + signature = np.average(np.stack(signatures), axis=0, weights=weight_array) + valid_duration = min(float(np.sum(weight_array)), max(right - left, 1e-8)) + return signature.astype(np.float32), float(np.clip(valid_duration / (right - left), 0.0, 1.0)) + + +def _dynamic_signature(sample: Sample, scaled_view: View) -> np.ndarray: + duration = sample.duration_s + segments = np.linspace(0.0, duration, 6) + centers = (scaled_view.edges[:-1] + scaled_view.edges[1:]) / 2 + audio = scaled_view.features["audio"] + audio_mask = scaled_view.observed["audio"] + vision = scaled_view.features["vision"] + vision_mask = scaled_view.observed["vision"] + # log-F0, log-energy; MediaPipe jaw-open proxy and normalized mouth aperture. + audio_values = audio[:, [67, 66]] + audio_valid = audio_mask[:, [67, 66]].all(axis=1) + vision_values = vision[:, [11, 31]] + vision_valid = vision_mask[:, [11, 31]].all(axis=1) + result: list[float] = [] + for index in range(5): + left, right = float(segments[index]), float(segments[index + 1]) + signature, coverage = _signature_for_segment(centers, audio_values, audio_valid, left, right) + result.extend(signature.tolist()) + result.append(coverage) + signature, coverage = _signature_for_segment(centers, vision_values, vision_valid, left, right) + result.extend(signature.tolist()) + result.append(coverage) + return np.asarray(result, dtype=np.float32) + + +def _pool_progress(view: View, include_speech: bool, extra: np.ndarray | None = None) -> np.ndarray: + duration = float(view.edges[-1]) + progress_edges = np.linspace(0.0, duration, 6) + centers = (view.edges[:-1] + view.edges[1:]) / 2 + cell_lengths = np.diff(view.edges) + names = ["text", "audio", "vision"] + (["speech"] if include_speech else []) + pooled: list[np.ndarray] = [] + for name in names: + values, masks, coverage = view.features[name], view.observed[name], view.coverage[name] + rows = [] + for left, right in zip(progress_edges[:-1], progress_edges[1:]): + select = (centers >= left) & (centers < right) + weights = cell_lengths[select, None] * coverage[select] * masks[select] + denom = weights.sum(axis=0) + good = denom > 0 + out = np.zeros(values.shape[1], dtype=np.float32) + if good.any(): + out[good] = ((values[select] * weights).sum(axis=0)[good] / denom[good]).astype(np.float32) + rows.append(out) + pooled.append(np.stack(rows).reshape(-1)) + if extra is not None: + pooled.append(extra) + return np.concatenate(pooled).astype(np.float32) + + +def _view_coverage(view: View, modality: str) -> float: + mask = view.observed[modality] + cov = view.coverage[modality] + if not mask.size: + return 0.0 + return float(np.mean(cov[mask])) if mask.any() else 0.0 + + +def _metrics(y_class: np.ndarray, p_class: np.ndarray, y_value: np.ndarray, p_value: np.ndarray) -> dict[str, float]: + pearson = float(np.corrcoef(y_value, p_value)[0, 1]) if len(y_value) > 1 and np.std(p_value) > 1e-12 else math.nan + return { + "accuracy": float(accuracy_score(y_class, p_class)), + "macro_f1": float(f1_score(y_class, p_class, labels=[0, 1, 2], average="macro", zero_division=0)), + "mae": float(mean_absolute_error(y_value, p_value)), + "pearson": pearson, + } + + +def _write_csv(path: Path, rows: list[dict[str, Any]], fields: list[str]) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("w", encoding="utf-8-sig", newline="") as stream: + writer = csv.DictWriter(stream, fieldnames=fields, extrasaction="ignore") + writer.writeheader() + writer.writerows(rows) + + +def _group_bootstrap_deltas( + samples: list[Sample], predictions: dict[str, dict[int, tuple[int, float]]], repeats: int, +) -> list[dict[str, Any]]: + rng = np.random.default_rng(SEED) + groups: dict[str, list[int]] = {} + for index, sample in enumerate(samples): + groups.setdefault(sample.video_id, []).append(index) + group_names = sorted(groups) + y_class = np.asarray([sample.polarity for sample in samples], dtype=np.int64) + y_value = np.asarray([sample.sentiment for sample in samples], dtype=np.float64) + records: list[dict[str, Any]] = [] + reference = "B1" + for method in ("B0", "B2", "B3", "B4"): + point_ref = np.asarray([predictions[reference][i][0] for i in range(len(samples))], dtype=np.int64) + point_method = np.asarray([predictions[method][i][0] for i in range(len(samples))], dtype=np.int64) + value_ref = np.asarray([predictions[reference][i][1] for i in range(len(samples))], dtype=np.float64) + value_method = np.asarray([predictions[method][i][1] for i in range(len(samples))], dtype=np.float64) + for metric in ("accuracy", "macro_f1", "mae", "pearson"): + deltas: list[float] = [] + for _ in range(repeats): + chosen = rng.choice(group_names, size=len(group_names), replace=True) + indices = np.asarray([index for name in chosen for index in groups[str(name)]], dtype=np.int64) + a = _metrics(y_class[indices], point_ref[indices], y_value[indices], value_ref[indices])[metric] + b = _metrics(y_class[indices], point_method[indices], y_value[indices], value_method[indices])[metric] + if math.isfinite(a) and math.isfinite(b): + deltas.append(b - a) + ref_metric = _metrics(y_class, point_ref, y_value, value_ref)[metric] + method_metric = _metrics(y_class, point_method, y_value, value_method)[metric] + records.append({ + "comparison": f"{method}-B1", + "metric": metric, + "reference_oof": ref_metric, + "method_oof": method_metric, + "delta_oof": method_metric - ref_metric if math.isfinite(method_metric) and math.isfinite(ref_metric) else math.nan, + "group_bootstrap_ci95_low": float(np.quantile(deltas, 0.025)) if deltas else math.nan, + "group_bootstrap_ci95_high": float(np.quantile(deltas, 0.975)) if deltas else math.nan, + "bootstrap_repeats": len(deltas), + }) + return records + + +def _evaluate(samples: list[Sample], views: list[tuple[View, View, View]], bootstrap_repeats: int) -> tuple[list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]]]: + y_class = np.asarray([sample.polarity for sample in samples], dtype=np.int64) + y_value = np.asarray([sample.sentiment for sample in samples], dtype=np.float64) + groups = np.asarray([sample.video_id for sample in samples]) + splitter = GroupKFold(n_splits=N_FOLDS) + folds = list(splitter.split(np.zeros(len(samples)), y_class, groups)) + methods = ("B0", "B1", "B2", "B3", "B4") + class_oof = {method: np.full(len(samples), -1, dtype=np.int64) for method in methods} + value_oof = {method: np.full(len(samples), np.nan, dtype=np.float64) for method in methods} + predictions: dict[str, dict[int, tuple[int, float]]] = {method: {} for method in methods} + fold_rows: list[dict[str, Any]] = [] + split_rows: list[dict[str, Any]] = [] + for fold_index, (train_indices, test_indices) in enumerate(folds, start=1): + train_groups = set(groups[train_indices].tolist()) + test_groups = set(groups[test_indices].tolist()) + if train_groups & test_groups: + raise AssertionError("video_id leakage across grouped fold") + for index in test_indices: + split_rows.append({ + "sample_id": samples[index].sample_id, + "video_id": samples[index].video_id, + "fold": fold_index, + "split": "valid_oof", + }) + + variant_views = { + "B0": [item[0] for item in views], + "B1": [item[1] for item in views], + "B2": [item[2] for item in views], + "B3": [item[1] for item in views], + "B4": [item[1] for item in views], + } + for method in methods: + source_views = variant_views[method] + scale_mode = "standard" if method == "B0" else "robust" + scalers = _fit_feature_scaler(samples, source_views, train_indices, scale_mode) + scaled = [_scaled_view(view, scalers, clip=(scale_mode == "robust")) for view in source_views] + add_speech = method == "B4" + x = np.stack([ + _pool_progress( + scaled[int(index)], + include_speech=add_speech, + extra=_dynamic_signature(samples[int(index)], scaled[int(index)]) if method == "B3" else None, + ) + for index in train_indices + ]) + x_valid = np.stack([ + _pool_progress( + scaled[int(index)], + include_speech=add_speech, + extra=_dynamic_signature(samples[int(index)], scaled[int(index)]) if method == "B3" else None, + ) + for index in test_indices + ]) + classifier = LogisticRegression(C=0.05, max_iter=2500, solver="lbfgs", random_state=SEED) + classifier.fit(x, y_class[train_indices]) + predicted_class = classifier.predict(x_valid) + regressor = Ridge(alpha=25.0, solver="lsqr") + regressor.fit(x, y_value[train_indices]) + predicted_value = np.clip(regressor.predict(x_valid), -3.0, 3.0) + class_oof[method][test_indices] = predicted_class + value_oof[method][test_indices] = predicted_value + for index, pred_class, pred_value in zip(test_indices, predicted_class, predicted_value): + predictions[method][int(index)] = (int(pred_class), float(pred_value)) + fold_metric = _metrics(y_class[test_indices], predicted_class, y_value[test_indices], predicted_value) + fold_rows.append({ + "method": method, + "fold": fold_index, + "train_samples": int(len(train_indices)), + "valid_samples": int(len(test_indices)), + "train_video_groups": len(train_groups), + "valid_video_groups": len(test_groups), + "accuracy": fold_metric["accuracy"], + "macro_f1": fold_metric["macro_f1"], + "mae": fold_metric["mae"], + "pearson": fold_metric["pearson"], + "feature_dimension": int(x.shape[1]), + }) + print(f"[CV] fold {fold_index}/{N_FOLDS}: train={len(train_indices)} clips/{len(train_groups)} videos; valid={len(test_indices)} clips/{len(test_groups)} videos", flush=True) + + summary_rows: list[dict[str, Any]] = [] + for method in methods: + fold_metrics = [row for row in fold_rows if row["method"] == method] + overall = _metrics(y_class, class_oof[method], y_value, value_oof[method]) + row: dict[str, Any] = { + "method": method, + "sample_count": len(samples), + "video_group_count": len(set(groups.tolist())), + "oof_accuracy": overall["accuracy"], + "oof_macro_f1": overall["macro_f1"], + "oof_mae": overall["mae"], + "oof_pearson": overall["pearson"], + } + for metric in ("accuracy", "macro_f1", "mae", "pearson"): + values = np.asarray([item[metric] for item in fold_metrics if math.isfinite(item[metric])], dtype=np.float64) + row[f"fold_{metric}_mean"] = float(values.mean()) if len(values) else math.nan + row[f"fold_{metric}_sd"] = float(values.std(ddof=1)) if len(values) > 1 else math.nan + summary_rows.append(row) + prediction_rows = [] + for index, sample in enumerate(samples): + row: dict[str, Any] = { + "sample_id": sample.sample_id, + "video_id": sample.video_id, + "clip_id": sample.clip_id, + "true_polarity": sample.polarity, + "true_polarity_name": ("negative", "neutral", "positive")[sample.polarity], + "true_sentiment": sample.sentiment, + } + for method in methods: + row[f"{method}_predicted_polarity"] = int(class_oof[method][index]) + row[f"{method}_predicted_sentiment"] = float(value_oof[method][index]) + prediction_rows.append(row) + delta_rows = _group_bootstrap_deltas(samples, predictions, bootstrap_repeats) + return summary_rows, fold_rows, prediction_rows, split_rows, delta_rows + + +def _sample_output_rows(samples: list[Sample], views: list[tuple[View, View, View]]) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + sample_rows: list[dict[str, Any]] = [] + modality_rows: list[dict[str, Any]] = [] + for sample, (view0, view1, view2) in zip(samples, views): + finite_boundaries = [item for item in sample.boundary_summary if math.isfinite(item["start_width90_s"]) and math.isfinite(item["end_width90_s"])] + hard_text_coverage = _view_coverage(view0, "text") + post_text_coverage = _view_coverage(view2, "text") + sample_rows.append({ + "sample_id": sample.sample_id, + "video_id": sample.video_id, + "clip_id": sample.clip_id, + "source_video_sha256": sample.video_sha256, + "duration_s": sample.duration_s, + "word_count": len(sample.text_words), + "hard_aligned_word_count": int(sample.hard_valid.sum()), + "unlocated_word_count": int((~sample.hard_valid).sum()), + "posterior_usable_word_count": len(finite_boundaries), + "mean_start_interval_width90_s": float(np.mean([item["start_width90_s"] for item in finite_boundaries])) if finite_boundaries else math.nan, + "mean_end_interval_width90_s": float(np.mean([item["end_width90_s"] for item in finite_boundaries])) if finite_boundaries else math.nan, + "text_hard_grid_coverage": hard_text_coverage, + "text_posterior_grid_occupancy": post_text_coverage, + "audio_grid_coverage": _view_coverage(view1, "audio"), + "vision_grid_coverage": _view_coverage(view1, "vision"), + "audio_native_rows": len(sample.audio_times), + "vision_native_rows": len(sample.vision_times), + "status": "ok", + }) + for modality, native_length, native_dim, view, key in ( + ("text", len(sample.text_words), 768, view1, "text"), + ("audio", len(sample.audio_times), 74, view1, "audio"), + ("vision", len(sample.vision_times), 35, view1, "vision"), + ): + coverage = view.coverage[key] + observed = view.observed[key] + observed_duration = float((coverage * np.diff(view.edges)[:, None] * observed).sum(axis=0).mean()) if observed.size else 0.0 + modality_rows.append({ + "sample_id": sample.sample_id, + "video_id": sample.video_id, + "clip_id": sample.clip_id, + "modality": modality, + "source_duration_s": sample.duration_s, + "observed_duration_s_mean_dimension": observed_duration, + "native_length": native_length, + "native_dimension": native_dim, + "main_grid_length": len(view.edges) - 1, + "grid_step_s": GRID_STEP_S, + "grid_dimension": native_dim, + "mean_grid_coverage": _view_coverage(view, key), + "status": "ok" if native_length else "no_native_rows", + "source_video_sha256": sample.video_sha256, + }) + return sample_rows, modality_rows + + +def _create_plot(rows: list[dict[str, Any]], output_path: Path) -> None: + labels = [row["method"] for row in rows] + figure, axes = plt.subplots(1, 3, figsize=(14, 4.5), constrained_layout=True) + metrics = (("oof_macro_f1", "Macro F1 (higher is better)"), ("oof_mae", "MAE (lower is better)"), ("oof_pearson", "Pearson r (higher is better)")) + colors = ("#718096", "#2463A6", "#6A8E3A", "#C77D27", "#8357A5") + for axis, (column, title) in zip(axes, metrics): + values = [float(row[column]) for row in rows] + bars = axis.bar(labels, values, color=colors) + axis.set_title(title) + axis.grid(axis="y", alpha=0.25) + for bar, value in zip(bars, values): + axis.text(bar.get_x() + bar.get_width() / 2, bar.get_height(), f"{value:.3f}", ha="center", va="bottom", fontsize=8) + figure.suptitle("B0-B4 emotion probe on grouped out-of-fold predictions") + output_path.parent.mkdir(parents=True, exist_ok=True) + figure.savefig(output_path, dpi=170) + plt.close(figure) + + +def _create_typical_alignment_figure( + samples: list[Sample], views: list[tuple[View, View, View]], output_path: Path, +) -> str: + eligible = [ + index for index, sample in enumerate(samples) + if sample.text_words and sample.hard_valid.all() and sample.vision_observed.any() + ] + if not eligible: + return "" + median_duration = float(np.median([samples[index].duration_s for index in eligible])) + chosen_index = min(eligible, key=lambda index: abs(samples[index].duration_s - median_duration)) + sample = samples[chosen_index] + view_b0, _, view_b2 = views[chosen_index] + middle = len(sample.text_words) // 2 + left_word = max(0, middle - 5) + right_word = min(len(sample.text_words), left_word + 10) + left_word = max(0, right_word - 10) + word_indices = np.arange(left_word, right_word) + + figure = plt.figure(figsize=(15, 11), constrained_layout=True) + grid = figure.add_gridspec(4, 1, height_ratios=(2.6, 1.1, 1.4, 2.1)) + alignment_axis = figure.add_subplot(grid[0, 0]) + coverage_axis = figure.add_subplot(grid[1, 0]) + feature_axis = figure.add_subplot(grid[2, 0]) + image_grid = grid[3, 0].subgridspec(1, 5, wspace=0.04) + image_axes = [figure.add_subplot(image_grid[0, i]) for i in range(5)] + + for y_position, word_index in enumerate(word_indices): + hard_start, hard_end = sample.hard_intervals[word_index] + alignment_axis.plot((hard_start, hard_end), (y_position, y_position), color="#2563a6", lw=5, solid_capstyle="butt") + boundary = sample.boundary_summary[word_index] + if math.isfinite(boundary["start_p05_s"]) and math.isfinite(boundary["start_p95_s"]): + center = boundary["start_mean_s"] + alignment_axis.errorbar( + center, y_position + 0.19, + xerr=np.asarray([[max(0.0, center - boundary["start_p05_s"]),], [max(0.0, boundary["start_p95_s"] - center),]]), + fmt="o", color="#d17a00", markersize=3, capsize=2, lw=1, + ) + if math.isfinite(boundary["end_p05_s"]) and math.isfinite(boundary["end_p95_s"]): + center = boundary["end_mean_s"] + alignment_axis.errorbar( + center, y_position - 0.19, + xerr=np.asarray([[max(0.0, center - boundary["end_p05_s"]),], [max(0.0, boundary["end_p95_s"] - center),]]), + fmt="s", color="#638b32", markersize=3, capsize=2, lw=1, + ) + alignment_axis.set_yticks(np.arange(len(word_indices)), labels=[sample.text_words[index] for index in word_indices], fontsize=8) + alignment_axis.set_ylim(-0.65, len(word_indices) - 0.35) + start_values = [float(sample.hard_intervals[index, 0]) for index in word_indices] + end_values = [float(sample.hard_intervals[index, 1]) for index in word_indices] + alignment_axis.set_xlim(max(0.0, min(start_values) - 0.25), min(sample.duration_s, max(end_values) + 0.25)) + alignment_axis.set_xlabel("seconds from clip start") + alignment_axis.set_title("Hard CTC word interval (blue); 90% internal start/end boundary intervals (orange/green)") + alignment_axis.grid(axis="x", alpha=0.25) + + times = (view_b0.edges[:-1] + view_b0.edges[1:]) / 2 + coverage_axis.plot(times, view_b0.coverage["text"].mean(axis=1), label="hard word coverage", color="#2563a6") + coverage_axis.plot(times, view_b2.coverage["text"].mean(axis=1), label="posterior word occupancy", color="#d17a00") + coverage_axis.plot(times, view_b0.coverage["audio"].mean(axis=1), label="audio coverage", color="#638b32") + coverage_axis.plot(times, view_b0.coverage["vision"].mean(axis=1), label="face feature coverage", color="#8357a5") + coverage_axis.set_ylim(0, 1.05) + coverage_axis.set_xlim(0, sample.duration_s) + coverage_axis.set_ylabel("coverage / occupancy") + coverage_axis.legend(ncol=4, fontsize=8, loc="upper right") + coverage_axis.grid(alpha=0.2) + + audio = sample.audio_features.astype(np.float32) + audio_time = sample.audio_times + feature_axis.plot(audio_time, audio[:, 66], color="#2563a6", lw=1, label="log energy") + pitch_valid = sample.audio_observed[:, 67] + if pitch_valid.any(): + pitch_axis = feature_axis.twinx() + pitch_axis.plot(audio_time[pitch_valid], np.exp(audio[pitch_valid, 67]), color="#d17a00", lw=0.8, alpha=0.8, label="F0 (Hz)") + pitch_axis.set_ylabel("F0 (Hz)") + vision_valid = sample.vision_observed[:, 31] + if vision_valid.any(): + feature_axis.scatter(sample.vision_times[vision_valid], sample.vision_features[vision_valid, 31].astype(np.float32), s=9, color="#638b32", label="mouth aperture") + feature_axis.set_xlim(0, sample.duration_s) + feature_axis.set_xlabel("seconds from clip start") + feature_axis.set_ylabel("log energy / mouth aperture") + feature_axis.set_title("Example native acoustic and facial feature trajectories") + feature_axis.grid(alpha=0.2) + handles, labels = feature_axis.get_legend_handles_labels() + if len(handles): + feature_axis.legend(handles, labels, loc="upper right", fontsize=8) + + video_path = DATA_DIR / sample.video_id / f"{sample.clip_id}.mp4" + capture = cv2.VideoCapture(str(video_path)) + frame_times = np.linspace(0.0, max(sample.duration_s - 0.05, 0.0), len(image_axes)) + for axis, timestamp in zip(image_axes, frame_times): + capture.set(cv2.CAP_PROP_POS_MSEC, float(timestamp) * 1000.0) + ok, bgr = capture.read() + if ok: + axis.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)) + axis.set_title(f"{timestamp:.2f}s", fontsize=8) + else: + axis.text(0.5, 0.5, "frame unavailable", ha="center", va="center") + axis.axis("off") + capture.release() + figure.suptitle(f"Typical sample alignment audit: {sample.sample_id} ({sample.duration_s:.2f}s)", fontsize=14) + output_path.parent.mkdir(parents=True, exist_ok=True) + figure.savefig(output_path, dpi=170) + plt.close(figure) + return sample.sample_id + + +def _write_report( + output_dir: Path, summary: list[dict[str, Any]], deltas: list[dict[str, Any]], + sample_rows: list[dict[str, Any]], modality_rows: list[dict[str, Any]], + manifest: dict[str, Any], +) -> None: + best_f1 = max(summary, key=lambda row: row["oof_macro_f1"]) + best_mae = min(summary, key=lambda row: row["oof_mae"]) + b1 = next(row for row in summary if row["method"] == "B1") + delta = {(row["comparison"], row["metric"]): row for row in deltas} + b4_f1 = delta[("B4-B1", "macro_f1")] + b0_mae = delta[("B0-B1", "mae")] + b0_pearson = delta[("B0-B1", "pearson")] + b2_f1 = delta[("B2-B1", "macro_f1")] + b2_mae = delta[("B2-B1", "mae")] + b3_f1 = delta[("B3-B1", "macro_f1")] + mean_start_width = float(np.nanmean([row["mean_start_interval_width90_s"] for row in sample_rows])) + mean_end_width = float(np.nanmean([row["mean_end_interval_width90_s"] for row in sample_rows])) + mean_hard_coverage = float(np.mean([row["text_hard_grid_coverage"] for row in sample_rows])) + mean_posterior_occupancy = float(np.mean([row["text_posterior_grid_occupancy"] for row in sample_rows])) + mean_vision_coverage = float(np.mean([row["vision_grid_coverage"] for row in sample_rows])) + complete_hard_count = sum(row["unlocated_word_count"] == 0 for row in sample_rows) + consistent = manifest["inputs"]["label_polarity_consistency_count"] + lines = [ + "# 问题一 B0-B4 模型对比结果", + "", + "本报告按 `math/问题一.pdf` 第 4.8.3 节实施五组单因素对照。全部 100 条附件一视频均使用同一套冻结特征抽取器、0.1 秒主时间网格、观测掩码与按 `video_id` 分组的五折划分。情感标签仅用于折内的轻量预测探针,不进入时间对齐、CTC 后验或动态签名计算。", + "", + "## 实际特征和比较版本", + "", + "| 版本 | 实施内容 |", + "| --- | --- |", + "| B0 | CTC Viterbi 词区间与音频/视觉物理时间区间投影;训练折均值/标准差缩放;视觉旋转向量和视线向量作普通分量均值。 |", + "| B1 | 在 B0 上改用训练折中位数与 MAD 的稳健尺度(MAD 为零时回退到训练折标准差),并对视觉旋转用 SO(3) 均值、视线用归一化向量均值。 |", + "| B2 | 在 B1 上只将文本词向量的硬边界投影替换为固定转写 CTC 状态图的前向–后向占据概率投影;媒体时间戳仍按物理时间。 |", + "| B3 | 在 B1 上仅附加音频 log-F0/能量与视觉 jaw-open/嘴部开合率的时间增广一、二阶路径签名;缺测点之间不连线。 |", + "| B4 | 在 B1 上仅附加冻结 Wav2Vec2-base-960h 最后四层的时间投影表示。 |", + "", + "附件一现有标签表和原始视频被直接使用。文本为 768 维 BERT-base-uncased 末四层均值;音频为 74 维(log-Mel 40、MFCC 13、ΔMFCC 13、韵律/谱统计 8);视觉为 35 维(17 个 MediaPipe blendshape 代理、6 维头姿、6 维近似视线、6 维面部比例几何)。视觉代理和几何索引定义见 `compare_models.py`,它们与 OpenFace AU 定义并不等同;该限制须在论文中明示。", + "", + "## 结果", + "", + "分类按连续标签的严格符号构造 Negative/Neutral/Positive,强度预测限幅到 [-3, 3]。每折训练折单独拟合标准化器、逻辑回归(C=0.05)与 Ridge(alpha=25);固定五折由 GroupKFold 按原始 `video_id` 分组。总体 OOF 指标按 100 条留组预测计算。", + "", + "| 方法 | OOF Accuracy | OOF Macro-F1 | OOF MAE | OOF Pearson | Macro-F1 折均值±SD |", + "| --- | ---: | ---: | ---: | ---: | ---: |", + ] + for row in summary: + lines.append( + f"| {row['method']} | {row['oof_accuracy']:.3f} | {row['oof_macro_f1']:.3f} | {row['oof_mae']:.3f} | {row['oof_pearson']:.3f} | {row['fold_macro_f1_mean']:.3f} ± {row['fold_macro_f1_sd']:.3f} |" + ) + lines += [ + "", + f"按当前 OOF 探针,Macro-F1 最高的是 {best_f1['method']}({best_f1['oof_macro_f1']:.3f}),MAE 最低的是 {best_mae['method']}({best_mae['oof_mae']:.3f})。相对 B1,B4 的 Macro-F1 差为 {b4_f1['delta_oof']:+.3f},视频组 Bootstrap 95% 区间 [{b4_f1['group_bootstrap_ci95_low']:+.3f}, {b4_f1['group_bootstrap_ci95_high']:+.3f}],区间跨过零。B0 的 MAE 差为 {b0_mae['delta_oof']:+.3f},区间 [{b0_mae['group_bootstrap_ci95_low']:+.3f}, {b0_mae['group_bootstrap_ci95_high']:+.3f}],Pearson 差为 {b0_pearson['delta_oof']:+.3f}。B2 的 Macro-F1 差为 {b2_f1['delta_oof']:+.3f},区间 [{b2_f1['group_bootstrap_ci95_low']:+.3f}, {b2_f1['group_bootstrap_ci95_high']:+.3f}],MAE 差为 {b2_mae['delta_oof']:+.3f};B3 的 Macro-F1 差为 {b3_f1['delta_oof']:+.3f},区间 [{b3_f1['group_bootstrap_ci95_low']:+.3f}, {b3_f1['group_bootstrap_ci95_high']:+.3f}]。组 Bootstrap 只反映当前 37 个来源视频上的抽样不确定性,未作多重比较校正。", + "", + "## 覆盖与对齐核验", + "", + f"样本数:{len(sample_rows)};标签表连续标签与极性一致 {consistent}/100;CTC 硬对齐完整的样本 {complete_hard_count}/100。B0 硬区间平均文本覆盖率为 {mean_hard_coverage:.3f},B2 平均词占据后验质量为 {mean_posterior_occupancy:.3f}(这是期望占据率,不是覆盖率);视觉检测覆盖率(按 0.1 秒网格平均)为 {mean_vision_coverage:.3f}。后验内部 90% 边界区间平均宽度为起点 {mean_start_width:.3f} 秒、终点 {mean_end_width:.3f} 秒。没有人工边界子集,因此这些宽度只是模型内部不确定性摘要,不是经验校准率或边界误差。", + "", + "B0–B4 的特征来源、有效掩码、连续覆盖率、词边界后验宽度、折内预测及视频哈希均分别保存在配套 CSV/JSON 中。没有人工词边界时不报告 IoU/MATE,也不把不同方法的预测探针分数解释为对齐真值。", + "", + "## 文件", + "", + "- `comparison_summary.csv`:五种方法总体 OOF 与折均值指标。", + "- `fold_metrics.csv`:每折分类/回归指标与特征维数。", + "- `oof_predictions.csv`:每条样本的留组预测。", + "- `group_bootstrap_deltas.csv`:相对 B1 的视频组配对 Bootstrap 95% 区间。", + "- `sample_alignment_summary.csv`:100 条样本、硬/概率文本覆盖和后验边界宽度。", + "- `modality_summary.csv`:300 行样本-模态明细。", + "- `word_alignment_posterior.csv`:逐词硬边界、实际相对质量权重及后验边界区间。", + "- `split_assignments.csv`:逐样本折号。", + "- `comparison.png`:核心 OOF 指标图。", + "- `typical_alignment_example.png`:中位时长样本的词边界、覆盖率、声学/视觉轨迹与视频帧核验图。", + "- `run_manifest.json`:环境、模型 revision、参数、哈希与运行时间。", + "", + "## 复现", + "", + "在仓库根目录执行:", + "", + "```bash", + "cd math", + "uv sync", + "uv run python compare_models.py", + "```", + "", + "特征缓存写在 `math/cache/native/`,正式结果只写在 `math/results/model_comparison/`。删除缓存后会从附件一重新提取。首次运行需要下载 BERT、Wav2Vec2 和 MediaPipe Face Landmarker 权重。", + ] + (output_dir / "report.md").write_text("\n".join(lines) + "\n", encoding="utf-8") + + +def _write_boundary_detail(output_dir: Path, samples: list[Sample]) -> None: + rows: list[dict[str, Any]] = [] + for sample in samples: + quality_weights = _normalized_hard_quality(sample) + for word_index, (word, interval, valid, quality, posterior) in enumerate(zip( + sample.text_words, + sample.hard_intervals, + sample.hard_valid, + sample.hard_quality, + sample.boundary_summary, + )): + rows.append({ + "sample_id": sample.sample_id, + "video_id": sample.video_id, + "clip_id": sample.clip_id, + "word_index": word_index, + "word": word, + "hard_start_s": float(interval[0]) if valid else math.nan, + "hard_end_s": float(interval[1]) if valid else math.nan, + "hard_valid": bool(valid), + "ctc_quality_score_uncalibrated": float(quality), + "relative_quality_weight": float(quality_weights[word_index]) if valid else math.nan, + **posterior, + }) + _write_csv(output_dir / "word_alignment_posterior.csv", rows, [ + "sample_id", "video_id", "clip_id", "word_index", "word", "hard_start_s", "hard_end_s", + "hard_valid", "ctc_quality_score_uncalibrated", "relative_quality_weight", "start_mean_s", "end_mean_s", + "start_p05_s", "start_p95_s", "end_p05_s", "end_p95_s", + "start_width90_s", "end_width90_s", + ]) + + +def run(args: argparse.Namespace) -> None: + output_dir = Path(args.output_dir).resolve() + cache_dir = Path(args.cache_dir).resolve() + input_dir = Path(args.data_dir).resolve() + label_file = input_dir / "label-100.xlsx" + records = _read_labels(label_file) + source_hashes: dict[str, str] = {} + for record in records: + video_path = input_dir / record["video_id"] / f"{record['clip_id']}.mp4" + if not video_path.is_file(): + raise FileNotFoundError(f"missing source video for {record['sample_id']}: {video_path}") + source_hashes[record["sample_id"]] = _sha256(video_path) + output_dir.mkdir(parents=True, exist_ok=True) + cache_dir.mkdir(parents=True, exist_ok=True) + cache_schema = "q1-b0b4-v3" + face_hash = _ensure_face_model() + samples: list[Sample] = [] + missing_records: list[dict[str, Any]] = [] + cache_paths = { + record["sample_id"]: cache_dir / f"{_safe_name(record['video_id'])}__{_safe_name(record['clip_id'])}.npz" + for record in records + } + if not args.force_extract: + for record in records: + path = cache_paths[record["sample_id"]] + if path.is_file(): + try: + samples.append(_load_cache(path, record, source_hashes[record["sample_id"]], cache_schema)) + except (ValueError, KeyError, OSError): + missing_records.append(record) + else: + missing_records.append(record) + else: + missing_records = records.copy() + # Restore source-row order even when resuming a partial cache. + cached_by_id = {sample.sample_id: sample for sample in samples} + if missing_records: + device = torch.device(args.device if args.device != "auto" else ("cuda" if torch.cuda.is_available() else "cpu")) + print(f"Extracting {len(missing_records)} uncached clips on {device}.", flush=True) + models = _load_models(device) + for index, record in enumerate(missing_records, start=1): + started = time.perf_counter() + sample = _extract_native_sample( + record, models, device, FACE_MODEL_PATH, source_hashes[record["sample_id"]] + ) + _save_cache(cache_paths[record["sample_id"]], sample, cache_schema) + cached_by_id[sample.sample_id] = sample + print(f"[features] {index}/{len(missing_records)} {sample.sample_id}: {time.perf_counter()-started:.2f}s", flush=True) + model_info = models[-1] + else: + manifest_path = output_dir / "run_manifest.json" + prior = json.loads(manifest_path.read_text(encoding="utf-8")) if manifest_path.is_file() else {} + model_info = prior.get("models", {"text_id": TEXT_MODEL_ID, "speech_id": SPEECH_MODEL_ID, "revision_status": "features resumed from cache"}) + samples = [cached_by_id[record["sample_id"]] for record in records] + views = [_make_views(sample) for sample in samples] + label_consistent_count = sum(bool(record["label_consistent"]) for record in records) + sample_rows, modality_rows = _sample_output_rows(samples, views) + summary, folds, predictions, splits, deltas = _evaluate(samples, views, args.bootstrap_repeats) + _write_csv(output_dir / "comparison_summary.csv", summary, [ + "method", "sample_count", "video_group_count", "oof_accuracy", "oof_macro_f1", "oof_mae", "oof_pearson", + "fold_accuracy_mean", "fold_accuracy_sd", "fold_macro_f1_mean", "fold_macro_f1_sd", + "fold_mae_mean", "fold_mae_sd", "fold_pearson_mean", "fold_pearson_sd", + ]) + _write_csv(output_dir / "fold_metrics.csv", folds, [ + "method", "fold", "train_samples", "valid_samples", "train_video_groups", "valid_video_groups", + "accuracy", "macro_f1", "mae", "pearson", "feature_dimension", + ]) + _write_csv(output_dir / "oof_predictions.csv", predictions, [ + "sample_id", "video_id", "clip_id", "true_polarity", "true_polarity_name", "true_sentiment", + *[f"{method}_predicted_polarity" for method in ("B0", "B1", "B2", "B3", "B4")], + *[f"{method}_predicted_sentiment" for method in ("B0", "B1", "B2", "B3", "B4")], + ]) + _write_csv(output_dir / "group_bootstrap_deltas.csv", deltas, [ + "comparison", "metric", "reference_oof", "method_oof", "delta_oof", + "group_bootstrap_ci95_low", "group_bootstrap_ci95_high", "bootstrap_repeats", + ]) + _write_csv(output_dir / "split_assignments.csv", sorted(splits, key=lambda row: row["sample_id"]), ["sample_id", "video_id", "fold", "split"]) + _write_csv(output_dir / "sample_alignment_summary.csv", sample_rows, list(sample_rows[0])) + _write_csv(output_dir / "modality_summary.csv", modality_rows, list(modality_rows[0])) + _write_boundary_detail(output_dir, samples) + _create_plot(summary, output_dir / "comparison.png") + typical_sample_id = _create_typical_alignment_figure(samples, views, output_dir / "typical_alignment_example.png") + manifest = { + "created_at_local": time.strftime("%Y-%m-%d %H:%M:%S %z"), + "python": sys.version, + "platform": platform.platform(), + "uv_version": subprocess.run(["uv", "--version"], capture_output=True, text=True).stdout.strip(), + "packages": {name: _version(name) for name in ("torch", "transformers", "numpy", "scipy", "scikit-learn", "mediapipe", "opencv-python-headless", "openpyxl", "matplotlib")}, + "device": args.device if args.device != "auto" else ("cuda" if torch.cuda.is_available() else "cpu"), + "cuda_available": bool(torch.cuda.is_available()), + "gpu_name": torch.cuda.get_device_name(0) if torch.cuda.is_available() and args.device != "cpu" else None, + "models": model_info, + "face_landmarker_asset_sha256": face_hash, + "inputs": { + "label_file": str(label_file), + "label_file_sha256": _sha256(label_file), + "sample_count": len(samples), + "video_sha256_by_sample": source_hashes, + "label_polarity_consistency_count": label_consistent_count, + }, + "experiment": { + "methods": { + "B0": "quality-weighted hard CTC word projection + physical source-time pooling + train-fold standard scaling", + "B1": "B0 + train-fold median/MAD scaling + SO(3) rotation mean + normalized gaze vector mean", + "B2": "B1 + fixed-transcript CTC forward-backward word occupancy projection for text", + "B3": "B1 + second-order time-augmented log signatures of selected audio/face channels", + "B4": "B1 + frozen Wav2Vec2 last-four-layer speech representation", + }, + "text_dimension": 768, + "audio_dimension": 74, + "vision_dimension": 35, + "audio_features": list(AUDIO_NAMES), + "vision_features": list(VISION_NAMES), + "vision_feature_note": "17 MediaPipe blendshape proxies and approximate gaze/landmark geometry; not OpenFace AU labels", + "grid_step_s": GRID_STEP_S, + "audio_window_samples": FRAME_LENGTH, + "audio_step_samples": FRAME_STEP, + "audio_fft": N_FFT, + "audio_mel_bands": MEL_COUNT, + "vision_sample_rate_hz": VISION_RATE_HZ, + "grouping": "GroupKFold by video_id", + "fold_count": N_FOLDS, + "probe": {"classifier": "LogisticRegression", "C": 0.05, "regressor": "Ridge", "alpha": 25.0, "intensity_clip": [-3.0, 3.0]}, + "bootstrap": {"unit": "video_id", "repeats": args.bootstrap_repeats, "seed": SEED}, + "human_boundary_reference_count": 0, + "boundary_interval_level": 0.90, + "hard_text_quality_weight": "per-sample median-normalized CTC path score clipped to [0.25, 4.0]; uncalibrated", + "cache_schema": cache_schema, + }, + "output_dir": str(output_dir), + "typical_sample_id": typical_sample_id, + "elapsed_seconds": time.time() - args.started_at, + } + (output_dir / "run_manifest.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + _write_report(output_dir, summary, deltas, sample_rows, modality_rows, manifest) + print(f"Saved B0-B4 comparison to {output_dir}", flush=True) + + +def _parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Run Q1 B0-B4 model comparison on Attachment 1.") + parser.add_argument("--data-dir", type=Path, default=DATA_DIR) + parser.add_argument("--output-dir", type=Path, default=OUTPUT_DIR) + parser.add_argument("--cache-dir", type=Path, default=CACHE_DIR) + parser.add_argument("--device", choices=("auto", "cuda", "cpu"), default="auto") + parser.add_argument("--bootstrap-repeats", type=int, default=2000) + parser.add_argument("--force-extract", action="store_true", help="recompute native features from the 100 raw videos") + args = parser.parse_args() + if args.bootstrap_repeats < 100: + parser.error("--bootstrap-repeats must be at least 100") + args.started_at = time.time() + return args + + +if __name__ == "__main__": + run(_parse_args()) diff --git a/math/pyproject.toml b/math/pyproject.toml new file mode 100644 index 0000000..f4afaf6 --- /dev/null +++ b/math/pyproject.toml @@ -0,0 +1,24 @@ +[project] +name = "math-q1-comparison" +version = "0.1.0" +requires-python = ">=3.14" +dependencies = [ + "matplotlib>=3.11.2", + "mediapipe>=1.0.1", + "numpy>=2.5.2", + "opencv-python-headless>=5.0.0.93", + "openpyxl>=3.1.5", + "pillow>=12.3.0", + "scikit-learn>=1.9.1", + "scipy>=1.17.1", + "torch>=2.14.0", + "transformers>=5.17.0", +] + +[tool.uv.sources] +torch = { index = "pytorch" } + +[[tool.uv.index]] +name = "pytorch" +url = "https://download.pytorch.org/whl/cu130" +explicit = true diff --git a/math/results/model_comparison/comparison.png b/math/results/model_comparison/comparison.png new file mode 100644 index 0000000..556343b Binary files /dev/null and b/math/results/model_comparison/comparison.png differ diff --git a/math/results/model_comparison/comparison_summary.csv b/math/results/model_comparison/comparison_summary.csv new file mode 100644 index 0000000..c001e08 --- /dev/null +++ b/math/results/model_comparison/comparison_summary.csv @@ -0,0 +1,6 @@ +method,sample_count,video_group_count,oof_accuracy,oof_macro_f1,oof_mae,oof_pearson,fold_accuracy_mean,fold_accuracy_sd,fold_macro_f1_mean,fold_macro_f1_sd,fold_mae_mean,fold_mae_sd,fold_pearson_mean,fold_pearson_sd +B0,100,37,0.6,0.3612633181126332,0.5642678308486938,0.34585652345724877,0.6,0.1274754878398196,0.33701813174429807,0.09810807621270928,0.5642678308486938,0.15030090846290933,0.40788979900767275,0.06001860958324475 +B1,100,37,0.61,0.387431302270012,0.5989421024918556,0.23765809617297712,0.61,0.1341640786499874,0.3493607699490052,0.11905440418044842,0.5989421024918556,0.15750913261096855,0.281166840616461,0.14435440813423514 +B2,100,37,0.58,0.33061794334825517,0.588000754788518,0.2790493470006418,0.5800000000000001,0.14404860290887933,0.3128829195495862,0.08742851668319461,0.588000754788518,0.14204292727229248,0.3331122890661654,0.08879703094318196 +B3,100,37,0.59,0.3587962962962963,0.5997931832820177,0.23011191320162028,0.5900000000000001,0.12942179105544785,0.33257284523004604,0.09564119982991781,0.5997931832820177,0.15746511520951317,0.2803250178248575,0.13217248970127823 +B4,100,37,0.6,0.4222603610475464,0.59276591360569,0.19864510121331094,0.6,0.13693063937629155,0.3976841268630668,0.08882960164587973,0.59276591360569,0.16014796281119822,0.24000288610371706,0.14964617105964673 diff --git a/math/results/model_comparison/fold_metrics.csv b/math/results/model_comparison/fold_metrics.csv new file mode 100644 index 0000000..248683a --- /dev/null +++ b/math/results/model_comparison/fold_metrics.csv @@ -0,0 +1,26 @@ +method,fold,train_samples,valid_samples,train_video_groups,valid_video_groups,accuracy,macro_f1,mae,pearson,feature_dimension +B0,1,80,20,31,6,0.75,0.29411764705882354,0.4224671095609665,0.39024875749849447,4385 +B1,1,80,20,31,6,0.75,0.29411764705882354,0.43092925772070884,0.3768780281745036,4385 +B2,1,80,20,31,6,0.75,0.2857142857142857,0.43804959058761594,0.3386523481377315,4385 +B3,1,80,20,31,6,0.75,0.29411764705882354,0.42625029012560844,0.3688530099245201,4455 +B4,1,80,20,31,6,0.8,0.42745098039215684,0.41526668667793276,0.3438838954822536,8225 +B0,2,80,20,30,7,0.6,0.3639846743295019,0.776566531509161,0.3958411255263523,4385 +B1,2,80,20,30,7,0.6,0.35714285714285715,0.8237437169998885,0.24091732574554836,4385 +B2,2,80,20,30,7,0.6,0.35714285714285715,0.7888965889811516,0.3639766310607314,4385 +B3,2,80,20,30,7,0.6,0.35714285714285715,0.8207762833684683,0.256615486910397,4455 +B4,2,80,20,30,7,0.6,0.3639846743295019,0.8059555269777775,0.19887966518486633,8225 +B0,3,80,20,29,8,0.65,0.44334975369458124,0.6439033597707748,0.4541649022346378,4385 +B1,3,80,20,29,8,0.7,0.5119047619047619,0.6599065795540809,0.3794933845977076,4385 +B2,3,80,20,29,8,0.6,0.35555555555555557,0.660385686159134,0.3833892851036205,4385 +B3,3,80,20,29,8,0.65,0.44334975369458124,0.6637263983488083,0.36870656729912815,4455 +B4,3,80,20,29,8,0.5,0.3956043956043956,0.6777055777609349,0.23098821201949785,8225 +B0,4,80,20,29,8,0.4,0.19047619047619047,0.5507291875779629,0.32319803952574416,4385 +B1,4,80,20,29,8,0.4,0.19047619047619047,0.6101470191031695,0.04446251878558958,4385 +B2,4,80,20,29,8,0.35,0.1728395061728395,0.5764139499515295,0.17960866044359325,4385 +B3,4,80,20,29,8,0.4,0.19047619047619047,0.6146079197525978,0.0589277387406542,4455 +B4,4,80,20,29,8,0.45,0.2792022792022792,0.607093845307827,0.018750134966085342,8225 +B0,5,80,20,29,8,0.6,0.39316239316239315,0.427672965824604,0.4759961702531348,4385 +B1,5,80,20,29,8,0.6,0.39316239316239315,0.46998393908143044,0.3640829457789559,4385 +B2,5,80,20,29,8,0.6,0.39316239316239315,0.4762579582631588,0.3999345205851506,4385 +B3,5,80,20,29,8,0.55,0.37777777777777777,0.4736050248146057,0.34852228624958836,4455 +B4,5,80,20,29,8,0.65,0.5221783047870004,0.45780793130397796,0.4075125228658822,8225 diff --git a/math/results/model_comparison/group_bootstrap_deltas.csv b/math/results/model_comparison/group_bootstrap_deltas.csv new file mode 100644 index 0000000..b895fb3 --- /dev/null +++ b/math/results/model_comparison/group_bootstrap_deltas.csv @@ -0,0 +1,17 @@ +comparison,metric,reference_oof,method_oof,delta_oof,group_bootstrap_ci95_low,group_bootstrap_ci95_high,bootstrap_repeats +B0-B1,accuracy,0.61,0.6,-0.010000000000000009,-0.029710396039603987,0.0,2000 +B0-B1,macro_f1,0.387431302270012,0.3612633181126332,-0.02616798415737881,-0.08327057744765032,0.0,2000 +B0-B1,mae,0.5989421024918556,0.5642678308486938,-0.034674271643161836,-0.06304207975806683,-0.012443204964559182,2000 +B0-B1,pearson,0.23765809617297712,0.34585652345724877,0.10819842728427165,0.04340079372240924,0.19005024141624596,2000 +B2-B1,accuracy,0.61,0.58,-0.030000000000000027,-0.0648204607046071,0.0,2000 +B2-B1,macro_f1,0.387431302270012,0.33061794334825517,-0.05681335892175682,-0.10940517350156256,-0.0009457159449812041,2000 +B2-B1,mae,0.5989421024918556,0.588000754788518,-0.010941347703337656,-0.027305471624463586,0.004017100735475708,2000 +B2-B1,pearson,0.23765809617297712,0.2790493470006418,0.041391250827664705,-0.009244736549056344,0.10131359014731482,2000 +B3-B1,accuracy,0.61,0.59,-0.020000000000000018,-0.05154639175257736,0.0,2000 +B3-B1,macro_f1,0.387431302270012,0.3587962962962963,-0.02863500597371571,-0.07212177947137302,0.0,2000 +B3-B1,mae,0.5989421024918556,0.5997931832820177,0.000851080790162051,-0.004701075716562739,0.006246566925533936,2000 +B3-B1,pearson,0.23765809617297712,0.23011191320162028,-0.007546182971356841,-0.022226358336772584,0.005402452990031458,2000 +B4-B1,accuracy,0.61,0.6,-0.010000000000000009,-0.08080808080808077,0.06196073008849559,2000 +B4-B1,macro_f1,0.387431302270012,0.4222603610475464,0.034829058777534394,-0.051408708516982864,0.13655330256210496,2000 +B4-B1,mae,0.5989421024918556,0.59276591360569,-0.006176188886165668,-0.03045045264816862,0.015397113913740889,2000 +B4-B1,pearson,0.23765809617297712,0.19864510121331094,-0.039012994959666175,-0.1082683426423725,0.03034022099301614,2000 diff --git a/math/results/model_comparison/modality_summary.csv b/math/results/model_comparison/modality_summary.csv new file mode 100644 index 0000000..71fa296 --- /dev/null +++ b/math/results/model_comparison/modality_summary.csv @@ -0,0 +1,301 @@ +sample_id,video_id,clip_id,modality,source_duration_s,observed_duration_s_mean_dimension,native_length,native_dimension,main_grid_length,grid_step_s,grid_dimension,mean_grid_coverage,status,source_video_sha256 +-3g5yACwYnA/13,-3g5yACwYnA,13,text,5.5139970779418945,2.946523889899254,15,768,56,0.1,768,0.7015532851219177,ok,aeb47627f59dce3d0a85a44ef35e4a3bc18211498e98c8c11cf60269646df24f +-3g5yACwYnA/13,-3g5yACwYnA,13,audio,5.5139970779418945,5.445240411887298,540,74,56,0.1,74,0.9882608652114868,ok,aeb47627f59dce3d0a85a44ef35e4a3bc18211498e98c8c11cf60269646df24f +-3g5yACwYnA/13,-3g5yACwYnA,13,vision,5.5139970779418945,5.5139970779418945,43,35,56,0.1,35,1.0,ok,aeb47627f59dce3d0a85a44ef35e4a3bc18211498e98c8c11cf60269646df24f +-3g5yACwYnA/3,-3g5yACwYnA,3,text,14.388997077941895,7.041063531115653,29,768,144,0.1,768,0.6343300342559814,ok,eff8cfefba2425155f2b72656829b34b23be8bfe1dcbece384154f56818aa26d +-3g5yACwYnA/3,-3g5yACwYnA,3,audio,14.388997077941895,14.260037878559858,1433,74,144,0.1,74,0.9912122488021851,ok,eff8cfefba2425155f2b72656829b34b23be8bfe1dcbece384154f56818aa26d +-3g5yACwYnA/3,-3g5yACwYnA,3,vision,14.388997077941895,14.388997077941895,103,35,144,0.1,35,1.0,ok,eff8cfefba2425155f2b72656829b34b23be8bfe1dcbece384154f56818aa26d +-3g5yACwYnA/2,-3g5yACwYnA,2,text,9.394009590148926,5.1430321040563305,14,768,94,0.1,768,0.7563282251358032,ok,0619c01f137d017c15c058176f18a575919189c7e81ebd2bfb993afdb86f3de7 +-3g5yACwYnA/2,-3g5yACwYnA,2,audio,9.394009590148926,9.331671435768538,924,74,94,0.1,74,0.9936367273330688,ok,0619c01f137d017c15c058176f18a575919189c7e81ebd2bfb993afdb86f3de7 +-3g5yACwYnA/2,-3g5yACwYnA,2,vision,9.394009590148926,9.394009590148926,78,35,94,0.1,35,1.0,ok,0619c01f137d017c15c058176f18a575919189c7e81ebd2bfb993afdb86f3de7 +-3g5yACwYnA/9,-3g5yACwYnA,9,text,8.816991806030273,5.6415157541632714,21,768,89,0.1,768,0.6637077927589417,ok,b962573b12ed1f06d5533f6427c80dce2bae3a99dd332f6d3fcb32c579f3f016 +-3g5yACwYnA/9,-3g5yACwYnA,9,audio,8.816991806030273,8.735654204761659,870,74,89,0.1,74,0.9912108778953552,ok,b962573b12ed1f06d5533f6427c80dce2bae3a99dd332f6d3fcb32c579f3f016 +-3g5yACwYnA/9,-3g5yACwYnA,9,vision,8.816991806030273,8.816991806030273,75,35,89,0.1,35,1.0,ok,b962573b12ed1f06d5533f6427c80dce2bae3a99dd332f6d3fcb32c579f3f016 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,text,7.867969036102295,5.002839090395719,18,768,79,0.1,768,0.7357116341590881,ok,7ea53ad502b77be7d2ee4494dc23a9478c897792203cf887d546e83d584c1728 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,audio,7.867969036102295,7.843361772234375,779,74,79,0.1,74,0.9971166849136353,ok,7ea53ad502b77be7d2ee4494dc23a9478c897792203cf887d546e83d584c1728 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,vision,7.867969036102295,7.816666602730405,67,35,79,0.1,35,0.9904456734657288,ok,7ea53ad502b77be7d2ee4494dc23a9478c897792203cf887d546e83d584c1728 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,text,3.9820311069488525,2.40418455898877,8,768,40,0.1,768,0.6164926290512085,ok,920a1052c09ebd1eedba6dd1ccfecd80f56f6f0fdcdd1f6dd32b0d90bcb89358 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,audio,3.9820311069488525,3.9192059241395896,392,74,40,0.1,74,0.9881895780563354,ok,920a1052c09ebd1eedba6dd1ccfecd80f56f6f0fdcdd1f6dd32b0d90bcb89358 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,vision,3.9820311069488525,0.8653643131256102,27,35,40,0.1,35,0.9814813733100891,ok,920a1052c09ebd1eedba6dd1ccfecd80f56f6f0fdcdd1f6dd32b0d90bcb89358 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,text,5.6529951095581055,3.0192474961280813,10,768,57,0.1,768,0.7021505832672119,ok,8d61b7f5840a8bd403d9bc6c3cd49029ffc4e304cf9c7834735c1a6bb5fd369d +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,audio,5.6529951095581055,5.595076320642555,555,74,57,0.1,74,0.9900854229927063,ok,8d61b7f5840a8bd403d9bc6c3cd49029ffc4e304cf9c7834735c1a6bb5fd369d +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,vision,5.6529951095581055,1.199999868869782,44,35,57,0.1,35,0.666666567325592,ok,8d61b7f5840a8bd403d9bc6c3cd49029ffc4e304cf9c7834735c1a6bb5fd369d +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,text,3.3580079078674316,1.3907382175326355,7,768,34,0.1,768,0.5562952756881714,ok,696576dcbd0dc42cb678fa40d8a0f0f419a3072bfa7662d653756ab29bba4c46 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,audio,3.3580079078674316,3.306980685486987,326,74,34,0.1,74,0.9901678562164307,ok,696576dcbd0dc42cb678fa40d8a0f0f419a3072bfa7662d653756ab29bba4c46 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,vision,3.3580079078674316,1.6413411736488344,21,35,34,0.1,35,0.841666579246521,ok,696576dcbd0dc42cb678fa40d8a0f0f419a3072bfa7662d653756ab29bba4c46 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,text,7.733983993530273,4.492685443162919,22,768,78,0.1,768,0.6705501675605774,ok,90c18e627f27a12c14e21ba24c79edf3008762b4ac26874b490ad3f888381702 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,audio,7.733983993530273,7.691443904670509,764,74,78,0.1,74,0.9946621060371399,ok,90c18e627f27a12c14e21ba24c79edf3008762b4ac26874b490ad3f888381702 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,vision,7.733983993530273,0.0,65,35,78,0.1,35,0.0,ok,90c18e627f27a12c14e21ba24c79edf3008762b4ac26874b490ad3f888381702 +-NFrJFQijFE/1,-NFrJFQijFE,1,text,5.745999813079834,4.074365028738975,16,768,58,0.1,768,0.7835317254066467,ok,d8fcf16c6eb51c56947ec3d0549c6f3bc7a0cf1fc5f5d89e8b38d4249a08db4f +-NFrJFQijFE/1,-NFrJFQijFE,1,audio,5.745999813079834,5.699824074635634,566,74,58,0.1,74,0.9922494292259216,ok,d8fcf16c6eb51c56947ec3d0549c6f3bc7a0cf1fc5f5d89e8b38d4249a08db4f +-NFrJFQijFE/1,-NFrJFQijFE,1,vision,5.745999813079834,0.0,44,35,58,0.1,35,0.0,ok,d8fcf16c6eb51c56947ec3d0549c6f3bc7a0cf1fc5f5d89e8b38d4249a08db4f +-NFrJFQijFE/2,-NFrJFQijFE,2,text,6.855999946594238,3.4186642885208136,18,768,69,0.1,768,0.7431879639625549,ok,a54a5c144a64f5abd26b19aafa6cea8142ee08e9385fa508fa70c934f6b616c1 +-NFrJFQijFE/2,-NFrJFQijFE,2,audio,6.855999946594238,6.798472889210726,670,74,69,0.1,74,0.9926568269729614,ok,a54a5c144a64f5abd26b19aafa6cea8142ee08e9385fa508fa70c934f6b616c1 +-NFrJFQijFE/2,-NFrJFQijFE,2,vision,6.855999946594238,0.0,55,35,69,0.1,35,0.0,ok,a54a5c144a64f5abd26b19aafa6cea8142ee08e9385fa508fa70c934f6b616c1 +-THoVjtIkeU/12,-THoVjtIkeU,12,text,14.896029472351074,7.941008102986966,39,768,149,0.1,768,0.6352806687355042,ok,e2f148f4f2e74724dc13b3ce870a0ce6a06740cfc224f5a9b3d0a870b196e7d4 +-THoVjtIkeU/12,-THoVjtIkeU,12,audio,14.896029472351074,14.759312417861578,1481,74,149,0.1,74,0.9911767244338989,ok,e2f148f4f2e74724dc13b3ce870a0ce6a06740cfc224f5a9b3d0a870b196e7d4 +-THoVjtIkeU/12,-THoVjtIkeU,12,vision,14.896029472351074,14.896029472351074,106,35,149,0.1,35,1.0,ok,e2f148f4f2e74724dc13b3ce870a0ce6a06740cfc224f5a9b3d0a870b196e7d4 +-THoVjtIkeU/2,-THoVjtIkeU,2,text,4.2919921875,2.5793988468125453,10,768,43,0.1,768,0.7164996266365051,ok,35a6c2464ffd68dd96411edb5dc2763f0efb59f264c1d8b737e616fa6b0d1d5b +-THoVjtIkeU/2,-THoVjtIkeU,2,audio,4.2919921875,4.247343715932063,424,74,43,0.1,74,0.9895758628845215,ok,35a6c2464ffd68dd96411edb5dc2763f0efb59f264c1d8b737e616fa6b0d1d5b +-THoVjtIkeU/2,-THoVjtIkeU,2,vision,4.2919921875,4.2919921875,31,35,43,0.1,35,1.0,ok,35a6c2464ffd68dd96411edb5dc2763f0efb59f264c1d8b737e616fa6b0d1d5b +-THoVjtIkeU/6,-THoVjtIkeU,6,text,8.097004890441895,5.15853084437549,30,768,81,0.1,768,0.6787540316581726,ok,efaa55ee6394032c867046690a92c29edfd825005f0a090cca5ccb763b227f64 +-THoVjtIkeU/6,-THoVjtIkeU,6,audio,8.097004890441895,8.027356093840018,799,74,81,0.1,74,0.9927164316177368,ok,efaa55ee6394032c867046690a92c29edfd825005f0a090cca5ccb763b227f64 +-THoVjtIkeU/6,-THoVjtIkeU,6,vision,8.097004890441895,8.097004890441895,68,35,81,0.1,35,1.0,ok,efaa55ee6394032c867046690a92c29edfd825005f0a090cca5ccb763b227f64 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,text,10.350000381469727,5.7645069250837,27,768,104,0.1,768,0.6550575494766235,ok,d5bbda38fcec15817d2b87bab5dcc559d6d425f7d28a82e6c32d13f14b48650c +-UuX1xuaiiE/1,-UuX1xuaiiE,1,audio,10.350000381469727,10.268040973753543,1027,74,104,0.1,74,0.9925051927566528,ok,d5bbda38fcec15817d2b87bab5dcc559d6d425f7d28a82e6c32d13f14b48650c +-UuX1xuaiiE/1,-UuX1xuaiiE,1,vision,10.350000381469727,0.45000076293945285,83,35,104,0.1,35,0.8333339691162109,ok,d5bbda38fcec15817d2b87bab5dcc559d6d425f7d28a82e6c32d13f14b48650c +-UuX1xuaiiE/0,-UuX1xuaiiE,0,text,3.6333329677581787,2.204757870733737,9,768,37,0.1,768,0.6484582424163818,ok,f578b305d53bc152702f5e771de0fcd12d1e9aaefc5cefce3d2082a417aab7c8 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,audio,3.6333329677581787,3.6124320519937045,358,74,37,0.1,74,0.994590699672699,ok,f578b305d53bc152702f5e771de0fcd12d1e9aaefc5cefce3d2082a417aab7c8 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,vision,3.6333329677581787,1.700000047683716,25,35,37,0.1,35,0.9444444179534912,ok,f578b305d53bc152702f5e771de0fcd12d1e9aaefc5cefce3d2082a417aab7c8 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,text,4.1300129890441895,2.0997684210538865,9,768,42,0.1,768,0.7240580320358276,ok,eddb408f25bdc13e6de2fb74caeed709cb7a8f00640e7897135330437f66a2aa +-UuX1xuaiiE/3,-UuX1xuaiiE,3,audio,4.1300129890441895,4.093458598368876,404,74,42,0.1,74,0.992123007774353,ok,eddb408f25bdc13e6de2fb74caeed709cb7a8f00640e7897135330437f66a2aa +-UuX1xuaiiE/3,-UuX1xuaiiE,3,vision,4.1300129890441895,4.03001308441162,29,35,42,0.1,35,0.976190447807312,ok,eddb408f25bdc13e6de2fb74caeed709cb7a8f00640e7897135330437f66a2aa +-UuX1xuaiiE/6,-UuX1xuaiiE,6,text,8.113997459411621,4.803536714613438,22,768,82,0.1,768,0.7064024806022644,ok,f0131ac00e44410fbd32c547a0d421c2791172434fc0203bb969abe14a530532 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,audio,8.113997459411621,7.968213647201255,795,74,82,0.1,74,0.984533965587616,ok,f0131ac00e44410fbd32c547a0d421c2791172434fc0203bb969abe14a530532 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,vision,8.113997459411621,7.9306641817092896,68,35,82,0.1,35,0.9776423573493958,ok,f0131ac00e44410fbd32c547a0d421c2791172434fc0203bb969abe14a530532 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,text,22.15397071838379,13.423765965458015,65,768,222,0.1,768,0.6580277681350708,ok,15d029fc15f50b268b98f1e8abc65e45582e638c13a018d7aa74a18373275946 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,audio,22.15397071838379,21.95386351814141,2209,74,222,0.1,74,0.9912921786308289,ok,15d029fc15f50b268b98f1e8abc65e45582e638c13a018d7aa74a18373275946 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,vision,22.15397071838379,22.15397071838379,142,35,222,0.1,35,1.0,ok,15d029fc15f50b268b98f1e8abc65e45582e638c13a018d7aa74a18373275946 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,text,8.694987297058105,5.3913327027112254,18,768,87,0.1,768,0.7001731395721436,ok,0b6389f45bb966113c65a11998c6e7facdd24c8c42acf2e8cf32e0f2139402e1 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,audio,8.694987297058105,8.639379485394505,854,74,87,0.1,74,0.9945195913314819,ok,0b6389f45bb966113c65a11998c6e7facdd24c8c42acf2e8cf32e0f2139402e1 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,vision,8.694987297058105,8.694987297058105,74,35,87,0.1,35,1.0,ok,0b6389f45bb966113c65a11998c6e7facdd24c8c42acf2e8cf32e0f2139402e1 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,text,10.966667175292969,5.40069461874664,14,768,110,0.1,768,0.71061772108078,ok,6f6e674bbba4353399e9e7825217f37e6d8ca1adf9675f33cf37106f31c55548 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,audio,10.966667175292969,10.855676183829436,1090,74,110,0.1,74,0.9910455346107483,ok,6f6e674bbba4353399e9e7825217f37e6d8ca1adf9675f33cf37106f31c55548 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,vision,10.966667175292969,10.966667175292969,86,35,110,0.1,35,1.0,ok,6f6e674bbba4353399e9e7825217f37e6d8ca1adf9675f33cf37106f31c55548 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,text,16.16100311279297,9.47002421617508,36,768,162,0.1,768,0.6812966465950012,ok,b5ffdc98a4a98b8f0aae55dee5fed66a43bcb129f47a250a004c1cc74e572595 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,audio,16.16100311279297,15.984151583668348,1602,74,162,0.1,74,0.9900091290473938,ok,b5ffdc98a4a98b8f0aae55dee5fed66a43bcb129f47a250a004c1cc74e572595 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,vision,16.16100311279297,16.16100311279297,112,35,162,0.1,35,1.0,ok,b5ffdc98a4a98b8f0aae55dee5fed66a43bcb129f47a250a004c1cc74e572595 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,text,20.5,13.566675072815258,41,768,205,0.1,768,0.7333337664604187,ok,04bd0be907fb46c613f926fe1b06bc2c3b30881c293156510baa34a4105ade55 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,audio,20.5,20.265135636200775,2042,74,205,0.1,74,0.9891952872276306,ok,04bd0be907fb46c613f926fe1b06bc2c3b30881c293156510baa34a4105ade55 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,vision,20.5,15.983333587646484,134,35,205,0.1,35,0.99895840883255,ok,04bd0be907fb46c613f926fe1b06bc2c3b30881c293156510baa34a4105ade55 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,text,16.697982788085938,9.495353608578453,34,768,167,0.1,768,0.6593995094299316,ok,46a5e523b5dd00364c99a3bcbc6fae4c80e1382a84b5b5e681c46eb074ed10f7 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,audio,16.697982788085938,16.517766948940555,1664,74,167,0.1,74,0.9901677966117859,ok,46a5e523b5dd00364c99a3bcbc6fae4c80e1382a84b5b5e681c46eb074ed10f7 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,vision,16.697982788085938,16.697982788085938,115,35,167,0.1,35,1.0,ok,46a5e523b5dd00364c99a3bcbc6fae4c80e1382a84b5b5e681c46eb074ed10f7 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,text,12.735026359558105,8.155348146427425,27,768,128,0.1,768,0.715381383895874,ok,55c1ff86729ab21da743a5107ed07b220e41b4193cd1c0ba9f009e65c3ab0513 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,audio,12.735026359558105,12.576174248392515,1263,74,128,0.1,74,0.9889141917228699,ok,55c1ff86729ab21da743a5107ed07b220e41b4193cd1c0ba9f009e65c3ab0513 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,vision,12.735026359558105,12.5,95,35,128,0.1,35,1.0,ok,55c1ff86729ab21da743a5107ed07b220e41b4193cd1c0ba9f009e65c3ab0513 +-egA8-b7-3M/26,-egA8-b7-3M,26,text,6.030990123748779,3.6452820789068947,15,768,61,0.1,768,0.6877890825271606,ok,11f78aed680ea9c5862a15e04ff6c1f8776c46d29c98b68d28773ff39d959685 +-egA8-b7-3M/26,-egA8-b7-3M,26,audio,6.030990123748779,5.994409297769134,593,74,61,0.1,74,0.9945786595344543,ok,11f78aed680ea9c5862a15e04ff6c1f8776c46d29c98b68d28773ff39d959685 +-egA8-b7-3M/26,-egA8-b7-3M,26,vision,6.030990123748779,6.030990123748779,47,35,61,0.1,35,1.0,ok,11f78aed680ea9c5862a15e04ff6c1f8776c46d29c98b68d28773ff39d959685 +-egA8-b7-3M/17,-egA8-b7-3M,17,text,7.271028995513916,3.4275580286979666,16,768,73,0.1,768,0.7292676568031311,ok,f967e81e0edd51c3700671721afb3fbecbbc32652f27d2db40ea444e8d80c68f +-egA8-b7-3M/17,-egA8-b7-3M,17,audio,7.271028995513916,7.202622791158187,710,74,73,0.1,74,0.9916234016418457,ok,f967e81e0edd51c3700671721afb3fbecbbc32652f27d2db40ea444e8d80c68f +-egA8-b7-3M/17,-egA8-b7-3M,17,vision,7.271028995513916,7.271028995513916,60,35,73,0.1,35,1.0,ok,f967e81e0edd51c3700671721afb3fbecbbc32652f27d2db40ea444e8d80c68f +-egA8-b7-3M/18,-egA8-b7-3M,18,text,8.386002540588379,3.9958887480199343,22,768,84,0.1,768,0.6243576407432556,ok,fd4bc95a6adfb16a9588b7ed65cc2812186ce3d607804dc76f4486312951ef90 +-egA8-b7-3M/18,-egA8-b7-3M,18,audio,8.386002540588379,8.326583495091747,827,74,84,0.1,74,0.9932008385658264,ok,fd4bc95a6adfb16a9588b7ed65cc2812186ce3d607804dc76f4486312951ef90 +-egA8-b7-3M/18,-egA8-b7-3M,18,vision,8.386002540588379,8.386002540588379,71,35,84,0.1,35,1.0,ok,fd4bc95a6adfb16a9588b7ed65cc2812186ce3d607804dc76f4486312951ef90 +-egA8-b7-3M/16,-egA8-b7-3M,16,text,5.538021087646484,3.3190146580338484,11,768,56,0.1,768,0.7375588417053223,ok,4c015f85e3bd901ecedde8c0c2ca4a756d9a77dfe4177625c481581f2037ff9c +-egA8-b7-3M/16,-egA8-b7-3M,16,audio,5.538021087646484,5.498074575251824,549,74,56,0.1,74,0.9940068125724792,ok,4c015f85e3bd901ecedde8c0c2ca4a756d9a77dfe4177625c481581f2037ff9c +-egA8-b7-3M/16,-egA8-b7-3M,16,vision,5.538021087646484,5.538021087646484,43,35,56,0.1,35,1.0,ok,4c015f85e3bd901ecedde8c0c2ca4a756d9a77dfe4177625c481581f2037ff9c +-egA8-b7-3M/13,-egA8-b7-3M,13,text,4.18398380279541,2.166685357689858,11,768,42,0.1,768,0.6372604370117188,ok,cbd627c225ebca37521ae238cb9ec254cad236822f4f37ebfbb039e6c56aea4c +-egA8-b7-3M/13,-egA8-b7-3M,13,audio,4.18398380279541,4.149822072886132,403,74,42,0.1,74,0.9924017786979675,ok,cbd627c225ebca37521ae238cb9ec254cad236822f4f37ebfbb039e6c56aea4c +-egA8-b7-3M/13,-egA8-b7-3M,13,vision,4.18398380279541,4.18398380279541,29,35,42,0.1,35,1.0,ok,cbd627c225ebca37521ae238cb9ec254cad236822f4f37ebfbb039e6c56aea4c +-egA8-b7-3M/1,-egA8-b7-3M,1,text,10.266016006469727,5.581577223725616,20,768,103,0.1,768,0.6490206122398376,ok,589a7989b1b4888568c31614a2d6beefba88fb87289c85b94df2d8051500403b +-egA8-b7-3M/1,-egA8-b7-3M,1,audio,10.266016006469727,10.199569694899225,1016,74,103,0.1,74,0.9937204718589783,ok,589a7989b1b4888568c31614a2d6beefba88fb87289c85b94df2d8051500403b +-egA8-b7-3M/1,-egA8-b7-3M,1,vision,10.266016006469727,10.266016006469727,83,35,103,0.1,35,1.0,ok,589a7989b1b4888568c31614a2d6beefba88fb87289c85b94df2d8051500403b +-egA8-b7-3M/6,-egA8-b7-3M,6,text,6.264974117279053,3.582069296762348,12,768,63,0.1,768,0.7164138555526733,ok,2e88a00d5e55863aa956b4b0949fc0e4f2975ccfd83b3194957f6fca86ecfce0 +-egA8-b7-3M/6,-egA8-b7-3M,6,audio,6.264974117279053,6.2242991206613745,619,74,63,0.1,74,0.9942464828491211,ok,2e88a00d5e55863aa956b4b0949fc0e4f2975ccfd83b3194957f6fca86ecfce0 +-egA8-b7-3M/6,-egA8-b7-3M,6,vision,6.264974117279053,6.264974117279053,50,35,63,0.1,35,1.0,ok,2e88a00d5e55863aa956b4b0949fc0e4f2975ccfd83b3194957f6fca86ecfce0 +-egA8-b7-3M/9,-egA8-b7-3M,9,text,5.0899739265441895,2.328742109239101,10,768,51,0.1,768,0.597113311290741,ok,bcd643f328616312eae9b28e6c9aabbe8acaec3e4c4be58daeb45e3eee4d973c +-egA8-b7-3M/9,-egA8-b7-3M,9,audio,5.0899739265441895,5.05666382530251,494,74,51,0.1,74,0.9939422011375427,ok,bcd643f328616312eae9b28e6c9aabbe8acaec3e4c4be58daeb45e3eee4d973c +-egA8-b7-3M/9,-egA8-b7-3M,9,vision,5.0899739265441895,5.0899739265441895,38,35,51,0.1,35,1.0,ok,bcd643f328616312eae9b28e6c9aabbe8acaec3e4c4be58daeb45e3eee4d973c +-egA8-b7-3M/20,-egA8-b7-3M,20,text,6.644987106323242,3.9119302723556753,20,768,67,0.1,768,0.6985589861869812,ok,719ef133920e74b3ea33925d2bca0270b062199116867568f88ac83cadcd74e8 +-egA8-b7-3M/20,-egA8-b7-3M,20,audio,6.644987106323242,6.588095611333847,648,74,67,0.1,74,0.992087185382843,ok,719ef133920e74b3ea33925d2bca0270b062199116867568f88ac83cadcd74e8 +-egA8-b7-3M/20,-egA8-b7-3M,20,vision,6.644987106323242,6.644987106323242,54,35,67,0.1,35,1.0,ok,719ef133920e74b3ea33925d2bca0270b062199116867568f88ac83cadcd74e8 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,text,5.620999813079834,2.037480006366969,8,768,57,0.1,768,0.6791599988937378,ok,39c547acd1a8da2ebc6c6ab008191a5676420398a974cd9611cad087f0ccec50 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,audio,5.620999813079834,5.578905152469068,554,74,57,0.1,74,0.9954468607902527,ok,39c547acd1a8da2ebc6c6ab008191a5676420398a974cd9611cad087f0ccec50 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,vision,5.620999813079834,0.0,28,35,57,0.1,35,0.0,ok,39c547acd1a8da2ebc6c6ab008191a5676420398a974cd9611cad087f0ccec50 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,text,4.104000091552734,2.2118893228471284,9,768,42,0.1,768,0.7135127186775208,ok,cc7b1c7a06ec41d72007b5c42fb8036f30b66d5cf76e3f093160c22fc5e38081 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,audio,4.104000091552734,4.083554145129952,401,74,42,0.1,74,0.995795726776123,ok,cc7b1c7a06ec41d72007b5c42fb8036f30b66d5cf76e3f093160c22fc5e38081 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,vision,4.104000091552734,0.0,21,35,42,0.1,35,0.0,ok,cc7b1c7a06ec41d72007b5c42fb8036f30b66d5cf76e3f093160c22fc5e38081 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,text,2.9030001163482666,1.5899996414780622,5,768,30,0.1,768,0.7227271199226379,ok,030b0b8d8d4ae47799432ab71b66fcc881f077c5b0feef892c1f146dc0a592e3 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,audio,2.9030001163482666,2.892310954429008,283,74,30,0.1,74,0.9973600506782532,ok,030b0b8d8d4ae47799432ab71b66fcc881f077c5b0feef892c1f146dc0a592e3 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,vision,2.9030001163482666,0.0,15,35,30,0.1,35,0.0,ok,030b0b8d8d4ae47799432ab71b66fcc881f077c5b0feef892c1f146dc0a592e3 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,text,3.4159998893737793,1.094375005364418,5,768,35,0.1,768,0.643750011920929,ok,352bdcc73d3622d6abac1b09f2039b211d15b9bf7acee66f0b07783c9b7a4c74 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,audio,3.4159998893737793,3.383608031917263,338,74,35,0.1,74,0.993934154510498,ok,352bdcc73d3622d6abac1b09f2039b211d15b9bf7acee66f0b07783c9b7a4c74 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,vision,3.4159998893737793,0.0,17,35,35,0.1,35,0.0,ok,352bdcc73d3622d6abac1b09f2039b211d15b9bf7acee66f0b07783c9b7a4c74 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,text,8.093000411987305,3.901277539858493,21,768,81,0.1,768,0.6192578673362732,ok,72a49e3da2862addcde033bd2fbae957d086533664ca4dcbccd3a851bcd50412 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,audio,8.093000411987305,8.037513972489212,803,74,81,0.1,74,0.9947929382324219,ok,72a49e3da2862addcde033bd2fbae957d086533664ca4dcbccd3a851bcd50412 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,vision,8.093000411987305,0.0,41,35,81,0.1,35,0.0,ok,72a49e3da2862addcde033bd2fbae957d086533664ca4dcbccd3a851bcd50412 +-lzEya4AM_4/5,-lzEya4AM_4,5,text,7.675000190734863,4.456424816604702,19,768,77,0.1,768,0.7427374720573425,ok,3b74de8d0e66fd754594f05985e5af3480adcc03555f79225d3b727cb4bed043 +-lzEya4AM_4/5,-lzEya4AM_4,5,audio,7.675000190734863,7.5937163826178855,757,74,77,0.1,74,0.9901386499404907,ok,3b74de8d0e66fd754594f05985e5af3480adcc03555f79225d3b727cb4bed043 +-lzEya4AM_4/5,-lzEya4AM_4,5,vision,7.675000190734863,7.675000190734863,64,35,77,0.1,35,1.0,ok,3b74de8d0e66fd754594f05985e5af3480adcc03555f79225d3b727cb4bed043 +-lzEya4AM_4/6,-lzEya4AM_4,6,text,14.7919921875,9.074837291240696,43,768,148,0.1,768,0.7318416833877563,ok,ff5da5afb551001d58100ed2471caea51c741046d5396957efbf40082307ca18 +-lzEya4AM_4/6,-lzEya4AM_4,6,audio,14.7919921875,14.634100490929308,1475,74,148,0.1,74,0.9907644391059875,ok,ff5da5afb551001d58100ed2471caea51c741046d5396957efbf40082307ca18 +-lzEya4AM_4/6,-lzEya4AM_4,6,vision,14.7919921875,14.7919921875,105,35,148,0.1,35,1.0,ok,ff5da5afb551001d58100ed2471caea51c741046d5396957efbf40082307ca18 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,text,6.103000164031982,1.9617638647556308,13,768,62,0.1,768,0.8174015879631042,ok,c8e3acb4ca08679796c4c8cdfcd8c2b3cffc0465015efaffa1eccdb55ff4f45b +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,audio,6.103000164031982,5.938054213652739,606,74,62,0.1,74,1.0,ok,c8e3acb4ca08679796c4c8cdfcd8c2b3cffc0465015efaffa1eccdb55ff4f45b +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,vision,6.103000164031982,0.0,31,35,62,0.1,35,0.0,ok,c8e3acb4ca08679796c4c8cdfcd8c2b3cffc0465015efaffa1eccdb55ff4f45b +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,text,5.730999946594238,3.5213801980018595,11,768,58,0.1,768,0.9266790151596069,ok,c41790f8b75f886bd1f5d6d72cbab1985306d0b715e5ae47203f3d0c8a3e7b28 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,audio,5.730999946594238,5.5761080561457455,571,74,58,0.1,74,1.0,ok,c41790f8b75f886bd1f5d6d72cbab1985306d0b715e5ae47203f3d0c8a3e7b28 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,vision,5.730999946594238,0.0,29,35,58,0.1,35,0.0,ok,c41790f8b75f886bd1f5d6d72cbab1985306d0b715e5ae47203f3d0c8a3e7b28 +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,text,2.256999969482422,1.1722640581429007,5,768,23,0.1,768,0.6512578129768372,ok,134a3a4ebbc423760133b0da0e90cfe84d75ea85df3968000afd84153c5d828d +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,audio,2.256999969482422,2.2208648198211596,223,74,23,0.1,74,0.9862568378448486,ok,134a3a4ebbc423760133b0da0e90cfe84d75ea85df3968000afd84153c5d828d +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,vision,2.256999969482422,2.256999969482422,12,35,23,0.1,35,1.0,ok,134a3a4ebbc423760133b0da0e90cfe84d75ea85df3968000afd84153c5d828d +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,text,7.0329999923706055,3.813062208145856,22,768,71,0.1,768,0.5777366757392883,ok,df3442f3ed8f894b507923e87e426ae9636790a4a502d00c350a215270cc3e47 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,audio,7.0329999923706055,6.9057026652870945,691,74,71,0.1,74,0.9846946001052856,ok,df3442f3ed8f894b507923e87e426ae9636790a4a502d00c350a215270cc3e47 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,vision,7.0329999923706055,6.832799911499023,35,35,71,0.1,35,0.9856857061386108,ok,df3442f3ed8f894b507923e87e426ae9636790a4a502d00c350a215270cc3e47 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,text,4.191999912261963,2.284389768779285,11,768,42,0.1,768,0.6529467701911926,ok,6af6614c9838417a48c4817f4dd5bf1e6669eb5f78f983e9a68adc113fcdc7cc +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,audio,4.191999912261963,4.127891841835266,418,74,42,0.1,74,0.9846959114074707,ok,6af6614c9838417a48c4817f4dd5bf1e6669eb5f78f983e9a68adc113fcdc7cc +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,vision,4.191999912261963,4.191999912261963,21,35,42,0.1,35,1.0,ok,6af6614c9838417a48c4817f4dd5bf1e6669eb5f78f983e9a68adc113fcdc7cc +-mqbVkbCndg/0,-mqbVkbCndg,0,text,6.466667175292969,3.891069056466222,12,768,65,0.1,768,0.7074670791625977,ok,cdeba953bba30907814acf72f3e35582dec263eaa25bdd922dad7fafe02e4dda +-mqbVkbCndg/0,-mqbVkbCndg,0,audio,6.466667175292969,6.400540961445988,639,74,65,0.1,74,0.9905118346214294,ok,cdeba953bba30907814acf72f3e35582dec263eaa25bdd922dad7fafe02e4dda +-mqbVkbCndg/0,-mqbVkbCndg,0,vision,6.466667175292969,6.466667175292969,53,35,65,0.1,35,1.0,ok,cdeba953bba30907814acf72f3e35582dec263eaa25bdd922dad7fafe02e4dda +-t217m2on-s/2,-t217m2on-s,2,text,5.6860032081604,2.3235132679343233,12,768,57,0.1,768,0.6279765367507935,ok,6713a983112173204502dc5adbb886bc6c38554b4627698611931420c47663a8 +-t217m2on-s/2,-t217m2on-s,2,audio,5.6860032081604,5.64178691047269,564,74,57,0.1,74,0.9959543347358704,ok,6713a983112173204502dc5adbb886bc6c38554b4627698611931420c47663a8 +-t217m2on-s/2,-t217m2on-s,2,vision,5.6860032081604,5.6860032081604,45,35,57,0.1,35,1.0,ok,6713a983112173204502dc5adbb886bc6c38554b4627698611931420c47663a8 +-t217m2on-s/7,-t217m2on-s,7,text,17.183008193969727,10.16458021551371,45,768,172,0.1,768,0.6867958903312683,ok,41c76b8a733ecb780d56348f55d00f0ba0c07f44f46e93044e62d876710180b7 +-t217m2on-s/7,-t217m2on-s,7,audio,17.183008193969727,17.025629438258505,1703,74,172,0.1,74,0.9928514361381531,ok,41c76b8a733ecb780d56348f55d00f0ba0c07f44f46e93044e62d876710180b7 +-t217m2on-s/7,-t217m2on-s,7,vision,17.183008193969727,17.183008193969727,117,35,172,0.1,35,1.0,ok,41c76b8a733ecb780d56348f55d00f0ba0c07f44f46e93044e62d876710180b7 +-tANM6ETl_M/3,-tANM6ETl_M,3,text,6.758008003234863,3.281156235933303,22,768,68,0.1,768,0.5859207510948181,ok,6d3af064c060dad3816a9e1dfa00101faebd8b7da7d8ceea85b0bc0fca70abd6 +-tANM6ETl_M/3,-tANM6ETl_M,3,audio,6.758008003234863,6.702588935075579,661,74,68,0.1,74,0.9936580061912537,ok,6d3af064c060dad3816a9e1dfa00101faebd8b7da7d8ceea85b0bc0fca70abd6 +-tANM6ETl_M/3,-tANM6ETl_M,3,vision,6.758008003234863,6.5333333015441895,54,35,68,0.1,35,0.9898989200592041,ok,6d3af064c060dad3816a9e1dfa00101faebd8b7da7d8ceea85b0bc0fca70abd6 +-tPCytz4rww/11,-tPCytz4rww,11,text,5.466991901397705,3.309338267147543,17,768,55,0.1,768,0.6753751635551453,ok,6dc09d02467baaef67594ff32cffb01f8ed1565cda4c5abd161b8261a51e2e5d +-tPCytz4rww/11,-tPCytz4rww,11,audio,5.466991901397705,5.402410984844775,538,74,55,0.1,74,0.9890678524971008,ok,6dc09d02467baaef67594ff32cffb01f8ed1565cda4c5abd161b8261a51e2e5d +-tPCytz4rww/11,-tPCytz4rww,11,vision,5.466991901397705,5.466991901397705,43,35,55,0.1,35,1.0,ok,6dc09d02467baaef67594ff32cffb01f8ed1565cda4c5abd161b8261a51e2e5d +-tPCytz4rww/10,-tPCytz4rww,10,text,4.788997173309326,2.2889054998755456,12,768,48,0.1,768,0.5449775457382202,ok,758183192cbd5f0f20823d26ece3ddee40dec0aadec35247b2495510a53f52f8 +-tPCytz4rww/10,-tPCytz4rww,10,audio,4.788997173309326,4.71733509463233,468,74,48,0.1,74,0.9894654750823975,ok,758183192cbd5f0f20823d26ece3ddee40dec0aadec35247b2495510a53f52f8 +-tPCytz4rww/10,-tPCytz4rww,10,vision,4.788997173309326,4.788997173309326,35,35,48,0.1,35,1.0,ok,758183192cbd5f0f20823d26ece3ddee40dec0aadec35247b2495510a53f52f8 +-tPCytz4rww/12,-tPCytz4rww,12,text,11.863997459411621,6.21423171013594,26,768,119,0.1,768,0.654129683971405,ok,e3c7f9cd67ad2d20fef997696dc278361f97f027db58762e22104e5720d509d5 +-tPCytz4rww/12,-tPCytz4rww,12,audio,11.863997459411621,11.690646183812941,1174,74,119,0.1,74,0.9875938892364502,ok,e3c7f9cd67ad2d20fef997696dc278361f97f027db58762e22104e5720d509d5 +-tPCytz4rww/12,-tPCytz4rww,12,vision,11.863997459411621,11.863997459411621,91,35,119,0.1,35,1.0,ok,e3c7f9cd67ad2d20fef997696dc278361f97f027db58762e22104e5720d509d5 +-tPCytz4rww/16,-tPCytz4rww,16,text,7.205989837646484,2.154985956847668,16,768,73,0.1,768,0.4489554166793823,ok,8b3f82f9628792eebaf8c227becc2ebeba59bb8abb668bcca86e07fb1a992a93 +-tPCytz4rww/16,-tPCytz4rww,16,audio,7.205989837646484,7.1144090478484685,714,74,73,0.1,74,0.988937258720398,ok,8b3f82f9628792eebaf8c227becc2ebeba59bb8abb668bcca86e07fb1a992a93 +-tPCytz4rww/16,-tPCytz4rww,16,vision,7.205989837646484,7.205989837646484,59,35,73,0.1,35,1.0,ok,8b3f82f9628792eebaf8c227becc2ebeba59bb8abb668bcca86e07fb1a992a93 +-tPCytz4rww/18,-tPCytz4rww,18,text,6.644987106323242,3.4940090492367735,16,768,67,0.1,768,0.6719247698783875,ok,eece70451e9c37a4b5f375bf646f66e09113fe3467f35bf1720cc14d986c1776 +-tPCytz4rww/18,-tPCytz4rww,18,audio,6.644987106323242,6.553973502565075,657,74,67,0.1,74,0.9872123599052429,ok,eece70451e9c37a4b5f375bf646f66e09113fe3467f35bf1720cc14d986c1776 +-tPCytz4rww/18,-tPCytz4rww,18,vision,6.644987106323242,6.644987106323242,54,35,67,0.1,35,1.0,ok,eece70451e9c37a4b5f375bf646f66e09113fe3467f35bf1720cc14d986c1776 +-vxjVxOeScU/4,-vxjVxOeScU,4,text,9.127017974853516,5.366417751088739,21,768,92,0.1,768,0.6465563774108887,ok,00282df9a314394f19d616d561bd1916d1d30dca4c814dfb43630ca164f4c719 +-vxjVxOeScU/4,-vxjVxOeScU,4,audio,9.127017974853516,9.08216616914079,904,74,92,0.1,74,0.9960808753967285,ok,00282df9a314394f19d616d561bd1916d1d30dca4c814dfb43630ca164f4c719 +-vxjVxOeScU/4,-vxjVxOeScU,4,vision,9.127017974853516,9.127017974853516,77,35,92,0.1,35,1.0,ok,00282df9a314394f19d616d561bd1916d1d30dca4c814dfb43630ca164f4c719 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,text,6.044010162353516,3.555890290439128,22,768,61,0.1,768,0.658498227596283,ok,04a73d73fd150b07edab8e652fd14c9cb4a0f6e017ea97b17e8146e377b9fae7 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,audio,6.044010162353516,5.968699067508853,598,74,61,0.1,74,0.9895980954170227,ok,04a73d73fd150b07edab8e652fd14c9cb4a0f6e017ea97b17e8146e377b9fae7 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,vision,6.044010162353516,5.944010257720948,48,35,61,0.1,35,0.9836065769195557,ok,04a73d73fd150b07edab8e652fd14c9cb4a0f6e017ea97b17e8146e377b9fae7 +-wny0OAz3g8/1,-wny0OAz3g8,1,text,6.844009876251221,4.170902410242706,23,768,69,0.1,768,0.62252277135849,ok,c5535859f129ce04da5f5b5104d02d4168057b9d947a5349d423278ad4f3d8e8 +-wny0OAz3g8/1,-wny0OAz3g8,1,audio,6.844009876251221,6.814914991726747,678,74,69,0.1,74,0.995954155921936,ok,c5535859f129ce04da5f5b5104d02d4168057b9d947a5349d423278ad4f3d8e8 +-wny0OAz3g8/1,-wny0OAz3g8,1,vision,6.844009876251221,3.327343463897705,56,35,69,0.1,35,0.9950981140136719,ok,c5535859f129ce04da5f5b5104d02d4168057b9d947a5349d423278ad4f3d8e8 +-wny0OAz3g8/0,-wny0OAz3g8,0,text,3.3333330154418945,1.6946923546493056,9,768,34,0.1,768,0.6052471995353699,ok,1cc21b4432e2f4b592284ee40558a18acc7d208019117aebdb2f6a1b67ea198d +-wny0OAz3g8/0,-wny0OAz3g8,0,audio,3.3333330154418945,3.3145942848276446,328,74,34,0.1,74,0.9955413937568665,ok,1cc21b4432e2f4b592284ee40558a18acc7d208019117aebdb2f6a1b67ea198d +-wny0OAz3g8/0,-wny0OAz3g8,0,vision,3.3333330154418945,2.6999998092651367,21,35,34,0.1,35,0.9999999403953552,ok,1cc21b4432e2f4b592284ee40558a18acc7d208019117aebdb2f6a1b67ea198d +-wny0OAz3g8/3,-wny0OAz3g8,3,text,6.146028995513916,4.208628869801758,20,768,62,0.1,768,0.7014381289482117,ok,ea917c506bc9fa39460f2b722f7c416f646312bb17cd74baa618905b54837bce +-wny0OAz3g8/3,-wny0OAz3g8,3,audio,6.146028995513916,6.13413711335208,610,74,62,0.1,74,0.9980819821357727,ok,ea917c506bc9fa39460f2b722f7c416f646312bb17cd74baa618905b54837bce +-wny0OAz3g8/3,-wny0OAz3g8,3,vision,6.146028995513916,1.5293622016906734,49,35,62,0.1,35,0.9895832538604736,ok,ea917c506bc9fa39460f2b722f7c416f646312bb17cd74baa618905b54837bce +-wny0OAz3g8/2,-wny0OAz3g8,2,text,6.686978816986084,4.909538650512694,23,768,67,0.1,768,0.7553136348724365,ok,1825fb37db2e914fb616cd80aebd613afd873eecb7edd4d0b53158bfda0e522a +-wny0OAz3g8/2,-wny0OAz3g8,2,audio,6.686978816986084,6.656249635122918,653,74,67,0.1,74,0.9957627058029175,ok,1825fb37db2e914fb616cd80aebd613afd873eecb7edd4d0b53158bfda0e522a +-wny0OAz3g8/2,-wny0OAz3g8,2,vision,6.686978816986084,5.4166669845581055,54,35,67,0.1,35,0.9848485589027405,ok,1825fb37db2e914fb616cd80aebd613afd873eecb7edd4d0b53158bfda0e522a +-wny0OAz3g8/5,-wny0OAz3g8,5,text,6.9119791984558105,3.941009076312184,20,768,70,0.1,768,0.6063091158866882,ok,6c6a8a4cba654b25190ab1793bfae81c3d2159ecd6cbc02d3fcbd598543acce0 +-wny0OAz3g8/5,-wny0OAz3g8,5,audio,6.9119791984558105,6.879425679509704,675,74,70,0.1,74,0.9961636066436768,ok,6c6a8a4cba654b25190ab1793bfae81c3d2159ecd6cbc02d3fcbd598543acce0 +-wny0OAz3g8/5,-wny0OAz3g8,5,vision,6.9119791984558105,1.4953122138977046,56,35,70,0.1,35,0.9895831346511841,ok,6c6a8a4cba654b25190ab1793bfae81c3d2159ecd6cbc02d3fcbd598543acce0 +-wny0OAz3g8/7,-wny0OAz3g8,7,text,8.06796932220459,5.293590973317621,29,768,81,0.1,768,0.6700748205184937,ok,cbf9cac1048ce191aef781d0c4563eb97f9f3ddd52eb1f9551fa78d31d70e7cd +-wny0OAz3g8/7,-wny0OAz3g8,7,audio,8.06796932220459,8.030726903515895,792,74,81,0.1,74,0.9956274628639221,ok,cbf9cac1048ce191aef781d0c4563eb97f9f3ddd52eb1f9551fa78d31d70e7cd +-wny0OAz3g8/7,-wny0OAz3g8,7,vision,8.06796932220459,7.06796932220459,68,35,81,0.1,35,1.0,ok,cbf9cac1048ce191aef781d0c4563eb97f9f3ddd52eb1f9551fa78d31d70e7cd +-wny0OAz3g8/9,-wny0OAz3g8,9,text,6.2130208015441895,4.012809376046059,20,768,63,0.1,768,0.6688015460968018,ok,b76f70fe783ee76bf1b637137226c98e67d13a6b15ec725894175b36cd76a136 +-wny0OAz3g8/9,-wny0OAz3g8,9,audio,6.2130208015441895,6.190979680177328,605,74,63,0.1,74,0.9969837069511414,ok,b76f70fe783ee76bf1b637137226c98e67d13a6b15ec725894175b36cd76a136 +-wny0OAz3g8/9,-wny0OAz3g8,9,vision,6.2130208015441895,5.8130205273628235,49,35,63,0.1,35,0.9672130942344666,ok,b76f70fe783ee76bf1b637137226c98e67d13a6b15ec725894175b36cd76a136 +-571d8cVauQ/0,-571d8cVauQ,0,text,5.066667079925537,3.21007038205862,12,768,51,0.1,768,0.6978414058685303,ok,defc62e1530d9b0cd27f2acfe042b71dd84d7e8c85f1df261f04912091976088 +-571d8cVauQ/0,-571d8cVauQ,0,audio,5.066667079925537,5.013243622071034,500,74,51,0.1,74,0.9903978705406189,ok,defc62e1530d9b0cd27f2acfe042b71dd84d7e8c85f1df261f04912091976088 +-571d8cVauQ/0,-571d8cVauQ,0,vision,5.066667079925537,4.9666670799255375,39,35,51,0.1,35,1.0,ok,defc62e1530d9b0cd27f2acfe042b71dd84d7e8c85f1df261f04912091976088 +-571d8cVauQ/5,-571d8cVauQ,5,text,15.272981643676758,9.052198391593993,43,768,153,0.1,768,0.7017207741737366,ok,e304c03fac1f477823fe0926c4fb421b9c4e4091f85718b729afe856c24a7d3e +-571d8cVauQ/5,-571d8cVauQ,5,audio,15.272981643676758,15.142900936426344,1512,74,153,0.1,74,0.9918006062507629,ok,e304c03fac1f477823fe0926c4fb421b9c4e4091f85718b729afe856c24a7d3e +-571d8cVauQ/5,-571d8cVauQ,5,vision,15.272981643676758,15.272981643676758,108,35,153,0.1,35,1.0,ok,e304c03fac1f477823fe0926c4fb421b9c4e4091f85718b729afe856c24a7d3e +-I_e4mIh0yE/1,-I_e4mIh0yE,1,text,7.622004985809326,3.535097924340517,18,768,77,0.1,768,0.6546477675437927,ok,8453a966d4bd1f0179eb86a35cd34c0864a3a3bc2fa86f37783060cc0d14f5df +-I_e4mIh0yE/1,-I_e4mIh0yE,1,audio,7.622004985809326,7.497626475627357,745,74,77,0.1,74,0.985649049282074,ok,8453a966d4bd1f0179eb86a35cd34c0864a3a3bc2fa86f37783060cc0d14f5df +-I_e4mIh0yE/1,-I_e4mIh0yE,1,vision,7.622004985809326,7.622004985809326,63,35,77,0.1,35,1.0,ok,8453a966d4bd1f0179eb86a35cd34c0864a3a3bc2fa86f37783060cc0d14f5df +-I_e4mIh0yE/3,-I_e4mIh0yE,3,text,9.163021087646484,4.626299023628236,22,768,92,0.1,768,0.6251755356788635,ok,a015f02ae51d74c42ad27e2a0831263a303f0658ac8d984819e27ad61342b23e +-I_e4mIh0yE/3,-I_e4mIh0yE,3,audio,9.163021087646484,9.017804326318405,900,74,92,0.1,74,0.9852646589279175,ok,a015f02ae51d74c42ad27e2a0831263a303f0658ac8d984819e27ad61342b23e +-I_e4mIh0yE/3,-I_e4mIh0yE,3,vision,9.163021087646484,9.163021087646484,77,35,92,0.1,35,1.0,ok,a015f02ae51d74c42ad27e2a0831263a303f0658ac8d984819e27ad61342b23e +-UacrmKiTn4/10,-UacrmKiTn4,10,text,7.361979007720947,2.732618988305329,18,768,74,0.1,768,0.47940683364868164,ok,00312e0602dbeac970de5d7dd0e8a970e514fe45d7fe6625b4f454b299e36360 +-UacrmKiTn4/10,-UacrmKiTn4,10,audio,7.361979007720947,7.319425493478775,725,74,74,0.1,74,0.9955651164054871,ok,00312e0602dbeac970de5d7dd0e8a970e514fe45d7fe6625b4f454b299e36360 +-UacrmKiTn4/10,-UacrmKiTn4,10,vision,7.361979007720947,7.361979007720947,60,35,74,0.1,35,1.0,ok,00312e0602dbeac970de5d7dd0e8a970e514fe45d7fe6625b4f454b299e36360 +-UacrmKiTn4/4,-UacrmKiTn4,4,text,4.741015911102295,3.0301611527800563,14,768,48,0.1,768,0.7214669585227966,ok,a7f2ab0d6ee2e2a2d5cd4239f03e6cac67c618ddb744891323df3ff87e29af84 +-UacrmKiTn4/4,-UacrmKiTn4,4,audio,4.741015911102295,4.704772258610339,469,74,48,0.1,74,0.9926760792732239,ok,a7f2ab0d6ee2e2a2d5cd4239f03e6cac67c618ddb744891323df3ff87e29af84 +-UacrmKiTn4/4,-UacrmKiTn4,4,vision,4.741015911102295,4.741015911102295,35,35,48,0.1,35,1.0,ok,a7f2ab0d6ee2e2a2d5cd4239f03e6cac67c618ddb744891323df3ff87e29af84 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,text,7.372000217437744,4.009185888338835,13,768,74,0.1,768,0.657243549823761,ok,0ec6fb76226315d3fafbb483e3500e60cc8a6729617b10e4b4b76163595080fb +-hnBHBN8p5A/7,-hnBHBN8p5A,7,audio,7.372000217437744,7.281608330236899,731,74,74,0.1,74,0.9905768632888794,ok,0ec6fb76226315d3fafbb483e3500e60cc8a6729617b10e4b4b76163595080fb +-hnBHBN8p5A/7,-hnBHBN8p5A,7,vision,7.372000217437744,0.0,37,35,74,0.1,35,0.0,ok,0ec6fb76226315d3fafbb483e3500e60cc8a6729617b10e4b4b76163595080fb +-hnBHBN8p5A/6,-hnBHBN8p5A,6,text,6.401000022888184,3.580871792882682,13,768,65,0.1,768,0.7618876099586487,ok,997f6808ac3973ddd71800e91c8e10755c10b5037186d84348a79e00d672fdc7 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,audio,6.401000022888184,6.346108104731585,634,74,65,0.1,74,0.9932082295417786,ok,997f6808ac3973ddd71800e91c8e10755c10b5037186d84348a79e00d672fdc7 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,vision,6.401000022888184,0.0,32,35,65,0.1,35,0.0,ok,997f6808ac3973ddd71800e91c8e10755c10b5037186d84348a79e00d672fdc7 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,text,4.677995204925537,2.927082145679743,16,768,47,0.1,768,0.6504627466201782,ok,ab19bf4a761d3919b7113b1104ccaadbbf0c4e7b45694904d094280a2c329c8b +-qDkUB0GgYY/6,-qDkUB0GgYY,6,audio,4.677995204925537,4.653116947730401,462,74,47,0.1,74,0.9946085214614868,ok,ab19bf4a761d3919b7113b1104ccaadbbf0c4e7b45694904d094280a2c329c8b +-qDkUB0GgYY/6,-qDkUB0GgYY,6,vision,4.677995204925537,4.677995204925537,35,35,47,0.1,35,1.0,ok,ab19bf4a761d3919b7113b1104ccaadbbf0c4e7b45694904d094280a2c329c8b +-uywlfIYOS8/4,-uywlfIYOS8,4,text,6.044987201690674,3.7997015411034236,18,768,61,0.1,768,0.6908547878265381,ok,fde46f5222cf5cfec7af9c93214c972ce2d686b0bf9c90a291021601968986f9 +-uywlfIYOS8/4,-uywlfIYOS8,4,audio,6.044987201690674,6.015325370511492,589,74,61,0.1,74,0.9957761168479919,ok,fde46f5222cf5cfec7af9c93214c972ce2d686b0bf9c90a291021601968986f9 +-uywlfIYOS8/4,-uywlfIYOS8,4,vision,6.044987201690674,6.044987201690674,48,35,61,0.1,35,1.0,ok,fde46f5222cf5cfec7af9c93214c972ce2d686b0bf9c90a291021601968986f9 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,text,12.805012702941895,6.537867438234387,34,768,129,0.1,768,0.63474440574646,ok,59b77a0f873b7fa95e7327b93d64bb5a4bdae84039321988ef70bba8e63ee1ae +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,audio,12.805012702941895,12.672918005408468,1274,74,129,0.1,74,0.9899758696556091,ok,59b77a0f873b7fa95e7327b93d64bb5a4bdae84039321988ef70bba8e63ee1ae +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,vision,12.805012702941895,12.805012702941895,95,35,129,0.1,35,1.0,ok,59b77a0f873b7fa95e7327b93d64bb5a4bdae84039321988ef70bba8e63ee1ae +-9y-fZ3swSY/0,-9y-fZ3swSY,0,text,6.8333330154418945,3.536603624001146,22,768,69,0.1,768,0.5440928339958191,ok,29a1fd181293cdbe24e50edcad51e3cc0f27a5824d840bcc39d453b272fb6e3c +-9y-fZ3swSY/0,-9y-fZ3swSY,0,audio,6.8333330154418945,6.794324037513217,676,74,69,0.1,74,0.9948647022247314,ok,29a1fd181293cdbe24e50edcad51e3cc0f27a5824d840bcc39d453b272fb6e3c +-9y-fZ3swSY/0,-9y-fZ3swSY,0,vision,6.8333330154418945,6.8333330154418945,57,35,69,0.1,35,1.0,ok,29a1fd181293cdbe24e50edcad51e3cc0f27a5824d840bcc39d453b272fb6e3c +-9y-fZ3swSY/4,-9y-fZ3swSY,4,text,2.8210289478302,1.160462707281113,9,768,29,0.1,768,0.5274830460548401,ok,fe04a26710e85c58bdaad5a48618c7e0f742d82b0d920eb4a046c8f14a6921dc +-9y-fZ3swSY/4,-9y-fZ3swSY,4,audio,2.8210289478302,2.7937038478819103,267,74,29,0.1,74,0.9926167726516724,ok,fe04a26710e85c58bdaad5a48618c7e0f742d82b0d920eb4a046c8f14a6921dc +-9y-fZ3swSY/4,-9y-fZ3swSY,4,vision,2.8210289478302,2.7210289478302006,15,35,29,0.1,35,1.0,ok,fe04a26710e85c58bdaad5a48618c7e0f742d82b0d920eb4a046c8f14a6921dc +-9y-fZ3swSY/8,-9y-fZ3swSY,8,text,4.988996982574463,2.1943973237220367,12,768,50,0.1,768,0.562736988067627,ok,6140d031e614b62a5d8df73346fef2417c28cee3501310aa95aa40d358b4b256 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,audio,4.988996982574463,4.9497673825665816,492,74,50,0.1,74,0.9931800365447998,ok,6140d031e614b62a5d8df73346fef2417c28cee3501310aa95aa40d358b4b256 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,vision,4.988996982574463,3.688997030258178,37,35,50,0.1,35,0.9487179517745972,ok,6140d031e614b62a5d8df73346fef2417c28cee3501310aa95aa40d358b4b256 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,text,22.511003494262695,12.134252551943066,41,768,226,0.1,768,0.6386448740959167,ok,e09034b30bb4f8fb9f9c2568afc20f2a764e327fe6ef4e13f21804eaac51bb7b +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,audio,22.511003494262695,22.31367928599184,2241,74,226,0.1,74,0.9917553663253784,ok,e09034b30bb4f8fb9f9c2568afc20f2a764e327fe6ef4e13f21804eaac51bb7b +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,vision,22.511003494262695,22.511003494262695,144,35,226,0.1,35,1.0,ok,e09034b30bb4f8fb9f9c2568afc20f2a764e327fe6ef4e13f21804eaac51bb7b +-HeZS2-Prhc/2,-HeZS2-Prhc,2,text,8.261979103088379,3.552112135011702,16,768,83,0.1,768,0.6830984950065613,ok,edb0fa22fdfbd990c8174764af78670bd2ecad799240d35d96a1124a3cd9dc0c +-HeZS2-Prhc/2,-HeZS2-Prhc,2,audio,8.261979103088379,8.205439110059995,816,74,83,0.1,74,0.9933875799179077,ok,edb0fa22fdfbd990c8174764af78670bd2ecad799240d35d96a1124a3cd9dc0c +-HeZS2-Prhc/2,-HeZS2-Prhc,2,vision,8.261979103088379,8.261979103088379,70,35,83,0.1,35,1.0,ok,edb0fa22fdfbd990c8174764af78670bd2ecad799240d35d96a1124a3cd9dc0c +-MeTTeMJBNc/0,-MeTTeMJBNc,0,text,9.300000190734863,4.416411150246859,21,768,94,0.1,768,0.6400595903396606,ok,54e2097f7bdb455d243e72254e5af7ed16160739f2f3cfd22f57d2729ec1acbe +-MeTTeMJBNc/0,-MeTTeMJBNc,0,audio,9.300000190734863,9.216486695006088,922,74,94,0.1,74,0.9939717650413513,ok,54e2097f7bdb455d243e72254e5af7ed16160739f2f3cfd22f57d2729ec1acbe +-MeTTeMJBNc/0,-MeTTeMJBNc,0,vision,9.300000190734863,9.200000190734862,78,35,94,0.1,35,1.0,ok,54e2097f7bdb455d243e72254e5af7ed16160739f2f3cfd22f57d2729ec1acbe +-MeTTeMJBNc/13,-MeTTeMJBNc,13,text,5.430013179779053,2.997564935684203,14,768,55,0.1,768,0.6661255359649658,ok,80c5d996e5d7b61c58e1fe32d706efcaf80c8c8cddb5c37a5c66d527786c2a44 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,audio,5.430013179779053,5.368323606413764,526,74,55,0.1,74,0.9918515682220459,ok,80c5d996e5d7b61c58e1fe32d706efcaf80c8c8cddb5c37a5c66d527786c2a44 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,vision,5.430013179779053,5.430013179779053,41,35,55,0.1,35,1.0,ok,80c5d996e5d7b61c58e1fe32d706efcaf80c8c8cddb5c37a5c66d527786c2a44 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,text,10.51699161529541,6.728291415888818,31,768,106,0.1,768,0.7313360571861267,ok,40716dc7402fd6398038eded58ce939ec76be6afbeea346b968bf4c427088f3a +-MeTTeMJBNc/7,-MeTTeMJBNc,7,audio,10.51699161529541,10.441329748243898,1042,74,106,0.1,74,0.9934103488922119,ok,40716dc7402fd6398038eded58ce939ec76be6afbeea346b968bf4c427088f3a +-MeTTeMJBNc/7,-MeTTeMJBNc,7,vision,10.51699161529541,10.51699161529541,84,35,106,0.1,35,1.0,ok,40716dc7402fd6398038eded58ce939ec76be6afbeea346b968bf4c427088f3a +-RfYyzHpjk4/11,-RfYyzHpjk4,11,text,5.238996982574463,3.062753976881504,17,768,53,0.1,768,0.6960803866386414,ok,96e481cd732001239639c8cb4e7f94e570925e5a15940920ffab0cec1f13f904 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,audio,5.238996982574463,5.202267333462432,508,74,53,0.1,74,0.9958056807518005,ok,96e481cd732001239639c8cb4e7f94e570925e5a15940920ffab0cec1f13f904 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,vision,5.238996982574463,5.238996982574463,40,35,53,0.1,35,1.0,ok,96e481cd732001239639c8cb4e7f94e570925e5a15940920ffab0cec1f13f904 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,text,4.588996887207031,2.8058770607668286,17,768,46,0.1,768,0.684955358505249,ok,ed8c672c532b8c7d1c830c82d6e2c14fcb3bbd3dc1a86670a03a6c8e83c02f3c +-RfYyzHpjk4/8,-RfYyzHpjk4,8,audio,4.588996887207031,4.553010454316745,454,74,46,0.1,74,0.994469404220581,ok,ed8c672c532b8c7d1c830c82d6e2c14fcb3bbd3dc1a86670a03a6c8e83c02f3c +-RfYyzHpjk4/8,-RfYyzHpjk4,8,vision,4.588996887207031,4.588996887207031,33,35,46,0.1,35,1.0,ok,ed8c672c532b8c7d1c830c82d6e2c14fcb3bbd3dc1a86670a03a6c8e83c02f3c +-RfYyzHpjk4/2,-RfYyzHpjk4,2,text,5.516016006469727,3.372718970850109,25,768,56,0.1,768,0.7175998091697693,ok,5e428ee22de58c9d6561b9b4353bef9dfb811a5841d9ab07b5bc453d697ad17f +-RfYyzHpjk4/2,-RfYyzHpjk4,2,audio,5.516016006469727,5.478826378849712,540,74,56,0.1,74,0.9948742389678955,ok,5e428ee22de58c9d6561b9b4353bef9dfb811a5841d9ab07b5bc453d697ad17f +-RfYyzHpjk4/2,-RfYyzHpjk4,2,vision,5.516016006469727,5.416016006469727,43,35,56,0.1,35,1.0,ok,5e428ee22de58c9d6561b9b4353bef9dfb811a5841d9ab07b5bc453d697ad17f +-UUCSKoHeMA/0,-UUCSKoHeMA,0,text,7.800000190734863,4.133793779369442,18,768,79,0.1,768,0.666740894317627,ok,3f9792888ec8e969f61cfb6cb4de7bdf7ef8944afe0a9d2a9d13586e1f13b898 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,audio,7.800000190734863,7.750270468963159,774,74,79,0.1,74,0.9943835139274597,ok,3f9792888ec8e969f61cfb6cb4de7bdf7ef8944afe0a9d2a9d13586e1f13b898 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,vision,7.800000190734863,7.700000190734862,66,35,79,0.1,35,1.0,ok,3f9792888ec8e969f61cfb6cb4de7bdf7ef8944afe0a9d2a9d13586e1f13b898 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,text,2.806999921798706,2.1131306469440463,8,768,29,0.1,768,0.7826409935951233,ok,93021c70c8fad20ad3fded80e7fc790a2f9c96835de58a3b694c6906de42684b +-ri04Z7vwnc/0,-ri04Z7vwnc,0,audio,2.806999921798706,2.8018783078000356,277,74,29,0.1,74,0.9982975125312805,ok,93021c70c8fad20ad3fded80e7fc790a2f9c96835de58a3b694c6906de42684b +-ri04Z7vwnc/0,-ri04Z7vwnc,0,vision,2.806999921798706,0.0,14,35,29,0.1,35,0.0,ok,93021c70c8fad20ad3fded80e7fc790a2f9c96835de58a3b694c6906de42684b +-ri04Z7vwnc/2,-ri04Z7vwnc,2,text,6.0269999504089355,3.9384737918153405,16,768,61,0.1,768,0.7431082725524902,ok,f5993ce3a6ee56298462c08692a96f78c7d914d7264257ed401de7d6e17fd148 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,audio,6.0269999504089355,6.008905370493193,592,74,61,0.1,74,0.9971521496772766,ok,f5993ce3a6ee56298462c08692a96f78c7d914d7264257ed401de7d6e17fd148 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,vision,6.0269999504089355,2.106416702270508,30,35,61,0.1,35,0.9906440377235413,ok,f5993ce3a6ee56298462c08692a96f78c7d914d7264257ed401de7d6e17fd148 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,text,3.5450000762939453,1.8027290821075441,9,768,36,0.1,768,0.721091628074646,ok,2a5e4319bf592a18c8eb5117f7c7ec30c6c79528f9eac9fe4fb85bf70f277736 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,audio,3.5450000762939453,3.534527108637063,344,74,36,0.1,74,0.9974266886711121,ok,2a5e4319bf592a18c8eb5117f7c7ec30c6c79528f9eac9fe4fb85bf70f277736 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,vision,3.5450000762939453,3.5450000762939453,18,35,36,0.1,35,1.0,ok,2a5e4319bf592a18c8eb5117f7c7ec30c6c79528f9eac9fe4fb85bf70f277736 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,text,4.7919921875,2.610484106093645,11,768,48,0.1,768,0.7055363059043884,ok,a33e8f82a185bcb7648b523927308cdc2142e3076479ba2b45cd0e828636fc09 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,audio,4.7919921875,4.72247887628304,465,74,48,0.1,74,0.9860281348228455,ok,a33e8f82a185bcb7648b523927308cdc2142e3076479ba2b45cd0e828636fc09 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,vision,4.7919921875,4.7919921875,35,35,48,0.1,35,1.0,ok,a33e8f82a185bcb7648b523927308cdc2142e3076479ba2b45cd0e828636fc09 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,text,6.800000190734863,3.6206328462809334,24,768,69,0.1,768,0.6351987719535828,ok,f2324dbc6debe0d1e4254e6f943523373e3cbb30d8d0555413ce3a7b370a4af5 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,audio,6.800000190734863,6.715675868979983,672,74,69,0.1,74,0.9885490536689758,ok,f2324dbc6debe0d1e4254e6f943523373e3cbb30d8d0555413ce3a7b370a4af5 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,vision,6.800000190734863,6.199999928474425,56,35,69,0.1,35,0.984375,ok,f2324dbc6debe0d1e4254e6f943523373e3cbb30d8d0555413ce3a7b370a4af5 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,text,8.561002731323242,3.4511515218298876,19,768,86,0.1,768,0.5150972604751587,ok,bd35eb8de64ce1f8b27921294598f7cf5bb971255738f51d06458c7096c58eae +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,audio,8.561002731323242,8.46259727510246,840,74,86,0.1,74,0.9896790981292725,ok,bd35eb8de64ce1f8b27921294598f7cf5bb971255738f51d06458c7096c58eae +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,vision,8.561002731323242,8.561002731323242,72,35,86,0.1,35,1.0,ok,bd35eb8de64ce1f8b27921294598f7cf5bb971255738f51d06458c7096c58eae +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,text,4.427018165588379,2.2374289706349377,9,768,45,0.1,768,0.6215080618858337,ok,76e0672ffce5857a789b41fb10606402f7da58c33579b1032a8282f86fb35bc9 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,audio,4.427018165588379,4.367301462550421,425,74,45,0.1,74,0.9892621040344238,ok,76e0672ffce5857a789b41fb10606402f7da58c33579b1032a8282f86fb35bc9 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,vision,4.427018165588379,3.027018189430237,31,35,45,0.1,35,0.96875,ok,76e0672ffce5857a789b41fb10606402f7da58c33579b1032a8282f86fb35bc9 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,text,6.966015815734863,3.9709798723459264,28,768,70,0.1,768,0.661829948425293,ok,5301f4403cf7cd299cc525d2f443392ac70fd70c3c9cd4a09406f2ba4df6734d +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,audio,6.966015815734863,6.848488390969263,684,74,70,0.1,74,0.9849807620048523,ok,5301f4403cf7cd299cc525d2f443392ac70fd70c3c9cd4a09406f2ba4df6734d +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,vision,6.966015815734863,4.0493486523628235,57,35,70,0.1,35,0.9496123194694519,ok,5301f4403cf7cd299cc525d2f443392ac70fd70c3c9cd4a09406f2ba4df6734d +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,text,2.4749999046325684,1.6227161765098577,5,768,25,0.1,768,0.8113580942153931,ok,40b684fd1b4559f0f82e72f9b47f4ce7c5e15059fe8d0d8ab112637cd3386451 +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,audio,2.4749999046325684,2.4289188214250514,232,74,25,0.1,74,0.9844902753829956,ok,40b684fd1b4559f0f82e72f9b47f4ce7c5e15059fe8d0d8ab112637cd3386451 +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,vision,2.4749999046325684,1.8999999761581425,14,35,25,0.1,35,1.0,ok,40b684fd1b4559f0f82e72f9b47f4ce7c5e15059fe8d0d8ab112637cd3386451 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,text,3.2949869632720947,1.9395141303539274,13,768,33,0.1,768,0.6465047001838684,ok,1de4d91bd9d9fb508a3779658747da88460db0bdb1beefe7ea5b2c77edfd2239 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,audio,3.2949869632720947,3.253163003921509,319,74,33,0.1,74,0.9880942702293396,ok,1de4d91bd9d9fb508a3779658747da88460db0bdb1beefe7ea5b2c77edfd2239 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,vision,3.2949869632720947,3.016666531562805,20,35,33,0.1,35,0.9731181859970093,ok,1de4d91bd9d9fb508a3779658747da88460db0bdb1beefe7ea5b2c77edfd2239 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,text,29.288021087646484,15.053765958920112,49,768,293,0.1,768,0.6873865723609924,ok,2f16da1baa8660e5bfc608f5237cdd59725d16e57a19bc02c4556cd2c7129a46 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,audio,29.288021087646484,28.759709144524624,2911,74,293,0.1,74,0.9836021065711975,ok,2f16da1baa8660e5bfc608f5237cdd59725d16e57a19bc02c4556cd2c7129a46 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,vision,29.288021087646484,27.471354246139526,178,35,293,0.1,35,0.999393880367279,ok,2f16da1baa8660e5bfc608f5237cdd59725d16e57a19bc02c4556cd2c7129a46 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,text,13.169010162353516,8.127011682093151,25,768,132,0.1,768,0.7192046046257019,ok,6d6145293cf84d1fc8324dfa8d39465e2d7fc07affb67ff68deeabf6e3c410d9 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,audio,13.169010162353516,12.971401820754682,1305,74,132,0.1,74,0.9867846369743347,ok,6d6145293cf84d1fc8324dfa8d39465e2d7fc07affb67ff68deeabf6e3c410d9 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,vision,13.169010162353516,13.169010162353516,97,35,132,0.1,35,1.0,ok,6d6145293cf84d1fc8324dfa8d39465e2d7fc07affb67ff68deeabf6e3c410d9 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,text,11.241994857788086,4.740236129239202,19,768,113,0.1,768,0.6869907975196838,ok,b51eb9ad06de804934cb6a315de591ba9ff7f8aa71bffff7f8001ab29945d989 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,audio,11.241994857788086,11.070711010679133,1125,74,113,0.1,74,0.9854583740234375,ok,b51eb9ad06de804934cb6a315de591ba9ff7f8aa71bffff7f8001ab29945d989 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,vision,11.241994857788086,11.241994857788086,87,35,113,0.1,35,1.0,ok,b51eb9ad06de804934cb6a315de591ba9ff7f8aa71bffff7f8001ab29945d989 diff --git a/math/results/model_comparison/oof_predictions.csv b/math/results/model_comparison/oof_predictions.csv new file mode 100644 index 0000000..b866563 --- /dev/null +++ b/math/results/model_comparison/oof_predictions.csv @@ -0,0 +1,101 @@ +sample_id,video_id,clip_id,true_polarity,true_polarity_name,true_sentiment,B0_predicted_polarity,B1_predicted_polarity,B2_predicted_polarity,B3_predicted_polarity,B4_predicted_polarity,B0_predicted_sentiment,B1_predicted_sentiment,B2_predicted_sentiment,B3_predicted_sentiment,B4_predicted_sentiment +-3g5yACwYnA/13,-3g5yACwYnA,13,2,positive,0.6666666865348816,2,2,2,2,2,0.13452544808387756,0.16021420061588287,0.14872726798057556,0.16442018747329712,0.229058176279068 +-3g5yACwYnA/3,-3g5yACwYnA,3,1,neutral,0.0,2,2,2,2,2,0.3026959300041199,0.33461102843284607,0.42589470744132996,0.31887251138687134,0.29829922318458557 +-3g5yACwYnA/2,-3g5yACwYnA,2,1,neutral,0.0,2,2,2,2,2,0.3966212272644043,0.46180492639541626,0.48163092136383057,0.43820273876190186,0.5120640397071838 +-3g5yACwYnA/9,-3g5yACwYnA,9,2,positive,0.6666666865348816,2,2,2,2,2,0.6833762526512146,0.7414957880973816,0.7930513024330139,0.7018600106239319,0.6162992715835571 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,1,neutral,0.0,0,0,0,0,0,-0.7614330053329468,-0.6502371430397034,-0.6979431509971619,-0.6381849050521851,-0.5865846872329712 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,1,neutral,0.0,2,2,2,2,2,0.6054284572601318,0.5735942721366882,0.6148816347122192,0.5838509798049927,0.8063328266143799 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,0,negative,-1.0,0,0,2,2,2,0.08644700050354004,-0.01681867241859436,0.054207056760787964,0.008860379457473755,0.08198326826095581 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,1,neutral,0.0,2,2,2,2,2,0.31941771507263184,0.4352392554283142,0.45426928997039795,0.40970659255981445,0.5301598310470581 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,0,negative,-0.3333333432674408,0,0,0,0,0,-0.07338133454322815,-0.14210763573646545,-0.13199511170387268,-0.13720062375068665,-0.2480643391609192 +-NFrJFQijFE/1,-NFrJFQijFE,1,2,positive,0.3333333432674408,2,2,2,2,1,-0.029091298580169678,0.04221409559249878,0.023884594440460205,0.038062989711761475,-0.10948124527931213 +-NFrJFQijFE/2,-NFrJFQijFE,2,1,neutral,0.0,2,2,2,2,2,0.5534588098526001,0.6096377372741699,0.5728316307067871,0.5841389894485474,0.6658575534820557 +-THoVjtIkeU/12,-THoVjtIkeU,12,2,positive,2.0,2,2,2,2,2,0.1105184555053711,-0.015041038393974304,0.01798933744430542,0.013076543807983398,0.05507504940032959 +-THoVjtIkeU/2,-THoVjtIkeU,2,2,positive,1.3333333730697632,2,2,2,2,2,0.14952212572097778,-0.03578713536262512,0.21528872847557068,-0.047229185700416565,0.07181030511856079 +-THoVjtIkeU/6,-THoVjtIkeU,6,2,positive,2.6666667461395264,2,2,2,2,2,0.28439241647720337,0.10436569154262543,0.19625744223594666,0.109825998544693,0.11878173053264618 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,2,positive,1.6666666269302368,2,2,2,2,2,0.05641767382621765,0.05484718084335327,0.02277640998363495,0.05113929510116577,0.011383742094039917 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,2,positive,2.6666667461395264,2,2,2,2,2,0.6992747783660889,0.6104735136032104,0.7187632918357849,0.6213169097900391,0.5144999027252197 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,2,positive,0.3333333432674408,2,2,2,2,2,0.66947340965271,0.5266174077987671,0.5624967217445374,0.5222238898277283,0.45163899660110474 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,0,negative,-0.3333333432674408,2,2,2,2,2,0.12534436583518982,0.002005934715270996,-0.03466030955314636,-0.01757238805294037,0.03905734419822693 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,2,positive,0.6666666865348816,2,2,2,2,2,0.24422422051429749,0.13229034841060638,0.1552799940109253,0.1265096515417099,0.17101362347602844 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,1,neutral,0.0,2,2,2,2,2,0.7103666663169861,0.8981346487998962,0.7498640418052673,0.908927321434021,0.7986767292022705 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,0,negative,-2.0,2,2,2,2,2,0.14777150750160217,0.2721712589263916,0.20749390125274658,0.26992136240005493,0.2557317018508911 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,2,positive,1.6666666269302368,2,2,2,2,2,0.4534122347831726,0.15173421800136566,0.23860448598861694,0.08927315473556519,0.17231377959251404 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,2,positive,1.0,2,2,2,1,2,0.30912163853645325,0.18118944764137268,0.1967533975839615,0.17624947428703308,0.20736707746982574 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,2,positive,0.6666666865348816,2,2,2,2,2,0.5904080867767334,0.34547320008277893,0.4100586771965027,0.3144497573375702,0.33179861307144165 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,2,positive,0.6666666865348816,2,2,2,2,2,0.40664565563201904,0.07521255314350128,0.0900307297706604,0.107652947306633,0.09203940629959106 +-egA8-b7-3M/26,-egA8-b7-3M,26,2,positive,1.6666666269302368,2,2,2,2,2,0.8926460146903992,0.8544832468032837,0.7031165957450867,0.8596105575561523,0.6629092693328857 +-egA8-b7-3M/17,-egA8-b7-3M,17,2,positive,0.3333333432674408,2,2,2,2,2,0.780834972858429,0.8010746240615845,0.7224219441413879,0.7491263151168823,0.7902140617370605 +-egA8-b7-3M/18,-egA8-b7-3M,18,2,positive,1.0,2,2,2,2,2,0.8284801244735718,0.8428431153297424,0.7629272937774658,0.8139240741729736,0.759922981262207 +-egA8-b7-3M/16,-egA8-b7-3M,16,2,positive,0.6666666865348816,2,2,2,2,2,1.1456997394561768,1.103100299835205,0.9217796921730042,1.0922913551330566,0.9465919733047485 +-egA8-b7-3M/13,-egA8-b7-3M,13,2,positive,0.3333333432674408,2,2,2,2,2,0.29149097204208374,0.2857578694820404,0.29504942893981934,0.2710241973400116,0.433204710483551 +-egA8-b7-3M/1,-egA8-b7-3M,1,2,positive,0.6666666865348816,2,2,2,2,2,0.49869486689567566,0.5516833662986755,0.4600910544395447,0.5341068506240845,0.5454411506652832 +-egA8-b7-3M/6,-egA8-b7-3M,6,2,positive,0.6666666865348816,2,2,2,2,2,0.8187044262886047,0.8529066443443298,0.7433335781097412,0.8614661693572998,0.7032537460327148 +-egA8-b7-3M/9,-egA8-b7-3M,9,2,positive,0.3333333432674408,2,2,2,2,2,0.746141791343689,0.755176305770874,0.7585423588752747,0.7326465845108032,0.7642356157302856 +-egA8-b7-3M/20,-egA8-b7-3M,20,2,positive,0.3333333432674408,2,2,2,2,2,0.75407874584198,0.783722460269928,0.7880091667175293,0.7994571924209595,0.7963440418243408 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,2,positive,0.6666666865348816,2,2,2,2,2,0.41121792793273926,0.26391637325286865,0.16125774383544922,0.30018502473831177,0.22292546927928925 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,2,positive,0.6666666865348816,2,2,2,2,2,0.6934136152267456,0.5427778959274292,0.5866559743881226,0.5839468240737915,0.5824995636940002 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,2,positive,0.3333333432674408,2,2,2,2,2,0.4273873567581177,0.3189065456390381,0.3010154962539673,0.3516676127910614,0.32149577140808105 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,2,positive,1.3333333730697632,2,2,1,2,2,0.01312372088432312,-0.0918610543012619,0.1977950930595398,-0.06410297751426697,-0.14683973789215088 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,2,positive,1.0,2,2,2,2,2,0.45394086837768555,0.2737142741680145,0.34107109904289246,0.34081369638442993,0.36690521240234375 +-lzEya4AM_4/5,-lzEya4AM_4,5,0,negative,-0.6666666865348816,2,1,1,1,2,0.003696233034133911,0.07954774796962738,-0.02835392951965332,0.06377251446247101,0.0930773913860321 +-lzEya4AM_4/6,-lzEya4AM_4,6,0,negative,-0.3333333432674408,1,1,1,1,1,-0.08578968048095703,-0.05591443181037903,-0.16103187203407288,-0.07273416221141815,-0.03954911231994629 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,1,neutral,0.0,2,2,2,2,1,0.32054486870765686,0.31638309359550476,0.4096267521381378,0.32599377632141113,0.11944134533405304 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,1,neutral,0.0,2,2,2,2,1,0.3205912411212921,0.2857860326766968,0.32545098662376404,0.2961588501930237,0.07219411432743073 +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,2,positive,0.3333333432674408,2,2,2,2,2,0.34881988167762756,0.2555202841758728,0.19199120998382568,0.22443163394927979,0.11697705090045929 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,1,neutral,0.0,2,2,2,2,2,0.49129533767700195,0.509657621383667,0.40949302911758423,0.49832504987716675,0.3923254609107971 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,0,negative,-0.3333333432674408,0,0,0,0,0,0.033514365553855896,-0.12224322557449341,0.015729933977127075,-0.13064196705818176,-0.10159948468208313 +-mqbVkbCndg/0,-mqbVkbCndg,0,1,neutral,0.0,2,2,2,2,2,-0.09232228994369507,-0.27456536889076233,-0.23857474327087402,-0.2712118625640869,-0.06543052196502686 +-t217m2on-s/2,-t217m2on-s,2,2,positive,0.6666666865348816,2,2,2,2,2,0.4828706979751587,0.4535056948661804,0.48303860425949097,0.4338659644126892,0.29441648721694946 +-t217m2on-s/7,-t217m2on-s,7,0,negative,-0.6666666865348816,2,2,2,2,2,0.03153911232948303,0.12483498454093933,0.23645390570163727,0.14657872915267944,0.2676320970058441 +-tANM6ETl_M/3,-tANM6ETl_M,3,2,positive,0.3333333432674408,2,2,2,2,2,0.13329337537288666,0.27301740646362305,0.20109084248542786,0.23898470401763916,0.2801833152770996 +-tPCytz4rww/11,-tPCytz4rww,11,1,neutral,0.0,2,2,2,2,2,0.39490315318107605,0.41642117500305176,0.5103898644447327,0.40319329500198364,0.5221617221832275 +-tPCytz4rww/10,-tPCytz4rww,10,1,neutral,0.0,2,2,2,2,2,0.45396602153778076,0.48757827281951904,0.39305949211120605,0.48652955889701843,0.5163553357124329 +-tPCytz4rww/12,-tPCytz4rww,12,1,neutral,0.0,2,2,2,2,2,0.4888620376586914,0.47673290967941284,0.523354709148407,0.47867047786712646,0.5164443254470825 +-tPCytz4rww/16,-tPCytz4rww,16,1,neutral,0.0,2,2,2,2,2,0.16386589407920837,0.1889176368713379,0.15202002227306366,0.20772001147270203,0.10384060442447662 +-tPCytz4rww/18,-tPCytz4rww,18,1,neutral,0.0,2,2,2,2,2,0.39335885643959045,0.48845911026000977,0.4801775813102722,0.49252307415008545,0.5596518516540527 +-vxjVxOeScU/4,-vxjVxOeScU,4,2,positive,1.0,2,2,2,2,2,1.300539255142212,1.3340058326721191,1.3243328332901,1.3665581941604614,1.3101918697357178 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,2,positive,0.3333333432674408,2,2,2,2,2,0.43083706498146057,0.3697093427181244,0.3281114399433136,0.3639947175979614,0.4309353828430176 +-wny0OAz3g8/1,-wny0OAz3g8,1,2,positive,0.3333333432674408,2,2,2,2,2,-0.029849499464035034,-0.0726122260093689,-0.024748489260673523,-0.07751013338565826,0.01515229046344757 +-wny0OAz3g8/0,-wny0OAz3g8,0,2,positive,0.3333333432674408,1,1,1,1,1,-0.26475363969802856,-0.4248991906642914,-0.3667675256729126,-0.43525469303131104,-0.2892696261405945 +-wny0OAz3g8/3,-wny0OAz3g8,3,0,negative,-1.3333333730697632,2,2,2,2,2,-0.03229987621307373,0.011097535490989685,-0.044357895851135254,0.014330193400382996,0.1011495590209961 +-wny0OAz3g8/2,-wny0OAz3g8,2,0,negative,-0.3333333432674408,2,2,2,2,2,0.0680823028087616,0.020685836672782898,0.1548982560634613,0.049939438700675964,0.12679153680801392 +-wny0OAz3g8/5,-wny0OAz3g8,5,2,positive,1.0,2,2,2,2,2,0.4779983460903168,0.42994704842567444,0.3525465130805969,0.4249609410762787,0.4561484158039093 +-wny0OAz3g8/7,-wny0OAz3g8,7,1,neutral,0.0,2,2,2,2,2,0.14757554233074188,0.11216723173856735,0.15002727508544922,0.10439274460077286,0.08023504912853241 +-wny0OAz3g8/9,-wny0OAz3g8,9,2,positive,0.6666666865348816,2,2,2,2,2,0.18945443630218506,0.2243257611989975,0.255195677280426,0.2078581154346466,0.26747772097587585 +-571d8cVauQ/0,-571d8cVauQ,0,1,neutral,0.0,1,1,1,1,1,0.1813371479511261,0.26319703459739685,0.20845845341682434,0.2597145736217499,0.2923925817012787 +-571d8cVauQ/5,-571d8cVauQ,5,2,positive,0.3333333432674408,2,2,2,2,2,0.7947983145713806,0.8263474702835083,0.8470317125320435,0.8056427836418152,0.7695794105529785 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,0,negative,-0.6666666865348816,1,1,2,1,2,-0.053890615701675415,0.05120442807674408,0.14258822798728943,0.058895498514175415,-0.0020049959421157837 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,2,positive,0.6666666865348816,2,2,2,2,2,0.20941728353500366,0.2584538459777832,0.3930857181549072,0.27197059988975525,0.3383082151412964 +-UacrmKiTn4/10,-UacrmKiTn4,10,0,negative,-0.6666666865348816,2,2,2,2,2,-0.007775545120239258,0.10976105183362961,0.2304498553276062,0.1546456217765808,0.1571420133113861 +-UacrmKiTn4/4,-UacrmKiTn4,4,0,negative,-1.3333333730697632,2,2,2,2,2,0.24989673495292664,0.44462817907333374,0.4752929210662842,0.4392329156398773,0.5184646844863892 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,2,positive,0.6666666865348816,2,2,2,2,2,0.25469517707824707,0.267363965511322,0.26611560583114624,0.2937210500240326,0.4176241457462311 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,2,positive,1.0,2,2,2,2,2,0.7116098403930664,0.6368920803070068,0.8011423349380493,0.6396559476852417,0.7429358959197998 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,2,positive,1.3333333730697632,2,2,2,2,2,1.4230821132659912,1.456520915031433,1.482230544090271,1.4008221626281738,1.3085699081420898 +-uywlfIYOS8/4,-uywlfIYOS8,4,2,positive,0.3333333432674408,2,2,2,2,2,0.6702563762664795,0.7197655439376831,0.6297314763069153,0.7727823257446289,0.7619336843490601 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,0,negative,-1.0,2,2,2,2,2,0.23289291560649872,0.10650955140590668,-0.048172906041145325,0.1659325510263443,0.07517096400260925 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,2,positive,1.0,2,2,2,2,2,0.8935344815254211,0.981560468673706,1.0655876398086548,0.9575732946395874,0.960616946220398 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,1,neutral,0.0,2,2,2,2,1,0.7359274625778198,0.8043063282966614,0.8141930103302002,0.8211376667022705,0.801345944404602 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,2,positive,1.6666666269302368,2,2,2,2,2,0.0990075170993805,0.17485348880290985,0.26351824402809143,0.15360157191753387,0.2083582729101181 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,2,positive,0.6666666865348816,2,2,2,2,2,0.9318890571594238,1.1048165559768677,1.1751078367233276,1.091732382774353,0.7978025078773499 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,2,positive,0.6666666865348816,2,2,2,2,2,0.42690128087997437,0.37649014592170715,0.3945169448852539,0.3838789463043213,0.30630016326904297 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,2,positive,0.3333333432674408,2,2,2,2,2,0.5873996019363403,0.4888506829738617,0.520802915096283,0.4796018600463867,0.48370563983917236 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,2,positive,0.3333333432674408,2,2,2,2,2,0.681941032409668,0.7230368852615356,0.6091403365135193,0.7292149662971497,0.745182454586029 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,2,positive,1.3333333730697632,2,2,2,2,2,0.5029646158218384,0.47240275144577026,0.5074828863143921,0.46745914220809937,0.47605717182159424 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,2,positive,2.0,2,2,2,2,2,0.5564365983009338,0.42342162132263184,0.5021690726280212,0.43483608961105347,0.43543678522109985 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,2,positive,0.3333333432674408,2,2,2,2,2,0.3994223177433014,0.3921676576137543,0.2823079228401184,0.40095123648643494,0.42251622676849365 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,2,positive,0.3333333432674408,2,2,2,2,1,0.365897536277771,0.38750067353248596,0.23726055026054382,0.3845585286617279,0.21417461335659027 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,1,neutral,0.0,2,2,2,2,2,0.5638669729232788,0.5825111269950867,0.6482444405555725,0.5764590501785278,0.5579362511634827 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,1,neutral,0.0,2,2,2,2,1,0.26682645082473755,0.1752839833498001,0.11657405644655228,0.17440180480480194,-0.12501448392868042 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,0,negative,-0.3333333432674408,2,2,2,2,1,0.41648173332214355,0.39698678255081177,0.31453409790992737,0.42282843589782715,-0.06992921233177185 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,2,positive,0.3333333432674408,2,2,2,2,2,0.7894954681396484,0.9298861026763916,0.8353837132453918,0.9478996992111206,0.9307202100753784 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,2,positive,0.6666666865348816,2,2,2,2,2,0.8451777696609497,0.7406796216964722,0.6926915645599365,0.7564423084259033,0.7351438403129578 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,0,negative,-0.3333333432674408,2,2,2,2,0,0.08492019772529602,0.08116327226161957,0.09997616708278656,0.09164288640022278,-0.18887805938720703 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,0,negative,-2.0,2,0,2,0,2,0.25190818309783936,0.23056381940841675,0.42701321840286255,0.2685755491256714,0.35108593106269836 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,1,neutral,0.0,2,2,2,2,2,0.8093756437301636,0.6910800933837891,0.8017246723175049,0.6906447410583496,0.7730451822280884 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,2,positive,1.0,2,2,2,2,1,0.04829922318458557,-0.06272962689399719,0.04885163903236389,-0.056273818016052246,-0.3453366756439209 +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,1,neutral,0.0,2,2,2,2,2,-0.11959794163703918,0.12442992627620697,0.22614140808582306,0.12353259325027466,0.05900001525878906 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,2,positive,1.3333333730697632,2,2,2,2,1,0.5094736218452454,0.4484489858150482,0.6055055856704712,0.42063793540000916,0.0980398952960968 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,1,neutral,0.0,0,0,0,0,0,-0.39470893144607544,-0.5162537693977356,-0.5732794404029846,-0.5318436622619629,-0.47799739241600037 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,0,negative,-0.6666666865348816,1,1,1,1,1,-0.31519562005996704,-0.4650754928588867,-0.48384714126586914,-0.4728321433067322,-0.4012225568294525 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,1,neutral,0.0,0,0,0,0,0,-0.3192596435546875,-0.48287540674209595,-0.5565515160560608,-0.4418525695800781,-0.5206273794174194 diff --git a/math/results/model_comparison/report.md b/math/results/model_comparison/report.md new file mode 100644 index 0000000..31c0135 --- /dev/null +++ b/math/results/model_comparison/report.md @@ -0,0 +1,61 @@ +# 问题一 B0-B4 模型对比结果 + +本报告按 `math/问题一.pdf` 第 4.8.3 节实施五组单因素对照。全部 100 条附件一视频均使用同一套冻结特征抽取器、0.1 秒主时间网格、观测掩码与按 `video_id` 分组的五折划分。情感标签仅用于折内的轻量预测探针,不进入时间对齐、CTC 后验或动态签名计算。 + +## 实际特征和比较版本 + +| 版本 | 实施内容 | +| --- | --- | +| B0 | CTC Viterbi 词区间与音频/视觉物理时间区间投影;训练折均值/标准差缩放;视觉旋转向量和视线向量作普通分量均值。 | +| B1 | 在 B0 上改用训练折中位数与 MAD 的稳健尺度(MAD 为零时回退到训练折标准差),并对视觉旋转用 SO(3) 均值、视线用归一化向量均值。 | +| B2 | 在 B1 上只将文本词向量的硬边界投影替换为固定转写 CTC 状态图的前向–后向占据概率投影;媒体时间戳仍按物理时间。 | +| B3 | 在 B1 上仅附加音频 log-F0/能量与视觉 jaw-open/嘴部开合率的时间增广一、二阶路径签名;缺测点之间不连线。 | +| B4 | 在 B1 上仅附加冻结 Wav2Vec2-base-960h 最后四层的时间投影表示。 | + +附件一现有标签表和原始视频被直接使用。文本为 768 维 BERT-base-uncased 末四层均值;音频为 74 维(log-Mel 40、MFCC 13、ΔMFCC 13、韵律/谱统计 8);视觉为 35 维(17 个 MediaPipe blendshape 代理、6 维头姿、6 维近似视线、6 维面部比例几何)。视觉代理和几何索引定义见 `compare_models.py`,它们与 OpenFace AU 定义并不等同;该限制须在论文中明示。 + +## 结果 + +分类按连续标签的严格符号构造 Negative/Neutral/Positive,强度预测限幅到 [-3, 3]。每折训练折单独拟合标准化器、逻辑回归(C=0.05)与 Ridge(alpha=25);固定五折由 GroupKFold 按原始 `video_id` 分组。总体 OOF 指标按 100 条留组预测计算。 + +| 方法 | OOF Accuracy | OOF Macro-F1 | OOF MAE | OOF Pearson | Macro-F1 折均值±SD | +| --- | ---: | ---: | ---: | ---: | ---: | +| B0 | 0.600 | 0.361 | 0.564 | 0.346 | 0.337 ± 0.098 | +| B1 | 0.610 | 0.387 | 0.599 | 0.238 | 0.349 ± 0.119 | +| B2 | 0.580 | 0.331 | 0.588 | 0.279 | 0.313 ± 0.087 | +| B3 | 0.590 | 0.359 | 0.600 | 0.230 | 0.333 ± 0.096 | +| B4 | 0.600 | 0.422 | 0.593 | 0.199 | 0.398 ± 0.089 | + +按当前 OOF 探针,Macro-F1 最高的是 B4(0.422),MAE 最低的是 B0(0.564)。相对 B1,B4 的 Macro-F1 差为 +0.035,视频组 Bootstrap 95% 区间 [-0.051, +0.137],区间跨过零。B0 的 MAE 差为 -0.035,区间 [-0.063, -0.012],Pearson 差为 +0.108。B2 的 Macro-F1 差为 -0.057,区间 [-0.109, -0.001],MAE 差为 -0.011;B3 的 Macro-F1 差为 -0.029,区间 [-0.072, +0.000]。组 Bootstrap 只反映当前 37 个来源视频上的抽样不确定性,未作多重比较校正。 + +## 覆盖与对齐核验 + +样本数:100;标签表连续标签与极性一致 100/100;CTC 硬对齐完整的样本 91/100。B0 硬区间平均文本覆盖率为 0.673,B2 平均词占据后验质量为 0.229(这是期望占据率,不是覆盖率);视觉检测覆盖率(按 0.1 秒网格平均)为 0.859。后验内部 90% 边界区间平均宽度为起点 0.131 秒、终点 0.111 秒。没有人工边界子集,因此这些宽度只是模型内部不确定性摘要,不是经验校准率或边界误差。 + +B0–B4 的特征来源、有效掩码、连续覆盖率、词边界后验宽度、折内预测及视频哈希均分别保存在配套 CSV/JSON 中。没有人工词边界时不报告 IoU/MATE,也不把不同方法的预测探针分数解释为对齐真值。 + +## 文件 + +- `comparison_summary.csv`:五种方法总体 OOF 与折均值指标。 +- `fold_metrics.csv`:每折分类/回归指标与特征维数。 +- `oof_predictions.csv`:每条样本的留组预测。 +- `group_bootstrap_deltas.csv`:相对 B1 的视频组配对 Bootstrap 95% 区间。 +- `sample_alignment_summary.csv`:100 条样本、硬/概率文本覆盖和后验边界宽度。 +- `modality_summary.csv`:300 行样本-模态明细。 +- `word_alignment_posterior.csv`:逐词硬边界、实际相对质量权重及后验边界区间。 +- `split_assignments.csv`:逐样本折号。 +- `comparison.png`:核心 OOF 指标图。 +- `typical_alignment_example.png`:中位时长样本的词边界、覆盖率、声学/视觉轨迹与视频帧核验图。 +- `run_manifest.json`:环境、模型 revision、参数、哈希与运行时间。 + +## 复现 + +在仓库根目录执行: + +```bash +cd math +uv sync +uv run python compare_models.py +``` + +特征缓存写在 `math/cache/native/`,正式结果只写在 `math/results/model_comparison/`。删除缓存后会从附件一重新提取。首次运行需要下载 BERT、Wav2Vec2 和 MediaPipe Face Landmarker 权重。 diff --git a/math/results/model_comparison/run_manifest.json b/math/results/model_comparison/run_manifest.json new file mode 100644 index 0000000..6e41f14 --- /dev/null +++ b/math/results/model_comparison/run_manifest.json @@ -0,0 +1,293 @@ +{ + "created_at_local": "2026-09-23 22:17:06 +0800", + "python": "3.14.7 (main, Aug 10 2026, 00:00:00) [GCC 16.1.1 20260515 (Red Hat 16.1.1-2)]", + "platform": "Linux-6.6.87.2-microsoft-standard-WSL2-x86_64-with-glibc2.43", + "uv_version": "uv 0.11.28 (x86_64-unknown-linux-gnu)", + "packages": { + "torch": "2.14.0+cu130", + "transformers": "5.17.0", + "numpy": "2.5.3", + "scipy": "1.18.1", + "scikit-learn": "1.9.1", + "mediapipe": "1.0.1", + "opencv-python-headless": "5.0.0.93", + "openpyxl": "3.1.5", + "matplotlib": "3.11.2" + }, + "device": "cuda", + "cuda_available": true, + "gpu_name": "NVIDIA GeForce RTX 5070 Ti", + "models": { + "text_id": "google-bert/bert-base-uncased", + "text_revision": "86b5e0934494bd15c9632b12f734a8a67f723594", + "speech_id": "facebook/wav2vec2-base-960h", + "speech_revision": "22aad52d435eb6dbaf354bdad9b0da84ce7d6156", + "speech_stride_samples": 320, + "speech_receptive_field_samples": 400 + }, + "face_landmarker_asset_sha256": "64184e229b263107bc2b804c6625db1341ff2bb731874b0bcc2fe6544e0bc9ff", + "inputs": { + "label_file": "/home/gloamxun/modeling_zhaocui/E题数据/附件1-数据集原始多模态样本/MOSEI数据集部分原始视频-100条/label-100.xlsx", + "label_file_sha256": "827334f782b1f242c84ad944a657bc7f7c63643f71ae9c977811a3eecdd3ab33", + "sample_count": 100, + "video_sha256_by_sample": { + "-3g5yACwYnA/13": "aeb47627f59dce3d0a85a44ef35e4a3bc18211498e98c8c11cf60269646df24f", + "-3g5yACwYnA/3": "eff8cfefba2425155f2b72656829b34b23be8bfe1dcbece384154f56818aa26d", + "-3g5yACwYnA/2": "0619c01f137d017c15c058176f18a575919189c7e81ebd2bfb993afdb86f3de7", + "-3g5yACwYnA/9": "b962573b12ed1f06d5533f6427c80dce2bae3a99dd332f6d3fcb32c579f3f016", + "-3nNcZdcdvU/5": "7ea53ad502b77be7d2ee4494dc23a9478c897792203cf887d546e83d584c1728", + "-HwX2H8Z4hY/2": "920a1052c09ebd1eedba6dd1ccfecd80f56f6f0fdcdd1f6dd32b0d90bcb89358", + "-HwX2H8Z4hY/5": "8d61b7f5840a8bd403d9bc6c3cd49029ffc4e304cf9c7834735c1a6bb5fd369d", + "-HwX2H8Z4hY/6": "696576dcbd0dc42cb678fa40d8a0f0f419a3072bfa7662d653756ab29bba4c46", + "-HwX2H8Z4hY/9": "90c18e627f27a12c14e21ba24c79edf3008762b4ac26874b490ad3f888381702", + "-NFrJFQijFE/1": "d8fcf16c6eb51c56947ec3d0549c6f3bc7a0cf1fc5f5d89e8b38d4249a08db4f", + "-NFrJFQijFE/2": "a54a5c144a64f5abd26b19aafa6cea8142ee08e9385fa508fa70c934f6b616c1", + "-THoVjtIkeU/12": "e2f148f4f2e74724dc13b3ce870a0ce6a06740cfc224f5a9b3d0a870b196e7d4", + "-THoVjtIkeU/2": "35a6c2464ffd68dd96411edb5dc2763f0efb59f264c1d8b737e616fa6b0d1d5b", + "-THoVjtIkeU/6": "efaa55ee6394032c867046690a92c29edfd825005f0a090cca5ccb763b227f64", + "-UuX1xuaiiE/1": "d5bbda38fcec15817d2b87bab5dcc559d6d425f7d28a82e6c32d13f14b48650c", + "-UuX1xuaiiE/0": "f578b305d53bc152702f5e771de0fcd12d1e9aaefc5cefce3d2082a417aab7c8", + "-UuX1xuaiiE/3": "eddb408f25bdc13e6de2fb74caeed709cb7a8f00640e7897135330437f66a2aa", + "-UuX1xuaiiE/6": "f0131ac00e44410fbd32c547a0d421c2791172434fc0203bb969abe14a530532", + "-a55Q6RWvTA/3": "15d029fc15f50b268b98f1e8abc65e45582e638c13a018d7aa74a18373275946", + "-aNfi7CP8vM/7": "0b6389f45bb966113c65a11998c6e7facdd24c8c42acf2e8cf32e0f2139402e1", + "-aqamKhZ1Ec/0": "6f6e674bbba4353399e9e7825217f37e6d8ca1adf9675f33cf37106f31c55548", + "-dxfTGcXJoc/1": "b5ffdc98a4a98b8f0aae55dee5fed66a43bcb129f47a250a004c1cc74e572595", + "-dxfTGcXJoc/0": "04bd0be907fb46c613f926fe1b06bc2c3b30881c293156510baa34a4105ade55", + "-dxfTGcXJoc/2": "46a5e523b5dd00364c99a3bcbc6fae4c80e1382a84b5b5e681c46eb074ed10f7", + "-dxfTGcXJoc/6": "55c1ff86729ab21da743a5107ed07b220e41b4193cd1c0ba9f009e65c3ab0513", + "-egA8-b7-3M/26": "11f78aed680ea9c5862a15e04ff6c1f8776c46d29c98b68d28773ff39d959685", + "-egA8-b7-3M/17": "f967e81e0edd51c3700671721afb3fbecbbc32652f27d2db40ea444e8d80c68f", + "-egA8-b7-3M/18": "fd4bc95a6adfb16a9588b7ed65cc2812186ce3d607804dc76f4486312951ef90", + "-egA8-b7-3M/16": "4c015f85e3bd901ecedde8c0c2ca4a756d9a77dfe4177625c481581f2037ff9c", + "-egA8-b7-3M/13": "cbd627c225ebca37521ae238cb9ec254cad236822f4f37ebfbb039e6c56aea4c", + "-egA8-b7-3M/1": "589a7989b1b4888568c31614a2d6beefba88fb87289c85b94df2d8051500403b", + "-egA8-b7-3M/6": "2e88a00d5e55863aa956b4b0949fc0e4f2975ccfd83b3194957f6fca86ecfce0", + "-egA8-b7-3M/9": "bcd643f328616312eae9b28e6c9aabbe8acaec3e4c4be58daeb45e3eee4d973c", + "-egA8-b7-3M/20": "719ef133920e74b3ea33925d2bca0270b062199116867568f88ac83cadcd74e8", + "-iRBcNs9oI8/3": "39c547acd1a8da2ebc6c6ab008191a5676420398a974cd9611cad087f0ccec50", + "-iRBcNs9oI8/7": "cc7b1c7a06ec41d72007b5c42fb8036f30b66d5cf76e3f093160c22fc5e38081", + "-iRBcNs9oI8/6": "030b0b8d8d4ae47799432ab71b66fcc881f077c5b0feef892c1f146dc0a592e3", + "-iRBcNs9oI8/9": "352bdcc73d3622d6abac1b09f2039b211d15b9bf7acee66f0b07783c9b7a4c74", + "-iRBcNs9oI8/8": "72a49e3da2862addcde033bd2fbae957d086533664ca4dcbccd3a851bcd50412", + "-lzEya4AM_4/5": "3b74de8d0e66fd754594f05985e5af3480adcc03555f79225d3b727cb4bed043", + "-lzEya4AM_4/6": "ff5da5afb551001d58100ed2471caea51c741046d5396957efbf40082307ca18", + "-mJ2ud6oKI8/1": "c8e3acb4ca08679796c4c8cdfcd8c2b3cffc0465015efaffa1eccdb55ff4f45b", + "-mJ2ud6oKI8/2": "c41790f8b75f886bd1f5d6d72cbab1985306d0b715e5ae47203f3d0c8a3e7b28", + "-mJ2ud6oKI8/6": "134a3a4ebbc423760133b0da0e90cfe84d75ea85df3968000afd84153c5d828d", + "-mJ2ud6oKI8/9": "df3442f3ed8f894b507923e87e426ae9636790a4a502d00c350a215270cc3e47", + "-mJ2ud6oKI8/8": "6af6614c9838417a48c4817f4dd5bf1e6669eb5f78f983e9a68adc113fcdc7cc", + "-mqbVkbCndg/0": "cdeba953bba30907814acf72f3e35582dec263eaa25bdd922dad7fafe02e4dda", + "-t217m2on-s/2": "6713a983112173204502dc5adbb886bc6c38554b4627698611931420c47663a8", + "-t217m2on-s/7": "41c76b8a733ecb780d56348f55d00f0ba0c07f44f46e93044e62d876710180b7", + "-tANM6ETl_M/3": "6d3af064c060dad3816a9e1dfa00101faebd8b7da7d8ceea85b0bc0fca70abd6", + "-tPCytz4rww/11": "6dc09d02467baaef67594ff32cffb01f8ed1565cda4c5abd161b8261a51e2e5d", + "-tPCytz4rww/10": "758183192cbd5f0f20823d26ece3ddee40dec0aadec35247b2495510a53f52f8", + "-tPCytz4rww/12": "e3c7f9cd67ad2d20fef997696dc278361f97f027db58762e22104e5720d509d5", + "-tPCytz4rww/16": "8b3f82f9628792eebaf8c227becc2ebeba59bb8abb668bcca86e07fb1a992a93", + "-tPCytz4rww/18": "eece70451e9c37a4b5f375bf646f66e09113fe3467f35bf1720cc14d986c1776", + "-vxjVxOeScU/4": "00282df9a314394f19d616d561bd1916d1d30dca4c814dfb43630ca164f4c719", + "-wMB_hJL-3o/7": "04a73d73fd150b07edab8e652fd14c9cb4a0f6e017ea97b17e8146e377b9fae7", + "-wny0OAz3g8/1": "c5535859f129ce04da5f5b5104d02d4168057b9d947a5349d423278ad4f3d8e8", + "-wny0OAz3g8/0": "1cc21b4432e2f4b592284ee40558a18acc7d208019117aebdb2f6a1b67ea198d", + "-wny0OAz3g8/3": "ea917c506bc9fa39460f2b722f7c416f646312bb17cd74baa618905b54837bce", + "-wny0OAz3g8/2": "1825fb37db2e914fb616cd80aebd613afd873eecb7edd4d0b53158bfda0e522a", + "-wny0OAz3g8/5": "6c6a8a4cba654b25190ab1793bfae81c3d2159ecd6cbc02d3fcbd598543acce0", + "-wny0OAz3g8/7": "cbf9cac1048ce191aef781d0c4563eb97f9f3ddd52eb1f9551fa78d31d70e7cd", + "-wny0OAz3g8/9": "b76f70fe783ee76bf1b637137226c98e67d13a6b15ec725894175b36cd76a136", + "-571d8cVauQ/0": "defc62e1530d9b0cd27f2acfe042b71dd84d7e8c85f1df261f04912091976088", + "-571d8cVauQ/5": "e304c03fac1f477823fe0926c4fb421b9c4e4091f85718b729afe856c24a7d3e", + "-I_e4mIh0yE/1": "8453a966d4bd1f0179eb86a35cd34c0864a3a3bc2fa86f37783060cc0d14f5df", + "-I_e4mIh0yE/3": "a015f02ae51d74c42ad27e2a0831263a303f0658ac8d984819e27ad61342b23e", + "-UacrmKiTn4/10": "00312e0602dbeac970de5d7dd0e8a970e514fe45d7fe6625b4f454b299e36360", + "-UacrmKiTn4/4": "a7f2ab0d6ee2e2a2d5cd4239f03e6cac67c618ddb744891323df3ff87e29af84", + "-hnBHBN8p5A/7": "0ec6fb76226315d3fafbb483e3500e60cc8a6729617b10e4b4b76163595080fb", + "-hnBHBN8p5A/6": "997f6808ac3973ddd71800e91c8e10755c10b5037186d84348a79e00d672fdc7", + "-qDkUB0GgYY/6": "ab19bf4a761d3919b7113b1104ccaadbbf0c4e7b45694904d094280a2c329c8b", + "-uywlfIYOS8/4": "fde46f5222cf5cfec7af9c93214c972ce2d686b0bf9c90a291021601968986f9", + "-6rXp3zJ3kc/8": "59b77a0f873b7fa95e7327b93d64bb5a4bdae84039321988ef70bba8e63ee1ae", + "-9y-fZ3swSY/0": "29a1fd181293cdbe24e50edcad51e3cc0f27a5824d840bcc39d453b272fb6e3c", + "-9y-fZ3swSY/4": "fe04a26710e85c58bdaad5a48618c7e0f742d82b0d920eb4a046c8f14a6921dc", + "-9y-fZ3swSY/8": "6140d031e614b62a5d8df73346fef2417c28cee3501310aa95aa40d358b4b256", + "-AUZQgSxyPQ/2": "e09034b30bb4f8fb9f9c2568afc20f2a764e327fe6ef4e13f21804eaac51bb7b", + "-HeZS2-Prhc/2": "edb0fa22fdfbd990c8174764af78670bd2ecad799240d35d96a1124a3cd9dc0c", + "-MeTTeMJBNc/0": "54e2097f7bdb455d243e72254e5af7ed16160739f2f3cfd22f57d2729ec1acbe", + "-MeTTeMJBNc/13": "80c5d996e5d7b61c58e1fe32d706efcaf80c8c8cddb5c37a5c66d527786c2a44", + "-MeTTeMJBNc/7": "40716dc7402fd6398038eded58ce939ec76be6afbeea346b968bf4c427088f3a", + "-RfYyzHpjk4/11": "96e481cd732001239639c8cb4e7f94e570925e5a15940920ffab0cec1f13f904", + "-RfYyzHpjk4/8": "ed8c672c532b8c7d1c830c82d6e2c14fcb3bbd3dc1a86670a03a6c8e83c02f3c", + "-RfYyzHpjk4/2": "5e428ee22de58c9d6561b9b4353bef9dfb811a5841d9ab07b5bc453d697ad17f", + "-UUCSKoHeMA/0": "3f9792888ec8e969f61cfb6cb4de7bdf7ef8944afe0a9d2a9d13586e1f13b898", + "-ri04Z7vwnc/0": "93021c70c8fad20ad3fded80e7fc790a2f9c96835de58a3b694c6906de42684b", + "-ri04Z7vwnc/2": "f5993ce3a6ee56298462c08692a96f78c7d914d7264257ed401de7d6e17fd148", + "-ri04Z7vwnc/5": "2a5e4319bf592a18c8eb5117f7c7ec30c6c79528f9eac9fe4fb85bf70f277736", + "-s9qJ7ATP7w/1": "a33e8f82a185bcb7648b523927308cdc2142e3076479ba2b45cd0e828636fc09", + "-s9qJ7ATP7w/0": "f2324dbc6debe0d1e4254e6f943523373e3cbb30d8d0555413ce3a7b370a4af5", + "-s9qJ7ATP7w/5": "bd35eb8de64ce1f8b27921294598f7cf5bb971255738f51d06458c7096c58eae", + "-s9qJ7ATP7w/4": "76e0672ffce5857a789b41fb10606402f7da58c33579b1032a8282f86fb35bc9", + "-s9qJ7ATP7w/7": "5301f4403cf7cd299cc525d2f443392ac70fd70c3c9cd4a09406f2ba4df6734d", + "-s9qJ7ATP7w/6": "40b684fd1b4559f0f82e72f9b47f4ce7c5e15059fe8d0d8ab112637cd3386451", + "-s9qJ7ATP7w/8": "1de4d91bd9d9fb508a3779658747da88460db0bdb1beefe7ea5b2c77edfd2239", + "-yRb-Jum7EQ/1": "2f16da1baa8660e5bfc608f5237cdd59725d16e57a19bc02c4556cd2c7129a46", + "-yRb-Jum7EQ/5": "6d6145293cf84d1fc8324dfa8d39465e2d7fc07affb67ff68deeabf6e3c410d9", + "-yRb-Jum7EQ/6": "b51eb9ad06de804934cb6a315de591ba9ff7f8aa71bffff7f8001ab29945d989" + }, + "label_polarity_consistency_count": 100 + }, + "experiment": { + "methods": { + "B0": "quality-weighted hard CTC word projection + physical source-time pooling + train-fold standard scaling", + "B1": "B0 + train-fold median/MAD scaling + SO(3) rotation mean + normalized gaze vector mean", + "B2": "B1 + fixed-transcript CTC forward-backward word occupancy projection for text", + "B3": "B1 + second-order time-augmented log signatures of selected audio/face channels", + "B4": "B1 + frozen Wav2Vec2 last-four-layer speech representation" + }, + "text_dimension": 768, + "audio_dimension": 74, + "vision_dimension": 35, + "audio_features": [ + "logmel_00", + "logmel_01", + "logmel_02", + "logmel_03", + "logmel_04", + "logmel_05", + "logmel_06", + "logmel_07", + "logmel_08", + "logmel_09", + "logmel_10", + "logmel_11", + "logmel_12", + "logmel_13", + "logmel_14", + "logmel_15", + "logmel_16", + "logmel_17", + "logmel_18", + "logmel_19", + "logmel_20", + "logmel_21", + "logmel_22", + "logmel_23", + "logmel_24", + "logmel_25", + "logmel_26", + "logmel_27", + "logmel_28", + "logmel_29", + "logmel_30", + "logmel_31", + "logmel_32", + "logmel_33", + "logmel_34", + "logmel_35", + "logmel_36", + "logmel_37", + "logmel_38", + "logmel_39", + "mfcc_00", + "mfcc_01", + "mfcc_02", + "mfcc_03", + "mfcc_04", + "mfcc_05", + "mfcc_06", + "mfcc_07", + "mfcc_08", + "mfcc_09", + "mfcc_10", + "mfcc_11", + "mfcc_12", + "delta_mfcc_00", + "delta_mfcc_01", + "delta_mfcc_02", + "delta_mfcc_03", + "delta_mfcc_04", + "delta_mfcc_05", + "delta_mfcc_06", + "delta_mfcc_07", + "delta_mfcc_08", + "delta_mfcc_09", + "delta_mfcc_10", + "delta_mfcc_11", + "delta_mfcc_12", + "log_energy", + "log_f0_hz", + "voicing_strength", + "spectral_centroid_hz", + "spectral_bandwidth_hz", + "spectral_flux", + "zero_crossing_rate", + "hnr_db" + ], + "vision_features": [ + "mp_blendshape_browDownLeft", + "mp_blendshape_browDownRight", + "mp_blendshape_browInnerUp", + "mp_blendshape_browOuterUpLeft", + "mp_blendshape_browOuterUpRight", + "mp_blendshape_eyeBlinkLeft", + "mp_blendshape_eyeBlinkRight", + "mp_blendshape_eyeSquintLeft", + "mp_blendshape_eyeSquintRight", + "mp_blendshape_eyeWideLeft", + "mp_blendshape_eyeWideRight", + "mp_blendshape_jawOpen", + "mp_blendshape_mouthFrownLeft", + "mp_blendshape_mouthFrownRight", + "mp_blendshape_mouthPucker", + "mp_blendshape_mouthSmileLeft", + "mp_blendshape_mouthSmileRight", + "pose_rotvec_x", + "pose_rotvec_y", + "pose_rotvec_z", + "pose_translation_x", + "pose_translation_y", + "pose_translation_z", + "gaze_left_x", + "gaze_left_y", + "gaze_left_z", + "gaze_right_x", + "gaze_right_y", + "gaze_right_z", + "eye_aperture_left", + "eye_aperture_right", + "mouth_aperture", + "mouth_width_face_ratio", + "brow_eye_distance_left", + "brow_eye_distance_right" + ], + "vision_feature_note": "17 MediaPipe blendshape proxies and approximate gaze/landmark geometry; not OpenFace AU labels", + "grid_step_s": 0.1, + "audio_window_samples": 400, + "audio_step_samples": 160, + "audio_fft": 512, + "audio_mel_bands": 40, + "vision_sample_rate_hz": 5.0, + "grouping": "GroupKFold by video_id", + "fold_count": 5, + "probe": { + "classifier": "LogisticRegression", + "C": 0.05, + "regressor": "Ridge", + "alpha": 25.0, + "intensity_clip": [ + -3.0, + 3.0 + ] + }, + "bootstrap": { + "unit": "video_id", + "repeats": 2000, + "seed": 20260923 + }, + "human_boundary_reference_count": 0, + "boundary_interval_level": 0.9, + "hard_text_quality_weight": "per-sample median-normalized CTC path score clipped to [0.25, 4.0]; uncalibrated", + "cache_schema": "q1-b0b4-v3" + }, + "output_dir": "/home/gloamxun/modeling_zhaocui/math/results/model_comparison", + "typical_sample_id": "-9y-fZ3swSY/0", + "elapsed_seconds": 124.10033178329468 +} diff --git a/math/results/model_comparison/sample_alignment_summary.csv b/math/results/model_comparison/sample_alignment_summary.csv new file mode 100644 index 0000000..75d637f --- /dev/null +++ b/math/results/model_comparison/sample_alignment_summary.csv @@ -0,0 +1,101 @@ +sample_id,video_id,clip_id,source_video_sha256,duration_s,word_count,hard_aligned_word_count,unlocated_word_count,posterior_usable_word_count,mean_start_interval_width90_s,mean_end_interval_width90_s,text_hard_grid_coverage,text_posterior_grid_occupancy,audio_grid_coverage,vision_grid_coverage,audio_native_rows,vision_native_rows,status +-3g5yACwYnA/13,-3g5yACwYnA,13,aeb47627f59dce3d0a85a44ef35e4a3bc18211498e98c8c11cf60269646df24f,5.5139970779418945,15,15,0,15,0.037333333333333406,0.020000000000000004,0.7015532851219177,0.24074573814868927,0.9882608652114868,1.0,540,43,ok +-3g5yACwYnA/3,-3g5yACwYnA,3,eff8cfefba2425155f2b72656829b34b23be8bfe1dcbece384154f56818aa26d,14.388997077941895,29,29,0,29,0.2793103448275863,0.25931034482758614,0.6343300342559814,0.19729532301425934,0.9912122488021851,1.0,1433,103,ok +-3g5yACwYnA/2,-3g5yACwYnA,2,0619c01f137d017c15c058176f18a575919189c7e81ebd2bfb993afdb86f3de7,9.394009590148926,14,14,0,14,0.2828571428571428,0.19142857142857145,0.7563282251358032,0.15269099175930023,0.9936367273330688,1.0,924,78,ok +-3g5yACwYnA/9,-3g5yACwYnA,9,b962573b12ed1f06d5533f6427c80dce2bae3a99dd332f6d3fcb32c579f3f016,8.816991806030273,21,21,0,21,0.22095238095238093,0.1942857142857142,0.6637077927589417,0.26207172870635986,0.9912108778953552,1.0,870,75,ok +-3nNcZdcdvU/5,-3nNcZdcdvU,5,7ea53ad502b77be7d2ee4494dc23a9478c897792203cf887d546e83d584c1728,7.867969036102295,18,18,0,18,0.03555555555555544,0.012222222222222258,0.7357116341590881,0.22051197290420532,0.9971166849136353,0.9904456734657288,779,67,ok +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,920a1052c09ebd1eedba6dd1ccfecd80f56f6f0fdcdd1f6dd32b0d90bcb89358,3.9820311069488525,8,7,1,7,0.12285714285714287,0.12285714285714275,0.6164926290512085,0.18007618188858032,0.9881895780563354,0.9814813733100891,392,27,ok +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,8d61b7f5840a8bd403d9bc6c3cd49029ffc4e304cf9c7834735c1a6bb5fd369d,5.6529951095581055,10,9,1,9,0.037777777777777764,0.040000000000000036,0.7021505832672119,0.22856950759887695,0.9900854229927063,0.666666567325592,555,44,ok +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,696576dcbd0dc42cb678fa40d8a0f0f419a3072bfa7662d653756ab29bba4c46,3.3580079078674316,7,7,0,7,0.048571428571428564,0.03428571428571422,0.5562952756881714,0.1454559713602066,0.9901678562164307,0.841666579246521,326,21,ok +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,90c18e627f27a12c14e21ba24c79edf3008762b4ac26874b490ad3f888381702,7.733983993530273,22,22,0,22,0.16363636363636375,0.15181818181818188,0.6705501675605774,0.25460928678512573,0.9946621060371399,0.0,764,65,ok +-NFrJFQijFE/1,-NFrJFQijFE,1,d8fcf16c6eb51c56947ec3d0549c6f3bc7a0cf1fc5f5d89e8b38d4249a08db4f,5.745999813079834,16,16,0,16,0.46625000000000005,0.47125000000000006,0.7835317254066467,0.27368244528770447,0.9922494292259216,0.0,566,44,ok +-NFrJFQijFE/2,-NFrJFQijFE,2,a54a5c144a64f5abd26b19aafa6cea8142ee08e9385fa508fa70c934f6b616c1,6.855999946594238,18,18,0,18,0.17888888888888899,0.1544444444444445,0.7431879639625549,0.24775999784469604,0.9926568269729614,0.0,670,55,ok +-THoVjtIkeU/12,-THoVjtIkeU,12,e2f148f4f2e74724dc13b3ce870a0ce6a06740cfc224f5a9b3d0a870b196e7d4,14.896029472351074,39,39,0,39,0.05999999999999991,0.05282051282051286,0.6352806687355042,0.23379945755004883,0.9911767244338989,1.0,1481,106,ok +-THoVjtIkeU/2,-THoVjtIkeU,2,35a6c2464ffd68dd96411edb5dc2763f0efb59f264c1d8b737e616fa6b0d1d5b,4.2919921875,10,10,0,10,0.016000000000000004,0.007999999999999985,0.7164996266365051,0.2465074211359024,0.9895758628845215,1.0,424,31,ok +-THoVjtIkeU/6,-THoVjtIkeU,6,efaa55ee6394032c867046690a92c29edfd825005f0a090cca5ccb763b227f64,8.097004890441895,30,30,0,30,0.053333333333333295,0.05733333333333333,0.6787540316581726,0.30513063073158264,0.9927164316177368,1.0,799,68,ok +-UuX1xuaiiE/1,-UuX1xuaiiE,1,d5bbda38fcec15817d2b87bab5dcc559d6d425f7d28a82e6c32d13f14b48650c,10.350000381469727,27,27,0,27,0.09555555555555556,0.060000000000000046,0.6550575494766235,0.22912898659706116,0.9925051927566528,0.8333339691162109,1027,83,ok +-UuX1xuaiiE/0,-UuX1xuaiiE,0,f578b305d53bc152702f5e771de0fcd12d1e9aaefc5cefce3d2082a417aab7c8,3.6333329677581787,9,9,0,9,0.03777777777777775,0.04666666666666665,0.6484582424163818,0.2555619180202484,0.994590699672699,0.9444444179534912,358,25,ok +-UuX1xuaiiE/3,-UuX1xuaiiE,3,eddb408f25bdc13e6de2fb74caeed709cb7a8f00640e7897135330437f66a2aa,4.1300129890441895,9,9,0,9,0.07777777777777779,0.0600000000000001,0.7240580320358276,0.16585363447666168,0.992123007774353,0.976190447807312,404,29,ok +-UuX1xuaiiE/6,-UuX1xuaiiE,6,f0131ac00e44410fbd32c547a0d421c2791172434fc0203bb969abe14a530532,8.113997459411621,22,22,0,22,0.06363636363636366,0.0736363636363637,0.7064024806022644,0.25750458240509033,0.984533965587616,0.9776423573493958,795,68,ok +-a55Q6RWvTA/3,-a55Q6RWvTA,3,15d029fc15f50b268b98f1e8abc65e45582e638c13a018d7aa74a18373275946,22.15397071838379,65,65,0,65,0.2215384615384614,0.18892307692307703,0.6580277681350708,0.23805321753025055,0.9912921786308289,1.0,2209,142,ok +-aNfi7CP8vM/7,-aNfi7CP8vM,7,0b6389f45bb966113c65a11998c6e7facdd24c8c42acf2e8cf32e0f2139402e1,8.694987297058105,18,18,0,18,0.2511111111111111,0.24000000000000002,0.7001731395721436,0.23255421221256256,0.9945195913314819,1.0,854,74,ok +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,6f6e674bbba4353399e9e7825217f37e6d8ca1adf9675f33cf37106f31c55548,10.966667175292969,14,13,1,13,0.22461538461538455,0.08615384615384586,0.71061772108078,0.1247716099023819,0.9910455346107483,1.0,1090,86,ok +-dxfTGcXJoc/1,-dxfTGcXJoc,1,b5ffdc98a4a98b8f0aae55dee5fed66a43bcb129f47a250a004c1cc74e572595,16.16100311279297,36,36,0,36,0.07777777777777778,0.033333333333333375,0.6812966465950012,0.2449914664030075,0.9900091290473938,1.0,1602,112,ok +-dxfTGcXJoc/0,-dxfTGcXJoc,0,04bd0be907fb46c613f926fe1b06bc2c3b30881c293156510baa34a4105ade55,20.5,41,38,3,38,0.09315789473684201,0.06789473684210537,0.7333337664604187,0.209048330783844,0.9891952872276306,0.99895840883255,2042,134,ok +-dxfTGcXJoc/2,-dxfTGcXJoc,2,46a5e523b5dd00364c99a3bcbc6fae4c80e1382a84b5b5e681c46eb074ed10f7,16.697982788085938,34,32,2,32,0.048124999999999946,0.03624999999999996,0.6593995094299316,0.2266717106103897,0.9901677966117859,1.0,1664,115,ok +-dxfTGcXJoc/6,-dxfTGcXJoc,6,55c1ff86729ab21da743a5107ed07b220e41b4193cd1c0ba9f009e65c3ab0513,12.735026359558105,27,27,0,27,0.05851851851851849,0.05407407407407409,0.715381383895874,0.25197115540504456,0.9889141917228699,1.0,1263,95,ok +-egA8-b7-3M/26,-egA8-b7-3M,26,11f78aed680ea9c5862a15e04ff6c1f8776c46d29c98b68d28773ff39d959685,6.030990123748779,15,15,0,15,0.08133333333333341,0.02533333333333337,0.6877890825271606,0.22332797944545746,0.9945786595344543,1.0,593,47,ok +-egA8-b7-3M/17,-egA8-b7-3M,17,f967e81e0edd51c3700671721afb3fbecbbc32652f27d2db40ea444e8d80c68f,7.271028995513916,16,16,0,16,0.017499999999999995,0.019999999999999962,0.7292676568031311,0.24067606031894684,0.9916234016418457,1.0,710,60,ok +-egA8-b7-3M/18,-egA8-b7-3M,18,fd4bc95a6adfb16a9588b7ed65cc2812186ce3d607804dc76f4486312951ef90,8.386002540588379,22,22,0,22,0.052727272727272734,0.021818181818181796,0.6243576407432556,0.26077014207839966,0.9932008385658264,1.0,827,71,ok +-egA8-b7-3M/16,-egA8-b7-3M,16,4c015f85e3bd901ecedde8c0c2ca4a756d9a77dfe4177625c481581f2037ff9c,5.538021087646484,11,11,0,11,0.010909090909090908,0.0181818181818182,0.7375588417053223,0.23636400699615479,0.9940068125724792,1.0,549,43,ok +-egA8-b7-3M/13,-egA8-b7-3M,13,cbd627c225ebca37521ae238cb9ec254cad236822f4f37ebfbb039e6c56aea4c,4.18398380279541,11,11,0,11,0.23818181818181816,0.23090909090909092,0.6372604370117188,0.2536529004573822,0.9924017786979675,1.0,403,29,ok +-egA8-b7-3M/1,-egA8-b7-3M,1,589a7989b1b4888568c31614a2d6beefba88fb87289c85b94df2d8051500403b,10.266016006469727,20,19,1,19,1.0621052631578947,1.0526315789473684,0.6490206122398376,0.19601602852344513,0.9937204718589783,1.0,1016,83,ok +-egA8-b7-3M/6,-egA8-b7-3M,6,2e88a00d5e55863aa956b4b0949fc0e4f2975ccfd83b3194957f6fca86ecfce0,6.264974117279053,12,12,0,12,0.08833333333333332,0.03666666666666665,0.7164138555526733,0.2193591147661209,0.9942464828491211,1.0,619,50,ok +-egA8-b7-3M/9,-egA8-b7-3M,9,bcd643f328616312eae9b28e6c9aabbe8acaec3e4c4be58daeb45e3eee4d973c,5.0899739265441895,10,10,0,10,0.007999999999999962,0.011999999999999966,0.597113311290741,0.2590937316417694,0.9939422011375427,1.0,494,38,ok +-egA8-b7-3M/20,-egA8-b7-3M,20,719ef133920e74b3ea33925d2bca0270b062199116867568f88ac83cadcd74e8,6.644987106323242,20,20,0,20,0.077,0.021000000000000008,0.6985589861869812,0.2369300276041031,0.992087185382843,1.0,648,54,ok +-iRBcNs9oI8/3,-iRBcNs9oI8,3,39c547acd1a8da2ebc6c6ab008191a5676420398a974cd9611cad087f0ccec50,5.620999813079834,8,8,0,8,0.10250000000000009,0.07500000000000001,0.6791599988937378,0.1166667565703392,0.9954468607902527,0.0,554,28,ok +-iRBcNs9oI8/7,-iRBcNs9oI8,7,cc7b1c7a06ec41d72007b5c42fb8036f30b66d5cf76e3f093160c22fc5e38081,4.104000091552734,9,9,0,9,0.10222222222222223,0.02666666666666669,0.7135127186775208,0.18537555634975433,0.995795726776123,0.0,401,21,ok +-iRBcNs9oI8/6,-iRBcNs9oI8,6,030b0b8d8d4ae47799432ab71b66fcc881f077c5b0feef892c1f146dc0a592e3,2.9030001163482666,5,5,0,5,0.03999999999999999,0.04399999999999998,0.7227271199226379,0.12799954414367676,0.9973600506782532,0.0,283,15,ok +-iRBcNs9oI8/9,-iRBcNs9oI8,9,352bdcc73d3622d6abac1b09f2039b211d15b9bf7acee66f0b07783c9b7a4c74,3.4159998893737793,5,5,0,5,0.20800000000000002,0.016000000000000014,0.643750011920929,0.14118166267871857,0.993934154510498,0.0,338,17,ok +-iRBcNs9oI8/8,-iRBcNs9oI8,8,72a49e3da2862addcde033bd2fbae957d086533664ca4dcbccd3a851bcd50412,8.093000411987305,21,21,0,21,0.23238095238095247,0.2228571428571429,0.6192578673362732,0.18252728879451752,0.9947929382324219,0.0,803,41,ok +-lzEya4AM_4/5,-lzEya4AM_4,5,3b74de8d0e66fd754594f05985e5af3480adcc03555f79225d3b727cb4bed043,7.675000190734863,19,19,0,19,0.12000000000000004,0.09473684210526319,0.7427374720573425,0.2366195172071457,0.9901386499404907,1.0,757,64,ok +-lzEya4AM_4/6,-lzEya4AM_4,6,ff5da5afb551001d58100ed2471caea51c741046d5396957efbf40082307ca18,14.7919921875,43,43,0,43,0.05023255813953489,0.024651162790697716,0.7318416833877563,0.2524191737174988,0.9907644391059875,1.0,1475,105,ok +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,c8e3acb4ca08679796c4c8cdfcd8c2b3cffc0465015efaffa1eccdb55ff4f45b,6.103000164031982,13,13,0,13,0.733846153846154,0.7399999999999998,0.8174015879631042,0.1573781669139862,1.0,0.0,606,31,ok +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,c41790f8b75f886bd1f5d6d72cbab1985306d0b715e5ae47203f3d0c8a3e7b28,5.730999946594238,11,11,0,11,0.4636363636363635,0.46181818181818185,0.9266790151596069,0.2666672170162201,1.0,0.0,571,29,ok +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,134a3a4ebbc423760133b0da0e90cfe84d75ea85df3968000afd84153c5d828d,2.256999969482422,5,5,0,5,0.11199999999999996,0.06400000000000003,0.6512578129768372,0.15656699240207672,0.9862568378448486,1.0,223,12,ok +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,df3442f3ed8f894b507923e87e426ae9636790a4a502d00c350a215270cc3e47,7.0329999923706055,22,22,0,22,0.11999999999999994,0.09454545454545453,0.5777366757392883,0.25714901089668274,0.9846946001052856,0.9856857061386108,691,35,ok +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,6af6614c9838417a48c4817f4dd5bf1e6669eb5f78f983e9a68adc113fcdc7cc,4.191999912261963,11,11,0,11,0.14363636363636367,0.06363636363636366,0.6529467701911926,0.26233649253845215,0.9846959114074707,1.0,418,21,ok +-mqbVkbCndg/0,-mqbVkbCndg,0,cdeba953bba30907814acf72f3e35582dec263eaa25bdd922dad7fafe02e4dda,6.466667175292969,12,12,0,12,0.06166666666666665,0.03333333333333339,0.7074670791625977,0.20000411570072174,0.9905118346214294,1.0,639,53,ok +-t217m2on-s/2,-t217m2on-s,2,6713a983112173204502dc5adbb886bc6c38554b4627698611931420c47663a8,5.6860032081604,12,12,0,12,0.21666666666666665,0.2333333333333333,0.6279765367507935,0.16491496562957764,0.9959543347358704,1.0,564,45,ok +-t217m2on-s/7,-t217m2on-s,7,41c76b8a733ecb780d56348f55d00f0ba0c07f44f46e93044e62d876710180b7,17.183008193969727,45,45,0,45,0.048444444444444436,0.017777777777777892,0.6867958903312683,0.23202678561210632,0.9928514361381531,1.0,1703,117,ok +-tANM6ETl_M/3,-tANM6ETl_M,3,6d3af064c060dad3816a9e1dfa00101faebd8b7da7d8ceea85b0bc0fca70abd6,6.758008003234863,22,22,0,22,0.030909090909090896,0.021818181818181792,0.5859207510948181,0.2757546901702881,0.9936580061912537,0.9898989200592041,661,54,ok +-tPCytz4rww/11,-tPCytz4rww,11,6dc09d02467baaef67594ff32cffb01f8ed1565cda4c5abd161b8261a51e2e5d,5.466991901397705,17,17,0,17,0.09764705882352945,0.08588235294117644,0.6753751635551453,0.28518491983413696,0.9890678524971008,1.0,538,43,ok +-tPCytz4rww/10,-tPCytz4rww,10,758183192cbd5f0f20823d26ece3ddee40dec0aadec35247b2495510a53f52f8,4.788997173309326,12,12,0,12,0.04499999999999999,0.00833333333333334,0.5449775457382202,0.225633442401886,0.9894654750823975,1.0,468,35,ok +-tPCytz4rww/12,-tPCytz4rww,12,e3c7f9cd67ad2d20fef997696dc278361f97f027db58762e22104e5720d509d5,11.863997459411621,26,26,0,26,0.14461538461538456,0.08769230769230774,0.654129683971405,0.22372934222221375,0.9875938892364502,1.0,1174,91,ok +-tPCytz4rww/16,-tPCytz4rww,16,8b3f82f9628792eebaf8c227becc2ebeba59bb8abb668bcca86e07fb1a992a93,7.205989837646484,16,16,0,16,0.05125000000000004,0.013749999999999984,0.4489554166793823,0.17846456170082092,0.988937258720398,1.0,714,59,ok +-tPCytz4rww/18,-tPCytz4rww,18,eece70451e9c37a4b5f375bf646f66e09113fe3467f35bf1720cc14d986c1776,6.644987106323242,16,16,0,16,0.16375,0.1275,0.6719247698783875,0.22222484648227692,0.9872123599052429,1.0,657,54,ok +-vxjVxOeScU/4,-vxjVxOeScU,4,00282df9a314394f19d616d561bd1916d1d30dca4c814dfb43630ca164f4c719,9.127017974853516,21,21,0,21,0.06380952380952383,0.037142857142857144,0.6465563774108887,0.2219761461019516,0.9960808753967285,1.0,904,77,ok +-wMB_hJL-3o/7,-wMB_hJL-3o,7,04a73d73fd150b07edab8e652fd14c9cb4a0f6e017ea97b17e8146e377b9fae7,6.044010162353516,22,22,0,22,0.012727272727272738,0.021818181818181816,0.658498227596283,0.31481292843818665,0.9895980954170227,0.9836065769195557,598,48,ok +-wny0OAz3g8/1,-wny0OAz3g8,1,c5535859f129ce04da5f5b5104d02d4168057b9d947a5349d423278ad4f3d8e8,6.844009876251221,23,22,1,22,0.013636363636363648,0.011818181818181823,0.62252277135849,0.3443901240825653,0.995954155921936,0.9950981140136719,678,56,ok +-wny0OAz3g8/0,-wny0OAz3g8,0,1cc21b4432e2f4b592284ee40558a18acc7d208019117aebdb2f6a1b67ea198d,3.3333330154418945,9,9,0,9,0.32000000000000006,0.2866666666666667,0.6052471995353699,0.2736770212650299,0.9955413937568665,0.9999999403953552,328,21,ok +-wny0OAz3g8/3,-wny0OAz3g8,3,ea917c506bc9fa39460f2b722f7c416f646312bb17cd74baa618905b54837bce,6.146028995513916,20,20,0,20,0.022999999999999986,0.02399999999999995,0.7014381289482117,0.3213139474391937,0.9980819821357727,0.9895832538604736,610,49,ok +-wny0OAz3g8/2,-wny0OAz3g8,2,1825fb37db2e914fb616cd80aebd613afd873eecb7edd4d0b53158bfda0e522a,6.686978816986084,23,23,0,23,0.02869565217391302,0.026086956521739167,0.7553136348724365,0.33939871191978455,0.9957627058029175,0.9848485589027405,653,54,ok +-wny0OAz3g8/5,-wny0OAz3g8,5,6c6a8a4cba654b25190ab1793bfae81c3d2159ecd6cbc02d3fcbd598543acce0,6.9119791984558105,20,20,0,20,0.004999999999999982,0.004999999999999982,0.6063091158866882,0.3181923031806946,0.9961636066436768,0.9895831346511841,675,56,ok +-wny0OAz3g8/7,-wny0OAz3g8,7,cbf9cac1048ce191aef781d0c4563eb97f9f3ddd52eb1f9551fa78d31d70e7cd,8.06796932220459,29,29,0,29,0.0186206896551724,0.017241379310344838,0.6700748205184937,0.3224986493587494,0.9956274628639221,1.0,792,68,ok +-wny0OAz3g8/9,-wny0OAz3g8,9,b76f70fe783ee76bf1b637137226c98e67d13a6b15ec725894175b36cd76a136,6.2130208015441895,20,20,0,20,0.025999999999999975,0.027000000000000024,0.6688015460968018,0.3180274963378906,0.9969837069511414,0.9672130942344666,605,49,ok +-571d8cVauQ/0,-571d8cVauQ,0,defc62e1530d9b0cd27f2acfe042b71dd84d7e8c85f1df261f04912091976088,5.066667079925537,12,12,0,12,0.07500000000000001,0.03000000000000001,0.6978414058685303,0.2360049933195114,0.9903978705406189,1.0,500,39,ok +-571d8cVauQ/5,-571d8cVauQ,5,e304c03fac1f477823fe0926c4fb421b9c4e4091f85718b729afe856c24a7d3e,15.272981643676758,43,43,0,43,0.14604651162790694,0.11534883720930222,0.7017207741737366,0.23815667629241943,0.9918006062507629,1.0,1512,108,ok +-I_e4mIh0yE/1,-I_e4mIh0yE,1,8453a966d4bd1f0179eb86a35cd34c0864a3a3bc2fa86f37783060cc0d14f5df,7.622004985809326,18,18,0,18,0.061111111111111116,0.02333333333333332,0.6546477675437927,0.2152525633573532,0.985649049282074,1.0,745,63,ok +-I_e4mIh0yE/3,-I_e4mIh0yE,3,a015f02ae51d74c42ad27e2a0831263a303f0658ac8d984819e27ad61342b23e,9.163021087646484,22,22,0,22,0.13,0.11545454545454543,0.6251755356788635,0.24003465473651886,0.9852646589279175,1.0,900,77,ok +-UacrmKiTn4/10,-UacrmKiTn4,10,00312e0602dbeac970de5d7dd0e8a970e514fe45d7fe6625b4f454b299e36360,7.361979007720947,18,18,0,18,0.04555555555555555,0.07222222222222224,0.47940683364868164,0.20824021100997925,0.9955651164054871,1.0,725,60,ok +-UacrmKiTn4/4,-UacrmKiTn4,4,a7f2ab0d6ee2e2a2d5cd4239f03e6cac67c618ddb744891323df3ff87e29af84,4.741015911102295,14,14,0,14,0.06714285714285716,0.09857142857142863,0.7214669585227966,0.246806800365448,0.9926760792732239,1.0,469,35,ok +-hnBHBN8p5A/7,-hnBHBN8p5A,7,0ec6fb76226315d3fafbb483e3500e60cc8a6729617b10e4b4b76163595080fb,7.372000217437744,13,13,0,13,0.01846153846153847,0.021538461538461593,0.657243549823761,0.1729772984981537,0.9905768632888794,0.0,731,37,ok +-hnBHBN8p5A/6,-hnBHBN8p5A,6,997f6808ac3973ddd71800e91c8e10755c10b5037186d84348a79e00d672fdc7,6.401000022888184,13,13,0,13,0.04307692307692312,0.012307692307692353,0.7618876099586487,0.22187285125255585,0.9932082295417786,0.0,634,32,ok +-qDkUB0GgYY/6,-qDkUB0GgYY,6,ab19bf4a761d3919b7113b1104ccaadbbf0c4e7b45694904d094280a2c329c8b,4.677995204925537,16,16,0,16,0.033749999999999974,0.02250000000000002,0.6504627466201782,0.24682332575321198,0.9946085214614868,1.0,462,35,ok +-uywlfIYOS8/4,-uywlfIYOS8,4,fde46f5222cf5cfec7af9c93214c972ce2d686b0bf9c90a291021601968986f9,6.044987201690674,18,18,0,18,0.0433333333333333,0.04333333333333334,0.6908547878265381,0.25089454650878906,0.9957761168479919,1.0,589,48,ok +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,59b77a0f873b7fa95e7327b93d64bb5a4bdae84039321988ef70bba8e63ee1ae,12.805012702941895,34,34,0,34,0.06470588235294118,0.034705882352941086,0.63474440574646,0.22114422917366028,0.9899758696556091,1.0,1274,95,ok +-9y-fZ3swSY/0,-9y-fZ3swSY,0,29a1fd181293cdbe24e50edcad51e3cc0f27a5824d840bcc39d453b272fb6e3c,6.8333330154418945,22,22,0,22,0.023636363636363688,0.019999999999999997,0.5440928339958191,0.2264895737171173,0.9948647022247314,1.0,676,57,ok +-9y-fZ3swSY/4,-9y-fZ3swSY,4,fe04a26710e85c58bdaad5a48618c7e0f742d82b0d920eb4a046c8f14a6921dc,2.8210289478302,9,9,0,9,0.1711111111111111,0.15999999999999998,0.5274830460548401,0.1851968914270401,0.9926167726516724,1.0,267,15,ok +-9y-fZ3swSY/8,-9y-fZ3swSY,8,6140d031e614b62a5d8df73346fef2417c28cee3501310aa95aa40d358b4b256,4.988996982574463,12,12,0,12,0.07333333333333339,0.05333333333333331,0.562736988067627,0.18345493078231812,0.9931800365447998,0.9487179517745972,492,37,ok +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,e09034b30bb4f8fb9f9c2568afc20f2a764e327fe6ef4e13f21804eaac51bb7b,22.511003494262695,41,41,0,41,0.6434146341463415,0.6102439024390245,0.6386448740959167,0.19374850392341614,0.9917553663253784,1.0,2241,144,ok +-HeZS2-Prhc/2,-HeZS2-Prhc,2,edb0fa22fdfbd990c8174764af78670bd2ecad799240d35d96a1124a3cd9dc0c,8.261979103088379,16,16,0,16,0.14125000000000004,0.08125000000000016,0.6830984950065613,0.15250585973262787,0.9933875799179077,1.0,816,70,ok +-MeTTeMJBNc/0,-MeTTeMJBNc,0,54e2097f7bdb455d243e72254e5af7ed16160739f2f3cfd22f57d2729ec1acbe,9.300000190734863,21,21,0,21,0.03714285714285711,0.026666666666666637,0.6400595903396606,0.22926528751850128,0.9939717650413513,1.0,922,78,ok +-MeTTeMJBNc/13,-MeTTeMJBNc,13,80c5d996e5d7b61c58e1fe32d706efcaf80c8c8cddb5c37a5c66d527786c2a44,5.430013179779053,14,14,0,14,0.042857142857142864,0.00714285714285715,0.6661255359649658,0.2075468748807907,0.9918515682220459,1.0,526,41,ok +-MeTTeMJBNc/7,-MeTTeMJBNc,7,40716dc7402fd6398038eded58ce939ec76be6afbeea346b968bf4c427088f3a,10.51699161529541,31,31,0,31,0.03225806451612902,0.02387096774193552,0.7313360571861267,0.269477516412735,0.9934103488922119,1.0,1042,84,ok +-RfYyzHpjk4/11,-RfYyzHpjk4,11,96e481cd732001239639c8cb4e7f94e570925e5a15940920ffab0cec1f13f904,5.238996982574463,17,17,0,17,0.018823529411764742,0.025882352941176467,0.6960803866386414,0.27842891216278076,0.9958056807518005,1.0,508,40,ok +-RfYyzHpjk4/8,-RfYyzHpjk4,8,ed8c672c532b8c7d1c830c82d6e2c14fcb3bbd3dc1a86670a03a6c8e83c02f3c,4.588996887207031,17,17,0,17,0.04588235294117646,0.005882352941176463,0.684955358505249,0.27527740597724915,0.994469404220581,1.0,454,33,ok +-RfYyzHpjk4/2,-RfYyzHpjk4,2,5e428ee22de58c9d6561b9b4353bef9dfb811a5841d9ab07b5bc453d697ad17f,5.516016006469727,25,25,0,25,0.12960000000000005,0.12880000000000008,0.7175998091697693,0.3444570004940033,0.9948742389678955,1.0,540,43,ok +-UUCSKoHeMA/0,-UUCSKoHeMA,0,3f9792888ec8e969f61cfb6cb4de7bdf7ef8944afe0a9d2a9d13586e1f13b898,7.800000190734863,18,18,0,18,0.23000000000000004,0.20999999999999996,0.666740894317627,0.22424933314323425,0.9943835139274597,1.0,774,66,ok +-ri04Z7vwnc/0,-ri04Z7vwnc,0,93021c70c8fad20ad3fded80e7fc790a2f9c96835de58a3b694c6906de42684b,2.806999921798706,8,8,0,8,0.35999999999999993,0.3525,0.7826409935951233,0.25714799761772156,0.9982975125312805,0.0,277,14,ok +-ri04Z7vwnc/2,-ri04Z7vwnc,2,f5993ce3a6ee56298462c08692a96f78c7d914d7264257ed401de7d6e17fd148,6.0269999504089355,16,16,0,16,0.23374999999999996,0.22875,0.7431082725524902,0.26666611433029175,0.9971521496772766,0.9906440377235413,592,30,ok +-ri04Z7vwnc/5,-ri04Z7vwnc,5,2a5e4319bf592a18c8eb5117f7c7ec30c6c79528f9eac9fe4fb85bf70f277736,3.5450000762939453,9,8,1,8,0.21249999999999986,0.23999999999999994,0.721091628074646,0.21714359521865845,0.9974266886711121,1.0,344,18,ok +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,a33e8f82a185bcb7648b523927308cdc2142e3076479ba2b45cd0e828636fc09,4.7919921875,11,11,0,11,0.01636363636363641,0.021818181818181816,0.7055363059043884,0.16956037282943726,0.9860281348228455,1.0,465,35,ok +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,f2324dbc6debe0d1e4254e6f943523373e3cbb30d8d0555413ce3a7b370a4af5,6.800000190734863,24,24,0,24,0.056666666666666664,0.029999999999999957,0.6351987719535828,0.2500007152557373,0.9885490536689758,0.984375,672,56,ok +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,bd35eb8de64ce1f8b27921294598f7cf5bb971255738f51d06458c7096c58eae,8.561002731323242,19,19,0,19,0.25578947368421046,0.26210526315789456,0.5150972604751587,0.16428017616271973,0.9896790981292725,1.0,840,72,ok +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,76e0672ffce5857a789b41fb10606402f7da58c33579b1032a8282f86fb35bc9,4.427018165588379,9,9,0,9,0.07555555555555557,0.024444444444444453,0.6215080618858337,0.20000608265399933,0.9892621040344238,0.96875,425,31,ok +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,5301f4403cf7cd299cc525d2f443392ac70fd70c3c9cd4a09406f2ba4df6734d,6.966015815734863,28,28,0,28,0.029285714285714304,0.02428571428571429,0.661829948425293,0.29855138063430786,0.9849807620048523,0.9496123194694519,684,57,ok +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,40b684fd1b4559f0f82e72f9b47f4ce7c5e15059fe8d0d8ab112637cd3386451,2.4749999046325684,5,5,0,5,0.21599999999999997,0.16400000000000006,0.8113580942153931,0.14165958762168884,0.9844902753829956,1.0,232,14,ok +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,1de4d91bd9d9fb508a3779658747da88460db0bdb1beefe7ea5b2c77edfd2239,3.2949869632720947,13,12,1,12,0.07166666666666661,0.06166666666666667,0.6465047001838684,0.2687399089336395,0.9880942702293396,0.9731181859970093,319,20,ok +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,2f16da1baa8660e5bfc608f5237cdd59725d16e57a19bc02c4556cd2c7129a46,29.288021087646484,49,49,0,49,0.2922448979591836,0.2689795918367347,0.6873865723609924,0.18630558252334595,0.9836021065711975,0.999393880367279,2911,178,ok +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,6d6145293cf84d1fc8324dfa8d39465e2d7fc07affb67ff68deeabf6e3c410d9,13.169010162353516,25,25,0,25,0.14880000000000007,0.18799999999999997,0.7192046046257019,0.19541765749454498,0.9867846369743347,1.0,1305,97,ok +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,b51eb9ad06de804934cb6a315de591ba9ff7f8aa71bffff7f8001ab29945d989,11.241994857788086,19,19,0,19,0.09578947368421038,0.15263157894736842,0.6869907975196838,0.16814078390598297,0.9854583740234375,1.0,1125,87,ok diff --git a/math/results/model_comparison/split_assignments.csv b/math/results/model_comparison/split_assignments.csv new file mode 100644 index 0000000..ef7b811 --- /dev/null +++ b/math/results/model_comparison/split_assignments.csv @@ -0,0 +1,101 @@ +sample_id,video_id,fold,split +-3g5yACwYnA/13,-3g5yACwYnA,1,valid_oof +-3g5yACwYnA/2,-3g5yACwYnA,1,valid_oof +-3g5yACwYnA/3,-3g5yACwYnA,1,valid_oof +-3g5yACwYnA/9,-3g5yACwYnA,1,valid_oof +-3nNcZdcdvU/5,-3nNcZdcdvU,5,valid_oof +-571d8cVauQ/0,-571d8cVauQ,2,valid_oof +-571d8cVauQ/5,-571d8cVauQ,2,valid_oof +-6rXp3zJ3kc/8,-6rXp3zJ3kc,4,valid_oof +-9y-fZ3swSY/0,-9y-fZ3swSY,1,valid_oof +-9y-fZ3swSY/4,-9y-fZ3swSY,1,valid_oof +-9y-fZ3swSY/8,-9y-fZ3swSY,1,valid_oof +-AUZQgSxyPQ/2,-AUZQgSxyPQ,3,valid_oof +-HeZS2-Prhc/2,-HeZS2-Prhc,2,valid_oof +-HwX2H8Z4hY/2,-HwX2H8Z4hY,3,valid_oof +-HwX2H8Z4hY/5,-HwX2H8Z4hY,3,valid_oof +-HwX2H8Z4hY/6,-HwX2H8Z4hY,3,valid_oof +-HwX2H8Z4hY/9,-HwX2H8Z4hY,3,valid_oof +-I_e4mIh0yE/1,-I_e4mIh0yE,1,valid_oof +-I_e4mIh0yE/3,-I_e4mIh0yE,1,valid_oof +-MeTTeMJBNc/0,-MeTTeMJBNc,5,valid_oof +-MeTTeMJBNc/13,-MeTTeMJBNc,5,valid_oof +-MeTTeMJBNc/7,-MeTTeMJBNc,5,valid_oof +-NFrJFQijFE/1,-NFrJFQijFE,5,valid_oof +-NFrJFQijFE/2,-NFrJFQijFE,5,valid_oof +-RfYyzHpjk4/11,-RfYyzHpjk4,3,valid_oof +-RfYyzHpjk4/2,-RfYyzHpjk4,3,valid_oof +-RfYyzHpjk4/8,-RfYyzHpjk4,3,valid_oof +-THoVjtIkeU/12,-THoVjtIkeU,2,valid_oof +-THoVjtIkeU/2,-THoVjtIkeU,2,valid_oof +-THoVjtIkeU/6,-THoVjtIkeU,2,valid_oof +-UUCSKoHeMA/0,-UUCSKoHeMA,1,valid_oof +-UacrmKiTn4/10,-UacrmKiTn4,4,valid_oof +-UacrmKiTn4/4,-UacrmKiTn4,4,valid_oof +-UuX1xuaiiE/0,-UuX1xuaiiE,2,valid_oof +-UuX1xuaiiE/1,-UuX1xuaiiE,2,valid_oof +-UuX1xuaiiE/3,-UuX1xuaiiE,2,valid_oof +-UuX1xuaiiE/6,-UuX1xuaiiE,2,valid_oof +-a55Q6RWvTA/3,-a55Q6RWvTA,5,valid_oof +-aNfi7CP8vM/7,-aNfi7CP8vM,4,valid_oof +-aqamKhZ1Ec/0,-aqamKhZ1Ec,3,valid_oof +-dxfTGcXJoc/0,-dxfTGcXJoc,5,valid_oof +-dxfTGcXJoc/1,-dxfTGcXJoc,5,valid_oof +-dxfTGcXJoc/2,-dxfTGcXJoc,5,valid_oof +-dxfTGcXJoc/6,-dxfTGcXJoc,5,valid_oof +-egA8-b7-3M/1,-egA8-b7-3M,1,valid_oof +-egA8-b7-3M/13,-egA8-b7-3M,1,valid_oof +-egA8-b7-3M/16,-egA8-b7-3M,1,valid_oof +-egA8-b7-3M/17,-egA8-b7-3M,1,valid_oof +-egA8-b7-3M/18,-egA8-b7-3M,1,valid_oof +-egA8-b7-3M/20,-egA8-b7-3M,1,valid_oof +-egA8-b7-3M/26,-egA8-b7-3M,1,valid_oof +-egA8-b7-3M/6,-egA8-b7-3M,1,valid_oof +-egA8-b7-3M/9,-egA8-b7-3M,1,valid_oof +-hnBHBN8p5A/6,-hnBHBN8p5A,3,valid_oof +-hnBHBN8p5A/7,-hnBHBN8p5A,3,valid_oof +-iRBcNs9oI8/3,-iRBcNs9oI8,4,valid_oof +-iRBcNs9oI8/6,-iRBcNs9oI8,4,valid_oof +-iRBcNs9oI8/7,-iRBcNs9oI8,4,valid_oof +-iRBcNs9oI8/8,-iRBcNs9oI8,4,valid_oof +-iRBcNs9oI8/9,-iRBcNs9oI8,4,valid_oof +-lzEya4AM_4/5,-lzEya4AM_4,2,valid_oof +-lzEya4AM_4/6,-lzEya4AM_4,2,valid_oof +-mJ2ud6oKI8/1,-mJ2ud6oKI8,5,valid_oof +-mJ2ud6oKI8/2,-mJ2ud6oKI8,5,valid_oof +-mJ2ud6oKI8/6,-mJ2ud6oKI8,5,valid_oof +-mJ2ud6oKI8/8,-mJ2ud6oKI8,5,valid_oof +-mJ2ud6oKI8/9,-mJ2ud6oKI8,5,valid_oof +-mqbVkbCndg/0,-mqbVkbCndg,2,valid_oof +-qDkUB0GgYY/6,-qDkUB0GgYY,1,valid_oof +-ri04Z7vwnc/0,-ri04Z7vwnc,4,valid_oof +-ri04Z7vwnc/2,-ri04Z7vwnc,4,valid_oof +-ri04Z7vwnc/5,-ri04Z7vwnc,4,valid_oof +-s9qJ7ATP7w/0,-s9qJ7ATP7w,3,valid_oof +-s9qJ7ATP7w/1,-s9qJ7ATP7w,3,valid_oof +-s9qJ7ATP7w/4,-s9qJ7ATP7w,3,valid_oof +-s9qJ7ATP7w/5,-s9qJ7ATP7w,3,valid_oof +-s9qJ7ATP7w/6,-s9qJ7ATP7w,3,valid_oof +-s9qJ7ATP7w/7,-s9qJ7ATP7w,3,valid_oof +-s9qJ7ATP7w/8,-s9qJ7ATP7w,3,valid_oof +-t217m2on-s/2,-t217m2on-s,4,valid_oof +-t217m2on-s/7,-t217m2on-s,4,valid_oof +-tANM6ETl_M/3,-tANM6ETl_M,5,valid_oof +-tPCytz4rww/10,-tPCytz4rww,4,valid_oof +-tPCytz4rww/11,-tPCytz4rww,4,valid_oof +-tPCytz4rww/12,-tPCytz4rww,4,valid_oof +-tPCytz4rww/16,-tPCytz4rww,4,valid_oof +-tPCytz4rww/18,-tPCytz4rww,4,valid_oof +-uywlfIYOS8/4,-uywlfIYOS8,4,valid_oof +-vxjVxOeScU/4,-vxjVxOeScU,3,valid_oof +-wMB_hJL-3o/7,-wMB_hJL-3o,3,valid_oof +-wny0OAz3g8/0,-wny0OAz3g8,2,valid_oof +-wny0OAz3g8/1,-wny0OAz3g8,2,valid_oof +-wny0OAz3g8/2,-wny0OAz3g8,2,valid_oof +-wny0OAz3g8/3,-wny0OAz3g8,2,valid_oof +-wny0OAz3g8/5,-wny0OAz3g8,2,valid_oof +-wny0OAz3g8/7,-wny0OAz3g8,2,valid_oof +-wny0OAz3g8/9,-wny0OAz3g8,2,valid_oof +-yRb-Jum7EQ/1,-yRb-Jum7EQ,5,valid_oof +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,valid_oof +-yRb-Jum7EQ/6,-yRb-Jum7EQ,5,valid_oof diff --git a/math/results/model_comparison/typical_alignment_example.png b/math/results/model_comparison/typical_alignment_example.png new file mode 100644 index 0000000..d56096b Binary files /dev/null and b/math/results/model_comparison/typical_alignment_example.png differ diff --git a/math/results/model_comparison/word_alignment_posterior.csv b/math/results/model_comparison/word_alignment_posterior.csv new file mode 100644 index 0000000..e5714f8 --- /dev/null +++ b/math/results/model_comparison/word_alignment_posterior.csv @@ -0,0 +1,1933 @@ +sample_id,video_id,clip_id,word_index,word,hard_start_s,hard_end_s,hard_valid,ctc_quality_score_uncalibrated,relative_quality_weight,start_mean_s,end_mean_s,start_p05_s,start_p95_s,end_p05_s,end_p95_s,start_width90_s,end_width90_s +-3g5yACwYnA/13,-3g5yACwYnA,13,0,They've,0.0024999999441206455,0.5625,True,3.1319849491673324e-11,4.0,0.019184879635086593,0.5625060804898443,0.0025000000000000005,0.10250000000000001,0.5625,0.5625,0.1,0.0 +-3g5yACwYnA/13,-3g5yACwYnA,13,1,been,1.222499966621399,1.3624999523162842,True,5.074469056759456e-12,2.26932692527771,1.2063062407761618,1.38194823633117,1.1425,1.2625,1.3625,1.4224999999999999,0.11999999999999988,0.05999999999999983 +-3g5yACwYnA/13,-3g5yACwYnA,13,2,able,1.4424999952316284,1.6024999618530273,True,2.422228541874849e-13,0.25,1.4426709260933925,1.5958374384159129,1.4425,1.4425,1.5825,1.6025,0.0,0.020000000000000018 +-3g5yACwYnA/13,-3g5yACwYnA,13,3,to,1.622499942779541,1.7024999856948853,True,1.4663940634679351e-12,0.6557784676551819,1.63353469473686,1.702500930802706,1.6225,1.6425,1.7025,1.7025,0.020000000000000018,0.0 +-3g5yACwYnA/13,-3g5yACwYnA,13,4,find,1.7625000476837158,2.0225000381469727,True,2.2361119032809906e-12,1.0,1.7625198227574603,2.022487282563605,1.7625,1.7625,2.0225,2.0225,0.0,0.0 +-3g5yACwYnA/13,-3g5yACwYnA,13,5,solutions,2.1624999046325684,2.6424999237060547,True,7.178173853927827e-12,3.210113763809204,2.162477129647909,2.642508732091731,2.1625,2.1625,2.6425,2.6425,0.0,0.0 +-3g5yACwYnA/13,-3g5yACwYnA,13,6,or,2.7225000858306885,2.802500009536743,True,1.8666060017102915e-11,4.0,2.7225030011118756,2.8025052458122928,2.7225,2.7225,2.8025,2.8025,0.0,0.0 +-3g5yACwYnA/13,-3g5yACwYnA,13,7,at,3.0225000381469727,3.122499942779541,True,7.055260780979011e-13,0.3155146539211273,3.0114486420923248,3.1096179351127704,2.9425,3.0225,3.0425,3.1225,0.08000000000000007,0.08000000000000007 +-3g5yACwYnA/13,-3g5yACwYnA,13,8,least,3.1624999046325684,3.382499933242798,True,4.716877496230287e-12,2.109410285949707,3.1602214981987653,3.377016650868552,3.1225,3.1625,3.3625,3.3825,0.040000000000000036,0.020000000000000018 +-3g5yACwYnA/13,-3g5yACwYnA,13,9,bring,3.4625000953674316,3.7225000858306885,True,5.437177401021454e-13,0.25,3.4542782483017413,3.707435340678973,3.3825,3.4625,3.6825,3.7225,0.08000000000000007,0.040000000000000036 +-3g5yACwYnA/13,-3g5yACwYnA,13,10,some,3.762500047683716,3.9625000953674316,True,4.003620351911152e-12,1.7904382944107056,3.7678537500060894,3.962399443995387,3.7625,3.8025,3.9625,3.9625,0.040000000000000036,0.0 +-3g5yACwYnA/13,-3g5yACwYnA,13,11,answers,4.002500057220459,4.322500228881836,True,3.1072377743718294e-12,1.3895716667175293,4.002374694620699,4.31993317940175,4.0025,4.0025,4.3025,4.322500000000001,0.0,0.020000000000000462 +-3g5yACwYnA/13,-3g5yACwYnA,13,12,to,4.362500190734863,4.422500133514404,True,1.1880822931367718e-13,0.25,4.360161068296207,4.4264563847068485,4.3425,4.402500000000001,4.4225,4.4625,0.0600000000000005,0.040000000000000036 +-3g5yACwYnA/13,-3g5yACwYnA,13,13,the,4.462500095367432,4.5625,True,2.673985605692892e-15,0.25,4.469530870157028,4.569707820997299,4.4625,4.482500000000001,4.562500000000001,4.5825000000000005,0.020000000000000462,0.019999999999999574 +-3g5yACwYnA/13,-3g5yACwYnA,13,14,table.,4.602499961853027,4.882500171661377,True,1.6668160992064363e-13,0.25,4.602502613481098,4.882542159056495,4.602500000000001,4.602500000000001,4.8825,4.8825,0.0,0.0 +-3g5yACwYnA/3,-3g5yACwYnA,3,0,We're,0.0024999999441206455,0.16249999403953552,True,1.0417753465441493e-10,4.0,0.01892479479475388,0.3908951550217483,0.0025000000000000005,0.0425,0.1625,0.8624999999999999,0.04,0.7 +-3g5yACwYnA/3,-3g5yACwYnA,3,1,a,0.20250000059604645,0.2224999964237213,True,2.0192024051055024e-13,0.25,0.5809306189576965,0.6009306189578986,0.2025,1.2425,0.2225,1.2625,1.04,1.04 +-3g5yACwYnA/3,-3g5yACwYnA,3,2,huge,0.6025000214576721,0.862500011920929,True,2.080993537212361e-11,4.0,0.8749699312498749,1.1586938794079154,0.6024999999999999,1.3625,0.8624999999999999,1.6625,0.7600000000000001,0.8000000000000002 +-3g5yACwYnA/3,-3g5yACwYnA,3,3,user,1.3624999523162842,1.662500023841858,True,1.8008346550080212e-11,4.0,1.6450011455096585,1.9430967049678605,1.3625,2.2425,1.6625,2.5025,0.8800000000000001,0.8399999999999999 +-3g5yACwYnA/3,-3g5yACwYnA,3,4,of,2.422499895095825,2.4825000762939453,True,2.5086363108356435e-12,0.6720010638237,2.3888363472402654,2.5262128094487677,2.1625,2.6025,2.4425,2.6625,0.43999999999999995,0.2200000000000002 +-3g5yACwYnA/3,-3g5yACwYnA,3,5,adhesives,2.6424999237060547,3.262500047683716,True,1.9735572551193847e-11,4.0,2.6479228501381638,3.2627808520362973,2.5625,2.7225,3.2625,3.2625,0.16000000000000014,0.0 +-3g5yACwYnA/3,-3g5yACwYnA,3,6,for,3.302500009536743,3.4825000762939453,True,5.313816608953914e-10,4.0,3.305240723840881,3.485738646070515,3.3025,3.3025,3.4825,3.4825,0.0,0.0 +-3g5yACwYnA/3,-3g5yACwYnA,3,7,our,3.5625,4.34250020980835,True,1.8105811988577969e-12,0.4850095212459564,3.6584500267844233,4.351316019909387,3.5625,4.202500000000001,4.3425,4.442500000000001,0.6400000000000006,0.10000000000000053 +-3g5yACwYnA/3,-3g5yACwYnA,3,8,"operation,",4.582499980926514,5.142499923706055,True,2.16136266870115e-12,0.5789751410484314,4.582841088198986,5.142577850811578,4.5825000000000005,4.5825000000000005,5.1425,5.1425,0.0,0.0 +-3g5yACwYnA/3,-3g5yACwYnA,3,9,called,5.502500057220459,5.78249979019165,True,7.694975732996934e-12,2.0612919330596924,5.469346469231026,5.787966327255339,5.242500000000001,5.5425,5.782500000000001,5.8425,0.2999999999999998,0.05999999999999961 +-3g5yACwYnA/3,-3g5yACwYnA,3,10,"flocking,",5.862500190734863,6.242499828338623,True,3.7366615877887366e-12,1.0009584426879883,5.862416384166256,6.255591073381409,5.862500000000001,5.862500000000001,6.242500000000001,6.2625,0.0,0.019999999999999574 +-3g5yACwYnA/3,-3g5yACwYnA,3,11,and,6.602499961853027,6.742499828338623,True,3.1151616659494397e-13,0.25,6.595235466538168,6.747981306446609,6.282500000000001,6.6225000000000005,6.702500000000001,6.742500000000001,0.33999999999999986,0.040000000000000036 +-3g5yACwYnA/3,-3g5yACwYnA,3,12,we,7.022500038146973,7.082499980926514,True,3.7330837206195344e-12,1.0,7.025503971831001,7.085534043478729,7.022500000000001,7.022500000000001,7.0825000000000005,7.0825000000000005,0.0,0.0 +-3g5yACwYnA/3,-3g5yACwYnA,3,13,don't,7.162499904632568,7.34250020980835,True,1.3746884186538466e-10,4.0,7.163477889296987,7.344480228729067,7.142500000000001,7.1625000000000005,7.3425,7.3425,0.019999999999999574,0.0 +-3g5yACwYnA/3,-3g5yACwYnA,3,14,have,7.522500038146973,7.662499904632568,True,1.6831982923887386e-14,0.25,7.518314039598685,7.660886400412066,7.482500000000001,7.522500000000001,7.6225000000000005,7.702500000000001,0.040000000000000036,0.08000000000000007 +-3g5yACwYnA/3,-3g5yACwYnA,3,15,the,7.722499847412109,7.882500171661377,True,8.987861453355062e-13,0.25,7.7243982678780885,7.882159094863079,7.7225,7.7625,7.862500000000001,7.8825,0.040000000000000036,0.019999999999999574 +-3g5yACwYnA/3,-3g5yACwYnA,3,16,technical,8.022500038146973,8.662500381469727,True,1.3002188301719508e-12,0.348296195268631,8.011902283844488,8.662006267621967,7.942500000000001,8.0425,8.6625,8.6625,0.09999999999999964,0.0 +-3g5yACwYnA/3,-3g5yACwYnA,3,17,inside,8.72249984741211,9.0024995803833,True,2.5177188350648805e-13,0.25,8.71091233648601,9.001311320857447,8.6825,8.7225,8.9825,9.0025,0.040000000000000924,0.019999999999999574 +-3g5yACwYnA/3,-3g5yACwYnA,3,18,compounding,9.40250015258789,10.22249984741211,True,6.742292813465001e-13,0.25,9.359030940393758,10.232189826338123,9.022499999999999,9.4025,10.2225,10.3025,0.3800000000000008,0.08000000000000007 +-3g5yACwYnA/3,-3g5yACwYnA,3,19,or,10.342499732971191,10.40250015258789,True,2.5491054037561633e-13,0.25,10.398864243814538,10.46224094293215,10.3425,10.5025,10.4025,10.5625,0.16000000000000014,0.16000000000000014 +-3g5yACwYnA/3,-3g5yACwYnA,3,20,the,10.5024995803833,10.682499885559082,True,1.6563738770326852e-13,0.25,10.54237820403615,10.694267109284878,10.4625,10.6625,10.5625,10.782499999999999,0.1999999999999993,0.21999999999999886 +-3g5yACwYnA/3,-3g5yACwYnA,3,21,technical,10.802499771118164,11.242500305175781,True,3.798831735291053e-11,4.0,10.778501265601966,11.232468921558434,10.5825,10.8425,10.9625,11.3825,0.2599999999999998,0.41999999999999993 +-3g5yACwYnA/3,-3g5yACwYnA,3,22,expertise,11.362500190734863,11.90250015258789,True,2.313237492182485e-12,0.6196585893630981,11.339150095742763,11.878519378812266,10.9825,11.4225,11.4825,11.942499999999999,0.4399999999999995,0.4599999999999991 +-3g5yACwYnA/3,-3g5yACwYnA,3,23,to,11.962499618530273,12.022500038146973,True,2.884898700136751e-12,0.772792398929596,11.943536876391573,12.008612822373081,11.6025,12.0025,11.6825,12.0825,0.40000000000000036,0.40000000000000036 +-3g5yACwYnA/3,-3g5yACwYnA,3,24,do,12.1225004196167,12.202500343322754,True,8.551721136784707e-11,4.0,12.100686304121547,12.180724080264547,11.8225,12.1225,11.9025,12.2025,0.3000000000000007,0.3000000000000007 +-3g5yACwYnA/3,-3g5yACwYnA,3,25,these,12.242500305175781,13.162500381469727,True,2.1788269105593727e-11,4.0,12.236831720783304,13.084602136464406,12.0025,12.2425,12.3225,13.1825,0.2400000000000002,0.8599999999999994 +-3g5yACwYnA/3,-3g5yACwYnA,3,26,types,13.202500343322754,13.462499618530273,True,1.7226959442284695e-11,4.0,13.170666582865142,13.46226141424027,12.9225,13.2025,13.3825,13.7225,0.28000000000000114,0.33999999999999986 +-3g5yACwYnA/3,-3g5yACwYnA,3,27,of,13.702500343322754,13.802499771118164,True,6.332336998510213e-12,1.6962751150131226,13.783998039741556,13.89545682407746,13.4625,13.9225,13.7225,14.0025,0.4599999999999991,0.27999999999999936 +-3g5yACwYnA/3,-3g5yACwYnA,3,28,things.,13.922499656677246,14.262499809265137,True,1.0484706852720294e-11,2.808591365814209,13.996225018186697,14.291213862031034,13.9225,14.0625,14.2625,14.3225,0.14000000000000057,0.0600000000000005 +-3g5yACwYnA/2,-3g5yACwYnA,2,0,Key,0.12250000238418579,0.2824999988079071,True,1.2059077694748233e-12,0.46602973341941833,0.12004656147855662,0.2754928971448747,0.0025000000000000005,0.1825,0.2025,0.28250000000000003,0.18,0.08000000000000002 +-3g5yACwYnA/2,-3g5yACwYnA,2,1,Polymer,1.4225000143051147,1.9824999570846558,True,1.2241609635699202e-11,4.0,1.2243119624106564,1.9746772787439282,0.2625,1.4224999999999999,1.5225,2.0225,1.16,0.5 +-3g5yACwYnA/2,-3g5yACwYnA,2,2,brings,2.0425000190734863,2.302500009536743,True,1.1930802483114955e-12,0.46107247471809387,2.0715362022919037,2.346903905400217,1.8625,2.1025,2.2425,2.5225,0.24,0.2799999999999998 +-3g5yACwYnA/2,-3g5yACwYnA,2,3,a,2.502500057220459,2.5225000381469727,True,2.7638483949404824e-12,1.0681045055389404,2.5343152915969336,2.5543152915969847,2.5025,2.6425,2.5225,2.6625,0.14000000000000012,0.14000000000000012 +-3g5yACwYnA/2,-3g5yACwYnA,2,4,technical,2.922499895095825,3.682499885559082,True,6.836649302233155e-11,4.0,2.945770103472421,3.662219509655508,2.9225,2.9225,3.5425,3.6825,0.0,0.14000000000000012 +-3g5yACwYnA/2,-3g5yACwYnA,2,5,aspect,3.762500047683716,4.102499961853027,True,7.779469071971662e-14,0.25,3.762773828203278,4.127419794909451,3.6625,3.8225000000000002,4.1025,4.1625000000000005,0.16000000000000014,0.0600000000000005 +-3g5yACwYnA/2,-3g5yACwYnA,2,6,to,4.382500171661377,4.442500114440918,True,2.0063360695043997e-11,4.0,4.397380835314191,4.461387623157674,4.3825,4.3825,4.442500000000001,4.522500000000001,0.0,0.08000000000000007 +-3g5yACwYnA/2,-3g5yACwYnA,2,7,our,4.502500057220459,4.862500190734863,True,9.0564179419661e-12,3.4999029636383057,4.554801215071612,4.891103084451879,4.5025,4.6225000000000005,4.862500000000001,4.862500000000001,0.1200000000000001,0.0 +-3g5yACwYnA/2,-3g5yACwYnA,2,8,operation,5.462500095367432,6.142499923706055,True,2.41139139905977e-12,0.9318955540657043,5.434152783262643,6.164972441664202,5.282500000000001,5.5025,6.142500000000001,6.3825,0.21999999999999975,0.23999999999999932 +-3g5yACwYnA/2,-3g5yACwYnA,2,9,that,6.222499847412109,6.382500171661377,True,2.55808666350249e-13,0.25,6.2506696287137125,6.425851613401193,6.2225,6.5025,6.3825,6.742500000000001,0.28000000000000025,0.3600000000000003 +-3g5yACwYnA/2,-3g5yACwYnA,2,10,we,6.682499885559082,6.742499828338623,True,3.615498471356421e-13,0.25,6.68956208113118,6.750288014655133,6.6825,6.822500000000001,6.742500000000001,6.8825,0.14000000000000057,0.13999999999999968 +-3g5yACwYnA/2,-3g5yACwYnA,2,11,don't,6.822500228881836,7.002500057220459,True,1.598295940041794e-10,4.0,6.829173580026902,7.0141967823015605,6.822500000000001,6.9225,6.982500000000001,7.1625000000000005,0.09999999999999964,0.17999999999999972 +-3g5yACwYnA/2,-3g5yACwYnA,2,12,have,7.042500019073486,7.202499866485596,True,5.563233250807653e-13,0.25,7.07007014122585,7.245521610851821,7.0425,7.282500000000001,7.202500000000001,7.5425,0.2400000000000002,0.33999999999999986 +-3g5yACwYnA/2,-3g5yACwYnA,2,13,internally.,7.28249979019165,9.182499885559082,True,4.959014102134951e-12,1.9164384603500366,7.391144668115456,9.147154329969988,7.282500000000001,8.2625,9.0825,9.2225,0.9799999999999986,0.14000000000000057 +-3g5yACwYnA/9,-3g5yACwYnA,9,0,We,0.0024999999441206455,0.0625,True,1.3202740289930404e-10,4.0,0.0037092361625596475,0.06376428622874805,0.0025000000000000005,0.0025000000000000005,0.0625,0.0625,0.0,0.0 +-3g5yACwYnA/9,-3g5yACwYnA,9,1,have,0.12250000238418579,0.8824999928474426,True,4.727816987730449e-13,0.4530237317085266,0.24601737150185057,0.9129629357636357,0.1225,0.8025,0.8825,1.0425,0.6799999999999999,0.16000000000000003 +-3g5yACwYnA/9,-3g5yACwYnA,9,2,many,0.9225000143051147,1.1024999618530273,True,3.4017011213069437e-13,0.3259541094303131,0.9672695832607601,1.1443447348089129,0.9225,1.1225,1.1025,1.3225,0.20000000000000007,0.21999999999999997 +-3g5yACwYnA/9,-3g5yACwYnA,9,3,new,1.1825000047683716,1.3224999904632568,True,3.941063621282215e-12,3.7763631343841553,1.262579923107276,1.4144081895232492,1.1824999999999999,1.6025,1.3225,1.8025,0.42000000000000015,0.48 +-3g5yACwYnA/9,-3g5yACwYnA,9,4,opportunities,1.6024999618530273,2.4024999141693115,True,1.088685782149601e-12,1.0431885719299316,1.6586099648067913,2.444467497988983,1.6025,1.8825,2.4025,2.7025,0.28,0.30000000000000027 +-3g5yACwYnA/9,-3g5yACwYnA,9,5,through,2.4825000762939453,2.7825000286102295,True,4.15607964167862e-14,0.25,2.5234634994329452,2.8696162143253496,2.4825,2.8025,2.7825,3.4425,0.3200000000000003,0.6599999999999997 +-3g5yACwYnA/9,-3g5yACwYnA,9,6,the,2.802500009536743,3.442500114440918,True,1.9428814026362096e-12,1.8616865873336792,2.902911114428035,3.464744278514586,2.8025,3.4825,3.4425,3.6025,0.6799999999999997,0.16000000000000014 +-3g5yACwYnA/9,-3g5yACwYnA,9,7,way,3.4825000762939453,3.6024999618530273,True,3.119503787230027e-12,2.9891369342803955,3.5099164031810415,3.63228134889645,3.4825,3.6825,3.6025,3.8225000000000002,0.20000000000000018,0.2200000000000002 +-3g5yACwYnA/9,-3g5yACwYnA,9,8,things,3.682499885559082,4.002500057220459,True,6.429745516393914e-13,0.6161040663719177,3.7145892049209013,4.026147698972161,3.6825,3.9225,3.9825,4.2625,0.23999999999999977,0.28000000000000025 +-3g5yACwYnA/9,-3g5yACwYnA,9,9,have,4.022500038146973,4.162499904632568,True,1.5793911859775245e-13,0.25,4.060617069421903,4.224488988758646,4.022500000000001,4.3025,4.1625000000000005,4.522500000000001,0.27999999999999936,0.3600000000000003 +-3g5yACwYnA/9,-3g5yACwYnA,9,10,changed,4.202499866485596,4.522500038146973,True,2.325777157669018e-12,2.228580951690674,4.267085991580041,4.5723446469859,4.202500000000001,4.5825000000000005,4.522500000000001,4.862500000000001,0.3799999999999999,0.33999999999999986 +-3g5yACwYnA/9,-3g5yACwYnA,9,11,through,4.582499980926514,5.582499980926514,True,1.854727959757496e-12,1.7772172689437866,4.6221517393402145,5.554001297056343,4.5825000000000005,4.8825,5.4625,5.6225000000000005,0.2999999999999998,0.16000000000000014 +-3g5yACwYnA/9,-3g5yACwYnA,9,12,the,5.622499942779541,5.742499828338623,True,3.626375675441773e-12,3.4748260974884033,5.595031140793692,5.718768123192464,5.522500000000001,5.6625000000000005,5.6225000000000005,5.8025,0.13999999999999968,0.17999999999999972 +-3g5yACwYnA/9,-3g5yACwYnA,9,13,"years,",5.78249979019165,5.982500076293945,True,3.45286983954949e-14,0.25,5.757698982112918,5.970677998071189,5.6425,5.8425,5.902500000000001,6.0425,0.20000000000000018,0.13999999999999968 +-3g5yACwYnA/9,-3g5yACwYnA,9,14,looking,6.042500019073486,6.442500114440918,True,1.2439189218602098e-12,1.1919344663619995,6.0297255832126435,6.383957853422528,5.9225,6.0825000000000005,6.282500000000001,6.442500000000001,0.16000000000000014,0.16000000000000014 +-3g5yACwYnA/9,-3g5yACwYnA,9,15,for,6.462500095367432,6.5625,True,1.4023155466696968e-12,1.343711495399475,6.419190410852593,6.540302343999718,6.3425,6.4625,6.482500000000001,6.562500000000001,0.1200000000000001,0.08000000000000007 +-3g5yACwYnA/9,-3g5yACwYnA,9,16,new,6.642499923706055,6.84250020980835,True,1.043613546275468e-12,1.0,6.635691555353821,6.833978589755013,6.642500000000001,6.642500000000001,6.8425,6.8425,0.0,0.0 +-3g5yACwYnA/9,-3g5yACwYnA,9,17,niche,6.862500190734863,7.0625,True,5.4846457372493065e-14,0.25,6.854528859600319,7.055299959028502,6.862500000000001,6.862500000000001,7.062500000000001,7.062500000000001,0.0,0.0 +-3g5yACwYnA/9,-3g5yACwYnA,9,18,"high-end,",7.082499980926514,7.462500095367432,True,7.439023897749808e-13,0.7128140330314636,7.0769385969042,7.45691194296881,7.0825000000000005,7.0825000000000005,7.4625,7.4625,0.0,0.0 +-3g5yACwYnA/9,-3g5yACwYnA,9,19,value-added,7.5625,8.082500457763672,True,5.798322705221487e-14,0.25,7.552404120714275,8.074980337515674,7.522500000000001,7.562500000000001,8.0425,8.0825,0.040000000000000036,0.03999999999999915 +-3g5yACwYnA/9,-3g5yACwYnA,9,20,products.,8.102499961853027,8.662500381469727,True,2.1248971752616495e-14,0.25,8.098459094614249,8.634617109598796,8.1025,8.1025,8.5425,8.6825,0.0,0.1399999999999988 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,0,Noncompliance,0.5425000190734863,1.5425000190734863,True,3.009791851513177e-13,4.0,0.5421899065110246,1.5434444401076381,0.5225,0.5425,1.5425,1.5425,0.020000000000000018,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,1,can,1.6825000047683716,1.8624999523162842,True,4.914635593020883e-14,0.9133073091506958,1.682499728861315,1.8625016311882543,1.6824999999999999,1.6824999999999999,1.8625,1.8625,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,2,result,1.9824999570846558,2.502500057220459,True,5.090972131707727e-13,4.0,1.9826826486872584,2.502627463381576,1.9825,1.9825,2.5025,2.5025,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,3,in,2.6024999618530273,2.702500104904175,True,1.6868163089196406e-14,0.3134681284427643,2.602500402040593,2.7114411198718202,2.6025,2.6025,2.7025,2.7225,0.0,0.020000000000000018 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,4,legal,2.8424999713897705,3.122499942779541,True,1.6298654049659578e-13,3.0288469791412354,2.8319148446350573,3.108045806654291,2.8025,2.8425,3.0625,3.1225,0.03999999999999959,0.06000000000000005 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,5,liability,3.1424999237060547,3.802500009536743,True,4.397796688447586e-13,4.0,3.1425001068073284,3.8025137671985,3.1425,3.1425,3.8025,3.8025,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,6,to,3.9825000762939453,4.142499923706055,True,2.3713054631870067e-13,4.0,3.982500462639652,4.142499970675897,3.9825,3.9825,4.1425,4.1425,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,7,you,4.262499809265137,4.522500038146973,True,9.180395498160389e-15,0.25,4.256718628077809,4.512681988741261,4.202500000000001,4.2625,4.4225,4.522500000000001,0.05999999999999961,0.10000000000000053 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,8,and,4.5625,5.142499923706055,True,9.738124342279983e-14,1.8096764087677002,4.610781303553796,5.143268143927736,4.562500000000001,5.0425,5.1425,5.1425,0.47999999999999954,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,9,to,5.242499828338623,5.322500228881836,True,1.2475421086802219e-13,2.318359613418579,5.242284573869038,5.322497097245752,5.242500000000001,5.242500000000001,5.322500000000001,5.322500000000001,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,10,the,5.422500133514404,5.522500038146973,True,5.847647127806e-14,1.0866926908493042,5.420521893684469,5.521005673422197,5.402500000000001,5.4225,5.522500000000001,5.522500000000001,0.019999999999999574,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,11,school,5.542500019073486,5.802499771118164,True,5.076406095748951e-15,0.25,5.541309582381759,5.801309274139924,5.5425,5.5425,5.8025,5.8025,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,12,district,5.822500228881836,6.182499885559082,True,2.3873014813431616e-16,0.25,5.822409113735198,6.18241082307903,5.822500000000001,5.822500000000001,6.1825,6.1825,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,13,in,6.202499866485596,6.262499809265137,True,3.187962021713249e-15,0.25,6.202413110773365,6.2624131946284285,6.202500000000001,6.202500000000001,6.2625,6.2625,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,14,which,6.28249979019165,6.462500095367432,True,3.9412292157998865e-16,0.25,6.282413518600741,6.46250329822077,6.282500000000001,6.282500000000001,6.4625,6.4625,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,15,you,6.482500076293945,6.622499942779541,True,4.329610265143072e-14,0.804589569568634,6.482504276688287,6.617728718552279,6.482500000000001,6.482500000000001,6.5825000000000005,6.6225000000000005,0.0,0.040000000000000036 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,16,are,6.642499923706055,6.742499828338623,True,4.5697071750531656e-14,0.8492078185081482,6.642361698991119,6.743794056590974,6.642500000000001,6.642500000000001,6.742500000000001,6.742500000000001,0.0,0.0 +-3nNcZdcdvU/5,-3nNcZdcdvU,5,17,employed.,6.84250020980835,7.28249979019165,True,6.300834149135931e-14,1.170910358428955,6.83813239815432,7.282623043355807,6.822500000000001,6.8425,7.282500000000001,7.282500000000001,0.019999999999999574,0.0 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,0,”,nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,1,[President,0.10249999910593033,0.762499988079071,True,8.245064109539332e-14,4.0,0.10250473972383489,0.7625327724371536,0.10250000000000001,0.10250000000000001,0.7625,0.7625,0.0,0.0 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,2,Ronald,0.8224999904632568,1.8025000095367432,True,5.068065997592048e-16,0.25,0.854274069167481,1.7270714047834743,0.8225,1.0225,1.3625,2.0425,0.19999999999999996,0.6799999999999999 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,3,Reagan:],1.8624999523162842,2.802500009536743,True,1.1842246509850916e-14,1.0,1.9694596577449979,2.8033453188270716,1.6625,2.2825,2.8025,2.8225,0.6200000000000001,0.019999999999999574 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,4,"""Look",2.882499933242798,3.0225000381469727,True,2.492327701099535e-14,2.104607105255127,2.881426774537937,3.0216973335913506,2.8825,2.8825,3.0225,3.0225,0.0,0.0 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,5,at,3.1024999618530273,3.1624999046325684,True,2.696593126813346e-15,0.25,3.1034472692660957,3.16550226599371,3.1025,3.1425,3.1625,3.2225,0.040000000000000036,0.06000000000000005 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,6,the,3.242500066757202,3.3424999713897705,True,2.8035099876354622e-14,2.367380142211914,3.2418077886934986,3.342347080125065,3.2425,3.2425,3.3425,3.3425,0.0,0.0 +-HwX2H8Z4hY/2,-HwX2H8Z4hY,2,7,record,3.422499895095825,3.9024999141693115,True,5.635536779396251e-16,0.25,3.421806202848189,3.881243156703797,3.4225,3.4225,3.8025,3.9025,0.0,0.09999999999999964 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,0,"""",nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,1,President,0.8025000095367432,1.2424999475479126,True,1.1130892147120756e-14,0.25,0.7991785910278454,1.249418363734453,0.8025,0.8025,1.2425,1.2625,0.0,0.020000000000000018 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,2,Ronald,1.3224999904632568,1.662500023841858,True,6.521055939158471e-13,3.265170097351074,1.3182879263108291,1.657037437672821,1.2625,1.3225,1.6025,1.6625,0.06000000000000005,0.06000000000000005 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,3,Reagan,1.7024999856948853,2.122499942779541,True,1.9971566447059969e-13,1.0,1.7002046832597368,2.1152442116829513,1.7025,1.7025,2.0625,2.1225,0.0,0.06000000000000005 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,4,blamed,2.202500104904175,2.5625,True,1.681951561534334e-13,0.8421730995178223,2.1942407816196767,2.5565269463501545,2.1225,2.2025,2.5025,2.5625,0.08000000000000007,0.06000000000000005 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,5,the,2.6624999046325684,2.762500047683716,True,1.4306970931858738e-14,0.25,2.643355740531605,2.752176231037962,2.6025,2.6625,2.7225,2.7625,0.06000000000000005,0.040000000000000036 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,6,professional,2.7825000286102295,3.422499895095825,True,1.6846922891011057e-14,0.25,2.7774452139102097,3.4217504683401407,2.7425,2.7825,3.4225,3.4225,0.040000000000000036,0.0 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,7,bureaucracy,3.4625000953674316,4.202499866485596,True,5.344916132951627e-13,2.676262855529785,3.4615893755070632,4.158197134262134,3.4625,3.4625,4.1425,4.202500000000001,0.0,0.0600000000000005 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,8,of,4.302499771118164,4.382500171661377,True,8.464278540218362e-13,4.0,4.265456447231751,4.360272046146851,4.202500000000001,4.3025,4.322500000000001,4.3825,0.09999999999999964,0.05999999999999961 +-HwX2H8Z4hY/5,-HwX2H8Z4hY,5,9,education,4.462500095367432,5.082499980926514,True,6.528327141028245e-13,3.268810749053955,4.462466272651668,5.082501771556385,4.4625,4.4625,5.0825000000000005,5.0825000000000005,0.0,0.0 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,0,And,0.0024999999441206455,0.6424999833106995,True,9.006679205073899e-16,0.25,0.049993577900290236,0.6401664878744063,0.0025000000000000005,0.2425,0.6224999999999999,0.6425,0.24,0.020000000000000018 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,1,in,0.6825000047683716,0.762499988079071,True,1.0384882278386635e-14,0.25,0.6755059356561959,0.7452473237909909,0.6625,0.6825,0.7224999999999999,0.7625,0.020000000000000018,0.040000000000000036 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,2,"part,",0.8424999713897705,1.1825000047683716,True,4.603873096013615e-14,0.3257012665271759,0.8366663344434105,1.175919532391122,0.7625,0.8424999999999999,1.1025,1.1824999999999999,0.07999999999999996,0.07999999999999985 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,3,Al,1.5425000190734863,1.622499942779541,True,1.3575890628683696e-12,4.0,1.542340600155332,1.622350825487453,1.5425,1.5425,1.6225,1.6225,0.0,0.0 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,4,Shanker,1.722499966621399,2.1624999046325684,True,1.41352627844836e-13,1.0,1.7221858829602623,2.1581962257056984,1.7225,1.7225,2.1025,2.1625,0.0,0.06000000000000005 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,5,did,2.262500047683716,2.4024999141693115,True,8.53964848054195e-13,4.0,2.2624871936417077,2.405549344077747,2.2625,2.2625,2.4025,2.4025,0.0,0.0 +-HwX2H8Z4hY/6,-HwX2H8Z4hY,6,6,too,2.682499885559082,2.822499990463257,True,9.367995962294984e-12,4.0,2.678787842175452,2.8245599587910464,2.6825,2.6825,2.8025,2.8425,0.0,0.03999999999999959 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,0,It,0.5625,0.6424999833106995,True,9.704259118015809e-15,0.25,0.3968797872067635,0.6168155228213217,0.0625,0.5824999999999999,0.5824999999999999,0.6425,0.5199999999999999,0.06000000000000005 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,1,is,0.6825000047683716,0.7425000071525574,True,1.4060067942810867e-13,0.25,0.6826864336953968,0.7429342737517168,0.6825,0.6825,0.7424999999999999,0.7424999999999999,0.0,0.0 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,2,a,0.8424999713897705,0.862500011920929,True,3.836665414622825e-13,0.2704606354236603,0.8431059245975748,0.863105924597575,0.8424999999999999,0.8424999999999999,0.8624999999999999,0.8624999999999999,0.0,0.0 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,3,word,0.9225000143051147,1.162500023841858,True,2.349814407723999e-13,0.25,0.9232465709824628,1.1633531719563064,0.9225,0.9225,1.1624999999999999,1.1624999999999999,0.0,0.0 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,4,which,1.2625000476837158,1.5625,True,5.4473098801870526e-14,0.25,1.2682948092150728,1.5630203083225693,1.2625,1.3225,1.5625,1.5625,0.06000000000000005,0.0 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,5,the,1.722499966621399,1.8224999904632568,True,8.272986245713709e-13,0.5831931829452515,1.6909958021630012,1.7986297285033759,1.6225,1.7225,1.7225,1.8225,0.09999999999999987,0.10000000000000009 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,6,administrator,1.8825000524520874,2.622499942779541,True,7.934183908833714e-13,0.559309720993042,1.8591177881897383,2.7274044722357593,1.8025,1.8825,2.6225,3.1625,0.08000000000000007,0.54 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,7,uses,2.9024999141693115,3.1624999046325684,True,2.1700481309897685e-13,0.25,2.968049678105385,3.2345771687388063,2.8825,3.2425,3.1625,3.5025,0.3600000000000003,0.33999999999999986 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,8,when,3.242500066757202,3.442500114440918,True,4.379272010128499e-13,0.3087109625339508,3.333607512728239,3.547610849410154,3.2425,3.6825,3.4425,3.9025,0.43999999999999995,0.45999999999999996 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,9,he,3.502500057220459,3.5625,True,1.9151127623844022e-13,0.25,3.6091286554749216,3.6789170759396757,3.5025,3.9625,3.5625,4.022500000000001,0.45999999999999996,0.46000000000000085 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,10,turns,3.6424999237060547,3.9024999141693115,True,2.0098356572767484e-12,1.416806936264038,3.750671620423674,3.986732770438924,3.6425,4.062500000000001,3.9025,4.2625,0.4200000000000008,0.3600000000000003 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,11,around,3.9625000953674316,4.262499809265137,True,3.172354393066179e-11,4.0,4.042443095688754,4.331695960114718,3.9625,4.3025,4.2625,4.5425,0.3400000000000003,0.28000000000000025 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,12,anything,4.302499771118164,5.002500057220459,True,4.246567507359966e-12,2.993561267852783,4.397334396251662,5.0187542042154245,4.3025,4.562500000000001,5.0025,5.1225000000000005,0.2600000000000007,0.1200000000000001 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,13,which,5.202499866485596,5.482500076293945,True,1.0097850507151396e-11,4.0,5.1998952268885485,5.481770232068269,5.1825,5.202500000000001,5.482500000000001,5.482500000000001,0.020000000000000462,0.0 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,14,he,5.542500019073486,5.602499961853027,True,3.1471665009295824e-13,0.25,5.541826700619963,5.601893321673665,5.5425,5.5425,5.602500000000001,5.602500000000001,0.0,0.0 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,15,doesn't,5.662499904632568,6.002500057220459,True,4.0290708269719033e-11,4.0,5.664100729682788,6.0016396736273805,5.6625000000000005,5.702500000000001,6.0025,6.0025,0.040000000000000036,0.0 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,16,like,6.042500019073486,6.182499885559082,True,2.3577168863087028e-12,1.662041187286377,6.0421210584664955,6.251301613627984,6.0425,6.0425,6.1825,6.322500000000001,0.0,0.14000000000000057 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,17,that,6.242499828338623,6.402500152587891,True,9.430432129642341e-12,4.0,6.31569748562974,6.490365143363123,6.242500000000001,6.402500000000001,6.402500000000001,6.602500000000001,0.16000000000000014,0.20000000000000018 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,18,the,6.462500095367432,6.602499961853027,True,3.4823832706365465e-10,4.0,6.546923966814362,6.670741888996065,6.4625,6.6625000000000005,6.602500000000001,6.7625,0.20000000000000018,0.15999999999999925 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,19,teacher,6.662499904632568,7.0625,True,3.151389912914304e-11,4.0,6.7149365146030195,7.083825396014788,6.6625000000000005,6.782500000000001,7.062500000000001,7.1225000000000005,0.1200000000000001,0.05999999999999961 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,20,is,7.162499904632568,7.262499809265137,True,2.1730292912303106e-11,4.0,7.167127941420237,7.250665423256899,7.1625000000000005,7.1825,7.2225,7.2625,0.019999999999999574,0.040000000000000036 +-HwX2H8Z4hY/9,-HwX2H8Z4hY,9,21,doing,7.322500228881836,7.582499980926514,True,2.088004595612869e-11,4.0,7.323569851270532,7.58443002944152,7.322500000000001,7.322500000000001,7.5825000000000005,7.602500000000001,0.0,0.020000000000000462 +-NFrJFQijFE/1,-NFrJFQijFE,1,0,Structural,0.0024999999441206455,0.7225000262260437,True,3.124166550461105e-11,0.801537275314331,0.029607444381030804,0.6871020932567873,0.0025000000000000005,0.10250000000000001,0.4825,0.9225,0.1,0.44 +-NFrJFQijFE/1,-NFrJFQijFE,1,1,mounts,1.122499942779541,1.7825000286102295,True,3.382181687494601e-11,0.8677337765693665,0.7741501022267345,1.168869413851003,0.5425,1.0425,0.9025,1.4625,0.5,0.5599999999999999 +-NFrJFQijFE/1,-NFrJFQijFE,1,2,inside,1.8424999713897705,2.242500066757202,True,3.242017765359151e-11,0.8317732214927673,1.259193099460418,1.646948133757638,0.9824999999999999,1.5625,1.3625,1.9425,0.5800000000000001,0.5799999999999998 +-NFrJFQijFE/1,-NFrJFQijFE,1,3,have,2.382499933242798,2.7825000286102295,True,3.251355781830334e-11,0.8341690301895142,1.7308771690731846,1.958774697749872,1.4625,2.0225,1.6824999999999999,2.2625,0.56,0.5800000000000003 +-NFrJFQijFE/1,-NFrJFQijFE,1,4,to,3.0625,3.122499942779541,True,3.055768832416206e-11,0.7839891314506531,2.040202773527604,2.1314457321513656,1.7625,2.3625,1.8425,2.4425,0.5999999999999999,0.5999999999999999 +-NFrJFQijFE/1,-NFrJFQijFE,1,5,be,3.1624999046325684,3.2225000858306885,True,2.7543876901514608e-11,0.7066667079925537,2.2165689766668426,2.3095375530237123,1.9224999999999999,2.5225,2.0025,2.6225,0.6000000000000001,0.6200000000000001 +-NFrJFQijFE/1,-NFrJFQijFE,1,6,properly,3.242500066757202,3.6624999046325684,True,3.094473635667505e-11,0.7939192652702332,2.398161975532348,2.939312401374726,2.0825,2.7025,2.5825,3.2225,0.6200000000000001,0.6400000000000001 +-NFrJFQijFE/1,-NFrJFQijFE,1,7,stress,3.7825000286102295,4.042500019073486,True,4.0694180664102575e-11,1.0440514087677002,3.024703822620534,3.3952124304109335,2.6625,3.3025,3.0825,3.6825,0.6400000000000001,0.6000000000000001 +-NFrJFQijFE/1,-NFrJFQijFE,1,8,analyzed,4.0625,4.482500076293945,True,5.706426650653462e-11,1.4640429019927979,3.4734230005814695,3.95665797695199,3.1625,3.7625,3.6625,4.202500000000001,0.6000000000000001,0.5400000000000005 +-NFrJFQijFE/1,-NFrJFQijFE,1,9,so,4.502500057220459,4.5625,True,3.726018105165707e-11,0.955948531627655,4.019371413642997,4.09926351081791,3.7625,4.2625,3.8425,4.322500000000001,0.5,0.48000000000000087 +-NFrJFQijFE/1,-NFrJFQijFE,1,10,we,4.582499980926514,4.682499885559082,True,4.315695370515904e-11,1.107236385345459,4.158343759812449,4.2382602103512115,3.9225,4.3825,4.0025,4.4625,0.4600000000000004,0.45999999999999996 +-NFrJFQijFE/1,-NFrJFQijFE,1,11,make,4.702499866485596,4.862500190734863,True,5.602865393861123e-11,1.437473177909851,4.297877403832084,4.498025124451961,4.062500000000001,4.5025,4.2625,4.6825,0.4399999999999995,0.41999999999999993 +-NFrJFQijFE/1,-NFrJFQijFE,1,12,sure,4.922500133514404,5.0625,True,5.5529952164290464e-11,1.4246784448623657,4.5595462645139255,4.759348019483343,4.322500000000001,4.742500000000001,4.5425,4.9225,0.41999999999999993,0.3799999999999999 +-NFrJFQijFE/1,-NFrJFQijFE,1,13,all,5.082499980926514,5.182499885559082,True,4.774074538471673e-11,1.2248382568359375,4.817843713841208,4.9557359749111045,4.6425,4.9625,4.782500000000001,5.102500000000001,0.3200000000000003,0.3200000000000003 +-NFrJFQijFE/1,-NFrJFQijFE,1,14,that,5.202499866485596,5.34250020980835,True,5.2850689102879045e-11,1.3559391498565674,5.012945479106424,5.209031399250358,4.8425,5.1425,5.062500000000001,5.322500000000001,0.2999999999999998,0.2599999999999998 +-NFrJFQijFE/1,-NFrJFQijFE,1,15,happens,5.362500190734863,5.642499923706055,True,5.486522347553091e-11,1.4076241254806519,5.265253840657979,5.6252282574922905,5.1425,5.362500000000001,5.5825000000000005,5.6425,0.22000000000000064,0.05999999999999961 +-NFrJFQijFE/2,-NFrJFQijFE,2,0,So,1.122499942779541,1.2424999475479126,True,2.0999696732503133e-14,0.3740757703781128,0.7017702038054376,0.8164313921794365,0.6625,0.8225,0.7224999999999999,0.9624999999999999,0.16000000000000003,0.24 +-NFrJFQijFE/2,-NFrJFQijFE,2,1,we,1.2825000286102295,1.3825000524520874,True,1.8122491829137936e-14,0.3228229880332947,0.9301739611043676,1.0355676938406366,0.7825,1.1225,0.8825,1.2425,0.3400000000000001,0.36 +-NFrJFQijFE/2,-NFrJFQijFE,2,2,coordinate,1.6425000429153442,2.0824999809265137,True,2.99360789792185e-14,0.5332630276679993,1.1385153786376387,1.8848721368518628,0.9624999999999999,1.3425,1.6824999999999999,2.0425,0.3800000000000001,0.3600000000000001 +-NFrJFQijFE/2,-NFrJFQijFE,2,3,with,2.1024999618530273,2.242500066757202,True,6.905049177840378e-14,1.2300232648849487,1.955838283594859,2.1544054792982386,1.7625,2.1025,1.9825,2.2625,0.3400000000000001,0.28000000000000025 +-NFrJFQijFE/2,-NFrJFQijFE,2,4,all,2.262500047683716,2.362499952316284,True,5.794130230945757e-14,1.0321309566497803,2.2032026778324427,2.3225781228227205,2.0625,2.3025,2.2025,2.4225,0.2400000000000002,0.21999999999999975 +-NFrJFQijFE/2,-NFrJFQijFE,2,5,the,2.382499933242798,2.4825000762939453,True,5.4333795763365084e-14,0.9678690433502197,2.3595980088641553,2.4785183487033846,2.2425,2.4625,2.3625,2.5825,0.21999999999999975,0.2200000000000002 +-NFrJFQijFE/2,-NFrJFQijFE,2,6,proper,2.5625,2.7825000286102295,True,4.613511653327011e-14,0.8218227624893188,2.5235697929220096,2.7911478799564198,2.3825,2.6425,2.6825,2.9025,0.26000000000000023,0.21999999999999975 +-NFrJFQijFE/2,-NFrJFQijFE,2,7,technical,2.802500009536743,3.242500066757202,True,2.8803697572693174e-14,0.5130914449691772,2.826699438084622,3.324501218236374,2.7225,2.9425,3.2025,3.5625,0.21999999999999975,0.3599999999999999 +-NFrJFQijFE/2,-NFrJFQijFE,2,8,fields,3.622499942779541,3.9625000953674316,True,3.771829203136345e-12,4.0,3.567640087175455,3.9341314603260984,3.3425,3.6225,3.8825,3.9625,0.28000000000000025,0.08000000000000007 +-NFrJFQijFE/2,-NFrJFQijFE,2,9,to,4.102499961853027,4.162499904632568,True,2.0974448035598198e-13,3.736259937286377,4.002873380071735,4.076475277349137,3.9025,4.1025,3.9625,4.1625000000000005,0.20000000000000018,0.20000000000000062 +-NFrJFQijFE/2,-NFrJFQijFE,2,10,get,4.182499885559082,4.322500228881836,True,2.997963680149811e-14,0.5340389609336853,4.131802025449857,4.282693539325499,4.1025,4.242500000000001,4.2625,4.3825,0.14000000000000057,0.1200000000000001 +-NFrJFQijFE/2,-NFrJFQijFE,2,11,ready,4.34250020980835,4.642499923706055,True,1.2902478564724706e-12,4.0,4.348985787804194,4.638174202884239,4.3425,4.4225,4.6225000000000005,4.6425,0.08000000000000007,0.019999999999999574 +-NFrJFQijFE/2,-NFrJFQijFE,2,12,for,4.702499866485596,4.802499771118164,True,3.9598769955347807e-14,0.7053883075714111,4.69689650444899,4.800728795198717,4.6625000000000005,4.702500000000001,4.782500000000001,4.822500000000001,0.040000000000000036,0.040000000000000036 +-NFrJFQijFE/2,-NFrJFQijFE,2,13,the,4.822500228881836,4.962500095367432,True,2.13347828986743e-12,4.0,4.832524953971189,4.960742471002819,4.822500000000001,4.8425,4.9625,4.9625,0.019999999999999574,0.0 +-NFrJFQijFE/2,-NFrJFQijFE,2,14,instrument,4.982500076293945,5.582499980926514,True,5.864949639226152e-14,1.0447462797164917,4.981819918289069,5.583200022323766,4.982500000000001,4.982500000000001,5.5825000000000005,5.5825000000000005,0.0,0.0 +-NFrJFQijFE/2,-NFrJFQijFE,2,15,to,6.0625,6.142499923706055,True,2.7822413291430856e-14,0.4956114590167999,6.008112967011355,6.1294094160023525,5.7625,6.062500000000001,6.0825000000000005,6.142500000000001,0.3000000000000007,0.0600000000000005 +-NFrJFQijFE/2,-NFrJFQijFE,2,16,arrive,6.202499866485596,6.502500057220459,True,1.3836344179771198e-12,4.0,6.202900777167125,6.502181568618448,6.202500000000001,6.202500000000001,6.5025,6.5025,0.0,0.0 +-NFrJFQijFE/2,-NFrJFQijFE,2,17,here,6.542500019073486,6.682499885559082,True,7.368213569662607e-13,4.0,6.542190924116508,6.682470262173858,6.5425,6.5425,6.6825,6.6825,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,0,What,0.0024999999441206455,0.8025000095367432,True,5.184272455771577e-11,4.0,0.0025000003549047693,0.8035597524626871,0.0025000000000000005,0.0025000000000000005,0.8025,0.8025,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,1,ever,1.6425000429153442,1.9225000143051147,True,4.004269246911385e-13,4.0,1.6529561096015108,1.911600849839455,1.6425,1.7225,1.8825,1.9224999999999999,0.07999999999999985,0.039999999999999813 +-THoVjtIkeU/12,-THoVjtIkeU,12,2,we,2.002500057220459,2.0625,True,3.836271849234213e-14,0.6021820306777954,2.0016582942541135,2.061671197113673,2.0025,2.0025,2.0625,2.0625,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,3,turn,2.1424999237060547,2.302500009536743,True,1.717639139068043e-15,0.25,2.1415002094996507,2.301430511112869,2.1425,2.1425,2.3025,2.3025,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,4,our,2.322499990463257,2.442500114440918,True,6.326280374124166e-14,0.9930402636528015,2.3216422600531423,2.441643863547024,2.3225,2.3225,2.4425,2.4425,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,5,attention,2.4825000762939453,2.882499933242798,True,1.9333507962838092e-15,0.25,2.4818262028628437,2.882207397831878,2.4825,2.4825,2.8825,2.8825,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,6,to,2.922499895095825,3.0625,True,6.509613540480602e-14,1.0218181610107422,2.9226896623999803,3.0626401735658586,2.9225,2.9225,3.0625,3.0625,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,7,is,3.182499885559082,3.2825000286102295,True,3.3738997381495273e-13,4.0,3.1823176206620607,3.2825267449727344,3.1825,3.1825,3.2825,3.2825,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,8,what,3.322499990463257,3.502500057220459,True,1.615317071995779e-14,0.25355735421180725,3.3225591942568835,3.5025797752496106,3.3225000000000002,3.3225000000000002,3.5025,3.5025,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,9,grows,3.5225000381469727,3.882499933242798,True,3.4992076239619835e-14,0.5492728352546692,3.522784014159437,3.8827429304851,3.5225,3.5225,3.8825,3.8825,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,10,and,4.362500190734863,4.482500076293945,True,9.108250991537309e-14,1.4297280311584473,4.362460354649206,4.482600317036873,4.362500000000001,4.362500000000001,4.482500000000001,4.482500000000001,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,11,so,4.542500019073486,4.642499923706055,True,1.8818568665174285e-12,4.0,4.542616593028849,4.642609848982019,4.5425,4.5425,4.6425,4.6425,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,12,if,4.682499885559082,4.78249979019165,True,6.370618144341603e-14,1.0,4.73088135814891,4.8068325905395515,4.6825,4.7625,4.7625,4.822500000000001,0.08000000000000007,0.0600000000000005 +-THoVjtIkeU/12,-THoVjtIkeU,12,13,we,4.882500171661377,4.962500095367432,True,6.87291274782155e-14,1.078845500946045,4.882564385938244,4.962677005890677,4.8825,4.8825,4.9625,4.9625,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,14,believe,5.022500038146973,5.522500038146973,True,2.0615089225527877e-13,3.235963821411133,5.0245719541936245,5.522680156939918,5.022500000000001,5.022500000000001,5.522500000000001,5.522500000000001,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,15,that,5.582499980926514,5.762499809265137,True,2.316116514818555e-15,0.25,5.582652937970199,5.762661710917487,5.5825000000000005,5.5825000000000005,5.7625,5.7625,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,16,anything,5.78249979019165,6.122499942779541,True,1.0723705621683722e-14,0.25,5.7857325380603175,6.128300725814943,5.782500000000001,5.8025,6.1225000000000005,6.1225000000000005,0.019999999999999574,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,17,is,6.182499885559082,6.262499809265137,True,5.072557499909147e-13,4.0,6.186674312374733,6.2654187095178235,6.1825,6.1825,6.242500000000001,6.2625,0.0,0.019999999999999574 +-THoVjtIkeU/12,-THoVjtIkeU,12,18,"possible,",6.302499771118164,6.742499828338623,True,4.263187974298463e-15,0.25,6.30960288496603,6.754539570207679,6.3025,6.3025,6.742500000000001,6.742500000000001,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,19,if,6.78249979019165,6.84250020980835,True,1.6299522766650282e-14,0.25585463643074036,6.813844945293333,6.877896626746542,6.782500000000001,6.782500000000001,6.8425,6.8425,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,20,we,6.902500152587891,7.042500019073486,True,8.570621968205516e-13,4.0,6.945868750376086,7.086394513895723,6.902500000000001,6.902500000000001,7.0425,7.0425,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,21,believe,7.5625,8.142499923706055,True,4.034537461061749e-13,4.0,7.495042199965977,8.16664224609275,7.142500000000001,7.562500000000001,8.0825,8.1425,0.41999999999999993,0.0600000000000005 +-THoVjtIkeU/12,-THoVjtIkeU,12,22,that,8.542499542236328,8.802499771118164,True,9.425311009100823e-14,1.4794970750808716,8.552403409813959,8.814869143102763,8.5425,8.5825,8.8025,8.862499999999999,0.03999999999999915,0.05999999999999872 +-THoVjtIkeU/12,-THoVjtIkeU,12,23,social,8.90250015258789,9.542499542236328,True,5.2791052779221914e-12,4.0,8.926572150764354,9.554650222126032,8.8425,9.0825,9.282499999999999,9.6825,0.2400000000000002,0.40000000000000036 +-THoVjtIkeU/12,-THoVjtIkeU,12,24,justice,9.602499961853027,10.082500457763672,True,3.2318182418417107e-12,4.0,9.622228193294516,10.075158284652437,9.4625,9.782499999999999,9.8825,10.1225,0.3199999999999985,0.2400000000000002 +-THoVjtIkeU/12,-THoVjtIkeU,12,25,can,10.182499885559082,10.322500228881836,True,9.062416344695484e-14,1.4225332736968994,10.163757654882376,10.305245554736647,10.022499999999999,10.1825,10.1225,10.3225,0.16000000000000014,0.1999999999999993 +-THoVjtIkeU/12,-THoVjtIkeU,12,26,be,10.422499656677246,10.482500076293945,True,1.1201589785944654e-12,4.0,10.406784621799975,10.467071219758102,10.2625,10.4225,10.3225,10.4825,0.16000000000000014,0.16000000000000014 +-THoVjtIkeU/12,-THoVjtIkeU,12,27,achieved,10.522500038146973,10.942500114440918,True,2.057594986591433e-14,0.3229820132255554,10.510673160622034,10.934793906175887,10.4225,10.522499999999999,10.942499999999999,10.942499999999999,0.09999999999999964,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,28,and,10.982500076293945,11.082500457763672,True,7.772953694541382e-15,0.25,10.975281306995331,11.075634516296919,10.9825,10.9825,11.0825,11.0825,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,29,if,11.102499961853027,11.162500381469727,True,1.2482614429403481e-14,0.25,11.096370572360204,11.156537360099648,11.1025,11.1025,11.1625,11.1625,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,30,we,11.182499885559082,11.242500305175781,True,1.2027428749131208e-13,1.8879531621932983,11.177150273118796,11.237494385446567,11.1825,11.1825,11.2425,11.2425,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,31,believe,11.322500228881836,11.822500228881836,True,1.71007942507094e-13,2.6843225955963135,11.317170351965828,11.81544774843011,11.3225,11.3225,11.8225,11.8225,0.0,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,32,in,11.842499732971191,11.962499618530273,True,1.5597131875974557e-13,2.448291778564453,11.874989445701733,11.986233154258349,11.8425,11.942499999999999,11.9625,12.0425,0.09999999999999964,0.08000000000000007 +-THoVjtIkeU/12,-THoVjtIkeU,12,33,"youth,",12.102499961853027,12.40250015258789,True,3.8225936223887716e-14,0.6000349521636963,12.07514111375613,12.372758250652677,12.0625,12.1025,12.362499999999999,12.4025,0.03999999999999915,0.040000000000000924 +-THoVjtIkeU/12,-THoVjtIkeU,12,34,they,12.882499694824219,13.042499542236328,True,3.4154286115885973e-14,0.5361220240592957,12.580522630946723,13.026778540456233,12.4025,12.9025,12.9825,13.0425,0.5,0.0600000000000005 +-THoVjtIkeU/12,-THoVjtIkeU,12,35,will,13.0625,13.202500343322754,True,1.877775482306797e-15,0.25,13.049451388170713,13.195483131860904,13.022499999999999,13.0625,13.1825,13.2225,0.040000000000000924,0.040000000000000924 +-THoVjtIkeU/12,-THoVjtIkeU,12,36,believe,13.242500305175781,13.542499542236328,True,3.5739823372928775e-14,0.5610103011131287,13.23451659139245,13.54107337938477,13.2225,13.2425,13.5425,13.5425,0.019999999999999574,0.0 +-THoVjtIkeU/12,-THoVjtIkeU,12,37,in,13.602499961853027,13.662500381469727,True,4.70323768402307e-15,0.25,13.59477173018874,13.655624982027442,13.5825,13.6025,13.6425,13.6625,0.019999999999999574,0.019999999999999574 +-THoVjtIkeU/12,-THoVjtIkeU,12,38,themselves.,13.682499885559082,14.682499885559082,True,1.3947767975850713e-14,0.25,13.682050784224838,14.477877429780559,13.6825,13.6825,14.1425,14.7225,0.0,0.5800000000000001 +-THoVjtIkeU/2,-THoVjtIkeU,2,0,I,0.042500000447034836,0.0625,True,3.5587171095174605e-14,0.5238187909126282,0.042747574508858015,0.06274757450885804,0.0425,0.0425,0.0625,0.0625,0.0,0.0 +-THoVjtIkeU/2,-THoVjtIkeU,2,1,think,0.16249999403953552,0.3824999928474426,True,2.8180750918579967e-13,4.0,0.16252283449036006,0.38258277339076985,0.1625,0.1625,0.3825,0.3825,0.0,0.0 +-THoVjtIkeU/2,-THoVjtIkeU,2,2,social,0.6825000047683716,1.4424999952316284,True,2.6086730974157757e-13,3.8397881984710693,0.6959264616025735,1.4393716808823362,0.6825,0.8025,1.4025,1.4425,0.12,0.039999999999999813 +-THoVjtIkeU/2,-THoVjtIkeU,2,3,justice,1.462499976158142,1.7625000476837158,True,5.4383574195609324e-14,0.8004889488220215,1.462500073806679,1.7625047152212947,1.4625,1.4625,1.7625,1.7625,0.0,0.0 +-THoVjtIkeU/2,-THoVjtIkeU,2,4,is,1.8025000095367432,1.8825000524520874,True,4.2815872917413567e-13,4.0,1.8025460129344417,1.8825969079606335,1.8025,1.8025,1.8825,1.8825,0.0,0.0 +-THoVjtIkeU/2,-THoVjtIkeU,2,5,extremely,1.9424999952316284,2.362499952316284,True,7.994530737279529e-15,0.25,1.9425053363639069,2.362500000000592,1.9425,1.9425,2.3625,2.3625,0.0,0.0 +-THoVjtIkeU/2,-THoVjtIkeU,2,6,important,2.382499933242798,2.822499990463257,True,5.668493222011316e-14,0.8343633413314819,2.3825001908451227,2.8223862620997116,2.3825,2.3825,2.8225,2.8225,0.0,0.0 +-THoVjtIkeU/2,-THoVjtIkeU,2,7,for,2.862499952316284,2.9825000762939453,True,4.5019671042305365e-13,4.0,2.8625263658238085,2.98251959707777,2.8625,2.8625,2.9825,2.9825,0.0,0.0 +-THoVjtIkeU/2,-THoVjtIkeU,2,8,young,3.0625,3.242500066757202,True,8.062027404714435e-15,0.25,3.0776871893499806,3.257933224930891,3.0625,3.1025,3.2425,3.2825,0.040000000000000036,0.040000000000000036 +-THoVjtIkeU/2,-THoVjtIkeU,2,9,people.,3.322499990463257,3.702500104904175,True,7.919095338249776e-14,1.1656365394592285,3.3220047688676053,3.702550181798884,3.3225000000000002,3.3225000000000002,3.7025,3.7025,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,0,You,0.0024999999441206455,0.10249999910593033,True,7.510342987706448e-15,0.4623764753341675,0.008626349453761577,0.16667783381217036,0.0025000000000000005,0.0625,0.10250000000000001,0.5425,0.06,0.43999999999999995 +-THoVjtIkeU/6,-THoVjtIkeU,6,1,know,0.12250000238418579,0.5425000190734863,True,6.107723236777041e-16,0.25,0.1987221878267382,0.5696078762787643,0.1225,0.5824999999999999,0.5425,0.7224999999999999,0.4599999999999999,0.17999999999999994 +-THoVjtIkeU/6,-THoVjtIkeU,6,2,that,0.5824999809265137,0.7425000071525574,True,1.469799013943153e-14,0.9048861265182495,0.6074026626126879,0.7695639834093579,0.5824999999999999,0.7424999999999999,0.7424999999999999,0.9225,0.16000000000000003,0.18000000000000005 +-THoVjtIkeU/6,-THoVjtIkeU,6,3,I,0.7825000286102295,0.8025000095367432,True,1.0772212982734786e-11,4.0,0.8124906763620903,0.8324906763620635,0.7825,0.9824999999999999,0.8025,1.0025,0.19999999999999996,0.19999999999999996 +-THoVjtIkeU/6,-THoVjtIkeU,6,4,think,0.9225000143051147,1.3224999904632568,True,5.037423183120761e-14,3.101304531097412,0.9372821593564936,1.3304404827120164,0.9025,1.0425,1.3225,1.3825,0.14,0.06000000000000005 +-THoVjtIkeU/6,-THoVjtIkeU,6,5,listening,1.3825000524520874,1.8825000524520874,True,9.660665720352419e-15,0.5947617292404175,1.3928878982518418,1.8981742756703237,1.3825,1.4825,1.8825,1.9224999999999999,0.09999999999999987,0.039999999999999813 +-THoVjtIkeU/6,-THoVjtIkeU,6,6,to,1.9424999952316284,2.002500057220459,True,1.2283348234496012e-14,0.756227970123291,1.942528648184741,2.0025308908655695,1.9425,1.9425,2.0025,2.0025,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,7,young,2.0625,2.262500047683716,True,1.2662656576298303e-15,0.25,2.0621304027330667,2.2621369025721645,2.0625,2.0625,2.2625,2.2625,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,8,"people,",2.302500009536743,2.5625,True,1.7007364483748177e-14,1.0470634698867798,2.3024999785176608,2.5634430580912624,2.3025,2.3025,2.5625,2.5625,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,9,taking,2.622499942779541,3.0225000381469727,True,2.2397052067786236e-14,1.3788810968399048,2.6227230997220414,3.0213912292627607,2.6225,2.6225,3.0225,3.0225,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,10,in,3.0425000190734863,3.1024999618530273,True,1.287970262804335e-14,0.7929427027702332,3.0563697916002726,3.123298588516466,3.0425,3.0825,3.1025,3.1625,0.040000000000000036,0.06000000000000005 +-THoVjtIkeU/6,-THoVjtIkeU,6,11,what,3.2225000858306885,3.382499933242798,True,1.399858132353782e-16,0.25,3.2090641191027367,3.368759455696855,3.1625,3.2225,3.3225000000000002,3.3825,0.06000000000000005,0.05999999999999961 +-THoVjtIkeU/6,-THoVjtIkeU,6,12,they,3.422499895095825,3.5625,True,1.5478470013954165e-14,0.952936589717865,3.422107918188843,3.5624991299962057,3.4225,3.4225,3.5625,3.5625,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,13,have,3.6024999618530273,3.742500066757202,True,9.16368692624285e-15,0.5641651153564453,3.6024997152443112,3.749687033398412,3.6025,3.6025,3.7425,3.7625,0.0,0.020000000000000018 +-THoVjtIkeU/6,-THoVjtIkeU,6,14,to,3.7825000286102295,3.862499952316284,True,1.177859367793065e-14,0.7251526117324829,3.7825058915301977,3.8625039279875057,3.7825,3.7825,3.8625,3.8625,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,15,say,3.942500114440918,4.122499942779541,True,1.6323537844770836e-13,4.0,3.942500199874739,4.122500127971544,3.9425,3.9425,4.1225000000000005,4.1225000000000005,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,16,because,4.162499904632568,4.482500076293945,True,1.3337907980772584e-13,4.0,4.166683924893797,4.48249963454062,4.1625000000000005,4.1825,4.482500000000001,4.482500000000001,0.019999999999999574,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,17,what,4.542500019073486,4.942500114440918,True,7.24388929238982e-17,0.25,4.554594493809835,4.895420128655968,4.522500000000001,4.6425,4.702500000000001,4.942500000000001,0.11999999999999922,0.2400000000000002 +-THoVjtIkeU/6,-THoVjtIkeU,6,18,we,5.002500057220459,5.0625,True,2.4732789465553226e-14,1.522681474685669,4.958055151596716,5.01805986357333,4.8825,5.0025,4.942500000000001,5.062500000000001,0.1200000000000001,0.1200000000000001 +-THoVjtIkeU/6,-THoVjtIkeU,6,19,have,5.082499980926514,5.222499847412109,True,1.3268368778088669e-14,0.8168710470199585,5.043438433626083,5.2030129096654605,5.0025,5.0825000000000005,5.1825,5.2225,0.08000000000000007,0.040000000000000036 +-THoVjtIkeU/6,-THoVjtIkeU,6,20,seen,5.242499828338623,5.422500133514404,True,3.088271961293812e-14,1.901303768157959,5.242158090563371,5.422237301298598,5.242500000000001,5.242500000000001,5.4225,5.4225,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,21,all,5.482500076293945,5.682499885559082,True,1.7910698016940577e-14,1.1026774644851685,5.482469297811507,5.681582380617955,5.482500000000001,5.482500000000001,5.6825,5.6825,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,22,around,5.702499866485596,5.962500095367432,True,4.47852407828124e-14,2.757216691970825,5.702103166805097,5.957460999624755,5.702500000000001,5.702500000000001,5.9225,5.9625,0.0,0.040000000000000036 +-THoVjtIkeU/6,-THoVjtIkeU,6,23,the,5.982500076293945,6.082499980926514,True,1.5442178252054344e-15,0.25,5.980183708565806,6.080183708652749,5.942500000000001,5.982500000000001,6.0425,6.0825000000000005,0.040000000000000036,0.040000000000000036 +-THoVjtIkeU/6,-THoVjtIkeU,6,24,world,6.102499961853027,6.322500228881836,True,1.8824873148341357e-15,0.25,6.102498364639328,6.324249512896174,6.102500000000001,6.102500000000001,6.322500000000001,6.322500000000001,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,25,is,6.402500152587891,6.522500038146973,True,3.4449125409924397e-13,4.0,6.402505356574926,6.5225017704465404,6.402500000000001,6.402500000000001,6.522500000000001,6.522500000000001,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,26,the,6.582499980926514,6.682499885559082,True,4.761372435105153e-14,2.9313530921936035,6.582500199985874,6.682500449272542,6.5825000000000005,6.5825000000000005,6.6825,6.6825,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,27,power,6.742499828338623,7.042500019073486,True,2.462818089656732e-14,1.516241192817688,6.74240651506444,7.042512615514087,6.742500000000001,6.742500000000001,7.0425,7.0425,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,28,of,7.082499980926514,7.142499923706055,True,2.6027791033556014e-12,4.0,7.083613699835981,7.143614692086718,7.0825000000000005,7.0825000000000005,7.142500000000001,7.142500000000001,0.0,0.0 +-THoVjtIkeU/6,-THoVjtIkeU,6,29,youth.,7.242499828338623,7.522500038146973,True,5.518415246790441e-14,3.3974287509918213,7.2424925780003235,7.522504128690015,7.242500000000001,7.242500000000001,7.522500000000001,7.522500000000001,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,0,^And,0.4625000059604645,0.5625,True,7.444570879352151e-15,0.25,0.43347005061479676,0.5584540097468289,0.1825,0.4625,0.5225,0.5625,0.28,0.040000000000000036 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,1,all,0.5824999809265137,0.7825000286102295,True,4.728579723958792e-13,4.0,0.6187218539498627,0.7942601619890411,0.5824999999999999,0.6625,0.7825,0.8225,0.08000000000000007,0.040000000000000036 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,2,of,0.8424999713897705,0.9024999737739563,True,2.301460346083861e-13,2.2389814853668213,0.8424948712648224,0.9027736800678561,0.8424999999999999,0.8424999999999999,0.9025,0.9025,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,3,them,0.9424999952316284,1.122499942779541,True,1.480158904514431e-14,0.25,0.9432060795990252,1.113068420763404,0.9425,0.9425,1.1025,1.1225,0.0,0.020000000000000018 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,4,are,1.2024999856948853,1.3224999904632568,True,2.4575976561962143e-13,2.3908801078796387,1.1923363969861287,1.3174479199245037,1.1225,1.2025,1.2825,1.3225,0.07999999999999985,0.040000000000000036 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,5,really,1.3825000524520874,1.662500023841858,True,2.800404426037649e-15,0.25,1.3814252978084791,1.6624772229432363,1.3825,1.3825,1.6625,1.6625,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,6,being,1.6825000047683716,1.9225000143051147,True,1.952734679413603e-14,0.25,1.6824843176111908,1.9214195095315,1.6824999999999999,1.6824999999999999,1.9025,1.9224999999999999,0.0,0.019999999999999796 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,7,able,2.5625,2.762500047683716,True,9.968488843626125e-14,0.9697869420051575,2.3964615747960076,2.7372177674963947,2.0225,2.5625,2.7225,2.7625,0.54,0.040000000000000036 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,8,to,2.7825000286102295,2.8424999713897705,True,1.889153675887264e-14,0.25,2.782500876058673,2.842501166223785,2.7825,2.7825,2.8425,2.8425,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,9,explore,2.882499933242798,3.5225000381469727,True,4.779727503546882e-13,4.0,2.9052813661038304,3.531178920856283,2.8825,2.9825,3.5225,3.5825,0.10000000000000009,0.06000000000000005 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,10,^these,3.622499942779541,4.242499828338623,True,6.823929984446642e-13,4.0,3.627667145170375,4.240710937512301,3.6225,3.6225,4.242500000000001,4.242500000000001,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,11,different,4.262499809265137,4.802499771118164,True,2.766109756069217e-14,0.26910167932510376,4.382878667595825,4.964671088009417,4.2625,4.522500000000001,4.8025,5.1825,0.2600000000000007,0.3799999999999999 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,12,areas,4.902500152587891,5.182499885559082,True,3.5131094675055e-14,0.34177374839782715,5.074588703285389,5.393802822040885,4.902500000000001,5.322500000000001,5.1825,5.6425,0.41999999999999993,0.45999999999999996 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,13,in,5.542500019073486,5.862500190734863,True,1.8041015729941545e-12,4.0,5.605517378896713,5.7680139174769876,5.242500000000001,5.8025,5.562500000000001,5.862500000000001,0.5599999999999996,0.2999999999999998 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,14,depth,5.962500095367432,6.34250020980835,True,3.677016915774878e-13,3.577195167541504,5.942366997981639,6.342105138567985,5.8425,6.062500000000001,6.3425,6.3425,0.22000000000000064,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,15,^in,6.382500171661377,6.582499980926514,True,7.172436472871468e-13,4.0,6.382663094054936,6.584390946636888,6.3825,6.3825,6.5825000000000005,6.602500000000001,0.0,0.020000000000000462 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,16,a,6.682499885559082,6.702499866485596,True,1.4643733274588566e-12,4.0,6.68250055881938,6.702500558819382,6.6825,6.6825,6.702500000000001,6.702500000000001,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,17,way,6.762499809265137,6.922500133514404,True,1.0279050424418304e-13,1.0,6.762495012667477,6.939677273518233,6.7625,6.7625,6.9225,6.9625,0.0,0.040000000000000036 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,18,that,7.022500038146973,7.202499866485596,True,1.8719922801561234e-14,0.25,7.021126903366722,7.195559932352289,7.022500000000001,7.022500000000001,7.1825,7.202500000000001,0.0,0.020000000000000462 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,19,really,7.222499847412109,7.522500038146973,True,4.071806385580511e-15,0.25,7.2194584454033,7.522500219334755,7.202500000000001,7.2225,7.522500000000001,7.522500000000001,0.019999999999999574,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,20,wasn't,7.5625,7.802499771118164,True,2.0166210281530317e-12,4.0,7.562499676953594,7.801666052689677,7.562500000000001,7.562500000000001,7.8025,7.8025,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,21,available,7.84250020980835,8.322500228881836,True,4.036739475674067e-14,0.3927152156829834,7.842499475900292,8.322500361921357,7.8425,7.8425,8.3225,8.3225,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,22,^before,8.362500190734863,8.702500343322754,True,3.3737571655638454e-13,3.28216814994812,8.362539013059672,8.702503611878011,8.362499999999999,8.362499999999999,8.7025,8.7025,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,23,the,8.742500305175781,8.842499732971191,True,2.0222062888683272e-14,0.25,8.74366559409698,8.844477233896045,8.7425,8.7425,8.8425,8.8425,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,24,center,8.862500190734863,9.302499771118164,True,2.695884422816708e-13,2.6226978302001953,8.86645495473147,9.305803311848454,8.862499999999999,8.862499999999999,9.3025,9.3025,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,25,was,9.442500114440918,9.602499961853027,True,3.3444106587853656e-14,0.32536181807518005,9.447406086810131,9.607217398306826,9.442499999999999,9.442499999999999,9.6025,9.6025,0.0,0.0 +-UuX1xuaiiE/1,-UuX1xuaiiE,1,26,here,9.922499656677246,10.102499961853027,True,9.340148446335128e-12,4.0,9.927156903525098,10.156147021362736,9.9225,9.942499999999999,10.1025,10.2425,0.019999999999999574,0.14000000000000057 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,0,^it's,0.0625,0.18250000476837158,True,5.385001797773847e-13,4.0,0.03084138853451605,0.18886906847383023,0.0025000000000000005,0.0825,0.14250000000000002,0.2425,0.08,0.09999999999999998 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,1,amazing,0.30250000953674316,0.8025000095367432,True,2.427161661759658e-13,4.0,0.2978772205761982,0.7982895129975586,0.2425,0.3025,0.7224999999999999,0.8025,0.06,0.08000000000000007 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,2,to,0.8824999928474426,0.9624999761581421,True,5.4123535080802254e-14,1.0,0.8823922464530151,0.962499782349916,0.8825,0.8825,0.9624999999999999,0.9624999999999999,0.0,0.0 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,3,see,1.0625,1.2424999475479126,True,3.0656412738222505e-13,4.0,1.0624987865229019,1.2425008786156162,1.0625,1.0625,1.2425,1.2425,0.0,0.0 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,4,their,1.3224999904632568,1.5225000381469727,True,7.977060365105054e-16,0.25,1.3222094811963274,1.5226780527244042,1.3225,1.3225,1.5225,1.5225,0.0,0.0 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,5,enthusiasm,1.5625,2.322499990463257,True,1.264410261605023e-13,2.336156129837036,1.55597757995693,2.3073898823403156,1.5425,1.5625,2.2225,2.3225,0.020000000000000018,0.09999999999999964 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,6,and,2.442500114440918,2.5425000190734863,True,3.3708023419493256e-15,0.25,2.4114640999737245,2.5267290614733597,2.3025,2.4425,2.4625,2.5425,0.13999999999999968,0.08000000000000007 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,7,their,2.5824999809265137,2.9825000762939453,True,1.4151743673944915e-14,0.261471152305603,2.5825076917084684,2.9839370714614866,2.5825,2.5825,2.9825,2.9825,0.0,0.0 +-UuX1xuaiiE/0,-UuX1xuaiiE,0,8,passion,3.122499942779541,3.502500057220459,True,6.910157649427136e-17,0.25,3.1188937037274393,3.5345878746530324,3.0825,3.1225,3.5025,3.5625,0.040000000000000036,0.06000000000000005 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,0,My,0.12250000238418579,0.32249999046325684,True,8.870484347056617e-10,4.0,0.12261680417447868,0.32700275790598615,0.1225,0.1225,0.3225,0.3825,0.0,0.06 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,1,goal,0.5625,0.8424999713897705,True,2.5603030112675285e-11,1.5297502279281616,0.5562232336384092,0.8381385156691515,0.5625,0.5625,0.8424999999999999,0.8424999999999999,0.0,0.0 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,2,is,1.222499966621399,1.2825000286102295,True,1.1648832939914477e-12,0.25,1.146023235323786,1.2660061071273174,1.0425,1.2225,1.2425,1.3425,0.17999999999999994,0.10000000000000009 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,3,to,1.462499976158142,1.6425000429153442,True,2.4778476492848256e-10,4.0,1.4593958501682065,1.6262894351115438,1.4625,1.4825,1.5625,1.6625,0.020000000000000018,0.10000000000000009 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,4,become,1.722499966621399,2.0425000190734863,True,1.1037502509192443e-11,0.6594774723052979,1.7086218803776163,2.042267428813497,1.6025,1.7225,2.0425,2.0425,0.11999999999999988,0.0 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,5,a,2.622499942779541,2.6424999237060547,True,2.320204575342877e-12,0.25,2.6157081677890304,2.6357081677890317,2.6225,2.6225,2.6425,2.6425,0.0,0.0 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,6,human,2.702500104904175,2.9024999141693115,True,2.8239372645844085e-12,0.25,2.707741696294927,2.923241916792613,2.7025,2.7625,2.9025,3.0625,0.06000000000000005,0.16000000000000014 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,7,rights,2.9825000762939453,3.4825000762939453,True,2.520619477031083e-11,1.5060398578643799,3.020026811992114,3.50541435590898,2.9825,3.2425,3.4825,3.5825,0.26000000000000023,0.10000000000000009 +-UuX1xuaiiE/3,-UuX1xuaiiE,3,8,lawyer,3.622499942779541,4.002500057220459,True,1.673673873103798e-11,1.0,3.636799554936652,4.012098400623447,3.6225,3.6825,4.0025,4.022500000000001,0.06000000000000005,0.020000000000000462 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,0,I,0.5824999809265137,0.6025000214576721,True,1.787539005704275e-10,4.0,0.270109773646166,0.2901097736461649,0.0225,0.5824999999999999,0.0425,0.6024999999999999,0.5599999999999999,0.5599999999999999 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,1,ended,0.6225000023841858,0.8025000095367432,True,2.451882826545043e-13,0.36168426275253296,0.5396114880489867,0.7337382133486879,0.5225,0.6224999999999999,0.7224999999999999,0.8025,0.09999999999999998,0.08000000000000007 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,2,up,0.8424999713897705,0.9225000143051147,True,9.941535442092864e-13,1.466504454612732,0.7558957635136302,0.8178524341981249,0.7424999999999999,0.8424999999999999,0.8025,0.9225,0.09999999999999998,0.12 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,3,going,0.9424999952316284,1.122499942779541,True,8.119074226679065e-15,0.25,0.8555654063033344,1.1208553058000463,0.8424999999999999,0.9425,1.1225,1.1225,0.10000000000000009,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,4,to,1.162500023841858,1.222499966621399,True,1.4474453062453436e-14,0.25,1.1624981375345769,1.2224993879065165,1.1624999999999999,1.1624999999999999,1.2225,1.2225,0.0,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,5,work,1.2625000476837158,1.462499976158142,True,4.01744846970694e-14,0.25,1.2624994413657256,1.4591329219296074,1.2625,1.2625,1.4224999999999999,1.4825,0.0,0.06000000000000005 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,6,for,1.5625,1.7424999475479126,True,5.021742028286924e-13,0.7407715916633606,1.5621988027396478,1.7420246341274674,1.5625,1.5625,1.7425,1.7425,0.0,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,7,the,1.8224999904632568,1.9824999570846558,True,2.22696115563005e-13,0.32850542664527893,1.8241144657810688,1.9721595686699893,1.8225,1.8225,1.9224999999999999,2.0025,0.0,0.08000000000000007 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,8,US,2.1624999046325684,2.242500066757202,True,7.930261482214096e-12,4.0,2.1214027566976656,2.197309546467254,1.9625,2.1625,2.0225,2.2425,0.20000000000000018,0.2200000000000002 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,9,government,2.262500047683716,2.7225000858306885,True,1.3203499606856146e-14,0.25,2.2378999774402657,2.7214863527895146,2.1625,2.2625,2.7225,2.7225,0.10000000000000009,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,10,as,2.8424999713897705,2.9024999141693115,True,7.30077456823075e-12,4.0,2.842739371428413,2.902744261495768,2.8425,2.8425,2.9025,2.9025,0.0,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,11,an,2.9825000762939453,3.0425000190734863,True,1.1879888349095036e-12,1.7524363994598389,2.972215429222952,3.0322589391232513,2.9425,2.9825,3.0025,3.0425,0.040000000000000036,0.040000000000000036 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,12,intelligence,3.0824999809265137,3.7225000858306885,True,5.813590169163885e-13,0.8575793504714966,3.082955856583384,3.7232939342321854,3.0825,3.0825,3.7225,3.7225,0.0,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,13,"analyst,",3.762500047683716,4.822500228881836,True,2.2186831365178517e-12,3.2728431224823,3.7644551139300924,4.80955242831551,3.7625,3.7625,4.7625,4.8425,0.0,0.08000000000000007 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,14,specializing,4.862500190734863,5.622499942779541,True,1.4901028544747619e-12,2.1980934143066406,4.88489165691581,5.637407196149477,4.862500000000001,4.982500000000001,5.6225000000000005,5.702500000000001,0.1200000000000001,0.08000000000000007 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,15,in,5.722499847412109,5.802499771118164,True,6.507028531450854e-13,0.959870457649231,5.719573747226648,5.80167959979051,5.7225,5.7225,5.8025,5.822500000000001,0.0,0.020000000000000462 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,16,war,5.882500171661377,6.002500057220459,True,2.1248417522018448e-12,3.1344151496887207,5.878821325527894,5.999303897122543,5.8825,5.8825,6.0025,6.0025,0.0,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,17,crimes,6.042500019073486,6.34250020980835,True,1.829281355298501e-13,0.2698425352573395,6.033983176986125,6.344507453138877,6.022500000000001,6.0425,6.3425,6.3425,0.019999999999999574,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,18,and,6.382500171661377,6.482500076293945,True,1.405874928191858e-13,0.25,6.384966204069522,6.485061293202971,6.3825,6.3825,6.482500000000001,6.482500000000001,0.0,0.0 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,19,human,6.502500057220459,6.702499866485596,True,7.051110455062737e-13,1.040129542350769,6.505737929966874,6.709886966565923,6.5025,6.5025,6.702500000000001,6.7225,0.0,0.019999999999999574 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,20,rights,6.722499847412109,6.982500076293945,True,4.419648241132945e-12,4.0,6.7350518605513106,7.002116245068988,6.7225,6.782500000000001,6.982500000000001,7.022500000000001,0.0600000000000005,0.040000000000000036 +-UuX1xuaiiE/6,-UuX1xuaiiE,6,21,issues,7.042500019073486,7.34250020980835,True,1.0247198922730405e-11,4.0,7.047294136122448,7.364531168340181,7.0425,7.0425,7.3425,7.562500000000001,0.0,0.22000000000000064 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,0,And,0.02250000089406967,0.8224999904632568,True,1.8799320281905063e-14,0.25,0.119519558806842,0.8420489822368266,0.0225,0.7625,0.8225,0.9225,0.74,0.09999999999999998 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,1,if,1.0425000190734863,1.122499942779541,True,1.864498572895501e-12,4.0,1.0396889744500983,1.1189426038956152,1.0425,1.0425,1.1025,1.1225,0.0,0.020000000000000018 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,2,you,1.1825000047683716,1.3825000524520874,True,8.737685922022287e-12,4.0,1.1823567191989515,1.3813940509165903,1.1824999999999999,1.1824999999999999,1.3825,1.3825,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,3,clip,1.4424999952316284,1.6825000047683716,True,4.2130695091478765e-13,1.162251591682434,1.4420208862780637,1.6970771282427792,1.4425,1.4425,1.6824999999999999,1.7425,0.0,0.06000000000000005 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,4,"coupons,",1.7625000476837158,2.5425000190734863,True,1.3545874491538434e-12,3.736875057220459,1.7613384775974255,2.544447333196721,1.7625,1.7625,2.5425,2.5825,0.0,0.040000000000000036 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,5,if,2.5824999809265137,2.742500066757202,True,1.0346320154785982e-12,2.854219913482666,2.591940711601199,2.7392036510285633,2.5825,2.7025,2.7225,2.7825,0.1200000000000001,0.06000000000000005 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,6,you,2.802500009536743,2.9825000762939453,True,4.206752676240433e-13,1.1605089902877808,2.805593026690063,2.980874186453363,2.8025,2.8425,2.9825,2.9825,0.03999999999999959,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,7,don't,3.0425000190734863,3.242500066757202,True,6.30838103976572e-10,4.0,3.0425001275429757,3.2477120612251564,3.0425,3.0425,3.2425,3.2825,0.0,0.040000000000000036 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,8,go,3.3424999713897705,3.442500114440918,True,1.436209983406156e-12,3.962045431137085,3.342501925342056,3.44250103576293,3.3425,3.3425,3.4425,3.4425,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,9,out,3.5625,3.702500104904175,True,1.3597915924767195e-13,0.37512314319610596,3.539193583208049,3.6907864440326263,3.4825,3.5625,3.6625,3.7025,0.08000000000000007,0.040000000000000036 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,10,for,3.742500066757202,3.862499952316284,True,5.18228004725476e-14,0.25,3.7424883769630815,3.862544926610272,3.7425,3.7425,3.8625,3.8625,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,11,dinner,3.942500114440918,4.382500171661377,True,1.2317580224026348e-13,0.3398027718067169,3.9419675211510485,4.380234510158347,3.9425,3.9425,4.3825,4.3825,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,12,and,4.462500095367432,4.5625,True,9.629341594930008e-14,0.26564285159111023,4.462225306627924,4.562438974723767,4.4625,4.4625,4.562500000000001,4.562500000000001,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,13,movies,4.662499904632568,5.142499923706055,True,1.1253193689386709e-11,4.0,4.655136187997946,5.1260571327776345,4.5825000000000005,4.6625000000000005,4.9625,5.1425,0.08000000000000007,0.17999999999999972 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,14,and,5.182499885559082,5.322500228881836,True,2.892920007279559e-13,0.7980644106864929,5.167784439597989,5.302560216276301,5.022500000000001,5.1825,5.1425,5.322500000000001,0.15999999999999925,0.1800000000000006 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,15,things,5.34250020980835,5.602499961853027,True,2.486937793286931e-13,0.6860668659210205,5.327936327257898,5.5895131003357275,5.1825,5.3425,5.4625,5.602500000000001,0.16000000000000014,0.14000000000000057 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,16,of,5.622499942779541,5.682499885559082,True,2.622747722128005e-12,4.0,5.610183745847421,5.671949375451719,5.482500000000001,5.6225000000000005,5.562500000000001,5.6825,0.13999999999999968,0.11999999999999922 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,17,that,5.702499866485596,5.84250020980835,True,2.375747710538223e-13,0.6553930640220642,5.696998378867096,5.8405395591316625,5.6625000000000005,5.702500000000001,5.8425,5.8425,0.040000000000000036,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,18,nature,5.902500152587891,6.28249979019165,True,2.4568303121086377e-12,4.0,5.901516263387521,6.276519742983215,5.902500000000001,5.902500000000001,6.242500000000001,6.322500000000001,0.0,0.08000000000000007 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,19,and,6.362500190734863,7.022500038146973,True,7.170564597820672e-13,1.9781302213668823,6.404674142671651,7.0242655162952055,6.362500000000001,6.8825,7.022500000000001,7.022500000000001,0.5199999999999996,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,20,try,7.082499980926514,7.302499771118164,True,9.657237032625887e-13,2.664123773574829,7.0846341886283755,7.303463941016041,7.0825000000000005,7.0825000000000005,7.3025,7.3025,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,21,to,7.402500152587891,7.462500095367432,True,4.870198465838733e-15,0.25,7.39206605640134,7.460182285553983,7.3825,7.402500000000001,7.442500000000001,7.4625,0.020000000000000462,0.019999999999999574 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,22,take,7.502500057220459,7.662499904632568,True,2.18452897237471e-14,0.25,7.49860130593234,7.661219461951071,7.4625,7.5025,7.6225000000000005,7.702500000000001,0.040000000000000036,0.08000000000000007 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,23,up,7.742499828338623,7.802499771118164,True,1.7658331665382915e-13,0.4871370792388916,7.742432282304045,7.802925440257224,7.742500000000001,7.742500000000001,7.8025,7.8025,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,24,things,7.962500095367432,8.302499771118164,True,4.2784580132210204e-13,1.1802902221679688,7.952760213706006,8.299296605177526,7.862500000000001,7.9625,8.2625,8.3025,0.09999999999999964,0.040000000000000924 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,25,in,8.362500190734863,8.462499618530273,True,1.1459259105853214e-12,3.1612443923950195,8.362640924084438,8.462201634766528,8.362499999999999,8.362499999999999,8.4625,8.4625,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,26,life,8.542499542236328,8.782500267028809,True,3.432629072479265e-13,0.9469529390335083,8.542499652125546,8.782508521681644,8.5425,8.5425,8.782499999999999,8.782499999999999,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,27,"that,",8.842499732971191,9.102499961853027,True,5.165082771207974e-13,1.4248816967010498,8.8325292619187,9.086651659124355,8.8025,8.862499999999999,9.022499999999999,9.1025,0.05999999999999872,0.08000000000000007 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,28,"well,",9.22249984741211,9.362500190734863,True,5.009049273453636e-13,1.381837010383606,9.193693502270262,9.36246372511127,9.0825,9.2225,9.362499999999999,9.362499999999999,0.14000000000000057,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,29,they,9.382499694824219,9.582500457763672,True,1.9582944342727907e-14,0.25,9.400462764831364,9.591486656966236,9.3825,9.4625,9.5825,9.6225,0.08000000000000007,0.040000000000000924 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,30,always,9.642499923706055,9.922499656677246,True,1.198839747092173e-13,0.3307216763496399,9.642498995341569,9.922498654780092,9.6425,9.6425,9.9225,9.9225,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,31,"say,",9.962499618530273,10.1225004196167,True,4.1787146659588714e-12,4.0,9.962500002041113,10.122500003597148,9.9625,9.9625,10.1225,10.1225,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,32,"""the",10.182499885559082,10.282500267028809,True,1.0157119015221511e-13,0.2802025377750397,10.18358703675862,10.283588063519483,10.1825,10.1825,10.282499999999999,10.282499999999999,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,33,best,10.302499771118164,10.522500038146973,True,4.5164518419670355e-14,0.25,10.323673882731844,10.535599687450915,10.3025,10.3425,10.522499999999999,10.5625,0.03999999999999915,0.040000000000000924 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,34,things,10.542499542236328,10.822500228881836,True,5.324179072336947e-14,0.25,10.564405953112635,10.834780913875006,10.5425,10.6025,10.782499999999999,10.862499999999999,0.05999999999999872,0.08000000000000007 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,35,in,10.842499732971191,10.922499656677246,True,4.024187463835295e-14,0.25,10.922409797559588,10.99278094836726,10.8025,11.0625,10.862499999999999,11.1225,0.2599999999999998,0.26000000000000156 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,36,life,10.982500076293945,11.182499885559082,True,2.4966956128393003e-13,0.6887587308883667,11.052018990177505,11.236140451775867,10.942499999999999,11.1825,11.1225,11.3425,0.2400000000000002,0.21999999999999886 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,37,are,11.242500305175781,11.342499732971191,True,1.2090145508000805e-12,3.3352856636047363,11.315824128651643,11.482355839813513,11.2425,11.442499999999999,11.3425,11.7225,0.1999999999999993,0.3800000000000008 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,38,"free"".",11.442500114440918,11.72249984741211,True,1.108621183677945e-13,0.30583325028419495,11.80240737192858,12.06420304908739,11.442499999999999,12.4225,11.7225,12.6625,0.9800000000000004,0.9399999999999995 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,39,Reading,11.782500267028809,12.72249984741211,True,7.512862402504761e-14,0.25,12.147773825953134,12.878409906681043,11.782499999999999,12.7825,12.6825,13.1625,1.0000000000000018,0.4800000000000004 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,40,a,12.782500267028809,12.802499771118164,True,9.634311577688681e-12,4.0,12.954937272825967,12.974937272826114,12.7825,13.2025,12.8025,13.2225,0.41999999999999993,0.41999999999999993 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,41,"book,",12.90250015258789,13.162500381469727,True,3.839624798662733e-12,4.0,13.294036123397236,13.538265691133404,12.9025,14.0625,13.1625,14.2025,1.1600000000000001,1.040000000000001 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,42,going,14.0625,14.542499542236328,True,3.271775645546926e-12,4.0,13.899637684976911,14.479520424724328,13.2025,14.2225,14.1625,14.6025,1.0199999999999996,0.4399999999999995 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,43,for,14.642499923706055,14.782500267028809,True,5.69680546767988e-14,0.25,14.57912428176785,14.724128175889916,14.3825,14.6425,14.5425,14.7825,0.2599999999999998,0.2400000000000002 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,44,a,14.802499771118164,14.822500228881836,True,1.7280364639216117e-11,4.0,14.777518286815813,14.797518286816297,14.7025,14.8025,14.7225,14.8225,0.09999999999999964,0.09999999999999964 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,45,nice,14.962499618530273,15.1225004196167,True,2.8319247988295437e-12,4.0,14.930842492182515,15.106118105713016,14.8825,14.9625,15.0825,15.1225,0.08000000000000007,0.040000000000000924 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,46,"walk,",15.182499885559082,15.462499618530273,True,1.6164060107765055e-12,4.0,15.18135379782965,15.461013343972695,15.1825,15.1825,15.4625,15.4625,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,47,"and,",15.5024995803833,15.602499961853027,True,2.406427210006456e-14,0.25,15.501115550027231,15.601660253222741,15.5025,15.5025,15.6025,15.6025,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,48,of,15.6225004196167,15.682499885559082,True,7.75856375673234e-12,4.0,15.621856150264364,15.682008493386707,15.6225,15.6225,15.6825,15.6825,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,49,"course,",15.702500343322754,15.942500114440918,True,5.6591589189325733e-14,0.25,15.702154879797067,15.942473582145436,15.7025,15.7025,15.942499999999999,15.942499999999999,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,50,combining,15.962499618530273,16.542499542236328,True,3.2498599623030644e-13,0.8965327739715576,15.962615579554416,16.54258848862367,15.9625,15.9625,16.5425,16.5425,0.0,0.0 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,51,exercise,16.5625,17.162500381469727,True,7.296909387485839e-13,2.0129847526550293,16.56451128516722,17.16727364513594,16.5625,16.5625,17.1625,17.2025,0.0,0.03999999999999915 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,52,and,17.202499389648438,17.302499771118164,True,1.9747090857576317e-14,0.25,17.212519549668535,17.31286686273573,17.2025,17.242500000000003,17.302500000000002,17.3425,0.0400000000000027,0.03999999999999915 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,53,various,17.322500228881836,17.622499465942383,True,9.008352603364495e-14,0.25,17.33331033428284,17.632382986564632,17.3225,17.3625,17.602500000000003,17.6625,0.03999999999999915,0.05999999999999872 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,54,things,17.642499923706055,17.88249969482422,True,2.6505485428555443e-14,0.25,17.65600623163198,17.90537406876171,17.642500000000002,17.7025,17.8825,18.0025,0.05999999999999872,0.120000000000001 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,55,of,17.90250015258789,17.962499618530273,True,3.624920459285863e-13,1.0,17.93835276685364,18.001385025457154,17.902500000000003,18.0425,17.962500000000002,18.102500000000003,0.13999999999999702,0.14000000000000057 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,56,that,18.002500534057617,18.142499923706055,True,1.8815473484812273e-11,4.0,18.04488132385217,18.219963675608064,17.9825,18.1825,18.142500000000002,18.462500000000002,0.1999999999999993,0.3200000000000003 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,57,nature,18.1825008392334,18.5625,True,2.4222108693794375e-12,4.0,18.28547153085806,18.701281830499646,18.1825,18.582500000000003,18.5625,19.142500000000002,0.40000000000000213,0.5800000000000018 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,58,where,18.582500457763672,19.042499542236328,True,1.1723989698985901e-14,0.25,18.726882158154776,19.134524101321563,18.582500000000003,19.2025,19.0425,19.442500000000003,0.6199999999999974,0.40000000000000213 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,59,you're,19.0625,19.262500762939453,True,6.019562018982905e-12,4.0,19.18884854699223,19.43021445240018,19.0625,19.5625,19.262500000000003,19.962500000000002,0.5,0.6999999999999993 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,60,not,19.282499313354492,19.40250015258789,True,2.795208725939191e-13,0.7711089849472046,19.521225771376137,19.66507505485541,19.282500000000002,20.282500000000002,19.402500000000003,20.5025,1.0,1.0999999999999979 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,61,spending,19.4424991607666,20.082500457763672,True,1.305721616983238e-13,0.3602069616317749,19.728286447221432,20.32897058236136,19.442500000000003,20.642500000000002,20.0225,21.1625,1.1999999999999993,1.1400000000000006 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,62,money,20.282499313354492,20.602500915527344,True,2.586418492572795e-13,0.7135103940963745,20.500230104664706,20.79165190936027,20.282500000000002,21.2225,20.602500000000003,21.402500000000003,0.9399999999999977,0.8000000000000007 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,63,per,20.842500686645508,21.0625,True,4.991007607202391e-13,1.3768599033355713,20.973787732360663,21.205024207243827,20.8425,21.422500000000003,21.0625,21.5425,0.5800000000000018,0.4800000000000004 +-a55Q6RWvTA/3,-a55Q6RWvTA,3,64,se.,21.22249984741211,21.582500457763672,True,1.484069464541271e-11,4.0,21.35793839975314,21.641898876505973,21.2225,21.5625,21.582500000000003,21.942500000000003,0.33999999999999986,0.35999999999999943 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,0,Maybe,0.5625,0.7425000071525574,True,1.3992611323093707e-12,4.0,0.5699168353417414,0.7684721379873901,0.5625,0.6224999999999999,0.7424999999999999,0.8624999999999999,0.05999999999999994,0.12 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,1,they,0.8025000095367432,1.0625,True,7.763144375385819e-14,0.6851189732551575,0.8381540024758877,1.1033643669058124,0.8025,1.0025,1.0625,1.4224999999999999,0.19999999999999996,0.3599999999999999 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,2,have,1.0824999809265137,1.2625000476837158,True,4.901391250332343e-13,4.0,1.1800089747111384,1.4216257555081657,1.0825,1.5825,1.2625,1.7425,0.5,0.48 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,3,no,1.4225000143051147,1.502500057220459,True,2.19147440537297e-13,1.9340368509292603,1.5502325525781857,1.6303863815472515,1.4025,1.8225,1.4625,1.8825,0.41999999999999993,0.42000000000000015 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,4,political,1.5824999809265137,2.0625,True,9.636221535340786e-14,0.8504232168197632,1.7219728765180327,2.217611584075496,1.5825,2.0425,2.0625,2.5825,0.45999999999999996,0.52 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,5,party,2.182499885559082,2.4625000953674316,True,4.943981964274091e-13,4.0,2.3189574948447387,2.597655834164009,2.1425,2.7025,2.3825,3.0225,0.56,0.6400000000000001 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,6,"affiliation,",2.5625,3.202500104904175,True,3.149363365581581e-13,2.77940034866333,2.6754966075215223,3.384642765575778,2.4425,3.0625,3.1625,3.8825,0.6200000000000001,0.7199999999999998 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,7,they're,3.322499990463257,3.882499933242798,True,6.927912236942557e-12,4.0,3.5162592580884375,3.9951804657104297,3.2625,4.2625,3.8825,4.482500000000001,1.0,0.600000000000001 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,8,not,4.262499809265137,4.422500133514404,True,9.374659794107731e-14,0.8273397088050842,4.3249445299839655,4.4702296803616,4.2625,4.5025,4.4225,4.6225000000000005,0.2400000000000002,0.20000000000000018 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,9,interested,4.502500057220459,5.142499923706055,True,1.493164993775567e-13,1.3177595138549805,4.536229501246246,5.153956404348874,4.5025,4.6625000000000005,5.1425,5.202500000000001,0.16000000000000014,0.0600000000000005 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,10,in,5.202499866485596,5.262499809265137,True,3.058207373863968e-14,0.2698952853679657,5.20525492933666,5.265296308868387,5.202500000000001,5.242500000000001,5.2625,5.3025,0.040000000000000036,0.040000000000000036 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,11,"politics,",5.34250020980835,5.922500133514404,True,3.0942337179897667e-14,0.2730746865272522,5.342027017595276,5.92221771234432,5.3425,5.3425,5.9225,5.9225,0.0,0.0 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,12,they,6.002500057220459,6.142499923706055,True,4.5508526451637586e-15,0.25,5.995617953652946,6.139102854390898,5.942500000000001,6.0025,6.102500000000001,6.142500000000001,0.05999999999999961,0.040000000000000036 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,13,could,6.162499904632568,6.502500057220459,True,1.133866492451091e-13,1.0006686449050903,6.165296514612912,6.5001556714207736,6.1625000000000005,6.1625000000000005,6.482500000000001,6.5025,0.0,0.019999999999999574 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,14,care,6.5625,6.822500228881836,True,1.1323512521524068e-13,0.9993313550949097,6.562667537244219,6.822789861817852,6.562500000000001,6.562500000000001,6.822500000000001,6.822500000000001,0.0,0.0 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,15,less,6.922500133514404,7.122499942779541,True,2.815684697118209e-13,2.484919786453247,6.9223711358609785,7.12232906665508,6.9225,6.9225,7.1225000000000005,7.1225000000000005,0.0,0.0 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,16,about,7.142499923706055,7.402500152587891,True,2.719624249110722e-14,0.25,7.14313662311112,7.4259741476470245,7.142500000000001,7.142500000000001,7.402500000000001,7.482500000000001,0.0,0.08000000000000007 +-aNfi7CP8vM/7,-aNfi7CP8vM,7,17,politics.,7.462500095367432,8.522500038146973,True,5.850625973274903e-14,0.5163339376449585,7.499265627423223,8.521439814756093,7.4625,7.6625000000000005,8.5025,8.522499999999999,0.20000000000000018,0.019999999999999574 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,0,In,0.36250001192092896,0.48249998688697815,True,2.7085831407619443e-13,0.44671571254730225,0.3661229464627679,0.4824918267992842,0.3625,0.4025,0.4825,0.4825,0.040000000000000036,0.0 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,1,"2008,",nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,2,there,0.6225000023841858,1.0225000381469727,True,4.3837511203535795e-13,0.7229943871498108,0.644216758746706,1.2320726340392565,0.6024999999999999,0.7424999999999999,1.0225,1.4825,0.14,0.45999999999999996 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,3,were,2.182499885559082,2.922499895095825,True,3.5700947406680505e-12,4.0,2.098391009917989,3.0003518244192926,1.3825,2.6425,2.7625,3.0825,1.26,0.31999999999999984 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,4,very,3.262500047683716,3.502500057220459,True,4.024087920523334e-13,0.6636766195297241,3.2628512483329692,3.5029909181345595,3.2625,3.2625,3.5025,3.5025,0.0,0.0 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,5,serious,3.6424999237060547,4.102499961853027,True,1.2576761463864439e-13,0.25,3.604995371759258,4.081283859552203,3.5425,3.6425,4.0425,4.1025,0.10000000000000009,0.05999999999999961 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,6,tribal,4.162499904632568,4.582499980926514,True,6.287949761568656e-12,4.0,4.164219364401541,4.584062047007865,4.1625000000000005,4.1625000000000005,4.5825000000000005,4.5825000000000005,0.0,0.0 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,7,warfare,4.722499847412109,5.202499866485596,True,1.5909093432821958e-13,0.26238226890563965,4.706837861170518,5.205690278227914,4.6425,4.7225,5.202500000000001,5.202500000000001,0.08000000000000007,0.0 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,8,in,6.142499923706055,6.202499866485596,True,1.019524534240368e-10,4.0,6.1186756160246425,6.21318732554233,6.062500000000001,6.1825,6.202500000000001,6.2625,0.11999999999999922,0.05999999999999961 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,9,Kenya,7.082499980926514,8.0024995803833,True,6.063326381776368e-13,1.0,7.055643839797694,8.001751852174415,6.3425,7.482500000000001,8.0025,8.0025,1.1400000000000006,0.0 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,10,following,8.162500381469727,9.282500267028809,True,1.3233601497616987e-12,2.1825644969940186,8.167307698703715,9.274023163387671,8.1625,8.1625,9.2025,9.282499999999999,0.0,0.0799999999999983 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,11,a,9.40250015258789,9.422499656677246,True,3.7868968377763323e-11,4.0,9.40242807987088,9.422428079870883,9.4025,9.4025,9.4225,9.4225,0.0,0.0 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,12,disputed,9.462499618530273,9.90250015258789,True,2.7071137757676833e-13,0.4464733600616455,9.47686688744534,9.925606046827598,9.4625,9.5025,9.9025,9.9825,0.03999999999999915,0.08000000000000007 +-aqamKhZ1Ec/0,-aqamKhZ1Ec,0,13,election.,10.022500038146973,10.802499771118164,True,3.659902676061977e-12,4.0,10.029209911460025,10.806518969512238,10.022499999999999,10.022499999999999,10.8025,10.862499999999999,0.0,0.05999999999999872 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,0,For,0.5625,0.7425000071525574,True,2.275428977183136e-12,4.0,0.3649672540175232,0.656470491487688,0.0225,0.5625,0.5824999999999999,0.7424999999999999,0.54,0.16000000000000003 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,1,the,0.8025000095367432,0.9424999952316284,True,3.523209827181739e-13,2.672248363494873,0.7190080419087704,0.8384369833953639,0.6425,0.8025,0.7424999999999999,0.9425,0.16000000000000003,0.20000000000000007 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,2,10th,1.002500057220459,1.0625,True,7.89121092892287e-16,0.25,0.9201663747546199,0.991584920117422,0.8025,1.0025,0.9025,1.0825,0.19999999999999996,0.18000000000000005 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,3,straight,1.0824999809265137,1.462499976158142,True,5.292460907187473e-15,0.25,1.0590410591480313,1.4525213757665048,0.9225,1.1225,1.4025,1.4625,0.20000000000000007,0.05999999999999983 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,4,"year,",1.5824999809265137,1.7625000476837158,True,4.7748890480642583e-14,0.36216092109680176,1.5743957871409902,1.7569251246340676,1.4825,1.5825,1.6824999999999999,1.7625,0.10000000000000009,0.08000000000000007 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,5,some,2.262500047683716,2.5425000190734863,True,1.943253283981372e-12,4.0,2.2612920543236856,2.5424015098644395,2.2625,2.2625,2.5425,2.5425,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,6,of,2.5824999809265137,2.6624999046325684,True,3.9846300087589825e-13,3.022221565246582,2.5853655723810456,2.6652560546039608,2.5825,2.6025,2.6625,2.6625,0.020000000000000018,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,7,Kentucky’s,2.762500047683716,3.262500047683716,True,1.15754682315089e-12,4.0,2.750634717027689,3.2556658742957265,2.7225,2.7625,3.2425,3.2625,0.040000000000000036,0.020000000000000018 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,8,best,3.422499895095825,3.762500047683716,True,8.019150258111243e-14,0.608228325843811,3.4022852380664403,3.72717692242951,3.2825,3.4225,3.7025,3.7625,0.13999999999999968,0.06000000000000005 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,9,and,3.922499895095825,4.022500038146973,True,1.6227658797339332e-14,0.25,3.9223628956324568,4.022449556910346,3.9225,3.9225,4.022500000000001,4.022500000000001,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,10,most,4.082499980926514,4.262499809265137,True,9.945570164952497e-14,0.7543414831161499,4.082499603629278,4.262509829162647,4.0825000000000005,4.0825000000000005,4.2625,4.2625,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,11,innovative,4.442500114440918,5.122499942779541,True,1.133854512017085e-12,4.0,4.4410250441935455,5.11803027501793,4.442500000000001,4.442500000000001,5.102500000000001,5.1225000000000005,0.0,0.019999999999999574 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,12,biotech,5.162499904632568,5.502500057220459,True,1.5729797564305315e-13,1.193057656288147,5.155285740506763,5.500234169729445,5.1225000000000005,5.1625000000000005,5.4625,5.5025,0.040000000000000036,0.040000000000000036 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,13,companies,5.542500019073486,6.022500038146973,True,8.639043798906731e-13,4.0,5.54199486653639,6.021684045459382,5.5425,5.5425,6.022500000000001,6.022500000000001,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,14,and,6.082499980926514,6.182499885559082,True,4.0721878045166596e-14,0.30886316299438477,6.081297587982795,6.181694894313973,6.0825000000000005,6.0825000000000005,6.1825,6.1825,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,15,technologies,6.222499847412109,6.922500133514404,True,2.050334592862066e-13,1.555116891860962,6.222158853837142,6.937339063734151,6.2225,6.2225,6.9225,6.9625,0.0,0.040000000000000036 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,16,were,6.942500114440918,7.482500076293945,True,3.483278661169098e-14,0.26419615745544434,7.130313396095074,7.4978267357210475,6.942500000000001,7.322500000000001,7.4625,7.522500000000001,0.3799999999999999,0.0600000000000005 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,17,on,7.502500057220459,7.702499866485596,True,1.5179640530660343e-11,4.0,7.540963992421254,7.71163558566263,7.5025,7.6825,7.702500000000001,7.782500000000001,0.17999999999999972,0.08000000000000007 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,18,display,7.84250020980835,8.40250015258789,True,7.89802034537046e-13,4.0,7.842515193459164,8.403630710839492,7.8425,7.8425,8.4025,8.4025,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,19,at,8.662500381469727,8.72249984741211,True,2.0993258435071053e-15,0.25,8.662467828886165,8.7226922086402,8.6625,8.6625,8.7225,8.7225,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,20,the,8.822500228881836,8.942500114440918,True,1.2593050246253318e-13,0.9551448225975037,8.822210482336128,8.942231664275779,8.8225,8.8225,8.942499999999999,8.942499999999999,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,21,annual,9.082500457763672,9.382499694824219,True,5.38172479670751e-13,4.0,9.082499874861758,9.382500529056607,9.0825,9.0825,9.3825,9.3825,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,22,BIO,9.662500381469727,9.90250015258789,True,6.07335223778982e-11,4.0,9.578064211583579,9.880240503537104,9.442499999999999,9.6625,9.8225,9.9025,0.22000000000000064,0.08000000000000007 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,23,International,9.922499656677246,10.682499885559082,True,7.311739511376911e-14,0.5545733571052551,9.908699669202857,10.700666650198874,9.8825,9.942499999999999,10.6825,10.7425,0.05999999999999872,0.0600000000000005 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,24,"Convention,",10.72249984741211,11.262499809265137,True,1.0889742883476994e-13,0.8259541392326355,10.747097081493896,11.267687896899911,10.7225,10.8025,11.2625,11.3025,0.08000000000000007,0.040000000000000924 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,25,which,11.322500228881836,12.082500457763672,True,4.037281915573489e-14,0.30621564388275146,11.364414611412695,12.082394236045653,11.3225,11.7425,12.0825,12.0825,0.41999999999999993,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,26,I,12.382499694824219,12.40250015258789,True,1.2588138864622067e-10,4.0,12.382510769537037,12.402510769537036,12.3825,12.3825,12.4025,12.4025,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,27,and,12.482500076293945,12.642499923706055,True,1.533161313562511e-14,0.25,12.48280965262064,12.642572691239474,12.4825,12.4825,12.6425,12.6425,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,28,other,12.702500343322754,12.962499618530273,True,9.549927173927233e-14,0.7243331670761108,12.702509718675014,12.962495484432637,12.7025,12.7025,12.9625,12.9625,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,29,state,12.982500076293945,13.242500305175781,True,6.808946852523978e-14,0.5164380669593811,12.98288355950477,13.242183987541857,12.9825,12.9825,13.2425,13.2425,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,30,officials,13.262499809265137,13.702500343322754,True,2.7725016360957873e-14,0.25,13.26382449943722,13.702492000013828,13.2625,13.2825,13.7025,13.7025,0.02000000000000135,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,31,attended,13.72249984741211,14.162500381469727,True,7.640498070381543e-15,0.25,13.724172197793889,14.162500196491765,13.7225,13.7225,14.1625,14.1625,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,32,this,14.22249984741211,14.362500190734863,True,1.377583214601935e-13,1.0448552370071411,14.222454748006289,14.362454751756776,14.2225,14.2225,14.362499999999999,14.362499999999999,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,33,week,14.422499656677246,14.6225004196167,True,4.912310792512531e-13,3.725839376449585,14.422499999645678,14.622500000213078,14.4225,14.4225,14.6225,14.6225,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,34,in,14.662500381469727,14.882499694824219,True,1.148558245039899e-12,4.0,14.664907397502905,14.88327589515385,14.6625,14.6625,14.8825,14.8825,0.0,0.0 +-dxfTGcXJoc/1,-dxfTGcXJoc,1,35,Chicago.,14.962499618530273,15.522500038146973,True,7.882481017733312e-13,4.0,14.962501636791323,15.51671348154772,14.9625,14.9625,15.5025,15.522499999999999,0.0,0.019999999999999574 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,0,This,0.20250000059604645,0.6625000238418579,True,1.436269511187623e-15,0.25,0.18800400140906554,0.6712783209637588,0.0225,0.3825,0.6625,0.7025,0.36,0.040000000000000036 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,1,is,0.7225000262260437,0.8025000095367432,True,1.321620655796163e-12,4.0,0.7296080131653702,0.8073423085081691,0.7224999999999999,0.7825,0.8025,0.8424999999999999,0.06000000000000005,0.039999999999999925 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,2,Governor,0.9024999737739563,1.2424999475479126,True,1.0927341930616619e-12,4.0,0.887471538448594,1.2277552870491857,0.8624999999999999,0.9025,1.2025,1.2425,0.040000000000000036,0.040000000000000036 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,3,Steve,1.2825000286102295,1.5625,True,7.474941753895722e-14,0.2840318977832794,1.281864992925297,1.5529176310112593,1.2825,1.2825,1.5425,1.5625,0.0,0.020000000000000018 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,4,Beshear,1.6024999618530273,1.9824999570846558,True,7.465651361004966e-13,2.8367886543273926,1.60314666497837,2.0731438341617148,1.6025,1.6025,1.9825,2.7625,0.0,0.7800000000000002 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,5,...,nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-dxfTGcXJoc/0,-dxfTGcXJoc,0,6,About,2.0824999809265137,2.8424999713897705,True,3.1875823053133245e-13,1.21121346950531,2.23390625717333,2.906884357988618,2.0825,2.9425,2.8425,3.3825,0.8599999999999999,0.54 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,7,Kentucky,2.942500114440918,4.482500076293945,True,1.9611760132542955e-12,4.0,3.0234051678294898,4.527675130658362,2.9425,3.4225,4.482500000000001,4.862500000000001,0.48,0.3799999999999999 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,8,Our,4.78249979019165,5.002500057220459,True,2.0286934025032233e-12,4.0,4.766380309692605,4.975474037119736,4.6225000000000005,4.9225,4.862500000000001,5.0425,0.2999999999999998,0.17999999999999972 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,9,state,5.142499923706055,5.482500076293945,True,2.2418547053482119e-13,0.8518571257591248,5.102480756287364,5.457607935480797,4.982500000000001,5.1425,5.3825,5.482500000000001,0.15999999999999925,0.10000000000000053 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,10,is,5.542500019073486,5.622499942779541,True,2.1595016898821873e-13,0.8205647468566895,5.542502282433472,5.62249050879839,5.5425,5.5425,5.6225000000000005,5.6225000000000005,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,11,home,5.702499866485596,5.902500152587891,True,7.612381997543563e-14,0.2892543375492096,5.6969075990261855,5.905562707339487,5.6425,5.702500000000001,5.862500000000001,5.902500000000001,0.0600000000000005,0.040000000000000036 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,12,to,5.922500133514404,6.042500019073486,True,7.356884334586491e-14,0.27954596281051636,5.937102992383272,6.056635431575253,5.9225,5.9225,6.0425,6.0425,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,13,more,6.222499847412109,6.622499942779541,True,6.24342970986097e-13,2.372370481491089,6.277575214162152,6.631543457001568,6.2225,6.322500000000001,6.6225000000000005,6.6625000000000005,0.10000000000000053,0.040000000000000036 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,14,than,6.802499771118164,7.102499961853027,True,9.57974747705509e-14,0.3640100359916687,6.803191204364817,7.107020835049525,6.8025,6.8025,7.102500000000001,7.142500000000001,0.0,0.040000000000000036 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,15,"1,500",nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-dxfTGcXJoc/0,-dxfTGcXJoc,0,16,bioscience,7.28249979019165,8.0625,True,5.816785312966199e-13,2.210254669189453,7.267452880689412,8.062370269304813,7.1825,7.282500000000001,8.0625,8.0625,0.10000000000000053,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,17,and,8.102499961853027,8.342499732971191,True,8.574386453673657e-14,0.32580846548080444,8.103254544239489,8.342748976407043,8.1025,8.1025,8.3425,8.3425,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,18,lifescience,8.462499618530273,9.0625,True,9.144152449125365e-13,3.474583387374878,8.440910172928174,9.06317123654407,8.3825,8.4625,9.0625,9.0625,0.08000000000000007,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,19,companies,9.102499961853027,10.102499961853027,True,1.1046472981127153e-12,4.0,9.103525367338998,10.10579297477803,9.1025,9.1025,10.1025,10.1225,0.0,0.02000000000000135 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,20,and,10.22249984741211,10.362500190734863,True,6.748803447510776e-14,0.2564401924610138,10.222497809790337,10.356745416243506,10.2225,10.2225,10.3425,10.362499999999999,0.0,0.019999999999999574 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,21,more,10.442500114440918,10.602499961853027,True,2.3733483711305126e-13,0.9018219113349915,10.414533955030066,10.579202864997653,10.3825,10.442499999999999,10.5625,10.6025,0.05999999999999872,0.03999999999999915 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,22,than,10.72249984741211,10.962499618530273,True,6.653097669138963e-13,2.5280356407165527,10.7225013520628,10.963060296230047,10.7225,10.7225,10.9625,10.9625,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,23,"100,000",nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-dxfTGcXJoc/0,-dxfTGcXJoc,0,24,people,11.102499961853027,11.5024995803833,True,1.0843516568600359e-13,0.41203057765960693,11.102483038622685,11.502500341848476,11.1025,11.1025,11.5025,11.5025,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,25,who,11.5625,11.702500343322754,True,1.174416358433461e-12,4.0,11.576823297591739,11.714007237913536,11.5625,11.6225,11.7025,11.7425,0.0600000000000005,0.03999999999999915 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,26,work,11.90250015258789,12.162500381469727,True,7.076656020075026e-14,0.2688978910446167,11.905745763990348,12.163903512245955,11.9025,11.9025,12.1625,12.1625,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,27,for,12.262499809265137,12.40250015258789,True,6.21533965787513e-13,2.36169695854187,12.262508738077944,12.402008549180124,12.2625,12.2625,12.4025,12.4025,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,28,these,12.5024995803833,12.72249984741211,True,5.1970743247115037e-14,0.25,12.50070802564183,12.722592853346624,12.5025,12.5025,12.7225,12.7225,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,29,"firms,",12.822500228881836,13.202500343322754,True,1.987435586383538e-14,0.25,12.810238807852192,13.202497205526639,12.7825,12.8225,13.2025,13.2025,0.03999999999999915,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,30,in,13.22249984741211,13.962499618530273,True,3.6057056862839887e-13,1.370091438293457,13.324914664363726,13.96804775045872,13.2225,13.942499999999999,13.9625,14.0425,0.7199999999999989,0.08000000000000007 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,31,areas,14.182499885559082,14.522500038146973,True,1.2572369089813157e-13,0.47772330045700073,14.18246398667518,14.522510488364302,14.1825,14.1825,14.522499999999999,14.522499999999999,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,32,from,14.5625,14.822500228881836,True,8.391539314822356e-15,0.25,14.562750522345475,14.823092307045739,14.5625,14.5625,14.8225,14.8225,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,33,nutrigenomics,15.182499885559082,16.122499465942383,True,1.1121746969558477e-12,4.0,15.177670019934878,16.099262169106762,15.1425,15.1825,16.0225,16.122500000000002,0.03999999999999915,0.10000000000000142 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,34,and,16.262500762939453,16.38249969482422,True,4.261740564398195e-14,0.25,16.258652767187964,16.38099827413018,16.262500000000003,16.282500000000002,16.3825,16.3825,0.019999999999999574,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,35,pharmaceuticals,16.422500610351562,17.262500762939453,True,5.213513540151815e-13,1.9810242652893066,16.4224417108849,17.25543344328825,16.422500000000003,16.422500000000003,17.2225,17.262500000000003,0.0,0.0400000000000027 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,36,to,17.642499923706055,17.74250030517578,True,4.542984640820008e-13,1.7262375354766846,17.642496491416676,17.742499915475133,17.642500000000002,17.642500000000002,17.742500000000003,17.742500000000003,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,37,nanotechnology,17.782499313354492,18.762500762939453,True,2.8901043342376143e-13,1.0981781482696533,17.782588215090776,18.763284028765124,17.782500000000002,17.782500000000002,18.762500000000003,18.762500000000003,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,38,and,18.822500228881836,18.922500610351562,True,1.1881575943657827e-14,0.25,18.822476509585076,18.922488605782018,18.8225,18.8225,18.922500000000003,18.922500000000003,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,39,medical,18.9424991607666,19.262500762939453,True,1.1681875898474775e-13,0.4438864290714264,18.942492184714514,19.2624987997749,18.942500000000003,18.942500000000003,19.262500000000003,19.262500000000003,0.0,0.0 +-dxfTGcXJoc/0,-dxfTGcXJoc,0,40,devices.,19.282499313354492,19.802499771118164,True,1.4210033974157432e-12,4.0,19.282502277797803,19.802471720501764,19.282500000000002,19.282500000000002,19.802500000000002,19.802500000000002,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,0,An,0.5625,0.6424999833106995,True,3.528646423450396e-14,2.5437161922454834,0.5517457553728019,0.6400199589743981,0.5625,0.5625,0.6425,0.6425,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,1,estimated,0.762499988079071,1.2625000476837158,True,3.06941976074501e-15,0.25,0.7624537774900568,1.2747010779553254,0.7625,0.7625,1.2625,1.3025,0.0,0.040000000000000036 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,2,"20,000",nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-dxfTGcXJoc/2,-dxfTGcXJoc,2,3,biotech,1.502500057220459,2.1424999237060547,True,5.178755102704102e-13,4.0,1.5016645351351747,2.145477612250111,1.5025,1.5025,2.1425,2.1625,0.0,0.020000000000000018 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,4,"scientists,",2.362499952316284,3.2825000286102295,True,3.88290907673422e-13,4.0,2.3601136758402634,3.177040551962975,2.3625,2.3625,2.9225,3.2825,0.0,0.3600000000000003 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,5,executives,3.3424999713897705,4.502500057220459,True,4.8946347734439566e-14,3.5284242630004883,3.3090474232848885,4.504003094828398,3.1825,3.4425,4.5025,4.5425,0.2599999999999998,0.040000000000000036 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,6,and,4.742499828338623,4.862500190734863,True,7.208249534101149e-15,0.5196253657341003,4.737240676908777,4.860440843264866,4.742500000000001,4.742500000000001,4.862500000000001,4.862500000000001,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,7,industry,5.042500019073486,5.442500114440918,True,6.4237835225287344e-15,0.46307510137557983,5.040880535443564,5.443378707143529,5.0425,5.0425,5.442500000000001,5.442500000000001,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,8,experts,5.582499980926514,6.022500038146973,True,3.06460179498938e-14,2.209197759628296,5.5703212329533915,6.014850126754625,5.482500000000001,5.5825000000000005,5.9625,6.022500000000001,0.09999999999999964,0.0600000000000005 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,9,from,6.422500133514404,6.582499980926514,True,9.360125936930621e-16,0.25,6.38109006975023,6.616702439780006,6.022500000000001,6.5025,6.5825000000000005,6.702500000000001,0.47999999999999954,0.1200000000000001 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,10,more,6.622499942779541,6.882500171661377,True,9.563321136515576e-14,4.0,6.664792178092532,6.8927378471517535,6.6225000000000005,6.7625,6.8825,6.9225,0.13999999999999968,0.040000000000000036 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,11,than,7.002500057220459,7.28249979019165,True,5.0399656372152393e-14,3.6331899166107178,7.0024999794329315,7.282500014929406,7.0025,7.0025,7.282500000000001,7.282500000000001,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,12,50,nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-dxfTGcXJoc/2,-dxfTGcXJoc,2,13,nations,7.362500190734863,7.742499828338623,True,3.6337700731715276e-15,0.261949747800827,7.369429892315447,7.749385730355412,7.362500000000001,7.4225,7.742500000000001,7.782500000000001,0.05999999999999961,0.040000000000000036 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,14,were,8.0625,8.22249984741211,True,1.6512727735737767e-14,1.190362811088562,8.062279727477186,8.222492308029125,8.0625,8.0625,8.2225,8.2225,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,15,at,8.382499694824219,8.462499618530273,True,2.5949011040230733e-15,0.25,8.382462737272258,8.46255610150032,8.3825,8.3825,8.4625,8.4625,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,16,the,8.522500038146973,8.642499923706055,True,1.0026508991150445e-15,0.25,8.527928748031597,8.648442775581263,8.5025,8.5625,8.6425,8.6825,0.0600000000000005,0.03999999999999915 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,17,BIO,8.662500381469727,8.942500114440918,True,7.251367041549717e-12,4.0,8.685797706798342,8.935314419747938,8.6625,8.8225,8.9025,8.9625,0.16000000000000014,0.0600000000000005 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,18,conference,9.0024995803833,9.5625,True,1.2436561925687623e-13,4.0,9.002366312686632,9.553113604517561,9.0025,9.0025,9.522499999999999,9.5625,0.0,0.040000000000000924 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,19,to,9.602499961853027,9.702500343322754,True,4.1949855590119045e-14,3.024064064025879,9.602500040663637,9.702500020830492,9.6025,9.6025,9.7025,9.7025,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,20,learn,9.802499771118164,10.0625,True,2.779141040325369e-16,0.25,9.80226629806537,10.062706163218133,9.8025,9.8025,10.0625,10.0625,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,21,about,10.202500343322754,10.442500114440918,True,1.123129689158944e-14,0.8096371293067932,10.18387034190013,10.433185442440921,10.1225,10.2025,10.4025,10.442499999999999,0.08000000000000007,0.03999999999999915 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,22,the,10.462499618530273,10.5625,True,2.2475309865299534e-15,0.25,10.462392739534936,10.562392741067562,10.4625,10.4625,10.5625,10.5625,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,23,latest,10.582500457763672,10.90250015258789,True,3.027837854573112e-15,0.25,10.582967332999607,10.903517748664571,10.5825,10.5825,10.9025,10.9025,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,24,scientific,10.922499656677246,11.442500114440918,True,9.800098143140554e-16,0.25,10.925212631979305,11.448081060031368,10.9225,10.9625,11.442499999999999,11.522499999999999,0.040000000000000924,0.08000000000000007 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,25,"advances,",11.5024995803833,12.042499542236328,True,3.089713950183218e-14,2.2273004055023193,11.505574248933469,12.04758122048326,11.5025,11.5425,12.0425,12.0625,0.040000000000000924,0.019999999999999574 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,26,and,12.082500457763672,12.6225004196167,True,2.6814522011229386e-14,1.9329943656921387,12.084524282799858,12.62267486373147,12.0825,12.0825,12.6225,12.6225,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,27,to,12.682499885559082,12.742500305175781,True,4.186913927947634e-15,0.30182453989982605,12.68249796092688,12.742535934060587,12.6825,12.6825,12.7425,12.7425,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,28,exchange,12.862500190734863,13.362500190734863,True,4.882353388631832e-15,0.3519571125507355,12.839402800312625,13.350664314337655,12.7825,12.862499999999999,13.3225,13.362499999999999,0.0799999999999983,0.03999999999999915 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,29,ideas,13.482500076293945,13.882499694824219,True,3.945389344004943e-14,2.8441362380981445,13.482486191160033,13.882548812984396,13.4825,13.4825,13.8825,13.8825,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,30,and,13.922499656677246,14.282500267028809,True,2.3429222700387803e-14,1.6889562606811523,13.922678087539742,14.282500215590204,13.9225,13.9225,14.2825,14.2825,0.0,0.0 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,31,establish,14.322500228881836,14.762499809265137,True,1.651188557322996e-15,0.25,14.322500022955364,14.773487639175407,14.3225,14.3225,14.7625,14.8425,0.0,0.08000000000000007 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,32,business,14.822500228881836,15.242500305175781,True,8.650353789394286e-14,4.0,14.832761792509285,15.240279039373075,14.8225,14.862499999999999,15.2025,15.2425,0.03999999999999915,0.03999999999999915 +-dxfTGcXJoc/2,-dxfTGcXJoc,2,33,relationships.,15.262499809265137,16.022499084472656,True,2.0376777268147532e-15,0.25,15.26250556174122,16.02250089371535,15.2625,15.2625,16.0225,16.0225,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,0,Kentucky’s,0.42250001430511475,0.9225000143051147,True,5.297549725280515e-12,4.0,0.4224967278309293,0.9225000000223426,0.4225,0.4225,0.9225,0.9225,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,1,participation,0.9424999952316284,1.7825000286102295,True,3.977016199002703e-14,0.8985112905502319,0.9465664649478172,1.7885813004286177,0.9425,0.9824999999999999,1.7825,1.8425,0.039999999999999925,0.06000000000000005 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,2,at,1.8424999713897705,1.9225000143051147,True,2.1943811513974038e-15,0.25,1.8533036193237216,1.9368632112892796,1.8425,1.9025,1.9224999999999999,2.0025,0.06000000000000005,0.08000000000000007 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,3,the,2.0225000381469727,2.1624999046325684,True,1.865988171812806e-15,0.25,2.020929687527187,2.151507239832155,1.9825,2.0225,2.0825,2.1625,0.040000000000000036,0.08000000000000007 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,4,annual,2.3424999713897705,2.682499885559082,True,2.7859146738661023e-13,4.0,2.308788690749572,2.6643921880715054,2.1625,2.3425,2.6225,2.6825,0.17999999999999972,0.06000000000000005 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,5,BIO,2.742500066757202,2.942500114440918,True,1.0218228173319854e-11,4.0,2.739909203795047,2.971583070334784,2.7425,2.7425,2.9425,3.0425,0.0,0.10000000000000009 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,6,International,2.9825000762939453,3.7225000858306885,True,4.252274124179681e-14,0.9606992602348328,3.0381234983409264,3.7414172328758766,2.9825,3.1225,3.7225,3.7625,0.14000000000000012,0.040000000000000036 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,7,Convention,3.802500009536743,4.882500171661377,True,1.806679534709782e-13,4.0,3.7986267028834164,4.640981911105811,3.7625,3.8025,4.322500000000001,4.8825,0.040000000000000036,0.5599999999999996 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,8,is,4.902500152587891,4.962500095367432,True,1.016744997961764e-15,0.25,4.882875855533999,4.9563961056449015,4.862500000000001,4.902500000000001,4.9225,4.9625,0.040000000000000036,0.040000000000000036 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,9,the,5.0625,5.162499904632568,True,1.3455526298201959e-13,3.0399529933929443,5.055186037952798,5.159575162330058,4.9625,5.062500000000001,5.1225000000000005,5.1625000000000005,0.10000000000000053,0.040000000000000036 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,10,primary,5.202499866485596,5.702499866485596,True,1.5114196718723875e-14,0.3414689898490906,5.2024999401486784,5.710515431236941,5.202500000000001,5.202500000000001,5.702500000000001,5.742500000000001,0.0,0.040000000000000036 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,11,means,5.802499771118164,6.142499923706055,True,4.23735550228628e-14,0.957328736782074,5.802486364345739,6.142863221968487,5.8025,5.8025,6.142500000000001,6.142500000000001,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,12,by,6.262499809265137,6.382500171661377,True,7.462917436806826e-12,4.0,6.262499999696703,6.382500000022064,6.2625,6.2625,6.3825,6.3825,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,13,which,6.422500133514404,6.682499885559082,True,4.42622826411776e-14,1.0,6.449507150222789,6.7000271550535855,6.4225,6.482500000000001,6.6825,6.7225,0.0600000000000005,0.040000000000000036 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,14,our,7.002500057220459,7.162499904632568,True,5.836931144583696e-14,1.3187144994735718,6.956397673938863,7.150806240348821,6.7225,7.022500000000001,7.102500000000001,7.1625000000000005,0.3000000000000007,0.05999999999999961 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,15,high-tech,7.222499847412109,7.662499904632568,True,1.0861458217201192e-12,4.0,7.2149935824394245,7.665882070120274,7.1625000000000005,7.2225,7.6625000000000005,7.702500000000001,0.05999999999999961,0.040000000000000036 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,16,companies,7.762499809265137,8.202500343322754,True,2.5332166919689314e-13,4.0,7.762376133681743,8.20258015845541,7.7625,7.7625,8.202499999999999,8.202499999999999,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,17,and,8.282500267028809,8.40250015258789,True,5.609055226036587e-14,1.2672313451766968,8.25984785590537,8.380906738814469,8.2225,8.282499999999999,8.362499999999999,8.4025,0.05999999999999872,0.040000000000000924 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,18,institutions,8.422499656677246,9.142499923706055,True,5.389259832399695e-15,0.25,8.422248950513739,9.142531347225114,8.4225,8.4225,9.1425,9.1425,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,19,can,9.242500305175781,9.5024995803833,True,2.1174656893472666e-15,0.25,9.282007274928727,9.511500731685478,9.1625,9.362499999999999,9.4825,9.5625,0.1999999999999993,0.08000000000000007 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,20,reach,9.5625,9.822500228881836,True,1.6722176960737127e-14,0.3777974247932434,9.569936347326685,9.826579649667691,9.5625,9.6425,9.8225,9.8825,0.08000000000000007,0.0600000000000005 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,21,out,9.882499694824219,10.1225004196167,True,3.801270076161413e-14,0.8588057160377502,9.905369645603065,10.128871358968683,9.8825,10.022499999999999,10.1225,10.1625,0.1399999999999988,0.03999999999999915 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,22,to,10.262499809265137,10.342499732971191,True,1.2812964393909415e-13,2.8947815895080566,10.262491452605754,10.342524144191376,10.2625,10.2625,10.3425,10.3425,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,23,the,10.422499656677246,10.522500038146973,True,1.0252761232240962e-14,0.25,10.420831128496536,10.52083710974172,10.4225,10.4225,10.522499999999999,10.522499999999999,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,24,global,10.542499542236328,10.90250015258789,True,4.665796625468767e-14,1.0541247129440308,10.54248245260101,10.903017817334318,10.5425,10.5425,10.9025,10.9025,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,25,scientific,10.942500114440918,11.582500457763672,True,1.1520418035607539e-14,0.260276198387146,10.943268176515302,11.582229395041422,10.942499999999999,10.942499999999999,11.5825,11.5825,0.0,0.0 +-dxfTGcXJoc/6,-dxfTGcXJoc,6,26,community.,11.602499961853027,12.102499961853027,True,2.5937306230745805e-13,4.0,11.612190715637311,12.102458094905488,11.6025,11.6425,12.1025,12.1025,0.040000000000000924,0.0 +-egA8-b7-3M/26,-egA8-b7-3M,26,0,We're,0.0024999999441206455,0.5824999809265137,True,2.7304946498274418e-11,4.0,0.04607508111870628,0.5898032740548333,0.0025000000000000005,0.5225,0.5824999999999999,0.6625,0.52,0.08000000000000007 +-egA8-b7-3M/26,-egA8-b7-3M,26,1,updating,0.6025000214576721,1.1425000429153442,True,1.190343722028142e-12,4.0,0.6201202747881431,1.1412705985929916,0.6024999999999999,0.7025,1.1225,1.1624999999999999,0.10000000000000009,0.039999999999999813 +-egA8-b7-3M/26,-egA8-b7-3M,26,2,it,1.2024999856948853,1.2625000476837158,True,6.882085098200777e-15,0.25,1.2068630134194995,1.2669326558135239,1.2025,1.2425,1.2625,1.3025,0.040000000000000036,0.040000000000000036 +-egA8-b7-3M/26,-egA8-b7-3M,26,3,all,1.3224999904632568,1.5225000381469727,True,3.317236825397911e-14,1.0,1.3240528697525118,1.5232767925449109,1.3225,1.3225,1.5225,1.5225,0.0,0.0 +-egA8-b7-3M/26,-egA8-b7-3M,26,4,the,1.5824999809265137,1.6825000047683716,True,1.9559788579532342e-15,0.25,1.5769041980110663,1.6835013931160456,1.5625,1.5825,1.6824999999999999,1.6824999999999999,0.020000000000000018,0.0 +-egA8-b7-3M/26,-egA8-b7-3M,26,5,time,1.7024999856948853,1.9824999570846558,True,4.720274798845024e-16,0.25,1.7062997103515074,1.984997575047607,1.7025,1.7425,1.9825,2.0225,0.040000000000000036,0.040000000000000036 +-egA8-b7-3M/26,-egA8-b7-3M,26,6,and,2.0225000381469727,2.5625,True,6.023966183732812e-15,0.25,2.0364141891598666,2.5625021914273565,2.0225,2.1825,2.5625,2.5625,0.16000000000000014,0.0 +-egA8-b7-3M/26,-egA8-b7-3M,26,7,looking,2.5824999809265137,2.942500114440918,True,5.855222312859884e-14,1.7650902271270752,2.582682866295387,2.9398393089929113,2.5825,2.5825,2.9025,2.9425,0.0,0.040000000000000036 +-egA8-b7-3M/26,-egA8-b7-3M,26,8,forward,3.002500057220459,3.3424999713897705,True,3.392760824073946e-15,0.25,2.999731412922151,3.3424460140552243,3.0025,3.0025,3.3425,3.3425,0.0,0.0 +-egA8-b7-3M/26,-egA8-b7-3M,26,9,to,3.382499933242798,3.4625000953674316,True,1.8818388687613652e-14,0.5672910809516907,3.3825160972871147,3.462510902065862,3.3825,3.3825,3.4625,3.4625,0.0,0.0 +-egA8-b7-3M/26,-egA8-b7-3M,26,10,your,3.5225000381469727,3.742500066757202,True,6.742193371796993e-15,0.25,3.522994713898922,3.743594339737526,3.5225,3.5225,3.7425,3.7425,0.0,0.0 +-egA8-b7-3M/26,-egA8-b7-3M,26,11,comments,3.7825000286102295,4.302499771118164,True,6.467650850647266e-14,1.9497103691101074,3.78386669880374,4.305125915713463,3.7825,3.7825,4.3025,4.3025,0.0,0.0 +-egA8-b7-3M/26,-egA8-b7-3M,26,12,on,4.462500095367432,4.5625,True,3.0199590658058773e-12,4.0,4.438194697536424,4.541530148943003,4.3425,4.4625,4.482500000000001,4.562500000000001,0.1200000000000001,0.08000000000000007 +-egA8-b7-3M/26,-egA8-b7-3M,26,13,our,4.602499961853027,4.742499828338623,True,1.3194816766981532e-11,4.0,4.597614970972109,4.7378090732319125,4.5425,4.602500000000001,4.6825,4.742500000000001,0.0600000000000005,0.0600000000000005 +-egA8-b7-3M/26,-egA8-b7-3M,26,14,videos.,4.882500171661377,5.242499828338623,True,7.06815682371964e-12,4.0,4.839578380641243,5.242501309845208,4.7225,4.8825,5.242500000000001,5.242500000000001,0.16000000000000014,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,0,As,0.6225000023841858,0.6825000047683716,True,6.329900796228638e-13,4.0,0.6225000000896067,0.682500000365255,0.6224999999999999,0.6224999999999999,0.6825,0.6825,0.0,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,1,you,0.7825000286102295,0.9424999952316284,True,1.412991631252053e-13,4.0,0.7823893755411854,0.9310866364147513,0.7825,0.7825,0.8825,0.9425,0.0,0.06000000000000005 +-egA8-b7-3M/17,-egA8-b7-3M,17,2,have,0.9624999761581421,1.1024999618530273,True,5.60062928109048e-15,0.25,0.9529266344489182,1.098373411090721,0.9225,0.9624999999999999,1.0625,1.1225,0.039999999999999925,0.06000000000000005 +-egA8-b7-3M/17,-egA8-b7-3M,17,3,more,1.1825000047683716,1.3424999713897705,True,7.51511771243012e-16,0.25,1.1824028515775171,1.3425010470509353,1.1824999999999999,1.1824999999999999,1.3425,1.3425,0.0,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,4,"experience,",1.3825000524520874,2.122499942779541,True,1.3858544574505555e-13,4.0,1.3873374469946451,2.1217125144118096,1.3825,1.4625,2.1225,2.1225,0.07999999999999985,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,5,you,3.2225000858306885,3.3424999713897705,True,3.083890429264255e-14,1.0576536655426025,3.213691251973658,3.354710556297301,3.2225,3.2225,3.3225000000000002,3.3825,0.0,0.05999999999999961 +-egA8-b7-3M/17,-egA8-b7-3M,17,6,have,3.362499952316284,3.5425000190734863,True,3.8175747827697004e-14,1.3092786073684692,3.377375456438648,3.5414414297293204,3.3625,3.4025,3.5425,3.5425,0.040000000000000036,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,7,more,3.6624999046325684,3.802500009536743,True,4.685770594101265e-15,0.25,3.6478162339869873,3.7964527218527744,3.5825,3.6625,3.7625,3.8025,0.08000000000000007,0.040000000000000036 +-egA8-b7-3M/17,-egA8-b7-3M,17,8,times,3.8424999713897705,4.182499885559082,True,1.295994798836738e-14,0.4444754421710968,3.8424998444900877,4.182500874910728,3.8425,3.8425,4.1825,4.1825,0.0,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,9,"exhibiting,",4.222499847412109,4.882500171661377,True,6.736042387940622e-14,2.3101987838745117,4.223205191074807,4.882471799434598,4.2225,4.2225,4.8825,4.8825,0.0,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,10,you,5.242499828338623,5.34250020980835,True,1.6752002473117609e-15,0.25,5.242488668737627,5.3432239190882544,5.242500000000001,5.242500000000001,5.3425,5.3425,0.0,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,11,get,5.402500152587891,5.522500038146973,True,2.7476793355765e-14,0.9423463940620422,5.402500228003155,5.522500551047494,5.402500000000001,5.402500000000001,5.522500000000001,5.522500000000001,0.0,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,12,to,5.582499980926514,5.642499923706055,True,4.209141343033008e-15,0.25,5.582587451647595,5.642588721621551,5.5825000000000005,5.5825000000000005,5.6425,5.6425,0.0,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,13,know,5.702499866485596,5.922500133514404,True,6.87243773174473e-14,2.3569769859313965,5.683751382141159,5.890393221205199,5.6625000000000005,5.702500000000001,5.822500000000001,5.9225,0.040000000000000036,0.09999999999999964 +-egA8-b7-3M/17,-egA8-b7-3M,17,14,more,5.942500114440918,6.102499961853027,True,3.703195011110858e-15,0.25,5.942366821871721,6.103246214752875,5.942500000000001,5.942500000000001,6.102500000000001,6.102500000000001,0.0,0.0 +-egA8-b7-3M/17,-egA8-b7-3M,17,15,people.,6.182499885559082,6.542500019073486,True,1.1336075036571386e-13,3.8878297805786133,6.182499922873765,6.542499989348836,6.1825,6.1825,6.5425,6.5425,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,0,It,0.5824999809265137,0.6825000047683716,True,5.045397490099392e-14,1.2702128887176514,0.4498708134808255,0.6283878986425523,0.0825,0.5824999999999999,0.6024999999999999,0.6825,0.4999999999999999,0.08000000000000007 +-egA8-b7-3M/18,-egA8-b7-3M,18,1,becomes,0.7024999856948853,1.122499942779541,True,1.2237954891819707e-14,0.30809876322746277,0.6740202091094792,1.123904883788223,0.6625,0.7025,1.1225,1.1425,0.040000000000000036,0.020000000000000018 +-egA8-b7-3M/18,-egA8-b7-3M,18,2,easier,1.1825000047683716,1.7424999475479126,True,5.1457912231397604e-15,0.25,1.2593575459889583,1.7659632994273018,1.1824999999999999,1.3825,1.7425,1.8225,0.20000000000000018,0.08000000000000007 +-egA8-b7-3M/18,-egA8-b7-3M,18,3,at,1.8424999713897705,1.9824999570846558,True,1.3661030043733008e-13,3.439256429672241,1.8446638169367537,1.9840793573308473,1.8425,1.8425,1.9825,1.9825,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,4,each,2.182499885559082,2.362499952316284,True,2.2053683545694182e-14,0.555216372013092,2.175812096254957,2.353765489008425,2.0625,2.1825,2.3225,2.3625,0.1200000000000001,0.040000000000000036 +-egA8-b7-3M/18,-egA8-b7-3M,18,5,one,2.4825000762939453,2.6024999618530273,True,8.226489693445582e-14,2.0710742473602295,2.465061924003497,2.5964168548924764,2.3625,2.4825,2.5625,2.6025,0.1200000000000001,0.040000000000000036 +-egA8-b7-3M/18,-egA8-b7-3M,18,6,of,2.622499942779541,2.682499885559082,True,2.7406403223782273e-14,0.6899747252464294,2.6223798933822544,2.68237989421122,2.6225,2.6225,2.6825,2.6825,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,7,these,2.702500104904175,2.882499933242798,True,2.363750047882111e-15,0.25,2.702441638482025,2.882768890312429,2.7025,2.7025,2.8825,2.8825,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,8,conferences,2.942500114440918,3.6024999618530273,True,9.357525334024314e-14,2.3558201789855957,2.940330155669175,3.593531353090126,2.9025,2.9425,3.5825,3.6025,0.040000000000000036,0.020000000000000018 +-egA8-b7-3M/18,-egA8-b7-3M,18,9,to,4.102499961853027,4.202499866485596,True,2.403003740002879e-13,4.0,4.10248789549808,4.202500336033287,4.1025,4.1025,4.202500000000001,4.202500000000001,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,10,connect,4.222499847412109,4.582499980926514,True,2.2258525589086836e-13,4.0,4.226862793204726,4.588976822861837,4.2225,4.2625,4.5825000000000005,4.6425,0.040000000000000036,0.05999999999999961 +-egA8-b7-3M/18,-egA8-b7-3M,18,11,with,4.622499942779541,4.78249979019165,True,3.549643396124941e-15,0.25,4.643047295040439,4.802463991137171,4.6225000000000005,4.6625000000000005,4.782500000000001,4.822500000000001,0.040000000000000036,0.040000000000000036 +-egA8-b7-3M/18,-egA8-b7-3M,18,12,people,4.882500171661377,5.162499904632568,True,1.767017623530414e-14,0.4448586106300354,4.882395800547012,5.162499794327169,4.8825,4.8825,5.1625000000000005,5.1625000000000005,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,13,that,5.202499866485596,5.362500190734863,True,5.594892829864539e-17,0.25,5.2024996957554865,5.3532616793556365,5.202500000000001,5.202500000000001,5.3425,5.362500000000001,0.0,0.020000000000000462 +-egA8-b7-3M/18,-egA8-b7-3M,18,14,you've,5.382500171661377,5.602499961853027,True,1.3271654608626449e-11,4.0,5.382502593463899,5.602570477903483,5.3825,5.3825,5.602500000000001,5.602500000000001,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,15,met,5.682499885559082,5.882500171661377,True,1.9963176077497646e-13,4.0,5.679981733714091,5.879140283703421,5.6825,5.6825,5.8825,5.8825,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,16,or,6.422500133514404,6.482500076293945,True,7.505055469236507e-14,1.8894484043121338,6.397987073919746,6.459058711645056,6.4225,6.4225,6.482500000000001,6.482500000000001,0.0,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,17,that,6.522500038146973,6.662499904632568,True,7.683182416404072e-17,0.25,6.51310953711065,6.660509407784024,6.522500000000001,6.522500000000001,6.6625000000000005,6.6825,0.0,0.019999999999999574 +-egA8-b7-3M/18,-egA8-b7-3M,18,18,you're,6.682499885559082,6.862500190734863,True,3.4061416881447926e-12,4.0,6.681564351164622,6.866491034969756,6.6825,6.702500000000001,6.862500000000001,6.8825,0.020000000000000462,0.019999999999999574 +-egA8-b7-3M/18,-egA8-b7-3M,18,19,doing,6.902500152587891,7.142499923706055,True,2.8987788325317634e-14,0.7297871112823486,6.902497657128809,7.133894547298574,6.902500000000001,6.902500000000001,7.102500000000001,7.142500000000001,0.0,0.040000000000000036 +-egA8-b7-3M/18,-egA8-b7-3M,18,20,business,7.182499885559082,7.5625,True,2.4658436913443244e-14,0.620792806148529,7.175063793795647,7.562567369568958,7.142500000000001,7.1825,7.562500000000001,7.562500000000001,0.03999999999999915,0.0 +-egA8-b7-3M/18,-egA8-b7-3M,18,21,with.,7.622499942779541,7.882500171661377,True,1.9961424874148648e-11,4.0,7.622509877955194,7.882500128054946,7.6225000000000005,7.6225000000000005,7.8825,7.8825,0.0,0.0 +-egA8-b7-3M/16,-egA8-b7-3M,16,0,"Third,",0.48249998688697815,0.762499988079071,True,1.2783299267217496e-14,0.45957401394844055,0.4823735110546779,0.765816467639421,0.4825,0.4825,0.7625,0.8225,0.0,0.06000000000000005 +-egA8-b7-3M/16,-egA8-b7-3M,16,1,another,0.8424999713897705,1.2825000286102295,True,4.566552146731233e-14,1.6417269706726074,0.8410692456432085,1.2830330828196779,0.8225,0.8424999999999999,1.2825,1.3025,0.019999999999999907,0.020000000000000018 +-egA8-b7-3M/16,-egA8-b7-3M,16,2,big,1.3224999904632568,1.4824999570846558,True,1.7119000038064505e-14,0.6154473423957825,1.3225007758015552,1.4825008899204788,1.3225,1.3225,1.4825,1.4825,0.0,0.0 +-egA8-b7-3M/16,-egA8-b7-3M,16,3,benefit,1.5625,1.962499976158142,True,4.657146047385048e-14,1.674296498298645,1.5624781565144765,1.962500288652209,1.5625,1.5625,1.9625,1.9625,0.0,0.0 +-egA8-b7-3M/16,-egA8-b7-3M,16,4,of,2.0225000381469727,2.1024999618530273,True,2.248744234171953e-14,0.808448851108551,2.022781738748026,2.097683776003884,2.0225,2.0225,2.0825,2.1025,0.0,0.020000000000000018 +-egA8-b7-3M/16,-egA8-b7-3M,16,5,exhibiting,2.122499942779541,2.7225000858306885,True,2.7815540466096834e-14,1.0,2.1197486749478904,2.722499622656068,2.1025,2.1225,2.7225,2.7225,0.020000000000000018,0.0 +-egA8-b7-3M/16,-egA8-b7-3M,16,6,is,2.822499990463257,2.882499933242798,True,7.896127192852029e-14,2.8387465476989746,2.822455644522566,2.8825844839545818,2.8225,2.8225,2.8825,2.8825,0.0,0.0 +-egA8-b7-3M/16,-egA8-b7-3M,16,7,connecting,2.922499895095825,3.4825000762939453,True,5.372833745970066e-15,0.25,2.9224863158974808,3.4838534184456353,2.9225,2.9225,3.4625,3.5225,0.0,0.06000000000000005 +-egA8-b7-3M/16,-egA8-b7-3M,16,8,with,3.502500057220459,3.6624999046325684,True,8.081755225572461e-16,0.25,3.5063061035173675,3.66635899435173,3.5025,3.5425,3.6625,3.7025,0.040000000000000036,0.040000000000000036 +-egA8-b7-3M/16,-egA8-b7-3M,16,9,existing,3.742500066757202,4.302499771118164,True,7.100570131868267e-14,2.552734851837158,3.743222429243274,4.303965535822457,3.7425,3.7425,4.3025,4.3025,0.0,0.0 +-egA8-b7-3M/16,-egA8-b7-3M,16,10,clients.,4.362500190734863,4.822500228881836,True,1.5700299133697415e-13,4.0,4.359248951566402,4.822504151992989,4.322500000000001,4.362500000000001,4.822500000000001,4.822500000000001,0.040000000000000036,0.0 +-egA8-b7-3M/13,-egA8-b7-3M,13,0,What,0.24250000715255737,0.6225000023841858,True,1.5400974069637363e-16,0.25,0.2141840485714987,0.6218597133402548,0.0225,0.4225,0.6224999999999999,0.6224999999999999,0.39999999999999997,0.0 +-egA8-b7-3M/13,-egA8-b7-3M,13,1,are,0.6424999833106995,0.7425000071525574,True,8.498745056231133e-14,2.449159622192383,0.6421815628124172,0.742500011758617,0.6425,0.6425,0.7424999999999999,0.7424999999999999,0.0,0.0 +-egA8-b7-3M/13,-egA8-b7-3M,13,2,you,0.762499988079071,0.862500011920929,True,8.022830108047295e-15,0.25,0.7653580882059453,0.8659613972267409,0.7625,0.7825,0.8624999999999999,0.8825,0.020000000000000018,0.020000000000000018 +-egA8-b7-3M/13,-egA8-b7-3M,13,3,doing,0.9024999737739563,1.122499942779541,True,2.871552483101579e-14,0.827521026134491,0.9025000213152364,1.1225003642958045,0.9025,0.9025,1.1225,1.1225,0.0,0.0 +-egA8-b7-3M/13,-egA8-b7-3M,13,4,that's,1.1425000429153442,1.3624999523162842,True,1.606225569217301e-11,4.0,1.1429115027852526,1.3625002174895329,1.1425,1.1425,1.3625,1.3625,0.0,0.0 +-egA8-b7-3M/13,-egA8-b7-3M,13,5,"different?""",1.3825000524520874,1.7825000286102295,True,1.846142698078406e-14,0.5320194959640503,1.4034251715517392,2.3733903913393863,1.3825,1.4224999999999999,1.7825,2.4425,0.039999999999999813,0.6599999999999999 +-egA8-b7-3M/13,-egA8-b7-3M,13,6,They,1.8025000095367432,2.4625000953674316,True,1.3074539687669626e-14,0.3767807185649872,2.441006479437174,2.718606976840083,1.8025,2.5025,2.4825,2.7425,0.7,0.26000000000000023 +-egA8-b7-3M/13,-egA8-b7-3M,13,7,always,2.502500057220459,2.7825000286102295,True,5.6516907988432216e-14,1.6286983489990234,2.7741362125960785,3.0562366014397764,2.5025,2.8025,2.7825,3.0825,0.30000000000000027,0.2999999999999998 +-egA8-b7-3M/13,-egA8-b7-3M,13,8,want,2.802500009536743,2.9825000762939453,True,3.4700659636314676e-14,1.0,3.1022008047455936,3.3186257301717013,2.8025,3.2025,2.9825,3.4425,0.3999999999999999,0.45999999999999996 +-egA8-b7-3M/13,-egA8-b7-3M,13,9,an,3.0625,3.122499942779541,True,3.821534492391525e-14,1.1012858152389526,3.4092592789422267,3.47028094392638,3.0625,3.4625,3.1225,3.5225,0.3999999999999999,0.3999999999999999 +-egA8-b7-3M/13,-egA8-b7-3M,13,10,answer.,3.202500104904175,3.5625,True,1.833897183417532e-12,4.0,3.5131397249203156,3.9093662996538545,3.2025,3.5625,3.5625,4.0025,0.3599999999999999,0.4400000000000004 +-egA8-b7-3M/1,-egA8-b7-3M,1,0,I,0.0024999999441206455,0.02250000089406967,True,3.349408424224709e-12,4.0,0.00807213853936062,0.02807213853936155,0.0025000000000000005,0.0825,0.0225,0.10250000000000001,0.08,0.08000000000000002 +-egA8-b7-3M/1,-egA8-b7-3M,1,1,started,0.042500000447034836,0.30250000953674316,True,2.7094884495759697e-13,0.8343841433525085,0.08285976140362887,0.392640622001406,0.0425,0.6224999999999999,0.3025,1.6225,0.58,1.32 +-egA8-b7-3M/1,-egA8-b7-3M,1,2,a,0.6225000023841858,0.6424999833106995,True,1.6140776215589625e-11,4.0,0.7018397959792573,0.7218397959792763,0.6224999999999999,1.7625,0.6425,1.7825,1.1400000000000001,1.1400000000000001 +-egA8-b7-3M/1,-egA8-b7-3M,1,3,successful,0.762499988079071,1.622499942779541,True,4.594923345892926e-14,0.25,0.8340952262394151,1.6983804921435448,0.7025,1.8425,1.6225,2.7025,1.1400000000000001,1.08 +-egA8-b7-3M/1,-egA8-b7-3M,1,4,Legal,1.8424999713897705,2.382499933242798,True,9.063408118632765e-13,2.791066884994507,1.909492493181274,2.4335311441149527,1.8425,2.7825,2.3825,3.1025,0.9400000000000002,0.7200000000000002 +-egA8-b7-3M/1,-egA8-b7-3M,1,5,Nurse,2.4625000953674316,2.702500104904175,True,3.247291487356446e-13,1.0,2.5228978831850655,2.7700245247650632,2.4625,3.2025,2.7025,3.4625,0.7400000000000002,0.7599999999999998 +-egA8-b7-3M/1,-egA8-b7-3M,1,6,Consulting,2.7825000286102295,3.4825000762939453,True,9.766556053475428e-13,3.007600784301758,2.8444628086268335,3.550414946085584,2.7825,3.5425,3.4625,4.562500000000001,0.7599999999999998,1.100000000000001 +-egA8-b7-3M/1,-egA8-b7-3M,1,7,Business,3.5425000190734863,3.9825000762939453,True,1.635268933068354e-13,0.5035793781280518,3.6237951499738292,4.086650313197705,3.5425,4.702500000000001,3.9825,5.402500000000001,1.1600000000000006,1.4200000000000008 +-egA8-b7-3M/1,-egA8-b7-3M,1,8,in,4.002500057220459,4.5625,True,9.467710767934942e-14,0.2915571630001068,4.122795613570893,4.643007217848893,4.0025,5.6225000000000005,4.562500000000001,5.6825,1.62,1.1199999999999992 +-egA8-b7-3M/1,-egA8-b7-3M,1,9,1989.,nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-egA8-b7-3M/1,-egA8-b7-3M,1,10,I,4.702499866485596,4.722499847412109,True,3.378953340000754e-14,0.25,4.822565464327348,4.842565464327365,4.702500000000001,6.3825,4.7225,6.402500000000001,1.6799999999999997,1.6800000000000006 +-egA8-b7-3M/1,-egA8-b7-3M,1,11,mentor,4.802499771118164,5.102499961853027,True,1.5290421923400133e-14,0.25,4.9231409745934025,5.229286423895843,4.8025,6.482500000000001,5.102500000000001,6.8425,1.6800000000000006,1.7399999999999993 +-egA8-b7-3M/1,-egA8-b7-3M,1,12,nurses,5.142499923706055,5.402500152587891,True,3.649005231277317e-15,0.25,5.285193221719072,5.554316901085585,5.1425,6.902500000000001,5.402500000000001,7.3025,1.7600000000000007,1.8999999999999995 +-egA8-b7-3M/1,-egA8-b7-3M,1,13,who,5.622499942779541,5.722499847412109,True,1.0704910807617096e-13,0.32965660095214844,5.754514660120223,5.858585417759601,5.6225000000000005,7.402500000000001,5.7225,7.522500000000001,1.7800000000000002,1.8000000000000007 +-egA8-b7-3M/1,-egA8-b7-3M,1,14,want,6.382500171661377,6.682499885559082,True,5.1592024923052815e-12,4.0,6.4705962452594825,6.762408602745925,6.3825,7.562500000000001,6.6825,7.7625,1.1800000000000006,1.08 +-egA8-b7-3M/1,-egA8-b7-3M,1,15,to,6.762499809265137,6.84250020980835,True,2.8021755922591485e-12,4.0,6.843815901061743,6.922242147418595,6.7625,7.8425,6.8425,7.902500000000001,1.08,1.0600000000000005 +-egA8-b7-3M/1,-egA8-b7-3M,1,16,become,6.942500114440918,7.462500095367432,True,5.2748408939373714e-12,4.0,7.017877169431938,7.522635350083966,6.942500000000001,7.9225,7.4625,8.2425,0.9799999999999995,0.7799999999999994 +-egA8-b7-3M/1,-egA8-b7-3M,1,17,Legal,7.5625,7.902500152587891,True,1.0792557711240824e-13,0.33235567808151245,7.620066755669658,7.950217895020635,7.562500000000001,8.3225,7.902500000000001,8.5425,0.7599999999999989,0.6399999999999997 +-egA8-b7-3M/1,-egA8-b7-3M,1,18,Nurse,7.962500095367432,8.242500305175781,True,1.0314321011867245e-12,3.1762843132019043,8.00911242193168,8.283288744907443,7.9625,8.5825,8.2425,8.782499999999999,0.6199999999999992,0.5399999999999991 +-egA8-b7-3M/1,-egA8-b7-3M,1,19,Consultants.,8.382499694824219,9.5024995803833,True,3.968895958411656e-12,4.0,8.410315918310687,9.492776884061083,8.3225,8.8225,9.4625,9.5025,0.5,0.03999999999999915 +-egA8-b7-3M/6,-egA8-b7-3M,6,0,First,0.5224999785423279,0.8025000095367432,True,2.200081683132425e-15,0.25,0.4853864311485953,0.8069054596275058,0.2025,0.5225,0.8025,0.8624999999999999,0.31999999999999995,0.05999999999999994 +-egA8-b7-3M/6,-egA8-b7-3M,6,1,exhibiting,0.8424999713897705,1.5625,True,3.04314916094086e-14,1.037160038948059,0.8581546005495158,1.5735363871558865,0.8424999999999999,1.0425,1.5625,1.6025,0.20000000000000007,0.040000000000000036 +-egA8-b7-3M/6,-egA8-b7-3M,6,2,is,1.6425000429153442,1.722499966621399,True,2.2094691798802552e-13,4.0,1.6424968655880368,1.7224987665687466,1.6425,1.6425,1.7225,1.7225,0.0,0.0 +-egA8-b7-3M/6,-egA8-b7-3M,6,3,a,1.8025000095367432,1.8224999904632568,True,1.2546567951243759e-11,4.0,1.8023980684775633,1.8223980684775658,1.8025,1.8025,1.8225,1.8225,0.0,0.0 +-egA8-b7-3M/6,-egA8-b7-3M,6,4,wonderful,1.9424999952316284,2.4625000953674316,True,2.6952779811077916e-14,0.9185992479324341,1.8748230106996233,2.4290915945601004,1.8425,1.9425,2.3825,2.4625,0.09999999999999987,0.08000000000000007 +-egA8-b7-3M/6,-egA8-b7-3M,6,5,opportunity,2.5425000190734863,3.202500104904175,True,1.6584008946381006e-14,0.5652128458023071,2.505562645229575,3.206492567731367,2.4625,2.5425,3.2025,3.2225,0.08000000000000007,0.020000000000000018 +-egA8-b7-3M/6,-egA8-b7-3M,6,6,to,3.2825000286102295,3.382499933242798,True,4.802218396700829e-14,1.636682391166687,3.282497056715122,3.3825000470074538,3.2825,3.2825,3.3825,3.3825,0.0,0.0 +-egA8-b7-3M/6,-egA8-b7-3M,6,7,network,3.4825000762939453,3.922499895095825,True,2.825085780274513e-14,0.9628400802612305,3.4783378131246514,3.9006160511864714,3.4225,3.4825,3.8625,3.9225,0.06000000000000005,0.06000000000000005 +-egA8-b7-3M/6,-egA8-b7-3M,6,8,with,3.9625000953674316,4.122499942779541,True,5.249891572357314e-15,0.25,3.9591645135049784,4.119164923234471,3.9225,3.9625,4.0825000000000005,4.1225000000000005,0.040000000000000036,0.040000000000000036 +-egA8-b7-3M/6,-egA8-b7-3M,6,9,other,4.262499809265137,4.502500057220459,True,3.9747078648148457e-14,1.354651927947998,4.241709003588393,4.488159328074618,4.1225000000000005,4.2625,4.442500000000001,4.5025,0.13999999999999968,0.05999999999999961 +-egA8-b7-3M/6,-egA8-b7-3M,6,10,legal,4.602499961853027,4.922500133514404,True,2.4844702846676253e-14,0.8467521667480469,4.572833735083782,4.898411272791733,4.482500000000001,4.602500000000001,4.8425,4.9225,0.1200000000000001,0.08000000000000007 +-egA8-b7-3M/6,-egA8-b7-3M,6,11,vendors.,4.962500095367432,5.442500114440918,True,5.481644191297416e-14,1.8682429790496826,4.962452113281357,5.442494524553728,4.9625,4.9625,5.442500000000001,5.442500000000001,0.0,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,0,"Secondly,",0.5625,1.0824999809265137,True,1.8873178844400207e-13,1.530295729637146,0.5556694643132206,1.0816803932159271,0.5625,0.5625,1.0825,1.0825,0.0,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,1,another,1.122499942779541,1.5824999809265137,True,1.2623711483691208e-13,1.0235695838928223,1.1289479746884983,1.585168118194489,1.1225,1.1225,1.5825,1.5825,0.0,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,2,goal,1.6825000047683716,1.8825000524520874,True,1.2042343305266462e-13,0.9764304161071777,1.6824995293756553,1.8825667309258272,1.6824999999999999,1.6824999999999999,1.8825,1.8825,0.0,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,3,of,1.9824999570846558,2.0425000190734863,True,9.055312055750164e-12,4.0,1.9823969628656442,2.0423972940717987,1.9825,1.9825,2.0425,2.0425,0.0,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,4,exhibiting,2.1024999618530273,2.622499942779541,True,2.0145135356413636e-14,0.25,2.102419345902239,2.6224487529212688,2.1025,2.1025,2.6225,2.6225,0.0,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,5,is,2.742500066757202,2.8424999713897705,True,2.4083781843819985e-12,4.0,2.742313009892268,2.8279796871804743,2.7425,2.7425,2.8025,2.8425,0.0,0.03999999999999959 +-egA8-b7-3M/9,-egA8-b7-3M,9,6,building,2.862499952316284,3.2825000286102295,True,2.3681746938886833e-14,0.25,2.8559528332329007,3.282546562084778,2.8425,2.8625,3.2825,3.2825,0.020000000000000018,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,7,your,3.322499990463257,3.502500057220459,True,8.219796608502968e-15,0.25,3.322499735080081,3.5015646541237775,3.3225000000000002,3.3225000000000002,3.5025,3.5025,0.0,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,8,company,3.5225000381469727,3.9024999141693115,True,3.6006809513156046e-13,2.919543504714966,3.5224999329970728,3.9025043103914396,3.5225,3.5225,3.9025,3.9025,0.0,0.0 +-egA8-b7-3M/9,-egA8-b7-3M,9,9,image.,4.042500019073486,4.302499771118164,True,5.5716044266033906e-15,0.25,4.064112624999909,4.345916642191695,4.0425,4.1025,4.3025,4.3825,0.05999999999999961,0.08000000000000007 +-egA8-b7-3M/20,-egA8-b7-3M,20,0,Now,0.5824999809265137,0.7425000071525574,True,3.1301773916999134e-14,0.2761642634868622,0.4356619142255531,0.7065679669073096,0.0625,0.5824999999999999,0.6825,0.7424999999999999,0.5199999999999999,0.05999999999999994 +-egA8-b7-3M/20,-egA8-b7-3M,20,1,you've,0.762499988079071,0.9624999761581421,True,1.005963715106084e-11,4.0,0.7493537559098281,0.9559724070717779,0.7424999999999999,0.7625,0.9425,0.9624999999999999,0.020000000000000018,0.019999999999999907 +-egA8-b7-3M/20,-egA8-b7-3M,20,2,got,0.9825000166893005,1.1825000047683716,True,2.447966891585933e-14,0.25,0.9825000739198075,1.1663853893456297,0.9824999999999999,0.9824999999999999,1.1425,1.1824999999999999,0.0,0.039999999999999813 +-egA8-b7-3M/20,-egA8-b7-3M,20,3,a,1.2024999856948853,1.222499966621399,True,5.193426851762828e-12,4.0,1.2024999656061082,1.2224999656061082,1.2025,1.2025,1.2225,1.2225,0.0,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,4,face,1.2424999475479126,1.5425000190734863,True,1.842966155119613e-13,1.6259825229644775,1.243189139356799,1.5429338149669567,1.2425,1.2425,1.5425,1.5425,0.0,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,5,that,1.6024999618530273,1.7825000286102295,True,4.151051823510308e-15,0.25,1.6025000546147912,1.782485139751137,1.6025,1.6025,1.7825,1.7825,0.0,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,6,you,1.8224999904632568,1.9225000143051147,True,2.3299396690012715e-15,0.25,1.8158877928657156,1.9213270670153828,1.8025,1.8225,1.9025,1.9224999999999999,0.020000000000000018,0.019999999999999796 +-egA8-b7-3M/20,-egA8-b7-3M,20,7,can,1.962499976158142,2.0625,True,4.888492497086283e-13,4.0,1.9624941818187185,2.062500087680068,1.9625,1.9625,2.0625,2.0625,0.0,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,8,connect,2.1024999618530273,2.4625000953674316,True,1.8919876787221873e-13,1.6692323684692383,2.108301743869357,2.4709835100351327,2.1025,2.1425,2.4625,2.5225,0.040000000000000036,0.06000000000000005 +-egA8-b7-3M/20,-egA8-b7-3M,20,9,with,2.5225000381469727,2.702500104904175,True,5.3128519548432e-15,0.25,2.5457953478717408,2.7183556023547792,2.5225,2.5825,2.7025,2.7425,0.06000000000000005,0.040000000000000036 +-egA8-b7-3M/20,-egA8-b7-3M,20,10,a,2.7825000286102295,2.802500009536743,True,4.2030949033711185e-12,4.0,2.782499639676574,2.8024996396765736,2.7825,2.7825,2.8025,2.8025,0.0,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,11,"voice,",2.822499990463257,3.202500104904175,True,2.7150111586021763e-12,4.0,2.83914372742463,3.220260657530159,2.8225,2.8825,3.2025,3.2825,0.06000000000000005,0.08000000000000007 +-egA8-b7-3M/20,-egA8-b7-3M,20,12,and,3.2825000286102295,4.022500038146973,True,1.7373433150013468e-13,1.5327953100204468,3.3491538445964393,4.026596308706412,3.2825,3.9425,4.022500000000001,4.062500000000001,0.6599999999999997,0.040000000000000036 +-egA8-b7-3M/20,-egA8-b7-3M,20,13,that,4.122499942779541,4.28249979019165,True,4.251538560768285e-14,0.3750979006290436,4.110459146562859,4.271831829133859,4.0425,4.1225000000000005,4.2225,4.282500000000001,0.08000000000000007,0.0600000000000005 +-egA8-b7-3M/20,-egA8-b7-3M,20,14,makes,4.302499771118164,4.502500057220459,True,9.645896006851146e-15,0.25,4.295467501888811,4.502881881025231,4.2625,4.3025,4.5025,4.5025,0.040000000000000036,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,15,you,4.542500019073486,4.682499885559082,True,3.1286988109871863e-14,0.27603378891944885,4.5424999966891395,4.682497906328179,4.5425,4.5425,4.6825,4.6825,0.0,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,16,closer,4.722499847412109,5.102499961853027,True,1.2777630245108113e-13,1.1273242235183716,4.722500016785279,5.102793700421638,4.7225,4.7225,5.102500000000001,5.102500000000001,0.0,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,17,to,5.202499866485596,5.302499771118164,True,9.8913234645049e-14,0.8726757764816284,5.202467187444825,5.302500007946147,5.202500000000001,5.202500000000001,5.3025,5.3025,0.0,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,18,that,5.362500190734863,5.5625,True,5.875642854202834e-13,4.0,5.356749432746811,5.56137750147641,5.322500000000001,5.362500000000001,5.562500000000001,5.562500000000001,0.040000000000000036,0.0 +-egA8-b7-3M/20,-egA8-b7-3M,20,19,client.,5.582499980926514,6.002500057220459,True,8.170173522101254e-14,0.7208248972892761,5.582466544181751,6.002488319140519,5.5825000000000005,5.5825000000000005,6.0025,6.0025,0.0,0.0 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,0,"Well,",0.4424999952316284,0.6225000023841858,True,4.203285289272607e-12,1.5519766807556152,0.44251731066523176,0.6402426472765932,0.4425,0.4425,0.6224999999999999,0.7025,0.0,0.08000000000000007 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,1,it,0.9024999737739563,0.9825000166893005,True,1.378709565133876e-13,0.25,0.9026934341895801,0.9877443085068495,0.9025,0.9025,0.9824999999999999,1.0025,0.0,0.020000000000000018 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,2,is,1.162500023841858,1.2424999475479126,True,2.6363368546599222e-14,0.25,1.1766154327924332,1.258820351938083,1.1624999999999999,1.2225,1.2425,1.3025,0.06000000000000005,0.06000000000000005 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,3,the,1.9824999570846558,2.302500009536743,True,7.262065948587804e-12,2.681368589401245,1.9861770102307585,2.318400811512359,1.9825,1.9825,2.3025,2.5425,0.0,0.23999999999999977 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,4,secret,3.322499990463257,3.622499942779541,True,1.9209831208372163e-12,0.7092835307121277,3.1189257501802254,3.604293380599604,2.6225,3.3225000000000002,3.5825,3.6225,0.7000000000000002,0.040000000000000036 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,5,of,3.7225000858306885,4.102499961853027,True,2.4477631293401414e-12,0.9037861824035645,3.7260529538165423,4.095743694350303,3.7225,3.7225,4.1025,4.1025,0.0,0.0 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,6,power,4.402500152587891,4.902500152587891,True,4.5697900324936924e-11,4.0,4.409120587918154,4.902042298636173,4.402500000000001,4.402500000000001,4.902500000000001,4.902500000000001,0.0,0.0 +-iRBcNs9oI8/3,-iRBcNs9oI8,3,7,pose,5.042500019073486,5.382500171661377,True,2.968922850621336e-12,1.096213698387146,5.047806403743758,5.364777216140973,5.0425,5.102500000000001,5.2225,5.3825,0.0600000000000005,0.16000000000000014 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,0,"Well,",0.10249999910593033,0.36250001192092896,True,2.920177391996931e-13,3.763028383255005,0.10136593814621651,0.3623925371058929,0.10250000000000001,0.10250000000000001,0.3625,0.3625,0.0,0.0 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,1,for,1.3224999904632568,1.4424999952316284,True,7.760179082444071e-14,1.0,0.9651913170585473,1.426231262055861,0.4425,1.3225,1.4025,1.4425,0.88,0.039999999999999813 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,2,"starters,",1.4824999570846558,1.9424999952316284,True,7.344413299097477e-14,0.9464231729507446,1.482722124857738,1.9316510145653845,1.4825,1.4825,1.8825,1.9425,0.0,0.05999999999999983 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,3,let's,1.9824999570846558,2.5625,True,5.298965259636912e-12,4.0,1.9825266210685708,2.562499980618171,1.9825,1.9825,2.5625,2.5625,0.0,0.0 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,4,look,2.622499942779541,2.882499933242798,True,8.900332185667048e-14,1.146923542022705,2.621435781036787,2.883659047511814,2.6225,2.6225,2.8825,2.9025,0.0,0.020000000000000018 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,5,at,2.9825000762939453,3.0625,True,3.4943981708874736e-14,0.45029863715171814,2.9829116244373175,3.062499663832645,2.9825,2.9825,3.0625,3.0625,0.0,0.0 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,6,the,3.1624999046325684,3.322499990463257,True,1.0356679977594624e-13,1.3345929384231567,3.156277465682998,3.3100716739224545,3.1225,3.1625,3.2425,3.3225000000000002,0.040000000000000036,0.08000000000000007 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,7,word,3.3424999713897705,3.682499885559082,True,3.161334693983363e-15,0.25,3.3424933417526446,3.682494353615535,3.3425,3.3425,3.6825,3.6825,0.0,0.0 +-iRBcNs9oI8/7,-iRBcNs9oI8,7,8,"""power""",3.702500104904175,4.002500057220459,True,2.9010224534024506e-14,0.3738344609737396,3.7025010532407543,3.9910909636389107,3.7025,3.7025,3.9625,4.0025,0.0,0.04000000000000048 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,0,What,0.042500000447034836,0.2224999964237213,True,6.827441173182236e-13,1.0,0.05154200673577662,0.2727785157094661,0.0425,0.0825,0.2225,0.3025,0.04,0.07999999999999999 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,1,is,0.4625000059604645,0.6025000214576721,True,1.1234021118954399e-13,0.25,0.4747218729776408,0.5963319673877671,0.4625,0.5225,0.5425,0.6024999999999999,0.05999999999999994,0.05999999999999994 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,2,a,0.7425000071525574,0.762499988079071,True,2.809957263616783e-14,0.25,0.7333161148797499,0.7533161148798755,0.6825,0.7424999999999999,0.7025,0.7625,0.05999999999999994,0.05999999999999994 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,3,power,0.9825000166893005,1.722499966621399,True,3.0594309637782535e-12,4.0,0.9841119228812493,1.722488496427188,0.9824999999999999,0.9824999999999999,1.7225,1.7225,0.0,0.0 +-iRBcNs9oI8/6,-iRBcNs9oI8,6,4,pose,2.1024999618530273,2.6024999618530273,True,4.7897163665822085e-12,4.0,2.1029123141162605,2.5993707527881207,2.0625,2.1025,2.5825,2.6025,0.040000000000000036,0.020000000000000018 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,0,Power,0.0024999999441206455,0.2224999964237213,True,8.225095646620991e-15,0.25,0.006262492974741897,0.22425165857230403,0.0025000000000000005,0.0225,0.2225,0.2225,0.019999999999999997,0.0 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,1,is,0.2824999988079071,0.3425000011920929,True,4.88303009138491e-11,4.0,0.2828602076691416,0.3461376424479182,0.28250000000000003,0.28250000000000003,0.3425,0.3425,0.0,0.0 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,2,similar,1.3025000095367432,1.722499966621399,True,1.3116465277459872e-14,0.25,1.1245273514934184,1.7144200210143659,0.4625,1.3025,1.7025,1.7425,0.84,0.040000000000000036 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,3,to,1.7424999475479126,1.8025000095367432,True,3.081003117563763e-12,4.0,1.7386692485023425,1.7996332226989926,1.7225,1.7625,1.7825,1.8225,0.040000000000000036,0.040000000000000036 +-iRBcNs9oI8/9,-iRBcNs9oI8,9,4,strength,1.9225000143051147,2.5824999809265137,True,4.50202212749079e-13,1.0,1.8981114999728592,2.5831794475236496,1.8025,1.9425,2.5825,2.5825,0.1399999999999999,0.0 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,0,I've,0.08250000327825546,0.24250000715255737,True,1.9600367336114477e-12,4.0,0.08247995998981052,0.24164600371421696,0.0825,0.0825,0.2425,0.2425,0.0,0.0 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,1,drawn,0.32249999046325684,0.6625000238418579,True,1.3570146525573867e-12,4.0,0.3229530278849659,0.6657272327837613,0.3225,0.3225,0.6625,0.7025,0.0,0.040000000000000036 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,2,this,1.0225000381469727,1.3424999713897705,True,7.521722367133041e-14,0.3343006670475006,1.0222614949808086,1.342502502681455,1.0225,1.0225,1.3425,1.3425,0.0,0.0 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,3,man,1.5225000381469727,1.6825000047683716,True,7.045138262920872e-14,0.3131190240383148,1.5236198190614774,1.6824829413710227,1.5225,1.5425,1.6824999999999999,1.6824999999999999,0.020000000000000018,0.0 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,4,"here,",1.902500033378601,2.0824999809265137,True,2.3500652988829758e-14,0.25,1.894543622342994,2.0867907583195966,1.7025,1.9825,2.0425,2.2025,0.28,0.16000000000000014 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,5,and,2.122499942779541,2.262500047683716,True,2.832734047331087e-13,1.2590000629425049,2.1331121793088736,2.2719190723194225,2.1225,2.2825,2.2625,2.3825,0.16000000000000014,0.11999999999999966 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,6,if,2.322499990463257,2.382499933242798,True,5.582629085572333e-13,2.48118257522583,2.33868003750859,2.4031823336609714,2.2825,2.5625,2.3825,2.6425,0.2799999999999998,0.26000000000000023 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,7,you,2.4825000762939453,2.6424999237060547,True,9.512268766718665e-14,0.4227698743343353,2.5072316046245557,2.6582997433161406,2.4825,2.7425,2.6425,2.8425,0.26000000000000023,0.19999999999999973 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,8,can,2.742500066757202,2.8424999713897705,True,4.3768065343882667e-13,1.945258378982544,2.75386187499682,2.937324736774701,2.7425,2.8825,2.8425,4.0425,0.13999999999999968,1.2000000000000006 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,9,"tell,",2.882499933242798,4.082499980926514,True,2.2499873058440256e-13,1.0,2.980365531712314,4.098930060097728,2.8825,4.1225000000000005,4.0825000000000005,4.282500000000001,1.2400000000000007,0.20000000000000018 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,10,he,4.122499942779541,4.182499885559082,True,4.699343873564542e-14,0.25,4.143350252178951,4.2046936964374835,4.1025,4.402500000000001,4.1825,4.4625,0.3000000000000007,0.28000000000000025 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,11,has,4.222499847412109,4.34250020980835,True,1.2339205991609287e-13,0.5484122633934021,4.245734427287916,4.369364316926948,4.2225,4.522500000000001,4.3425,4.6825,0.3000000000000007,0.33999999999999986 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,12,a,4.402500152587891,4.422500133514404,True,4.446784954148519e-12,4.0,4.431854037932112,4.451854037932103,4.402500000000001,4.742500000000001,4.4225,4.7625,0.33999999999999986,0.33999999999999986 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,13,lot,4.522500038146973,4.682499885559082,True,2.9134436833541666e-14,0.25,4.5482175681919905,4.7054606013575935,4.522500000000001,4.8425,4.6825,4.9625,0.3199999999999994,0.28000000000000025 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,14,of,4.742499828338623,4.802499771118164,True,5.46444290031446e-15,0.25,4.767774255389696,4.82777455421578,4.742500000000001,5.062500000000001,4.8025,5.1225000000000005,0.3200000000000003,0.3200000000000003 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,15,big,4.84250020980835,4.962500095367432,True,2.147364317611755e-12,4.0,4.875985463534146,5.002288285727535,4.8425,5.202500000000001,4.9625,5.3425,0.3600000000000003,0.3799999999999999 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,16,"muscles,",5.0625,5.462500095367432,True,1.9685501397915563e-14,0.25,5.087760129561801,5.490328924230847,5.062500000000001,5.3825,5.4625,5.8025,0.3199999999999994,0.33999999999999986 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,17,he,5.682499885559082,5.802499771118164,True,2.0166227628765077e-12,4.0,5.678916934830031,5.797729507728853,5.6225000000000005,5.862500000000001,5.702500000000001,5.9225,0.2400000000000002,0.21999999999999975 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,18,looks,6.502500057220459,6.762499809265137,True,4.851144984850675e-13,2.156076669692993,6.49249963470516,6.761737275706995,6.5025,6.5025,6.7625,6.7625,0.0,0.0 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,19,very,7.202499866485596,7.402500152587891,True,6.853084722965863e-13,3.045832633972168,7.2021361104523285,7.402531057662287,7.202500000000001,7.202500000000001,7.402500000000001,7.402500000000001,0.0,0.0 +-iRBcNs9oI8/8,-iRBcNs9oI8,8,20,strong,7.602499961853027,8.0024995803833,True,4.99631972350912e-14,0.25,7.602283377792524,8.002472983869318,7.602500000000001,7.602500000000001,8.0025,8.0025,0.0,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,0,If,0.5224999785423279,0.5824999809265137,True,3.035739655531458e-14,0.25,0.5224777847512705,0.5825087523727438,0.5225,0.5225,0.5824999999999999,0.5824999999999999,0.0,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,1,it,0.6625000238418579,0.7425000071525574,True,9.317088658748751e-14,0.5512282848358154,0.6439698113695347,0.7142330631919445,0.6224999999999999,0.6625,0.6825,0.7424999999999999,0.040000000000000036,0.05999999999999994 +-lzEya4AM_4/5,-lzEya4AM_4,5,2,falls,0.762499988079071,1.0225000381469727,True,1.690241371345158e-13,1.0,0.7456461893744665,1.0056523214029987,0.7224999999999999,0.7625,0.9824999999999999,1.0225,0.040000000000000036,0.040000000000000036 +-lzEya4AM_4/5,-lzEya4AM_4,5,3,into,1.0824999809265137,1.2625000476837158,True,9.029643623526679e-14,0.5342221260070801,1.06263615289812,1.2547635900885998,1.0225,1.0825,1.1624999999999999,1.2625,0.06000000000000005,0.10000000000000009 +-lzEya4AM_4/5,-lzEya4AM_4,5,4,oh,1.2825000286102295,1.3424999713897705,True,5.106823641807916e-14,0.30213576555252075,1.3017148062167647,1.3783215908484356,1.1824999999999999,1.3825,1.2625,1.4625,0.20000000000000018,0.19999999999999996 +-lzEya4AM_4/5,-lzEya4AM_4,5,5,any,1.3825000524520874,1.4824999570846558,True,2.4951281275484294e-13,1.4761962890625,1.416671421638377,1.5684959034922972,1.2825,1.5025,1.4625,1.7425,0.21999999999999997,0.28 +-lzEya4AM_4/5,-lzEya4AM_4,5,6,of,1.6425000429153442,1.7424999475479126,True,2.3230219831082977e-11,4.0,1.6744825900566362,1.7571266553083897,1.6425,1.7825,1.7425,1.8425,0.1399999999999999,0.10000000000000009 +-lzEya4AM_4/5,-lzEya4AM_4,5,7,those,1.8025000095367432,2.0425000190734863,True,3.8556565709266244e-13,2.281127691268921,1.813751078471044,2.042598142283778,1.8025,1.8625,2.0425,2.0425,0.06000000000000005,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,8,three,2.0824999809265137,2.2825000286102295,True,9.28581078132526e-14,0.5493777990341187,2.082500668233339,2.282500675241747,2.0825,2.0825,2.2825,2.2825,0.0,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,9,"categories,",2.322499990463257,2.9024999141693115,True,7.862823212618705e-14,0.4651893675327301,2.3225014444100087,2.9024997494292215,2.3225,2.3225,2.9025,2.9025,0.0,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,10,inducing,3.6424999237060547,4.202499866485596,True,1.9956248025615464e-12,4.0,3.6424999115902814,4.202500006501488,3.6425,3.6425,4.202500000000001,4.202500000000001,0.0,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,11,nausea,4.262499809265137,5.382500171661377,True,1.1790844993073146e-12,4.0,4.463467536769676,5.383299142343135,4.2625,5.022500000000001,5.3825,5.3825,0.7600000000000007,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,12,and,5.422500133514404,5.542500019073486,True,8.983205347125323e-13,4.0,5.424328417539918,5.544325310866087,5.4225,5.4225,5.5425,5.5425,0.0,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,13,vomiting,5.5625,5.982500076293945,True,5.396987652790675e-13,3.1930277347564697,5.576995124703589,5.9820157407403665,5.562500000000001,5.602500000000001,5.982500000000001,5.982500000000001,0.040000000000000036,0.0 +-lzEya4AM_4/5,-lzEya4AM_4,5,14,would,6.022500038146973,6.382500171661377,True,4.5605273707840024e-14,0.2698151469230652,6.023217173328293,6.409607625661401,6.022500000000001,6.022500000000001,6.3825,6.4225,0.0,0.040000000000000036 +-lzEya4AM_4/5,-lzEya4AM_4,5,15,be,6.402500152587891,6.462500095367432,True,7.951032101427113e-16,0.25,6.483258350281619,6.549422500484275,6.402500000000001,6.522500000000001,6.4625,6.602500000000001,0.1200000000000001,0.14000000000000057 +-lzEya4AM_4/5,-lzEya4AM_4,5,16,your,6.502500057220459,6.642499923706055,True,8.889075456611217e-15,0.25,6.592861811750548,6.7463621054641605,6.482500000000001,6.642500000000001,6.6225000000000005,6.8025,0.16000000000000014,0.17999999999999972 +-lzEya4AM_4/5,-lzEya4AM_4,5,17,next,6.682499885559082,6.822500228881836,True,8.763239699866032e-13,4.0,6.774462248977959,6.919159147895202,6.642500000000001,6.862500000000001,6.8025,7.0425,0.21999999999999975,0.2400000000000002 +-lzEya4AM_4/5,-lzEya4AM_4,5,18,step.,6.862500190734863,7.102499961853027,True,8.070761398602799e-13,4.0,6.9531891126610725,7.268405006346323,6.862500000000001,7.0825000000000005,7.102500000000001,7.522500000000001,0.21999999999999975,0.41999999999999993 +-lzEya4AM_4/6,-lzEya4AM_4,6,0,If,0.6225000023841858,0.7024999856948853,True,3.9581296682085487e-13,4.0,0.6218706464646045,0.7023365326741986,0.6224999999999999,0.6224999999999999,0.7025,0.7025,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,1,the,0.7425000071525574,0.8424999713897705,True,7.399572254029266e-15,0.4287492334842682,0.7424768243763704,0.8424768481110348,0.7424999999999999,0.7424999999999999,0.8424999999999999,0.8424999999999999,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,2,product,0.862500011920929,1.2424999475479126,True,1.7258508058543183e-14,1.0,0.8624984023485787,1.2425003773706746,0.8624999999999999,0.8624999999999999,1.2425,1.2425,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,3,or,1.2825000286102295,1.6024999618530273,True,2.486088049834245e-13,4.0,1.282676981052881,1.6025512390288499,1.2825,1.2825,1.6025,1.6025,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,4,poison,1.662500023841858,2.1024999618530273,True,4.366728604144471e-14,2.530189037322998,1.6673157302049542,2.0989654347339073,1.6625,1.7225,2.0625,2.1025,0.05999999999999983,0.040000000000000036 +-lzEya4AM_4/6,-lzEya4AM_4,6,5,is,2.202500104904175,2.262500047683716,True,8.725329588346858e-15,0.5055668354034424,2.180319198328119,2.2460606071930846,2.1425,2.2025,2.2225,2.2625,0.06000000000000005,0.040000000000000036 +-lzEya4AM_4/6,-lzEya4AM_4,6,6,some,2.2825000286102295,2.442500114440918,True,2.255789346007446e-15,0.25,2.278221478596384,2.4349226931964756,2.2625,2.2825,2.4225,2.4425,0.020000000000000018,0.020000000000000018 +-lzEya4AM_4/6,-lzEya4AM_4,6,7,type,2.4625000953674316,2.682499885559082,True,1.0200491167879078e-13,4.0,2.462554132308005,2.682496700492244,2.4625,2.4625,2.6825,2.6825,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,8,of,2.702500104904175,2.762500047683716,True,5.058627467109146e-14,2.9310920238494873,2.7039424007353188,2.7639755466185556,2.7025,2.7025,2.7625,2.7625,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,9,petroleum,2.882499933242798,3.3424999713897705,True,4.413881640828038e-13,4.0,2.8775856658907264,3.3593962724351547,2.8225,2.8825,3.3425,3.4225,0.06000000000000005,0.08000000000000007 +-lzEya4AM_4/6,-lzEya4AM_4,6,10,product,3.4024999141693115,3.822499990463257,True,5.6658426865127676e-14,3.2829272747039795,3.4179361032192093,3.8208257166363166,3.4025,3.4425,3.8225000000000002,3.8225000000000002,0.040000000000000036,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,11,or,4.222499847412109,4.302499771118164,True,2.7757481439760236e-14,1.608336091041565,4.12428872001621,4.2612516688364535,3.8825,4.2225,4.242500000000001,4.3025,0.3400000000000003,0.05999999999999961 +-lzEya4AM_4/6,-lzEya4AM_4,6,12,corrosive,4.362500190734863,4.84250020980835,True,4.3797563774490567e-13,4.0,4.329747394910065,4.842412625596829,4.3025,4.362500000000001,4.8425,4.8425,0.0600000000000005,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,13,"product,",4.862500190734863,5.262499809265137,True,3.187660435632379e-14,1.8470081090927124,4.862499669555491,5.262370885994928,4.862500000000001,4.862500000000001,5.2625,5.2625,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,14,you,5.802499771118164,5.902500152587891,True,1.5641947796290719e-15,0.25,5.53509435686845,5.867162990568692,5.322500000000001,5.8025,5.862500000000001,5.902500000000001,0.47999999999999954,0.040000000000000036 +-lzEya4AM_4/6,-lzEya4AM_4,6,15,would,5.922500133514404,6.122499942779541,True,1.0120089614679573e-14,0.5863826274871826,5.922112572905214,6.122047150371503,5.9225,5.9225,6.1225000000000005,6.1225000000000005,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,16,not,6.142499923706055,6.262499809265137,True,6.352139781784071e-15,0.368058443069458,6.142500764751273,6.2625701809161365,6.142500000000001,6.142500000000001,6.2625,6.2625,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,17,attempt,6.302499771118164,6.822500228881836,True,1.9684304540361092e-15,0.25,6.318155035522648,6.821948412854423,6.3025,6.4625,6.822500000000001,6.822500000000001,0.16000000000000014,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,18,to,7.182499885559082,7.28249979019165,True,1.797134727002988e-14,1.0413036346435547,7.182534654775597,7.28252803343239,7.1825,7.1825,7.282500000000001,7.282500000000001,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,19,induce,7.382500171661377,7.922500133514404,True,4.838478183106891e-14,2.803532123565674,7.414923567572577,7.934817600865357,7.3825,7.5025,7.9225,7.9625,0.1200000000000001,0.040000000000000036 +-lzEya4AM_4/6,-lzEya4AM_4,6,20,vomiting,7.962500095367432,8.382499694824219,True,8.089727889307174e-13,4.0,7.989677049757497,8.384180167319787,7.9625,8.0025,8.3825,8.3825,0.03999999999999915,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,21,and,8.602499961853027,8.702500343322754,True,7.461027882484355e-15,0.4323101341724396,8.558395721540947,8.70051005570173,8.4225,8.6025,8.6825,8.7025,0.17999999999999972,0.02000000000000135 +-lzEya4AM_4/6,-lzEya4AM_4,6,22,"nausea,",8.72249984741211,9.142499923706055,True,1.0365191344119395e-11,4.0,8.722975493432113,9.139562814034488,8.7225,8.7225,9.1225,9.1425,0.0,0.019999999999999574 +-lzEya4AM_4/6,-lzEya4AM_4,6,23,as,9.642499923706055,9.702500343322754,True,8.344037537733745e-14,4.0,9.641942999273425,9.701962157826868,9.6425,9.6425,9.7025,9.7025,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,24,as,9.762499809265137,9.822500228881836,True,5.40865399342727e-12,4.0,9.762383360924126,9.822383364858918,9.7625,9.7625,9.8225,9.8225,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,25,the,9.842499732971191,9.942500114440918,True,6.742547008052472e-15,0.39067959785461426,9.842500125440687,9.942500469035092,9.8425,9.8425,9.942499999999999,9.942499999999999,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,26,product,10.0024995803833,10.342499732971191,True,2.207761392052001e-14,1.2792307138442993,9.999605801336743,10.338683442149089,9.9625,10.0025,10.282499999999999,10.3425,0.03999999999999915,0.0600000000000005 +-lzEya4AM_4/6,-lzEya4AM_4,6,27,burned,10.362500190734863,10.682499885559082,True,1.995170183038096e-14,1.156050205230713,10.362784650428713,10.68227166700739,10.362499999999999,10.362499999999999,10.6825,10.6825,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,28,on,10.702500343322754,10.782500267028809,True,2.3671003850610217e-13,4.0,10.702523528497984,10.782508642676058,10.7025,10.7025,10.782499999999999,10.782499999999999,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,29,the,10.822500228881836,10.922499656677246,True,9.76079348504735e-15,0.5655641555786133,10.823841751296246,10.923854219050918,10.8225,10.8425,10.9225,10.942499999999999,0.019999999999999574,0.019999999999999574 +-lzEya4AM_4/6,-lzEya4AM_4,6,30,way,11.0024995803833,11.1225004196167,True,9.980518066729852e-15,0.5782955288887024,10.97704504414781,11.089484271552267,10.942499999999999,11.0025,11.0625,11.1225,0.0600000000000005,0.0600000000000005 +-lzEya4AM_4/6,-lzEya4AM_4,6,31,down,11.142499923706055,11.382499694824219,True,1.0334919192959893e-14,0.5988304018974304,11.139335546006153,11.392634807234638,11.1025,11.1425,11.3825,11.4225,0.040000000000000924,0.03999999999999915 +-lzEya4AM_4/6,-lzEya4AM_4,6,32,it,11.422499656677246,11.822500228881836,True,4.624125230265992e-15,0.26793307065963745,11.473483985557554,11.813451673400056,11.4225,11.7225,11.7625,11.8225,0.3000000000000007,0.0600000000000005 +-lzEya4AM_4/6,-lzEya4AM_4,6,33,could,11.842499732971191,12.022500038146973,True,3.321526835517517e-15,0.25,11.841404836972417,12.022500039924171,11.8225,11.8425,12.022499999999999,12.022499999999999,0.019999999999999574,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,34,cause,12.0625,12.322500228881836,True,5.640726550264078e-15,0.3268374502658844,12.06249996265842,12.322485847197163,12.0625,12.0625,12.3225,12.3225,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,35,damage,12.362500190734863,12.702500343322754,True,1.301325600690283e-14,0.7540197372436523,12.362499995548271,12.702500000019468,12.362499999999999,12.362499999999999,12.7025,12.7025,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,36,and,12.742500305175781,12.842499732971191,True,3.552262157300055e-16,0.25,12.742469306485088,12.842550373760359,12.7425,12.7425,12.8425,12.8425,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,37,burning,12.882499694824219,13.482500076293945,True,1.0955535659435203e-13,4.0,12.882500009396367,13.474533767589687,12.8825,12.8825,13.4825,13.4825,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,38,on,13.5625,13.6225004196167,True,6.547006318156912e-14,3.793494939804077,13.558178654761617,13.618923926660116,13.5625,13.5625,13.6225,13.6225,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,39,the,13.642499923706055,13.762499809265137,True,5.965204543566466e-15,0.3456384837627411,13.653632540597108,13.769364286143006,13.6425,13.7025,13.7625,13.8025,0.0600000000000005,0.040000000000000924 +-lzEya4AM_4/6,-lzEya4AM_4,6,40,way,13.822500228881836,13.982500076293945,True,1.5995148253318027e-14,0.9267978668212891,13.822149170618747,13.981798894446957,13.8225,13.8225,13.9825,13.9825,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,41,back,14.022500038146973,14.182499885559082,True,3.619833416573879e-15,0.25,14.022029813684714,14.182729174722772,14.022499999999999,14.022499999999999,14.1825,14.1825,0.0,0.0 +-lzEya4AM_4/6,-lzEya4AM_4,6,42,up.,14.202500343322754,14.542499542236328,True,1.867283073430921e-16,0.25,14.203948102653264,14.521972037563804,14.2025,14.2025,14.2825,14.7025,0.0,0.41999999999999993 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,0,There,0.0024999999441206455,0.48249998688697815,True,8.852508309731277e-11,1.0036022663116455,0.0698258865699199,0.5209542854210507,0.0025000000000000005,0.2225,0.3025,0.8225,0.22,0.52 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,1,are,0.5024999976158142,0.6025000214576721,True,8.811709695244474e-11,0.9989769458770752,0.6773580062375331,0.9126256507986633,0.4025,1.0225,0.6024999999999999,1.2825,0.6199999999999999,0.68 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,2,a,0.6225000023841858,0.6424999833106995,True,8.820733726766505e-11,1.0,1.0689133910196154,1.0889133910215332,0.7224999999999999,1.4825,0.7424999999999999,1.5025,0.76,0.76 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,3,dozen,0.6625000238418579,0.8424999713897705,True,8.838636073038586e-11,1.002029538154602,1.2452262918671384,1.6960141945305303,0.8624999999999999,1.6625,1.2825,2.1625,0.8000000000000002,0.8800000000000001 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,4,or,0.862500011920929,0.9225000143051147,True,8.844412008324198e-11,1.0026843547821045,1.8525124174329262,1.9802406363476905,1.4224999999999999,2.3225,1.5425,2.4625,0.8999999999999999,0.9199999999999999 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,5,more,0.9424999952316284,1.0824999809265137,True,8.837957449214784e-11,1.0019526481628418,2.13674030925521,2.479925987685495,1.6824999999999999,2.6225,2.0025,2.9625,0.9400000000000002,0.96 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,6,hands,1.1024999618530273,1.2825000286102295,True,8.822227670624017e-11,1.0001693964004517,2.636425683706365,3.0873399364897796,2.1625,3.1225,2.6025,3.5825,0.96,0.98 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,7,on,5.002500057220459,5.0625,True,8.802221451720271e-11,0.9979012608528137,3.2438396325030245,3.3715681957004184,2.7425,3.7225,2.8825,3.8625,0.98,0.98 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,8,techniques,5.082499980926514,5.462500095367432,True,8.812522239720622e-11,0.999069094657898,3.5280678917076664,4.517627610187784,3.0425,4.0025,4.062500000000001,4.9225,0.9600000000000004,0.8599999999999994 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,9,that,5.482500076293945,5.622499942779541,True,8.802477496905325e-11,0.9979302883148193,4.674114102900365,5.017234219415555,4.242500000000001,5.062500000000001,4.6225000000000005,5.362500000000001,0.8200000000000003,0.7400000000000002 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,10,we,5.78249979019165,5.84250020980835,True,8.77886582872911e-11,0.9952534437179565,5.173628548001558,5.301276562327708,4.8025,5.482500000000001,4.942500000000001,5.602500000000001,0.6800000000000006,0.6600000000000001 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,11,can,5.862500190734863,5.962500095367432,True,8.818036578706057e-11,0.9996942281723022,5.4575589081038185,5.692827986897282,5.1425,5.702500000000001,5.4225,5.8825,0.5600000000000005,0.45999999999999996 +-mJ2ud6oKI8/1,-mJ2ud6oKI8,1,12,do,5.982500076293945,6.042500019073486,True,9.066991601969221e-11,1.0279181003570557,5.849047962874614,5.976323928323296,5.6425,5.982500000000001,5.822500000000001,6.0425,0.34000000000000075,0.21999999999999975 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,0,So,0.0024999999441206455,0.0625,True,9.096196018631986e-11,1.0093817710876465,0.032718039902220324,0.12302393990958412,0.0025000000000000005,0.10250000000000001,0.0625,0.2225,0.1,0.16 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,1,physical,0.08250000327825546,0.7425000071525574,True,9.035900500053984e-11,1.0026909112930298,0.20484162269624073,0.7183170211432781,0.10250000000000001,0.3425,0.5425,0.9425,0.24000000000000002,0.4 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,2,therapists,0.762499988079071,1.1425000429153442,True,9.044751059228417e-11,1.0036730766296387,0.7999759850899307,1.454059627827414,0.6024999999999999,1.0225,1.2025,1.7225,0.42000000000000004,0.52 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,3,and,1.162500023841858,1.2625000476837158,True,9.025457464728603e-11,1.0015320777893066,1.5358937446088856,1.6969050105096142,1.2825,1.8225,1.4224999999999999,1.9825,0.54,0.56 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,4,chiropractors,1.3025000095367432,1.8025000095367432,True,9.00861468755565e-11,0.9996631145477295,1.7787420065370874,2.644814585780178,1.5025,2.0625,2.3425,2.9425,0.56,0.6000000000000001 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,5,will,1.8224999904632568,1.962499976158142,True,9.00861468755565e-11,0.9996631145477295,2.72665159286188,2.9581697385244805,2.4225,3.0225,2.6625,3.2625,0.6000000000000001,0.6000000000000001 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,6,do,1.9824999570846558,2.0425000190734863,True,9.00861468755565e-11,0.9996631145477295,3.0400067456061746,3.1305127941614,2.7425,3.3425,2.8225,3.4225,0.5999999999999996,0.6000000000000001 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,7,joint,2.0625,2.242500066757202,True,9.00861468755565e-11,0.9996631145477295,3.2123498012430876,3.51437399545938,2.9225,3.5025,3.2225,3.8025,0.5800000000000001,0.5800000000000001 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,8,manipulations,2.262500047683716,2.762500047683716,True,9.00861468755565e-11,0.9996631145477295,3.5962110025410743,4.462293761119333,3.3025,3.8825,4.202500000000001,4.702500000000001,0.5799999999999996,0.5 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,9,and,4.722499847412109,4.822500228881836,True,9.011650453638609e-11,1.0,4.544132032136779,4.705125324259879,4.3025,4.7625,4.4625,4.9225,0.45999999999999996,0.45999999999999996 +-mJ2ud6oKI8/2,-mJ2ud6oKI8,2,10,mobilizations,4.84250020980835,5.682499885559082,True,9.054999805524488e-11,1.0048103332519531,4.786928814409058,5.65272602695609,4.562500000000001,4.982500000000001,5.5825000000000005,5.6825,0.41999999999999993,0.09999999999999964 +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,0,They,0.02250000089406967,0.3824999928474426,True,5.596440533759718e-14,0.25,0.07685901928112787,0.3990715972593789,0.0225,0.14250000000000002,0.3825,0.4425,0.12000000000000002,0.06 +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,1,are,0.4424999952316284,0.7024999856948853,True,6.72760512663434e-13,1.0,0.5160575050547208,0.7227117404819162,0.4425,0.6024999999999999,0.7025,0.7424999999999999,0.15999999999999992,0.039999999999999925 +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,2,all,0.7825000286102295,0.9424999952316284,True,2.1975723649668433e-13,0.3266500234603882,0.7935273972149047,0.9526167018557699,0.7424999999999999,0.8424999999999999,0.8624999999999999,0.9425,0.09999999999999998,0.08000000000000007 +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,3,very,1.0824999809265137,1.3825000524520874,True,3.322413177908601e-11,4.0,1.1101423300401905,1.4078282823092163,1.0625,1.0825,1.3825,1.3825,0.020000000000000018,0.0 +-mJ2ud6oKI8/6,-mJ2ud6oKI8,6,4,safe,1.8224999904632568,2.1624999046325684,True,4.374835129578036e-12,4.0,1.859322265183538,2.141602476798535,1.7825,1.9425,2.0225,2.1625,0.15999999999999992,0.14000000000000012 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,0,It's,0.0625,0.26249998807907104,True,1.3943171617292194e-10,4.0,0.047669511258957874,0.2484408818378565,0.0025000000000000005,0.0625,0.1825,0.28250000000000003,0.06,0.10000000000000003 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,1,safe,0.4025000035762787,0.6225000023841858,True,4.5447569319012615e-12,4.0,0.3360747022548775,0.5170328362234636,0.2025,0.4025,0.4225,0.6224999999999999,0.2,0.19999999999999996 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,2,and,0.6424999833106995,0.7425000071525574,True,2.003821819912999e-15,0.25,0.5856019452028779,0.7191063800421992,0.4825,0.6425,0.7025,0.7424999999999999,0.15999999999999998,0.039999999999999925 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,3,the,0.8424999713897705,0.9624999761581421,True,1.243637679816667e-12,2.812455415725708,0.8453878094860923,0.9667462538582235,0.8424999999999999,0.8424999999999999,0.9624999999999999,0.9624999999999999,0.0,0.0 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,4,person,1.122499942779541,1.3825000524520874,True,1.8701285366216208e-13,0.4229249060153961,1.0165126982997161,1.308275716440458,0.9824999999999999,1.1225,1.2825,1.3825,0.14000000000000012,0.10000000000000009 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,5,will,1.462499976158142,1.6425000429153442,True,3.865140087329355e-13,0.8740917444229126,1.3867817686280777,1.5999738769213134,1.3625,1.4625,1.5225,1.7225,0.09999999999999987,0.19999999999999996 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,6,feel,1.7024999856948853,1.9225000143051147,True,2.057110043288471e-13,0.46521028876304626,1.6644042882905339,1.8580207414522327,1.5625,1.8425,1.7625,2.0825,0.28,0.32000000000000006 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,7,better,2.0625,2.3424999713897705,True,2.55443778109099e-12,4.0,1.9039668350534087,2.269341184316521,1.8425,2.1225,2.2225,2.3825,0.28,0.1599999999999997 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,8,later,2.382499933242798,2.742500066757202,True,6.280226447392956e-13,1.4202574491500854,2.3391000804104283,2.610403111609425,2.3225,2.4025,2.5225,2.7425,0.08000000000000007,0.2200000000000002 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,9,"on,",2.922499895095825,3.002500057220459,True,4.978645534031712e-13,1.1259082555770874,2.736678888486408,2.8013639750269204,2.6825,2.9225,2.7425,3.0025,0.23999999999999977,0.2599999999999998 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,10,but,3.0225000381469727,3.1424999237060547,True,5.492410657683376e-15,0.25,2.853221959313782,3.0344224455998434,2.8025,3.0225,3.0025,3.1425,0.21999999999999975,0.14000000000000012 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,11,it's,3.182499885559082,3.2825000286102295,True,7.276466755523625e-12,4.0,3.110513745542075,3.269832850162292,3.0625,3.1825,3.2625,3.2825,0.1200000000000001,0.020000000000000018 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,12,sort,3.302500009536743,3.4625000953674316,True,1.0976491254550275e-13,0.25,3.30240099690659,3.461609169642533,3.3025,3.3025,3.4425,3.4825,0.0,0.040000000000000036 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,13,of,3.5425000190734863,3.622499942779541,True,2.677345107768292e-12,4.0,3.5413547723387526,3.6216566418041243,3.5425,3.5425,3.6225,3.6225,0.0,0.0 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,14,like,3.6624999046325684,3.8424999713897705,True,8.644191455296421e-14,0.25,3.666813689753435,3.838871048201672,3.6625,3.7025,3.8225000000000002,3.8625,0.040000000000000036,0.03999999999999959 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,15,flossing,3.882499933242798,4.34250020980835,True,1.1762174621874483e-13,0.26599863171577454,3.8838651729144584,4.3424120629860194,3.8825,3.8825,4.3425,4.3425,0.0,0.0 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,16,your,4.362500190734863,5.0625,True,3.292849730406923e-14,0.25,4.41819147818272,5.111481728190935,4.362500000000001,4.9625,5.022500000000001,5.1625000000000005,0.5999999999999996,0.13999999999999968 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,17,teeth,5.102499961853027,5.922500133514404,True,1.063016455459323e-13,0.25,5.148201109665343,5.921581298640506,5.102500000000001,5.202500000000001,5.9225,5.9225,0.09999999999999964,0.0 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,18,for,5.962500095367432,6.0625,True,6.951333768583784e-14,0.25,5.954329937943031,6.058653654509152,5.942500000000001,5.9625,6.0425,6.062500000000001,0.019999999999999574,0.020000000000000462 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,19,the,6.082499980926514,6.202499866485596,True,4.954940624468662e-11,4.0,6.082503363629208,6.202503801804082,6.0825000000000005,6.0825000000000005,6.202500000000001,6.202500000000001,0.0,0.0 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,20,first,6.262499809265137,6.502500057220459,True,5.828269290797383e-12,4.0,6.26250188369506,6.513630284736709,6.2625,6.2625,6.5025,6.562500000000001,0.0,0.0600000000000005 +-mJ2ud6oKI8/9,-mJ2ud6oKI8,9,21,time,6.662499904632568,6.882500171661377,True,1.4780298296032668e-12,3.342527389526367,6.662037112250419,6.879055062501529,6.6625000000000005,6.6625000000000005,6.862500000000001,6.8825,0.0,0.019999999999999574 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,0,Sometimes,0.7825000286102295,1.162500023841858,True,6.672226790169211e-13,0.2790868580341339,0.4509397771605163,1.1624976149860125,0.0625,0.7825,1.1624999999999999,1.1624999999999999,0.72,0.0 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,1,we,1.222499966621399,1.3624999523162842,True,1.8925133682401452e-10,4.0,1.2224980141426944,1.3624753576252613,1.2225,1.2225,1.3625,1.3625,0.0,0.0 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,2,have,1.4225000143051147,1.6425000429153442,True,1.5286633721009468e-12,0.6394115090370178,1.422078617604423,1.6204572489346851,1.4025,1.4425,1.5825,1.6425,0.039999999999999813,0.06000000000000005 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,3,to,1.7024999856948853,1.8025000095367432,True,2.3907347455887074e-12,1.0,1.7059088038846568,1.799902197420372,1.7025,1.7025,1.7825,1.8025,0.0,0.020000000000000018 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,4,stretch,1.9824999570846558,2.262500047683716,True,5.604740629938654e-12,2.3443591594696045,1.932309459892086,2.2160627365081274,1.8825,1.9825,2.1625,2.2625,0.09999999999999987,0.10000000000000009 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,5,that,2.302500009536743,2.442500114440918,True,2.0492338295013957e-12,0.85715651512146,2.2511005842143135,2.4180146282719335,2.2025,2.3025,2.4025,2.4425,0.10000000000000009,0.040000000000000036 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,6,joint,2.4825000762939453,2.8424999713897705,True,6.914385296957759e-12,2.8921592235565186,2.4558962302559877,2.8143964443535863,2.4225,2.4825,2.7825,2.8425,0.06000000000000005,0.05999999999999961 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,7,that,2.922499895095825,3.182499885559082,True,2.6334511828152163e-12,1.101523756980896,2.889294160998902,3.104634416094476,2.8225,2.9425,3.0625,3.1825,0.1200000000000001,0.1200000000000001 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,8,is,3.2225000858306885,3.2825000286102295,True,1.5851010825088108e-12,0.6630184054374695,3.128230706539492,3.2041105692463807,3.0825,3.2225,3.1825,3.2825,0.14000000000000012,0.10000000000000009 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,9,already,3.302500009536743,3.702500104904175,True,1.9910991258531574e-11,4.0,3.240455573466579,3.5472033751853838,3.2225,3.3025,3.5025,3.7025,0.08000000000000007,0.20000000000000018 +-mJ2ud6oKI8/8,-mJ2ud6oKI8,8,10,irritated,3.742500066757202,4.142499923706055,True,5.874412826838149e-13,0.25,3.594318712702423,4.142499418606456,3.5225,3.7425,4.1425,4.1425,0.2200000000000002,0.0 +-mqbVkbCndg/0,-mqbVkbCndg,0,0,"How,",0.16249999403953552,0.36250001192092896,True,7.513402335186659e-13,3.2922470569610596,0.16295956092843808,0.4110743546178127,0.1625,0.1625,0.3625,0.4625,0.0,0.10000000000000003 +-mqbVkbCndg/0,-mqbVkbCndg,0,1,at,0.4625000059604645,0.9024999737739563,True,5.430498715638943e-13,2.3795535564422607,0.5327332294690263,0.9094743295388469,0.4625,0.8825,0.9025,0.9624999999999999,0.41999999999999993,0.05999999999999994 +-mqbVkbCndg/0,-mqbVkbCndg,0,2,a,0.9825000166893005,1.002500057220459,True,2.976669952192701e-11,4.0,0.9824999384988177,1.0024999384988176,0.9824999999999999,0.9824999999999999,1.0025,1.0025,0.0,0.0 +-mqbVkbCndg/0,-mqbVkbCndg,0,3,particular,1.0225000381469727,1.5625,True,1.1336772991719923e-13,0.4967584013938904,1.035725275560386,1.5800902946906012,1.0225,1.0625,1.5625,1.6025,0.040000000000000036,0.040000000000000036 +-mqbVkbCndg/0,-mqbVkbCndg,0,4,moment,1.6024999618530273,1.9824999570846558,True,1.4489467568476466e-13,0.6349042057991028,1.6349622213695993,2.0086853034404504,1.6025,1.6625,1.9825,2.0425,0.06000000000000005,0.06000000000000005 +-mqbVkbCndg/0,-mqbVkbCndg,0,5,in,2.0225000381469727,2.122499942779541,True,1.2200440310805583e-13,0.5346028804779053,2.0643636679285398,2.153146501312387,2.0225,2.1025,2.1025,2.1825,0.08000000000000007,0.08000000000000007 +-mqbVkbCndg/0,-mqbVkbCndg,0,6,time—our,2.242500066757202,2.942500114440918,True,1.081351371293171e-12,4.0,2.2427627508097463,2.94254615237048,2.2425,2.2425,2.9425,2.9425,0.0,0.0 +-mqbVkbCndg/0,-mqbVkbCndg,0,7,moment,3.002500057220459,3.4024999141693115,True,2.059274381875295e-13,0.9023395776748657,3.032264713672813,3.4035362198847228,3.0025,3.0625,3.4025,3.4025,0.06000000000000005,0.0 +-mqbVkbCndg/0,-mqbVkbCndg,0,8,in,3.442500114440918,3.5425000190734863,True,4.4287579788367115e-13,1.9406076669692993,3.4443813754599724,3.5444835777278967,3.4425,3.4425,3.5425,3.5425,0.0,0.0 +-mqbVkbCndg/0,-mqbVkbCndg,0,9,time—are,3.682499885559082,4.622499942779541,True,1.3476970461921006e-13,0.5905382633209229,3.679404616920505,4.624780510292684,3.6225,3.6825,4.6225000000000005,4.6625000000000005,0.06000000000000005,0.040000000000000036 +-mqbVkbCndg/0,-mqbVkbCndg,0,10,they,4.722499847412109,4.922500133514404,True,7.855013568845021e-14,0.34419354796409607,4.718384341212022,4.920950495392551,4.702500000000001,4.7225,4.9225,4.9225,0.019999999999999574,0.0 +-mqbVkbCndg/0,-mqbVkbCndg,0,11,limited,5.422500133514404,5.902500152587891,True,2.5050260802315927e-13,1.0976605415344238,5.42248890408293,5.900145834505198,5.4225,5.4225,5.8825,5.902500000000001,0.0,0.020000000000000462 +-t217m2on-s/2,-t217m2on-s,2,0,But,0.5224999785423279,0.7024999856948853,True,4.395274508933733e-12,0.7390152812004089,0.5225184924573115,0.725752175317485,0.5225,0.5225,0.7025,0.7424999999999999,0.0,0.039999999999999925 +-t217m2on-s/2,-t217m2on-s,2,1,a,0.7225000262260437,0.7425000071525574,True,3.8194742507657864e-11,4.0,0.8000684223499559,0.820068422350041,0.7224999999999999,0.9025,0.7424999999999999,0.9225,0.18000000000000005,0.18000000000000005 +-t217m2on-s/2,-t217m2on-s,2,2,good,0.862500011920929,1.002500057220459,True,7.123131945396821e-12,1.1976734399795532,0.9991130601109262,1.1892688242883607,0.7825,1.3625,1.0025,1.5625,0.5800000000000001,0.56 +-t217m2on-s/2,-t217m2on-s,2,3,thing,1.0625,1.5625,True,4.771816188714473e-12,0.802326500415802,1.2388210425890023,1.644624686370855,1.0625,1.6025,1.5625,1.8225,0.54,0.26 +-t217m2on-s/2,-t217m2on-s,2,4,to,1.6425000429153442,1.7024999856948853,True,1.0024173158207361e-10,4.0,1.7111086033802672,1.7718470918463047,1.6425,1.8625,1.7025,1.9224999999999999,0.21999999999999997,0.21999999999999997 +-t217m2on-s/2,-t217m2on-s,2,5,do,1.722499966621399,1.8224999904632568,True,1.4645716280362042e-12,0.25,1.8248417371760293,1.899259041877084,1.7225,2.0025,1.8225,2.0625,0.28,0.24 +-t217m2on-s/2,-t217m2on-s,2,6,is,1.8624999523162842,1.9225000143051147,True,2.995276249251333e-11,4.0,1.9473941160787953,2.048927727382598,1.8625,2.1225,1.9224999999999999,2.3225,0.26,0.3999999999999999 +-t217m2on-s/2,-t217m2on-s,2,7,"yawning,",2.002500057220459,2.5225000381469727,True,2.0731873249385524e-12,0.34858280420303345,2.126425467276586,2.7815458651990497,2.0025,2.4025,2.5225,3.3825,0.3999999999999999,0.8599999999999999 +-t217m2on-s/2,-t217m2on-s,2,8,chewing,3.322499990463257,3.862499952316284,True,8.043577089111853e-12,1.352435827255249,3.3678403420855934,3.876952620924111,3.3225000000000002,3.4625,3.8625,3.9025,0.13999999999999968,0.040000000000000036 +-t217m2on-s/2,-t217m2on-s,2,9,gum,4.002500057220459,4.182499885559082,True,4.4149128797243975e-12,0.742317259311676,4.002468735954162,4.1826709100986985,4.0025,4.0025,4.1825,4.1825,0.0,0.0 +-t217m2on-s/2,-t217m2on-s,2,10,is,4.302499771118164,4.402500152587891,True,4.180251630958587e-11,4.0,4.302498326491306,4.402498558458009,4.3025,4.3025,4.402500000000001,4.402500000000001,0.0,0.0 +-t217m2on-s/2,-t217m2on-s,2,11,effective.,4.422500133514404,5.042500019073486,True,2.2316224389251627e-12,0.3752218782901764,4.423601965630909,5.043327191160557,4.4225,4.4225,5.0425,5.0425,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,0,If,0.5224999785423279,0.6025000214576721,True,2.0082098740962498e-15,0.25,0.3015441331703468,0.6023878008153598,0.0625,0.5425,0.5824999999999999,0.6024999999999999,0.48,0.020000000000000018 +-t217m2on-s/7,-t217m2on-s,7,1,you,0.6424999833106995,0.8025000095367432,True,8.301148532669292e-14,0.42261114716529846,0.6434799647001955,0.7975552797224235,0.6425,0.6425,0.7625,0.8025,0.0,0.040000000000000036 +-t217m2on-s/7,-t217m2on-s,7,2,find,0.8424999713897705,1.122499942779541,True,2.140681512260989e-12,4.0,0.8412030234650724,1.1153169739376245,0.8424999999999999,0.8424999999999999,1.0625,1.1225,0.0,0.06000000000000005 +-t217m2on-s/7,-t217m2on-s,7,3,that,1.1425000429153442,1.3424999713897705,True,1.610306723882004e-15,0.25,1.1383865714841004,1.3366361795938604,1.1025,1.1425,1.2825,1.3425,0.040000000000000036,0.06000000000000005 +-t217m2on-s/7,-t217m2on-s,7,4,your,1.402500033378601,1.5425000190734863,True,4.7928254789421365e-14,0.25,1.4035147118997728,1.5474983663610131,1.4025,1.4025,1.5425,1.6025,0.0,0.06000000000000005 +-t217m2on-s/7,-t217m2on-s,7,5,ears,1.7024999856948853,2.0225000381469727,True,1.2316479758821275e-13,0.6270315051078796,1.7035309636037015,2.0069588683882187,1.7025,1.7225,1.9425,2.0225,0.020000000000000018,0.08000000000000007 +-t217m2on-s/7,-t217m2on-s,7,6,consistently,2.7225000858306885,4.002500057220459,True,5.272141772628969e-13,2.6840453147888184,2.6778890918337224,4.004975277533073,2.0225,2.7225,4.0025,4.0025,0.7000000000000002,0.0 +-t217m2on-s/7,-t217m2on-s,7,7,do,4.28249979019165,4.402500152587891,True,2.9934043525164933e-12,4.0,4.279017335996583,4.399301163358553,4.282500000000001,4.282500000000001,4.402500000000001,4.402500000000001,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,8,this,4.522500038146973,4.702499866485596,True,1.2310472770565937e-14,0.25,4.4871016225096705,4.692839750002059,4.442500000000001,4.522500000000001,4.6625000000000005,4.702500000000001,0.08000000000000007,0.040000000000000036 +-t217m2on-s/7,-t217m2on-s,7,9,and,4.78249979019165,4.882500171661377,True,2.4961423986807896e-14,0.25,4.771094354005105,4.876832336738395,4.702500000000001,4.782500000000001,4.8425,4.8825,0.08000000000000007,0.040000000000000036 +-t217m2on-s/7,-t217m2on-s,7,10,you,4.902500152587891,5.002500057220459,True,2.269763060296537e-15,0.25,4.900825762575524,5.003465900093947,4.902500000000001,4.902500000000001,5.0025,5.022500000000001,0.0,0.020000000000000462 +-t217m2on-s/7,-t217m2on-s,7,11,can't,5.042500019073486,5.34250020980835,True,1.9953183549858977e-10,4.0,5.0430587580198285,5.342191859761064,5.0425,5.0425,5.3425,5.3425,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,12,pop,5.5625,5.802499771118164,True,2.0839250464144143e-12,4.0,5.562475953090791,5.802493273965683,5.562500000000001,5.562500000000001,5.8025,5.8025,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,13,them,5.862500190734863,6.0625,True,3.170972870131933e-14,0.25,5.862493429115527,6.062460001350499,5.862500000000001,5.862500000000001,6.062500000000001,6.062500000000001,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,14,"often,",6.182499885559082,6.442500114440918,True,3.143114634123097e-14,0.25,6.167211454501574,6.46103084293285,6.102500000000001,6.1825,6.442500000000001,6.482500000000001,0.07999999999999918,0.040000000000000036 +-t217m2on-s/7,-t217m2on-s,7,15,you'll,6.482500076293945,7.082499980926514,True,6.824945990302478e-12,4.0,6.574808668518842,7.082477879268368,6.482500000000001,6.742500000000001,7.0825000000000005,7.0825000000000005,0.2599999999999998,0.0 +-t217m2on-s/7,-t217m2on-s,7,16,definitely,7.102499961853027,7.702499866485596,True,7.39595559275108e-13,3.7652781009674072,7.102586666901631,7.699765961681586,7.102500000000001,7.102500000000001,7.6825,7.702500000000001,0.0,0.020000000000000462 +-t217m2on-s/7,-t217m2on-s,7,17,need,7.742499828338623,7.902500152587891,True,4.3668524742426773e-13,2.223162889480591,7.742483042947323,7.90343923658525,7.742500000000001,7.742500000000001,7.902500000000001,7.902500000000001,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,18,to,7.982500076293945,8.042499542236328,True,7.402548727805918e-15,0.25,7.967266830139866,8.02793425896618,7.942500000000001,7.982500000000001,8.0025,8.0425,0.040000000000000036,0.040000000000000924 +-t217m2on-s/7,-t217m2on-s,7,19,see,8.0625,8.202500343322754,True,6.569796789923643e-13,3.3446807861328125,8.062499998585567,8.202499998830312,8.0625,8.0625,8.202499999999999,8.202499999999999,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,20,a,8.242500305175781,8.262499809265137,True,2.488813842516091e-11,4.0,8.242500408823773,8.262500408823774,8.2425,8.2425,8.2625,8.2625,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,21,physician,8.322500228881836,8.882499694824219,True,4.652816760347678e-13,2.3687472343444824,8.318703380787824,8.881929128769334,8.282499999999999,8.3225,8.8825,8.8825,0.040000000000000924,0.0 +-t217m2on-s/7,-t217m2on-s,7,22,regarding,8.90250015258789,9.922499656677246,True,1.5294997256568021e-13,0.778667688369751,8.904235783104783,9.922499327985719,8.9025,8.9025,9.9225,9.9225,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,23,those,9.942500114440918,10.162500381469727,True,1.9642521929732343e-13,1.0,9.942499955586987,10.162498402387016,9.942499999999999,9.942499999999999,10.1625,10.1625,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,24,"things,",10.202500343322754,10.522500038146973,True,3.872858929171094e-14,0.25,10.202499406780868,10.522499422185247,10.2025,10.2025,10.522499999999999,10.522499999999999,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,25,it,10.90250015258789,10.982500076293945,True,1.0897798505618561e-13,0.5548064708709717,10.90176918863294,10.98161988705827,10.9025,10.9025,10.9825,10.9825,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,26,could,11.022500038146973,11.22249984741211,True,3.0060584013322234e-13,1.5303831100463867,11.022415515548126,11.222436263178336,11.022499999999999,11.022499999999999,11.2225,11.2225,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,27,be,11.242500305175781,11.302499771118164,True,3.1117084820300733e-13,1.5841695070266724,11.242499890968537,11.302500000932035,11.2425,11.2425,11.3025,11.3025,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,28,something,11.362500190734863,11.762499809265137,True,1.3482193775293545e-14,0.25,11.36250003427757,11.76250000280012,11.362499999999999,11.362499999999999,11.7625,11.7625,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,29,more,11.782500267028809,11.982500076293945,True,2.739622764758032e-13,1.3947408199310303,11.782500172700903,11.982499985922653,11.782499999999999,11.782499999999999,11.9825,11.9825,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,30,of,12.0024995803833,12.0625,True,1.2251334495505528e-11,4.0,12.00250300781206,12.062503075601885,12.0025,12.0025,12.0625,12.0625,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,31,a,12.1225004196167,12.142499923706055,True,1.9523441023572286e-12,4.0,12.122493511797718,12.142493511797717,12.1225,12.1225,12.1425,12.1425,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,32,nasal,12.202500343322754,12.482500076293945,True,1.2489926627667902e-12,4.0,12.202481052988533,12.482563637084958,12.2025,12.2025,12.4825,12.4825,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,33,infection,12.542499542236328,13.082500457763672,True,1.863801268268267e-13,0.9488604664802551,12.548488364093338,13.112190709215227,12.5425,12.5825,13.0825,13.2025,0.03999999999999915,0.120000000000001 +-t217m2on-s/7,-t217m2on-s,7,34,or,13.202500343322754,13.362500190734863,True,1.096706384560997e-12,4.0,13.268630794746127,13.380613030877182,13.2025,13.3425,13.362499999999999,13.4025,0.1399999999999988,0.040000000000000924 +-t217m2on-s/7,-t217m2on-s,7,35,a,13.482500076293945,13.5024995803833,True,5.468596062097042e-12,4.0,13.480302700842564,13.500302700842568,13.442499999999999,13.4825,13.4625,13.5025,0.040000000000000924,0.03999999999999915 +-t217m2on-s/7,-t217m2on-s,7,36,sinus,13.542499542236328,13.802499771118164,True,6.39902573203871e-13,3.2577414512634277,13.55040940879016,13.803847280153091,13.5025,13.5825,13.8025,13.8025,0.08000000000000007,0.0 +-t217m2on-s/7,-t217m2on-s,7,37,infection,13.842499732971191,14.5024995803833,True,1.1748278131579193e-12,4.0,13.844256664988658,14.507515066421155,13.8425,13.8425,14.5025,14.522499999999999,0.0,0.019999999999999574 +-t217m2on-s/7,-t217m2on-s,7,38,that,14.6225004196167,15.322500228881836,True,1.0841008673450128e-14,0.25,14.62701468477748,15.32177485942577,14.6225,14.6225,15.3225,15.3225,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,39,he,15.382499694824219,15.462499618530273,True,1.5006362038411103e-12,4.0,15.382499899762017,15.462499926162874,15.3825,15.3825,15.4625,15.4625,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,40,would,15.522500038146973,15.742500305175781,True,7.458575722102054e-14,0.37971580028533936,15.523687096195976,15.743719806141243,15.522499999999999,15.522499999999999,15.7425,15.7425,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,41,need,15.782500267028809,15.982500076293945,True,6.329921260544644e-14,0.32225602865219116,15.783733230314803,15.975640595301629,15.7825,15.8025,15.9625,15.9825,0.019999999999999574,0.019999999999999574 +-t217m2on-s/7,-t217m2on-s,7,42,to,16.022499084472656,16.082500457763672,True,2.435565990424951e-14,0.25,16.01099501177981,16.070999623759587,15.9825,16.0225,16.0425,16.082500000000003,0.040000000000000924,0.0400000000000027 +-t217m2on-s/7,-t217m2on-s,7,43,deal,16.102500915527344,16.262500762939453,True,5.6791098482689064e-15,0.25,16.102225899317638,16.262741723317955,16.102500000000003,16.102500000000003,16.262500000000003,16.262500000000003,0.0,0.0 +-t217m2on-s/7,-t217m2on-s,7,44,with.,16.342500686645508,16.522499084472656,True,4.8448539695074636e-14,0.25,16.342197762523412,16.52250670243474,16.3425,16.3425,16.5225,16.5225,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,0,The,0.5625,0.6625000238418579,True,6.435688570602394e-14,2.004267930984497,0.5356969890918912,0.658616661956421,0.3425,0.5625,0.6224999999999999,0.6625,0.21999999999999997,0.040000000000000036 +-tANM6ETl_M/3,-tANM6ETl_M,3,1,first,0.7024999856948853,0.9624999761581421,True,3.526284895593451e-14,1.098191738128662,0.7009661313991286,0.9602388802710622,0.7025,0.7025,0.9225,0.9624999999999999,0.0,0.039999999999999925 +-tANM6ETl_M/3,-tANM6ETl_M,3,2,place,1.002500057220459,1.3224999904632568,True,1.331900779580732e-14,0.4147941470146179,0.999946689866764,1.308838714213955,1.0025,1.0025,1.2825,1.3225,0.0,0.040000000000000036 +-tANM6ETl_M/3,-tANM6ETl_M,3,3,is,1.3825000524520874,1.4424999952316284,True,4.107557105185273e-15,0.25,1.389821334669526,1.45349568534902,1.3625,1.4224999999999999,1.4425,1.4825,0.05999999999999983,0.040000000000000036 +-tANM6ETl_M/3,-tANM6ETl_M,3,4,either,1.5425000190734863,1.7825000286102295,True,2.895699020735547e-14,0.9018082022666931,1.5201676262785533,1.7605858681075623,1.4825,1.5425,1.7225,1.7825,0.06000000000000005,0.06000000000000005 +-tANM6ETl_M/3,-tANM6ETl_M,3,5,you,1.8624999523162842,2.0225000381469727,True,3.5744268601835966e-14,1.1131845712661743,1.8553028266965272,2.0036440368509445,1.8225,1.8625,1.9224999999999999,2.0225,0.040000000000000036,0.10000000000000009 +-tANM6ETl_M/3,-tANM6ETl_M,3,6,have,2.0625,2.202500104904175,True,7.299865464709121e-15,0.25,2.062385601587532,2.202536012487326,2.0625,2.0625,2.2025,2.2025,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,7,a,2.2825000286102295,2.302500009536743,True,1.1580021663792905e-11,4.0,2.282498533579872,2.302498533579872,2.2825,2.2825,2.3025,2.3025,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,8,"prospect,",2.322499990463257,2.882499933242798,True,4.4684812321421196e-15,0.25,2.3231238527656637,2.882916379552269,2.3225,2.3225,2.8825,2.8825,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,9,or,2.942500114440918,3.002500057220459,True,2.767639904147773e-13,4.0,2.942497276629371,3.0032399939030863,2.9425,2.9425,3.0025,3.0025,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,10,a,3.0625,3.0824999809265137,True,1.837679140803683e-11,4.0,3.0620961698677016,3.0820961698677016,3.0625,3.0625,3.0825,3.0825,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,11,customer,3.1024999618530273,3.4825000762939453,True,1.1064295367489013e-13,3.445755958557129,3.103188292319035,3.4840491250071417,3.1025,3.1025,3.4825,3.4825,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,12,who's,3.5225000381469727,3.682499885559082,True,3.082221630701376e-11,4.0,3.5274568778891453,3.6835674538224654,3.5225,3.5425,3.6825,3.6825,0.020000000000000018,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,13,never,3.882499933242798,4.182499885559082,True,8.976713720498884e-15,0.27956199645996094,3.8070924541804487,4.15445694471168,3.7225,3.8825,4.1225000000000005,4.1825,0.1599999999999997,0.05999999999999961 +-tANM6ETl_M/3,-tANM6ETl_M,3,14,done,4.28249979019165,4.462500095367432,True,3.556252158937656e-15,0.25,4.255324390674593,4.449549096474829,4.202500000000001,4.282500000000001,4.4225,4.4625,0.08000000000000007,0.040000000000000036 +-tANM6ETl_M/3,-tANM6ETl_M,3,15,it,4.482500076293945,4.542500019073486,True,2.5008395351864936e-14,0.7788370251655579,4.485970581662388,4.545979863534526,4.482500000000001,4.522500000000001,4.5425,4.5825000000000005,0.040000000000000036,0.040000000000000036 +-tANM6ETl_M/3,-tANM6ETl_M,3,16,"before,",4.602499961853027,4.982500076293945,True,2.1828892859954152e-14,0.6798176765441895,4.602479292145233,4.978115573980364,4.602500000000001,4.602500000000001,4.982500000000001,4.982500000000001,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,17,or,5.022500038146973,5.082499980926514,True,5.056437717533904e-14,1.5747275352478027,5.0206841105147095,5.0806852891637515,5.022500000000001,5.022500000000001,5.0825000000000005,5.0825000000000005,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,18,they've,5.102499961853027,5.34250020980835,True,3.8970549335291815e-13,4.0,5.101592897531236,5.337826895494357,5.102500000000001,5.102500000000001,5.322500000000001,5.3425,0.0,0.019999999999999574 +-tANM6ETl_M/3,-tANM6ETl_M,3,19,never,5.422500133514404,5.662499904632568,True,2.0569947790450085e-14,0.6406103372573853,5.422381810653897,5.662099104183884,5.4225,5.4225,5.6625000000000005,5.6625000000000005,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,20,tried,5.722499847412109,6.002500057220459,True,1.0326153248988758e-14,0.32158762216567993,5.722183877149623,6.001503992763337,5.7225,5.7225,6.0025,6.0025,0.0,0.0 +-tANM6ETl_M/3,-tANM6ETl_M,3,21,it.,6.0625,6.122499942779541,True,2.0461776804175935e-12,4.0,6.063300842860167,6.130318478523356,6.062500000000001,6.062500000000001,6.1225000000000005,6.1225000000000005,0.0,0.0 +-tPCytz4rww/11,-tPCytz4rww,11,0,Make,0.0024999999441206455,0.14249999821186066,True,3.090905894946594e-14,0.25,0.02169566240224484,0.17425271469887066,0.0025000000000000005,0.0425,0.14250000000000002,0.1825,0.04,0.03999999999999998 +-tPCytz4rww/11,-tPCytz4rww,11,1,sure,0.18250000476837158,0.6225000023841858,True,6.222975260095076e-12,4.0,0.346787166754646,0.6374821536776674,0.1825,0.5025,0.6224999999999999,0.6825,0.31999999999999995,0.06000000000000005 +-tPCytz4rww/11,-tPCytz4rww,11,2,that,0.6625000238418579,0.8224999904632568,True,3.477579552449428e-13,1.9737460613250732,0.6725399070879395,0.8375782669395493,0.6625,0.7025,0.8225,0.8825,0.040000000000000036,0.05999999999999994 +-tPCytz4rww/11,-tPCytz4rww,11,3,your,0.862500011920929,1.0225000381469727,True,3.126307340515556e-15,0.25,0.8784328640568163,1.0433921603265537,0.8624999999999999,0.9225,1.0225,1.1025,0.06000000000000005,0.08000000000000007 +-tPCytz4rww/11,-tPCytz4rww,11,4,using,1.0425000190734863,1.222499966621399,True,1.8500610386110866e-13,1.050026535987854,1.0729127611360898,1.2830561203794688,1.0425,1.1624999999999999,1.2225,1.4625,0.11999999999999988,0.24 +-tPCytz4rww/11,-tPCytz4rww,11,5,comps,1.3025000095367432,1.5425000190734863,True,6.064278853384897e-14,0.34418612718582153,1.3432746992012874,1.6062773987725414,1.2425,1.5625,1.5025,1.8825,0.32000000000000006,0.3800000000000001 +-tPCytz4rww/11,-tPCytz4rww,11,6,that,1.5625,1.8224999904632568,True,6.134831141355046e-13,3.4819042682647705,1.6472699997478626,1.8896951897898389,1.5625,1.9025,1.8225,2.0625,0.3400000000000001,0.24 +-tPCytz4rww/11,-tPCytz4rww,11,7,are,1.9225000143051147,2.0625,True,5.638180792741105e-15,0.25,1.971279454556468,2.097049019461683,1.9224999999999999,2.1025,2.0625,2.2025,0.18000000000000016,0.14000000000000012 +-tPCytz4rww/11,-tPCytz4rww,11,8,not,2.1024999618530273,2.302500009536743,True,1.9874132721475757e-12,4.0,2.133150452735309,2.3222142523728997,2.1025,2.2225,2.3025,2.3825,0.1200000000000001,0.07999999999999963 +-tPCytz4rww/11,-tPCytz4rww,11,9,"larger,",2.502500057220459,2.8424999713897705,True,2.330519674811904e-13,1.3227171897888184,2.4520214020764155,2.820602708781465,2.4025,2.5025,2.7625,2.8425,0.10000000000000009,0.07999999999999963 +-tPCytz4rww/11,-tPCytz4rww,11,10,no,3.2225000858306885,3.322499990463257,True,7.816119171159819e-14,0.4436141550540924,3.2170783747909404,3.32249684334124,3.2225,3.2225,3.3225000000000002,3.3225000000000002,0.0,0.0 +-tPCytz4rww/11,-tPCytz4rww,11,11,larger,3.382499933242798,3.682499885559082,True,9.446646752602622e-15,0.25,3.382499571327774,3.6829963136388377,3.3825,3.3825,3.6825,3.6825,0.0,0.0 +-tPCytz4rww/11,-tPCytz4rww,11,12,than,3.702500104904175,3.9024999141693115,True,2.853919290018818e-14,0.25,3.703456733094279,3.884414196985789,3.7025,3.7025,3.8425,3.9025,0.0,0.06000000000000005 +-tPCytz4rww/11,-tPCytz4rww,11,13,twelve,3.942500114440918,4.242499828338623,True,6.64411762912008e-14,0.37709563970565796,3.9459603741824063,4.243307639989169,3.9425,3.9625,4.242500000000001,4.242500000000001,0.020000000000000018,0.0 +-tPCytz4rww/11,-tPCytz4rww,11,14,hundred,4.262499809265137,4.622499942779541,True,1.7619183835439894e-13,1.0,4.263793015967037,4.62249338252602,4.2625,4.2625,4.6225000000000005,4.6225000000000005,0.0,0.0 +-tPCytz4rww/11,-tPCytz4rww,11,15,square,4.662499904632568,4.982500076293945,True,3.165683318782919e-13,1.7967252731323242,4.662500502666387,4.982478809793004,4.6625000000000005,4.6625000000000005,4.982500000000001,4.982500000000001,0.0,0.0 +-tPCytz4rww/11,-tPCytz4rww,11,16,feet.,5.0625,5.28249979019165,True,3.689433470104725e-13,2.0939865112304688,5.062500417509267,5.282497153233201,5.062500000000001,5.062500000000001,5.282500000000001,5.282500000000001,0.0,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,0,Say,0.0024999999441206455,0.12250000238418579,True,3.2502712327131533e-11,4.0,0.002505057883538294,0.1225226855817078,0.0025000000000000005,0.0025000000000000005,0.1225,0.1225,0.0,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,1,twenty,0.20250000059604645,0.7225000262260437,True,6.181854507458784e-12,1.105215072631836,0.20256298455497526,0.7225242384992536,0.2025,0.2025,0.7224999999999999,0.7224999999999999,0.0,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,2,percent,0.8025000095367432,1.2024999856948853,True,4.0030847560379446e-13,0.25,0.8175673372248227,1.202531136762618,0.8025,0.9025,1.2025,1.2025,0.09999999999999998,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,3,so,1.2424999475479126,1.3825000524520874,True,1.546988042224265e-13,0.25,1.2430952066521186,1.3768309486444459,1.2425,1.2425,1.3625,1.3825,0.0,0.020000000000000018 +-tPCytz4rww/10,-tPCytz4rww,10,4,if,1.5824999809265137,1.722499966621399,True,2.316052731543561e-12,0.41407257318496704,1.582535696275133,1.722513322878117,1.5825,1.5825,1.7225,1.7225,0.0,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,5,you've,1.9424999952316284,2.2825000286102295,True,1.4418195803944656e-10,4.0,1.9519629063531054,2.282409676113536,1.9425,1.9625,2.2825,2.2825,0.020000000000000018,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,6,got,2.4825000762939453,2.6424999237060547,True,1.1913363524851395e-11,2.129915714263916,2.4824364558586436,2.642480769217724,2.4825,2.4825,2.6425,2.6425,0.0,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,7,a,2.702500104904175,2.7225000858306885,True,8.198944127790764e-12,1.4658379554748535,2.702496664722302,2.7224966647239226,2.7025,2.7025,2.7225,2.7225,0.0,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,8,thousand,2.822499990463257,3.2825000286102295,True,6.314457962584841e-13,0.25,2.822534476359815,3.281519597807987,2.8225,2.8225,3.2825,3.2825,0.0,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,9,square,3.322499990463257,3.882499933242798,True,5.894128501243712e-13,0.25,3.4688986221058005,3.8957732430891063,3.3225000000000002,3.6825,3.8825,3.9225,0.3599999999999999,0.040000000000000036 +-tPCytz4rww/10,-tPCytz4rww,10,10,foot,3.9024999141693115,4.122499942779541,True,2.942341509326596e-11,4.0,3.9231015848774184,4.122296003381612,3.9025,3.9625,4.1225000000000005,4.1225000000000005,0.06000000000000005,0.0 +-tPCytz4rww/10,-tPCytz4rww,10,11,condo.,4.422500133514404,4.622499942779541,True,5.004845062689389e-12,0.8947849869728088,4.422276698912244,4.637538051382122,4.4225,4.4225,4.6225000000000005,4.6625000000000005,0.0,0.040000000000000036 +-tPCytz4rww/12,-tPCytz4rww,12,0,No,0.08250000327825546,0.16249999403953552,True,1.4483042586402317e-12,2.761003017425537,0.08114481503602712,0.16217620079296532,0.0625,0.0825,0.1625,0.1625,0.020000000000000004,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,1,less,0.2224999964237213,0.4625000059604645,True,4.10721673685388e-12,4.0,0.22219314838082402,0.4616554631769186,0.2225,0.2225,0.4625,0.4625,0.0,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,2,than,0.5024999976158142,0.6825000047683716,True,5.063582474325312e-13,0.9653059244155884,0.5017505310429379,0.6818042885306567,0.5025,0.5025,0.6825,0.6825,0.0,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,3,eight,0.7024999856948853,1.0425000190734863,True,9.050614532997436e-13,1.7253814935684204,0.7020298754293801,1.0413866100393672,0.7025,0.7025,1.0425,1.0425,0.0,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,4,hundred,1.3624999523162842,1.7424999475479126,True,1.8136402481824104e-13,0.34574684500694275,1.3600963696569792,1.740637256117597,1.3625,1.3625,1.7425,1.7425,0.0,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,5,squire,1.7825000286102295,2.2225000858306885,True,1.852836894328247e-12,3.532191753387451,1.7936826033289333,2.203577332640142,1.7825,1.8225,2.0225,2.2225,0.040000000000000036,0.20000000000000018 +-tPCytz4rww/12,-tPCytz4rww,12,6,feet,2.6024999618530273,2.7825000286102295,True,1.4244164658547276e-12,2.7154641151428223,2.562656419923969,2.737386374888778,2.0425,2.6225,2.2225,2.7825,0.5800000000000001,0.56 +-tPCytz4rww/12,-tPCytz4rww,12,7,and,2.822499990463257,2.922499895095825,True,7.50539994737176e-12,4.0,2.8040084810806176,2.9083167912758485,2.6625,2.8225,2.8825,2.9225,0.1599999999999997,0.040000000000000036 +-tPCytz4rww/12,-tPCytz4rww,12,8,going,2.9825000762939453,3.242500066757202,True,1.8712631270900726e-12,3.567318916320801,2.972907476639749,3.2485900463543764,2.9225,2.9825,3.1825,3.3425,0.06000000000000005,0.1599999999999997 +-tPCytz4rww/12,-tPCytz4rww,12,9,to,3.322499990463257,3.4625000953674316,True,1.7221121718317273e-13,0.3282982110977173,3.3804194320253904,3.4819767729461604,3.2425,3.6425,3.3425,3.7225,0.3999999999999999,0.38000000000000034 +-tPCytz4rww/12,-tPCytz4rww,12,10,similar,3.6424999237060547,4.022500038146973,True,8.151455313694378e-13,1.5539685487747192,3.6554667644090957,4.022687363378376,3.6025,3.7625,3.9625,4.062500000000001,0.16000000000000014,0.10000000000000098 +-tPCytz4rww/12,-tPCytz4rww,12,11,"in,",4.042500019073486,4.122499942779541,True,6.854618001678192e-12,4.0,4.062473519113548,4.135646046857629,4.0425,4.1025,4.1225000000000005,4.1625000000000005,0.05999999999999961,0.040000000000000036 +-tPCytz4rww/12,-tPCytz4rww,12,12,similar,4.942500114440918,5.322500228881836,True,3.7164002886398706e-13,0.7084832191467285,4.856473555076607,5.325159731998561,4.202500000000001,4.942500000000001,5.322500000000001,5.322500000000001,0.7400000000000002,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,13,with,5.582499980926514,5.78249979019165,True,5.430205913289736e-14,0.25,5.565606085452562,5.774287522003375,5.4625,5.5825000000000005,5.742500000000001,5.782500000000001,0.1200000000000001,0.040000000000000036 +-tPCytz4rww/12,-tPCytz4rww,12,14,bedrooms,5.922500133514404,6.322500228881836,True,2.7115378627325104e-13,0.5169193148612976,5.91833513197217,6.321445991446334,5.9225,5.9225,6.322500000000001,6.322500000000001,0.0,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,15,and,6.422500133514404,6.582499980926514,True,1.5096515617457618e-12,2.8779537677764893,6.415225660149443,6.570339834181551,6.3825,6.4225,6.5025,6.5825000000000005,0.040000000000000036,0.08000000000000007 +-tPCytz4rww/12,-tPCytz4rww,12,16,bathrooms,6.662499904632568,7.102499961853027,True,9.588660296539278e-14,0.25,6.649534180591883,7.103515746095183,6.5825000000000005,6.6625000000000005,7.102500000000001,7.102500000000001,0.08000000000000007,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,17,as,7.182499885559082,7.28249979019165,True,2.5051279952358063e-13,0.47756996750831604,7.182713277688271,7.281488350142335,7.1825,7.1825,7.282500000000001,7.282500000000001,0.0,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,18,well,7.882500171661377,8.082500457763672,True,1.5330628205714042e-13,0.2922584116458893,7.743203575778251,8.06287017488467,7.3025,7.8825,8.022499999999999,8.0825,0.5800000000000001,0.0600000000000005 +-tPCytz4rww/12,-tPCytz4rww,12,19,and,8.242500305175781,8.342499732971191,True,1.736000666135995e-13,0.3309458792209625,8.195382128579398,8.336167495849628,8.1225,8.2425,8.3025,8.362499999999999,0.11999999999999922,0.05999999999999872 +-tPCytz4rww/12,-tPCytz4rww,12,20,hopefully,8.362500190734863,8.762499809265137,True,5.427562696155852e-13,1.034693956375122,8.38126225674004,8.800728012660858,8.362499999999999,8.4225,8.7625,8.862499999999999,0.0600000000000005,0.09999999999999964 +-tPCytz4rww/12,-tPCytz4rww,12,21,the,8.842499732971191,9.22249984741211,True,1.5777048450234948e-13,0.30076882243156433,8.939716417127721,9.233476473717799,8.8225,9.1425,9.2225,9.3025,0.3200000000000003,0.08000000000000007 +-tPCytz4rww/12,-tPCytz4rww,12,22,complexes,9.40250015258789,9.862500190734863,True,4.707200883420637e-13,0.8973664045333862,9.400885044089927,9.865401598848464,9.4025,9.4025,9.862499999999999,9.9025,0.0,0.040000000000000924 +-tPCytz4rww/12,-tPCytz4rww,12,23,have,9.942500114440918,10.102499961853027,True,2.9300275313642876e-12,4.0,9.941644931466874,10.10126370487901,9.942499999999999,9.942499999999999,10.1025,10.1025,0.0,0.0 +-tPCytz4rww/12,-tPCytz4rww,12,24,similar,10.162500381469727,10.542499542236328,True,1.139832179379921e-13,0.25,10.163551445389935,10.604138254114487,10.1625,10.1625,10.5425,10.7025,0.0,0.16000000000000014 +-tPCytz4rww/12,-tPCytz4rww,12,25,amenities.,10.6225004196167,11.602499961853027,True,3.5955082227506763e-12,4.0,10.709443501320298,11.61568048027064,10.6225,10.8425,11.5425,11.7225,0.21999999999999886,0.17999999999999972 +-tPCytz4rww/16,-tPCytz4rww,16,0,So,0.5824999809265137,0.7225000262260437,True,1.0900147971726337e-11,2.107679605484009,0.5824988545142109,0.7225003068930176,0.5824999999999999,0.5824999999999999,0.7224999999999999,0.7224999999999999,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,1,make,0.8824999928474426,1.0824999809265137,True,8.273993469531948e-12,1.5998799800872803,0.8873053054868005,1.0895852394390597,0.8624999999999999,0.9624999999999999,1.0825,1.1425,0.09999999999999998,0.06000000000000005 +-tPCytz4rww/16,-tPCytz4rww,16,2,sure,1.1825000047683716,1.3624999523162842,True,4.89173209317767e-13,0.25,1.1824972875537523,1.3625090418290506,1.1824999999999999,1.1824999999999999,1.3625,1.3625,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,3,to,1.4824999570846558,1.662500023841858,True,8.923322150633517e-13,0.25,1.4824959809329938,1.6625015961399936,1.4825,1.4825,1.6625,1.6625,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,4,get,1.9225000143051147,2.0425000190734863,True,2.0692742224576177e-12,0.4001200199127197,1.9224425845184057,2.0424873809086117,1.9224999999999999,1.9224999999999999,2.0425,2.0425,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,5,a,2.1024999618530273,2.122499942779541,True,1.6197307384224757e-11,3.1319515705108643,2.1024966862255567,2.122496686225557,2.1025,2.1025,2.1225,2.1225,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,6,through,2.202500104904175,2.5625,True,6.382161509346784e-13,0.25,2.194829264614116,2.557246651427563,2.1425,2.2025,2.5025,2.5625,0.06000000000000005,0.06000000000000005 +-tPCytz4rww/16,-tPCytz4rww,16,7,or,3.1424999237060547,3.2225000858306885,True,2.622704137200671e-11,4.0,3.1424300748546017,3.2224545318159237,3.1425,3.1425,3.2225,3.2225,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,8,to,4.262499809265137,4.34250020980835,True,9.882743359562393e-14,0.25,4.210863172668486,4.341936445692636,3.9225,4.2625,4.3425,4.3425,0.3400000000000003,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,9,do,4.422500133514404,4.522500038146973,True,1.4996654959520406e-11,2.8997905254364014,4.422508837940596,4.5225076494860605,4.4225,4.4225,4.522500000000001,4.522500000000001,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,10,a,4.662499904632568,4.682499885559082,True,2.231034974820023e-11,4.0,4.6619831203681485,4.681983120368152,4.6625000000000005,4.6625000000000005,4.6825,4.6825,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,11,through,4.722499847412109,5.102499961853027,True,6.987023806748205e-13,0.25,4.722842072869845,5.102508213245117,4.7225,4.7225,5.102500000000001,5.102500000000001,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,12,cleaning,5.122499942779541,5.542500019073486,True,6.977411812388035e-13,0.25,5.123908908733183,5.544329216386563,5.1225000000000005,5.1225000000000005,5.5425,5.5425,0.0,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,13,of,5.582499980926514,5.862500190734863,True,1.382491083418147e-11,2.6732192039489746,5.616153867927133,5.8758597493577955,5.5825000000000005,5.8425,5.862500000000001,5.9625,0.2599999999999998,0.09999999999999964 +-tPCytz4rww/16,-tPCytz4rww,16,14,the,6.262499809265137,6.502500057220459,True,1.5708401246428139e-10,4.0,6.266147318112281,6.501861147995156,6.2625,6.322500000000001,6.5025,6.5025,0.0600000000000005,0.0 +-tPCytz4rww/16,-tPCytz4rww,16,15,property.,6.5625,7.122499942779541,True,1.007599602712017e-12,0.25,6.562252572276781,7.122499604680712,6.562500000000001,6.562500000000001,7.1225000000000005,7.1225000000000005,0.0,0.0 +-tPCytz4rww/18,-tPCytz4rww,18,0,Do,0.5425000190734863,0.6424999833106995,True,6.279769673017688e-12,4.0,0.4577015282761664,0.5637259104571192,0.0425,0.5425,0.10250000000000001,0.6425,0.5,0.5399999999999999 +-tPCytz4rww/18,-tPCytz4rww,18,1,so,0.762499988079071,0.9225000143051147,True,9.772651438089142e-13,4.0,0.7297637425083854,0.8808360734940381,0.5425,0.7625,0.6425,0.9225,0.21999999999999997,0.28 +-tPCytz4rww/18,-tPCytz4rww,18,2,and,1.5225000381469727,1.622499942779541,True,3.8262928524386564e-13,2.566894769668579,1.3848902857859928,1.5188761214324742,0.7025,1.5225,0.9225,1.6225,0.82,0.7000000000000001 +-tPCytz4rww/18,-tPCytz4rww,18,3,as,1.7024999856948853,1.7625000476837158,True,1.1480210228634324e-13,0.7701577544212341,1.6801337977048072,1.7422092862293954,1.5625,1.7025,1.6225,1.7625,0.1399999999999999,0.1399999999999999 +-tPCytz4rww/18,-tPCytz4rww,18,4,well,1.8224999904632568,2.1024999618530273,True,4.317257136640315e-14,0.2896261513233185,1.8047449158844084,2.0739518481040995,1.7025,1.8225,1.9425,2.1025,0.1200000000000001,0.16000000000000014 +-tPCytz4rww/18,-tPCytz4rww,18,5,you'll,2.5625,2.7825000286102295,True,4.398781686121289e-11,4.0,2.5010674825755013,2.7816743887812576,2.1025,2.5625,2.7825,2.7825,0.45999999999999996,0.0 +-tPCytz4rww/18,-tPCytz4rww,18,6,also,2.822499990463257,3.0625,True,1.0343581460098283e-13,0.6939062476158142,2.8229435101245044,3.0581425038034475,2.8025,2.8425,3.0225,3.0825,0.03999999999999959,0.06000000000000005 +-tPCytz4rww/18,-tPCytz4rww,18,7,want,3.1424999237060547,3.322499990463257,True,7.557796314510475e-15,0.25,3.14970832157837,3.3279337466346512,3.1425,3.2025,3.3225000000000002,3.3625,0.06000000000000005,0.03999999999999959 +-tPCytz4rww/18,-tPCytz4rww,18,8,to,3.4024999141693115,3.5425000190734863,True,1.7010866456765306e-13,1.1411856412887573,3.4025001233819,3.5425000693102824,3.4025,3.4025,3.5425,3.5425,0.0,0.0 +-tPCytz4rww/18,-tPCytz4rww,18,9,remove,3.622499942779541,3.942500114440918,True,5.3244467347482796e-14,0.3571941554546356,3.626808956541107,3.9453705442557396,3.6225,3.6825,3.9425,3.9825,0.06000000000000005,0.040000000000000036 +-tPCytz4rww/18,-tPCytz4rww,18,10,any,3.9625000953674316,4.102499961853027,True,1.28017523881932e-13,0.8588143587112427,3.9746334399483496,4.104266931525665,3.9625,4.0025,4.1025,4.1025,0.04000000000000048,0.0 +-tPCytz4rww/18,-tPCytz4rww,18,11,clutter,4.222499847412109,4.662499904632568,True,2.1503506847332307e-14,0.25,4.215421975132926,4.663287259592333,4.1425,4.2225,4.6625000000000005,4.6825,0.08000000000000007,0.019999999999999574 +-tPCytz4rww/18,-tPCytz4rww,18,12,from,4.84250020980835,4.982500076293945,True,5.341139314683774e-13,3.5831398963928223,4.837114731944649,4.977657863914085,4.8425,4.8425,4.982500000000001,4.982500000000001,0.0,0.0 +-tPCytz4rww/18,-tPCytz4rww,18,13,that,5.002500057220459,5.142499923706055,True,5.396275382785328e-16,0.25,4.999508925414773,5.139697183402384,5.0025,5.0025,5.1425,5.1425,0.0,0.0 +-tPCytz4rww/18,-tPCytz4rww,18,14,you've,5.162499904632568,5.34250020980835,True,2.645488515751193e-11,4.0,5.16074853713978,5.342500661315979,5.1625000000000005,5.1625000000000005,5.3425,5.3425,0.0,0.0 +-tPCytz4rww/18,-tPCytz4rww,18,15,accumulated.,5.402500152587891,6.522500038146973,True,8.827004340135336e-13,4.0,5.400102213934783,6.512170678859689,5.3825,5.4625,6.4625,6.522500000000001,0.08000000000000007,0.0600000000000005 +-vxjVxOeScU/4,-vxjVxOeScU,4,0,You're,0.0024999999441206455,0.32249999046325684,True,1.5470193485619954e-12,3.368727445602417,0.0029563428740617594,0.29346729925949566,0.0025000000000000005,0.0025000000000000005,0.2025,0.4225,0.0,0.21999999999999997 +-vxjVxOeScU/4,-vxjVxOeScU,4,1,going,0.5224999785423279,0.7024999856948853,True,9.600089820316349e-13,2.090477228164673,0.5220072174639193,0.7031866953765705,0.5225,0.5225,0.7025,0.7025,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,2,to,0.7225000262260437,0.7825000286102295,True,2.1261818531920912e-13,0.46298885345458984,0.7239908232403981,0.7843177483023872,0.7224999999999999,0.7224999999999999,0.7825,0.7825,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,3,talk,0.8424999713897705,1.122499942779541,True,3.087919934400933e-14,0.25,0.8273659506445371,1.0905327934600164,0.8025,0.8424999999999999,1.0425,1.1225,0.039999999999999925,0.08000000000000007 +-vxjVxOeScU/4,-vxjVxOeScU,4,4,about,1.1825000047683716,1.6024999618530273,True,6.140968809853486e-13,1.3372328281402588,1.1852211848482213,1.6047478626253122,1.1824999999999999,1.1824999999999999,1.6025,1.6025,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,5,their,1.6425000429153442,2.0625,True,6.062020409437633e-15,0.25,1.6640391436621444,2.0694865731735606,1.6425,1.8825,2.0625,2.1025,0.24,0.040000000000000036 +-vxjVxOeScU/4,-vxjVxOeScU,4,6,"life,",2.1024999618530273,2.5425000190734863,True,1.918054690769333e-12,4.0,2.140782386335001,2.579308133483268,2.1025,2.2025,2.5425,2.6425,0.10000000000000009,0.10000000000000009 +-vxjVxOeScU/4,-vxjVxOeScU,4,7,their,2.622499942779541,3.182499885559082,True,1.0584406818343016e-14,0.25,2.7224969696046233,3.1752309276097845,2.6225,2.9625,3.1425,3.1825,0.33999999999999986,0.040000000000000036 +-vxjVxOeScU/4,-vxjVxOeScU,4,8,marriage,3.242500066757202,3.822499990463257,True,9.971537823423061e-15,0.25,3.241210169650607,3.825199297988689,3.1825,3.2425,3.8225000000000002,3.8225000000000002,0.06000000000000005,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,9,and,4.462500095367432,4.5625,True,1.410027368302369e-12,3.0704190731048584,4.452967302117755,4.640251380407333,4.3825,4.5025,4.522500000000001,4.782500000000001,0.1200000000000001,0.2599999999999998 +-vxjVxOeScU/4,-vxjVxOeScU,4,10,usually,4.762499809265137,5.482500076293945,True,1.6004079572001784e-12,3.4849843978881836,4.851114393665739,5.482486596984726,4.7625,5.0025,5.482500000000001,5.482500000000001,0.2400000000000002,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,11,how,5.522500038146973,5.722499847412109,True,4.592296052978451e-13,1.0,5.525640963404545,5.725972052153117,5.522500000000001,5.522500000000001,5.7225,5.7225,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,12,amazing,5.902500152587891,6.502500057220459,True,6.916904657545964e-13,1.506197452545166,5.9024997564652315,6.502508539881368,5.902500000000001,5.902500000000001,6.5025,6.5025,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,13,it,6.662499904632568,6.722499847412109,True,2.1100000002424735e-13,0.4594651460647583,6.662473520526038,6.722503456624384,6.6625000000000005,6.6625000000000005,6.7225,6.7225,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,14,is,6.84250020980835,6.902500152587891,True,6.980565807329772e-16,0.25,6.834745016706655,6.902340309975699,6.7625,6.8425,6.902500000000001,6.902500000000001,0.08000000000000007,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,15,that,6.982500076293945,7.162499904632568,True,1.3848431678741696e-13,0.30155789852142334,6.982535263961875,7.162875631455382,6.982500000000001,6.982500000000001,7.1625000000000005,7.1625000000000005,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,16,they've,7.182499885559082,7.502500057220459,True,1.4167369534467955e-12,3.0850296020507812,7.18830786025921,7.499636426891534,7.1825,7.202500000000001,7.4625,7.5025,0.020000000000000462,0.040000000000000036 +-vxjVxOeScU/4,-vxjVxOeScU,4,17,stayed,7.522500038146973,7.862500190734863,True,2.276652174074134e-13,0.4957546591758728,7.5225191866663135,7.8628040961908825,7.522500000000001,7.522500000000001,7.862500000000001,7.862500000000001,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,18,together,7.922500133514404,8.482500076293945,True,7.508617208898394e-13,1.635046362876892,7.951205794831128,8.482846561288776,7.9225,7.982500000000001,8.4825,8.4825,0.0600000000000005,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,19,this,8.5625,8.782500267028809,True,1.077622973494341e-11,4.0,8.562488552433173,8.782505471531966,8.5625,8.5625,8.782499999999999,8.782499999999999,0.0,0.0 +-vxjVxOeScU/4,-vxjVxOeScU,4,20,long.,8.862500190734863,9.022500038146973,True,1.3307234884873433e-14,0.25,8.84487426972022,9.02198370726463,8.8225,8.862499999999999,9.022499999999999,9.022499999999999,0.03999999999999915,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,0,So,0.6025000214576721,0.8224999904632568,True,4.930794271149064e-13,4.0,0.602499648212456,0.8224999940402619,0.6024999999999999,0.6024999999999999,0.8225,0.8225,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,1,if,0.9424999952316284,1.1425000429153442,True,3.520454937224089e-14,2.2842962741851807,0.9495859338563555,1.1379864720902402,0.9425,0.9425,1.1225,1.1425,0.0,0.020000000000000018 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,2,you,1.2024999856948853,1.3224999904632568,True,8.520083340831774e-15,0.5528374910354614,1.1899086153822664,1.3046461227483739,1.1624999999999999,1.2025,1.2625,1.3425,0.040000000000000036,0.08000000000000007 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,3,have,1.3825000524520874,1.5225000381469727,True,1.1133222165352064e-13,4.0,1.3555953310480724,1.5160767063261227,1.3225,1.3825,1.5025,1.5225,0.06000000000000005,0.020000000000000018 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,4,a,1.5425000190734863,1.5625,True,4.2741949302788074e-13,4.0,1.5406014206323078,1.5606014206323082,1.5225,1.5425,1.5425,1.5625,0.020000000000000018,0.020000000000000018 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,5,loved,1.6024999618530273,1.8224999904632568,True,2.6587540762762485e-12,4.0,1.6017163722664503,1.8216123303039624,1.6025,1.6025,1.8225,1.8225,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,6,one,1.902500033378601,2.002500057220459,True,6.939063734013153e-15,0.4502508342266083,1.896415540653591,2.000333519800293,1.8425,1.9025,1.9825,2.0025,0.06000000000000005,0.020000000000000018 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,7,who,2.0225000381469727,2.1624999046325684,True,2.149073570807008e-15,0.25,2.0224997179877056,2.149062987763053,2.0225,2.0225,2.1225,2.1625,0.0,0.040000000000000036 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,8,is,2.202500104904175,2.262500047683716,True,1.8062620152294213e-14,1.17201828956604,2.1850443997523645,2.2531201231317675,2.1425,2.2025,2.2225,2.2825,0.06000000000000005,0.06000000000000005 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,9,depressed,2.302500009536743,2.9024999141693115,True,8.335262128169425e-16,0.25,2.302498985661637,2.8908095885097147,2.3025,2.3025,2.8625,2.9025,0.0,0.040000000000000036 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,10,those,2.922499895095825,3.4024999141693115,True,2.3576904588807485e-14,1.5298203229904175,2.922649231893573,3.40250415475127,2.9225,2.9225,3.4025,3.4025,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,11,are,3.442500114440918,3.5625,True,4.111901791281625e-14,2.668064832687378,3.4426174034431227,3.5625004913768072,3.4425,3.4425,3.5625,3.5625,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,12,some,3.6024999618530273,3.762500047683716,True,6.959169839785423e-14,4.0,3.6024968346111734,3.762500000089275,3.6025,3.6025,3.7625,3.7625,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,13,of,3.7825000286102295,3.8424999713897705,True,8.037168681778416e-15,0.5215029120445251,3.782500000350712,3.8425000004085677,3.7825,3.7825,3.8425,3.8425,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,14,the,3.862499952316284,3.9625000953674316,True,9.505426603977334e-15,0.6167728900909424,3.8625000018810254,3.9625000861085344,3.8625,3.8625,3.9625,3.9625,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,15,things,4.022500038146973,4.28249979019165,True,2.8207193254314172e-14,1.8302631378173828,4.02228486995236,4.282719674458678,4.022500000000001,4.022500000000001,4.282500000000001,4.282500000000001,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,16,that,4.302499771118164,4.442500114440918,True,2.5476262894126795e-15,0.25,4.317388672273269,4.4650042095716405,4.3025,4.3425,4.442500000000001,4.5025,0.040000000000000036,0.05999999999999961 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,17,you,4.522500038146973,4.622499942779541,True,1.6509219537028477e-15,0.25,4.522330946791593,4.623047680043856,4.522500000000001,4.522500000000001,4.6225000000000005,4.6225000000000005,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,18,should,4.662499904632568,4.882500171661377,True,7.711374716913349e-16,0.25,4.662444498188476,4.892354900163382,4.6625000000000005,4.6625000000000005,4.8825,4.902500000000001,0.0,0.020000000000000462 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,19,think,4.922500133514404,5.162499904632568,True,6.412755661775252e-14,4.0,4.922610088256987,5.162437694966212,4.9225,4.9225,5.1625000000000005,5.1625000000000005,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,20,about,5.182499885559082,5.482500076293945,True,1.2760483587750254e-14,0.8279817700386047,5.182502383872996,5.482478605735311,5.1825,5.1825,5.482500000000001,5.482500000000001,0.0,0.0 +-wMB_hJL-3o/7,-wMB_hJL-3o,7,21,doing.,5.502500057220459,5.942500114440918,True,5.4805903658440016e-17,0.25,5.502500038298437,5.9373994065594875,5.5025,5.5025,5.862500000000001,5.9625,0.0,0.09999999999999964 +-wny0OAz3g8/1,-wny0OAz3g8,1,0,And,0.0625,0.16249999403953552,True,4.102848025515013e-14,0.25,0.06047791614036171,0.1625861933013224,0.0625,0.0625,0.1625,0.1625,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,1,because,0.2224999964237213,0.7225000262260437,True,1.2541806785823506e-12,4.0,0.22249961554408024,0.7191211883038924,0.2225,0.2225,0.6825,0.7224999999999999,0.0,0.039999999999999925 +-wny0OAz3g8/1,-wny0OAz3g8,1,2,they,0.762499988079071,0.9225000143051147,True,5.174728917936577e-13,1.7670706510543823,0.7614318724074157,0.9217152166737397,0.7625,0.7625,0.9225,0.9225,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,3,couldn’t,0.9624999761581421,1.3224999904632568,True,1.1262601094796931e-12,3.8459622859954834,0.9657010687822808,1.3224324547627764,0.9624999999999999,1.0225,1.3225,1.3225,0.06000000000000005,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,4,join,1.3624999523162842,1.5824999809265137,True,9.85640280330713e-13,3.3657724857330322,1.3624999986916286,1.564069483231479,1.3625,1.3625,1.5225,1.5825,0.0,0.06000000000000005 +-wny0OAz3g8/1,-wny0OAz3g8,1,5,"unions,",1.7024999856948853,2.002500057220459,True,9.332146871671859e-14,0.3186749219894409,1.7022222882961973,2.0023825938707542,1.7025,1.7025,2.0025,2.0025,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,6,many,2.1624999046325684,2.322499990463257,True,2.7132393554119005e-12,4.0,2.162479380379709,2.3224794737033037,2.1625,2.1625,2.3225,2.3225,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,7,Black,2.362499952316284,2.5824999809265137,True,1.329381618892303e-14,0.25,2.3624801795036876,2.58248096295503,2.3625,2.3625,2.5825,2.5825,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,8,workers,2.6024999618530273,2.9024999141693115,True,5.2922337329510197e-14,0.25,2.602482919026416,2.9021214065219594,2.6025,2.6025,2.9025,2.9025,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,9,couldn’t,2.922499895095825,3.202500104904175,True,6.70556167016445e-13,2.289820671081543,2.9221269767762283,3.2024805980770332,2.9225,2.9225,3.2025,3.2025,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,10,get,3.242500066757202,3.3424999713897705,True,2.4445779127639684e-14,0.25,3.2424999997519612,3.3425003277495025,3.2425,3.2425,3.3425,3.3425,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,11,manufacturing,3.362499952316284,4.002500057220459,True,1.1555361702220157e-13,0.39459341764450073,3.362711746755879,4.003943023298609,3.3625,3.3625,4.0025,4.022500000000001,0.0,0.020000000000000462 +-wny0OAz3g8/1,-wny0OAz3g8,1,12,or,4.042500019073486,4.102499961853027,True,1.3667748573545357e-12,4.0,4.042501825771753,4.102502245324265,4.0425,4.0425,4.1025,4.1025,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,13,trade,4.162499904632568,4.362500190734863,True,2.0616414323870562e-14,0.25,4.157861064149656,4.35788689791687,4.1225000000000005,4.1625000000000005,4.322500000000001,4.362500000000001,0.040000000000000036,0.040000000000000036 +-wny0OAz3g8/1,-wny0OAz3g8,1,14,work,4.382500171661377,4.542500019073486,True,5.308752315378489e-15,0.25,4.3896416702266565,4.542659962096714,4.3425,4.402500000000001,4.5425,4.5425,0.0600000000000005,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,15,–,nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-wny0OAz3g8/1,-wny0OAz3g8,1,16,which,4.622499942779541,4.822500228881836,True,1.5271720282957705e-15,0.25,4.622532694722632,4.8226636212397045,4.6225000000000005,4.6225000000000005,4.822500000000001,4.822500000000001,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,17,paid,4.862500190734863,5.042500019073486,True,1.2096574826883644e-12,4.0,4.8626972941115385,5.042674934174243,4.862500000000001,4.862500000000001,5.0425,5.0425,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,18,much,5.082499980926514,5.28249979019165,True,3.8547794513690836e-13,1.3163331747055054,5.110245524980024,5.306652598313615,5.0825000000000005,5.1625000000000005,5.282500000000001,5.3425,0.08000000000000007,0.05999999999999961 +-wny0OAz3g8/1,-wny0OAz3g8,1,19,better,5.382500171661377,5.702499866485596,True,1.6741794243795537e-14,0.25,5.3826235445812465,5.702633447017242,5.3825,5.3825,5.702500000000001,5.702500000000001,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,20,than,5.84250020980835,6.042500019073486,True,2.0020649634661103e-13,0.6836667656898499,5.8132744013990765,6.02222844530872,5.782500000000001,5.8425,6.0025,6.0425,0.05999999999999961,0.040000000000000036 +-wny0OAz3g8/1,-wny0OAz3g8,1,21,service,6.102499961853027,6.482500076293945,True,4.1255077153946884e-13,1.4087817668914795,6.104189832791148,6.482308960960844,6.102500000000001,6.102500000000001,6.482500000000001,6.482500000000001,0.0,0.0 +-wny0OAz3g8/1,-wny0OAz3g8,1,22,work,6.522500038146973,6.722499847412109,True,1.1393435023557275e-12,3.890639543533325,6.522533906902053,6.722653624861335,6.522500000000001,6.522500000000001,6.7225,6.7225,0.0,0.0 +-wny0OAz3g8/0,-wny0OAz3g8,0,0,trade,0.4025000035762787,0.6825000047683716,True,6.750676840444614e-12,4.0,0.3219886038225564,0.6163855182678646,0.0425,0.4425,0.5025,0.7224999999999999,0.4,0.21999999999999997 +-wny0OAz3g8/0,-wny0OAz3g8,0,1,labor,0.762499988079071,0.9825000166893005,True,2.737547818640329e-12,2.004483222961426,0.6723732232751013,0.8851323232237341,0.5225,0.7825,0.7224999999999999,0.9824999999999999,0.26,0.26 +-wny0OAz3g8/0,-wny0OAz3g8,0,2,unions,1.1024999618530273,1.3424999713897705,True,1.97636991407929e-13,0.25,0.9698868422267436,1.2332032969798863,0.7625,1.1025,1.0625,1.3425,0.3400000000000001,0.28 +-wny0OAz3g8/0,-wny0OAz3g8,0,3,didn’t,1.3825000524520874,1.6825000047683716,True,1.3657125560659344e-12,1.0,1.2886744936782788,1.5570604996248456,1.1425,1.3825,1.3625,1.6824999999999999,0.24,0.31999999999999984 +-wny0OAz3g8/0,-wny0OAz3g8,0,4,allow,1.722499966621399,1.9424999952316284,True,7.948464342223335e-14,0.25,1.597575059821635,1.8485178438401406,1.3825,1.7625,1.6824999999999999,1.9825,0.3799999999999999,0.30000000000000004 +-wny0OAz3g8/0,-wny0OAz3g8,0,5,Black,2.002500057220459,2.2825000286102295,True,1.8220999795787174e-12,1.3341753482818604,1.9280555178208747,2.2017594206098794,1.7225,2.0025,1.9425,2.2825,0.28,0.3400000000000003 +-wny0OAz3g8/0,-wny0OAz3g8,0,6,workers,2.3424999713897705,2.762500047683716,True,2.0082564354973603e-13,0.25,2.278583747946665,2.7073076409000514,2.0025,2.4025,2.4225,2.8825,0.3999999999999999,0.45999999999999996 +-wny0OAz3g8/0,-wny0OAz3g8,0,7,to,2.822499990463257,2.882499933242798,True,1.7081647240343306e-13,0.25,2.795627903779211,2.867191431881903,2.4825,2.9225,2.6225,2.9825,0.43999999999999995,0.3599999999999999 +-wny0OAz3g8/0,-wny0OAz3g8,0,8,join,2.9625000953674316,3.202500104904175,True,2.8858948650928307e-12,2.113105535507202,2.9688315656033817,3.2127652271035108,2.9225,3.0625,3.2025,3.2425,0.14000000000000012,0.040000000000000036 +-wny0OAz3g8/3,-wny0OAz3g8,3,0,Which,0.0024999999441206455,0.30250000953674316,True,1.063455855494777e-12,4.0,0.002532140686589533,0.2758708790689764,0.0025000000000000005,0.0025000000000000005,0.2225,0.3025,0.0,0.07999999999999999 +-wny0OAz3g8/3,-wny0OAz3g8,3,1,then,0.32249999046325684,0.48249998688697815,True,1.6761636837617916e-13,4.0,0.31656018451331996,0.4774565875920375,0.28250000000000003,0.3225,0.4425,0.4825,0.03999999999999998,0.03999999999999998 +-wny0OAz3g8/3,-wny0OAz3g8,3,2,allowed,0.5425000190734863,0.8224999904632568,True,3.7471050296899316e-14,1.023621916770935,0.5441020695647343,0.8225031085039468,0.5425,0.5625,0.8225,0.8225,0.020000000000000018,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,3,the,0.9024999737739563,1.0225000381469727,True,2.521534498263695e-15,0.25,0.9020954097118318,1.022499565639348,0.9025,0.9025,1.0225,1.0225,0.0,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,4,white,1.0625,1.2424999475479126,True,2.5187026130111395e-14,0.6880509853363037,1.0624995479965396,1.242500032360087,1.0625,1.0625,1.2425,1.2425,0.0,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,5,workers,1.2825000286102295,1.6825000047683716,True,9.733679113372792e-14,2.6590147018432617,1.2825008640728779,1.6824524891403205,1.2825,1.2825,1.6824999999999999,1.6824999999999999,0.0,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,6,and,1.722499966621399,1.8224999904632568,True,3.1632411533893956e-14,0.8641238808631897,1.7225790148273712,1.8226231419127565,1.7225,1.7225,1.8225,1.8225,0.0,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,7,unions,1.962499976158142,2.2225000858306885,True,5.4908461878297975e-15,0.25,1.9136149388959556,2.1972650430525142,1.8825,1.9625,2.1825,2.2225,0.07999999999999985,0.040000000000000036 +-wny0OAz3g8/3,-wny0OAz3g8,3,8,to,2.242500066757202,2.322499990463257,True,2.5397617155523654e-14,0.6938038468360901,2.242499492552246,2.322500654512255,2.2425,2.2425,2.3225,2.3225,0.0,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,9,justify,2.3424999713897705,2.702500104904175,True,2.7394013164643016e-13,4.0,2.3465313452716563,2.708943472591961,2.3425,2.4025,2.7025,2.8025,0.06000000000000005,0.10000000000000009 +-wny0OAz3g8/3,-wny0OAz3g8,3,10,their,2.7825000286102295,3.002500057220459,True,3.7028682257998075e-14,1.0115374326705933,2.7863605350957643,3.0051172336331358,2.7825,2.8425,3.0025,3.0425,0.05999999999999961,0.040000000000000036 +-wny0OAz3g8/3,-wny0OAz3g8,3,11,decision,3.0625,3.442500114440918,True,1.0442468660338666e-14,0.28526395559310913,3.061928269798612,3.446658912342991,3.0625,3.0625,3.4425,3.4825,0.0,0.040000000000000036 +-wny0OAz3g8/3,-wny0OAz3g8,3,12,to,3.5225000381469727,3.622499942779541,True,1.8596247859745813e-13,4.0,3.522543175857031,3.6225387940545746,3.5225,3.5225,3.6225,3.6225,0.0,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,13,not,3.762500047683716,3.922499895095825,True,6.781422211971089e-13,4.0,3.7626099906511024,3.922812910626179,3.7625,3.7625,3.9225,3.9225,0.0,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,14,allow,3.9825000762939453,4.262499809265137,True,3.618399728607356e-14,0.9884626269340515,3.9831660641663293,4.259794101175912,3.9825,3.9825,4.2225,4.2625,0.0,0.040000000000000036 +-wny0OAz3g8/3,-wny0OAz3g8,3,15,black,4.302499771118164,4.622499942779541,True,5.304778426425127e-13,4.0,4.302467397441632,4.6238221223566285,4.3025,4.3025,4.6225000000000005,4.6425,0.0,0.019999999999999574 +-wny0OAz3g8/3,-wny0OAz3g8,3,16,workers,4.822500228881836,5.182499885559082,True,3.043428004187096e-14,0.8313937187194824,4.7511172240657515,5.1626108171564065,4.6625000000000005,4.822500000000001,5.102500000000001,5.1825,0.16000000000000014,0.07999999999999918 +-wny0OAz3g8/3,-wny0OAz3g8,3,17,into,5.202499866485596,5.382500171661377,True,1.884133819828656e-14,0.5147015452384949,5.19585098799925,5.381566976982173,5.1625000000000005,5.202500000000001,5.3825,5.3825,0.040000000000000036,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,18,their,5.422500133514404,5.762499809265137,True,4.205888736515551e-15,0.25,5.421675399709751,5.760589260048857,5.4225,5.4225,5.7625,5.7625,0.0,0.0 +-wny0OAz3g8/3,-wny0OAz3g8,3,19,union,5.78249979019165,6.002500057220459,True,8.382809962674542e-13,4.0,5.782500067776348,6.002500253985618,5.782500000000001,5.782500000000001,6.0025,6.0025,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,0,And,0.0024999999441206455,0.10249999910593033,True,1.7852615273681455e-14,0.39666062593460083,0.009268933724016128,0.11272779056163183,0.0025000000000000005,0.0425,0.10250000000000001,0.1625,0.04,0.06 +-wny0OAz3g8/2,-wny0OAz3g8,2,1,because,0.14249999821186066,0.48249998688697815,True,3.0093440760159407e-13,4.0,0.15613830486104457,0.4783389175803099,0.14250000000000002,0.2225,0.4425,0.4825,0.07999999999999999,0.03999999999999998 +-wny0OAz3g8/2,-wny0OAz3g8,2,2,they,0.5024999976158142,0.6424999833106995,True,3.2948963314140788e-15,0.25,0.500228014631938,0.6411874151576354,0.4625,0.5025,0.6224999999999999,0.6425,0.039999999999999925,0.020000000000000018 +-wny0OAz3g8/2,-wny0OAz3g8,2,3,couldn’t,0.6625000238418579,1.0425000190734863,True,1.0930697536340461e-12,4.0,0.6621778628090622,1.0338893709683967,0.6625,0.6625,0.9824999999999999,1.0425,0.0,0.06000000000000005 +-wny0OAz3g8/2,-wny0OAz3g8,2,4,get,1.122499942779541,1.2424999475479126,True,9.124004449103523e-14,2.027228593826294,1.1044792090557718,1.2214760298378058,1.0025,1.1225,1.1025,1.2425,0.1200000000000001,0.1399999999999999 +-wny0OAz3g8/2,-wny0OAz3g8,2,5,these,1.2625000476837158,1.4424999952316284,True,4.420967765998837e-15,0.25,1.2414761103051,1.4275101963469414,1.1225,1.2625,1.3425,1.4425,0.1399999999999999,0.09999999999999987 +-wny0OAz3g8/2,-wny0OAz3g8,2,6,"jobs,",1.4824999570846558,1.622499942779541,True,9.117111257921076e-17,0.25,1.4671903258153054,1.6149842590168326,1.3825,1.4825,1.5625,1.6225,0.09999999999999987,0.06000000000000005 +-wny0OAz3g8/2,-wny0OAz3g8,2,7,Black,1.6425000429153442,2.0225000381469727,True,4.183806079360863e-12,4.0,1.6425267594186002,2.0225037593548576,1.6425,1.6425,2.0225,2.0225,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,8,communities,2.2225000858306885,2.762500047683716,True,8.090853833263301e-13,4.0,2.2210278203653933,2.762521926399968,2.2225,2.2225,2.7625,2.7625,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,9,had,2.822499990463257,2.922499895095825,True,5.415088831576794e-15,0.25,2.8224974932022153,2.922509663136557,2.8225,2.8225,2.9225,2.9225,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,10,more,2.942500114440918,3.122499942779541,True,4.5007278611473855e-14,1.0,2.942523637142635,3.1224999999350835,2.9425,2.9425,3.1225,3.1225,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,11,men,3.1624999046325684,3.262500047683716,True,3.634124725866543e-14,0.8074526786804199,3.162499999504434,3.2625000000072166,3.1625,3.1625,3.2625,3.2625,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,12,out,3.2825000286102295,3.382499933242798,True,1.8249694102019344e-16,0.25,3.282708035980563,3.3827283868097444,3.2825,3.2825,3.3825,3.3825,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,13,of,3.422499895095825,3.4825000762939453,True,3.758835148519324e-13,4.0,3.4222075384617283,3.4822075403563395,3.4225,3.4225,3.4825,3.4825,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,14,"work,",3.5225000381469727,3.6624999046325684,True,3.3016277022459087e-14,0.7335764169692993,3.522500088158193,3.662500670791443,3.5225,3.5225,3.6625,3.6625,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,15,higher,3.7225000858306885,4.202499866485596,True,6.150453190229823e-15,0.25,3.724500860928217,4.153264174821034,3.7225,3.7225,4.1425,4.202500000000001,0.0,0.0600000000000005 +-wny0OAz3g8/2,-wny0OAz3g8,2,16,rates,4.222499847412109,4.402500152587891,True,4.178439617420239e-14,0.9283919930458069,4.19143499158515,4.3718706695944265,4.1825,4.2225,4.362500000000001,4.402500000000001,0.040000000000000036,0.040000000000000036 +-wny0OAz3g8/2,-wny0OAz3g8,2,17,of,4.422500133514404,4.482500076293945,True,8.391063451712588e-14,1.8643791675567627,4.407059628080299,4.467172046816429,4.402500000000001,4.4225,4.4625,4.482500000000001,0.019999999999999574,0.020000000000000462 +-wny0OAz3g8/2,-wny0OAz3g8,2,18,"poverty,",4.502500057220459,4.982500076293945,True,1.2409367424696255e-13,2.7571911811828613,4.502723343495389,4.982492269661619,4.5025,4.5025,4.982500000000001,4.982500000000001,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,19,and,5.082499980926514,5.182499885559082,True,4.206491823973996e-15,0.25,5.082532400809459,5.1832919282128875,5.0825000000000005,5.0825000000000005,5.1825,5.1825,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,20,more,5.28249979019165,5.522500038146973,True,7.057249478813893e-14,1.5680240392684937,5.286690563603926,5.522587796836602,5.282500000000001,5.362500000000001,5.522500000000001,5.522500000000001,0.08000000000000007,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,21,criminal,5.602499961853027,6.002500057220459,True,5.797682348313363e-14,1.2881654500961304,5.6024998811431255,6.004895968302497,5.602500000000001,5.602500000000001,6.0025,6.0025,0.0,0.0 +-wny0OAz3g8/2,-wny0OAz3g8,2,22,behavior,6.042500019073486,6.502500057220459,True,8.128294044784656e-12,4.0,6.044907337430317,6.502260696408047,6.0425,6.0425,6.5025,6.5025,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,0,This,0.0024999999441206455,0.26249998807907104,True,1.3640474383694312e-12,2.6988413333892822,0.003992614795843328,0.26402516901857465,0.0025000000000000005,0.0025000000000000005,0.2625,0.2625,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,1,is,0.3425000011920929,0.4025000035762787,True,5.003446875567752e-12,4.0,0.3455404024503229,0.4057867967217855,0.3425,0.3425,0.4025,0.4025,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,2,what’s,0.4625000059604645,0.8224999904632568,True,1.3798032161282947e-11,4.0,0.4689256588302098,0.8257665121741922,0.4625,0.4625,0.8225,0.8225,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,3,now,0.8824999928474426,1.002500057220459,True,7.477922361193157e-13,1.4795472621917725,0.884681124078631,1.005510603459454,0.8825,0.8825,1.0025,1.0025,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,4,known,1.1024999618530273,1.402500033378601,True,6.791148996236271e-14,0.25,1.1045596670118656,1.4033642322333042,1.1025,1.1025,1.4025,1.4025,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,5,as,1.5625,1.622499942779541,True,3.495196482499602e-13,0.691543459892273,1.5624999617181765,1.6224999909013247,1.5625,1.5625,1.6225,1.6225,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,6,racial,1.7424999475479126,2.0225000381469727,True,2.5938493432124676e-14,0.25,1.7236696275904895,2.0135054081516173,1.7025,1.7425,1.9825,2.0225,0.040000000000000036,0.040000000000000036 +-wny0OAz3g8/5,-wny0OAz3g8,5,7,formation,2.0425000190734863,2.502500057220459,True,8.995870048227397e-14,0.25,2.042498883726085,2.502516094158499,2.0425,2.0425,2.5025,2.5025,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,8,"theory,",2.5625,2.822499990463257,True,2.28589906335272e-13,0.45227745175361633,2.561166959632408,2.8224983990052683,2.5625,2.5625,2.8225,2.8225,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,9,a,3.1024999618530273,3.122499942779541,True,1.5396341970438931e-12,3.0462491512298584,3.1025002400560107,3.122500240056011,3.1025,3.1025,3.1225,3.1225,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,10,theory,3.182499885559082,3.4024999141693115,True,8.635281346317664e-14,0.25,3.182499996308189,3.4024999967473804,3.1825,3.1825,3.4025,3.4025,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,11,formalized,3.422499895095825,3.922499895095825,True,3.7153637913629745e-13,0.7351047396659851,3.422499999704111,3.9223584723202434,3.4225,3.4225,3.9225,3.9225,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,12,by,3.942500114440918,4.002500057220459,True,2.2909525838887834e-12,4.0,3.942500007809117,4.002500007918179,3.9425,3.9425,4.0025,4.0025,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,13,modern,4.0625,4.362500190734863,True,4.389206148059169e-14,0.25,4.072012047116495,4.362462041170702,4.062500000000001,4.0825000000000005,4.362500000000001,4.362500000000001,0.019999999999999574,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,14,sociologists,4.382500171661377,5.022500038146973,True,7.646028992239207e-13,1.5128079652786255,4.3826825043211555,5.022640992110379,4.3825,4.3825,5.022500000000001,5.022500000000001,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,15,Michael,5.042500019073486,5.442500114440918,True,2.0837234119153863e-13,0.41227591037750244,5.047794963805033,5.442525017815331,5.0425,5.0825000000000005,5.442500000000001,5.442500000000001,0.040000000000000036,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,16,Omi,5.502500057220459,5.622499942779541,True,2.1487714765063698e-14,0.25,5.502505713472408,5.622502608037449,5.5025,5.5025,5.6225000000000005,5.6225000000000005,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,17,and,5.662499904632568,5.822500228881836,True,4.389145297212238e-12,4.0,5.662574457646359,5.822578829922969,5.6625000000000005,5.6625000000000005,5.822500000000001,5.822500000000001,0.0,0.0 +-wny0OAz3g8/5,-wny0OAz3g8,5,18,Howard,5.922500133514404,6.222499847412109,True,6.393029009822693e-13,1.2648952007293701,5.921724323074964,6.218265066239246,5.9225,5.9225,6.1625000000000005,6.2225,0.0,0.05999999999999961 +-wny0OAz3g8/5,-wny0OAz3g8,5,19,Winant,6.302499771118164,6.662499904632568,True,5.3509067836354784e-12,4.0,6.302641526631446,6.662501030109093,6.3025,6.3025,6.6625000000000005,6.6625000000000005,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,0,Omi,0.042500000447034836,0.18250000476837158,True,5.724248657544562e-13,2.633195638656616,0.04244340083416118,0.18338120669739688,0.0425,0.0425,0.1825,0.1825,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,1,and,0.2824999988079071,0.4424999952316284,True,2.6359350899923806e-13,1.212549090385437,0.28245764724904965,0.4467660931471465,0.28250000000000003,0.28250000000000003,0.4425,0.5025,0.0,0.05999999999999994 +-wny0OAz3g8/7,-wny0OAz3g8,7,2,Winant,0.48249998688697815,0.8025000095367432,True,8.451231901795975e-12,4.0,0.49016837626293247,0.7853902575957773,0.4825,0.5225,0.7625,0.8025,0.03999999999999998,0.040000000000000036 +-wny0OAz3g8/7,-wny0OAz3g8,7,3,argue,0.8224999904632568,1.0625,True,7.892336957582291e-13,3.6305317878723145,0.8224757457922287,1.0676672843497057,0.8225,0.8225,1.0625,1.1025,0.0,0.040000000000000036 +-wny0OAz3g8/7,-wny0OAz3g8,7,4,that,1.1425000429153442,1.3224999904632568,True,6.123268938337117e-14,0.2816747725009918,1.1377341883765733,1.3195217703113347,1.0825,1.1425,1.2825,1.3225,0.06000000000000005,0.040000000000000036 +-wny0OAz3g8/7,-wny0OAz3g8,7,5,the,1.3424999713897705,1.4424999952316284,True,1.2730490998120927e-14,0.25,1.3440425032977281,1.4448918858978665,1.3425,1.3625,1.4425,1.4625,0.020000000000000018,0.020000000000000018 +-wny0OAz3g8/7,-wny0OAz3g8,7,6,concept,1.5225000381469727,1.8624999523162842,True,2.460763797590415e-13,1.1319690942764282,1.5279296219329088,1.8634414995423771,1.5225,1.5425,1.8625,1.8625,0.020000000000000018,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,7,of,1.9225000143051147,1.9824999570846558,True,1.3178159735324768e-12,4.0,1.9226435499615355,1.9829324455007173,1.9224999999999999,1.9224999999999999,1.9825,1.9825,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,8,race,2.0824999809265137,2.242500066757202,True,3.6809178751914806e-14,0.25,2.0824184093373526,2.2424999998142665,2.0825,2.0825,2.2425,2.2425,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,9,came,2.2825000286102295,2.4625000953674316,True,1.1092636412277784e-13,0.510269284248352,2.282500009294918,2.46249946919691,2.2825,2.2825,2.4625,2.4625,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,10,about,2.5225000381469727,2.702500104904175,True,1.5981041766614454e-14,0.25,2.50596479396657,2.688239210156162,2.4825,2.5225,2.6625,2.7025,0.040000000000000036,0.040000000000000036 +-wny0OAz3g8/7,-wny0OAz3g8,7,11,as,2.742500066757202,2.822499990463257,True,1.3851884862661062e-13,0.6371966600418091,2.7414056060970298,2.820828518642153,2.7425,2.7425,2.8225,2.8225,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,12,a,2.8424999713897705,2.862499952316284,True,1.0622554051653577e-11,4.0,2.8424999992289264,2.862499999228926,2.8425,2.8425,2.8625,2.8625,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,13,tool,2.922499895095825,3.122499942779541,True,2.4609784696205672e-12,4.0,2.922499514367321,3.122506056854534,2.9225,2.9225,3.1225,3.1225,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,14,to,3.202500104904175,3.262500047683716,True,2.1649702701149326e-13,0.995901882648468,3.2025010194804278,3.2625016442219503,3.2025,3.2025,3.2625,3.2625,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,15,justify,3.322499990463257,3.762500047683716,True,6.311653131564621e-13,2.9034059047698975,3.3224999965992708,3.7625087559140353,3.3225000000000002,3.3225000000000002,3.7625,3.7625,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,16,and,3.8424999713897705,3.9825000762939453,True,6.5197286385301235e-15,0.25,3.842662866801597,3.980611906887309,3.8425,3.8425,3.9625,3.9825,0.0,0.020000000000000018 +-wny0OAz3g8/7,-wny0OAz3g8,7,17,maintain,4.002500057220459,4.462500095367432,True,2.042441863626585e-15,0.25,4.002481016298704,4.461250026333836,4.0025,4.0025,4.4625,4.4625,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,18,the,4.482500076293945,4.582499980926514,True,1.5537561471809513e-12,4.0,4.483034653975056,4.583079213530119,4.482500000000001,4.482500000000001,4.5825000000000005,4.5825000000000005,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,19,economic,4.642499923706055,5.042500019073486,True,2.8485436123597274e-13,1.3103505373001099,4.6367405754513396,5.044914535897253,4.6225000000000005,4.6425,5.0425,5.062500000000001,0.019999999999999574,0.020000000000000462 +-wny0OAz3g8/7,-wny0OAz3g8,7,20,and,5.102499961853027,5.202499866485596,True,1.1146189900961348e-13,0.512732744216919,5.10250104206515,5.202626715315435,5.102500000000001,5.102500000000001,5.202500000000001,5.202500000000001,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,21,political,5.242499828338623,5.602499961853027,True,2.099547554381049e-15,0.25,5.244466340076222,5.62200941915277,5.242500000000001,5.242500000000001,5.602500000000001,5.6425,0.0,0.03999999999999915 +-wny0OAz3g8/7,-wny0OAz3g8,7,22,power,5.622499942779541,5.982500076293945,True,2.1738790238409744e-13,1.0,5.653380236049285,5.989345211747652,5.6225000000000005,5.6625000000000005,5.942500000000001,5.982500000000001,0.040000000000000036,0.040000000000000036 +-wny0OAz3g8/7,-wny0OAz3g8,7,23,held,6.042500019073486,6.222499847412109,True,2.3580451962790586e-14,0.25,6.05669488419283,6.2355620783067325,6.0425,6.0425,6.2225,6.2225,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,24,by,6.28249979019165,6.34250020980835,True,5.590170457070963e-14,0.25715187191963196,6.295711270231749,6.355844879545134,6.282500000000001,6.282500000000001,6.3425,6.3425,0.0,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,25,those,6.382500171661377,6.622499942779541,True,2.3303180132078216e-13,1.0719630718231201,6.397350767685814,6.637488449175456,6.3825,6.4225,6.6225000000000005,6.6225000000000005,0.040000000000000036,0.0 +-wny0OAz3g8/7,-wny0OAz3g8,7,26,of,6.702499866485596,6.762499809265137,True,7.917183923701002e-15,0.25,6.714737727531676,6.779059354262793,6.6625000000000005,6.742500000000001,6.7625,6.8425,0.08000000000000007,0.08000000000000007 +-wny0OAz3g8/7,-wny0OAz3g8,7,27,European,6.822500228881836,7.382500171661377,True,3.6068148251064414e-13,1.6591607332229614,6.839878020990127,7.40042919656395,6.822500000000001,7.0025,7.3825,7.442500000000001,0.17999999999999972,0.0600000000000005 +-wny0OAz3g8/7,-wny0OAz3g8,7,28,descent,7.5625,7.902500152587891,True,5.926632448693958e-12,4.0,7.563703156515533,7.902497095601888,7.562500000000001,7.562500000000001,7.902500000000001,7.902500000000001,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,0,He,0.02250000089406967,0.10249999910593033,True,3.690228678188134e-12,2.9857406616210938,0.01570359411021808,0.08848826505862535,0.0025000000000000005,0.0225,0.0625,0.10250000000000001,0.019999999999999997,0.04000000000000001 +-wny0OAz3g8/9,-wny0OAz3g8,9,1,explores,0.14249999821186066,0.6424999833106995,True,1.33896398742811e-12,1.0833473205566406,0.12249887573356905,0.6389535213723231,0.0825,0.1625,0.5824999999999999,0.6425,0.08,0.06000000000000005 +-wny0OAz3g8/9,-wny0OAz3g8,9,2,why,0.6825000047683716,0.7825000286102295,True,9.870467290729046e-12,4.0,0.6788645232657202,0.784400961311651,0.6625,0.6825,0.7825,0.7825,0.020000000000000018,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,3,Black,0.862500011920929,1.1024999618530273,True,3.686124756124842e-12,2.9824202060699463,0.8631983314393331,1.1029731457106366,0.8624999999999999,0.8624999999999999,1.1025,1.1025,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,4,and,1.1825000047683716,1.3424999713897705,True,5.2772343786533504e-12,4.0,1.1825146996856872,1.342497699820921,1.1824999999999999,1.1824999999999999,1.3425,1.3425,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,5,White,1.402500033378601,1.5824999809265137,True,8.070731583043056e-13,0.6529977917671204,1.4024933386901064,1.5832357178381051,1.4025,1.4025,1.5825,1.5825,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,6,Americans,1.6425000429153442,2.0824999809265137,True,1.0394870999120426e-13,0.25,1.6424944033583473,2.0809849259710984,1.6425,1.6425,2.0825,2.0825,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,7,tend,2.1024999618530273,2.262500047683716,True,3.9480879909748953e-14,0.25,2.102222472329328,2.262513185028439,2.1025,2.1025,2.2625,2.2625,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,8,to,2.2825000286102295,2.3424999713897705,True,6.124948638552841e-13,0.4955657422542572,2.28261991037791,2.3426199111197468,2.2825,2.2825,2.3425,2.3425,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,9,have,2.362499952316284,2.502500057220459,True,1.3514602848277435e-12,1.0934580564498901,2.365759465357853,2.5093280317862643,2.3625,2.4025,2.5025,2.5625,0.040000000000000036,0.06000000000000005 +-wny0OAz3g8/9,-wny0OAz3g8,9,10,such,2.5425000190734863,2.702500104904175,True,4.4576911606419856e-12,3.606689929962158,2.563265883639007,2.7336550703965714,2.5425,2.5825,2.7025,2.7625,0.040000000000000036,0.06000000000000005 +-wny0OAz3g8/9,-wny0OAz3g8,9,11,different,2.802500009536743,3.322499990463257,True,2.1473345020520118e-13,0.25,2.8025875890661442,3.3226400145089827,2.8025,2.8025,3.3225000000000002,3.3225000000000002,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,12,outcomes,3.382499933242798,3.9024999141693115,True,8.532017323550911e-13,0.6903201341629028,3.382868179253032,3.9038235552458773,3.3825,3.3825,3.9025,3.9025,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,13,in,4.002500057220459,4.0625,True,3.568455752243904e-13,0.28872150182724,4.0023310891423645,4.062508621161237,4.0025,4.0025,4.062500000000001,4.062500000000001,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,14,terms,4.162499904632568,4.482500076293945,True,3.854301426631235e-12,3.1184909343719482,4.162879085237475,4.482499860398114,4.1625000000000005,4.1625000000000005,4.482500000000001,4.482500000000001,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,15,of,4.542500019073486,4.662499904632568,True,2.5795234749755556e-14,0.25,4.543504439499194,4.663010117094874,4.522500000000001,4.602500000000001,4.6625000000000005,4.6625000000000005,0.08000000000000007,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,16,"income,",4.722499847412109,5.082499980926514,True,1.1329377106600313e-12,0.9166527390480042,4.722783972994184,5.083036643699158,4.7225,4.7225,5.0825000000000005,5.0825000000000005,0.0,0.0 +-wny0OAz3g8/9,-wny0OAz3g8,9,17,"education,",5.202499866485596,5.722499847412109,True,3.289460934544075e-12,2.661482095718384,5.20112438124031,5.617248567010778,5.202500000000001,5.202500000000001,5.5825000000000005,5.7225,0.0,0.13999999999999968 +-wny0OAz3g8/9,-wny0OAz3g8,9,18,and,5.762499809265137,5.862500190734863,True,3.816548178837628e-14,0.25,5.647324687175936,5.747357974508286,5.6225000000000005,5.7625,5.7225,5.862500000000001,0.13999999999999968,0.14000000000000057 +-wny0OAz3g8/9,-wny0OAz3g8,9,19,more,5.882500171661377,6.022500038146973,True,2.074348722305719e-12,1.6783424615859985,5.817082481580934,5.993166312381108,5.782500000000001,5.8825,5.982500000000001,6.022500000000001,0.09999999999999964,0.040000000000000036 +-571d8cVauQ/0,-571d8cVauQ,0,0,This,0.42250001430511475,1.1425000429153442,True,1.6880530193742792e-15,0.25,0.36545353509037076,1.1497830274676015,0.0425,0.7625,1.1425,1.2025,0.72,0.05999999999999983 +-571d8cVauQ/0,-571d8cVauQ,0,1,is,1.2024999856948853,1.2625000476837158,True,1.1562954370034073e-12,4.0,1.2072494672557035,1.2695928728483776,1.2025,1.2425,1.2625,1.3225,0.040000000000000036,0.06000000000000005 +-571d8cVauQ/0,-571d8cVauQ,0,2,Rhett,1.3025000095367432,1.5425000190734863,True,1.0972020953467845e-13,0.5990563631057739,1.314310355709599,1.5400492489243816,1.3025,1.3425,1.5025,1.5425,0.040000000000000036,0.040000000000000036 +-571d8cVauQ/0,-571d8cVauQ,0,3,"Reiger,",1.5625,1.8825000524520874,True,1.3116477305327723e-13,0.7161405682563782,1.5646701061124126,1.8860143148046669,1.5625,1.5825,1.8825,1.9025,0.020000000000000018,0.020000000000000018 +-571d8cVauQ/0,-571d8cVauQ,0,4,White,1.9225000143051147,2.1424999237060547,True,7.403700862020773e-14,0.4042312800884247,1.9225171969481951,2.1425231516004852,1.9224999999999999,1.9224999999999999,2.1425,2.1425,0.0,0.0 +-571d8cVauQ/0,-571d8cVauQ,0,5,Caspian,2.1624999046325684,2.5625,True,1.1581609152613859e-12,4.0,2.162561668852808,2.5634643731990616,2.1625,2.1625,2.5625,2.5625,0.0,0.0 +-571d8cVauQ/0,-571d8cVauQ,0,6,Studios,2.622499942779541,3.0625,True,1.5272361825711955e-13,0.8338487148284912,2.622576837146804,3.0645311269113757,2.6225,2.6225,3.0625,3.1025,0.0,0.040000000000000036 +-571d8cVauQ/0,-571d8cVauQ,0,7,on,3.1424999237060547,3.202500104904175,True,2.5477747082197633e-12,4.0,3.1424877070707216,3.2024918071032786,3.1425,3.1425,3.2025,3.2025,0.0,0.0 +-571d8cVauQ/0,-571d8cVauQ,0,8,behalf,3.262500047683716,3.6024999618530273,True,7.087249352926567e-14,0.3869534730911255,3.262499999603474,3.5985239851668043,3.2625,3.2625,3.5825,3.6025,0.0,0.020000000000000018 +-571d8cVauQ/0,-571d8cVauQ,0,9,of,3.622499942779541,3.682499885559082,True,2.463900936576502e-13,1.3452539443969727,3.622492865316998,3.6826183503531253,3.6225,3.6225,3.6825,3.6825,0.0,0.0 +-571d8cVauQ/0,-571d8cVauQ,0,10,Expert,3.702500104904175,4.082499980926514,True,4.2966633940003107e-13,2.3459155559539795,3.718376212606498,4.069501795831513,3.7025,3.7825,4.0425,4.0825000000000005,0.08000000000000007,0.040000000000000036 +-571d8cVauQ/0,-571d8cVauQ,0,11,Village.,4.102499961853027,4.982500076293945,True,2.135865269370374e-13,1.1661512851715088,4.102528781943396,4.942896755710078,4.1025,4.1025,4.902500000000001,4.982500000000001,0.0,0.08000000000000007 +-571d8cVauQ/5,-571d8cVauQ,5,0,So,0.0625,0.14249999821186066,True,1.961745210721233e-10,4.0,0.061026267841565805,0.14039837035299824,0.0625,0.0625,0.14250000000000002,0.14250000000000002,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,1,very,0.5425000190734863,0.7225000262260437,True,5.542242012546161e-13,3.911118745803833,0.39099748158334563,0.7070536888457671,0.1825,0.5425,0.6825,0.7224999999999999,0.36,0.039999999999999925 +-571d8cVauQ/5,-571d8cVauQ,5,2,important,0.762499988079071,1.3025000095367432,True,1.289873698302746e-13,0.9102542400360107,0.7504742650006566,1.2691000312282303,0.7224999999999999,0.7625,1.2025,1.3425,0.040000000000000036,0.14000000000000012 +-571d8cVauQ/5,-571d8cVauQ,5,3,to,1.3424999713897705,1.402500033378601,True,6.078231137740422e-16,0.25,1.3274161608563455,1.3876820258440432,1.2825,1.4224999999999999,1.3425,1.4825,0.1399999999999999,0.1399999999999999 +-571d8cVauQ/5,-571d8cVauQ,5,4,go,1.4225000143051147,1.4824999570846558,True,5.364711279376433e-12,4.0,1.4430355265690127,1.512146626666273,1.4224999999999999,1.6025,1.4825,1.7425,0.18000000000000016,0.26 +-571d8cVauQ/5,-571d8cVauQ,5,5,out,1.6024999618530273,1.8025000095367432,True,9.859104635120963e-13,4.0,1.637724047396162,1.82970814525818,1.6025,1.9224999999999999,1.8025,2.0425,0.31999999999999984,0.24 +-571d8cVauQ/5,-571d8cVauQ,5,6,to,1.9225000143051147,2.002500057220459,True,1.4170477671045928e-13,1.0,1.9843274093437095,2.066520692378383,1.9224999999999999,2.4625,2.0025,2.5625,0.54,0.56 +-571d8cVauQ/5,-571d8cVauQ,5,7,the,2.4625000953674316,2.6424999237060547,True,4.532087053733813e-13,3.1982598304748535,2.464986666672805,2.648123686812614,2.4225,2.6225,2.5625,2.7225,0.20000000000000018,0.16000000000000014 +-571d8cVauQ/5,-571d8cVauQ,5,8,"locations,",2.742500066757202,3.382499933242798,True,2.9229296392117854e-13,2.0626895427703857,2.7477243046229103,3.379244935643703,2.7425,2.8025,3.3625,3.3825,0.06000000000000005,0.020000000000000018 +-571d8cVauQ/5,-571d8cVauQ,5,9,walk,3.4024999141693115,3.742500066757202,True,8.698149042223296e-16,0.25,3.405197916129465,3.7593203164399864,3.4025,3.4025,3.7225,4.022500000000001,0.0,0.3000000000000007 +-571d8cVauQ/5,-571d8cVauQ,5,10,"around,",3.762500047683716,4.082499980926514,True,4.603956444055625e-14,0.32489776611328125,3.7894646126851903,4.113669860878586,3.7625,4.1425,4.0825000000000005,4.482500000000001,0.3799999999999999,0.40000000000000036 +-571d8cVauQ/5,-571d8cVauQ,5,11,talk,4.142499923706055,4.442500114440918,True,1.35541764986237e-13,0.9565081000328064,4.190362867190777,4.484542398894459,4.1425,4.5025,4.442500000000001,4.9225,0.3600000000000003,0.47999999999999954 +-571d8cVauQ/5,-571d8cVauQ,5,12,with,4.502500057220459,4.922500133514404,True,8.38819099358186e-14,0.5919483304023743,4.541720300661576,4.940244070441893,4.5025,4.9625,4.9225,5.102500000000001,0.45999999999999996,0.1800000000000006 +-571d8cVauQ/5,-571d8cVauQ,5,13,the,5.002500057220459,5.102499961853027,True,2.0982386767193044e-14,0.25,5.018430928164901,5.1207677393025,5.0025,5.1625000000000005,5.102500000000001,5.2625,0.16000000000000014,0.15999999999999925 +-571d8cVauQ/5,-571d8cVauQ,5,14,owners,5.162499904632568,5.482500076293945,True,3.260156359284616e-13,2.3006680011749268,5.183334041083281,5.504277901364218,5.1625000000000005,5.3425,5.482500000000001,5.602500000000001,0.17999999999999972,0.1200000000000001 +-571d8cVauQ/5,-571d8cVauQ,5,15,if,5.502500057220459,5.5625,True,1.7678204942973808e-16,0.25,5.535479301056968,5.596502741603346,5.5025,5.6625000000000005,5.562500000000001,5.7225,0.16000000000000014,0.15999999999999925 +-571d8cVauQ/5,-571d8cVauQ,5,16,you,5.582499980926514,5.722499847412109,True,4.4787060209583104e-14,0.3160589337348938,5.624735476439397,5.761850848637931,5.5825000000000005,5.742500000000001,5.7225,5.862500000000001,0.16000000000000014,0.14000000000000057 +-571d8cVauQ/5,-571d8cVauQ,5,17,"can,",5.742499828338623,5.862500190734863,True,4.924350383299532e-14,0.3475077152252197,5.7829325715282085,5.904529793030309,5.742500000000001,5.8825,5.862500000000001,6.0825000000000005,0.13999999999999968,0.21999999999999975 +-571d8cVauQ/5,-571d8cVauQ,5,18,tell,5.882500171661377,6.142499923706055,True,2.1348444930249788e-13,1.506543755531311,5.9288363923069145,6.188435906968508,5.8825,6.1625000000000005,6.142500000000001,6.5025,0.28000000000000025,0.35999999999999943 +-571d8cVauQ/5,-571d8cVauQ,5,19,them,6.482500076293945,6.682499885559082,True,1.303422159700668e-13,0.9198152422904968,6.374882165415015,6.68920056196025,6.1625000000000005,6.562500000000001,6.642500000000001,6.742500000000001,0.40000000000000036,0.09999999999999964 +-571d8cVauQ/5,-571d8cVauQ,5,20,what,6.722499847412109,6.882500171661377,True,4.340288640102517e-14,0.3062909245491028,6.74280020146315,6.90711834793619,6.6625000000000005,6.782500000000001,6.822500000000001,6.942500000000001,0.1200000000000001,0.1200000000000001 +-571d8cVauQ/5,-571d8cVauQ,5,21,you're,6.922500133514404,7.162499904632568,True,6.8854756965497366e-12,4.0,6.949658840062754,7.201229129569963,6.862500000000001,6.982500000000001,7.1625000000000005,7.1625000000000005,0.1200000000000001,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,22,"doing,",7.182499885559082,7.422500133514404,True,2.756355798987087e-13,1.9451396465301514,7.2233293105612,7.466068313841497,7.1825,7.1825,7.4225,7.4225,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,23,build,7.682499885559082,7.902500152587891,True,4.2132330203880144e-14,0.29732468724250793,7.713083083513668,7.964945886320176,7.642500000000001,7.6825,7.902500000000001,7.9625,0.03999999999999915,0.05999999999999961 +-571d8cVauQ/5,-571d8cVauQ,5,24,a,7.942500114440918,7.962500095367432,True,3.905624535263143e-14,0.27561700344085693,8.004457849233917,8.024457849233954,7.942500000000001,7.982500000000001,7.9625,8.0025,0.040000000000000036,0.03999999999999915 +-571d8cVauQ/5,-571d8cVauQ,5,25,little,7.982500076293945,8.262499809265137,True,3.241799393489085e-14,0.25,8.047286338490512,8.319486249797016,7.982500000000001,8.0425,8.2625,8.3025,0.05999999999999961,0.040000000000000924 +-571d8cVauQ/5,-571d8cVauQ,5,26,"excitement,",8.282500267028809,8.862500190734863,True,3.179512656306151e-14,0.25,8.340643589235283,8.907759359152092,8.282499999999999,8.3425,8.8225,8.862499999999999,0.0600000000000005,0.03999999999999915 +-571d8cVauQ/5,-571d8cVauQ,5,27,put,9.422499656677246,9.522500038146973,True,7.793622653707102e-14,0.5499901175498962,9.448525366526367,9.558693789160388,9.4225,9.4225,9.522499999999999,9.522499999999999,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,28,a,9.5625,9.582500457763672,True,9.874617399804886e-13,4.0,9.599558257830385,9.619558257830356,9.5625,9.5825,9.5825,9.6025,0.019999999999999574,0.019999999999999574 +-571d8cVauQ/5,-571d8cVauQ,5,29,little,9.6225004196167,9.882499694824219,True,8.713415053504189e-14,0.6148991584777832,9.657902881779448,9.933980702020806,9.6225,9.6225,9.8825,9.8825,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,30,glitz,9.982500076293945,10.182499885559082,True,2.0400179809310082e-11,4.0,9.989943619156207,10.19563550900826,9.9225,9.9825,10.1225,10.1825,0.0600000000000005,0.05999999999999872 +-571d8cVauQ/5,-571d8cVauQ,5,31,on,10.282500267028809,10.382499694824219,True,1.639427634446411e-12,4.0,10.275149544087014,10.392708390362388,10.1625,10.282499999999999,10.3025,10.3825,0.11999999999999922,0.08000000000000007 +-571d8cVauQ/5,-571d8cVauQ,5,32,there,10.422499656677246,10.6225004196167,True,4.004103296216359e-14,0.2825665771961212,10.454077564626562,10.673171811912887,10.362499999999999,10.4225,10.6225,10.6225,0.0600000000000005,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,33,and,10.642499923706055,11.322500228881836,True,8.731728447924914e-13,4.0,10.912128782316048,11.369185804372504,10.6425,11.2625,11.3225,11.362499999999999,0.6199999999999992,0.03999999999999915 +-571d8cVauQ/5,-571d8cVauQ,5,34,let,11.542499542236328,11.662500381469727,True,4.009867524829014e-14,0.28297334909439087,11.569560975686585,11.698227520663279,11.5425,11.5425,11.6625,11.6625,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,35,everybody,11.702500343322754,12.082500457763672,True,9.238042188858264e-13,4.0,11.740536622390566,12.121806518011748,11.7025,11.7025,12.0825,12.0825,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,36,knows,12.102499961853027,12.302499771118164,True,9.206563734032863e-14,0.6497002840042114,12.144266740138423,12.349209984328715,12.1025,12.1025,12.3025,12.3225,0.0,0.019999999999999574 +-571d8cVauQ/5,-571d8cVauQ,5,37,this,12.762499809265137,12.942500114440918,True,3.215953165661839e-13,2.2694740295410156,12.73313275369772,12.95957414691892,12.3225,12.7625,12.8825,12.942499999999999,0.4399999999999995,0.05999999999999872 +-571d8cVauQ/5,-571d8cVauQ,5,38,is,12.982500076293945,13.042499542236328,True,4.4049882014576824e-13,3.108567237854004,13.019727126882461,13.080592199899773,12.9825,12.9825,13.0425,13.0425,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,39,a,13.162500381469727,13.182499885559082,True,3.718831232540909e-12,4.0,13.198762296608688,13.218762296608658,13.1625,13.1625,13.1825,13.1825,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,40,very,13.322500228881836,13.542499542236328,True,1.494705916113212e-13,1.0548027753829956,13.35522890003284,13.57665212442405,13.3225,13.3225,13.5425,13.5425,0.0,0.0 +-571d8cVauQ/5,-571d8cVauQ,5,41,valuable,13.682499885559082,14.442500114440918,True,9.463182190985742e-13,4.0,13.714516252757837,14.474684869756821,13.6825,13.6825,14.442499999999999,14.5025,0.0,0.0600000000000005 +-571d8cVauQ/5,-571d8cVauQ,5,42,spot.,14.662500381469727,14.962499618530273,True,1.3657936543884364e-12,4.0,14.673377195931495,14.96784942174552,14.6625,14.6625,14.9025,15.0425,0.0,0.14000000000000057 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,0,In,0.16249999403953552,0.24250000715255737,True,8.721677351684887e-13,4.0,0.1142069655201318,0.21499044195057157,0.0625,0.1625,0.1825,0.2425,0.1,0.06 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,1,the,0.8224999904632568,0.9624999761581421,True,4.6919015032767866e-14,0.4219171106815338,0.779575729691009,0.9513972402826147,0.28250000000000003,0.8424999999999999,0.8624999999999999,0.9624999999999999,0.5599999999999998,0.09999999999999998 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,2,United,1.0225000381469727,1.2825000286102295,True,1.241436966246956e-13,1.116356611251831,1.022454650069054,1.2824630944967872,1.0225,1.0225,1.2825,1.2825,0.0,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,3,States,1.3025000095367432,1.5824999809265137,True,2.2734993226268757e-15,0.25,1.3219094885294929,1.6019038732024349,1.3025,1.3425,1.5825,1.6225,0.040000000000000036,0.040000000000000036 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,4,we,1.6425000429153442,1.7424999475479126,True,5.195034398323972e-13,4.0,1.6425025929936214,1.7425022697843806,1.6425,1.6425,1.7425,1.7425,0.0,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,5,don't,1.8624999523162842,2.0824999809265137,True,3.625834965603758e-09,4.0,1.8625138297841282,2.0820620731977453,1.8625,1.8625,2.0825,2.0825,0.0,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,6,punish,2.202500104904175,2.502500057220459,True,9.826499016611992e-14,0.8836435079574585,2.2024907371313374,2.5025001246537304,2.2025,2.2025,2.5025,2.5025,0.0,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,7,failure,2.5625,3.0824999809265137,True,3.813583563522238e-14,0.342934787273407,2.57581736001806,3.080994991799556,2.5625,2.6425,3.0825,3.0825,0.08000000000000007,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,8,to,3.5225000381469727,3.622499942779541,True,3.0746702384641666e-13,2.764883279800415,3.52221470372663,3.622506415239828,3.5225,3.5225,3.6225,3.6225,0.0,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,9,the,3.682499885559082,3.7825000286102295,True,3.3432115989452324e-14,0.30063679814338684,3.6824927941693253,3.782492797896148,3.6825,3.6825,3.7825,3.7825,0.0,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,10,degree,3.802500009536743,4.162499904632568,True,6.262374109946081e-14,0.5631411671638489,3.802499999654366,4.162501191750939,3.8025,3.8025,4.1625000000000005,4.1625000000000005,0.0,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,11,to,4.302499771118164,4.362500190734863,True,8.0105626992788e-13,4.0,4.291511506534855,4.352642714953695,4.2625,4.3025,4.322500000000001,4.362500000000001,0.040000000000000036,0.040000000000000036 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,12,which,4.422500133514404,4.662499904632568,True,2.4741273347552925e-14,0.25,4.405226899791058,4.654286753863474,4.3425,4.4225,4.6225000000000005,4.6625000000000005,0.08000000000000007,0.040000000000000036 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,13,failure,4.742499828338623,5.28249979019165,True,2.8274669931771523e-13,2.5425868034362793,4.739944443800792,5.282521785832095,4.7225,4.742500000000001,5.282500000000001,5.282500000000001,0.020000000000000462,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,14,is,5.34250020980835,5.402500152587891,True,4.104637975539151e-14,0.369107723236084,5.34226851016023,5.4052279359374715,5.3425,5.3425,5.402500000000001,5.442500000000001,0.0,0.040000000000000036 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,15,punished,5.502500057220459,5.902500152587891,True,7.313151684706573e-14,0.6576318740844727,5.500985614179578,5.901454375232485,5.5025,5.5025,5.902500000000001,5.902500000000001,0.0,0.0 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,16,in,6.302499771118164,6.422500133514404,True,2.6584829715230185e-13,2.3906288146972656,6.284817034685479,6.406331516286906,6.1625000000000005,6.322500000000001,6.322500000000001,6.4225,0.16000000000000014,0.09999999999999964 +-I_e4mIh0yE/1,-I_e4mIh0yE,1,17,Europe.,6.662499904632568,6.922500133514404,True,5.098422226935961e-13,4.0,6.656895370927335,6.922440434999503,6.642500000000001,6.6625000000000005,6.9225,6.9225,0.019999999999999574,0.0 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,0,It's,0.5824999809265137,0.7225000262260437,True,3.472087617417685e-10,4.0,0.5822805233935374,0.7211801408748947,0.5824999999999999,0.5824999999999999,0.7025,0.7224999999999999,0.0,0.019999999999999907 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,1,perceived,0.9225000143051147,1.4824999570846558,True,1.4726222086376695e-13,0.25,0.8894760335439114,1.4662801504889216,0.7224999999999999,0.9225,1.4425,1.4825,0.20000000000000007,0.040000000000000036 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,2,that,1.5425000190734863,1.7424999475479126,True,2.1773252959714912e-14,0.25,1.5118009805496575,1.7076001797166942,1.4625,1.5425,1.6625,1.7425,0.08000000000000007,0.07999999999999985 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,3,you,1.7625000476837158,1.8624999523162842,True,4.304102037343098e-14,0.25,1.7445763600944204,1.8591816436803994,1.7225,1.7625,1.8225,1.8825,0.040000000000000036,0.06000000000000005 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,4,have,1.9225000143051147,2.1424999237060547,True,3.9425008396820616e-12,4.0,1.923373173881217,2.165102454180477,1.9224999999999999,1.9224999999999999,2.1425,2.1825,0.0,0.040000000000000036 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,5,actually,2.1624999046325684,2.6424999237060547,True,4.010823791145146e-12,4.0,2.1990408804792785,2.68428186359062,2.1625,2.2225,2.6425,2.8025,0.06000000000000005,0.16000000000000014 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,6,learned,2.7825000286102295,3.122499942779541,True,4.510655087289206e-13,0.5370558500289917,2.781821592938269,3.1219551838308943,2.6625,2.8425,3.0025,3.1625,0.17999999999999972,0.16000000000000014 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,7,"something,",3.2225000858306885,3.702500104904175,True,1.2301406638118295e-12,1.4646525382995605,3.210776660611705,3.685039851830411,3.0625,3.2225,3.4425,3.7025,0.16000000000000014,0.26000000000000023 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,8,over,3.762500047683716,3.9625000953674316,True,6.062504827580167e-14,0.25,3.7497129407356837,3.9509308917543975,3.5025,3.8225000000000002,3.7025,4.0425,0.3200000000000003,0.3400000000000003 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,9,the,3.9825000762939453,4.082499980926514,True,7.674462736313725e-14,0.25,3.988517118629397,4.105443941306858,3.8225000000000002,4.1225000000000005,4.0425,4.362500000000001,0.30000000000000027,0.3200000000000003 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,10,course,4.262499809265137,4.542500019073486,True,1.2368673793505813e-12,1.4726616144180298,4.274087408439977,4.559334574473354,4.2625,4.3825,4.5425,4.6825,0.1200000000000001,0.13999999999999968 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,11,of,4.622499942779541,4.682499885559082,True,4.1304034303045467e-13,0.491781622171402,4.680345626946339,4.744915525012013,4.6225000000000005,5.1625000000000005,4.6825,5.2625,0.54,0.5800000000000001 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,12,your,5.242499828338623,5.5625,True,1.1803501752394308e-11,4.0,5.248953696227165,5.565865409986523,5.1625000000000005,5.4625,5.562500000000001,5.6225000000000005,0.2999999999999998,0.05999999999999961 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,13,"carreer,",5.682499885559082,6.022500038146973,True,5.404035292172482e-12,4.0,5.67524877133456,6.022628998062419,5.6625000000000005,5.6825,6.022500000000001,6.022500000000001,0.019999999999999574,0.0 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,14,and,6.042500019073486,6.162499904632568,True,1.5327623068342455e-12,1.824965476989746,6.051594198076872,6.163218343693183,6.0425,6.062500000000001,6.1625000000000005,6.1625000000000005,0.020000000000000462,0.0 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,15,that,6.222499847412109,6.362500190734863,True,8.04463049994264e-13,0.9578244686126709,6.223196086715864,6.366824761858561,6.2225,6.2225,6.362500000000001,6.362500000000001,0.0,0.0 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,16,you,6.482500076293945,6.742499828338623,True,8.753082893914188e-13,1.042175531387329,6.485121347497934,6.727387463759083,6.482500000000001,6.482500000000001,6.602500000000001,6.782500000000001,0.0,0.17999999999999972 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,17,won't,6.902500152587891,7.0625,True,6.68682470505999e-11,4.0,6.850043955382938,7.036261507491488,6.7225,6.902500000000001,7.0025,7.0825000000000005,0.1800000000000006,0.08000000000000007 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,18,make,7.082499980926514,7.462500095367432,True,4.19843760451899e-12,4.0,7.142215541761871,7.4625317001592855,7.0825000000000005,7.202500000000001,7.4625,7.4625,0.1200000000000001,0.0 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,19,the,7.702499866485596,7.942500114440918,True,2.8825946078898934e-13,0.34321272373199463,7.711799725224728,7.948721670810593,7.702500000000001,7.7225,7.942500000000001,7.9625,0.019999999999999574,0.019999999999999574 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,20,mistake,8.0024995803833,8.422499656677246,True,2.3740891522648633e-13,0.2826681435108185,8.001170899583583,8.421542106933641,8.0025,8.0025,8.4225,8.4225,0.0,0.0 +-I_e4mIh0yE/3,-I_e4mIh0yE,3,21,twice.,8.662500381469727,8.962499618530273,True,1.2501067889192363e-14,0.25,8.587039530663365,8.962645923111332,8.4825,8.6825,8.9625,8.9625,0.1999999999999993,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,0,"Because,",0.02250000089406967,0.36250001192092896,True,1.475930685448327e-14,0.25,0.022500000004257795,0.3625472694174722,0.0225,0.0225,0.3625,0.3625,0.0,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,1,if,0.4025000035762787,0.4625000059604645,True,2.200777673164525e-13,1.5552595853805542,0.4026353313760795,0.46269966085687303,0.4025,0.4025,0.4625,0.4625,0.0,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,2,they,0.5224999785423279,0.7825000286102295,True,1.5841776675185049e-13,1.1195167303085327,0.5250717282237793,0.7824865774462136,0.5225,0.5625,0.7825,0.7825,0.040000000000000036,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,3,are,1.0225000381469727,1.162500023841858,True,2.8222001084298072e-14,0.25,0.9993191173234123,1.1572935816657954,0.9425,1.0225,1.1225,1.2425,0.07999999999999996,0.11999999999999988 +-UacrmKiTn4/10,-UacrmKiTn4,10,4,not,1.1825000047683716,1.3025000095367432,True,1.917614504687304e-12,4.0,1.212195552950287,1.3411265228208296,1.1824999999999999,1.3825,1.3025,1.6225,0.20000000000000018,0.32000000000000006 +-UacrmKiTn4/10,-UacrmKiTn4,10,5,in,1.5225000381469727,1.622499942779541,True,3.806191202059689e-13,2.6897835731506348,1.5472873413699313,1.6685377212106935,1.5225,1.7025,1.6225,2.2225,0.17999999999999994,0.6000000000000001 +-UacrmKiTn4/10,-UacrmKiTn4,10,6,any,2.442500114440918,2.5625,True,4.2097759739984086e-13,2.9749913215637207,2.4295782593879096,2.562499437343288,2.2025,2.4425,2.5625,2.5625,0.23999999999999977,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,7,way,2.6424999237060547,2.7825000286102295,True,1.2459322039793524e-13,0.8804833292961121,2.642499960569166,2.782499959619364,2.6425,2.6425,2.7825,2.7825,0.0,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,8,held,2.882499933242798,3.0625,True,1.871778990483741e-12,4.0,2.882499663382942,3.06249970189482,2.8825,2.8825,3.0625,3.0625,0.0,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,9,accountable,3.1024999618530273,3.8424999713897705,True,2.4792566274706856e-14,0.25,3.1034985154384263,3.843995047957288,3.1025,3.1025,3.8425,3.8625,0.0,0.020000000000000018 +-UacrmKiTn4/10,-UacrmKiTn4,10,10,for,3.9625000953674316,4.142499923706055,True,8.828910909655652e-13,4.0,3.9618912743665837,4.1422515787201855,3.9625,3.9625,4.1425,4.1425,0.0,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,11,reading,4.202499866485596,4.522500038146973,True,5.040660204231988e-14,0.35621657967567444,4.217612209195304,4.533819065539573,4.202500000000001,4.282500000000001,4.522500000000001,4.5825000000000005,0.08000000000000007,0.05999999999999961 +-UacrmKiTn4/10,-UacrmKiTn4,10,12,the,4.602499961853027,4.702499866485596,True,4.6737817744691226e-14,0.3302897810935974,4.602499650444098,4.702499657454214,4.602500000000001,4.602500000000001,4.702500000000001,4.702500000000001,0.0,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,13,material,4.722499847412109,5.322500228881836,True,2.7899259508537555e-14,0.25,4.722500025503899,5.3163663313084415,4.7225,4.7225,5.2625,5.322500000000001,0.0,0.0600000000000005 +-UacrmKiTn4/10,-UacrmKiTn4,10,14,they,5.34250020980835,6.122499942779541,True,1.6694450184241705e-14,0.25,5.346698826778056,6.105480164175808,5.3425,5.3425,6.062500000000001,6.1225000000000005,0.0,0.05999999999999961 +-UacrmKiTn4/10,-UacrmKiTn4,10,15,won't,6.142499923706055,6.302499771118164,True,6.240683664282543e-11,4.0,6.1425008497064475,6.309788862779577,6.142500000000001,6.142500000000001,6.3025,6.3425,0.0,0.040000000000000036 +-UacrmKiTn4/10,-UacrmKiTn4,10,16,do,6.402500152587891,6.502500057220459,True,8.948922874431331e-13,4.0,6.4025000340549125,6.502500042623035,6.402500000000001,6.402500000000001,6.5025,6.5025,0.0,0.0 +-UacrmKiTn4/10,-UacrmKiTn4,10,17,it.,6.622499942779541,6.682499885559082,True,2.6122733262547854e-14,0.25,6.623106947941723,6.688042407993376,6.6225000000000005,6.6225000000000005,6.6825,6.702500000000001,0.0,0.020000000000000462 +-UacrmKiTn4/4,-UacrmKiTn4,4,0,Just,0.0024999999441206455,0.6424999833106995,True,4.562072507957593e-12,4.0,0.004947655251735573,0.6504811942238563,0.0025000000000000005,0.0225,0.6425,0.7025,0.019999999999999997,0.06000000000000005 +-UacrmKiTn4/4,-UacrmKiTn4,4,1,given,0.762499988079071,1.002500057220459,True,6.256041691632408e-14,1.8532153367996216,0.7364139253098347,0.9636047049601082,0.6825,0.7625,0.8825,1.0025,0.07999999999999996,0.12 +-UacrmKiTn4/4,-UacrmKiTn4,4,2,to,1.0225000381469727,1.0824999809265137,True,1.5428832189179169e-15,0.25,1.0025937583992537,1.0639978885987913,0.9425,1.0225,1.0025,1.0825,0.07999999999999996,0.08000000000000007 +-UacrmKiTn4/4,-UacrmKiTn4,4,3,their,1.1024999618530273,1.3224999904632568,True,2.0475887269816778e-16,0.25,1.0908284753739195,1.3135099105503243,1.0225,1.1025,1.2225,1.3225,0.08000000000000007,0.10000000000000009 +-UacrmKiTn4/4,-UacrmKiTn4,4,4,own,1.3825000524520874,1.502500057220459,True,1.73095121474621e-15,0.25,1.37705306367968,1.4988073905995172,1.3225,1.3825,1.4625,1.5025,0.06000000000000005,0.040000000000000036 +-UacrmKiTn4/4,-UacrmKiTn4,4,5,devices,1.5425000190734863,2.122499942779541,True,4.961841416797723e-14,1.4698368310928345,1.5408861101749405,2.117455888833504,1.5425,1.5425,2.0825,2.1225,0.0,0.040000000000000036 +-UacrmKiTn4/4,-UacrmKiTn4,4,6,they,2.202500104904175,2.3424999713897705,True,6.740486261595097e-14,1.9967213869094849,2.2006234143728935,2.341308883214659,2.2025,2.2025,2.3425,2.3425,0.0,0.0 +-UacrmKiTn4/4,-UacrmKiTn4,4,7,are,2.362499952316284,2.4825000762939453,True,3.205953569025005e-13,4.0,2.3615948075228883,2.481585319634036,2.3625,2.3625,2.4825,2.4825,0.0,0.0 +-UacrmKiTn4/4,-UacrmKiTn4,4,8,not,2.5225000381469727,2.682499885559082,True,5.5410154410759013e-14,1.6414045095443726,2.52250550991515,2.6825054463052336,2.5225,2.5225,2.6825,2.6825,0.0,0.0 +-UacrmKiTn4/4,-UacrmKiTn4,4,9,going,2.762500047683716,3.0425000190734863,True,1.7897125160993774e-14,0.5301631689071655,2.743302852447095,3.0226983210219336,2.7225,2.7625,3.0025,3.0425,0.040000000000000036,0.040000000000000036 +-UacrmKiTn4/4,-UacrmKiTn4,4,10,to,3.0824999809265137,3.1424999237060547,True,4.2949559449852355e-15,0.25,3.0824999856606508,3.1425000044551568,3.0825,3.0825,3.1425,3.1425,0.0,0.0 +-UacrmKiTn4/4,-UacrmKiTn4,4,11,read,3.2225000858306885,3.422499895095825,True,3.4303006890215463e-15,0.25,3.222702148003313,3.418441830412285,3.2225,3.2425,3.3825,3.4225,0.020000000000000018,0.040000000000000036 +-UacrmKiTn4/4,-UacrmKiTn4,4,12,the,3.442500114440918,3.5425000190734863,True,1.6336893860283141e-15,0.25,3.4691372489699823,3.5816860218914264,3.4425,3.6625,3.5425,3.8225000000000002,0.2200000000000002,0.28000000000000025 +-UacrmKiTn4/4,-UacrmKiTn4,4,13,textbook.,3.6624999046325684,4.142499923706055,True,1.503377094038208e-13,4.0,3.647318800103063,4.282380916193305,3.5625,3.9025,4.0825000000000005,4.6625000000000005,0.33999999999999986,0.5800000000000001 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,0,Picture,0.16249999403953552,0.6424999833106995,True,2.388505246451317e-13,1.0,0.16093215462874963,0.6492774175568524,0.1625,0.1625,0.6425,0.7025,0.0,0.06000000000000005 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,1,"this,",0.6825000047683716,1.002500057220459,True,1.7479208185011696e-12,4.0,0.6967693237113916,1.0043499540624952,0.6825,0.7424999999999999,1.0025,1.0025,0.05999999999999994,0.0 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,2,before,1.2625000476837158,1.8825000524520874,True,3.712301462326789e-14,0.25,1.2568305382584097,1.8793181771780305,1.1624999999999999,1.2625,1.8225,1.8825,0.10000000000000009,0.06000000000000005 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,3,we,1.9824999570846558,2.122499942779541,True,3.7951361346079404e-13,1.5889167785644531,1.9788165575745025,2.1177397110667036,1.9825,1.9825,2.1225,2.1225,0.0,0.0 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,4,actually,2.2225000858306885,3.682499885559082,True,2.084581151359094e-13,0.8727555274963379,2.217809149643507,3.6792332685589186,2.2225,2.2225,3.6225,3.6825,0.0,0.06000000000000005 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,5,start,3.742500066757202,4.082499980926514,True,1.9712341568084435e-12,4.0,3.7424998928545663,4.082502830606967,3.7425,3.7425,4.0825000000000005,4.0825000000000005,0.0,0.0 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,6,"hacking,",4.222499847412109,4.702499866485596,True,2.2997982980347588e-14,0.25,4.221812245247405,4.727831407783964,4.2225,4.242500000000001,4.702500000000001,4.782500000000001,0.020000000000000462,0.08000000000000007 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,7,we’re,4.922500133514404,5.142499923706055,True,1.77046884097809e-11,4.0,4.920433348583369,5.142277923757999,4.9225,4.9225,5.1425,5.1425,0.0,0.0 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,8,in,5.182499885559082,5.242499828338623,True,3.179557853984216e-13,1.3311915397644043,5.182457696430692,5.242471813790377,5.1825,5.1825,5.242500000000001,5.242500000000001,0.0,0.0 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,9,a,5.28249979019165,5.302499771118164,True,5.193478754553704e-15,0.25,5.284921857502635,5.3049218575026345,5.282500000000001,5.3025,5.3025,5.322500000000001,0.019999999999999574,0.020000000000000462 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,10,room,5.34250020980835,5.502500057220459,True,4.2035475374493404e-15,0.25,5.342924994112858,5.502498287036115,5.3425,5.3425,5.5025,5.5025,0.0,0.0 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,11,formal,5.522500038146973,5.902500152587891,True,1.3692799877892264e-13,0.5732790231704712,5.522499935669881,5.902497519672031,5.522500000000001,5.522500000000001,5.902500000000001,5.902500000000001,0.0,0.0 +-hnBHBN8p5A/7,-hnBHBN8p5A,7,12,setting,6.882500171661377,7.242499828338623,True,5.154608294019591e-13,2.1580896377563477,6.876668294203695,7.242903312234083,6.8425,6.8825,7.242500000000001,7.242500000000001,0.040000000000000036,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,0,"Discussion,",0.20250000059604645,0.6025000214576721,True,7.413789807928048e-16,0.25,0.05734253021101946,0.6025331203999742,0.0025000000000000005,0.1825,0.6024999999999999,0.6024999999999999,0.18,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,1,how,0.6424999833106995,0.7825000286102295,True,1.488793626141377e-13,0.9633798003196716,0.6425435974958801,0.7825102245774119,0.6425,0.6425,0.7825,0.7825,0.0,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,2,to,0.862500011920929,0.9424999952316284,True,4.985656256329546e-14,0.3226155936717987,0.8625061466012319,0.9433688622350123,0.8624999999999999,0.8624999999999999,0.9425,0.9425,0.0,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,3,discuss,1.002500057220459,1.2825000286102295,True,5.747768390797561e-14,0.37193092703819275,1.002478560527885,1.282636894103437,1.0025,1.0025,1.2825,1.2825,0.0,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,4,ideas,1.3224999904632568,1.7424999475479126,True,7.848715709475595e-13,4.0,1.3870056407994262,1.7424735743902229,1.3225,1.4825,1.7425,1.7425,0.15999999999999992,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,5,and,1.7625000476837158,1.8624999523162842,True,1.503318303175405e-11,4.0,1.7624947007218714,1.8624953633132175,1.7625,1.7625,1.8625,1.8625,0.0,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,6,opinions,1.8825000524520874,2.2225000858306885,True,2.2395399337099553e-12,4.0,1.88249543276377,2.223362908527545,1.8825,1.8825,2.2225,2.2225,0.0,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,7,more,3.8424999713897705,3.9825000762939453,True,2.2274653909554187e-12,4.0,3.813089593624601,3.975339622828584,3.7625,3.8625,3.9225,4.0025,0.09999999999999964,0.08000000000000052 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,8,effectively,4.002500057220459,4.582499980926514,True,1.0292728990076924e-13,0.6660296320915222,4.001976607641939,4.579303253022034,3.9425,4.0425,4.5425,4.5825000000000005,0.10000000000000053,0.040000000000000036 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,9,than,4.602499961853027,4.942500114440918,True,1.545385997989146e-13,1.0,4.602805718995574,4.942454042242472,4.602500000000001,4.602500000000001,4.942500000000001,4.942500000000001,0.0,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,10,a,4.982500076293945,5.002500057220459,True,1.1543436345684555e-11,4.0,4.973083161483878,4.993083161483986,4.9625,4.982500000000001,4.982500000000001,5.0025,0.020000000000000462,0.019999999999999574 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,11,native,5.022500038146973,5.982500076293945,True,2.7570120123519837e-13,1.7840280532836914,5.023246868555434,5.982429087559479,5.022500000000001,5.022500000000001,5.982500000000001,5.982500000000001,0.0,0.0 +-hnBHBN8p5A/6,-hnBHBN8p5A,6,12,speaker,6.002500057220459,6.322500228881836,True,1.1699105226248285e-13,0.7570344805717468,6.0024817013264,6.318882058754529,6.0025,6.0025,6.3025,6.322500000000001,0.0,0.020000000000000462 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,0,We,0.0024999999441206455,0.0625,True,9.337668442285785e-13,0.4947294592857361,0.004150950202978793,0.06513475794367299,0.0025000000000000005,0.0225,0.0625,0.0825,0.019999999999999997,0.020000000000000004 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,1,always,0.10249999910593033,0.4025000035762787,True,2.7101797368811464e-12,1.435910701751709,0.10268331893228248,0.4027179907882608,0.10250000000000001,0.10250000000000001,0.4025,0.4025,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,2,love,0.48249998688697815,0.6625000238418579,True,1.558735508288417e-13,0.25,0.4821765173364106,0.6623160427138763,0.4825,0.4825,0.6625,0.6625,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,3,to,0.7225000262260437,0.8025000095367432,True,6.635134065444137e-13,0.35154345631599426,0.7222857214492022,0.8027704858444851,0.7224999999999999,0.7224999999999999,0.8025,0.8025,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,4,hear,0.9825000166893005,1.1425000429153442,True,5.576355783382114e-12,2.9544713497161865,0.9824963006452994,1.1424985239327123,0.9824999999999999,0.9824999999999999,1.1425,1.1425,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,5,what,1.222499966621399,1.402500033378601,True,6.127329275473076e-14,0.25,1.2225943761411022,1.4025803637052279,1.2225,1.2225,1.4025,1.4025,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,6,you,1.462499976158142,1.5625,True,1.2773379664372201e-14,0.25,1.4508682284819499,1.5565077680365997,1.4224999999999999,1.4625,1.5225,1.5625,0.040000000000000036,0.040000000000000036 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,7,"say,",1.5824999809265137,1.7424999475479126,True,2.74772760967823e-12,1.4558043479919434,1.5837011690674971,1.7213764295415506,1.5825,1.5825,1.6824999999999999,1.7625,0.0,0.08000000000000007 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,8,and,1.902500033378601,2.122499942779541,True,2.0415532112072476e-11,4.0,1.9027662090732207,2.123002766118228,1.9025,1.9025,2.1225,2.1225,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,9,like,2.202500104904175,2.702500104904175,True,1.0162235636324013e-12,0.5384168028831482,2.2032672035614334,2.67955362682512,2.2025,2.2025,2.6625,2.7025,0.0,0.040000000000000036 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,10,and,2.742500066757202,2.882499933242798,True,3.416096572284033e-11,4.0,2.7427614638556794,2.8827771318550117,2.7425,2.7425,2.8825,2.8825,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,11,share,2.942500114440918,3.242500066757202,True,1.1194105538347987e-11,4.0,2.9573490079626183,3.2448006952303574,2.9425,3.0225,3.2425,3.2625,0.08000000000000007,0.020000000000000018 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,12,this,3.322499990463257,3.5625,True,1.1903970864590718e-11,4.0,3.3267286352579317,3.5372195818299765,3.3225000000000002,3.3425,3.4825,3.5625,0.019999999999999574,0.08000000000000007 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,13,video,3.6024999618530273,3.9024999141693115,True,7.060332787162116e-12,3.7407138347625732,3.601699909740036,3.9012860766225366,3.6025,3.6025,3.9025,3.9025,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,14,as,3.922499895095825,4.002500057220459,True,1.0646788355453407e-12,0.5640894174575806,3.9230020734809483,4.002898737678011,3.9225,3.9225,4.0025,4.0025,0.0,0.0 +-qDkUB0GgYY/6,-qDkUB0GgYY,6,15,well.,4.042500019073486,4.522500038146973,True,7.8364842826667e-13,0.4151935279369354,4.1010353264747215,4.535698864584865,4.0425,4.4225,4.522500000000001,4.602500000000001,0.3799999999999999,0.08000000000000007 +-uywlfIYOS8/4,-uywlfIYOS8,4,0,And,0.02250000089406967,0.16249999403953552,True,5.988297357983896e-11,4.0,0.022602156621392876,0.1630419189656043,0.0225,0.0225,0.1625,0.1625,0.0,0.0 +-uywlfIYOS8/4,-uywlfIYOS8,4,1,then,0.42250001430511475,0.6625000238418579,True,1.9874759390331453e-12,4.0,0.4046817558066659,0.6583254135084216,0.3825,0.4225,0.6224999999999999,0.6625,0.03999999999999998,0.040000000000000036 +-uywlfIYOS8/4,-uywlfIYOS8,4,2,from,0.8224999904632568,0.9825000166893005,True,1.0401202468757198e-12,4.0,0.8134819794270989,0.9735283961462557,0.7625,0.8225,0.9225,0.9824999999999999,0.06000000000000005,0.05999999999999994 +-uywlfIYOS8/4,-uywlfIYOS8,4,3,a,1.0824999809265137,1.1024999618530273,True,6.67349883036808e-14,0.5558029413223267,1.0652153145723244,1.0852153145723227,0.9624999999999999,1.0825,0.9824999999999999,1.1025,0.1200000000000001,0.1200000000000001 +-uywlfIYOS8/4,-uywlfIYOS8,4,4,brand,1.2024999856948853,1.4424999952316284,True,1.370544624920136e-14,0.25,1.1838669782022566,1.4434563674323948,1.0825,1.2025,1.4425,1.4425,0.11999999999999988,0.0 +-uywlfIYOS8/4,-uywlfIYOS8,4,5,point,1.5824999809265137,1.9824999570846558,True,1.667973620550836e-13,1.3891733884811401,1.6264036729392484,2.021516023502526,1.5825,1.7625,1.9825,2.2025,0.17999999999999994,0.2200000000000002 +-uywlfIYOS8/4,-uywlfIYOS8,4,6,of,2.122499942779541,2.202500104904175,True,3.508121744488779e-12,4.0,2.1405318506933226,2.2203001571442478,2.1225,2.2425,2.2025,2.3025,0.1200000000000001,0.10000000000000009 +-uywlfIYOS8/4,-uywlfIYOS8,4,7,"view,",2.382499933242798,2.5425000190734863,True,3.820997066927151e-13,3.1823208332061768,2.382480809329932,2.54428426955582,2.3825,2.3825,2.5425,2.5625,0.0,0.020000000000000018 +-uywlfIYOS8/4,-uywlfIYOS8,4,8,we,2.6424999237060547,2.7225000858306885,True,4.428764280761839e-14,0.3688500225543976,2.642474815240312,2.722478205982455,2.6425,2.6425,2.7225,2.7225,0.0,0.0 +-uywlfIYOS8/4,-uywlfIYOS8,4,9,need,2.822499990463257,3.002500057220459,True,7.078356862233112e-14,0.589521586894989,2.8015348641925786,2.9936915393927097,2.7825,2.8225,2.9625,3.0025,0.03999999999999959,0.040000000000000036 +-uywlfIYOS8/4,-uywlfIYOS8,4,10,to,3.0824999809265137,3.1424999237060547,True,1.7816755286826497e-14,0.25,3.082466476739016,3.142468401478628,3.0825,3.0825,3.1425,3.1425,0.0,0.0 +-uywlfIYOS8/4,-uywlfIYOS8,4,11,make,3.202500104904175,3.362499952316284,True,7.334166233314773e-14,0.6108267307281494,3.182153732642052,3.342160432953954,3.1625,3.2025,3.3225000000000002,3.3625,0.040000000000000036,0.03999999999999959 +-uywlfIYOS8/4,-uywlfIYOS8,4,12,sure,3.442500114440918,3.6024999618530273,True,5.5085622207348e-14,0.45878109335899353,3.43999834296272,3.5975051950710397,3.4025,3.4425,3.5425,3.6025,0.040000000000000036,0.06000000000000005 +-uywlfIYOS8/4,-uywlfIYOS8,4,13,we're,3.682499885559082,3.862499952316284,True,3.684579377716268e-11,4.0,3.6833066425391294,3.8624815665334,3.6825,3.6825,3.8625,3.8625,0.0,0.0 +-uywlfIYOS8/4,-uywlfIYOS8,4,14,driving,3.9024999141693115,4.222499847412109,True,4.1946619924260534e-14,0.34935280680656433,3.9024850739862837,4.222491770692106,3.9025,3.9025,4.2225,4.2225,0.0,0.0 +-uywlfIYOS8/4,-uywlfIYOS8,4,15,the,4.242499828338623,4.34250020980835,True,3.531454168263955e-14,0.2941174805164337,4.242503793608108,4.342507015743014,4.242500000000001,4.242500000000001,4.3425,4.3425,0.0,0.0 +-uywlfIYOS8/4,-uywlfIYOS8,4,16,relevant,4.362500190734863,4.722499847412109,True,3.1015102053451316e-13,2.5830955505371094,4.362528100683705,4.7228847343356,4.362500000000001,4.362500000000001,4.7225,4.7225,0.0,0.0 +-uywlfIYOS8/4,-uywlfIYOS8,4,17,insight.,4.882500171661377,5.822500228881836,True,2.73377674664399e-12,4.0,4.881390463456283,5.819079782519511,4.862500000000001,4.8825,5.782500000000001,5.862500000000001,0.019999999999999574,0.08000000000000007 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,0,Many,0.08250000327825546,0.2824999988079071,True,7.850928566109638e-13,3.5132734775543213,0.10585923401689983,0.33275215154873433,0.0825,0.14250000000000002,0.28250000000000003,0.4425,0.06000000000000001,0.15999999999999998 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,1,people,0.4025000035762787,0.7024999856948853,True,9.156772562413096e-13,4.0,0.4426754338118783,0.7227427877341543,0.4025,0.4825,0.7025,0.7424999999999999,0.07999999999999996,0.039999999999999925 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,2,are,0.7825000286102295,0.9825000166893005,True,2.8262345263575794e-13,1.2647337913513184,0.7845461092295155,0.9620080068815149,0.7825,0.7825,0.9225,0.9824999999999999,0.0,0.05999999999999994 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,3,not,1.0225000381469727,1.1425000429153442,True,4.933300133420221e-14,0.25,1.0239882241362008,1.1437603517251953,1.0225,1.0225,1.1425,1.1425,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,4,until,1.1825000047683716,1.5425000190734863,True,1.1237945253192438e-13,0.5028955936431885,1.1842781652958174,1.5435631922214206,1.1824999999999999,1.1824999999999999,1.5425,1.5425,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,5,they,1.5824999809265137,1.9424999952316284,True,1.3072862562434062e-13,0.5850077271461487,1.5848135452386243,1.940893219335555,1.5825,1.5825,1.9425,1.9425,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,6,get,2.0225000381469727,2.1624999046325684,True,1.3913614760384472e-14,0.25,2.0224595608245117,2.162566220706084,2.0225,2.0225,2.1625,2.1625,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,7,to,2.262500047683716,2.3424999713897705,True,2.638859826996614e-14,0.25,2.264419013866157,2.3477816786947727,2.2025,2.3225,2.3425,2.3825,0.11999999999999966,0.040000000000000036 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,8,be,2.4024999141693115,2.502500057220459,True,4.1763540867788274e-13,1.8689093589782715,2.4025004305045847,2.502500872803157,2.4025,2.4025,2.5025,2.5025,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,9,a,2.6624999046325684,2.682499885559082,True,9.004533772262457e-13,4.0,2.6624925234542722,2.6824925234542722,2.6625,2.6625,2.6825,2.6825,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,10,older,3.322499990463257,3.5425000190734863,True,2.0256505620010884e-13,0.906474232673645,3.3198354757754682,3.5423462179745098,3.3225000000000002,3.3225000000000002,3.5425,3.5425,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,11,age,3.762500047683716,3.922499895095825,True,3.217204334968887e-13,1.4396919012069702,3.7624739015695634,3.922669449686004,3.7625,3.7625,3.9225,3.9225,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,12,and,4.022500038146973,4.182499885559082,True,1.5305238223713505e-14,0.25,4.034930648788859,4.200137383139412,4.022500000000001,4.1025,4.1825,4.2225,0.07999999999999918,0.040000000000000036 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,13,they,4.322500228881836,4.502500057220459,True,1.6199097185171096e-13,0.7249060869216919,4.321713048262524,4.501433219594749,4.322500000000001,4.322500000000001,4.5025,4.5025,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,14,realize,4.622499942779541,4.982500076293945,True,5.409635413233804e-13,2.420799970626831,4.619013484915951,4.951435893611253,4.6225000000000005,4.6225000000000005,4.9225,4.982500000000001,0.0,0.0600000000000005 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,15,that,5.0625,5.362500190734863,True,1.7663386031596673e-10,4.0,5.061109736838025,5.357915223735426,5.062500000000001,5.062500000000001,5.322500000000001,5.362500000000001,0.0,0.040000000000000036 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,16,gosh,5.402500152587891,5.582499980926514,True,6.985038936146992e-11,4.0,5.412608374385401,5.583867731142024,5.402500000000001,5.442500000000001,5.5825000000000005,5.5825000000000005,0.040000000000000036,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,17,they,5.762499809265137,5.942500114440918,True,9.114082643972565e-14,0.40785321593284607,5.743872692230504,5.933506686984788,5.6225000000000005,5.7625,5.902500000000001,5.942500000000001,0.13999999999999968,0.040000000000000036 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,18,wasted,5.962500095367432,6.28249979019165,True,6.252937400584016e-15,0.25,5.9755017709324125,6.318240025679866,5.9625,6.0025,6.282500000000001,6.3425,0.040000000000000036,0.05999999999999961 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,19,a,6.362500190734863,6.382500171661377,True,9.418957584370058e-13,4.0,6.362501464590465,6.3825014645904625,6.362500000000001,6.362500000000001,6.3825,6.3825,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,20,lot,6.442500114440918,6.5625,True,1.293143381004419e-13,0.5786788463592529,6.442499934859892,6.5625000135512535,6.442500000000001,6.442500000000001,6.562500000000001,6.562500000000001,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,21,of,6.622499942779541,6.702499866485596,True,2.4035458952992306e-12,4.0,6.615005116878734,6.6837688432472016,6.5825000000000005,6.6225000000000005,6.642500000000001,6.702500000000001,0.040000000000000036,0.05999999999999961 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,22,time,6.742499828338623,7.0625,True,3.271341869810242e-14,0.25,6.7425061991759785,7.062501833718776,6.742500000000001,6.742500000000001,7.062500000000001,7.062500000000001,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,23,and,7.142499923706055,7.242499828338623,True,7.342488162614957e-15,0.25,7.114865685343713,7.23577604907428,7.0825000000000005,7.142500000000001,7.202500000000001,7.242500000000001,0.0600000000000005,0.040000000000000036 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,24,money,7.34250020980835,7.5625,True,2.4677303386497207e-13,1.1043039560317993,7.342288899962515,7.563080577866272,7.3425,7.3425,7.562500000000001,7.562500000000001,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,25,in,8.602499961853027,8.982500076293945,True,1.5762575706484983e-13,0.7053718566894531,8.364611154997718,8.85810714822456,7.602500000000001,8.6225,8.6225,8.9825,1.0199999999999996,0.35999999999999943 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,26,placing,9.0625,9.6225004196167,True,1.828831275871648e-13,0.8183979988098145,9.066924678538173,9.62794870027181,8.9625,9.3025,9.6225,9.6625,0.33999999999999986,0.03999999999999915 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,27,bets,9.642499923706055,9.882499694824219,True,4.637042486099752e-12,4.0,9.682127934242377,9.909239237242446,9.6425,9.7025,9.8825,9.9225,0.0600000000000005,0.03999999999999915 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,28,on,9.942500114440918,10.042499542236328,True,3.03088699971088e-11,4.0,9.944177340580937,10.044079828969402,9.942499999999999,9.942499999999999,10.0425,10.0425,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,29,stock,10.1225004196167,10.40250015258789,True,1.0609971966757045e-14,0.25,10.13073084545628,10.425039706715383,10.1225,10.1625,10.4025,10.5025,0.03999999999999915,0.09999999999999964 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,30,that's,10.482500076293945,10.72249984741211,True,1.9271074319648918e-11,4.0,10.493521815416006,10.722486771164357,10.4825,10.5425,10.7225,10.7225,0.0600000000000005,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,31,ultimately,10.742500305175781,11.362500190734863,True,2.4436450584384983e-13,1.0935258865356445,10.744089634125213,11.362750520402031,10.7425,10.7425,11.362499999999999,11.362499999999999,0.0,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,32,lost,11.462499618530273,11.702500343322754,True,1.1303276904414163e-14,0.25,11.458537715767447,11.702573699169442,11.442499999999999,11.4625,11.7025,11.7025,0.02000000000000135,0.0 +-6rXp3zJ3kc/8,-6rXp3zJ3kc,8,33,value.,11.842499732971191,12.242500305175781,True,1.0531544169731233e-12,4.0,11.844283755647352,12.241341598308948,11.8425,11.8425,12.2425,12.2425,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,0,"is,",0.0024999999441206455,0.0625,True,3.060766640139434e-10,4.0,0.0025112058701024778,0.0626767445741339,0.0025000000000000005,0.0025000000000000005,0.0625,0.0625,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,1,you,0.12250000238418579,0.2224999964237213,True,1.535432336829956e-10,4.0,0.12240190227637165,0.22247758827306965,0.1225,0.1225,0.2225,0.2225,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,2,can,0.26249998807907104,0.3824999928474426,True,2.600926939100301e-11,4.0,0.2624053486672871,0.3825267286438774,0.2625,0.2625,0.3825,0.3825,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,3,"say,",0.4625000059604645,0.6424999833106995,True,3.910752364305603e-12,1.8001569509506226,0.46261070574901725,0.6425522763266137,0.4625,0.4625,0.6425,0.6425,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,4,hey,0.7825000286102295,1.0425000190734863,True,3.1533831535562884e-12,1.4515326023101807,0.7823334202971419,1.04253429725383,0.7825,0.7825,1.0425,1.0425,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,5,I,1.1024999618530273,1.122499942779541,True,2.4848057639248466e-11,4.0,1.106823013333484,1.1268230133336934,1.0825,1.1225,1.1025,1.1425,0.040000000000000036,0.040000000000000036 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,6,really,1.462499976158142,1.7625000476837158,True,8.315149783999498e-12,3.8275434970855713,1.4586973624020396,1.760280018786308,1.4625,1.4625,1.7625,1.7625,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,7,like,1.7825000286102295,2.002500057220459,True,2.202190625764499e-14,0.25,1.8349168890968484,2.049505831918696,1.7825,1.9425,2.0025,2.1025,0.15999999999999992,0.10000000000000009 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,8,baby,2.0425000190734863,2.302500009536743,True,4.1377170786893736e-12,1.9046310186386108,2.0909214645105583,2.320850643943992,2.0425,2.1425,2.3025,2.3425,0.10000000000000009,0.03999999999999959 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,9,"skin,",2.4024999141693115,2.7225000858306885,True,1.806715150751148e-12,0.8316483497619629,2.3998643025533677,2.7200288568107656,2.4025,2.4025,2.7225,2.7225,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,10,they,2.9825000762939453,3.322499990463257,True,5.184020313714344e-12,2.38625431060791,2.982507862329635,3.3109432237495335,2.9825,2.9825,3.2625,3.3225000000000002,0.0,0.06000000000000005 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,11,are,3.442500114440918,3.6424999237060547,True,1.3909029093414627e-12,0.6402459740638733,3.442499981962662,3.6424997548724356,3.4425,3.4425,3.6425,3.6425,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,12,so,3.742500066757202,3.822499990463257,True,1.5805114378722451e-13,0.25,3.746053024158016,3.8230914471326036,3.7425,3.7625,3.8225000000000002,3.8225000000000002,0.020000000000000018,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,13,"soft,",3.882499933242798,4.102499961853027,True,2.7519693880477536e-13,0.25,3.8825012869595423,4.102466215181166,3.8825,3.8825,4.1025,4.1025,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,14,they,4.28249979019165,4.602499961853027,True,8.551512904915459e-13,0.3936343491077423,4.282513053129279,4.602513532707415,4.282500000000001,4.282500000000001,4.602500000000001,4.602500000000001,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,15,don’t,4.682499885559082,4.902500152587891,True,8.042919108497415e-11,4.0,4.683443564494826,4.903185399030555,4.6825,4.6825,4.902500000000001,4.902500000000001,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,16,have,4.962500095367432,5.222499847412109,True,1.4296327793469898e-13,0.25,4.967341030440776,5.226155811124558,4.9625,5.022500000000001,5.2225,5.2625,0.0600000000000005,0.040000000000000036 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,17,any,5.322500228881836,5.442500114440918,True,2.458334967883613e-12,1.131595253944397,5.322497337046365,5.442501103881926,5.322500000000001,5.322500000000001,5.442500000000001,5.442500000000001,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,18,hair,5.522500038146973,5.78249979019165,True,8.543707733475736e-13,0.39327508211135864,5.522549514283644,5.782686723091677,5.522500000000001,5.522500000000001,5.782500000000001,5.782500000000001,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,19,on,5.882500171661377,5.942500114440918,True,1.8865666407547055e-12,0.868404746055603,5.882448764418133,5.9425058227663135,5.8825,5.8825,5.942500000000001,5.942500000000001,0.0,0.0 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,20,their,6.022500038146973,6.34250020980835,True,4.095190170045476e-13,0.25,6.0212367814366665,6.362506654169406,6.022500000000001,6.022500000000001,6.3425,6.402500000000001,0.0,0.0600000000000005 +-9y-fZ3swSY/0,-9y-fZ3swSY,0,21,face,6.462500095367432,6.722499847412109,True,3.871533356489959e-13,0.25,6.462437165544646,6.717253186710826,6.3825,6.522500000000001,6.6225000000000005,6.7225,0.14000000000000057,0.09999999999999964 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,0,I’ve,0.4025000035762787,0.5024999976158142,True,2.0237548525869897e-08,4.0,0.3604930640300776,0.5025259623963769,0.3025,0.4025,0.5025,0.5025,0.10000000000000003,0.0 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,1,seen,0.5625,0.7825000286102295,True,5.362225594107706e-11,1.505155086517334,0.5576079937154002,0.7374851585800298,0.5225,0.5625,0.7025,0.7825,0.040000000000000036,0.07999999999999996 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,2,this,0.8224999904632568,1.0425000190734863,True,3.008013326269432e-12,0.25,0.8081106426559449,1.0121021476836018,0.7625,0.8225,0.9225,1.0425,0.06000000000000005,0.12 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,3,in,1.122499942779541,1.2024999856948853,True,5.537627301155368e-11,1.5543895959854126,1.1072155754604693,1.192481658849235,1.0225,1.1225,1.1025,1.2225,0.10000000000000009,0.11999999999999988 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,4,US,1.2825000286102295,1.4824999570846558,True,5.11657140267463e-11,1.4362009763717651,1.2692331019302276,1.440947430874424,1.1225,1.2825,1.2025,1.4825,0.15999999999999992,0.28 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,5,or,1.5625,1.8424999713897705,True,1.1776651702433139e-12,0.25,1.5884781405612562,1.81895963877589,1.2825,1.8225,1.4825,1.9825,0.54,0.5 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,6,in,1.902500033378601,1.9824999570846558,True,4.608553664554871e-13,0.25,1.9176942178451357,2.0156957087418754,1.8225,2.0425,1.9825,2.1425,0.21999999999999997,0.16000000000000014 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,7,the,2.0425000190734863,2.322499990463257,True,3.562573500093258e-11,1.0,2.0775599959853452,2.2745366471050685,2.0425,2.2025,2.1825,2.3625,0.16000000000000014,0.17999999999999972 +-9y-fZ3swSY/4,-9y-fZ3swSY,4,8,US,2.4024999141693115,2.5625,True,2.4587404594961226e-12,0.25,2.3624797829867665,2.563519061540398,2.3025,2.4625,2.5625,2.5625,0.1599999999999997,0.0 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,0,That’s,0.08250000327825546,0.42250001430511475,True,9.314120308356877e-11,4.0,0.0806608236315872,0.4421451291187421,0.0625,0.0825,0.4225,0.4825,0.020000000000000004,0.06 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,1,a,0.4625000059604645,0.48249998688697815,True,1.3536963433882776e-12,1.1048375368118286,0.5336691584869542,0.5536691584869534,0.4625,0.6024999999999999,0.4825,0.6224999999999999,0.1399999999999999,0.13999999999999996 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,2,more,0.9624999761581421,1.162500023841858,True,1.1315475872920519e-13,0.25,0.915860858527888,1.1624825207872158,0.6024999999999999,0.9624999999999999,1.1624999999999999,1.1624999999999999,0.36,0.0 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,3,decent,1.3624999523162842,1.8025000095367432,True,3.1133767981229854e-13,0.2541024386882782,1.361983429299652,1.8391916213136885,1.3625,1.3625,1.8025,2.1225,0.0,0.32000000000000006 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,4,and,2.1024999618530273,2.322499990463257,True,2.3098985831720986e-12,1.8852548599243164,2.114016786911137,2.3136987008669143,2.1025,2.2025,2.2625,2.3225,0.10000000000000009,0.05999999999999961 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,5,more,2.382499933242798,2.7825000286102295,True,1.0729073879334194e-12,0.8756678104400635,2.4241202403087847,2.781629417286628,2.3825,2.4825,2.7825,2.7825,0.10000000000000009,0.0 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,6,polite,2.922499895095825,3.2825000286102295,True,1.4056551062013867e-13,0.25,2.9215736524164218,3.2824992595126026,2.9225,2.9225,3.2825,3.2825,0.0,0.0 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,7,way,3.4825000762939453,3.6024999618530273,True,3.170587490469723e-12,2.5877177715301514,3.4208157907789016,3.5888738666999616,3.3425,3.4825,3.5425,3.6025,0.14000000000000012,0.06000000000000005 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,8,to,3.6624999046325684,4.022500038146973,True,6.365228981917992e-13,0.5195067524909973,3.6700739437613157,4.023422620318217,3.6625,3.6625,4.022500000000001,4.022500000000001,0.0,0.0 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,9,call,4.082499980926514,4.34250020980835,True,9.880774150261562e-12,4.0,4.082498071211092,4.342498071249503,4.0825000000000005,4.0825000000000005,4.3425,4.3425,0.0,0.0 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,10,a,4.382500171661377,4.402500152587891,True,1.398533979596328e-11,4.0,4.38238720408983,4.402387204089831,4.3825,4.3825,4.402500000000001,4.402500000000001,0.0,0.0 +-9y-fZ3swSY/8,-9y-fZ3swSY,8,11,lady,4.722499847412109,4.902500152587891,True,1.096793229155013e-12,0.8951625823974609,4.725094218121915,4.90232210201576,4.7225,4.742500000000001,4.902500000000001,4.902500000000001,0.020000000000000462,0.0 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,0,The,0.14249999821186066,0.5824999809265137,True,1.1787321505419158e-14,0.25,0.27252131830482507,0.5876429988753463,0.1225,0.5225,0.5824999999999999,0.6224999999999999,0.39999999999999997,0.040000000000000036 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,1,perfect,0.6025000214576721,1.002500057220459,True,3.2728529088255076e-13,0.25,0.6092378774561676,1.0025942417269524,0.6024999999999999,0.6425,1.0025,1.0025,0.040000000000000036,0.0 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,2,soul,1.0425000190734863,1.2625000476837158,True,3.279520058296903e-11,4.0,1.042594908835863,1.262583948424393,1.0425,1.0425,1.2625,1.2625,0.0,0.0 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,3,mate,1.3025000095367432,1.5625,True,8.825176700533177e-12,1.7002969980239868,1.302545298794321,1.5265084161584652,1.3025,1.3025,1.4825,1.5625,0.0,0.08000000000000007 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,4,to,1.6024999618530273,1.662500023841858,True,1.4148528269114502e-12,0.2725917100906372,1.6056070545522665,1.6656434794159292,1.6025,1.6025,1.6625,1.6625,0.0,0.0 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,5,the,1.722499966621399,1.8224999904632568,True,5.101854268912964e-13,0.25,1.735751104704133,1.8401369240743506,1.7225,1.8625,1.8225,1.9825,0.14000000000000012,0.15999999999999992 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,6,Clarisonic,1.8624999523162842,2.5625,True,3.914031425356068e-12,0.7540943622589111,1.8851971012939985,2.6083585906340376,1.8625,2.0825,2.4825,3.4025,0.21999999999999997,0.9199999999999999 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,7,Spot,3.1024999618530273,3.4024999141693115,True,2.7890302914390652e-12,0.5373467206954956,3.1445458318034225,3.4526482322797505,3.1025,3.5625,3.4025,3.9625,0.45999999999999996,0.56 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,8,Therapy,3.5625,3.9625000953674316,True,1.1581469290533608e-11,2.2313363552093506,3.606693728375404,4.068442576095661,3.5625,4.1025,3.9625,5.0425,0.54,1.0800000000000005 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,9,"Brush,",4.042500019073486,4.322500228881836,True,4.2936924089971573e-13,0.25,4.152623283975696,4.44807120308332,4.0425,5.1825,4.322500000000001,5.562500000000001,1.1399999999999997,1.2400000000000002 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,10,this,4.942500114440918,5.122499942779541,True,2.7933718164084576e-13,0.25,4.98188533431721,5.221250227451901,4.562500000000001,5.742500000000001,5.0825000000000005,6.062500000000001,1.1799999999999997,0.9800000000000004 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,11,"gentle,",5.182499885559082,5.642499923706055,True,1.0272394046495492e-11,1.9791241884231567,5.298987408234679,5.714191899190055,5.1825,6.202500000000001,5.602500000000001,6.562500000000001,1.0200000000000005,0.96 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,12,Ph,5.742499828338623,5.822500228881836,True,4.917092080725105e-11,4.0,5.807498087279645,5.894975688983383,5.6625000000000005,6.6225000000000005,5.7225,6.7625,0.96,1.04 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,13,balanced,5.922500133514404,6.442500114440918,True,2.114638976077887e-12,0.4074155390262604,6.020752430532114,6.566108548962118,5.742500000000001,6.902500000000001,6.3025,7.4625,1.1600000000000001,1.1600000000000001 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,14,and,6.502500057220459,6.622499942779541,True,2.047474386215886e-12,0.3944753408432007,6.6474085491968244,6.8075910652999445,6.4225,7.602500000000001,6.562500000000001,7.702500000000001,1.1800000000000006,1.1399999999999997 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,15,hydrating,6.742499828338623,7.462500095367432,True,2.415321089833944e-13,0.25,6.931675287821492,7.679988215120003,6.742500000000001,7.822500000000001,7.4625,8.282499999999999,1.08,0.8199999999999985 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,16,exfoliant,7.682499885559082,9.022500038146973,True,9.834040699818747e-12,1.8946690559387207,7.832606323443743,8.842506718610109,7.5825000000000005,8.6025,8.1025,9.2225,1.0199999999999987,1.120000000000001 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,17,containing,9.382499694824219,10.322500228881836,True,7.338613224050494e-12,1.4138891696929932,9.053975217156005,9.999233994578377,8.1625,9.4025,9.1825,10.4825,1.2400000000000002,1.3000000000000007 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,18,jojoba,10.462499618530273,10.962499618530273,True,1.2090047712964846e-11,2.3293211460113525,10.153471942108839,10.632818750234803,9.3825,10.5425,9.862499999999999,10.9825,1.1600000000000001,1.120000000000001 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,19,and,11.142499923706055,11.362500190734863,True,6.746394415335644e-11,4.0,10.865587426362282,11.092469474696552,10.0025,11.1425,10.4825,11.362499999999999,1.1400000000000006,0.879999999999999 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,20,acai,11.442500114440918,11.582500457763672,True,3.173180121440744e-11,4.0,11.185082640911101,11.40354090768313,10.5425,11.4825,10.8825,11.6825,0.9399999999999995,0.7999999999999989 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,21,fruit,11.702500343322754,12.5625,True,3.936610586119382e-12,0.7584445476531982,11.542750165286042,12.199442610047605,10.9825,12.3225,11.362499999999999,12.5625,1.3399999999999999,1.200000000000001 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,22,oils,12.702500343322754,12.962499618530273,True,1.2418142035508506e-11,2.392533302307129,12.312457137645003,12.53612750534288,11.4225,12.7025,11.5825,12.9625,1.2800000000000011,1.3800000000000008 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,23,and,13.0024995803833,13.182499885559082,True,1.4112935646515279e-11,2.719059705734253,12.838743358082878,13.096751343161257,12.3825,13.1025,12.522499999999999,13.6025,0.7199999999999989,1.08 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,24,bamboo,13.5625,14.0625,True,6.703672773139546e-12,1.2915587425231934,13.33881562914513,13.769541054426064,12.7025,13.7425,13.1225,14.0625,1.0399999999999991,0.9399999999999995 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,25,and,14.142499923706055,14.362500190734863,True,8.946042691360123e-12,1.7235835790634155,13.864704428194672,14.118485920377335,13.2625,14.1425,13.5825,14.362499999999999,0.8800000000000008,0.7799999999999994 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,26,prickly,14.662500381469727,15.102499961853027,True,3.0223447442662144e-13,0.25,14.322593078254965,14.767185447932158,13.6625,14.6625,14.0625,15.1025,1.0,1.0399999999999991 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,27,bear,15.702500343322754,15.862500190734863,True,4.4243590995723947e-13,0.25,15.12995941247925,15.403516804053789,14.1425,15.7025,14.362499999999999,15.8625,1.5600000000000005,1.5000000000000018 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,28,extracts,15.942500114440918,16.322500228881836,True,1.6714140650946757e-13,0.25,15.53453527528529,16.17754300405277,14.6625,15.942499999999999,15.8225,16.4025,1.2799999999999994,0.5800000000000001 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,29,deliver,16.38249969482422,16.862499237060547,True,1.0248501672955809e-13,0.25,16.270850501054223,16.686664552019476,15.942499999999999,16.5025,16.282500000000002,16.8625,0.5600000000000023,0.5799999999999983 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,30,intense,16.90250015258789,17.322500228881836,True,7.725160029899147e-13,0.25,16.78021481124627,17.24047823295799,16.5025,16.962500000000002,17.0625,17.3225,0.46000000000000085,0.26000000000000156 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,31,"healing,",17.362499237060547,18.0625,True,4.7344672805685675e-14,0.25,17.313333485444595,18.013450491442516,17.122500000000002,17.622500000000002,17.942500000000003,18.0625,0.5,0.11999999999999744 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,32,while,18.122499465942383,18.38249969482422,True,1.305523180880619e-12,0.2515277862548828,18.121970016579592,18.382910922205134,18.122500000000002,18.122500000000002,18.3825,18.3825,0.0,0.0 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,33,smooth,18.462499618530273,18.922500610351562,True,6.875201363082395e-12,1.32460618019104,18.46245288047144,18.91253360874653,18.462500000000002,18.462500000000002,18.902500000000003,18.922500000000003,0.0,0.019999999999999574 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,34,granules,19.0625,19.622499465942383,True,6.236156729899633e-11,4.0,19.060714967031537,19.62165223075318,19.0625,19.0625,19.622500000000002,19.622500000000002,0.0,0.0 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,35,buff,19.702499389648438,20.342500686645508,True,5.486440295132677e-12,1.0570415258407593,19.89197269833418,20.35923287241106,19.7025,20.122500000000002,20.3425,20.402500000000003,0.4200000000000017,0.060000000000002274 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,36,away,20.6825008392334,20.962499618530273,True,1.5412348047111335e-12,0.29694101214408875,20.646430815099194,20.960356266677547,20.402500000000003,20.6825,20.962500000000002,20.962500000000002,0.2799999999999976,0.0 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,37,"dead,",20.982500076293945,21.142499923706055,True,7.757587107415365e-12,1.4946105480194092,20.986751725007654,21.14226403506907,20.9825,21.0025,21.142500000000002,21.142500000000002,0.019999999999999574,0.0 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,38,dry,21.202499389648438,21.38249969482422,True,5.190373738445109e-12,1.0,21.20398053353988,21.388662026269635,21.2025,21.2025,21.3825,21.442500000000003,0.0,0.060000000000002274 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,39,skin,21.482500076293945,21.622499465942383,True,6.363738702663824e-11,4.0,21.480180957830996,21.622991854845147,21.4825,21.4825,21.622500000000002,21.642500000000002,0.0,0.019999999999999574 +-AUZQgSxyPQ/2,-AUZQgSxyPQ,2,40,cells.,21.642499923706055,21.842500686645508,True,2.2591633425106394e-11,4.0,21.64385152483771,21.84267698383198,21.642500000000002,21.6625,21.8425,21.8425,0.019999999999999574,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,0,The,0.24250000715255737,0.4025000035762787,True,1.1845117768582991e-11,4.0,0.1959311331958721,0.40235082912774206,0.0425,0.2425,0.4025,0.4025,0.19999999999999998,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,1,August,1.402500033378601,2.122499942779541,True,1.4341861032107772e-12,0.8177534341812134,1.4478832208215444,2.1272597779712865,1.4025,1.7625,2.1225,2.1625,0.3599999999999999,0.040000000000000036 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,2,jobs,2.322499990463257,2.6024999618530273,True,2.558615125325403e-11,4.0,2.320611337970802,2.6004673835909573,2.3225,2.3225,2.6025,2.6025,0.0,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,3,report,2.682499885559082,3.002500057220459,True,2.7453449669839758e-12,1.5653584003448486,2.68170298259558,3.009440710897623,2.6825,2.6825,3.0025,3.0825,0.0,0.08000000000000007 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,4,is,3.0625,3.1424999237060547,True,4.514987830221001e-13,0.2574384808540344,3.0812734603350624,3.1623839522789665,3.0625,3.3225000000000002,3.1425,3.4225,0.26000000000000023,0.2799999999999998 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,5,out,3.322499990463257,3.4625000953674316,True,2.090342601703682e-13,0.25,3.344295656509894,3.4967551728462754,3.1625,3.8625,3.4225,3.9825,0.6999999999999997,0.56 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,6,and,3.862499952316284,3.9825000762939453,True,8.034748539241521e-14,0.25,3.877242383787142,4.00469880646666,3.8625,4.062500000000001,3.9825,4.242500000000001,0.20000000000000107,0.2600000000000007 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,7,it,4.302499771118164,4.382500171661377,True,2.6032816310625484e-13,0.25,4.275837833615807,4.386597712761713,4.202500000000001,4.3025,4.3825,4.402500000000001,0.09999999999999964,0.020000000000000462 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,8,was,4.502500057220459,4.702499866485596,True,6.574726874042369e-12,3.7488200664520264,4.5026476132951725,4.702857723024613,4.5025,4.5025,4.702500000000001,4.702500000000001,0.0,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,9,seen,5.262499809265137,5.642499923706055,True,9.668883749203161e-12,4.0,5.26248580780262,5.643139038744664,5.2625,5.2625,5.6425,5.6625000000000005,0.0,0.020000000000000462 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,10,overall,6.202499866485596,6.722499847412109,True,2.0734386430021345e-12,1.1822465658187866,6.135176538397465,6.722530461705236,5.7625,6.202500000000001,6.7225,6.7225,0.4400000000000004,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,11,as,6.802499771118164,6.882500171661377,True,8.576729821144213e-13,0.4890334904193878,6.802730239021207,6.882715843694687,6.8025,6.8025,6.8825,6.8825,0.0,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,12,solid,6.942500114440918,7.202499866485596,True,8.672484930714874e-13,0.494493305683136,6.944034109898724,7.203577690574796,6.942500000000001,6.942500000000001,7.202500000000001,7.202500000000001,0.0,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,13,but,7.34250020980835,7.602499961853027,True,3.902187947768532e-11,4.0,7.342753371410023,7.602373466405716,7.3425,7.3425,7.602500000000001,7.602500000000001,0.0,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,14,not,7.662499904632568,7.802499771118164,True,2.746409328256705e-13,0.25,7.663526959768611,7.802856928638411,7.6625000000000005,7.6625000000000005,7.8025,7.8025,0.0,0.0 +-HeZS2-Prhc/2,-HeZS2-Prhc,2,15,great.,7.862500190734863,8.082500457763672,True,2.701561847492928e-12,1.5403938293457031,7.8635557979644375,8.088359004012458,7.862500000000001,7.862500000000001,8.0825,8.1225,0.0,0.040000000000000924 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,0,"Okay,",0.9424999952316284,1.2424999475479126,True,3.710065674816798e-12,4.0,0.9432326596664109,1.2056759510520048,0.9225,1.0025,1.1025,1.2425,0.07999999999999996,0.1399999999999999 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,1,what,1.3025000095367432,1.502500057220459,True,1.2836673354322831e-14,1.0,1.2968934930611797,1.4994382940713709,1.3025,1.3025,1.5025,1.5025,0.0,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,2,happens,1.5625,2.122499942779541,True,1.206398787698083e-14,0.9398064017295837,1.558655575902781,2.121205916667169,1.5425,1.5625,2.1225,2.1225,0.020000000000000018,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,3,at,2.202500104904175,2.2825000286102295,True,2.9099730082044395e-15,0.25,2.1952647147514655,2.2751562874460314,2.1425,2.2025,2.2225,2.2825,0.06000000000000005,0.06000000000000005 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,4,this,2.322499990463257,2.4825000762939453,True,3.948112470227071e-15,0.3075650930404663,2.3262151924486174,2.488170818444105,2.3225,2.3625,2.4825,2.5225,0.040000000000000036,0.040000000000000036 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,5,point,2.5225000381469727,2.882499933242798,True,3.802389345497915e-15,0.29621297121047974,2.5670758567670444,2.901260034406884,2.5225,2.6225,2.8825,2.9225,0.10000000000000009,0.040000000000000036 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,6,after,3.202500104904175,3.422499895095825,True,4.455512734203183e-15,0.34709247946739197,3.1913281357894654,3.419919056829773,3.1825,3.2025,3.3825,3.4225,0.020000000000000018,0.040000000000000036 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,7,we've,3.4625000953674316,3.682499885559082,True,1.9134102288709265e-11,4.0,3.4638915322588497,3.6825000001063266,3.4625,3.4625,3.6825,3.6825,0.0,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,8,taken,3.7225000858306885,4.002500057220459,True,3.697702849480861e-15,0.28805771470069885,3.7225000291431787,4.010663846188186,3.7225,3.7225,4.0025,4.0425,0.0,0.040000000000000036 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,9,this,4.042500019073486,4.222499847412109,True,1.42208513980455e-14,1.1078299283981323,4.0553085178820885,4.231976591647393,4.0425,4.1025,4.2225,4.2625,0.05999999999999961,0.040000000000000036 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,10,brief,4.462500095367432,4.702499866485596,True,1.0028261925834787e-14,0.7812196612358093,4.462443349973335,4.704718386141115,4.4625,4.4625,4.702500000000001,4.702500000000001,0.0,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,11,walk,4.78249979019165,5.142499923706055,True,6.560490405050842e-15,0.5110740065574646,4.813190037922622,5.151410892553026,4.7625,4.8825,5.1425,5.1825,0.1200000000000001,0.040000000000000036 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,12,down,5.202499866485596,5.462500095367432,True,7.031535591414326e-14,4.0,5.203195360240823,5.463194049014288,5.202500000000001,5.202500000000001,5.4625,5.4625,0.0,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,13,memory,5.582499980926514,5.902500152587891,True,2.5533394842902624e-13,4.0,5.582483141326186,5.9028098326745795,5.5825000000000005,5.5825000000000005,5.902500000000001,5.902500000000001,0.0,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,14,"lane,",5.962500095367432,6.302499771118164,True,3.5930408496566424e-13,4.0,5.975316507304133,6.305343427476204,5.9625,6.142500000000001,6.3025,6.3425,0.1800000000000006,0.040000000000000036 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,15,is,6.84250020980835,6.902500152587891,True,7.547921489214904e-12,4.0,6.8424998796201235,6.902499886452121,6.8425,6.8425,6.902500000000001,6.902500000000001,0.0,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,16,the,6.982500076293945,7.082499980926514,True,3.779567948558279e-16,0.25,6.9590939849105835,7.061940314452324,6.942500000000001,6.982500000000001,7.0425,7.0825000000000005,0.040000000000000036,0.040000000000000036 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,17,presentation,7.122499942779541,7.862500190734863,True,3.29521523931872e-15,0.2567031979560852,7.122435235689702,7.862573230447805,7.1225000000000005,7.1225000000000005,7.862500000000001,7.862500000000001,0.0,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,18,of,7.902500152587891,7.962500095367432,True,4.660046220433811e-13,4.0,7.903398437119373,7.963914730371576,7.902500000000001,7.902500000000001,7.9625,7.9625,0.0,0.0 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,19,the,8.042499542236328,8.162500381469727,True,4.581407410560179e-14,3.5689990520477295,8.064463282027926,8.1771366928654,8.0425,8.1025,8.1625,8.202499999999999,0.05999999999999872,0.03999999999999915 +-MeTTeMJBNc/0,-MeTTeMJBNc,0,20,gift.,8.242500305175781,8.582500457763672,True,2.0623882376197278e-12,4.0,8.242500389132172,8.582544997263367,8.2425,8.2425,8.5825,8.5825,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,0,It,0.3425000011920929,0.4424999952316284,True,1.1344515604694294e-11,4.0,0.34125700409427956,0.4421278439000176,0.3425,0.3425,0.4425,0.4425,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,1,just,0.5024999976158142,1.3224999904632568,True,7.597669889058967e-12,4.0,0.6357895630564467,1.3217086751335387,0.5025,1.0625,1.3225,1.3225,0.56,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,2,needs,1.402500033378601,1.6425000429153442,True,1.3798399814239637e-13,2.5175373554229736,1.4024617994614186,1.6427802038920662,1.4025,1.4025,1.6425,1.6425,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,3,to,1.722499966621399,1.7825000286102295,True,1.4288968093597795e-14,0.2607042193412781,1.722500342761648,1.7825003763940888,1.7225,1.7225,1.7825,1.7825,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,4,be,1.8424999713897705,1.9225000143051147,True,4.578755452046279e-13,4.0,1.8425000061154377,1.922500028437251,1.8425,1.8425,1.9224999999999999,1.9224999999999999,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,5,a,2.0225000381469727,2.0425000190734863,True,4.161020486503908e-11,4.0,2.022500304881204,2.0425003048812034,2.0225,2.0225,2.0425,2.0425,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,6,simple,2.2225000858306885,2.5625,True,1.4861399057989472e-13,2.7114830017089844,2.2205922795367226,2.562499455730098,2.2225,2.2225,2.5625,2.5625,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,7,"statement,",2.5824999809265137,3.202500104904175,True,3.476265990695485e-15,0.25,2.5825113951826295,3.202756423531097,2.5825,2.5825,3.2025,3.2025,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,8,and,3.2225000858306885,3.6424999237060547,True,1.5177185476813494e-14,0.27690985798835754,3.230022374213786,3.639560341276429,3.2225,3.2225,3.6025,3.6425,0.0,0.040000000000000036 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,9,then,3.6624999046325684,3.802500009536743,True,8.128732731618369e-16,0.25,3.6595605480135602,3.799753359197992,3.6225,3.6625,3.7625,3.8025,0.040000000000000036,0.040000000000000036 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,10,you,3.822499990463257,3.922499895095825,True,3.6388318573610245e-14,0.6639099717140198,3.82250569880218,3.9263450272879767,3.8225000000000002,3.8225000000000002,3.9225,3.9425,0.0,0.020000000000000018 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,11,present,3.9825000762939453,4.34250020980835,True,5.4407035314182374e-15,0.25,3.982499819073152,4.342058126051071,3.9825,3.9825,4.3425,4.3425,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,12,the,4.362500190734863,4.482500076293945,True,4.4931062586879914e-14,0.8197734951972961,4.362503466738968,4.482502178652516,4.362500000000001,4.362500000000001,4.482500000000001,4.482500000000001,0.0,0.0 +-MeTTeMJBNc/13,-MeTTeMJBNc,13,13,gift.,4.522500038146973,4.862500190734863,True,6.468716756908091e-14,1.180226445198059,4.5225058016335105,4.862473226976465,4.522500000000001,4.522500000000001,4.862500000000001,4.862500000000001,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,0,Maybe,0.042500000447034836,0.3824999928474426,True,3.770235466600373e-14,0.9178741574287415,0.04382005310267007,0.37623012683122026,0.0425,0.0625,0.3425,0.3825,0.019999999999999997,0.03999999999999998 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,1,you,0.6025000214576721,0.7425000071525574,True,2.4669209383598734e-11,4.0,0.6014484098137175,0.7393633434603328,0.5425,0.6224999999999999,0.7025,0.7424999999999999,0.07999999999999996,0.039999999999999925 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,2,could,0.8025000095367432,1.1425000429153442,True,6.561903256006862e-14,1.5975133180618286,0.8039196735936374,1.1445578036248207,0.8025,0.8025,1.1425,1.1824999999999999,0.0,0.039999999999999813 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,3,find,1.5625,1.8424999713897705,True,4.50442504476567e-12,4.0,1.561707044410993,1.8424368444910948,1.5625,1.5625,1.8425,1.8425,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,4,a,1.9424999952316284,1.962499976158142,True,3.019118375441332e-12,4.0,1.9424658593762911,1.962465859376291,1.9425,1.9425,1.9625,1.9625,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,5,picture,2.002500057220459,2.362499952316284,True,2.292061499094538e-14,0.5580086708068848,2.0026882078534736,2.377115832890999,2.0025,2.0025,2.3625,2.4025,0.0,0.040000000000000036 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,6,of,2.422499895095825,2.4825000762939453,True,5.609922791062483e-13,4.0,2.4277161082497907,2.498121486901269,2.4225,2.4625,2.4825,2.5625,0.040000000000000036,0.08000000000000007 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,7,the,2.5824999809265137,2.682499885559082,True,8.198723275808228e-15,0.25,2.579265356662479,2.6792832693436104,2.5425,2.5825,2.6425,2.6825,0.040000000000000036,0.040000000000000036 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,8,couple,2.702500104904175,3.0425000190734863,True,2.822629892947244e-14,0.6871770024299622,2.699416899972035,3.0720880659627245,2.6625,2.7025,3.0425,3.1025,0.040000000000000036,0.06000000000000005 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,9,from,3.0824999809265137,3.322499990463257,True,3.6664202286728655e-15,0.25,3.126486933752154,3.3590129371154913,3.0825,3.1625,3.3225000000000002,3.4225,0.08000000000000007,0.09999999999999964 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,10,their,3.4625000953674316,3.922499895095825,True,1.8800955055493264e-14,0.45771440863609314,3.462535896135531,3.9223684291480794,3.4625,3.4625,3.9225,3.9225,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,11,wedding,3.942500114440918,4.442500114440918,True,4.442729279081903e-13,4.0,3.942471261233754,4.44238517073405,3.9425,3.9425,4.442500000000001,4.442500000000001,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,12,or,4.642499923706055,4.702499866485596,True,2.026530222657471e-14,0.4933643341064453,4.642065602925446,4.702431704556223,4.6425,4.6425,4.702500000000001,4.702500000000001,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,13,sometime,4.902500152587891,5.362500190734863,True,3.989258874409138e-14,0.9711959958076477,4.86246421614156,5.34648215111066,4.8025,4.902500000000001,5.322500000000001,5.362500000000001,0.10000000000000053,0.040000000000000036 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,14,in,5.382500171661377,5.442500114440918,True,2.355478347635699e-15,0.25,5.382091465093613,5.442262434223061,5.3825,5.3825,5.442500000000001,5.442500000000001,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,15,their,5.462500095367432,5.682499885559082,True,6.219688816305443e-15,0.25,5.462726237673856,5.682500012758481,5.4625,5.4625,5.6825,5.6825,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,16,"life,",5.722499847412109,6.042500019073486,True,9.027134074968135e-12,4.0,5.722500033125576,6.042499810582332,5.7225,5.7225,6.0425,6.0425,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,17,or,6.082499980926514,6.182499885559082,True,3.5410132400055805e-13,4.0,6.0825677398853735,6.184103345429151,6.0825000000000005,6.0825000000000005,6.1825,6.202500000000001,0.0,0.020000000000000462 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,18,maybe,6.262499809265137,6.462500095367432,True,1.1368580772955217e-12,4.0,6.2625000261871655,6.462574470158711,6.2625,6.2625,6.4625,6.4625,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,19,even,6.582499980926514,6.762499809265137,True,1.2781007805925948e-12,4.0,6.549329203691951,6.727341946384188,6.5025,6.5825000000000005,6.702500000000001,6.7625,0.08000000000000007,0.05999999999999961 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,20,a,6.802499771118164,6.822500228881836,True,7.715516593675975e-12,4.0,6.802500479833359,6.822500479833361,6.8025,6.8025,6.822500000000001,6.822500000000001,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,21,current,6.922500133514404,7.322500228881836,True,4.107573452921155e-14,1.0,6.913379676245901,7.315998196321345,6.8425,6.9225,7.2625,7.322500000000001,0.08000000000000007,0.0600000000000005 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,22,picture,7.362500190734863,7.822500228881836,True,5.0320147083459527e-14,1.2250577211380005,7.362392721111548,7.822399324363143,7.362500000000001,7.362500000000001,7.822500000000001,7.822500000000001,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,23,and,7.84250020980835,8.262499809265137,True,2.99166141620906e-14,0.7283281683921814,7.899502149493908,8.268061882040197,7.8425,8.202499999999999,8.2625,8.3025,0.35999999999999854,0.040000000000000924 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,24,have,8.282500267028809,8.422499656677246,True,3.7114418932919155e-14,0.9035606980323792,8.288246235381468,8.42975344190582,8.282499999999999,8.3225,8.4225,8.4625,0.040000000000000924,0.040000000000000924 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,25,it,8.482500076293945,8.542499542236328,True,3.107029336504169e-13,4.0,8.482487466508353,8.542487472734381,8.4825,8.4825,8.5425,8.5425,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,26,put,8.582500457763672,8.72249984741211,True,1.557926015841385e-14,0.37928134202957153,8.582500416372213,8.722595724165645,8.5825,8.5825,8.7225,8.7225,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,27,in,8.782500267028809,8.842499732971191,True,1.3454399236162342e-14,0.3275510370731354,8.771773292426657,8.83177402315951,8.7425,8.782499999999999,8.8025,8.8425,0.03999999999999915,0.03999999999999915 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,28,a,8.862500190734863,8.882499694824219,True,1.2338593417381832e-13,3.003864288330078,8.862501392958345,8.882501392958348,8.862499999999999,8.862499999999999,8.8825,8.8825,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,29,beautiful,8.922499656677246,9.342499732971191,True,1.4680022876554372e-14,0.3573891818523407,8.922499999807949,9.342591336440261,8.9225,8.9225,9.3425,9.3425,0.0,0.0 +-MeTTeMJBNc/7,-MeTTeMJBNc,7,30,frame.,9.40250015258789,9.842499732971191,True,2.176588553490233e-12,4.0,9.402788993999224,9.842498636710845,9.4025,9.4025,9.8425,9.8425,0.0,0.0 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,0,So,0.5625,0.7225000262260437,True,5.925417491739471e-13,1.2584871053695679,0.6104202949033318,0.7450530455063744,0.5625,0.7025,0.7224999999999999,0.8225,0.14,0.10000000000000009 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,1,get,1.0425000190734863,1.162500023841858,True,2.0000498653083287e-12,4.0,1.0352633548141328,1.157345829119535,1.0425,1.0425,1.1624999999999999,1.1624999999999999,0.0,0.0 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,2,your,1.222499966621399,1.462499976158142,True,3.061544344862971e-13,0.6502349972724915,1.2204229605923966,1.4590623617756209,1.2225,1.2225,1.4625,1.4625,0.0,0.0 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,3,friends,1.5425000190734863,1.8624999523162842,True,4.583915644523588e-14,0.25,1.5348954679823508,1.8560549491335907,1.5225,1.5425,1.8225,1.8625,0.020000000000000018,0.040000000000000036 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,4,lined,1.8825000524520874,2.0824999809265137,True,4.106438279694036e-12,4.0,1.8794013903302467,2.108598210328863,1.8825,1.8825,2.0825,2.1425,0.0,0.06000000000000005 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,5,"up,",2.1024999618530273,2.1624999046325684,True,2.6779603925011775e-14,0.25,2.132709439233833,2.1930046249082458,2.1025,2.1625,2.1625,2.2225,0.06000000000000005,0.06000000000000005 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,6,get,2.242500066757202,2.362499952316284,True,1.191502972675007e-11,4.0,2.236394349302283,2.3507283319084338,2.2025,2.2425,2.3025,2.3625,0.040000000000000036,0.05999999999999961 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,7,your,2.4024999141693115,2.5625,True,8.169106125062442e-13,1.7350194454193115,2.3922253609813726,2.5522580570477773,2.3625,2.4025,2.5225,2.5625,0.040000000000000036,0.040000000000000036 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,8,business,2.5824999809265137,2.9625000953674316,True,2.262260609961833e-13,0.4804767966270447,2.5807347769870606,2.959944910812453,2.5825,2.5825,2.9625,2.9625,0.0,0.0 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,9,colleagues,2.9825000762939453,3.502500057220459,True,1.0240140332906655e-11,4.0,2.980355311251425,3.5007947034242104,2.9825,2.9825,3.5025,3.5025,0.0,0.0 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,10,lined,3.5425000190734863,3.762500047683716,True,1.963730014101911e-13,0.4170725345611572,3.540848027479565,3.7591541239086355,3.5425,3.5425,3.7225,3.7625,0.0,0.040000000000000036 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,11,up,3.802500009536743,3.862499952316284,True,2.895594734039081e-13,0.6149893403053284,3.8011925535359468,3.8611960341643234,3.8025,3.8025,3.8625,3.8625,0.0,0.0 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,12,and,3.9024999141693115,4.042500019073486,True,4.708365858654973e-13,1.0,3.9015861885760605,4.035220914868527,3.9025,3.9025,4.022500000000001,4.0425,0.0,0.019999999999999574 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,13,have,4.122499942779541,4.262499809265137,True,1.2910945099489646e-13,0.27421286702156067,4.1214453840766305,4.266966117222006,4.1225000000000005,4.1225000000000005,4.2625,4.282500000000001,0.0,0.020000000000000462 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,14,a,4.302499771118164,4.322500228881836,True,1.385675343863529e-14,0.25,4.302061162786527,4.322061162786528,4.3025,4.3025,4.322500000000001,4.322500000000001,0.0,0.0 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,15,good,4.442500114440918,4.762499809265137,True,2.0156643281560305e-12,4.0,4.440412188277476,4.761898046857764,4.4225,4.442500000000001,4.7625,4.7625,0.020000000000000462,0.0 +-RfYyzHpjk4/11,-RfYyzHpjk4,11,16,time.,4.84250020980835,5.042500019073486,True,3.757925221004044e-11,4.0,4.8422608498843465,5.0426273492741265,4.8425,4.8425,5.0425,5.0425,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,0,It's,0.48249998688697815,0.5824999809265137,True,1.4532529624133872e-09,4.0,0.29136950661161193,0.581764070401369,0.0025000000000000005,0.4825,0.5824999999999999,0.5824999999999999,0.48,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,1,"pretty,",0.6025000214576721,0.9624999761581421,True,1.087615783025575e-13,0.44241130352020264,0.602707872197142,0.9658396862173649,0.6024999999999999,0.6024999999999999,0.9624999999999999,1.0025,0.0,0.040000000000000036 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,2,pretty,0.9825000166893005,1.3025000095367432,True,1.235450950527392e-13,0.502546489238739,0.9901859507557427,1.3023208099968344,0.9824999999999999,1.0425,1.3025,1.3025,0.06000000000000005,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,3,easy,1.3424999713897705,1.5225000381469727,True,1.3342861429448127e-13,0.54274982213974,1.3425056143864518,1.5225050163964364,1.3425,1.3425,1.5225,1.5225,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,4,to,1.5625,1.6425000429153442,True,1.0378338101836148e-14,0.25,1.5678174351393568,1.645624593702227,1.5625,1.6225,1.6425,1.6824999999999999,0.06000000000000005,0.039999999999999813 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,5,do,1.7024999856948853,1.8025000095367432,True,5.799786649204886e-13,2.359189033508301,1.702500208385816,1.8025001764746025,1.7025,1.7025,1.8025,1.8025,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,6,but,1.8825000524520874,2.002500057220459,True,9.461694292910595e-15,0.25,1.8798579047304698,2.0026025026774623,1.8625,1.8825,2.0025,2.0025,0.020000000000000018,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,7,you,2.0425000190734863,2.1624999046325684,True,3.8030705971567325e-13,1.5469814538955688,2.0420726874845885,2.161792162433309,2.0425,2.0425,2.1625,2.1625,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,8,got,2.202500104904175,2.302500009536743,True,2.636872518295766e-14,0.25,2.2024992287053813,2.3025002711087743,2.2025,2.2025,2.3025,2.3025,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,9,to,2.3424999713897705,2.4024999141693115,True,5.37920436546966e-14,0.25,2.342231385558277,2.402500610322223,2.3425,2.3425,2.4025,2.4025,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,10,set,2.442500114440918,2.6024999618530273,True,8.723621326180153e-13,3.5485222339630127,2.4425000521424303,2.6025000862422343,2.4425,2.4425,2.6025,2.6025,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,11,up,2.682499885559082,2.762500047683716,True,1.8668987796649494e-12,4.0,2.6824947822719523,2.762491370232272,2.6825,2.6825,2.7625,2.7625,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,12,those,2.8424999713897705,3.0225000381469727,True,4.680378805875518e-13,1.9038455486297607,2.8410879425174627,3.021367438715059,2.8425,2.8425,3.0225,3.0225,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,13,numbers,3.0425000190734863,3.382499933242798,True,3.799781940917041e-13,1.54564368724823,3.0424927295428903,3.382497615488898,3.0425,3.0425,3.3825,3.3825,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,14,ahead,3.422499895095825,3.622499942779541,True,2.4583815343669213e-13,1.0,3.4224973293396848,3.623183535894426,3.4225,3.4225,3.6225,3.6225,0.0,0.0 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,15,of,3.862499952316284,3.942500114440918,True,4.153858246952469e-12,4.0,3.8543357537960174,3.9395657009074068,3.7025,3.8625,3.9225,3.9425,0.1599999999999997,0.020000000000000018 +-RfYyzHpjk4/8,-RfYyzHpjk4,8,16,time.,3.9825000762939453,4.522500038146973,True,2.1563972124865466e-13,0.8771613240242004,3.987601471873267,4.522151300490132,3.9825,3.9825,4.522500000000001,4.522500000000001,0.0,0.0 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,0,You,0.5024999976158142,0.6025000214576721,True,3.148869782542557e-13,0.5932096838951111,0.4641556042763561,0.6001832615386288,0.2025,0.5025,0.5824999999999999,0.6024999999999999,0.29999999999999993,0.020000000000000018 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,1,can,0.6225000023841858,0.7225000262260437,True,5.3242779109174965e-12,4.0,0.6224966097439738,0.722793687589131,0.6224999999999999,0.6224999999999999,0.7224999999999999,0.7224999999999999,0.0,0.0 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,2,make,0.762499988079071,0.9024999737739563,True,9.325262784187771e-12,4.0,0.7624999520131719,0.902500457618032,0.7625,0.7625,0.9025,0.9025,0.0,0.0 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,3,a,0.9225000143051147,0.9424999952316284,True,5.164016322846063e-14,0.25,0.9225004608316872,0.9425004608316874,0.9225,0.9225,0.9425,0.9425,0.0,0.0 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,4,conference,0.9624999761581421,1.3624999523162842,True,2.2286452197595175e-12,4.0,0.9625004885635444,1.36250528925742,0.9624999999999999,0.9624999999999999,1.3625,1.3625,0.0,0.0 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,5,call,1.3825000524520874,1.5225000381469727,True,1.5288667684285051e-12,2.8802037239074707,1.3825053283407196,1.5225057774228026,1.3825,1.3825,1.5225,1.5225,0.0,0.0 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,6,but,1.5625,1.662500023841858,True,3.5439503436908437e-13,0.6676381826400757,1.5625044965401071,1.6625261687119126,1.5625,1.5625,1.6625,1.6625,0.0,0.0 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,7,it,1.6825000047683716,1.7424999475479126,True,1.332392182695763e-11,4.0,1.682547174299906,1.7425472119934313,1.6824999999999999,1.6824999999999999,1.7425,1.7425,0.0,0.0 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,8,takes,1.7625000476837158,1.9424999952316284,True,1.057303116586139e-11,4.0,1.762547757390463,1.9664725912063723,1.7625,1.7625,1.9425,2.0025,0.0,0.06000000000000005 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,9,quite,1.9824999570846558,2.182499885559082,True,8.99263163933739e-11,4.0,1.9998589771697997,2.2030919285306947,1.9825,2.0225,2.1825,2.2425,0.040000000000000036,0.06000000000000005 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,10,a,2.202500104904175,2.2225000858306885,True,6.754598508122711e-14,0.25,2.2377339721451066,2.257733972145132,2.2025,2.2825,2.2225,2.3025,0.08000000000000007,0.08000000000000007 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,11,bit,2.242500066757202,2.3424999713897705,True,5.308189868560853e-13,1.0,2.2777869381841898,2.3777903079199927,2.2425,2.3225,2.3425,2.4225,0.07999999999999963,0.08000000000000007 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,12,of,2.362499952316284,2.422499895095825,True,2.1314319666870807e-13,0.4015364944934845,2.402322583593929,2.4623288813321236,2.3625,2.4825,2.4225,2.5425,0.1200000000000001,0.1200000000000001 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,13,"planning,",2.442500114440918,2.802500009536743,True,8.171992948871956e-14,0.25,2.491071073576032,2.876893066167285,2.4425,2.5825,2.8025,2.9825,0.14000000000000012,0.17999999999999972 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,14,well,2.8424999713897705,2.9825000762939453,True,1.5282908402344808e-13,0.28791186213493347,2.9062972987384375,3.0472606332625687,2.8225,3.0025,2.9825,3.1425,0.18000000000000016,0.16000000000000014 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,15,not,3.002500057220459,3.1024999618530273,True,1.5203597658174778e-13,0.28641775250434875,3.0757937390130943,3.190636335135603,3.0025,3.1825,3.1025,3.3225000000000002,0.18000000000000016,0.2200000000000002 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,16,a,3.122499942779541,3.1424999237060547,True,5.646774280804179e-12,4.0,3.2204657819657214,3.2404657819657814,3.1225,3.3625,3.1425,3.3825,0.23999999999999977,0.23999999999999977 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,17,lot,3.182499885559082,3.322499990463257,True,2.893943290842478e-14,0.25,3.284991537547337,3.429295019753589,3.1825,3.4625,3.3025,3.6225,0.2799999999999998,0.31999999999999984 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,18,of,3.362499952316284,3.442500114440918,True,7.363686049810525e-12,4.0,3.5028824001740775,3.5721282708109663,3.3625,3.7225,3.4225,3.7825,0.3600000000000003,0.3600000000000003 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,19,planning,3.4625000953674316,3.882499933242798,True,4.804686379658585e-13,0.9051459431648254,3.6038900191011245,4.016084286438504,3.4625,3.8225000000000002,3.8825,4.242500000000001,0.3600000000000003,0.36000000000000076 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,20,it's,3.9825000762939453,4.162499904632568,True,4.394659983142368e-12,4.0,4.101904154902036,4.272254213499532,3.9825,4.3025,4.1625000000000005,4.442500000000001,0.3200000000000003,0.28000000000000025 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,21,pretty,4.28249979019165,4.582499980926514,True,3.0015099021681035e-13,0.5654488801956177,4.3755106093167,4.666803222682432,4.282500000000001,4.522500000000001,4.5825000000000005,4.822500000000001,0.2400000000000002,0.2400000000000002 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,22,easy,4.602499961853027,4.802499771118164,True,1.904853228276715e-13,0.35885176062583923,4.695244949059977,4.955538123762717,4.602500000000001,4.862500000000001,4.8025,5.202500000000001,0.2599999999999998,0.40000000000000036 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,23,to,5.182499885559082,5.262499809265137,True,6.027319702367473e-12,4.0,5.204784669311505,5.2778043991771115,5.1825,5.242500000000001,5.2625,5.3025,0.0600000000000005,0.040000000000000036 +-RfYyzHpjk4/2,-RfYyzHpjk4,2,24,do.,5.322500228881836,5.382500171661377,True,6.078794152070133e-12,4.0,5.321774080990339,5.382084433603389,5.322500000000001,5.322500000000001,5.3825,5.3825,0.0,0.0 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,0,I,1.2625000476837158,1.2825000286102295,True,2.3367625542891624e-11,4.0,1.2625116119279252,1.282511611927958,1.2625,1.2625,1.2825,1.2825,0.0,0.0 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,1,mentioned,1.3424999713897705,1.9824999570846558,True,4.0802847212084714e-12,4.0,1.3425128709237222,1.9809538948415186,1.3425,1.3425,1.9025,2.0025,0.0,0.09999999999999987 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,2,a,2.0625,2.0824999809265137,True,1.506490071578881e-11,4.0,2.0622694400311663,2.082269440031173,2.0625,2.0625,2.0825,2.0825,0.0,0.0 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,3,word,2.122499942779541,2.442500114440918,True,2.1203724269013707e-13,0.25,2.122499953395551,2.4426974718634,2.1225,2.1225,2.4425,2.4425,0.0,0.0 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,4,in,2.5225000381469727,2.702500104904175,True,7.434052830788962e-13,0.8034750819206238,2.584625951615478,2.729305029738961,2.5225,2.6825,2.7025,2.8225,0.16000000000000014,0.11999999999999966 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,5,the,2.802500009536743,2.9024999141693115,True,3.7196781028578374e-13,0.40202412009239197,2.8131936626394123,2.9242575602781646,2.8025,2.9225,2.9025,3.1425,0.11999999999999966,0.2400000000000002 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,6,last,2.922499895095825,3.202500104904175,True,1.1070697310266997e-12,1.1965248584747314,2.9627315540783767,3.240944821647639,2.9225,3.3625,3.2025,3.6225,0.43999999999999995,0.41999999999999993 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,7,clip,3.362499952316284,3.622499942779541,True,4.579349486416584e-12,4.0,3.3990179872718147,3.655597836538976,3.3625,3.7625,3.6225,3.9825,0.40000000000000036,0.3599999999999999 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,8,called,3.682499885559082,4.042500019073486,True,3.3319351509623896e-13,0.36011672019958496,3.721438804024425,4.085925612332038,3.6825,4.1025,4.0425,4.522500000000001,0.41999999999999993,0.4800000000000004 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,9,"'monotone',",4.102499961853027,4.962500095367432,True,2.0431005498533494e-10,4.0,4.159192072906399,5.018715781241488,4.1025,4.562500000000001,4.9625,5.5025,0.46000000000000085,0.54 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,10,and,5.042500019073486,5.542500019073486,True,1.1826091050447934e-13,0.25,5.092525670092953,5.5518883043060585,5.0425,5.5825000000000005,5.522500000000001,5.702500000000001,0.54,0.17999999999999972 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,11,I,5.582499980926514,5.602499961853027,True,7.732506995816735e-11,4.0,5.606475013180348,5.626475013180339,5.5825000000000005,5.8425,5.602500000000001,5.862500000000001,0.2599999999999998,0.2599999999999998 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,12,want,5.622499942779541,5.862500190734863,True,5.911523983000155e-13,0.6389195919036865,5.658054633318278,5.887746639201687,5.6225000000000005,5.8825,5.862500000000001,6.102500000000001,0.2599999999999998,0.2400000000000002 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,13,to,6.022500038146973,6.102499961853027,True,3.9711322338126243e-13,0.4292013645172119,6.043176971260156,6.1243497078647895,6.022500000000001,6.2625,6.102500000000001,6.3425,0.23999999999999932,0.23999999999999932 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,14,talk,6.202499866485596,6.422500133514404,True,3.8754988259358247e-13,0.41886529326438904,6.231623776195076,6.445624482990393,6.202500000000001,6.522500000000001,6.4225,6.6825,0.3200000000000003,0.2599999999999998 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,15,about,6.462500095367432,6.682499885559082,True,1.5894668122917038e-13,0.25,6.486890400692468,6.713296690480922,6.442500000000001,6.742500000000001,6.6825,6.982500000000001,0.2999999999999998,0.3000000000000007 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,16,that,6.922500133514404,7.182499885559082,True,2.632421711168398e-11,4.0,6.914653107260793,7.186191805860277,6.8825,7.0425,7.1825,7.2225,0.16000000000000014,0.040000000000000036 +-UUCSKoHeMA/0,-UUCSKoHeMA,0,17,briefly.,7.28249979019165,7.682499885559082,True,2.8430669277157428e-12,3.0727968215942383,7.266711655048036,7.682512766971292,7.2225,7.282500000000001,7.6825,7.6825,0.0600000000000005,0.0 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,0,going,0.0024999999441206455,0.18250000476837158,True,5.097316457813861e-10,1.124098539352417,0.024398001194100988,0.2924496876375644,0.0025000000000000005,0.0825,0.2025,0.4225,0.08,0.21999999999999997 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,1,to,0.20250000059604645,0.26249998807907104,True,4.4608275406865516e-10,0.983735203742981,0.3627568244570231,0.44950644808341267,0.2425,0.5025,0.3225,0.6024999999999999,0.25999999999999995,0.2799999999999999 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,2,get,0.32249999046325684,0.48249998688697815,True,4.529311370404798e-10,0.9988377690315247,0.5278888053411263,0.7010825325354665,0.3625,0.7025,0.5025,0.9824999999999999,0.34,0.48 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,3,married,0.6625000238418579,1.402500033378601,True,4.135821685125052e-10,0.9120624661445618,0.8307791916512809,1.3855115536618379,0.5625,1.1824999999999999,1.0425,1.5825,0.6199999999999999,0.54 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,4,or,1.4225000143051147,1.5225000381469727,True,4.414137388941697e-10,0.9734387397766113,1.4655582811151127,1.5522323688932067,1.2025,1.6824999999999999,1.3025,1.7625,0.48,0.45999999999999996 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,5,are,1.6825000047683716,1.8025000095367432,True,6.311645650569631e-10,1.3918914794921875,1.633247732983863,1.7776768200035915,1.3825,1.8225,1.5425,1.9625,0.43999999999999995,0.41999999999999993 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,6,already,1.8224999904632568,2.0824999809265137,True,4.5398515502448333e-10,1.0011621713638306,1.84121973750598,2.23857055338298,1.6425,2.0025,2.0425,2.3825,0.3599999999999999,0.33999999999999986 +-ri04Z7vwnc/0,-ri04Z7vwnc,0,7,married,2.182499885559082,2.7225000858306885,True,4.677451204138094e-10,1.0315066576004028,2.3092338374060906,2.7215355637832084,2.1425,2.4425,2.6625,2.7425,0.2999999999999998,0.08000000000000007 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,0,most,0.042500000447034836,0.2824999988079071,True,3.2669008557389967e-12,0.9973236918449402,0.03533530632279461,0.2915191734222421,0.0025000000000000005,0.0825,0.1625,0.3425,0.08,0.18000000000000002 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,1,people,0.3824999928474426,0.8424999713897705,True,3.1715836554258026e-12,0.9682251214981079,0.37951785526938786,0.8040705105858642,0.3425,0.4225,0.6224999999999999,0.8825,0.07999999999999996,0.26 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,2,think,0.8824999928474426,1.3025000095367432,True,1.2376642679473582e-12,0.377835750579834,0.880992595479909,1.2249863793838607,0.6825,0.9225,0.8825,1.3425,0.24,0.4600000000000001 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,3,it'll,1.402500033378601,1.7825000286102295,True,2.4132093545681244e-10,4.0,1.3095751724347637,1.530903636824568,0.9225,1.4025,1.3025,1.7825,0.4800000000000001,0.48 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,4,sort,1.8624999523162842,2.302500009536743,True,4.662647004605169e-12,1.4234188795089722,1.606748818471774,1.8158763538890752,1.3825,1.8625,1.6824999999999999,2.0825,0.48,0.40000000000000013 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,5,itself,2.322499990463257,2.5425000190734863,True,2.164716756541951e-12,0.660847544670105,1.8871830849169948,2.3170325866349173,1.8425,2.1625,2.1625,2.4625,0.32000000000000006,0.2999999999999998 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,6,"out,",2.5625,2.702500104904175,True,1.7914156486345534e-12,0.5468856692314148,2.372672664661856,2.4993875621536525,2.2225,2.4825,2.3625,2.6025,0.2599999999999998,0.2400000000000002 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,7,"""we'll",2.7225000858306885,2.862499952316284,True,7.49354953089032e-11,4.0,2.5485761578230206,2.735453096562189,2.4025,2.6225,2.5825,2.8025,0.2200000000000002,0.2200000000000002 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,8,discuss,2.882499933242798,3.1424999237060547,True,1.244877790261556e-12,0.38003790378570557,2.769634619145668,3.0783780752313397,2.6025,2.8425,2.9625,3.1425,0.23999999999999977,0.18000000000000016 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,9,it,3.1624999046325684,3.2225000858306885,True,3.2844339227511288e-12,1.002676248550415,3.1168374269808057,3.182508050326935,3.0225,3.1625,3.1025,3.2425,0.14000000000000012,0.14000000000000012 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,10,"later,""",3.242500066757202,3.422499895095825,True,6.055528040810332e-12,1.8486393690109253,3.213576245227149,3.4151321092630402,3.1425,3.2825,3.3425,3.5025,0.14000000000000012,0.16000000000000014 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,11,it's,3.442500114440918,3.5425000190734863,True,1.0349616302862685e-10,4.0,3.451680714649028,3.576908987243269,3.3625,3.5425,3.4825,3.7225,0.18000000000000016,0.2400000000000002 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,12,not,3.5625,3.702500104904175,True,1.5995723625858438e-12,0.4883195161819458,3.6143920521257327,3.7361958558643753,3.5225,3.7825,3.6425,3.9025,0.26000000000000023,0.2599999999999998 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,13,something,3.742500066757202,4.422500133514404,True,2.2604188486263777e-12,0.6900635957717896,3.777755699176747,4.436873888478261,3.7025,3.9625,4.402500000000001,4.4625,0.2599999999999998,0.05999999999999961 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,14,too,4.84250020980835,5.022500038146973,True,2.015573125069281e-10,4.0,4.78410811013368,4.995321876065659,4.482500000000001,4.8425,4.942500000000001,5.022500000000001,0.35999999999999943,0.08000000000000007 +-ri04Z7vwnc/2,-ri04Z7vwnc,2,15,important,5.042500019073486,5.542500019073486,True,5.276962460748491e-12,1.6109578609466553,5.042487498132745,5.543272605933794,5.0425,5.0425,5.5425,5.5425,0.0,0.0 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,0,"""",nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-ri04Z7vwnc/5,-ri04Z7vwnc,5,1,So,0.02250000089406967,0.08250000327825546,True,5.531704955208383e-11,4.0,0.06342992056271926,0.14143729395540497,0.0225,0.2225,0.0825,0.28250000000000003,0.2,0.2 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,2,I,0.2224999964237213,0.24250000715255737,True,1.6104359599339313e-12,0.4176913797855377,0.303244394241129,0.3232443942411471,0.2225,0.5225,0.2425,0.5425,0.29999999999999993,0.3 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,3,think,0.5224999785423279,0.8025000095367432,True,8.501941013185077e-13,0.25,0.5468122658585075,0.7930804306754985,0.5225,0.6425,0.7424999999999999,0.8424999999999999,0.12,0.09999999999999998 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,4,it's,0.8824999928474426,1.0824999809265137,True,3.3593516857166605e-11,4.0,0.8827280561963028,1.0827702576220137,0.8825,0.8825,1.0825,1.0825,0.0,0.0 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,5,important,1.162500023841858,1.662500023841858,True,6.419234935273188e-12,1.6649274826049805,1.1539397855459228,1.6509180681704647,1.1225,1.2225,1.5425,1.7225,0.09999999999999987,0.17999999999999994 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,6,to,2.322499990463257,2.4625000953674316,True,3.383222955261056e-12,0.8774909973144531,2.098755755525236,2.258181340358846,1.6625,2.3225,1.7225,2.4625,0.6599999999999997,0.74 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,7,discuss,2.5225000381469727,2.862499952316284,True,2.7650663876610526e-12,0.717162549495697,2.4394224473580834,2.792790803676593,2.3025,2.5225,2.6625,2.8625,0.21999999999999975,0.19999999999999973 +-ri04Z7vwnc/5,-ri04Z7vwnc,5,8,finances,2.9024999141693115,3.322499990463257,True,4.327905221701567e-12,1.1225088834762573,2.866859719198108,3.2956421389284056,2.8025,2.9025,3.2225,3.4225,0.09999999999999964,0.19999999999999973 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,0,But,0.5625,0.7024999856948853,True,2.1161275043455469e-13,1.0,0.5496646247778796,0.702164602009161,0.5425,0.5625,0.7025,0.7025,0.020000000000000018,0.0 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,1,the,0.8424999713897705,1.402500033378601,True,6.26251817330975e-13,2.959423780441284,0.8420559143387191,1.406478256178167,0.8225,0.9225,1.4025,1.4224999999999999,0.09999999999999998,0.019999999999999796 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,2,hardest,1.4824999570846558,1.8424999713897705,True,1.8739304270647128e-13,0.8855470418930054,1.4825189926134468,1.8518094365299989,1.4825,1.4825,1.8425,1.8825,0.0,0.040000000000000036 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,3,thing,2.0225000381469727,2.262500047683716,True,8.017903425612885e-14,0.378895103931427,2.020780201902659,2.2611176783830214,2.0225,2.0225,2.2625,2.2625,0.0,0.0 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,4,in,2.322499990463257,2.422499895095825,True,6.493226502269842e-14,0.3068447709083557,2.320865793192878,2.422328440790031,2.3225,2.3225,2.4225,2.4825,0.0,0.06000000000000005 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,5,life,2.6024999618530273,3.202500104904175,True,2.1193372848771902e-13,1.0015168190002441,2.600471167683731,3.1896348019912866,2.6025,2.6025,3.2025,3.2025,0.0,0.0 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,6,to,3.262500047683716,3.3424999713897705,True,6.471526873413902e-14,0.3058193325996399,3.2608217425607964,3.3421634910399116,3.2625,3.2625,3.3425,3.3425,0.0,0.0 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,7,"learn,",3.4024999141693115,3.6624999046325684,True,3.52563437428996e-13,1.6660784482955933,3.4027175839840345,3.66329101504063,3.4025,3.4025,3.6625,3.6625,0.0,0.0 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,8,is,3.802500009536743,3.882499933242798,True,1.9704459689341008e-13,0.9311565160751343,3.80444740581124,3.884674702639147,3.8025,3.8025,3.8825,3.8825,0.0,0.0 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,9,to,3.9825000762939453,4.042500019073486,True,4.005100016826052e-13,1.892655372619629,3.973553794154936,4.04829152917298,3.9425,4.0025,4.0025,4.1225000000000005,0.0600000000000005,0.1200000000000001 +-s9qJ7ATP7w/1,-s9qJ7ATP7w,1,10,lose,4.222499847412109,4.502500057220459,True,8.517983193789824e-12,4.0,4.222786002066446,4.50249136136073,4.2225,4.2225,4.5025,4.5025,0.0,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,0,they,0.042500000447034836,0.24250000715255737,True,1.2452759092992927e-12,1.144152045249939,0.035296410608304025,0.24507960324400196,0.0225,0.0625,0.2225,0.3025,0.04,0.07999999999999999 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,1,have,0.2824999988079071,0.5425000190734863,True,9.242065663120358e-13,0.8491554260253906,0.30454331855208594,0.5638608046103386,0.28250000000000003,0.3425,0.5425,0.6024999999999999,0.06,0.05999999999999994 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,2,"doubt,",0.7024999856948853,0.9225000143051147,True,2.921006535608339e-13,0.2683803141117096,0.7016751768490946,0.9389234569792527,0.7025,0.7025,0.9225,0.9824999999999999,0.0,0.05999999999999994 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,3,they,1.0824999809265137,1.3025000095367432,True,2.414696914643244e-12,2.218608856201172,1.0824749234219044,1.3025575291805016,1.0825,1.0825,1.3025,1.3025,0.0,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,4,have,1.402500033378601,1.8424999713897705,True,1.4843991921059674e-12,1.3638570308685303,1.480454771743787,1.8441928116392656,1.4025,1.5825,1.8425,1.8625,0.17999999999999994,0.020000000000000018 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,5,"fear,",1.8624999523162842,2.0824999809265137,True,6.6919907115714494e-12,4.0,1.8672921296696843,2.08198887608499,1.8625,1.9025,2.0825,2.0825,0.040000000000000036,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,6,they,2.122499942779541,2.2825000286102295,True,7.773068213395851e-13,0.7141848206520081,2.1272049813809994,2.285785138186709,2.1225,2.1625,2.2625,2.3225,0.040000000000000036,0.05999999999999961 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,7,lose,2.302500009536743,2.4825000762939453,True,2.6457091725773374e-12,2.430861711502075,2.3155930936973776,2.470759112376862,2.3025,2.3425,2.4425,2.5025,0.03999999999999959,0.06000000000000005 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,8,in,2.502500057220459,2.5824999809265137,True,1.923453930852137e-11,4.0,2.5130796331063547,2.582583582398577,2.4825,2.5225,2.5825,2.5825,0.040000000000000036,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,9,a,2.622499942779541,2.6424999237060547,True,2.0894479722810555e-12,1.9197721481323242,2.622205727070115,2.6422057270701145,2.6225,2.6225,2.6425,2.6425,0.0,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,10,Ferrari,2.6624999046325684,3.0824999809265137,True,4.712646288831945e-13,0.43299511075019836,2.680606250238554,3.083650895889502,2.6625,2.7025,3.0825,3.0825,0.040000000000000036,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,11,"race,",3.1024999618530273,3.242500066757202,True,9.314907786078797e-13,0.8558481335639954,3.103672235105714,3.2438796035307136,3.1025,3.1025,3.2425,3.2425,0.0,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,12,or,3.262500047683716,3.3424999713897705,True,4.8605338504037476e-11,4.0,3.264086176296221,3.344207480546319,3.2625,3.2625,3.3425,3.3425,0.0,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,13,they,3.422499895095825,3.682499885559082,True,2.5745997347947913e-11,4.0,3.414911960971616,3.675032305819791,3.3625,3.4225,3.6425,3.6825,0.06000000000000005,0.040000000000000036 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,14,lose,3.7825000286102295,3.942500114440918,True,7.575693002602468e-13,0.6960501074790955,3.7616974887882315,3.920602352332232,3.7225,3.7825,3.8825,3.9425,0.06000000000000005,0.06000000000000005 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,15,in,4.102499961853027,4.162499904632568,True,3.397961165912955e-12,3.122026205062866,4.0719655131892,4.156779322130816,3.9225,4.1025,4.1225000000000005,4.1825,0.18000000000000016,0.05999999999999961 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,16,a,4.202499866485596,4.222499847412109,True,5.129190258287841e-13,0.47126689553260803,4.214525556613766,4.23452555661377,4.202500000000001,4.2225,4.2225,4.242500000000001,0.019999999999999574,0.020000000000000462 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,17,"race,",4.522500038146973,4.78249979019165,True,8.075219095834973e-13,0.741946280002594,4.523863360616268,4.783031253821107,4.522500000000001,4.522500000000001,4.782500000000001,4.782500000000001,0.0,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,18,and,5.182499885559082,5.322500228881836,True,2.4335565572235207e-13,0.25,5.142079904620651,5.314934950906367,4.8025,5.1825,5.242500000000001,5.3425,0.3799999999999999,0.09999999999999964 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,19,then,5.422500133514404,5.5625,True,1.1495937936398942e-13,0.25,5.406993962189282,5.55731323856257,5.3025,5.4225,5.522500000000001,5.562500000000001,0.1200000000000001,0.040000000000000036 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,20,they,5.582499980926514,5.762499809265137,True,1.4886081950438168e-11,4.0,5.582500046565337,5.7607591757751635,5.5825000000000005,5.5825000000000005,5.742500000000001,5.7625,0.0,0.019999999999999574 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,21,just,5.78249979019165,5.922500133514404,True,1.4744784169670733e-12,1.3547419309616089,5.782499967123763,5.922500201867736,5.782500000000001,5.782500000000001,5.9225,5.9225,0.0,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,22,give,5.962500095367432,6.162499904632568,True,2.479647346828595e-13,0.25,5.962426812392603,6.162335078542887,5.9625,5.9625,6.1625000000000005,6.1625000000000005,0.0,0.0 +-s9qJ7ATP7w/0,-s9qJ7ATP7w,0,23,up,6.642499923706055,6.702499866485596,True,5.418672780442557e-13,0.49786439538002014,6.61413642460844,6.68734623928928,6.5825000000000005,6.642500000000001,6.6625000000000005,6.702500000000001,0.0600000000000005,0.040000000000000036 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,0,I,0.0024999999441206455,0.02250000089406967,True,8.043445250127679e-12,4.0,0.0032990285590143776,0.023299028559016173,0.0025000000000000005,0.0025000000000000005,0.0225,0.0225,0.0,0.0 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,1,have,0.08250000327825546,0.42250001430511475,True,3.238681241593544e-12,4.0,0.06717380191828314,0.32357469353523305,0.0425,0.1225,0.1825,0.4225,0.07999999999999999,0.24 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,2,been,0.5224999785423279,0.7425000071525574,True,1.3483621771198662e-12,2.748244285583496,0.3951901849667031,0.6275678443671301,0.2225,0.5225,0.4225,0.7424999999999999,0.29999999999999993,0.31999999999999995 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,3,beat,0.7825000286102295,1.3424999713897705,True,1.4721684700284843e-13,0.3000587522983551,0.6899705310710409,1.079888780943723,0.5225,1.1225,0.7424999999999999,1.3425,0.6000000000000001,0.6000000000000001 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,4,up,1.3624999523162842,1.4225000143051147,True,6.7126171158019e-13,1.3681719303131104,1.1659770402041265,1.3613713122992432,0.7825,1.3625,1.2425,1.4224999999999999,0.5800000000000001,0.17999999999999994 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,5,and,1.462499976158142,1.6024999618530273,True,2.956292166362423e-13,0.602554202079773,1.4205737927255522,1.5482913645398126,1.3225,1.4625,1.4224999999999999,1.6025,0.1399999999999999,0.18000000000000016 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,6,put,1.7424999475479126,1.9424999952316284,True,5.560912516057448e-13,1.1334303617477417,1.6589005375801091,1.842611262769312,1.4625,1.7425,1.6025,2.0025,0.28,0.3999999999999999 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,7,down,2.0425000190734863,2.442500114440918,True,8.62298581605532e-14,0.25,1.9559455563234505,2.310078948483982,1.7425,2.0425,2.0025,2.4425,0.30000000000000004,0.43999999999999995 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,8,and,2.5824999809265137,2.702500104904175,True,1.233855411505308e-13,0.25148555636405945,2.5125746937182574,2.693039630571944,2.3225,2.6025,2.6025,2.7025,0.28000000000000025,0.10000000000000009 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,9,everything,2.8424999713897705,3.9825000762939453,True,5.351290564099484e-14,0.25,2.8684364082492393,4.011810221786433,2.8425,2.8425,3.9825,3.9825,0.0,0.0 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,10,that,4.902500152587891,5.122499942779541,True,5.439115737665423e-12,4.0,4.89797082813463,5.13239484504563,4.902500000000001,4.9625,5.102500000000001,5.1625000000000005,0.05999999999999961,0.05999999999999961 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,11,can,5.162499904632568,5.34250020980835,True,4.8560754619926885e-14,0.25,5.188221176465659,5.361559915166783,5.1625000000000005,5.3825,5.2625,5.5025,0.21999999999999975,0.2400000000000002 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,12,go,5.422500133514404,5.502500057220459,True,1.665226523296301e-13,0.3394080102443695,5.454580933666803,5.539748928566693,5.4225,5.602500000000001,5.5025,5.702500000000001,0.1800000000000006,0.20000000000000018 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,13,"wrong,",5.602499961853027,6.202499866485596,True,4.906267449603097e-13,1.0,5.65194480101253,6.236338881255996,5.602500000000001,6.1225000000000005,6.142500000000001,6.8025,0.5199999999999996,0.6599999999999993 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,14,has,6.702499866485596,6.802499771118164,True,7.809464338225103e-13,1.5917322635650635,6.7180709524906215,6.819550494578619,6.702500000000001,6.942500000000001,6.8025,7.062500000000001,0.2400000000000002,0.2600000000000007 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,15,gone,6.862500190734863,7.0625,True,6.044744240742139e-14,0.25,6.884818614020353,7.0893755044610485,6.862500000000001,7.142500000000001,7.062500000000001,7.4225,0.28000000000000025,0.35999999999999943 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,16,wrong,7.28249979019165,7.582499980926514,True,6.222165794753098e-13,1.2682076692581177,7.27870407791671,7.598153728057217,7.142500000000001,7.482500000000001,7.5825000000000005,7.8025,0.33999999999999986,0.21999999999999975 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,17,for,7.662499904632568,7.802499771118164,True,2.2805403941152103e-13,0.46482187509536743,7.688982736794739,7.83358602588385,7.6625000000000005,8.022499999999999,7.8025,8.202499999999999,0.35999999999999854,0.3999999999999986 +-s9qJ7ATP7w/5,-s9qJ7ATP7w,5,18,me,8.142499923706055,8.262499809265137,True,6.399445209859245e-12,4.0,8.149809329284016,8.26073298564643,8.1425,8.2425,8.2425,8.362499999999999,0.09999999999999964,0.11999999999999922 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,0,I,0.02250000089406967,0.042500000447034836,True,2.5145097115597537e-10,4.0,0.022581619903897353,0.04258161990389827,0.0225,0.0225,0.0425,0.0425,0.0,0.0 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,1,have,0.10249999910593033,0.32249999046325684,True,5.2369983349898064e-11,4.0,0.10275901230479557,0.3234319644678103,0.10250000000000001,0.10250000000000001,0.3225,0.3225,0.0,0.0 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,2,lost,0.4025000035762787,0.8025000095367432,True,4.580078720797798e-13,1.0,0.5590338658826747,0.8117400282480208,0.4025,0.6224999999999999,0.7825,0.8624999999999999,0.21999999999999992,0.07999999999999996 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,3,at,0.9024999737739563,1.0425000190734863,True,8.964015510773415e-13,1.9571750164031982,0.937330588114691,1.0553245531559798,0.9025,1.0225,1.0425,1.0825,0.12,0.040000000000000036 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,4,everything,1.3224999904632568,2.0824999809265137,True,2.723942219787917e-13,0.5947369933128357,1.323579559459154,2.0836404722492556,1.3225,1.3425,2.0825,2.0825,0.020000000000000018,0.0 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,5,you,2.182499885559082,2.362499952316284,True,1.1392326155785365e-13,0.25,2.166667845312565,2.364468039998308,2.1425,2.1825,2.3625,2.3625,0.040000000000000036,0.0 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,6,can,2.5225000381469727,2.702500104904175,True,1.9086615222888882e-14,0.25,2.5339093670209367,2.762821360795334,2.4825,2.6225,2.7025,2.8025,0.14000000000000012,0.10000000000000009 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,7,"imagine,",3.002500057220459,3.382499933242798,True,3.490432942676591e-11,4.0,2.9764326793531897,3.3827679885419752,2.8825,3.0025,3.3825,3.3825,0.1200000000000001,0.0 +-s9qJ7ATP7w/4,-s9qJ7ATP7w,4,8,seriously,3.442500114440918,4.022500038146973,True,2.7026327681888007e-13,0.5900843739509583,3.4400904252806708,4.025070808901028,3.4225,3.4425,4.022500000000001,4.022500000000001,0.020000000000000018,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,0,I,0.02250000089406967,0.042500000447034836,True,6.969980148596733e-11,4.0,0.02678660345931201,0.04678660345934946,0.0225,0.10250000000000001,0.0425,0.1225,0.08000000000000002,0.07999999999999999 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,1,used,0.3824999928474426,0.5425000190734863,True,3.881826110552211e-11,4.0,0.35018109647684703,0.5409254689733906,0.10250000000000001,0.3825,0.5425,0.5425,0.28,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,2,to,0.5625,0.6225000023841858,True,5.419344834001194e-11,4.0,0.5617484066259408,0.6218305196632183,0.5625,0.5625,0.6224999999999999,0.6224999999999999,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,3,work,0.6424999833106995,0.7825000286102295,True,1.2994504560923104e-13,0.25,0.6439510150136057,0.7956763526640003,0.6425,0.6425,0.7825,0.8225,0.0,0.040000000000000036 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,4,for,0.862500011920929,0.9825000166893005,True,5.919409927501729e-13,0.25,0.8703185545526655,0.9934280704856465,0.8624999999999999,0.9025,0.9824999999999999,1.0425,0.040000000000000036,0.06000000000000005 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,5,Warren,1.0425000190734863,1.3624999523162842,True,2.076905487868874e-12,0.55162113904953,1.0499859516799703,1.362546218062043,1.0425,1.0825,1.3625,1.3625,0.040000000000000036,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,6,"Avis,",1.4424999952316284,1.6825000047683716,True,5.145964557251581e-11,4.0,1.441602626222574,1.6811464831337093,1.4425,1.4425,1.6824999999999999,1.6824999999999999,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,7,the,1.7024999856948853,1.9824999570846558,True,7.724032351219545e-12,2.0514845848083496,1.7012855259737578,1.9803489043794023,1.7025,1.7025,1.9825,1.9825,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,8,guy,2.0225000381469727,2.1424999237060547,True,1.3621283788400884e-11,3.6177804470062256,2.0202241581787876,2.141641797729933,2.0225,2.0225,2.1425,2.1425,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,9,who,2.1624999046325684,2.262500047683716,True,1.5639521622201613e-10,4.0,2.1618504322195777,2.2658099313974582,2.1625,2.1625,2.2625,2.2825,0.0,0.020000000000000018 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,10,started,2.302500009536743,2.5625,True,3.76403162111183e-12,0.9997177720069885,2.301007069455703,2.562164512343847,2.3025,2.3025,2.5625,2.5625,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,11,Avis,2.6024999618530273,2.7825000286102295,True,1.6464942256821935e-11,4.0,2.6021628830951244,2.7711338037144446,2.6025,2.6025,2.7425,2.7825,0.0,0.040000000000000036 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,12,Rent,2.802500009536743,3.002500057220459,True,3.706247982127042e-12,0.9843705892562866,2.799981994850341,2.994845622631275,2.7825,2.8225,2.9625,3.0025,0.03999999999999959,0.040000000000000036 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,13,a,3.0225000381469727,3.0425000190734863,True,6.146569798276547e-13,0.25,3.014930168179437,3.034930168179444,2.9825,3.0225,3.0025,3.0425,0.040000000000000036,0.040000000000000036 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,14,"Car,",3.0625,3.1624999046325684,True,6.6249657669492645e-12,1.7595750093460083,3.062430806341528,3.1624378407080567,3.0625,3.0625,3.1625,3.1625,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,15,and,3.182499885559082,3.302500009536743,True,1.0457030207022822e-12,0.27773621678352356,3.1825015875733373,3.2987676736960596,3.1825,3.1825,3.2825,3.3025,0.0,0.020000000000000018 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,16,he,3.3424999713897705,3.4024999141693115,True,1.69514088096262e-12,0.4502253532409668,3.3416142026375746,3.402494144256177,3.3425,3.3425,3.4025,3.4025,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,17,said,3.442500114440918,3.622499942779541,True,7.551881754490342e-13,0.25,3.442500007657619,3.6225138017818206,3.4425,3.4425,3.6225,3.6225,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,18,to,3.702500104904175,3.762500047683716,True,1.4711676497793265e-14,0.25,3.6993621761372792,3.7652132808598355,3.6625,3.7425,3.7625,3.8025,0.08000000000000007,0.040000000000000036 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,19,me,3.882499933242798,3.9625000953674316,True,3.844036200462142e-12,1.0209667682647705,3.882508254724707,3.9624960997761027,3.8825,3.8825,3.9625,3.9625,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,20,one,4.022500038146973,4.182499885559082,True,4.8639130917349505e-12,1.2918436527252197,4.022505987413522,4.182510136166168,4.022500000000001,4.022500000000001,4.1825,4.1825,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,21,"day,",4.922500133514404,5.042500019073486,True,8.347099920980039e-12,2.2169697284698486,4.921261247051621,5.042292247022992,4.9225,4.9225,5.0425,5.0425,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,22,"""Robert,",5.162499904632568,5.442500114440918,True,3.313618097359333e-13,0.25,5.157729190413535,5.437921281142969,5.1225000000000005,5.1625000000000005,5.402500000000001,5.442500000000001,0.040000000000000036,0.040000000000000036 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,23,"""what's",5.502500057220459,5.802499771118164,True,2.250095726061274e-12,0.5976200699806213,5.493928773068351,5.787613456780464,5.4225,5.5025,5.6625000000000005,5.8025,0.08000000000000007,0.13999999999999968 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,24,the,5.822500228881836,5.922500133514404,True,2.3816506492663203e-13,0.25,5.8117797173499195,5.916011727614231,5.7225,5.822500000000001,5.862500000000001,5.9225,0.10000000000000053,0.05999999999999961 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,25,purpose,5.942500114440918,6.28249979019165,True,1.1442309773290749e-11,3.0390501022338867,5.94251287266894,6.286029911061819,5.942500000000001,5.942500000000001,6.282500000000001,6.322500000000001,0.0,0.040000000000000036 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,26,of,6.362500190734863,6.442500114440918,True,3.76615709105077e-12,1.0002822875976562,6.3626166902528665,6.4423161972541,6.362500000000001,6.362500000000001,6.442500000000001,6.442500000000001,0.0,0.0 +-s9qJ7ATP7w/7,-s9qJ7ATP7w,7,27,business,6.462500095367432,6.822500228881836,True,2.3635134648036793e-12,0.6277435421943665,6.462403766646239,6.821232931946638,6.4625,6.4625,6.8025,6.822500000000001,0.0,0.020000000000000462 +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,0,But,0.042500000447034836,0.2224999964237213,True,6.265210247304032e-13,0.2663658559322357,0.04595421401102171,0.19960157519223576,0.0025000000000000005,0.10250000000000001,0.1225,0.28250000000000003,0.1,0.16000000000000003 +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,1,I,0.26249998807907104,0.2824999988079071,True,4.512839754666764e-13,0.25,0.3053911111772659,0.3253911111772663,0.2625,0.6625,0.28250000000000003,0.6825,0.39999999999999997,0.39999999999999997 +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,2,just,0.6625000238418579,1.402500033378601,True,9.192134033109145e-12,3.9080424308776855,0.6529190020049375,1.3804359304662248,0.5625,1.0025,1.2825,1.4025,0.43999999999999995,0.1200000000000001 +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,3,kept,1.4824999570846558,1.6425000429153442,True,2.3521070074278283e-12,1.0,1.4731671348482018,1.634072464256062,1.3425,1.4825,1.5425,1.6425,0.1399999999999999,0.10000000000000009 +-s9qJ7ATP7w/6,-s9qJ7ATP7w,6,4,going,1.7024999856948853,2.262500047683716,True,6.741932099402215e-12,2.866337299346924,1.7043089382694716,2.2765034438543106,1.7025,1.7025,2.2625,2.3025,0.0,0.040000000000000036 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,0,"""",nan,nan,False,0.0,nan,nan,nan,nan,nan,nan,nan,nan,nan +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,1,And,0.12250000238418579,0.24250000715255737,True,5.430787416993432e-11,2.974587917327881,0.13211225042789249,0.25671074886264156,0.1225,0.1625,0.2425,0.3425,0.04000000000000001,0.10000000000000003 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,2,I,0.32249999046325684,0.3425000011920929,True,2.400587367779039e-11,1.3148661851882935,0.3668057281520321,0.3868057281532408,0.3225,0.5225,0.3425,0.5425,0.19999999999999996,0.19999999999999996 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,3,"said,",0.5224999785423279,0.7225000262260437,True,2.0516449650287427e-11,1.1237410306930542,0.5449670600283814,0.7418337194054421,0.5225,0.6625,0.6825,0.9025,0.14,0.21999999999999997 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,4,"""Oh,",0.8224999904632568,0.9024999737739563,True,1.968307895144905e-12,0.25,0.8328528775409426,0.9142629965513558,0.7825,0.9824999999999999,0.9025,1.0425,0.19999999999999996,0.14 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,5,make,0.9825000166893005,1.2625000476837158,True,1.3614405436346289e-10,4.0,0.9900671560139473,1.2648433600608693,0.9225,1.0825,1.2625,1.2625,0.16000000000000003,0.0 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,6,a,1.3424999713897705,1.3624999523162842,True,1.5998102148584437e-11,0.8762589693069458,1.342202284908815,1.36220228490884,1.3425,1.3425,1.3625,1.3625,0.0,0.0 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,7,"profit,",1.3825000524520874,1.8624999523162842,True,1.0078236856170264e-11,0.5520120859146118,1.3882990201214693,1.8605397868103712,1.3825,1.4224999999999999,1.8625,1.8625,0.039999999999999813,0.0 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,8,and,1.902500033378601,2.002500057220459,True,2.559467611809585e-12,0.25,1.9024795079759782,2.002565711600564,1.9025,1.9025,2.0025,2.0025,0.0,0.0 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,9,all,2.0625,2.1624999046325684,True,1.0053620262684415e-11,0.5506637692451477,2.0632850578056883,2.1639649354818697,2.0625,2.0625,2.1625,2.1625,0.0,0.0 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,10,these,2.202500104904175,2.382499933242798,True,1.4980766193523065e-12,0.25,2.2033509669407514,2.3840730034618955,2.2025,2.2025,2.3825,2.3825,0.0,0.0 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,11,other,2.4825000762939453,2.742500066757202,True,4.946603543443118e-11,2.7093875408172607,2.4818356624233613,2.7605229751379516,2.4825,2.4825,2.7425,2.7825,0.0,0.040000000000000036 +-s9qJ7ATP7w/8,-s9qJ7ATP7w,8,12,things,2.762500047683716,3.122499942779541,True,4.533611680512806e-11,2.4831807613372803,2.795081236142752,3.131064936710411,2.7625,2.8425,3.1225,3.1625,0.07999999999999963,0.040000000000000036 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,0,it,0.48249998688697815,0.5625,True,2.2540422653372083e-11,0.62372887134552,0.48282851572821867,0.5627058230843515,0.4825,0.4825,0.5625,0.5625,0.0,0.0 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,1,comes,0.5824999809265137,0.8224999904632568,True,4.899627231713666e-11,1.3558037281036377,0.6122922089193678,0.8890952566150813,0.5824999999999999,0.6224999999999999,0.8025,1.1025,0.040000000000000036,0.30000000000000004 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,2,with,0.862500011920929,1.1024999618530273,True,5.177407114143051e-11,1.432669758796692,1.0343328058467511,1.2714862000398628,0.8624999999999999,2.0425,1.1025,2.3825,1.1800000000000002,1.2799999999999998 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,3,the,1.162500023841858,2.1424999237060547,True,1.6085549559008427e-11,0.4451123774051666,1.7534948157635741,2.317185306234759,1.1624999999999999,2.5025,2.1425,2.8225,1.34,0.6799999999999997 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,4,assistance,2.242500066757202,3.4625000953674316,True,5.7605586967213185e-11,1.5940369367599487,2.4377709212653507,3.5095971681953815,2.2425,2.9625,3.4025,3.6225,0.7199999999999998,0.2200000000000002 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,5,and,3.4825000762939453,3.5824999809265137,True,1.789636147608853e-11,0.4952203929424286,4.0819872324546465,4.286099413915198,3.4425,4.5425,3.5625,4.8425,1.1000000000000005,1.2800000000000002 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,6,agitation,4.542500019073486,5.402500152587891,True,5.5601932780202645e-11,1.5385926961898804,4.775625557132102,5.481898357717567,4.5425,5.0825000000000005,5.402500000000001,5.6625000000000005,0.54,0.2599999999999998 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,7,of,5.482500076293945,5.602499961853027,True,9.260540945188467e-11,2.5625369548797607,5.806335671074142,5.92265445706831,5.482500000000001,6.482500000000001,5.602500000000001,6.6225000000000005,1.0,1.0199999999999996 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,8,states,6.482500076293945,6.982500076293945,True,5.0344433483173745e-11,1.3931094408035278,6.551695071292202,6.893363711888713,6.482500000000001,6.8025,6.7225,7.0825000000000005,0.3199999999999994,0.3600000000000003 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,9,and,7.102499961853027,7.822500228881836,True,1.104089805692432e-10,3.055189609527588,6.97998107934995,7.432471150361345,6.8025,7.102500000000001,6.982500000000001,7.822500000000001,0.3000000000000007,0.8399999999999999 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,10,"regimes,",7.882500171661377,8.262499809265137,True,5.572348485416434e-11,1.5419561862945557,7.716863671576262,8.18288138010086,7.102500000000001,7.8825,8.1025,8.2625,0.7799999999999994,0.16000000000000014 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,11,Yesterday,8.302499771118164,8.842499732971191,True,9.80091181823628e-12,0.2712065875530243,8.243045019532943,8.802590784018477,8.1825,8.3025,8.782499999999999,8.8425,0.120000000000001,0.0600000000000005 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,12,Iran,9.302499771118164,9.442500114440918,True,9.267232814469395e-12,0.25643885135650635,9.28248466227814,9.428928899971622,9.3025,9.3025,9.442499999999999,9.442499999999999,0.0,0.0 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,13,announced,9.462499618530273,9.922499656677246,True,4.382011420389631e-11,1.2125712633132935,9.470828595188868,9.948668430727986,9.4625,9.5025,9.9225,10.0625,0.03999999999999915,0.14000000000000057 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,14,that,10.082500457763672,10.22249984741211,True,6.737973894110905e-12,0.25,10.112171472976984,10.317274030543697,10.0825,10.0825,10.2225,10.3425,0.0,0.11999999999999922 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,15,it,11.022500038146973,11.082500457763672,True,1.3952581277842935e-11,0.3860898017883301,10.98394079716456,11.063832396543807,10.9025,11.022499999999999,11.0425,11.1625,0.11999999999999922,0.11999999999999922 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,16,will,11.162500381469727,11.362500190734863,True,4.104548298466959e-11,1.135792851448059,11.193551591725347,11.379601260949299,11.1425,11.2625,11.362499999999999,11.5025,0.11999999999999922,0.14000000000000057 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,17,finance,11.422499656677246,11.762499809265137,True,2.8811382099536154e-11,0.7972561120986938,11.4400876158457,11.820485161778358,11.4225,11.5625,11.7625,11.9225,0.14000000000000057,0.16000000000000014 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,18,the,11.802499771118164,11.922499656677246,True,3.0040948895138087e-11,0.8312801718711853,11.866457503420186,11.978970130729623,11.782499999999999,11.942499999999999,11.9025,12.0825,0.16000000000000014,0.17999999999999972 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,19,families,11.942500114440918,12.382499694824219,True,3.755114622028266e-11,1.039099097251892,12.034518519610577,12.432086350730916,11.942499999999999,12.1025,12.3825,12.6425,0.16000000000000014,0.2599999999999998 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,20,of,12.462499618530273,12.542499542236328,True,2.093970396382927e-12,0.25,12.519979089225814,12.600236932231414,12.4625,12.7225,12.5425,12.8225,0.2599999999999998,0.27999999999999936 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,21,the,12.6225004196167,12.822500228881836,True,1.0107663404174128e-12,0.25,12.683711846600158,12.879735837706036,12.6225,13.6025,12.8225,13.7625,0.9799999999999986,0.9399999999999995 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,22,terrorists,13.582500457763672,14.102499961853027,True,3.2193830934446055e-11,0.890853762626648,13.48057177307044,14.12193960941006,12.9225,13.8025,14.022499999999999,14.3225,0.8800000000000008,0.3000000000000007 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,23,and,14.242500305175781,14.442500114440918,True,6.540654823306014e-11,1.8099017143249512,14.243990294329773,14.439934456951706,14.1625,14.3825,14.3225,14.5025,0.22000000000000064,0.17999999999999972 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,24,murderers,14.602499961853027,15.202500343322754,True,5.3976757091733774e-11,1.4936214685440063,14.574493863698141,15.18575901971097,14.3825,14.6025,15.1625,15.2425,0.21999999999999886,0.08000000000000007 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,25,this,15.282500267028809,15.662500381469727,True,9.564676828333063e-11,2.646696090698242,15.271233298767404,15.507784351694662,15.2225,15.2825,15.4625,15.6625,0.0600000000000005,0.1999999999999993 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,26,shows,15.762499809265137,16.162500381469727,True,1.070308425221711e-10,2.9617111682891846,15.638094435743163,15.937968171367956,15.4825,15.7625,15.7425,16.1625,0.27999999999999936,0.4200000000000017 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,27,that,16.22249984741211,16.422500610351562,True,1.4821713301138573e-10,4.0,16.03565573699944,16.203248310703422,15.7625,16.2225,16.1625,16.4025,0.46000000000000085,0.23999999999999844 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,28,"Iran,",16.502500534057617,16.72249984741211,True,4.210410839422529e-11,1.1650867462158203,16.26544869858648,16.458665519694218,16.2225,16.5025,16.3625,16.7225,0.28000000000000114,0.35999999999999943 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,29,even,17.5625,17.762500762939453,True,9.684803653486895e-11,2.6799371242523193,16.61354563803406,16.827777791718276,16.5025,17.5625,16.7225,17.762500000000003,1.0599999999999987,1.0400000000000027 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,30,after,17.822500228881836,18.002500534057617,True,3.2281885498086638e-12,0.25,17.554003479065504,17.80643906509736,17.5225,17.8225,17.762500000000003,18.0025,0.3000000000000007,0.23999999999999844 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,31,the,18.0625,18.202499389648438,True,1.899481093248223e-11,0.5256162285804749,17.860950102720363,18.01428792989417,17.8225,18.0625,17.962500000000002,18.2025,0.23999999999999844,0.23999999999999844 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,32,nuclear,18.282499313354492,18.622499465942383,True,7.600799330209629e-12,0.25,18.086117188736683,18.544572324433087,18.0625,18.282500000000002,18.5225,18.622500000000002,0.22000000000000242,0.10000000000000142 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,33,"agreement,",18.6825008392334,19.502500534057617,True,1.3309903179603566e-10,3.683058977127075,18.689252254938246,19.452889571682917,18.622500000000002,18.6825,19.422500000000003,19.5025,0.05999999999999872,0.0799999999999983 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,34,is,19.6825008392334,19.762500762939453,True,6.084657951099803e-12,0.25,19.557316484633294,19.728965377547198,19.4825,19.6825,19.7025,19.762500000000003,0.1999999999999993,0.060000000000002274 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,35,continuing,20.202499389648438,20.662500381469727,True,5.529132013348814e-11,1.5299975872039795,20.186404995029186,20.684973994192696,20.2025,20.2025,20.6625,20.742500000000003,0.0,0.08000000000000185 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,36,to,21.502500534057617,21.582500457763672,True,9.673984946445557e-10,4.0,21.502510645887668,21.582509151446565,21.5025,21.5025,21.582500000000003,21.582500000000003,0.0,0.0 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,37,aid,21.662500381469727,21.782499313354492,True,4.237645789828548e-10,4.0,21.662507714897142,21.788616675529326,21.6625,21.6625,21.782500000000002,21.8225,0.0,0.03999999999999915 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,38,"terrorism,",21.842500686645508,22.342500686645508,True,9.071070283805938e-12,0.2510107457637787,21.838637629170766,22.378070868609647,21.802500000000002,21.8625,22.3425,22.442500000000003,0.05999999999999872,0.10000000000000142 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,39,including,22.6825008392334,23.162500381469727,True,6.269147527493413e-12,0.25,22.67344056762576,23.179853509455537,22.6825,22.6825,23.1625,23.262500000000003,0.0,0.10000000000000142 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,40,Palestinian,23.342500686645508,24.042499542236328,True,1.5516138721083372e-11,0.4293558895587921,23.341317527591546,24.04398988161638,23.3425,23.3425,24.0025,24.082500000000003,0.0,0.08000000000000185 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,41,"terrorism,",24.102500915527344,24.582500457763672,True,2.0350023749449164e-11,0.5631170868873596,24.10249792843023,24.583562825209636,24.102500000000003,24.102500000000003,24.582500000000003,24.582500000000003,0.0,0.0 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,42,Hezbollah,24.702499389648438,25.262500762939453,True,8.40829662840381e-12,0.25,24.68922904288737,25.2904581805427,24.642500000000002,24.7025,25.2025,25.3825,0.05999999999999872,0.17999999999999972 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,43,terrorism,25.322500228881836,26.002500534057617,True,7.838881627142413e-11,2.1691415309906006,25.346885974875732,26.004277391559278,25.3225,25.422500000000003,26.0025,26.0025,0.10000000000000142,0.0 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,44,and,26.842500686645508,26.982500076293945,True,3.270300696911477e-11,0.9049434661865234,26.818193885178502,26.98777704569297,26.802500000000002,26.8425,26.922500000000003,27.0225,0.03999999999999915,0.09999999999999787 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,45,its,27.082500457763672,27.202499389648438,True,3.613817578518308e-11,1.0,27.057459753673502,27.203179205761856,26.962500000000002,27.082500000000003,27.1625,27.242500000000003,0.120000000000001,0.08000000000000185 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,46,assistance,27.282499313354492,28.122499465942383,True,1.4203026255099616e-10,3.9302000999450684,27.289326195794334,28.100023559728623,27.282500000000002,27.282500000000002,28.062500000000004,28.142500000000002,0.0,0.0799999999999983 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,47,to,28.202499389648438,28.282499313354492,True,7.287294032098934e-12,0.25,28.202197475208703,28.282161719627336,28.2025,28.2025,28.282500000000002,28.282500000000002,0.0,0.0 +-yRb-Jum7EQ/1,-yRb-Jum7EQ,1,48,Hamas.,28.342500686645508,28.782499313354492,True,2.1801163305190663e-11,0.6032723784446716,28.34016592506999,28.781192489043658,28.302500000000002,28.3425,28.782500000000002,28.782500000000002,0.03999999999999915,0.0 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,0,Yesterday,0.12250000238418579,0.862500011920929,True,2.1098019165055604e-11,0.4256690740585327,0.11640499422426298,0.8237373720723118,0.0625,0.1225,0.7825,0.8624999999999999,0.06,0.07999999999999996 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,1,Eliav,0.9024999737739563,1.162500023841858,True,6.203321190056954e-11,1.2515686750411987,0.8757917552775388,1.1610153192742962,0.8424999999999999,0.9025,1.1225,1.1624999999999999,0.06000000000000005,0.039999999999999813 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,2,Gelman,1.222499966621399,1.662500023841858,True,2.492321973801559e-11,0.5028454661369324,1.2232918082472444,1.6615993583479005,1.2225,1.2225,1.6025,1.6824999999999999,0.0,0.07999999999999985 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,3,lost,2.7225000858306885,2.862499952316284,True,5.466818109312044e-10,4.0,2.709146128467911,2.8661180187391095,2.7025,2.7625,2.8625,2.9225,0.06000000000000005,0.06000000000000005 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,4,his,2.9024999141693115,3.002500057220459,True,3.090692146656693e-10,4.0,2.9108267355157285,3.0414643223665143,2.9025,2.9625,3.0025,3.2425,0.06000000000000005,0.2400000000000002 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,5,life,3.1024999618530273,3.362499952316284,True,1.2600011312091652e-10,2.5421509742736816,3.1401606861304536,3.357841510464017,3.0225,3.3025,3.2425,3.5625,0.28000000000000025,0.31999999999999984 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,6,in,3.442500114440918,3.5625,True,2.6729063407060494e-10,4.0,3.428606886284111,3.532967025626201,3.3025,3.6625,3.3625,3.7225,0.3599999999999999,0.3600000000000003 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,7,another,3.6624999046325684,4.242499828338623,True,3.822804919839662e-11,0.771280825138092,3.6285882996720065,4.14030831047379,3.4425,3.8025,3.9425,4.242500000000001,0.3600000000000003,0.3000000000000007 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,8,terrorist,4.28249979019165,5.242499828338623,True,4.334416506268646e-11,0.8745024800300598,4.227954760286244,5.168522414951293,4.062500000000001,4.3425,4.9625,5.242500000000001,0.27999999999999936,0.28000000000000025 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,9,"attack,",5.34250020980835,5.682499885559082,True,6.46387596225928e-11,1.3041375875473022,5.276098853024842,5.630281070381624,5.1225000000000005,5.3425,5.442500000000001,5.7225,0.21999999999999975,0.27999999999999936 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,10,not,5.78249979019165,5.902500152587891,True,1.2150396140608866e-11,0.25,5.716276151729501,5.852571298442281,5.482500000000001,5.782500000000001,5.6825,5.9225,0.2999999999999998,0.2400000000000002 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,11,by,5.982500076293945,6.082499980926514,True,1.0236080212611132e-11,0.25,5.934587808080619,6.029627616167395,5.782500000000001,5.982500000000001,5.862500000000001,6.0825000000000005,0.20000000000000018,0.21999999999999975 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,12,the,6.122499942779541,6.302499771118164,True,4.95643699693904e-11,1.0,6.089065477376196,6.26458295760959,5.982500000000001,6.1225000000000005,6.2225,6.3025,0.13999999999999968,0.08000000000000007 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,13,students,6.322500228881836,6.802499771118164,True,1.086939913075291e-10,2.192986488342285,6.304983799467197,6.802649601015644,6.282500000000001,6.322500000000001,6.8025,6.8025,0.040000000000000036,0.0 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,14,of,7.422500133514404,7.522500038146973,True,3.4040623098086087e-10,4.0,7.421097526520383,7.5222877816487355,7.4225,7.4225,7.522500000000001,7.522500000000001,0.0,0.0 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,15,"terrorism,",7.662499904632568,8.362500190734863,True,1.7434940643989982e-11,0.3517635762691498,7.651950712497826,8.326166381941334,7.5825000000000005,7.6625000000000005,8.282499999999999,8.362499999999999,0.08000000000000007,0.08000000000000007 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,16,but,8.40250015258789,8.542499542236328,True,4.870383610300344e-12,0.25,8.40232606126986,8.544283059130962,8.4025,8.4025,8.5425,8.5425,0.0,0.0 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,17,by,8.662500381469727,8.72249984741211,True,3.2112475872869695e-11,0.6478943824768066,8.65890888774039,8.725163996226525,8.6425,8.7025,8.7225,8.7625,0.0600000000000005,0.03999999999999915 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,18,those,8.782500267028809,9.162500381469727,True,9.06100472430893e-11,1.828128695487976,8.782524958225315,9.20255260115738,8.782499999999999,8.782499999999999,9.1625,9.3225,0.0,0.16000000000000014 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,19,who,9.202500343322754,9.322500228881836,True,7.350461905808459e-11,1.4830132722854614,9.292884555691698,9.434678222093696,9.2025,9.4225,9.3225,9.5825,0.21999999999999886,0.2599999999999998 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,20,teach,9.422499656677246,9.72249984741211,True,4.777102324826643e-11,0.963817834854126,9.512342365613454,9.798499598139479,9.4025,9.6225,9.7225,9.8825,0.22000000000000064,0.16000000000000014 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,21,"terrorism,",9.822500228881836,10.6225004196167,True,2.364412277078287e-10,4.0,9.885742869369814,10.623797601314282,9.8225,9.9625,10.522499999999999,10.8025,0.14000000000000057,0.28000000000000114 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,22,a,10.842499732971191,10.862500190734863,True,7.060157580091042e-12,0.25,10.76912108115059,10.789121081150874,10.6025,10.8425,10.6225,10.862499999999999,0.2400000000000002,0.23999999999999844 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,23,Palestinian,10.962499618530273,12.522500038146973,True,4.3775850999683286e-11,0.8832120895385742,10.898607984569265,12.05718561330501,10.782499999999999,10.9625,11.6625,12.522499999999999,0.1800000000000015,0.8599999999999994 +-yRb-Jum7EQ/5,-yRb-Jum7EQ,5,24,teacher.,12.5625,12.962499618530273,True,8.628150971468074e-11,1.7407970428466797,12.515745111313707,12.963414362425844,12.4625,12.6225,12.942499999999999,12.9825,0.16000000000000014,0.040000000000000924 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,0,"Therefore,",0.4025000035762787,0.9424999952316284,True,1.6840784322624813e-10,1.0,0.4024729803370939,0.9336746683054675,0.4025,0.4025,0.9025,0.9624999999999999,0.0,0.05999999999999994 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,1,the,1.0625,1.2024999856948853,True,9.747938567450376e-11,0.5788292288780212,1.0589909815193694,1.1984154783750278,1.0625,1.0625,1.1624999999999999,1.2025,0.0,0.040000000000000036 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,2,world,1.2625000476837158,1.5225000381469727,True,1.6847746808767994e-10,1.000413417816162,1.2558060204353718,1.5185764126331496,1.2225,1.2625,1.5225,1.5225,0.040000000000000036,0.0 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,3,needs,1.5625,1.902500033378601,True,1.0756048135496243e-10,0.6386904716491699,1.5614918157611801,1.8797170301478279,1.5625,1.5625,1.7825,1.9625,0.0,0.17999999999999994 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,4,to,1.9424999952316284,2.002500057220459,True,1.7243546868161985e-10,1.0239158868789673,1.9494528303504337,2.021352098064118,1.8825,2.2425,1.9625,2.3225,0.3600000000000001,0.3599999999999999 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,5,stand,2.0425000190734863,2.4625000953674316,True,1.421072287621783e-10,0.8438278436660767,2.1454380160719135,2.5239863439827293,2.0425,2.3825,2.4625,2.8225,0.33999999999999986,0.3599999999999999 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,6,with,2.5425000190734863,2.822499990463257,True,3.683832960899025e-10,2.1874473094940186,2.627782996043301,2.9132515079477193,2.5425,2.8625,2.8225,3.9025,0.31999999999999984,1.08 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,7,Israel,3.742500066757202,4.122499942779541,True,1.1312620978864985e-10,0.6717395782470703,3.7309032744213915,4.150365024998529,3.7425,3.9425,4.1225000000000005,4.2225,0.19999999999999973,0.09999999999999964 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,8,against,4.242499828338623,4.682499885559082,True,2.678313681947486e-10,1.5903735160827637,4.242938262935196,4.670751606173934,4.242500000000001,4.242500000000001,4.5825000000000005,4.7225,0.0,0.13999999999999968 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,9,this,4.742499828338623,4.902500152587891,True,9.41213912364347e-11,0.5588895678520203,4.724187153540902,4.903113320015298,4.6625000000000005,4.742500000000001,4.862500000000001,4.902500000000001,0.08000000000000007,0.040000000000000036 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,10,"incitement,",5.422500133514404,6.102499961853027,True,6.119732498532926e-11,0.3633876144886017,5.423858436959219,6.115242073345665,5.4225,5.4225,6.102500000000001,6.202500000000001,0.0,0.09999999999999964 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,11,which,6.502500057220459,6.802499771118164,True,2.0067764117115416e-10,1.1916170120239258,6.50248685522129,6.802489095420521,6.5025,6.5025,6.8025,6.8025,0.0,0.0 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,12,is,6.862500190734863,6.942500114440918,True,8.340554358277075e-10,4.0,6.8625014843098695,6.942410921639754,6.862500000000001,6.862500000000001,6.942500000000001,6.942500000000001,0.0,0.0 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,13,the,7.002500057220459,7.182499885559082,True,3.8694789039617206e-10,2.2976832389831543,7.002492295030229,7.182530934830729,7.0025,7.0025,7.1825,7.1825,0.0,0.0 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,14,number,7.402500152587891,7.762499809265137,True,2.0023324664997233e-10,1.1889781951904297,7.378536282253883,7.766816192156913,7.3025,7.402500000000001,7.6825,7.822500000000001,0.10000000000000053,0.14000000000000057 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,15,one,9.782500267028809,9.90250015258789,True,1.6587432816184133e-10,0.9849560856819153,9.77142133456187,9.889990542704302,9.7425,9.782499999999999,9.8425,9.9025,0.03999999999999915,0.0600000000000005 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,16,cause,9.962499618530273,10.162500381469727,True,1.8768611664832235e-10,1.1144737005233765,9.974359250912508,10.190149976930748,9.9625,10.0025,10.1625,10.2225,0.03999999999999915,0.0600000000000005 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,17,of,10.382499694824219,10.442500114440918,True,3.711768045699948e-11,0.25,10.352394778030892,10.418035924396685,10.2025,10.3825,10.2625,10.442499999999999,0.17999999999999972,0.17999999999999972 +-yRb-Jum7EQ/6,-yRb-Jum7EQ,6,18,terrorism.,10.5024995803833,10.982500076293945,True,1.314886949321803e-10,0.7807753682136536,10.4911182530075,10.981002444124938,10.3825,10.5025,10.9825,10.9825,0.11999999999999922,0.0 diff --git a/math/问题一.pdf b/math/问题一.pdf new file mode 100644 index 0000000..eda1efb Binary files /dev/null and b/math/问题一.pdf differ diff --git a/复杂场景下多模态情感识别的数学建模与算法设计.docx b/复杂场景下多模态情感识别的数学建模与算法设计.docx new file mode 100644 index 0000000..4a88ee4 Binary files /dev/null and b/复杂场景下多模态情感识别的数学建模与算法设计.docx differ