Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 98 lines (86 sloc) 2.879 kB
dc0715c @alexy computing Kendall's Tau between caps and skew
authored
1 open Common
2
3 (* Kendall's Tau
4 translated from Incanter *)
5
6 (*
7
8 (defn kendalls-tau
9 "
10 http://en.wikipedia.org/wiki/Kendall_tau_rank_correlation_coefficient
11 http://www.statsdirect.com/help/nonparametric_methods/kend.htm
12 http://mail.scipy.org/pipermail/scipy-dev/2009-March/011589.html
13 best explanation and example is in \"cluster analysis for researchers\" page 165.
14 http://www.amazon.com/Cluster-Analysis-Researchers-Charles-Romesburg/dp/1411606175
15 "
16 [a b]
17 (let [_ (assert (= (count a) (count b)))
18 n (count a)
19 ranked (reverse (sort-map (zipmap a b)))
20 ;;dcd is the meat of the calculation, the difference between the doncordant and discordant pairs
21 dcd (second
22 (reduce
23 (fn [[vals total] [k v]]
24 (let [diff (- (count (filter #(> % v) vals))
25 (count (filter #(< % v) vals)))]
26 [(conj vals v) (+ total diff)]))
27 [[] 0]
28 ranked))]
29 (/ ( * 2 dcd)
30 ( * n (- n 1)))))
31
32 (deftest kendalls-tau-test
33 (is (= 23/45
34 (kendalls-tau [4 10 3 1 9 2 6 7 8 5]
35 [5 8 6 2 10 3 9 4 7 1])))
36 (is (= 9/13
37 (kendalls-tau
38 [1 3 2 4 5 8 6 7 13 10 12 11 9]
39 [1 4 3 2 7 5 6 8 9 10 12 13 11]))))
40
41 *)
42
cf6d6f9 @alexy in skew, have to pass compareSkew to Kendall.tau2, or it will compare…
authored
43 let tau1 ?(sort=false) ?(comp=compare) x y =
44 let less,greater = lt_gt_of comp in
dc0715c @alexy computing Kendall's Tau between caps and skew
authored
45 let n = A.length x in
46 assert (n = A.length y);
47 let a = A.map2 (fun x y -> (x,y)) x y in
48 if sort then A.sort compPairAsc1 a else ();
49 let _,dcd = A.fold_left begin fun (vals,total) (_,v) ->
cf6d6f9 @alexy in skew, have to pass compareSkew to Kendall.tau2, or it will compare…
authored
50 let lt = L.filter (less v) vals |> L.length in
51 let gt = L.filter (greater v) vals |> L.length in
dc0715c @alexy computing Kendall's Tau between caps and skew
authored
52 let diff = gt - lt in
53 (* NB can we enumerate over A prefix, in second, and not allocate vals at all? *)
54 v::vals, total + diff
55 end ([],0) a in
56 let n' = float n in
57 (float dcd) *. 2. /. (n' *. (n' -. 1.))
58
59
60 let countPrefix a n v f =
61 A.enum a |> E.take n |> E.filter (f v) |> E.count
62
63
cf6d6f9 @alexy in skew, have to pass compareSkew to Kendall.tau2, or it will compare…
authored
64 let tau2 ?(sort=false) ?(comp=compare) x y =
65 let less,greater = lt_gt_of comp in
dc0715c @alexy computing Kendall's Tau between caps and skew
authored
66 let n = A.length x in
67 assert (n = A.length y);
68 let a = A.map2 (fun x y -> (x,y)) x y in
69 let y = if sort then begin
70 A.sort compPairAsc1 a;
71 A.map snd a
72 end
73 else y in
74 let _,dcd = A.fold_left begin fun (n,total) (_,v) ->
75 let scan = countPrefix y n v in
9f95925 @alexy parameterize compareSkew with ~length and propagate that down from do…
authored
76 let lt = scan less in
77 let gt = scan greater in
dc0715c @alexy computing Kendall's Tau between caps and skew
authored
78 let diff = gt - lt in
79 (* NB can we enumerate over A prefix, in second, and not allocate vals at all? *)
80 succ n, total + diff
81 end (0,0) a in
82 let n' = float n in
83 (float dcd) *. 2. /. (n' *. (n' -. 1.))
84
85
cf6d6f9 @alexy in skew, have to pass compareSkew to Kendall.tau2, or it will compare…
authored
86 let kendall_tau_test: (?sort:bool -> ?comp:('b -> 'b -> int) -> 'a array -> 'b array -> float) -> unit =
dc0715c @alexy computing Kendall's Tau between caps and skew
authored
87 fun f ->
88 let sort = true in
89 assert begin
90 f ~sort [|4;10;3;1;9;2;6;7;8;5|]
91 [|5;8;6;2;10;3;9;4;7;1|]
92 = 23./.45.
93 end;
94 assert begin
95 f ~sort [|1;3;2;4;5;8;6;7;13;10;12;11;9|]
96 [|1;4;3;2;7;5;6;8;9;10;12;13;11|]
97 = 9./.13.
98 end
Something went wrong with that request. Please try again.