在Scikit Learn中,从保存的训练分类器中进行预测

3

我在Python中编写了一个用于推文分类的分类器,然后将其保存为.pkl格式并存储在磁盘上,因此我可以再次运行它而不需要每次重新训练。以下是代码:

import pandas
import re
from sklearn.feature_extraction import FeatureHasher

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

from sklearn import cross_validation

from sklearn.externals import joblib


#read the dataset of tweets

header_row=['sentiment','tweetid','date','query', 'user', 'text']
train = pandas.read_csv("training.data.csv",names=header_row)

#keep only the right columns

train = train[["sentiment","text"]]

#remove puctuation, special characters, numbers and lower case the text

def remove_spch(text):

    return re.sub("[^a-z]", ' ', text.lower())

train['text'] = train['text'].apply(remove_spch)


#Feature Hashing

def tokens(doc):
    """Extract tokens from doc.

    This uses a simple regex to break strings into tokens.
    """
    return (tok.lower() for tok in re.findall(r"\w+", doc))

n_features = 2**18
hasher = FeatureHasher(n_features=n_features, input_type="string", non_negative=True)
X = hasher.transform(tokens(d) for d in train['text'])

y = train['sentiment']

X_new = SelectKBest(chi2, k=20000).fit_transform(X, y)

a_train, a_test, b_train, b_test = cross_validation.train_test_split(X_new, y, test_size=0.2, random_state=42)

from sklearn.ensemble import RandomForestClassifier 

classifier=RandomForestClassifier(n_estimators=10)                  
classifier.fit(a_train.toarray(), b_train)                            
prediction = classifier.predict(a_test.toarray()) 

#Export the trained model to load it in another project

joblib.dump(classifier, 'my_model.pkl', compress=9)

假设我有另一个Python文件,并且我想对一条推文进行分类。我该如何进行分类?

from sklearn.externals import joblib
model_clone = joblib.load('my_model.pkl')

mytweet = 'Uh wow:@medium is doing a crowdsourced data-driven investigation tracking down a disappeared refugee boat'

hasher.transform之前,我可以复制相同的过程将其添加到预测模型中,但是现在遇到了一个问题,我无法计算最佳的20k个特征。要使用SelectKBest,您需要同时添加特征和标签。由于我想预测标签,所以我不能使用SelectKBest。那么,我该如何解决这个问题以继续进行预测呢?


我不应该从同样的预处理中传递文本,然后尝试进行预测吗?如果我只是将文本作为列表传递,然后经过分类器处理,就会出现以下错误:ValueError: could not convert string to float: Uh wow:@medium is doing a crowdsourced data-driven investigation tracking down a disappeared refugee boat - Tasos
你需要执行与训练时相同的特征提取,并将其作为数据传递。 - EdChum
@EdChum,这是我的问题。在之前的特征提取中,我有一个大数据集用于训练。它是一个带标签的数据集,我使用文本和标签来找到特征。现在当我只有一条推文或者一个包含10条推文但没有标签的列表时,我该如何再次进行呢?因为我正在尝试进行预测。如果您能提供具体的细节作为答案,我将不胜感激 :) - Tasos
什么意思没有标签?我不明白为什么不能再次提取特征?你需要编写代码,以便提取与训练时使用的相同特征。 - EdChum
1
抱歉,重点是使用您的模型来预测标签,其是否正确是由决定的。关键在于通过训练数据构建模型,这些数据可能足够代表它处理未见过的数据。 - EdChum
显示剩余2条评论
1个回答

5

我支持@EdChum的评论,即

你通过在数据上进行训练来构建模型,这些数据可能足够代表性,以便它能够处理未见过的数据

实际上,这意味着您需要仅使用predictFeatureHasherSelectKBest应用于新数据。(在新数据上重新训练FeatureHasher是错误的,因为通常会产生不同的特征)。

要做到这一点,可以选择:

  • 分别pickle FeatureHasherSelectKBest

或者(更好的方式)

  • 创建一个包含FeatureHasher、SelectKBest和RandomForestClassifierPipeline,然后pickle整个pipeline。然后,您可以加载此pipeline并对新数据使用predict

看起来是有效的,但不幸的是,我以前没有创建过“管道”。您能否也提供一下在我的示例中的步骤? - Tasos
1
Scikit learn在他们的网站上有一个很好的例子。 - Rick
有没有办法将分类器标签与流水线一起传递进去? - MyopicVisage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接