add failing test defining expected probabilities
@@ -38,3 +38,48 @@ def test_u_train():
br = linker._settings_obj._blocking_rules_to_generate_predictions[0]
assert br.blocking_rule == "l.name = r.name"
+
+
+def test_u_train_link_only():
+
+ data_l = [
+ {"unique_id": 1, "name": "Amanda"},
+ {"unique_id": 2, "name": "Robin"},
+ {"unique_id": 3, "name": "Robyn"},
+ {"unique_id": 4, "name": "David"},
+ {"unique_id": 5, "name": "Eve"},
+ {"unique_id": 6, "name": "Amanda"},
+ {"unique_id": 7, "name": "Stuart"},
+ ]
+ data_r = [
+ {"unique_id": 1, "name": "Eva"},
+ {"unique_id": 2, "name": "David"},
+ {"unique_id": 3, "name": "Sophie"},
+ {"unique_id": 4, "name": "Jimmy"},
+ {"unique_id": 5, "name": "Stuart"},
+ {"unique_id": 6, "name": "Jimmy"},
+ ]
+ df_l = pd.DataFrame(data_l)
+ df_r = pd.DataFrame(data_r)
+
+ _mutable_params["dialect"] = "duckdb"
+ settings = {
+ "link_type": "link_only",
+ "comparisons": [levenshtein_at_thresholds("name", 2)],
+ "blocking_rules_to_generate_predictions": [],
+ }
+
+ linker = DuckDBLinker([df_l, df_r], settings)
+ linker.debug_mode = True
+ linker.estimate_u_using_random_sampling(target_rows=1e6)
+ cc_name = linker._settings_obj.comparisons[0]
+
+ denom = (6 * 7) # only l <-> r candidate links
+ cl_exact = cc_name._get_comparison_level_by_comparison_vector_value(2)
+ # David, Stuart
+ assert cl_exact.u_probability == 2 / denom
+ # Eve/Eva
+ cl_lev = cc_name._get_comparison_level_by_comparison_vector_value(1)
+ assert cl_lev.u_probability == 1 / denom
+ cl_no = cc_name._get_comparison_level_by_comparison_vector_value(0)
+ assert cl_no.u_probability == (denom - 3) / denom
