docs: def run_gap_k_selection(data, k_min=1, k_max=50, B=5,
          skip=5, **kwargs):
      """
      Runs gap score for all k from k_min to k_max.
      """
      if k_min == k_max:
          return k_min
      gap_vals = []
      sk_vals = []
      k_range = list(range(k_min, k_max, skip))
      min_k = 0
      min_i = 0
      for i, k in enumerate(k_range):
          km = KMeans(k)
          clusters = km.fit_predict(data)
          gap, sk = calculate_gap(data, clusters, km, B=B)
          if len(gap_vals) > 1:
              if gap_vals[-1] >= gap - (skip+1)*sk:
                  min_i = i
                  min_k = k_range[i-1]
                  break
                  #return k_range[-1], gap_vals, sk_vals
          gap_vals.append(gap)
          sk_vals.append(sk)
      if min_k == 0:
          min_k = k_max
      if skip == 1:
          return min_k, gap_vals, sk_vals
      gap_vals = []
      sk_vals = []
      for k in range(min_k - skip, min_k + skip):
          km = KMeans(k)
          clusters = km.fit_predict(data)
          gap, sk = calculate_gap(data, clusters, km, B=B)
          if len(gap_vals) > 1:
              if gap_vals[-1] >= gap - sk:
                  min_k = k-1
                  return min_k, gap_vals, sk_vals
          gap_vals.append(gap)
          sk_vals.append(sk)
      return k, gap_vals, sk_vals