在sklearn中是否需要对Vectorizers进行缩放?

我有一组自定义特征和一组使用Vectorizers创建的特征,在这种情况下使用的是TfidfVectorizer。

我所有的自定义特征都是简单的np.arrays(例如[0, 5, 4, 22, 1])。我使用StandardScaler来缩放所有特征,你可以在我的Pipeline中看到,在我的“custom pipeline”之后调用StandardScaler。问题是,我是否有必要或有方法来缩放我在“vectorized_pipeline”中使用的Vectorizers。在Vectorizers上应用StandardScaler似乎不起作用(我得到以下错误:“ValueError: Cannot center sparse matrices”)。

还有另一个问题,在我将它们合并到FeatureUnion之后,是否有必要缩放所有特征,还是应该分别缩放它们(在我的例子中,通过在“pos_cluster”和“stylistic_features”中分别调用缩放器,而不是在它们合并之后调用),哪种做法更好?

from sklearn.pipeline import FeatureUnion, Pipelinefrom sklearn import feature_selectionfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.preprocessing import StandardScalerfrom sklearn.svm import LinearSVCX = ['I am a sentence', 'an example']Y = [1, 2]X_dev = ['another sentence']inner_scaler = StandardScaler()# classifierLinearSVC1 = LinearSVC(tol=1e-4,  C = 0.10000000000000001)# vectorizerscountVecWord = TfidfVectorizer(ngram_range=(1, 3), max_features=2000, analyzer=u'word', sublinear_tf=True, use_idf = True, min_df=2, max_df=0.85, lowercase = True)countVecWord_tags = TfidfVectorizer(ngram_range=(1, 4), max_features= 1000, analyzer=u'word', min_df=2, max_df=0.85, sublinear_tf=True, use_idf = True, lowercase = False)pipeline = Pipeline([    ('union', FeatureUnion(            transformer_list=[            ('vectorized_pipeline', Pipeline([                ('union_vectorizer', FeatureUnion([                    ('stem_text', Pipeline([                        ('selector', ItemSelector(key='stem_text')),                        ('stem_tfidf', countVecWord)                    ])),                    ('pos_text', Pipeline([                        ('selector', ItemSelector(key='pos_text')),                        ('pos_tfidf', countVecWord_tags)                    ])),                ])),                ])),            ('custom_pipeline', Pipeline([                ('custom_features', FeatureUnion([                    ('pos_cluster', Pipeline([                        ('selector', ItemSelector(key='pos_text')),                        ('pos_cluster_inner', pos_cluster)                    ])),                    ('stylistic_features', Pipeline([                        ('selector', ItemSelector(key='raw_text')),                        ('stylistic_features_inner', stylistic_features)                    ]))                ])),                    ('inner_scale', inner_scaler)            ])),            ],            # weight components in FeatureUnion            # n_jobs=6,            transformer_weights={                'vectorized_pipeline': 0.8,  # 0.8,                'custom_pipeline': 1.0  # 1.0            },    )),    ('clf', classifier),    ])pipeline.fit(X, Y)y_pred = pipeline.predict(X_dev)

回答:

首先要说的是:

错误“Cannot center sparse matrices”

原因很简单 – StandardScaler有效地应用了按特征的变换:

f_i = (f_i - mean(f_i)) / std(f_i)

对于稀疏矩阵,这将导致密集矩阵,因为mean(f_i)通常不为零。实际上,只有等于其均值的特征才会变为零。Scikit learn不希望这样做,因为这会对你的数据进行巨大的修改,可能会导致代码的其他部分出现故障,占用大量内存等。如何处理这个问题?如果你真的想这样做,有两个选项:

  • 通过.toarray()将你的矩阵密集化,这将需要大量内存,但会给你期望的结果
  • 创建一个不计算均值的StandardScaler,即StandardScaler(with_mean = False),这将应用f_i = f_i / std(f_i),但会保留数据的稀疏格式。

是否需要缩放?

这是一个完全不同的问题 – 通常,任何形式的缩放只是一种启发式方法。这不是你必须应用的东西,没有保证它会有所帮助,这只是当你不知道你的数据是什么样子时,合理的事情。“智能”向量化器,如tfidf,实际上已经在做这件事了。idf变换的目的是创建一种合理的数据缩放。没有保证哪一种会更好,但总的来说,tfidf应该足够了。特别是考虑到它仍然支持稀疏计算,而StandardScaler则不支持。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注