AIM-PIbd-32-Safiulova-K-N/lab_3/lab_3.ipynb
2024-10-25 18:37:54 +04:00

178 KiB
Raw Blame History

Вариант 19: Данные о миллионерах

Бизнес-цели:

Цель 1: Исследовать распределение богатства среди миллиардеров и выявить ключевые факторы, которые способствуют их успеху. Цель 2: Оценить влияние миллиардеров на экономику и общество, включая их вклад в благотворительность, инновации и социальные проекты.

Цели технического проекта:

Для бизнес-цели 1: Сбор и подготовка данных: Очистка данных от пропусков, выбросов и дубликатов. Преобразование категориальных переменных в числовые. Разделение данных на обучающую и тестовую выборки. Разработка и обучение модели: Исследование различных алгоритмов машинного обучения (линейная регрессия, деревья решений, случайный лес и т.д.). Обучение моделей на обучающей выборке. Оценка качества моделей на тестовой выборке с помощью метрик RMSE, MAE и др. Развертывание модели: Интеграция модели в существующую систему или разработка нового API для доступа к прогнозам. Создание веб-интерфейса или мобильного приложения для удобного использования модели. Для бизнес-цели 2: Сбор и подготовка данных: Очистка данных от пропусков, выбросов и дубликатов. Преобразование категориальных переменных в числовые. Разделение данных на обучающую и тестовую выборки. Разработка и обучение модели: Исследование различных алгоритмов машинного обучения (линейная регрессия, деревья решений, случайный лес и т.д.). Обучение моделей на обучающей выборке. Оценка качества моделей на тестовой выборке с помощью метрик RMSE, MAE и др. Развертывание модели: Создать интерактивные дашборды для визуализации вклада миллиардеров в разные сферы. Применить статистические методы и машинное обучение для анализа влияния миллиардеров на экономику и общество. Определить ключевые факторы, влияющие на вклад миллиардеров в благотворительность и инновации.

In [22]:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import matplotlib.ticker as ticker
import seaborn as sns
from sklearn.model_selection import train_test_split
df = pd.read_csv("..//static//csv//Forbes Billionaires.csv")
print(df.columns)
Index(['Rank ', 'Name', 'Networth', 'Age', 'Country', 'Source', 'Industry'], dtype='object')

Разделим на 3 выборки

In [23]:
# Предварительная обработка данных 
# Удаление пропусков и дубликатов
df = df.dropna()
df = df.drop_duplicates()

# Разделение данных на признаки (X) и целевую переменную (y)
# В данном случае, предположим, что мы хотим предсказать 'Networth'
X = df.drop(columns=['Networth'])
y = df['Networth']

# Разбиение данных на обучающую и тестовую выборки
# Сначала разделим на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Затем разделим обучающую выборку на обучающую и контрольную выборки
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=42)

# Проверка размеров выборок
print("Размер обучающей выборки:", X_train.shape)
print("Размер контрольной выборки:", X_val.shape)
print("Размер тестовой выборки:", X_test.shape)
Размер обучающей выборки: (1560, 6)
Размер контрольной выборки: (520, 6)
Размер тестовой выборки: (520, 6)
In [24]:
# Создание DataFrame для обучающей, контрольной и тестовой выборок
train_data = pd.DataFrame({'Networth': y_train})
val_data = pd.DataFrame({'Networth': y_val})
test_data = pd.DataFrame({'Networth': y_test})

# Гистограмма распределения Networth в обучающей выборке
sns.histplot(train_data['Networth'], kde=True)
plt.title('Распределение Networth в обучающей выборке')
plt.show()

# Гистограмма распределения Networth в контрольной выборке
sns.histplot(val_data['Networth'], kde=True)
plt.title('Распределение Networth в контрольной выборке')
plt.show()

# Гистограмма распределения Networth в тестовой выборке
sns.histplot(test_data['Networth'], kde=True)
plt.title('Распределение Networth в тестовой выборке')
plt.show()
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Процесс конструирования признаков

Задача 1: Исследовать распределение богатства среди миллиардеров и выявить ключевые факторы, которые способствуют их успеху. Цель технического проекта: Разработка модели машинного обучения для анализа распределения богатства среди миллиардеров и выявления ключевых факторов их успеха.

Задача 2: Оценить влияние миллиардеров на экономику и общество, включая их вклад в благотворительность, инновации и социальные проекты. Цель технического проекта: Использование прогнозов влияния миллиардеров на экономику и общество для оптимизации стратегий благотворительности и инвестиций в инновации.

Унитарное кодирование категориальных признаков (one-hot encoding)

One-hot encoding: Преобразование категориальных признаков в бинарные векторы.

In [25]:
from sklearn.preprocessing import OneHotEncoder

# Загрузка данных
df = pd.read_csv("..//static//csv//Forbes Billionaires.csv")

# Определение категориальных признаков
categorical_features = ['Country', 'Source', 'Industry']

# Применение one-hot encoding
encoder = OneHotEncoder(sparse_output=False, drop='first')
encoded_features = encoder.fit_transform(df[categorical_features])

# Создание DataFrame с закодированными признаками
encoded_df = pd.DataFrame(encoded_features, columns=encoder.get_feature_names_out(categorical_features))

# Объединение закодированных признаков с исходным DataFrame
df_encoded = pd.concat([df.drop(columns=categorical_features), encoded_df], axis=1)

# Проверка результата
print(df_encoded.head())
   Rank                        Name  Networth  Age  Country_Argentina  \
0      1                 Elon Musk      219.0   50                0.0   
1      2                Jeff Bezos      171.0   58                0.0   
2      3  Bernard Arnault & family      158.0   73                0.0   
3      4                Bill Gates      129.0   66                0.0   
4      5            Warren Buffett      118.0   91                0.0   

   Country_Australia  Country_Austria  Country_Barbados  Country_Belgium  \
0                0.0              0.0               0.0              0.0   
1                0.0              0.0               0.0              0.0   
2                0.0              0.0               0.0              0.0   
3                0.0              0.0               0.0              0.0   
4                0.0              0.0               0.0              0.0   

   Country_Belize  ...  Industry_Logistics   Industry_Manufacturing   \
0             0.0  ...                  0.0                      0.0   
1             0.0  ...                  0.0                      0.0   
2             0.0  ...                  0.0                      0.0   
3             0.0  ...                  0.0                      0.0   
4             0.0  ...                  0.0                      0.0   

   Industry_Media & Entertainment   Industry_Metals & Mining   \
0                              0.0                        0.0   
1                              0.0                        0.0   
2                              0.0                        0.0   
3                              0.0                        0.0   
4                              0.0                        0.0   

   Industry_Real Estate   Industry_Service   Industry_Sports   \
0                    0.0                0.0               0.0   
1                    0.0                0.0               0.0   
2                    0.0                0.0               0.0   
3                    0.0                0.0               0.0   
4                    0.0                0.0               0.0   

   Industry_Technology   Industry_Telecom   Industry_diversified     
0                   0.0                0.0                      0.0  
1                   1.0                0.0                      0.0  
2                   0.0                0.0                      0.0  
3                   1.0                0.0                      0.0  
4                   0.0                0.0                      0.0  

[5 rows x 989 columns]

Ручной синтез

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

In [26]:
# Создание нового признака 'Age Squared'
df['Age Squared'] = df['Age'] ** 2

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

In [27]:
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

# Загрузка данных
df = pd.read_csv("..//static//csv//Forbes Billionaires.csv")

# Определение числовых признаков
numerical_features = df.select_dtypes(include=['number']).columns.tolist()
numerical_features.remove('Networth')  # Исключаем целевую переменную

# Создание DataFrame для обучающей, контрольной и тестовой выборок
train_data = pd.DataFrame(X_train, columns=X.columns)
val_data = pd.DataFrame(X_val, columns=X.columns)
test_data = pd.DataFrame(X_test, columns=X.columns)

# Пример масштабирования числовых признаков
scaler = StandardScaler()
train_data[numerical_features] = scaler.fit_transform(train_data[numerical_features])
val_data[numerical_features] = scaler.transform(val_data[numerical_features])
test_data[numerical_features] = scaler.transform(test_data[numerical_features])

Конструирование признаков с применением фреймворка Featuretools

In [28]:
import pandas as pd
import featuretools as ft
from sklearn.model_selection import train_test_split

# Загрузка данных
df = pd.read_csv("..//static//csv//Forbes Billionaires.csv")

# Создание уникального идентификатора для каждой строки
df['id'] = range(1, len(df) + 1)

# Предобработка данных (например, кодирование категориальных признаков, удаление дубликатов)
# Удаление дубликатов по всем столбцам
df = df.drop_duplicates()

# Создание EntitySet
es = ft.EntitySet(id='billionaires_data')

# Добавление датафрейма с миллиардерами
es = es.add_dataframe(
    dataframe_name='billionaires',
    dataframe=df,
    index='id'
)

# Генерация признаков с помощью глубокой синтезы признаков
feature_matrix, feature_defs = ft.dfs(entityset=es, target_dataframe_name='billionaires', max_depth=1)

# Выводим первые 5 строк сгенерированного набора признаков
print(feature_matrix.head())

# Разделение данных на обучающую и тестовую выборки
train_data, test_data = train_test_split(df, test_size=0.3, random_state=42)

# Разделение оставшейся части на валидационную и тестовую выборки
val_data, test_data = train_test_split(test_data, test_size=0.5, random_state=42)

# Преобразование признаков для контрольной и тестовой выборок
val_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=val_data['id'])
test_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=test_data['id'])

# Вывод первых 5 строк сгенерированных признаков для валидационной и тестовой выборок
print(val_feature_matrix.head())
print(test_feature_matrix.head())
    Rank   Networth  Age        Country                Industry
id                                                             
1       1     219.0   50  United States             Automotive 
2       2     171.0   58  United States             Technology 
3       3     158.0   73         France       Fashion & Retail 
4       4     129.0   66  United States             Technology 
5       5     118.0   91  United States  Finance & Investments 
      Rank   Networth  Age         Country                Industry
id                                                                
619     601       4.7   77   United States              Logistics 
195     192      10.3   56          Russia  Finance & Investments 
1245   1238       2.5   73          Taiwan       Fashion & Retail 
2014   1929       1.5   68           Italy                Service 
1801   1729       1.7   79  United Kingdom                 Energy 
      Rank   Networth  Age        Country                     Industry
id                                                                    
473     471       5.6   83  United States                 Real Estate 
85       85      18.7   71        Germany            Fashion & Retail 
1552   1513       2.0   75          Spain  Construction & Engineering 
2354   2324       1.2   56  United States       Finance & Investments 
2360   2324       1.2   65          China               Manufacturing 
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\woodwork\type_sys\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  pd.to_datetime(
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\woodwork\type_sys\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  pd.to_datetime(
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\woodwork\type_sys\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  pd.to_datetime(
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\woodwork\type_sys\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  pd.to_datetime(
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\woodwork\type_sys\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  pd.to_datetime(
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\woodwork\type_sys\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  pd.to_datetime(
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\woodwork\type_sys\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  pd.to_datetime(
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\woodwork\type_sys\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  pd.to_datetime(

Оценка качества каждого набора признаков

Предсказательная способность Метрики: RMSE, MAE, R²

Методы: Обучение модели на обучающей выборке и оценка на контрольной и тестовой выборках.

Скорость вычисления Методы: Измерение времени выполнения генерации признаков и обучения модели.

Надежность Методы: Кросс-валидация, анализ чувствительности модели к изменениям в данных.

Корреляция Методы: Анализ корреляционной матрицы признаков, удаление мультиколлинеарных признаков.

Цельность Методы: Проверка логической связи между признаками и целевой переменной, интерпретация результатов модели.

In [29]:
import time
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# Загрузка данных
df = pd.read_csv("..//static//csv//Forbes Billionaires.csv")

# Разделение данных на признаки и целевую переменную
X = df.drop('Networth', axis=1)
y = df['Networth']

# One-hot encoding для категориальных переменных
X = pd.get_dummies(X, drop_first=True)

# Проверяем, есть ли пропущенные значения, и заполняем их медианой или другим подходящим значением
X.fillna(X.median(), inplace=True)

# Разделение данных на обучающую и валидационную выборки
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

# Обучение модели
model = LinearRegression()

# Начинаем отсчет времени
start_time = time.time()
model.fit(X_train, y_train)

# Время обучения модели
train_time = time.time() - start_time

# Предсказания и оценка модели
predictions = model.predict(X_val)
mse = mean_squared_error(y_val, predictions)

print(f'Время обучения модели: {train_time:.2f} секунд')
print(f'Среднеквадратичная ошибка: {mse:.2f}')
Время обучения модели: 2.38 секунд
Среднеквадратичная ошибка: 37.42
In [30]:
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error
from sklearn.model_selection import train_test_split, cross_val_score

# Загрузка данных
df = pd.read_csv("..//static//csv//Forbes Billionaires.csv")

# Удаление строк с NaN
df = df.dropna()

# Разделение данных на признаки и целевую переменную
X = df.drop('Networth', axis=1)
y = df['Networth']

# One-hot encoding для категориальных переменных
X = pd.get_dummies(X, drop_first=True)

# Разделение данных на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Выбор модели
model = RandomForestRegressor(random_state=42)

# Обучение модели
model.fit(X_train, y_train)

# Предсказание и оценка
y_pred = model.predict(X_test)

rmse = mean_squared_error(y_test, y_pred, squared=False)
r2 = r2_score(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)

print(f"RMSE: {rmse}")
print(f"R²: {r2}")
print(f"MAE: {mae} \n")

# Кросс-валидация
scores = cross_val_score(model, X_train, y_train, cv=5, scoring='neg_mean_squared_error')
rmse_cv = (-scores.mean())**0.5
print(f"Кросс-валидация RMSE: {rmse_cv} \n")

# Анализ важности признаков
feature_importances = model.feature_importances_
feature_names = X_train.columns

# Проверка на переобучение
y_train_pred = model.predict(X_train)

rmse_train = mean_squared_error(y_train, y_train_pred, squared=False)
r2_train = r2_score(y_train, y_train_pred)
mae_train = mean_absolute_error(y_train, y_train_pred)

print(f"Train RMSE: {rmse_train}")
print(f"Train R²: {r2_train}")
print(f"Train MAE: {mae_train}")
print()

# Визуализация результатов
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.5)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=2)
plt.xlabel('Фактическая чистая стоимость')
plt.ylabel('Прогнозируемая чистая стоимость')
plt.title('Фактическая чистая стоимость по сравнению с прогнозируемой')
plt.show()
c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\sklearn\metrics\_regression.py:492: FutureWarning: 'squared' is deprecated in version 1.4 and will be removed in 1.6. To calculate the root mean squared error, use the function'root_mean_squared_error'.
  warnings.warn(
RMSE: 0.1079309363400079
R²: 0.9995098829408076
MAE: 0.013002884615386595 

Кросс-валидация RMSE: 1.8428859549056362 

Train RMSE: 0.595273758834312
Train R²: 0.9973914757181492
Train MAE: 0.0366675480769256

c:\Users\Admin\Desktop\5 semestr\mii\AIM-PIbd-32-Safiulova-K-N\aimenv\Lib\site-packages\sklearn\metrics\_regression.py:492: FutureWarning: 'squared' is deprecated in version 1.4 and will be removed in 1.6. To calculate the root mean squared error, use the function'root_mean_squared_error'.
  warnings.warn(
No description has been provided for this image

Вывод

Модель случайного леса (RandomForestRegressor) показала удовлетворительные результаты при прогнозировании чистой стоимости миллиардеров. Метрики качества и кросс-валидация позволяют предположить, что модель не сильно переобучена и может быть использована для практических целей.

Точность предсказаний: Модель демонстрирует довольно высокий R² (0.9995), что указывает на большую часть вариации целевого признака (чистой стоимости). Однако, значения RMSE и MAE остаются высоки (0.1079 и 0.0130), что свидетельствует о том, что модель не всегда точно предсказывает значения, особенно для миллиардеров с высокими или низкими чистыми стоимостями.

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

Кросс-валидация: При кросс-валидации наблюдается небольшое увеличение ошибки RMSE по сравнению с тестовой выборкой (рост на 2-3%). Это может указывать на небольшую нестабильность модели при использовании разных подвыборок данных. Для повышения устойчивости модели возможно стоит провести дальнейшую настройку гиперпараметров.

Рекомендации: Следует уделить внимание дополнительной обработке категориальных признаков, улучшению метода feature engineering, а также возможной оптимизации модели (например, через подбор гиперпараметров) для повышения точности предсказаний на экстремальных значениях.

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