-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_features.py
More file actions
52 lines (40 loc) · 1.66 KB
/
Copy pathtest_features.py
File metadata and controls
52 lines (40 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import numpy as np
from keywraith.synthetic import KeystrokeStreamGenerator, MachineProfile
from keywraith.features import (
extract_features,
features_to_vector,
sessions_to_matrix,
FEATURE_NAMES,
)
def test_feature_vector_shape_and_order():
gen = KeystrokeStreamGenerator(seed=1)
feats = extract_features(gen.human_session(100))
assert set(feats) == set(FEATURE_NAMES)
vec = features_to_vector(feats)
assert vec.shape == (len(FEATURE_NAMES),)
def test_burst_has_low_cv_and_high_superhuman_fraction():
gen = KeystrokeStreamGenerator(seed=2)
burst = extract_features(
gen.machine_session(300, MachineProfile(mode="burst", device_delay_ms=5.0))
)
human = extract_features(gen.human_session(300))
assert burst["iki_cv"] < human["iki_cv"]
assert burst["frac_iki_sub20ms"] > 0.9
assert human["frac_iki_sub20ms"] < 0.1
def test_human_has_corrections_machine_does_not():
gen = KeystrokeStreamGenerator(seed=3)
human = extract_features(gen.human_session(600))
machine = extract_features(gen.machine_session(600))
assert machine["correction_rate"] == 0.0
assert human["correction_rate"] >= 0.0 # may be 0 in a short draw, but non-negative
def test_matrix_labels():
gen = KeystrokeStreamGenerator(seed=4)
ds = gen.dataset(n_human=15, n_machine=15)
X, y, ids = sessions_to_matrix(ds)
assert X.shape == (30, len(FEATURE_NAMES))
assert set(y.tolist()) == {0, 1}
assert len(ids) == 30
def test_empty_session_is_safe():
from keywraith.synthetic import Session
feats = extract_features(Session("empty", "human", "human", []))
assert all(np.isfinite(v) for v in feats.values())