2017-04-25 9 views
0

:)
非常抱歉,如果我的代码看起来像一个总新手会写的东西。下面是python中的一部分代码。我在摆弄sklearn和机器学习技术。 我根据不同的数据集训练了几个朴素贝叶斯模型,并将它们存储在trained_models 在此步骤之前,我使用chi2函数为特征选择创建了SelectPercentile类的对象​​。
从我的理解,我应该写data_feature_reduced = chi_squared.transform(some_data)然后使用data_feature_reduced在这样的训练时间,即:nb.fit(data_feature_reduced, data.target)
这是什么做的,存储在结果对象列表trained_models nb(和其他一些信息功能选择sklearn - ValueError:X有一个不同的形状比拟合

我现在尝试在不同的数据集的应用这些模型(实际上是从同一来源,如果该事项的问题)

for name, model, intra_result, dev, training_data, chi_squarer in trained_models: 
    cross_results = [] 
    new_vect= StemmedVectorizer(ngram_range=(1, 4), stop_words='english', max_df=0.90, min_df=2) 
    for data in demframes: 
     data_name = data[0] 
     X_test_data = new_vect.fit_transform(data[1].values.astype('U')) 
     Y_test_data = data[2] 
     chi_squared_test_data = chi_squarer.transform(X_test_data) 
     final_results.append((name, "applied to", data[0], model.score(X_test_data,Y_test_data))) 

我不得不承认,我有点陌生到功能选择部分 这里是我的错误:

ValueError: X has a different shape than during fitting. 

在行chi_squared_test_data = chi_squarer.transform(X_test_data)

我假设我做特征选择的方式不正确,在哪里我会错呢?

+2

这个错误是由于这一行'new_vect。 fit_transform()'。就像你的训练模型一样,你应该使用在训练时使用的相同的“StemmedVectorizer” –

+0

我认为这就是我所做的。或者我应该使用相同的对象?它会有什么不同? – GuidoKaz

+2

与已经训练的模型和未经训练的模型具有相同的区别。相同的StemmedVectorizer对象会将'X_test_data'转换为相同的形状,即训练过程中的形状。目前,你正在使用不同的对象和拟合(fit_transform是合适的和变换),因此形状是不同的。因此错误 –

回答

0

为什么不使用管道使其变得简单?这样你就不需要变换两次并且保持形状。

from sklearn.feature_selection import SelectKBest 
from sklearn.feature_selection import chi2 
from sklearn.pipeline import Pipeline 
from sklearn.linear_model import LogisticRegression 

chi_squarer = SelectKBest(chi2, k=100) # change accordingly 
lr = LogisticRegression() # or naive bayes 

clf = pipeline.Pipeline([('chi_sq', chi_squarer), ('model', lr)]) 

# for training: 
clf.fit(training_data, targets) 

# for predictions: 
clf.predict(test_data) 

,你还可以在管道中添加new_vect

+0

是的。数据 - >使用你的矢量 - >使用管道。根据您的需要改变k的模型和价值。在这里阅读关于管道的更多信息:http://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html –

+0

我想使用已经训练好的模型进行预测,不会调用pipeline中的fit方法 - 模型?我正在检查新数据的准确性 – GuidoKaz

0

感谢大家的帮助:) 我只粘贴帮我从@维韦克 - 库马尔解决我的问题的评论。

“这个错误是由于该行new_vect.fit_transform()。就像你训练的模型,你应该使用相同的StemmedVectorizer这是在训练时使用

同样StemmedVectorizer对象将转换X_test_data以相同的形状,它在训练过程中有什么,目前你正在使用不同的对象和拟合(fit_transform是拟合和变换),因此形状是不同的,因此错误“