使用SGDClassifier的partial_fit方法进行增量/在线学习

我已经构建了一个增量学习模型,但不确定它是否正确。我有两组训练数据,第一组包含20000行,第二组包含10000行,两者都有两个列:描述和ID…在离线学习的情况下,我的模型运行良好,能够为给定的描述正确分类ID…datafile_train是第一组训练数据,datafile_train1是第二组训练数据。我使用SGDClassifier和partial_fit方法进行增量学习

1) Countvectorizer、tfidf和partial_fit

vectorizer = CountVectorizer()tfidf_transformer = TfidfTransformer()X_train = vectorizer.fit_transform(datafile_train.loc[:,'description'])X_train_tfidf = tfidf_transformer.fit_transform(X_train)clf = linear_model.SGDClassifier(penalty='l2',loss='hinge')prd=clf.partial_fit(X_train_tfidf, datafile_train.loc[:,'taxonomy_id'],classes=np.unique(datafile_train.loc[:,'taxonomy_id']))

之后,我将分类器序列化并再次反序列化以用于下一次partial_fit进行增量学习

2) 分类器的序列化和反序列化

def store(prd):    import pickle    filename = "incremental"    f = open(filename, 'wb')    pickle.dump(prd, f)    f.close()store(prd)def train_data():    import pickle    f = open('incremental', 'rb')    classifier = pickle.load(f)    f.close()    return classifier    clfp=train_data()

3) 再次对新数据使用Countvectorizer、tfidf和partial_fit

vectorizer = CountVectorizer()tfidf_transformer = TfidfTransformer()X_train1 = vectorizer.fit_transform(datafile_train1.loc[:,'description'])X_train_tfidf1 = tfidf_transformer.fit_transform(X_train1)prd1=clfp.partial_fit(X_train_tfidf1, datafile_train1.loc[:,'taxonomy_id'])# 这里的clfp是之前训练过的数据,已经反序列化

我按照这种方式构建了模型,但当我检查第一个训练数据的序列化文件大小时,它是5 MB,当我使用这个模型来训练新数据时,如您在第二个partial_fit中看到的,我使用了clfp(大小为5 MB),在训练新数据后,当我为第二个partial_fit序列化训练文件时,它也显示只有5 MB大小,因为我在之前训练的数据上训练了新数据,所以它应该得到更新。这是否是实现增量/在线学习的正确方法?请帮助我,我是机器学习的新手,所以如果您能用代码解释会更好

并且抛出了这个错误

ValueError: Number of features 125897 does not match previous data 124454.

****编辑(使用Hashingvectorizer)

hashing = HashingVectorizer()X_train_hashing=hashing.fit_transform(datafile_train.loc[:,'description'])clf = linear_model.SGDClassifier(penalty='l2',loss='hinge')prd=clf.partial_fit(X_train_hashing, datafile_train.loc[:,'taxonomy_id'],classes=np.unique(datafile_train.loc[:,'taxonomy_id']))def store(prd):    import pickle    filename = "inc"    f = open(filename, 'wb')    pickle.dump(prd, f)    f.close()store(prd)def train_data():    import pickle    f = open('inc', 'rb')    classifier = pickle.load(f)    f.close()    return classifier clfp=train_data()

现在我使用clfp训练模型进行下一次partial_fit

X_train_hashing1=hashing.transform(datafile_train1.loc[:,'description'])prd1=clfp.partial_fit(X_train_hashing1, datafile_train1.loc[:,'taxonomy_id'])def store(prd1):    import pickle    timestr = time.strftime("%Y%m%d-%H%M%S")    filename = "Train-" + timestr +".pickle"    f = open(filename, 'wb')    pickle.dump(prd1, f)    f.close()store(prd1) 

在这一次编辑中,没有出现任何错误,但两个序列化文件的大小都是25.2 MB,但第二个序列化文件的大小应该大于第一个序列化文件,因为我在新数据上使用了第一个训练模型


回答:

我认为保存的模型大小不应该增加很多,或者可能根本不会增加。

模型不会存储发送到partial_fit()的整个新数据,只会根据这些数据更新其属性。这些属性一旦根据它们的类型(如float32, float64等)分配了存储空间,无论它们的值如何,都会占据相同的空间。

在SGDClassifier中会发生变化的显著属性包括:

coef_ : 数组,形状为(1, n_features) 如果n_classes == 2 否则为(n_classes, n_features) 分配给特征的权重。

intercept_ : 数组,形状为(1,) 如果n_classes == 2 否则为(n_classes,) 决策函数中的常数项。

所以当您初始化模型时,这些属性要么未分配,要么全部初始化为0。一旦您将第一组数据传递给partial_fit(),这些值会根据数据更新,试图最小化预测的损失。

当您传递新数据时,这些值再次更新,但它们仍然占据与其类型(如float32, float64等)指定的相同存储空间。

所以这就是保存的模型大小没有变化的原因。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注