docs: def best_kmers(dt, response, sequence, k=6, consider_shift=True, n_cores=1,
                 seq_align="start", trim_seq_len=None):
      """
      Find best k-mers for CONCISE initialization.
  
      Args:
          dt (pd.DataFrame): Table containing response variable and sequence.
          response (str): Name of the column used as the reponse variable.
          sequence (str): Name of the column storing the DNA/RNA sequences.
          k (int): Desired k-mer length.
          n_cores (int): Number of cores to use for computation. It can use up to 3 cores.
          consider_shift (boolean): When performing stepwise k-mer selection. Is TATTTA similar to ATTTAG?
          seq_align (str): one of ``{"start", "end"}``. To which end should we align sequences?
          trim_seq_len (int): Consider only first `trim_seq_len` bases of each sequence when generating the sequence design matrix. If :python:`None`, set :py:attr:`trim_seq_len` to the longest sequence length, hence whole sequences are considered.
  
      Returns:
          string list: Best set of motifs for this dataset sorted with respect to
                       confidence (best candidate occuring first).
  
  
      Details:
          First a lasso model gets fitted to get a set of initial motifs. Next, the best
          subset of unrelated motifs is selected by stepwise selection.
      """
      y = dt[response]
      seq = dt[sequence]
  
      if trim_seq_len is not None:
          seq = pad_sequences(seq, align=seq_align, maxlen=trim_seq_len)
          seq = [s.replace("N", "") for s in seq]
  
      dt_kmer = kmer_count(seq, k)
      Xsp = csc_matrix(dt_kmer)
      en = ElasticNet(alpha=1, standardize=False, n_splits=3)
      en.fit(Xsp, y)
      # which coefficients are nonzero?=
      nonzero_kmers = dt_kmer.columns.values[en.coef_ != 0].tolist()
  
      # perform stepwise selection
      #
      # TODO - how do we deal with the intercept?
  
      # largest number of motifs where they don't differ by more than 1 k-mer
      def find_next_best(dt_kmer, y, selected_kmers, to_be_selected_kmers, consider_shift=True):
          """
          perform stepwise model selection while preventing to add a motif similar to the
          already selected motifs.
          """
          F, pval = f_regression(dt_kmer[to_be_selected_kmers], y)
          kmer = to_be_selected_kmers.pop(pval.argmin())
          selected_kmers.append(kmer)
  
          def select_criterion(s1, s2, consider_shift=True):
              if hamming_distance(s1, s2) <= 1:
                  return False
              if consider_shift and hamming_distance(s1[1:], s2[:-1]) == 0:
                  return False
              if consider_shift and hamming_distance(s1[:-1], s2[1:]) == 0:
                  return False
              return True
  
          to_be_selected_kmers = [ckmer for ckmer in to_be_selected_kmers
                                  if select_criterion(ckmer, kmer, consider_shift)]
          if len(to_be_selected_kmers) == 0:
              return selected_kmers
          else:
              # regress out the new feature
              lm = LinearRegression()
              lm.fit(dt_kmer[selected_kmers], y)
              y_new = y - lm.predict(dt_kmer[selected_kmers])
              return find_next_best(dt_kmer, y_new, selected_kmers, to_be_selected_kmers, consider_shift)
  
      selected_kmers = find_next_best(dt_kmer, y, [], nonzero_kmers, consider_shift)
  
      return selected_kmers