使用model.fit训练朴素贝叶斯文本分类模型时触发ValueError
文本分类朴素贝叶斯模型构建报错:样本数不一致
数据样例
获取数据样例的代码:
df_some_observations = filtered_training.sample(frac=0.0001) df_some_observations.to_dict()
输出结果:
{'Intitulé (Ce champ doit respecter la nomenclature suivante : Code action – Libellé)_x': {40219: 'aegua00268 format oper scad htbhta fonction avance', 16820: 'aeedf50490 sort conflit facon construct', 24771: '4022mps192 prepar a lhabilit electr boho indic v personnel non elec', 34482: '3095mceg73 affirmezvous relat professionnel bas ref 7114'}, 'Nœud parent au niveau N y compris moi-même.1': {40219: 'distribu electricit rel reseau electricit ecr exploit conduit reseau electricit', 16820: 'ct competent transvers rhu ressourc humain for pilotag gestion format', 24771: 'ss sant securit prevent prf prevent risqu professionnel hcp habilit certif perm prevent risqu meti', 34482: 'nan'}, 'Thème de formation (Chemin complet)': {40219: 'distribu electricit rel reseau electricit ecr exploit conduit reseau electricit', 16820: 'ct competent transvers rhu ressourc humain for pilotag gestion format', 24771: 'ss sant securit prevent prf prevent risqu professionnel hcp habilit certif perm prevent risqu meti', 34482: 'in ingenier esp equip sous pression'}, 'Description du champ supplémentaire : Objectifs de la formation': {40219: 'nan', 16820: 'nan', 24771: 'prepar a lhabilit electr boho indic v autoris special lissu cet format stagiair doit connaitr risqu electr savoir sen proteg doit etre capabl deffectu oper simpl dexploit suiv certain methodolog', 34482: 'nan'}, 'Objectifs': {40219: 'nan', 16820: 'nan', 24771: 'nan', 34482: 'nan'}, 'Programme de formation': {40219: 'nan', 16820: 'nan', 24771: 'notion elementair delectricit sensibilis risqu electr prevent risqu electr publiqu utec 18 510 definit oper lenviron intervent tbt b appareillag electr bt materiel protect individuel collect manoeuvr mesurag essais verif outillag electr portat a main mis situat coffret didact', 34482: 'nan'}, 'Populations concernées': {40219: 'nan', 16820: 'nan', 24771: 'personnel electricien effectu oper dordr electr', 34482: 'nan'}, 'Prérequis': {40219: 'nan', 16820: 'nan', 24771: 'personnel non electricien effectu oper simpl remplac fusibl rearm disjoncteur rel thermiqu', 34482: 'nan'}, "Description du champ supplémentaire : Commanditaire de l'action": {40219: 'nan', 16820: 'nan', 24771: 'nan', 34482: 'nan'}, "Organisme dispensant l'action": {40219: 'local sei', 16820: 'intern edf', 24771: 'intern edf', 34482: 'intern edf'}, 'Durée théorique (h)': {40219: 14.0, 24771: 11.0, 34482: 14.0}, 'Coût de la catégorie Coût pédagogique': {40219: 0.0, 16820: 0.0, 24771: 0.0, 34482: 0.0}, 'Coût de la catégorie Coût logistique': {40219: 0.0, 16820: 0.0, 24771: 0.0, 34482: 0.0}, }
数据拆分处理
移除不必要列后,按如下代码拆分训练集和测试集(目标变量位于第15列):
df_training = filtered_training.sample(frac=0.8, random_state=42) df_test = filtered_training.drop(df_training.index) X_train = df_training.iloc[:,:14] y_train = df_training.iloc[:,15] X_test = df_test.iloc[:,:14] y_test = df_test.iloc[:,15]
模型构建与报错
使用以下代码构建朴素贝叶斯模型:
model = make_pipeline(TfidfVectorizer(), MultinomialNB()) model.fit(X_train, y_train) predicted_categories = model.predict(X_test)
执行model.fit(X_train, y_train)时触发错误:
ValueError: Found input variables with inconsistent numbers of samples: [14, 35478]
补充数据维度信息
np.shape(X_train) #(35478, 14) np.shape(y_train) #(35478,) np.shape(X_test) #(8870, 14) np.shape(y_test) #(8870,)
问题原因与解决方法
原因
TfidfVectorizer默认仅处理单特征列的文本数据,传入包含14列的DataFrame时,会被识别为14个样本,与标签的35478个样本数不匹配,从而触发错误。
解决方法
方法1:合并所有文本特征列为单一文本列
将X_train中的所有文本型列合并为一列,再传入模型:
# 合并文本列(若存在非文本列,需先筛选出文本列再合并) X_train_combined = X_train.apply(lambda row: ' '.join(row.dropna().astype(str)), axis=1) X_test_combined = X_test.apply(lambda row: ' '.join(row.dropna().astype(str)), axis=1) # 重新训练模型 model = make_pipeline(TfidfVectorizer(), MultinomialNB()) model.fit(X_train_combined, y_train) predicted_categories = model.predict(X_test_combined)
方法2:使用ColumnTransformer处理多列文本
若需要保留各列特征的区分度,可通过ColumnTransformer对每列文本分别做TF-IDF转换后合并特征:
from sklearn.compose import ColumnTransformer # 定义转换规则:对所有列应用TfidfVectorizer transformer = ColumnTransformer( transformers=[ ('tfidf', TfidfVectorizer(), X_train.columns) ]) # 构建并训练模型 model = make_pipeline(transformer, MultinomialNB()) model.fit(X_train, y_train) predicted_categories = model.predict(X_test)
内容的提问来源于stack exchange,提问作者Wajih101
相关产品推荐
相关产品推荐

