使用SGD分类器偏位方法的增量/在线学习



我已经建立了一个增量学习模型,但不确定它是对是错。我有两个训练数据,第一个由20000行组成,第二个由10000行组成,这两个数据都有两列的描述和id…在离线学习的情况下,我的模型运行良好,它为给定的描述分类了正确的id。。datafile_train是第一个训练数据datafile_train1是第二个训练数据我正在使用SGD分类器和偏位方法进行增量

1) 计数矢量器、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']))

在此之后,我对分类器进行了pickle,并再次取消pickle以在下一个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) 再次计数矢量器,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'])
# here clfp is previously trained data which is unpickled

我有这样的构建模型,但当我检查pickle文件(第一个训练的数据)的大小时,它是5 MB,当我使用这个模型训练新数据时,正如你在第二个部分拟合中看到的那样,我在训练新数据后使用了clfp(5 MB大小)这是实现增量/在线学习的正确方法吗??请帮忙,我是机器学习的新手,所以如果你解释使用代码会很好

这个错误被抛出

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

****编辑(使用哈希矢量器)

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-train模型进行下一个部分比特

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) 

在这个EDIT中,它没有给出任何错误,但两个pickle文件都有相同的大小25.2 MB,但第二个pickles大小应该大于第一个pickled大小,因为我在新数据上使用第一个训练的模型

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

该模型不存储发送到partial_fit()的所有新数据,只是根据这些数据更新其属性。这些属性一旦根据其类型(float32, float64等)分配了一些存储空间,无论其值如何,都将占用那么多空间。

SGD分类器中会发生变化的显著属性有:-

coeff_:数组,形状(1,n_features)如果n_classes==2 else(n_classes,n_feature)分配给特征的权重。

intercept_:数组,shape(1,)if n_classes==2 else(n_classes,)决策函数中的常量。

因此,在初始化模型时,它们要么未分配,要么全部初始化为0。一旦您将第一个数据传递给partial_fit(),这些值就会根据数据进行更新,以尽量减少预测的损失。

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

所以这就是保存的模型没有改变尺寸的原因。

最新更新