随机森林进一步改进

Random Forest further improvement

按照 Jason Brownlee 的教程,我开发了自己的随机森林分类器代码。我把它贴在下面,我想知道我可以做些什么进一步的改进来提高我的代码的准确性

from numpy import mean
from numpy import std
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import RandomForestClassifier
from matplotlib import pyplot


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.05, shuffle = True, random_state=0)

scaler = StandardScaler()
x_train = scaler.fit_transform(X_train)

x_test = scaler.transform(X_test)



# get a list of models to evaluate
def get_models():
    models = dict()
    # consider tree depths from 1 to 7 and None=full
    depths = [i for i in range(1,8)] + [None]
    for n in depths:
        models[str(n)] = RandomForestClassifier(max_depth=n)
    return models

# evaluate  model using cross-validation
def evaluate_model(model, X, y):
    # define the evaluation procedure
    cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
    # evaluate the model and collect the results
    scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
    return scores


# get the models to evaluate
models = get_models()
# evaluate the models and store results
results, names = list(), list()
for name, model in models.items():
    # evaluate the model
    scores = evaluate_model(model, X, y)
    # store the results
    results.append(scores)
    names.append(name)
    # summarize the performance along the way
    print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores)))
# plot model performance for comparison
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()

数据,X 是 (140,20000) 的矩阵,y 是 (140,) 分类矩阵。

我得到了以下结果,但想探索如何进一步提高准确性。

>1 0.573 (0.107)
>2 0.650 (0.089)
>3 0.647 (0.118)
>4 0.676 (0.101)
>5 0.708 (0.103)
>6 0.698 (0.124)
>7 0.726 (0.121)
>None 0.700 (0.107)

以下是让我印象深刻的地方:

  • 您拆分了数据但未使用拆分。
  • 您正在缩放数据,但 tree-based 随机森林等方法不需要此步骤。
  • 您正在做自己的调整循环,而不是使用 sklearn.model_selection.GridSearchCV。这很好,但它可能会变得非常繁琐(想象一下想要跨过另一个超参数)。
  • 如果您使用 GridSearchCV,则无需进行自己的交叉验证。
  • 您正在使用准确性进行评估,这通常不是 multi-class class化的重要评估指标。加权 F1 更好。
  • 如果你正在进行交叉验证,你需要将定标器放在 CV 循环中(例如使用管道),否则定标器已经看到验证数据......但你不需要定标器这个学习算法所以这一点没有实际意义。

我可能会这样做:

import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split

X, y = make_classification()

# Split the data.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.05, shuffle=True, random_state=0)

# Make things for the cross validation.
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
param_grid = {'max_depth': np.arange(3, 8)}
model = RandomForestClassifier(random_state=1)

# Create and train the cross validation.
clf = GridSearchCV(model, param_grid,
                   scoring='f1_weighted',
                   cv=cv, verbose=3)

clf.fit(X_train, y_train)

看看 clf.cv_results_ 的分数等,如果你想的话,你可以画出来。默认情况下 GridSearchCV 在最佳超参数上训练最终模型,因此您可以使用 clf.

进行预测

差点忘了...你问过关于改进模型的问题:)这里有一些想法:

  • 以上将帮助您调整更多超参数(例如 max_featuresn_estimatorsmin_samples_leaf)。但是不要对超参数调整太过投入。
  • 您可以尝试转换某些功能(X 中的列),或添加新功能。
  • 查找更多数据,例如更多行、更高质量的标签等。
  • 解决 class 失衡的任何问题。
  • 尝试更复杂的算法,比如梯度提升树(sklearn中有模型,或者看看xgboost)。