Используя информацию, описанную в этом вопросе, Combining random forest models in scikit learn , я попытался объединить несколько случайных лесных классификаторов в единый классификатор с использованием python2.7.10 и sklearn 0.16.1, но получить это исключение в в некоторых случаях:Неожиданное исключение при объединении случайных лесных деревьев
Traceback (most recent call last):
File "sktest.py", line 50, in <module>
predict(rf)
File "sktest.py", line 46, in predict
Y = rf.predict(X)
File "/python-2.7.10/lib/python2.7/site-packages/sklearn/ensemble/forest.py", line 462, in predict
proba = self.predict_proba(X)
File "/python-2.7.10/lib/python2.7/site-packages/sklearn/ensemble/forest.py", line 520, in predict_proba
proba += all_proba[j]
ValueError: non-broadcastable output operand with shape (39,1) doesn't match the broadcast shape (39,2)
приложения для создания ряда случайных лесных классификаторов на многих процессорах и объединить эти объекты в единый классификатор доступного для всех процессоров.
Код ошибки для создания этого исключения приведен ниже, он создает 5 классификаторов со случайным числом массивов из 10 функций. Если yfrac изменен на 0.5, код не даст исключения. Является ли это допустимым методом объединения объектов классификатора? Кроме того, это же исключение создается при использовании warm_start для добавления деревьев к существующему RandomForestClassifier, когда n_estimators увеличиваются, а данные добавляются через fit.
from sklearn.ensemble import RandomForestClassifier
from sklearn.cross_validation import train_test_split
from numpy import zeros,random,logical_or,where,array
random.seed(1)
def generate_rf(X_train, y_train, X_test, y_test, numTrees=50):
rf = RandomForestClassifier(n_estimators=numTrees, n_jobs=-1)
rf.fit(X_train, y_train)
print "rf score ", rf.score(X_test, y_test)
return rf
def combine_rfs(rf_a, rf_b):
rf_a.estimators_ += rf_b.estimators_
rf_a.n_estimators = len(rf_a.estimators_)
return rf_a
def make_data(ndata, yfrac=0.5):
nx = int(random.uniform(10,100))
X = zeros((nx,ndata))
Y = zeros(nx)
for n in range(ndata):
rnA = random.random()*10**(random.random()*5)
X[:,n] = random.uniform(-rnA,rnA, nx)
Y = logical_or(Y,where(X[:,n] > yfrac*rnA, 1.,0.))
return X, Y
def train(ntrain=5, ndata=10, test_frac=0.2, yfrac=0.5):
rfs = []
for u in range(ntrain):
X, Y = make_data(ndata, yfrac=yfrac)
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=test_frac)
#Train the random forest and add to list
rfs.append(generate_rf(X_train, Y_train, X_test, Y_test))
# Combine the block classifiers into a single classifier
return reduce(combine_rfs, rfs)
def predict(rf, ndata=10):
X, Y = make_data(ndata)
Y = rf.predict(X)
if __name__ == "__main__":
rf = train(yfrac = 0.42)
predict(rf)