2016-11-04 3 views
0

나는 어떤 길이의 스트링 아이템의리스트를 가지고있다. 나는이리스트를 "normalize"하여 각 아이템이 정규 분포의 일부가되도록 문자열에 가중치를 추가해야한다.일반 분포에 평탄한리스트를 웨이팅

내가 가지고있는 것 외에 다른 점에 대해 더 효과적이고 수학적으로/통계적으로 어떤 방법이 있습니까?

func normalizeAppend(in []string, shuffle bool) []string { 
    var ret []string 

    if shuffle { 
     shuffleStrings(in) 
    } 

    l := len(in) 
    switch { 
    case remain(l, 3) == 0: 
     l3 := (l/3) 
     var low, mid, high []string 
     for i, v := range in { 
      o := i + 1 
      switch { 
      case o <= l3: 
       low = append(low, v) 
      case o > l3 && o <= l3*2: 
       mid = append(mid, v) 
      case o >= l3*2: 
       high = append(high, v) 
      } 
     } 

     q1 := 1600/len(low) 
     q2 := 6800/len(mid) 
     q3 := 1600/len(high) 

     for _, v := range low { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q1)) 
     } 

     for _, v := range mid { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q2)) 
     } 

     for _, v := range high { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q3)) 
     } 
    case remain(l, 2) == 0 && l >= 4: 
     l4 := (l/4) 
     var first, second, third, fourth []string 
     for i, v := range in { 
      o := i + 1 
      switch { 
      case o <= l4: 
       first = append(first, v) 
      case o > l4 && o <= l4*2: 
       second = append(second, v) 
      case o > l4*2 && o <= l4*3: 
       third = append(third, v) 
      case o > l4*3: 
       fourth = append(fourth, v) 
      } 
     } 
     q1 := 1600/len(first) 
     q2 := 3400/len(second) 
     q3 := 3400/len(third) 
     q4 := 1600/len(fourth) 

     for _, v := range first { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q1)) 
     } 

     for _, v := range second { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q2)) 
     } 

     for _, v := range third { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q3)) 
     } 

     for _, v := range fourth { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q4)) 
     } 
    default: 
     var first, second, third []string 
     q1 := (1 + math.Floor(float64(l)*.16)) 
     q3 := (float64(l) - math.Floor(float64(l)*.16)) 
     var o float64 
     for i, v := range in { 
      o = float64(i + 1) 
      switch { 
      case o <= q1: 
       first = append(first, v) 
      case o > q1 && o < q3: 
       second = append(second, v) 
      case o >= q3: 
       third = append(third, v) 
      } 
     } 
     lq1 := 1600/len(first) 
     lq2 := 3400/len(second) 
     lq3 := 1600/len(third) 
     for _, v := range first { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq1)) 
     } 

     for _, v := range second { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq2)) 
     } 

     for _, v := range third { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq3)) 
     } 

    } 

    return ret 
} 

일부 요청 설명 :

나는 (묵시적) 무게와 목록을 가지고 시작하는 가중 선택하여 한 번에 많은 시간을 목록에서 하나를 선택합니다 항목의 목록이 1 :

[A_1, B_1, 한 c_1, d_1의 파라미터, e_1, F_1, g_1, H_1, i_1, j_1, k_1]

뭔가 더 생산에 그 목록을 만들기 위해 더 나은 방법을 찾고 있어요 선택에 대한 가중치의 '보통'분포 :

[A_1, B_2, c_3, d_5, e_14, f_30, g_14, h_5, i_3, j_2, k_1]

또는 아마도 내가 더 통계적으로 접지 뭔가 내 방법을 변경해야 할 가능성이 높습니다. 최종선은 항목 목록에서 선택 항목을 여러 가지 방법으로 제어하려는 것입니다. 여기서는 항목이 표준 곡선에 가깝게 반환되도록합니다.

+0

사용자 요구 사항을 이해할 수 없습니다. 명확히 해 주시겠습니까? 요소가 정규 분포의 일부인 것은 무엇을 의미합니까? 가중치를 덧붙임으로써 간단한 문자열 연결을 의미합니까? 어쩌면 예제를 게시 할 수 있습니다. –

+0

코드는 질문 및 개념만큼 중요하지 않습니다. 내가 작업하고있는 다른 개념의 개념을 처음으로 깨기 쉽습니다. – blueblank

+0

가중치를 계산하는 것 (적절한 평균과 분산을 갖는 정규 분포 공식 사용) 또는이 분포로부터 샘플링하는 것 (정규 분포에 대해 임의 생성기 사용)과 관련한 것입니까? –

답변

0

그냥 주어진 목록에 대한 가중치를 계산하려면, 당신은 다음과 같은 사항이 필요합니다

  • 정규 분포
  • 정규 분포
  • discretizer의 분산의 평균을 값의 경우

첫 번째 것은 매우 간단합니다. 평균이 목록의 중심에 있도록하고 싶습니다. 따라서 (제로 기반 색인을 가정) :

mean = (list.size - 1)/2 

두 번째는 임의의 종류의 당신이 당신의 무게가 떨어질하는 방법 가파른에 따라 달라집니다. 정규 분포의 가중치는 mean에서 3 * standard_deviation의 거리를 넘어 실제적으로 0입니다.

standard_deviation = (1/4 .. 1/6) * list.size 
variance = standard_deviation^2 

당신이 정규 분포에서 가중치를 이산화 할 필요가, 당신이 정수 가중치를 원하는 가정 : 그래서 대부분의 경우 좋은 표준 편차는 아마 네 번째와 여섯 번째 목록 길이 사이의 무언가이다. 이를 수행하는 가장 쉬운 방법은 평균 위치에서 요소의 최대 가중치를 지정하는 것입니다.

그게 전부입니다. 위치가 i 인 요소의 가중치는 다음과 같습니다.

weight[i] = round(max_weight * exp(-(i - mean)^2/(2 * variance)))