Описательная аналитика для работы совета директоров

Введение

В этом исследовании мы используем подход, похожий на стратегию, показанную в фильме «Moneyball», но перенесенную на область корпоративного управления. Подобно тому, как Moneyball использовала статистику игроков для выбора бейсбольной команды, мы используем различные показатели, чтобы понять характеристики успешных членов совета директоров.

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

С помощью этого исследования наша конечная цель состоит в том, чтобы предложить организациям ценную информацию, которая потенциально может помочь оптимизировать их процесс выбора совета директоров, тем самым повышая эффективность их корпоративного управления. Наши уникальные данные о влиянии директоров выделяют наше исследование, предлагая новые перспективы в понимании отношений между директорами и эффективностью компании.

Обзор методологии

Описание набора данных

Наш набор данных представляет собой тщательно обработанное объединение данных, полученных от Free Float, LLC, дополненных сторонними данными от MSCI ESG Research, ESGauge, S&P Global и Preqin. Он состоит из 86 772 строк и 41 столбца, предлагая подробное представление о профилях директоров, их прошлом и профессиональном влиянии.

Понимание расчета целевой характеристики

Производительность: категория» — это мера, которую мы используем для ранжирования директоров компаний на основе их влияния на успех компании. «Производительность: Категория» — это, по сути, рейтинговая система для директоров компаний, основанная на их влиянии на успех компании. Вот пошаговое объяснение:

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

Например:если процент побед режиссера › 90 % всех директоров: категория эффективности = ‘Зал славы’.

Процесс разработки модели

  1. Предварительная обработка данных. Начавшись с тщательной очистки данных, отсутствующие значения были устранены с использованием подходящих методов условного исчисления, а выбросы были обработаны с учетом их потенциального влияния.
  2. Исследовательский анализ данных (EDA): этот этап включал понимание структуры данных, наблюдение взаимосвязей между переменными и выявление потенциальных аномалий, что позволило получить важную информацию для выбора функций.
  3. Выбор модели и обучение. Мы сравнили несколько моделей классификации, выбрали наиболее подходящую модель и выполнили обучение модели, используя оптимальное разбиение набора для обучения и тестирования. Для предотвращения переобучения использовалась перекрестная проверка.
  4. Оценка модели. Модели оценивались по сочетанию точности, прецизионности, полноты и балла F1 для сбалансированной и всесторонней оценки производительности.
  5. Выбор функций и оптимизация модели. Мы использовали комбинацию статистических методов и методов важности функций, чтобы определить наиболее важные функции, влияющие на «ПРОИЗВОДИТЕЛЬНОСТЬ: КАТЕГОРИЯ». Используя настройку гиперпараметров и масштабирование функций, мы смогли итеративно уточнить и повысить производительность модели.
  6. Интерпретация результатов. Последний шаг включал анализ прогнозов модели и понимание вклада различных функций в процесс прогнозирования.

Анализ данных

Исследовательский анализ данных

Сводная статистика: непрерывные переменные

В наших данных мы нашли недостающие значения в непрерывных переменных и выбрали методы вменения на основе распределения каждой переменной. Для нормально распределенных переменных, таких как возраст, мы использовали вменение среднего значения. Для искаженных данных, таких как мощность и влияние сети, мы использовали медианное вменение. Переменные с более чем 80% отсутствующих значений, такие как разнообразие и другой показатель производительности, были исключены, чтобы предотвратить ненадежные и необъективные результаты. Мы также выбрали только одну характеристику производительности для целевой переменной, чтобы избежать мультиколлинеарности, улучшив производительность и интерпретируемость нашей модели.

Обработка выбросов для числовых признаков

age_mean = df['DIRECTOR: AGE'].mean()
df['DIRECTOR: AGE'].fillna(age_mean, inplace= True)

inf5_median = df['INFLUENCE: 5YR MEDIAN'].median()
df['INFLUENCE: 5YR MEDIAN'].fillna(inf5_median, inplace= True)

Сводная статистика: характеристики категорий

Мы проанализировали распределение категориальных переменных и нашли несбалансированную целевую переменную, в которой большинство экземпляров не оценены, а наименьшее — в Зале славы. Мы также обнаружили гендерное неравенство: мужчин-директоров значительно больше, чем женщин. Несмотря на эти дисбалансы, мы изначально не применяли методы балансировки данных, стремясь сначала оценить производительность наших моделей на исходном наборе данных, а затем, при необходимости, рассмотреть методы балансировки.

Обработка выбросов для категориальных признаков

sector_mode = df['COMPANY: SECTOR'].mode()
df['COMPANY: SECTOR'].fillna(sector_mode[0], inplace= True)

gender_mode = df['DIRECTOR: GENDER'].mode()
df['DIRECTOR: GENDER'].fillna(gender_mode[0], inplace= True)

Кодирование категорийных признаков

Правильная предварительная обработка, особенно кодирование категориальных переменных в числовой формат, имеет решающее значение в машинном обучении для точных вычислений и прогнозов. Обычно используются такие методы, как горячее, порядковое и двоичное кодирование. Точно так же оптимизация категорий целевых переменных способствует повышению производительности и интерпретируемости модели. В этом исследовании мы объединили похожие категории, чтобы уменьшить сложность. Например, «Зал славы» и «Все звезды» были сгруппированы в категорию 2, «Новички» и «Ротация» — в категорию 1, а «Бенчвормеры» и «Без рейтинга» — в категорию 0. Этот подход соответствует передовым методам машинного обучения. для обеспечения эффективного обучения модели и надежных результатов.

Гендерное кодирование

encoder = LabelEncoder()
df['DIRECTOR: GENDER'] = encoder.fit_transform(df['DIRECTOR: GENDER'])

Кодировка сектора компании

columns_to_select = [col for col in df.columns if col not in ['COMPANY: DOMICILE', 'COMPANY: SECTOR']]

# Select all rows and specific columns using DataFrame.loc[]
filtered_df = df.loc[:, columns_to_select]

Кодирование исполнения режиссера

category_to_value = {
    "HALL OF FAMER": 2,
    "ALL STAR": 2,
    "STARTER": 1,
    "ROTATION": 1,
    "BENCHWARMER": 0,
    "UNRATED": 0
}

# Encode the values in the 'PERFORMANCE: CATEGORY' column
df['PERFORMANCE: CATEGORY'] = df['PERFORMANCE: CATEGORY'].map(category_to_value)

Обработка мультиколлинеарности

df = df.dropna(axis = 0)

corr = df.corr()

plt.figure(figsize=(100, 60))
sns.heatmap(corr, cmap = 'Blues', annot=True,annot_kws={"size": 30})
# Change the size of the x-axis labels
plt.xticks(fontsize=35)
plt.yticks(fontsize=35)

plt.show()

Мы провели корреляционный анализ, чтобы понять взаимосвязь между функциями, помогая в выборе функций и принятии решений по моделям. Это позволило нам обнаружить потенциальную мультиколлинеарность, которая может повлиять на производительность модели. Кроме того, мы использовали коэффициент инфляции дисперсии (VIF), чтобы точно определить особенности, вызывающие мультиколлинеарность.

Определив «ВЛИЯНИЕ: 2023» и «ВЛИЯНИЕ: MRY» как проблемные из-за их высокой корреляции, мы удалили их из нашего набора данных, чтобы повысить надежность и надежность нашего анализа.

Выбор модели и обучение

Модель на основе дерева

Модель дерева решений

Мы выполнили модель дерева решений с максимальной глубиной дерева 4, которую мы выбрали в качестве начальной попытки сбалансировать сложность модели и интерпретируемость. Глубина 4 может помочь уменьшить переоснащение, при этом позволяя модели фиксировать сложные отношения в данных.

X = df.drop(['PERFORMANCE: CATEGORY'], axis = 1)
y = df['PERFORMANCE: CATEGORY']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

#define classification algorithm
clf_tree = tree.DecisionTreeClassifier(max_depth = 4)

# get start time
start_time = time.time()

# fit the model
clf_tree = clf_tree.fit(X_train, y_train)

# calculate and print the time taken to train the model
train_time = time.time() - start_time
print("Training time: ", train_time)

# reset start time
start_time = time.time()

# make predictions
y_pred_tree = clf_tree.predict(X_test)

# calculate and print the time taken to make predictions
predict_time = time.time() - start_time
print("Prediction time: ", predict_time)

В итоговом отчете о классификации указаны следующие показатели производительности:

cm_tree = confusion_matrix(y_test, y_pred_tree)

# Create a heatmap
plt.figure(figsize=(8, 6))
sns.heatmap(cm_tree, annot=True, fmt='d', cmap='Blues',annot_kws={"size": 14})

plt.xlabel('Predicted', fontsize = 14)
plt.ylabel('Actual', fontsize = 14)
plt.title('Confusion Matrix for Decision Tree', fontsize = 14)

# Show the plot
plt.show()

Оценка модели

from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred_tree))

Модель дерева решений демонстрирует высокую точность во всех категориях эффективности, что свидетельствует о надежной классификации работы режиссера. Он особенно хорошо подходит для определения исполнителей более низкого и высшего уровня, хотя некоторые из этих категорий могут быть упущены. Это говорит о том, что он редко ошибается в классификации, но не всегда может определить всех потенциальных лучших исполнителей, что должно быть в центре внимания оптимизации.

Важность функции

# Extract feature importances
importances = clf_tree.feature_importances_

# Create a DataFrame with feature names and their corresponding importances
features_importance = pd.DataFrame({
    "Feature": X.columns, 
    "Importance": importances
})

# Sort the DataFrame by importance in descending order
features_importance = features_importance.sort_values("Importance", ascending=False)

# Select the top 10 most important features
top_10_features = features_importance.head(10)

# Plot the feature importances of the top 10 features
plt.figure(figsize=(10, 8))
sns.barplot(x="Importance", y="Feature", data=top_10_features, palette = 'Blues_r')
plt.title('Top 10 Feature Importance for Decision Tree')
plt.xlabel('Importance')
plt.ylabel('Feature')
plt.show()

Модель случайного леса (бэггинг)

Следовательно, мы применили алгоритм случайного леса для сравнения его производительности с моделью дерева решений, поскольку он имеет несколько преимуществ. Случайный лес может обеспечить лучшее обобщение благодаря своей ансамблевой природе, которая объединяет несколько деревьев решений для прогнозирования. Создавая деревья с различными подмножествами данных и агрегируя их результаты, случайный лес может фиксировать более сложные отношения и менее подвержен переоснащению.

X = df.drop('PERFORMANCE: CATEGORY', axis = 1)
y = df['PERFORMANCE: CATEGORY']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# create regressor object
clf_rdm = RandomForestClassifier(n_estimators = 100, random_state = 42)

# get start time
start_time = time.time()

# fit the regressor with x and y data
clf_rdm = clf_rdm.fit(X_train, y_train)  

# calculate and print the time taken to train the model
train_time = time.time() - start_time
print("Training time: ", train_time)

# reset start time
start_time = time.time()

# make predictions
y_pred_rdm = clf_rdm.predict(X_test)

# calculate and print the time taken to make predictions
predict_time = time.time() - start_time
print("Prediction time: ", predict_time)

Мы установили количество деревьев в модели Random Forest равным 100 и получили следующие показатели производительности:

cm_rdm = confusion_matrix(y_test, y_pred_rdm)

# Create a heatmap
plt.figure(figsize=(8, 6))
sns.heatmap(cm_rdm, annot=True, fmt='d', cmap='Blues',annot_kws={"size": 14})

# Add labels and title
plt.xlabel('Predicted', fontsize = 14)
plt.ylabel('Actual', fontsize = 14)
plt.title('Confusion Matrix for Random Forest', fontsize = 14)

# Show the plot
plt.show()

Оценка модели

from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred_rdm))

С моделью Random Forest мы наблюдаем впечатляющее повышение производительности во всех категориях. Независимо от уровня производительности («Средний запас», «Без рейтинга», «Начинающий», «Ротация», «Зал славы», «Все звезды») модель демонстрирует высокую точность, что указывает на высокую достоверность ее прогнозов. Это означает, что риск неправильной классификации минимален.

При сопоставлении с моделью дерева решений модель случайного леса демонстрирует заметное улучшение. Его превосходство в производительности проявляется в высокой точности на всех уровнях производительности, что подтверждает надежность его прогнозов и снижает вероятность ошибочной идентификации.

С точки зрения бизнеса, повышенная производительность модели Random Forest предполагает, что это более надежный инструмент для прогнозирования эффективности членов совета директоров. Благодаря его высокой точности мы можем доверять его прогнозам, тем самым уменьшая количество потенциальных ошибок в нашем процессе принятия решений и обеспечивая выявление высокоэффективных директоров.

Важность функции

# Extract feature importances
importances = clf_rdm.feature_importances_

# Create a DataFrame with feature names and their corresponding importances
features_importance = pd.DataFrame({
    "Feature": X.columns, 
    "Importance": importances
})

# Sort the DataFrame by importance in descending order
features_importance = features_importance.sort_values("Importance", ascending=False)

# Select the top 10 most important features
top_10_features = features_importance.head(10)

# Plot the feature importances of the top 10 features
plt.figure(figsize=(10, 8))
sns.barplot(x="Importance", y="Feature", data=top_10_features, palette='Blues_r')
plt.title('Top 10 Feature Importance for Random Forest')
plt.xlabel('Importance')
plt.ylabel('Feature')
plt.show()

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

Модель XGBoost (повышение)

После наших экспериментов с моделью Random Forest мы обратились к алгоритму XGBoost. XGBoost, известный своей вычислительной эффективностью и улучшенной производительностью модели, представляет собой веский аргумент в пользу превосходных результатов. Его структура повышения градиента позволяет исправить ошибки предыдущей модели, часто повышая точность прогнозирования и сводя к минимуму переоснащение. Кроме того, он эффективно обрабатывает пропущенные значения. Поэтому мы использовали XGBoost, чтобы изучить его потенциал в улучшении прогнозирования производительности совета директоров.

from xgboost import XGBClassifier
clf_xgb = XGBClassifier(objective = 'multi:softmax', 
                        eval_metric = 'merror',
                        learning_rate = 0.1, 
                        max_depth = 5, 
                        n_estimators = 1000, 
                        verbosity = 1,
                        seed = 42)
# get start time
start_time = time.time()

# fit the model
clf_xgb.fit(X_train, y_train, verbose = True, early_stopping_rounds = 10, eval_set = [(X_test, y_test)])

# calculate and print the time taken to train the model
train_time = time.time() - start_time

# reset start time
start_time = time.time()
print("Training time: ", train_time)

# Generate predictions
y_pred_xgb = clf_xgb.predict(X_test)
from sklearn.metrics import confusion_matrix

# Calculate the confusion matrix
conf_matrix_xgb = confusion_matrix(y_test, y_pred_xgb)

# Create a heatmap
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix_xgb, annot=True, fmt='d', cmap='Blues', annot_kws={"size": 14})

# Add labels and title
plt.xlabel('Predicted', fontsize = 14)
plt.ylabel('Actual' , fontsize = 14)
plt.title('Confusion Matrix for XgBoost' , fontsize = 14)

# Show the plot
plt.show()

Оценка модели

from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred_xgb))

Модель XGBoost демонстрирует хорошую точность во всех категориях производительности, но модель Random Forest превосходит ее по точности на всех уровнях. Модель случайного леса лучше обрабатывает вариации данных, предлагая более надежные прогнозы. С точки зрения бизнеса, его высокая точность способствует эффективному управлению советом директоров и стратегическому планированию. Таким образом, несмотря на хорошую производительность XGBoost, Random Forest является предпочтительным выбором для прогнозирования производительности режиссера из-за его более высокой точности.

Важность функции

# Extract feature importances
importances = clf_xgb.feature_importances_

# Create a DataFrame with feature names and their corresponding importances
features_importance = pd.DataFrame({
    "Feature": X.columns, 
    "Importance": importances
})

# Sort the DataFrame by importance in descending order
features_importance = features_importance.sort_values("Importance", ascending=False)

# Select the top 10 most important features
top_10_features = features_importance.head(10)


# Plot the feature importances of the top 10 features
plt.figure(figsize=(10, 8))
sns.barplot(x="Importance", y="Feature", data=top_10_features, palette = 'Blues_r')
plt.title('Top 10 Feature Importance for XGBoost')
plt.xlabel('Importance')
plt.ylabel('Feature')
plt.show()

Модель XGBoost подчеркивает, что местоположение и сектор компании значительно влияют на эффективность работы совета директоров. Ключевая характеристика «Компания: местонахождение_США» предполагает, что директора в компаниях, базирующихся в США, работают отчетливо, возможно, из-за специфической бизнес-среды. Модель также подчеркивает важность директоров в других странах, предполагая, что региональная деловая практика может повлиять на эффективность директоров. Функция «Компания: Сектор_Недвижимость» указывает на отраслевую динамику, влияющую на эффективность работы директора. По сути, эти выводы предполагают необходимость для спонсоров учитывать уникальные условия своего рабочего контекста для более точного прогнозирования результатов работы совета директоров.

Модель нейронной сети

Многослойный персептрон (MLP)

Мы расширили наше моделирование, включив в него нейронную сеть с прямой связью, после благоприятных результатов моделей Random Forest и XGBoost. Этот тип сети, часть семейства глубокого обучения, превосходно извлекает сложные функции из данных, хотя и за счет вычислительных ресурсов и тщательной настройки гиперпараметров. Мы построили нашу модель, используя архитектуру Keras Sequential, создав линейный стек слоев в сети.

Наша модель чередует слои Dense и Dropout с выходным слоем. Плотные слои с узлами под номерами 128, 64, 32 и 16 применяют функцию активации «relu», имеющую решающее значение для изучения сложных взаимосвязей данных. Слои отсева со скоростью 0,5 предотвращают переоснащение, случайным образом обнуляя половину входных единиц во время обучения, повышая надежность модели. Выходной слой использует функцию активации «softmax» для вывода вероятностей для трех классов производительности.

Модель использует оптимизатор «адам» и функцию потерь «sparse_categorical_crossentropy», подходящую для многоклассовой классификации, с «точностью» в качестве метрики. Архитектура и параметры оптимизируются, чтобы сбалансировать сложность модели и переобучение, на основе итеративного тестирования и уточнения, а также дорабатываются с использованием методов перекрестной проверки и поиска по сетке.

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

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# Define a function to create your Keras model
model = Sequential()
model.add(Dense(128, activation='relu', input_shape=(X_train.shape[1],)))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(16, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation='softmax'))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# Set the learning rate
learning_rate = 0.001

# Create the optimizer with the specified learning rate
optimizer = Adam(learning_rate=learning_rate)

model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])

history = model.fit(X_train, y_train, epochs=100, batch_size=32, verbose=1, validation_data=(X_test, y_test))

# Obtain the predicted probabilities from the neural network
y_pred_probs1 = model.predict(X_test)

# Convert the predicted probabilities to class labels
y_pred_nn1 = np.argmax(y_pred_probs, axis=1)
# Compute the confusion matrix
cm_nn1 = confusion_matrix(y_test, y_pred_nn)

# Create a heatmap
plt.figure(figsize=(8, 6))
sns.heatmap(cm_nn1, annot=True, fmt='d', cmap='Blues', annot_kws={"size": 14})

# Add labels and title
plt.xlabel('Predicted', fontsize = 14)
plt.ylabel('Actual' , fontsize = 14)
plt.title('Confusion Matrix for Neural Network' , fontsize = 14)

# Show the plot
plt.show()

Оценка модели

from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred_nn1))

Производительность модели нейронной сети демонстрирует значительную эффективность с общей точностью 81%. Однако по сравнению с моделями XGBoost и Random Forest он демонстрирует несколько более низкие показатели с точки зрения точности, достоверности и полноты.

Чтобы еще больше оптимизировать нашу модель глубокого обучения, мы приступили к точной настройке гиперпараметров модели. Этот процесс направлен на улучшение прогнозирующих возможностей модели и более точное согласование ее производительности с моделями XGBoost и Random Forest.

Настройка гиперпараметров

Мы улучшили нашу модель, используя RandomSearch Keras Tuner для настройки гиперпараметров, корректируя параметры в определенных диапазонах, чтобы максимизировать точность проверки. Наша функция build_model помогла упростить этот процесс настройки.

В функции мы настроили:

  1. Количество юнитов во входном и скрытом слоях (от 128 до 256 и от 32 до 128 соответственно с шагом 32).
  2. Коэффициент отсева внутри слоев (от 0 до 0,5 с размером шага 0,1), который помогает уменьшить переоснащение за счет случайного отбрасывания нейронов во время обучения.
  3. Мы предоставили оптимизатору три варианта скорости обучения, что помогает сбалансировать скорость обучения с риском превышения минимума.

Используя RandomSearch, мы провели поиск гиперпараметров в пяти испытаниях, при этом в каждом испытании использовался другой набор гиперпараметров.

from keras_tuner import RandomSearch

# Define a function to create your Keras model
def build_model(hp):
    model = Sequential()
    model.add(Dense(units=hp.Int('units_input',
                                 min_value=128,
                                 max_value=256,
                                 step=32),
                    activation='relu', 
                    input_shape=(X_train.shape[1],)))
    model.add(Dense(units=hp.Int('units_hidden',
                                 min_value=32,
                                 max_value=128,
                                 step=32), 
                    activation='relu'))
    model.add(Dropout(hp.Float('dropout', 0, 0.5, step=0.1)))
    model.add(Dense(units=hp.Int('units_hidden',
                                 min_value=32,
                                 max_value=128,
                                 step=32), 
                    activation='relu'))
    model.add(Dropout(hp.Float('dropout', 0, 0.5, step=0.1)))
    model.add(Dense(16, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(3, activation='softmax'))

    learning_rate = hp.Choice('learning_rate', [1e-2, 1e-3, 1e-4])

    optimizer = Adam(learning_rate=learning_rate)

    model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])

    return model

start_time = time.time()

# Initialize the tuner
tuner = RandomSearch(
    build_model,
    objective='val_accuracy',
    max_trials=5,  # the number of different models to try
)

# Perform the hyperparameter search
tuner.search(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

# Get the optimal hyperparameters
best_hps=tuner.get_best_hyperparameters(num_trials=1)[0]

# Build the model with the optimal hyperparameters and train it
model = tuner.hypermodel.build(best_hps)
history = model.fit(X_train, y_train, epochs=100, batch_size=32, verbose=1, validation_data=(X_test, y_test))

# Obtain the predicted probabilities from the neural network
y_pred_probs2 = model.predict(X_test)

# Convert the predicted probabilities to class labels
y_pred_nn2 = np.argmax(y_pred_probs2, axis=1)

# Compute the confusion matrix
cm_nn2 = confusion_matrix(y_test, y_pred_nn2)

end_time = time.time()

computation_time = end_time - start_time

print(f"The computation time is {computation_time} seconds.")

Наша модель нейронной сети показала заметные улучшения в точности, воспроизводимости и отзыве после настройки гиперпараметров. Тем не менее, он все еще не превзошел модели XGBoost и Random Forest для нашей конкретной задачи.

Наша цель состояла в том, чтобы изучить, как функции влияют на оптимальную работу совета директоров (класс 2). Модели XGBoost и Random Forest показали лучшую точность и полноту для прогнозов класса 2, а также более высокую общую точность, что указывает на превосходную классификацию для всех классов производительности.

Несмотря на улучшения, модель нейронной сети уступила моделям XGBoost и Random Forest. Однако выбор модели зависит от набора данных и конкретного варианта использования. В некоторых сценариях модель нейронной сети может преуспеть, если данные соответствуют присущим ей предположениям и вычислительным преимуществам. Также стоит отметить, что модель нейронной сети имела более длительное время вычислений, около 85 секунд, что является ключевым фактором, когда время имеет решающее значение.

Линейная модель

Логистическая регрессия

На заключительном этапе сравнения моделей мы внедрили модель логистической регрессии. Логистическая регрессия, статистически обоснованный алгоритм, превосходно справляется с задачами бинарной и мультиклассовой классификации. Это проще, чем древовидные модели или нейронные сети, и его особенно ценят за его интерпретируемость и устойчивость к переоснащению.

# define logistic regression classifier
clf_logreg = LogisticRegression()

# get start time
start_time = time.time()

# fit the model
clf_logreg = clf_logreg.fit(X_train, y_train)

# calculate and print the time taken to train the model
train_time = time.time() - start_time
print("Training time: ", train_time)

# reset start time
start_time = time.time()

# make predictions
y_pred_logreg = clf_logreg.predict(X_test)

# calculate and print the time taken to make predictions
predict_time = time.time() - start_time
print("Prediction time: ", predict_time)

# Generate predictions
y_pred_logreg = clf_logreg.predict(X_test)

Однако наша модель логистической регрессии изо всех сил пыталась точно предсказать классы 0 и 2, о чем свидетельствуют низкие оценки отзыва 0,29 и 0,17 соответственно. Вероятно, это связано с неспособностью модели фиксировать сложные нелинейные отношения в данных. Результаты подчеркивают, что для нашего конкретного набора данных более сложные модели, такие как древовидные модели и нейронные сети, кажутся лучше оснащенными.

Заключение

Изучая модели машинного обучения для прогнозирования производительности членов совета директоров, мы обнаружили, что модель случайного леса отличается точностью и аккуратностью. Это согласуется с известной устойчивостью модели к переоснащению и способностью обрабатывать сложные отношения данных.

Модель XGBoost также показала хорошие результаты, хотя и немного менее эффективна, чем Random Forest. Модели дерева решений давали ценную информацию о переменных, но их предсказуемость была ограниченной, что демонстрировало их склонность к переоснащению.

Несмотря на улучшения после настройки гиперпараметров, нейронные сети по-прежнему уступали моделям Random Forest и XGBoost. Однако их потенциал раскрывается при наличии больших наборов данных и соответствующих условий.

Наконец, использование логистической регрессии подчеркнуло проблемы работы со сложными данными и нелинейными отношениями. Хотя он известен своей простотой и интерпретируемостью, он боролся с нашим набором данных, подчеркивая необходимость сложных моделей для сложных наборов данных.

Рекомендация

Результаты показывают, что спонсоры и заинтересованные стороны должны учитывать следующее при выборе и оценке членов совета директоров:

  1. Сила профессиональной сети директора имеет важное значение. Директора с обширными связями, особенно те, у кого есть влияние и опыт работы в качестве генеральных директоров, скорее всего, будут работать лучше.
  2. Учитывайте динамику влияния и состав самого совета, включая гендерный разрыв во власти. Правление, сбалансированное с точки зрения пола и имеющее здоровое распределение влияния, может привести к повышению производительности.
  3. Местоположение имеет значение. Директора, находящиеся в разных регионах, могут работать по-разному в зависимости от местной деловой практики и факторов окружающей среды. Поэтому учитывайте эти аспекты при выборе и прогнозировании производительности.
  4. Специфические отраслевые знания имеют жизненно важное значение. Директора, работающие в таких отраслях, как недвижимость, должны иметь глубокое понимание уникальной динамики сектора.

Вы можете найти полный код этого проекта в связанном репозитории GitHub. Не стесняйтесь клонировать, разветвлять или помечать его. Вот ссылка: Репозиторий GitHub