我是机器学习的新手,正在尝试使用scikit的RandomForestClassifier对文本进行分类。我的问题是我的测试数据结果与sklearn的分类报告不匹配。训练集大约有25k个样本,其中大约25%被标记为1,75%标记为0。我还有一个额外的1k测试集,用于训练后的测试。
# 训练
vectorizer = TfidfVectorizer(max_features=40, stop_words=stopwords.words('english')) X = vectorizer.fit_transform(documents).toarray() X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, random_state=0) classifier = RandomForestClassifier( n_jobs=-1, bootstrap=False, n_estimators=200, random_state=0) classifier.fit(X_train, y_train) y_pred = classifier.predict(X_test) print(confusion_matrix(y_test, y_pred)) print(classification_report(y_test, y_pred)) print(accuracy_score(y_test, y_pred)) precision recall f1-score support 0 0.98 0.99 0.98 4231 1 0.95 0.90 0.92 883accuracy 0.97 5114
# 测试
df = pandas.read_csv(input_file, header=None)df.columns = ["data", "target"]df, y = df.data, df.targettest_documents = []for body in range(0, len(df)): document = str(df[body]) test_documents.append(document)X = vectorizer.fit_transform(test_documents).toarray()prediction = pd.DataFrame(classifier.predict(X)) precision recall f1-score support 0 0.89 0.87 0.88 856 1 0.38 0.42 0.40 154
回答:
我原本希望@某人会添加这个内容,但现在由我来做。
尝试在您的测试代码中使用以下内容:
测试
df = pandas.read_csv(input_file, header=None)df.columns = ["data", "target"]df, y = df.data, df.targettest_documents = []for body in range(0, len(df)): document = str(df[body]) test_documents.append(document)X = vectorizer.transform(test_documents).toarray() #这里是变化的地方!prediction = pd.DataFrame(classifier.predict(X))
注意变化…我们现在使用vectorizer的transform方法。我假设您可以将这段测试代码放入与训练代码相同的文件中,这样您的vectorizer对象仍然存在。
您使用transform而不是fit_transform的原因是,您已经使用带有特定词汇表的vectorizer训练了模型,而在测试期间可能会出现新词。使用现有的vectorizer将忽略这些新词/组合,并且有助于保持您的tdif向量一致。相反,使用fit_transform会重新创建您的vectorizer,可能会有小或大的差异。
编辑:您可能也想尝试一下逻辑分类器…有时候它在这类数据上也能取得不错的结果。