这是我第一次尝试用ML和Python进行文档分类。
- 我首先查询我的数据库,提取5000篇与洗钱有关的文章,并将它们转换为熊猫df
- 然后我提取了 500 篇与洗钱无关的文章,并将它们转换为熊猫 df
- 我将两个 dfs 连接起来,并将它们标记为"洗钱"或"其他"
- 我进行预处理(删除标点符号和停用词,小写等)
-
然后根据词袋原理馈送模型,如下所示:
vectorizer = CountVectorizer(analyzer = "word", tokenizer = None, preprocessor = None, stop_words = None, max_features = 5000) text_features = vectorizer.fit_transform(full_df["processed full text"]) text_features = text_features.toarray() labels = np.array(full_df['category']) X_train, X_test, y_train, y_test = train_test_split(text_features, labels, test_size=0.33) forest = RandomForestClassifier(n_estimators = 100) forest = forest.fit(X_train, y_train) y_pred = forest.predict(X_test) accuracy_score(y_pred=y_pred, y_true=y_test)
到目前为止,它工作正常(即使给了我太高的准确度 99%)。但是我现在想在一个全新的文本文档上测试它。如果我对其进行矢量化并执行forest.predict(test)
它显然会说:
ValueError: Number of features of the model must match the input. Model n_features is 5000 and input n_features is 45
我不确定如何克服这一点才能对全新的文章进行分类。
首先,尽管我的主张可能有效,但我强烈强调这样一个事实,即此解决方案具有一些统计和计算结果,您需要在运行此代码之前了解这些结果。假设您有一个初始的文本语料库full_df["processed full text"]
并且test
是您要测试的新文本。然后,让我们用 full_df
和 test
定义full_added
文本语料库。
text_features = vectorizer.fit_transform(full_added)
text_features = text_features.toarray()
您可以使用full_df
作为您的火车组(X_train = full_df["processed full text"]
和y_train = np.array(full_df['category'])
)。然后你可以跑
forest = RandomForestClassifier(n_estimators = 100)
forest = forest.fit(X_train, y_train)
y_pred = forest.predict(test)
当然,在此解决方案中,您已经定义了参数,并且认为模型在新数据上具有鲁棒性。
另一个评论是,如果你有一股新文本作为你想要分析的输入,这个解决方案将是可怕的,因为计算新vectorizer.fit_transform(full_added)
的计算时间会急剧增加。
我希望它有所帮助。
我的第一个朴素贝叶斯实现来自文本blob库。它非常慢,我的机器最终耗尽了内存。
第二次尝试是基于这篇文章 http://zacstewart.com/2015/04/28/document-classification-with-scikit-learn.html 并使用了sklearn.naive_bayes库中的多项式NB。它就像一个魅力:
#initialize vectorizer
count_vectorizer = CountVectorizer(analyzer = "word",
tokenizer = None,
preprocessor = None,
stop_words = None,
max_features = 5000)
counts = count_vectorizer.fit_transform(df['processed full text'].values)
targets = df['category'].values
#divide into train and test sets
X_train, X_test, y_train, y_test = train_test_split(counts, targets, test_size=0.33)
#create classifier
classifier = MultinomialNB()
classifier.fit(X_train, y_train)
#check accuracy
y_pred = classifier.predict(X_test)
accuracy_score(y_true=y_test, y_pred=y_pred)
#check on completely new example
new_counts = count_vectorizer.transform([processed_test_string])
prediction = classifier.predict(new_counts)
prediction
输出:
array(['money laundering'],
dtype='<U16')
而且准确率在91%左右,所以比99.96%更逼真。
正是我想要的。很高兴看到信息量最大的功能,我会尽力解决。谢谢大家。