Permuted generates permuted random splits of table rows, using given list of probabilities, which will be normalized to sum to 1 (error returned if sum = 0) names are optional names for each split (e.g., Train, Test) which will be used to label the Values of the resulting Splits.
(ix *table.IndexView, probs []float64, names []string)
| 17 | // names are optional names for each split (e.g., Train, Test) which will be |
| 18 | // used to label the Values of the resulting Splits. |
| 19 | func Permuted(ix *table.IndexView, probs []float64, names []string) (*table.Splits, error) { |
| 20 | if ix == nil || ix.Len() == 0 { |
| 21 | return nil, fmt.Errorf("split.Random table is nil / empty") |
| 22 | } |
| 23 | np := len(probs) |
| 24 | if len(names) > 0 && len(names) != np { |
| 25 | return nil, fmt.Errorf("split.Random names not same len as probs") |
| 26 | } |
| 27 | sum := floats.Sum(probs) |
| 28 | if sum == 0 { |
| 29 | return nil, fmt.Errorf("split.Random probs sum to 0") |
| 30 | } |
| 31 | nr := ix.Len() |
| 32 | ns := make([]int, np) |
| 33 | cum := 0 |
| 34 | fnr := float64(nr) |
| 35 | for i, p := range probs { |
| 36 | p /= sum |
| 37 | per := int(math.Round(p * fnr)) |
| 38 | if cum+per > nr { |
| 39 | per = nr - cum |
| 40 | if per <= 0 { |
| 41 | break |
| 42 | } |
| 43 | } |
| 44 | ns[i] = per |
| 45 | cum += per |
| 46 | } |
| 47 | spl := &table.Splits{} |
| 48 | perm := ix.Clone() |
| 49 | perm.Permuted() |
| 50 | cum = 0 |
| 51 | spl.SetLevels("permuted") |
| 52 | for i, n := range ns { |
| 53 | nm := "" |
| 54 | if names != nil { |
| 55 | nm = names[i] |
| 56 | } else { |
| 57 | nm = fmt.Sprintf("p=%v", probs[i]/sum) |
| 58 | } |
| 59 | spl.New(ix.Table, []string{nm}, perm.Indexes[cum:cum+n]...) |
| 60 | cum += n |
| 61 | } |
| 62 | return spl, nil |
| 63 | } |