test.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. "sort"
  6. )
  7. func rank(data []float64) []float64 {
  8. n := len(data)
  9. ranked := make([]float64, n)
  10. for i := range ranked {
  11. ranked[i] = float64(i + 1)
  12. }
  13. sort.Float64s(data)
  14. for i := 0; i < n; {
  15. j := i
  16. for j < n && data[i] == data[j] {
  17. j++
  18. }
  19. rank := (float64(i+1) + float64(j)) / 2
  20. for k := i; k < j; k++ {
  21. ranked[k] = rank
  22. }
  23. i = j
  24. }
  25. return ranked
  26. }
  27. func mannWhitneyU(sampleA, sampleB []float64) (float64, float64) {
  28. n1 := float64(len(sampleA))
  29. n2 := float64(len(sampleB))
  30. all := append(sampleA, sampleB...)
  31. ranks := rank(all)
  32. rankSumA := 0.0
  33. for i := 0; i < len(sampleA); i++ {
  34. rankSumA += ranks[i]
  35. }
  36. u1 := rankSumA - n1*(n1+1)/2
  37. u2 := n1*n2 - u1
  38. return u1, u2
  39. }
  40. func calculatePValue(u, n1, n2 float64) float64 {
  41. meanU := n1 * n2 / 2
  42. sdU := math.Sqrt(n1 * n2 * (n1 + n2 + 1) / 12)
  43. z := (u - meanU) / sdU
  44. pValue := 2 * (1 - normalCDF(math.Abs(z)))
  45. return pValue
  46. }
  47. func normalCDF(x float64) float64 {
  48. return 0.5 * (1 + math.Erf(x/math.Sqrt2))
  49. }
  50. func main() {
  51. sampleA := []float64{-30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65}
  52. sampleB := []float64{-28, -23, -18, -13, -8, -3, 2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67}
  53. u1, u2 := mannWhitneyU(sampleA, sampleB)
  54. pValue := calculatePValue(u1, float64(len(sampleA)), float64(len(sampleB)))
  55. fmt.Printf("U1 统计量: %.2f\n", u1)
  56. fmt.Printf("U2 统计量: %.2f\n", u2)
  57. fmt.Printf("p 值: %.4f\n", pValue)
  58. }