Что такое случайный лес?

Случайный лес — это популярный метод ансамблевого обучения, в частности, метод мешков, который создает «лес» из нескольких деревьев решений во время обучения и выводит класс, который является режимом классов (классификация) или средним/средним предсказанием (регрессия). отдельные деревья для невидимых данных.

Математика случайного леса:

  1. Начальная выборка: случайный лес начинается с выбора «n» случайных подмножеств из набора данных с использованием метода начальной загрузки. Это означает, что некоторые образцы будут использоваться несколько раз в одном дереве, а другие не будут использоваться вообще.
  2. Разделение: для каждого узла в дереве решений случайным образом выбирается только подмножество признаков. Затем среди этих признаков находится наилучшее разделение. Это вносит дополнительную изменчивость в модель и помогает декоррелировать деревья, тем самым уменьшая переоснащение.
  3. Прогноз:
  • Для классификации: Каждое дерево решений дает «голос» за класс, и класс с наибольшим количеством голосов выбирается лесом в качестве окончательного решения.
  • Для регрессии: средний прогноз всех деревьев является окончательным прогнозом модели.

Псевдокод для Random Forest:

function RandomForest(training_data, number_of_trees, max_features):
    forest = []
    
    for i = 1 to number_of_trees:
        bootstrap_sample = RandomlySampleWithReplacement(training_data)
        tree = BuildDecisionTree(bootstrap_sample, max_features)
        forest.append(tree)
    
    return forest

function Predict(forest, new_data):
    predictions = []
    
    for tree in forest:
        prediction = tree.predict(new_data)
        predictions.append(prediction)
    
    return MajorityVote(predictions)  # For classification
    # return Average(predictions)  # For regression
function RandomlySampleWithReplacement(data):
    sample = []
    n = length(data)

    for i = 1 to n:
        random_index = RandomNumberBetween(1, n)
        sample.append(data[random_index])

    return sample
function BuildDecisionTree(data, max_features, max_depth=none, depth=0):
    if data is pure or depth == max_depth:
        return LeafNode(most_common_label_in_data)
    
    best_split_feature, best_split_value = None, None
    best_split_gini = infinity
    best_split_datasets = None, None

    for feature in RandomSubsetOfFeatures(data.features, max_features):
        for value in UniqueValuesOfFeature(data, feature):
            left_dataset, right_dataset = SplitData(data, feature, value)
            current_gini = CalculateWeightedGini(left_dataset, right_dataset)
            
            if current_gini < best_split_gini:
                best_split_gini = current_gini
                best_split_feature = feature
                best_split_value = value
                best_split_datasets = left_dataset, right_dataset
    
    if best_split_gini == infinity:  # no good split was found
        return LeafNode(most_common_label_in_data)

    left_tree = BuildDecisionTree(best_split_datasets[0], max_features, max_depth, depth+1)
    right_tree = BuildDecisionTree(best_split_datasets[1], max_features, max_depth, depth+1)
    
    return DecisionNode(best_split_feature, best_split_value, left_tree, right_tree)


function SplitData(data, feature, value):
    left_dataset = all rows where feature < value
    right_dataset = all rows where feature >= value
    return left_dataset, right_dataset

Математика поиска лучшего разделения:

Дерево решений выбирает наилучшее разделение, используя критерий, который измеряет качество разделения. Одним из распространенных критериев является примесь Джини, но есть также и информационный прирост (который основан на энтропии).

Предварительная обработка данных:

  1. Обработка пропущенных данных: вы можете удалить или заполнить пропущенные значения.
  2. Категориальные данные: Преобразование категорийных данных в числовые данные с использованием таких методов, как One-Hot Encoding или Label Encoding.
  3. Масштабирование функций: хотя деревья решений (и, следовательно, случайный лес) меньше зависят от масштабирования функций, часто рекомендуется масштабировать функции, особенно если вы планируете использовать другие алгоритмы в тандеме.
  4. Разработка функций: на основе знаний предметной области создавайте новые значимые функции.
  5. Выбросы: обработайте выбросы, поскольку они могут повлиять на разделение дерева.

Установка гиперпараметров:

  1. n_estimators: Количество деревьев в лесу. Посмотрите на точку стабилизации точности — после определенного количества деревьев производительность обычно стабилизируется.
  2. max_features: Количество функций, которые следует учитывать при поиске наилучшего разделения. Если ваш EDA указывает на высокую корреляцию между функциями, рассмотрите возможность ее уменьшения.
  3. max_depth: Максимальная глубина каждого дерева. Если вы обнаружите, что ваша модель переоснащается, уменьшите это значение.
  4. min_samples_split и min_samples_leaf: минимальные выборки, необходимые для разделения внутреннего узла или конечного узла. Отрегулируйте на основе EDA и в случае переобучения модели.
  5. bootstrap: Используются ли загрузочные образцы при построении деревьев. Обычно оставляют как True.

Пример использования Python и sklearn:

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Load dataset
data = load_iris()
X = data.data
y = data.target

# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Train RandomForest
clf = RandomForestClassifier(n_estimators=100, max_features="sqrt")
clf.fit(X_train, y_train)

# Predict
y_pred = clf.predict(X_test)

# Evaluate
print("Accuracy:", accuracy_score(y_test, y_pred))