SVM训练遇样本数不一致报错,排查后仍存疑问求助
解决SVM训练时样本数不一致的问题
问题根源
你遇到的错误核心是Pipeline中的TfidfVectorizer无法直接处理多列特征。当传入包含text和length的DataFrame时,TfidfVectorizer会错误地将每一列视为一个独立"文档",最终输出仅2个样本(对应两列),但y_train有8000个样本,导致样本数不匹配,触发ValueError。仅用text列时,TfidfVectorizer处理的是8000个文本样本,因此能正常运行。
解决方案
需要用ColumnTransformer分别处理不同类型的特征:
- 对
text列使用TfidfVectorizer提取文本特征 - 对
length列直接保留或做标准化处理
将两者的特征合并后,再传入SVM模型。
修改后的完整代码
data = '/kaggle/input/200k-short-texts-for-humor-detection/dataset.csv' df = pd.DataFrame(pd.read_csv(data,nrows=10000)) # 标签编码 df['humor'] = np.where(df['humor'],1,0) import nltk from nltk.tokenize import word_tokenize from nltk.stem.porter import PorterStemmer nltk.download('wordnet') nltk.download('stopwords') sw = set(stopwords.words('english')) stemmer = PorterStemmer() def preproc(sentence): sentence = [w.lower() for w in sentence if w.isalpha()] sentence = [stemmer.stem(word) for word in sentence] return ' '.join(sentence) new_data = [] for sentence in df['text']: sentence = word_tokenize(sentence) sentence = preproc(sentence) new_data.append(sentence) new_data = pd.DataFrame(new_data, columns=["text"]) new_data['humor'] = df['humor'].tolist() new_data['length'] = new_data['text'].apply(len) # 导入必要工具 from sklearn.svm import SVC from sklearn.pipeline import make_pipeline from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split from sklearn.compose import ColumnTransformer from sklearn.preprocessing import StandardScaler X = new_data[['text','length']] y = new_data['humor'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 构建特征预处理管道 preprocessor = ColumnTransformer( transformers=[ ('text_tfidf', TfidfVectorizer(), 'text'), # 处理文本列 ('num_scaler', StandardScaler(), ['length']) # 标准化数值列,提升SVM性能 ]) # 完整训练管道:预处理 + SVM pipe_new = make_pipeline(preprocessor, SVC()) pipe_new.fit(X_train, y_train) # 输出测试集评分 print(pipe_new.score(X_test, y_test))
关键说明
ColumnTransformer的作用是针对不同列应用不同预处理逻辑,确保文本和数值特征被正确处理并合并。- 若不想对
length列做标准化,可将StandardScaler()替换为'passthrough',直接保留原始值:('num_passthrough', 'passthrough', ['length'])。 - SVM对特征尺度敏感,标准化
length列通常能提升模型性能。
内容的提问来源于stack exchange,提问作者Anon_name
相关产品推荐
相关产品推荐

