【发布时间】:2022-01-12 03:52:12
【问题描述】:
这是我的代码:
from sklearn.linear_model import SGDClassifier, LogisticRegression
from sklearn.metrics import classification_report, accuracy_score
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.preprocessing import LabelEncoder, MaxAbsScaler
from sklearn.metrics import precision_recall_fscore_support
from sklearn.decomposition import TruncatedSVD
from scipy.sparse import csr_matrix, hstack
import os
sgd_classifier = SGDClassifier(loss='log', penalty='elasticnet', max_iter=30, n_jobs=60, alpha=1e-6, l1_ratio=0.7, class_weight='balanced', random_state=0)
vectorizer = TfidfVectorizer(analyzer="char_wb", ngram_range=(4,4), min_df=10)
X_train = vectorizer.fit_transform(X_text_train.ravel())
X_test = vectorizer.transform(X_text_test.ravel())
print('TF-IDF number of features:', len(vectorizer.get_feature_names()))
scaler = MaxAbsScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
print('Inputs shape:', X_train.shape)
sgd_classifier.fit(X_train, y_train)
y_predicted = sgd_classifier.predict(X_test)
y_predicted_prob = sgd_classifier.predict_proba(X_test)
results_report = classification_report(y_test, y_predicted, labels=classes_trained, digits=2, output_dict=True)
df_results_report = pd.DataFrame.from_dict(results_report)
pd.set_option('display.max_rows', 300)
print(df_results_report.transpose())
X_text_train & X_text_test 的形状分别为 (2M, 2) 和 (100k, 2)。
他们的第一栏是关于金融交易的描述,一般来说每个描述由5-15个单词组成;所以每行包含大约 5-15 个单词。 第二列是一个分类变量,只有与该银行交易相关的银行名称。
我将这两列合并到一个描述中,所以现在 X_text_train 和 X_text_test 的形状分别为 (2M, ) 和 (100k, )。
然后我应用 TF-IDF,现在 X_text_train 和 X_text_test 的形状分别为 (2M, 50k) 和 (100k, 50k)。
我观察到的是,当第二列上有一个看不见的值(因此合并描述中的新银行名称)时,SGDClassifier 会返回一些非常不同且完全随机的预测,而不是如果我完全放弃它会返回的预测第二列是银行名称。
如果我只对描述执行 TF-IDF 并将银行名称单独保留为分类变量,也会发生同样的情况。
为什么SGDClassifier 会发生这种情况?
是不是因为 SGD 以这种随机方式收敛,所以一般来说 SGD 不能很好地处理所有看不见的值?
有趣的是,在 TF-IDF 上,词汇表是预先确定的,因此测试集中看不见的值基本上不会在特征中考虑(即所有各自的特征都只有 0 作为值),但仍然是新元突破。
(我也在 skLearn 的 Github https://github.com/scikit-learn/scikit-learn/issues/21906 上发布了这个)
【问题讨论】:
-
能否添加堆栈跟踪错误?
-
您好@AntoineDubuis,谢谢您的提问。在严格的一般意义上没有错误,只是 SGDClassifier 在遇到看不见的值时会返回一些非常不同且非常随机的预测(即使只是一个或几个特征,而不是全部)。不确定这是否有帮助。
标签: machine-learning scikit-learn stochastic-gradient