【sklearn】训练集和测试集维度不一致问题(svm调用predict出现ValueError: X.shape should be equal to或者Dimension mismatch等问题

【sklearn】训练集和测试集维度不一致问题(调用predict出现Dimension mismatch ValueError: X.shape should be equal to 等

问题记录

在使用TF-IDF 进行文本训练时,首先svm在predict时出现报错:

ValueError: X.shape[1] = 3216 should be equal to 8610, the number of features at training time

我暂时注释掉svm模型,使用MultinomialNB模型,仍然在predict出出现

ValueError: dimension mismatch

可见并不是单个模型原因,是数据处理出了问题

寻找答案

svm搜索

使用svm报错的关键词搜索,发现使用scikit-learn python的线性SVM时的ValueError
上面链接中给出的解释是

一种可能性是它们作为稀疏矩阵加载,并且load_svmlight_file推断出特征的数量 . 如果测试数据包含训练数据未见的特征,则生成的 X_test 可能具有更大的维度 . 要避免这种情况,可以通过传递参数 n_features 来指定 load_svmlight_file 中的要素数 .

也就是说测试集中包含训练集中没有的数据,建议使用load_svmlight_file读取数据时指定n_feature这个参数。
sklearn.datasets.load_svmlight_file该函数的说明介绍,但是我之前也没有使用这个函数读文件,修改困难,所以寻找其它方法解决问题。

MultinomialNB报错搜索

使用朴素贝叶斯模型的报错搜索问题,发现这个相关回答非常多,找对了。
答案较多,附上其中一个链接sklearn调用朴素贝叶斯.predict()报错dimension mismatch
上面说

fit():就是求得训练集的均值,方差,最大值,最小值,这些训练集的固有属性。
transform():在fit的基础上,进行标准化,降维,归一化等操作。
fit_transform():fit_transform是fit和transform的组合,既包括了训练又包含了转换。transform()和fit_transform()二者的功能都是对数据进行某种统一处理(比如标准化~N(0,1),将数据缩放(映射)到某个固定区间,归一化,正则化等)

需要修改为

tf = TfidfVectorizer()
tf.fit_tranform(X_train)
tf.tranform(X_test)

翻译一下就是,fit_transorm 又训练又变换了,然后对于测试集的文件只需要使用归一化操作
我仔细检测我自己的文件,果然发现,一开始写的TF-IDF中,对于变量的处理是tf.fit_tranform 函数,然后测试集也直接调用了该函数,所以出错。

但当我修改了该函数发现了新的报错

ValueError: Input has n_features=3216 while the model has been trained with n_features=8610

问题解决

为什么仍然出现维度不对的情况呢,我又搜索了新的报错,发现链接
ValueError: Input has n_features=10 while the model has been trained with n_features=4261
上面给的解答方案没看懂,但他说

您没有保留最初适合数据的 CountVectorizer。
这个 bagOfWords 调用在它自己的范围内安装了一个单独的 CountVectorizer。
new_word_counts = util.bagOfWords([“a place to listen to music it s making its way to the us”])
您想使用适合您的训练集的那个。
你也在用整个 X 训练你的转换器,包括 X_test。您希望从任何培训(包括转换)中排除您的测试测试。

CountVectorizer 仍然在被x_test训练,又仔细查看代码发现,CountVectorizer那里漏了一个fit_tranform没修改。因此附上修改后的代码

vectorizer = CountVectorizer(min_df=1e-5) #将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频  
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(vectorizer.fit_transform(contents) #计算个词语出现的次数)   
tfidf_test = transformer.transform(vectorizer.transform(content_test))#将词频矩阵X统计成TF-IDF值 

猜你喜欢

转载自blog.csdn.net/m0_54352040/article/details/123947961
今日推荐