def weighted_account_match( row )
      query_tokens = tokenize(row[:description])

      search_vector = []
      account_vectors = {}

      query_tokens.each do |token|
        idf = Math.log((accounts.keys.length + 1) / ((tokens[token] || {}).keys.length.to_f + 1))
        tf = 1.0 / query_tokens.length.to_f
        search_vector << tf*idf

        accounts.each do |account, total_terms|
          tf = (tokens[token] && tokens[token][account]) ? tokens[token][account] / total_terms.to_f : 0
          account_vectors[account] ||= []
          account_vectors[account] << tf*idf
        end
      end

      # Should I normalize the vectors?  Probably unnecessary due to tf-idf and short documents.

      account_vectors = account_vectors.to_a.map do |account, account_vector|
        { :cosine => (0...account_vector.length).to_a.inject(0) { |m, i| m + search_vector[i] * account_vector[i] },
          :account => account }
      end
      account_vectors.sort! {|a, b| b[:cosine] <=> a[:cosine] }

      # Return empty set if no accounts matched so that we can fallback to the defaults in the unattended mode
      if options[:unattended]
        if account_vectors.first && account_vectors.first[:account]
          account_vectors = [] if account_vectors.first[:cosine] == 0
        end
      end

      return account_vectors
    end
def weighted_account_match( row )
      query_tokens = tokenize(row[:description])

      search_vector = []
      account_vectors = {}

      query_tokens.each do |token|
        idf = Math.log((accounts.keys.length + 1) / ((tokens[token] || {}).keys.length.to_f + 1))
        tf = 1.0 / query_tokens.length.to_f
        search_vector << tf*idf

        accounts.each do |account, total_terms|
          tf = (tokens[token] && tokens[token][account]) ? tokens[token][account] / total_terms.to_f : 0
          account_vectors[account] ||= []
          account_vectors[account] << tf*idf
        end
      end

      # Should I normalize the vectors?  Probably unnecessary due to tf-idf and short documents.

      account_vectors = account_vectors.to_a.map do |account, account_vector|
        { :cosine => (0...account_vector.length).to_a.inject(0) { |m, i| m + search_vector[i] * account_vector[i] },
          :account => account }
      end
      account_vectors.sort! {|a, b| b[:cosine] <=> a[:cosine] }

      # Return empty set if no accounts matched so that we can fallback to the defaults in the unattended mode
      if options[:unattended]
        if account_vectors.first && account_vectors.first[:account]
          account_vectors = [] if account_vectors.first[:cosine] == 0
        end
      end

      return account_vectors
    end
Weigh accounts by how well they match the row