В двоичной текстовой классификации с scikit-learn с SGDClassifier линейной моделью на TF-IDF представлении пакета слов я хочу получить значения функций поКласс через модели коэффициентов. Я слышал расходящиеся мнения, следует ли масштабировать столбцы (объекты) с помощью StandardScaler (with_mean = False) или нет для этого случая.
При разреженных данных центрирование данных до масштабирования не можетбыть сделано в любом случае (with_mean = False часть). Строка TfidfVectorizer по умолчанию также L2 нормализует каждый экземпляр уже. Основываясь на эмпирических результатах, таких как приведенный ниже автономный пример, кажется, что лучшие функции для каждого класса более интуитивно понятны, если не использовать StandardScaler. Например, 'nasa' и 'space' - это главные токены для sci.space, а 'god' и 'христиане' для talk.religion.misc и т. Д.
Я что-то упустил? Следует ли использовать StandardScaler (with_mean = False) для получения значений признаков из коэффициентов линейной модели в таких случаях НЛП?
Эти значения функций без StandardScaler (with_mean = False) в подобных случаях все еще ненадежны с теоретической точки зрения?
# load text from web
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train', remove=('headers', 'footers', 'quotes'),
categories=['sci.space','talk.religion.misc'])
newsgroups_test = fetch_20newsgroups(subset='test', remove=('headers', 'footers', 'quotes'),
categories=['sci.space','talk.religion.misc'])
# setup grid search, optionally use scaling
from sklearn.pipeline import Pipeline
from sklearn.linear_model import SGDClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import StandardScaler
text_clf = Pipeline([
('vect', TfidfVectorizer(ngram_range=(1, 2), min_df=2, max_df=0.8)),
# remove comment below to use scaler
#('scaler', StandardScaler(with_mean=False)),
#
('clf', SGDClassifier(random_state=0, max_iter=1000))
])
from sklearn.model_selection import GridSearchCV
parameters = {
'clf__alpha': (0.0001, 0.001, 0.01, 0.1, 1.0, 10.0)
}
# find best model
gs_clf = GridSearchCV(text_clf, parameters, cv=8, n_jobs=-1, verbose=-2)
gs_clf.fit(newsgroups_train.data, newsgroups_train.target)
# model performance, very similar with and without scaling
y_predicted = gs_clf.predict(newsgroups_test.data)
from sklearn import metrics
print(metrics.classification_report(newsgroups_test.target, y_predicted))
# use eli5 to get feature importances, corresponds to the coef_ of the model, only top 10 lowest and highest for brevity of this posting
from eli5 import show_weights
show_weights(gs_clf.best_estimator_.named_steps['clf'], vec=gs_clf.best_estimator_.named_steps['vect'], top=(10, 10))
# Outputs:
No scaling:
Weight? Feature
+1.872 god
+1.235 objective
+1.194 christians
+1.164 koresh
+1.149 such
+1.147 jesus
+1.131 christian
+1.111 that
+1.065 religion
+1.060 kent
… 10616 more positive …
… 12664 more negative …
-0.922 on
-0.939 it
-0.976 get
-0.977 launch
-0.994 edu
-1.071 at
-1.098 thanks
-1.117 orbit
-1.210 nasa
-2.627 space
StandardScaler:
Weight? Feature
+0.040 such
+0.023 compuserve
+0.021 cockroaches
+0.017 how about
+0.016 com
+0.014 figures
+0.014 inquisition
+0.013 time no
+0.012 long time
+0.010 fellowship
… 11244 more positive …
… 14299 more negative …
-0.011 sherzer
-0.011 sherzer methodology
-0.011 methodology
-0.012 update
-0.012 most of
-0.012 message
-0.013 thanks for
-0.013 thanks
-0.028 ironic
-0.032 <BIAS>