Choosing the right parameters to train a Tf-Idf vectoriser
There are no silver bullets. But here are some suggests:


Use a better stopwords vocabulary. If you still have words like "to" and "at", then you are either not removing stopwords or using a lousy vocabulary. Try using the Spanish stopwords from nltk:

from nltk.corpus import stopwords
stopwords.words('spanish')

Use max_df &lt; 1. This will truncate words that appear in more than that percentage number of documents.
The TF-IDF part that punishes common words (transversal to all documents) is the IDF part of TF-IDF, which means inverse document transform. Several functions may be used as your IDF function. Usually, IDF=$\log\frac{\text{#documents}}{\text{#documents where word appears}}$ is used. You could try a more punitive IDF function. sklearn does not seem to allow to specify it, but you can use nltk or gensim or easily implement your own TF-IDF vectorization. It needs no more than five lines of code.


I would try each of these suggestions in this order, and stop when it is good enough. It sounds like using a better stopwords vocabulary will be good enough for you.

EDIT: I forgot to mention, but of course you can add more uninteresting words to the stopwords list, if you have the need to do so.

You may also want to first evaluate the impact TF-IDF is having in your counts. I think this will work:

m = TfidfVectorizer().fit(docs)
c = [m.transform([word]) for word in m.vocabulary_]
for i in np.argsort(c)[::-1][:20]:
    print(m.vocabulary_[i], c[i])


You may have to adjust the code. Try to use with IDF disabled and enabled, and other tweaks.