Вопрос по machine-learning, scikit-learn, python, classification – Как получить наиболее информативные функции для классификаторов scikit-learn?

62

Классификаторы в пакетах машинного обучения, такие как liblinear и nltk, предлагают методshow_most_informative_features(), что действительно полезно для отладки функций:

viagra = None          ok : spam     =      4.5 : 1.0
hello = True           ok : spam     =      4.5 : 1.0
hello = None           spam : ok     =      3.3 : 1.0
viagra = True          spam : ok     =      3.3 : 1.0
casino = True          spam : ok     =      2.0 : 1.0
casino = None          ok : spam     =      1.5 : 1.0

Мой вопрос, если что-то подобное реализовано для классификаторов в Scikit-Learn. Я искал документацию, но не смог найти ничего подобного.

Если такой функции еще нет, знает ли кто-нибудь обходной путь, как получить эти значения?

Большое спасибо!

@eowl: на языке машинного обучения,parameters настройки, созданные процедурой обучения на основеfeatures вашего тренировочного набора. Скорость обучения и т. Д.hyperparameters. Fred Foo
Я не уверен, что вы имеете в виду под параметрами. я имею в виду наиболее отличительные черты, как в модели «мешок слов» для классификации спама, какие слова дают наибольшее количество доказательств для каждого класса. не те параметры, которые я понимаю как «настройки»; для классификатора - как скорость обучения и т. д. tobigue
Ты имеешь в виду самый различающий параметр? Simon Bergot

Ваш Ответ

8   ответов
2

торе NaiveBayes, и хотя я использовал вышеупомянутые функции, я не смог получить важность функций на основе классов. Я просмотрел документацию по scikit learn и немного подправил вышеперечисленные функции, чтобы убедиться, что она работает для моей проблемы. Надеюсь, это вам тоже поможет!

def important_features(vectorizer,classifier,n=20):
class_labels = classifier.classes_
feature_names =vectorizer.get_feature_names()
topn_class1 = sorted(zip(classifier.feature_count_[0], feature_names),reverse=True)[:n]
topn_class2 = sorted(zip(classifier.feature_count_[1], feature_names),reverse=True)[:n]
print("Important words in negative reviews")
for coef, feat in topn_class1:
    print(class_labels[0], coef, feat)
print("-----------------------------------------")
print("Important words in positive reviews")
for coef, feat in topn_class2:
    print(class_labels[1], coef, feat) 

Note that your classifier(in my case it's NaiveBayes) must have attribute feature_count_ for this to work.

45

def show_most_informative_features(vectorizer, clf, n=20):
    feature_names = vectorizer.get_feature_names()
    coefs_with_fns = sorted(zip(clf.coef_[0], feature_names))
    top = zip(coefs_with_fns[:n], coefs_with_fns[:-(n + 1):-1])
    for (coef_1, fn_1), (coef_2, fn_2) in top:
        print "\t%.4f\t%-15s\t\t%.4f\t%-15s" % (coef_1, fn_1, coef_2, fn_2)
Как вы вызываете функцию из основного метода? что означает f1 и f2? Я пытаюсь вызвать функцию из классификатора дерева решений с помощью scikit-learn.
спасибо, только то, что мне было нужно!
Этот код будет работать только с линейным классификатором, который имеетcoef_ массив, так что, к сожалению, я не думаю, что его можно использовать с классификаторами дерева решений sklearn.fn_1 а такжеfn_2 стоять за названиями функций. tobigue
0

RandomForestClassifier еще не имеетcoef_ attrubute, но это будет в версии 0.17, я думаю. Тем не менее, увидетьRandomForestClassifierWithCoef класс вИсключение рекурсивных функций в Random Forest с помощью scikit-learn, Это может дать вам некоторые идеи, чтобы обойти ограничение выше.

14

Чтобы добавить обновление,RandomForestClassifier теперь поддерживает.feature_importances_ приписывать. этоатрибут говорит вам, сколько из наблюдаемой дисперсии объясняется этой особенностью. Очевидно, что сумма всех этих значений должна быть & lt; = 1.

Я нахожу этот атрибут очень полезным при выполнении функций проектирования.

Спасибо команде Scikit-Learn и авторам за реализацию этого!

редактировать: это работает как для RandomForest и GradientBoosting. ТакRandomForestClassifier, RandomForestRegressor, GradientBoostingClassifier а такжеGradientBoostingRegressor все это поддерживают.

56

они просто видят числовые массивы. Тем не менее, если вы извлекли свои функции с помощьюVectorizer/CountVectorizer/TfidfVectorizer/DictVectorizer, and Вы используете линейную модель (например,LinearSVC или Наивный Байес), то вы можете применить тот же трюк, что ипример классификации документов использует. Пример (untested, может содержать ошибку или два):

def print_top10(vectorizer, clf, class_labels):
    """Prints features with the highest coefficient values, per class"""
    feature_names = vectorizer.get_feature_names()
    for i, class_label in enumerate(class_labels):
        top10 = np.argsort(clf.coef_[i])[-10:]
        print("%s: %s" % (class_label,
              " ".join(feature_names[j] for j in top10)))

Это для мультиклассовой классификации; для двоичного случая, я думаю, вы должны использоватьclf.coef_[0] только. Возможно, вам придется отсортироватьclass_labels.

как определяются class_labels? Я хочу знать порядок меток классов.
@RyanRosario: правильно. В двоичном случаеcoef_ сплющен для экономии места.
да, в моих случаях у меня есть только два класса, но с вашим кодом я смог придумать то, что хотел. большое спасибо! tobigue
Для 2 классов это выглядит такcoef_ скорее, чемcoef_[0].
Вы можете получить заказанные классы из классификатора сclass_labels=clf.classes_
9

https://github.com/TeamHG-Memex/eli5), что позволяет сделать это: он обрабатывает различные классификаторы из случаев scikit-learn, двоичного / мультикласса, позволяет выделять текст в соответствии со значениями признаков, интегрируется с IPython и т. д.

0

чтобы создать график важных функций по порядку:

importances = clf.feature_importances_
std = np.std([tree.feature_importances_ for tree in clf.estimators_],
         axis=0)
indices = np.argsort(importances)[::-1]

# Print the feature ranking
#print("Feature ranking:")


# Plot the feature importances of the forest
plt.figure()
plt.title("Feature importances")
plt.bar(range(train[features].shape[1]), importances[indices],
   color="r", yerr=std[indices], align="center")
plt.xticks(range(train[features].shape[1]), indices)
plt.xlim([-1, train[features].shape[1]])
plt.show()
0

что вы ищете, но быстрый способ получить коэффициенты наибольшей величины (предполагая, что столбцы pandas dataframe - ваши имена объектов):

Вы тренировали модель как:

lr = LinearRegression()
X_train, X_test, y_train, y_test = train_test_split(df, Y, test_size=0.25)
lr.fit(X_train, y_train)

Получите 10 самых больших отрицательных значений коэффициента (или измените на обратный = True для наибольшего положительного значения), например:

sorted(list(zip(feature_df.columns, lr.coef_)), key=lambda x: x[1], 
reverse=False)[:10]

Похожие вопросы