40 KiB
1. Цены на золото¶
Исторически золото использовалось как форма валюты в различных частях мира, включая США. В настоящее время драгоценные металлы, такие как золото, хранятся в центральных банках всех стран для гарантии выплаты внешних долгов, а также для контроля инфляции, что отражает финансовую устойчивость страны. В последнее время развивающиеся мировые экономики, такие как Китай, Россия и Индия, стали крупными покупателями золота, в то время как США, Южная Африка и Австралия относятся к крупнейшим продавцам золота.
Прогнозирование роста и падения ежедневных цен на золото может помочь инвесторам решать, когда покупать (или продавать) этот актив. Однако цены на золото зависят от множества факторов, таких как цены на другие драгоценные металлы, цены на нефть, динамика фондового рынка, цены на облигации, валютные курсы и т.д.
Задача этого проекта — точно предсказать будущую скорректированную цену закрытия Gold ETF на заданный период времени в будущем. Проблема является задачей регрессии, поскольку выходное значение, скорректированная цена закрытия в этом проекте, является непрерывной переменной.
Объект исследования - данные о торгах золотом на биржах
Проблемная область - прогнозирование цен на золото
import pandas as pd;
data_gold = pd.read_csv("..//static//csv//gold.csv", sep=",")
print('количество колонок: ' + str(data_gold.columns.size))
print('колонки: ' + ', '.join(data_gold.columns))
Получение сведений о пропущенных данных
Типы пропущенных данных:
None - представление пустых данных в Python
NaN - представление пустых данных в Pandas
'' - пустая строка
# Количество пустых значений признаков
print(data_gold.isnull().sum())
print()
# Есть ли пустые значения признаков
print(data_gold.isnull().any())
print()
# Процент пустых значений признаков
for i in data_gold.columns:
null_rate = data_gold[i].isnull().sum() / len(data_gold) * 100
if null_rate > 0:
print(f"{i} процент пустых значений: %{null_rate:.2f}")
Итог: пропущеных значений нет
Количество столбцов слишком большое, оставим только самые необходимые
Date: Уникальный идентификатор для каждого торгового дня.
Close: Цена закрытия золота на соответствующую дату.
Volume: Объем торгов золотом на соответствующую дату.
Open: Цена открытия золота на соответствующую дату.
High: Самая высокая зафиксированная цена золота в течение торгового дня.
Low: Самая низкая зафиксированная цена золота в течение торгового дня.
data_gold_reduced = data_gold[['Date', 'Close', 'Volume', 'Open', 'High', 'Low']]
data_gold_reduced.head()
Аномальное рапределение будем искать по z-индексу. Z-индекс показывает, насколько далеко значение находится от среднего в стандартных отклонениях. Значения Z-индекса больше 3 или меньше -3 обычно считаются аномальными.
from scipy import stats
# Вычисляем Z-индексы только для числовых столбцов
gold_zscores = data_gold_reduced.select_dtypes(include=['float64', 'int64']).apply(stats.zscore, nan_policy='omit')
# Устанавливаем порог для поиска аномалий
threshold = 3
def find_anomalies(zscores, df):
for column in zscores.columns:
# Проверяем, есть ли аномалии в Z-индексах
anomalies = df[column][(zscores[column].abs() > threshold)]
if not anomalies.empty:
print(f"В атрибуте '{column}' обнаружены аномалии: {anomalies.tolist()}")
# Находим аномалии
try:
print("Аномалии в наборе данных gold:")
find_anomalies(gold_zscores, data_gold_reduced)
except Exception as e:
print(f"Произошла ошибка: {e}")
Теперь выполним 10 пункт, разобьем данные на выборки
from sklearn.model_selection import train_test_split
def split_data(df, target_column, test_size=0.2, random_state=42):
# Разделяем данные на обучающую и временную выборки
X_train, X_temp, y_train, y_temp = train_test_split(df.drop(columns=[target_column]),
df[target_column],
test_size=test_size,
random_state=random_state)
# Делим временную выборку на контрольную и тестовую
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp,
test_size=0.5,
random_state=random_state)
return X_train, X_val, X_test, y_train, y_val, y_test
gold_train, gold_val, gold_test, gold_train_labels, gold_val_labels, gold_test_labels = split_data(data_gold_reduced, 'Close')
def check_balance(y_train, y_val, y_test):
print("Обучающая выборка:")
print(y_train.value_counts(normalize=True))
print("\nКонтрольная выборка:")
print(y_val.value_counts(normalize=True))
print("\nТестовая выборка:")
print(y_test.value_counts(normalize=True))
print("Набор данных gold:")
check_balance(gold_train_labels, gold_val_labels, gold_test_labels)
Как мы видим, данные не требуется аугментировать, т.к. пропорции классов сбалансированы.
Для этого набора данных не надо использовать преращение данных так как задача не на классификацию.
2. Диабет у женщин Пима¶
Этот набор данных изначально был получен из Национального института диабета, заболеваний пищеварительной системы и почек. Целью набора данных является диагностическое прогнозирование наличия или отсутствия у пациента диабета на основе определенных диагностических измерений, включенных в набор данных. На выбор этих случаев из более крупной базы данных налагалось несколько ограничений. В частности, все пациенты здесь — женщины в возрасте не менее 21 года индейского происхождения пима.
Проблемная область - предсказание диабета
diabetes = pd.read_csv("..//static//csv//diabetes.csv", sep=",")
print('количество колонок: ' + str(diabetes.columns.size))
print('колонки: ' + ', '.join(diabetes.columns))
Получение сведений о пропущенных данных
Типы пропущенных данных:
None - представление пустых данных в Python
NaN - представление пустых данных в Pandas
'' - пустая строка
# Количество пустых значений признаков
print(diabetes.isnull().sum())
print()
# Есть ли пустые значения признаков
print(diabetes.isnull().any())
print()
# Процент пустых значений признаков
for i in diabetes.columns:
null_rate = diabetes[i].isnull().sum() / len(diabetes) * 100
if null_rate > 0:
print(f"{i} процент пустых значений: %{null_rate:.2f}")
Итог: пропущенных данных нет
print(diabetes.describe())
Теперь проверим данные на аномалии
# Вычисляем Z-индексы только для числовых столбцов
diabetes_zscores = diabetes.select_dtypes(include=['float64', 'int64']).apply(stats.zscore, nan_policy='omit')
# Устанавливаем порог для поиска аномалий
threshold = 3
# Находим аномалии
try:
print("Аномалии в наборе данных diabetes:")
find_anomalies(diabetes_zscores, diabetes)
except Exception as e:
print(f"Произошла ошибка: {e}")
Теперь выполним разбиение данных
diabetes_train, diabetes_val, diabetes_test, diabetes_train_labels, diabetes_val_labels, diabetes_test_labels = split_data(diabetes, 'Outcome')
check_balance(diabetes_train_labels, diabetes_val_labels, diabetes_test_labels)
В этом наборе данных наблюдается дисбаланс, 0 тип составляет около 65%, а 1 тип около 35%. В этом случае лучше использовать метод oversampling.
from imblearn.over_sampling import RandomOverSampler
X_diabetes = diabetes.drop('Outcome', axis=1)
y_diabetes = diabetes['Outcome']
# Oversampling
ros_diabetes = RandomOverSampler(random_state=42)
X_diabetes_resampled, y_diabetes_resampled = ros_diabetes.fit_resample(X_diabetes, y_diabetes)
diabetes_resampled = pd.DataFrame(X_diabetes_resampled, columns=X_diabetes.columns)
diabetes_resampled['Outcome'] = y_diabetes_resampled
print("\nOversampling для Diabetes:")
print(diabetes_resampled['Outcome'].value_counts())
3. Индикаторы инсульта¶
По данным Всемирной организации здравоохранения (ВОЗ), инсульт является второй по значимости причиной смертности во всем мире, на его долю приходится примерно 11% от общего числа смертей. Этот набор данных используется для прогнозирования вероятности инсульта у пациента на основе таких входных параметров, как пол, возраст, различные заболевания и статус курильщика. Каждая строка данных содержит соответствующую информацию о пациенте.
Объект исследования - реальные данные о пациентах
Проблемная область - предсказание инсульта
healthcare = pd.read_csv("..//static//csv//healthcare-dataset-stroke-data.csv", sep=",")
print('количество колонок: ' + str(healthcare.columns.size))
print('колонки: ' + ', '.join(healthcare.columns))
Получение сведений о пропущенных данных
Типы пропущенных данных:
None - представление пустых данных в Python
NaN - представление пустых данных в Pandas
'' - пустая строка
# Количество пустых значений признаков
print(healthcare.isnull().sum())
print()
# Есть ли пустые значения признаков
print(healthcare.isnull().any())
print()
# Процент пустых значений признаков
for i in healthcare.columns:
null_rate = healthcare[i].isnull().sum() / len(healthcare) * 100
if null_rate > 0:
print(f"{i} процент пустых значений: %{null_rate:.2f}")
Для столбца bmi используем заполнение данных на "Unknown" для пустых значений.
healthcare['bmi'] = healthcare['bmi'].fillna('Unknown')
print(healthcare.describe())
Проверим данные на аномалии
healthcare_zscores = healthcare.select_dtypes(include=['float64', 'int64']).apply(stats.zscore, nan_policy='omit')
# Устанавливаем порог для поиска аномалий
threshold = 3
# Находим аномалии
try:
print("\nАномалии в наборе данных healthcare:")
find_anomalies(healthcare_zscores, healthcare)
except Exception as e:
print(f"Произошла ошибка: {e}")
Теперь выполним разбиение данных
healthcare_train, healthcare_val, healthcare_test, healthcare_train_labels, healthcare_val_labels, healthcare_test_labels = split_data(healthcare, 'stroke')
check_balance(healthcare_train_labels, healthcare_val_labels, healthcare_test_labels)
В этом наборе данных данные совсем несбалансированы, из-за чего аугментация данных необходима для более точного обучения. В этом наборе используем undersampling.
from imblearn.under_sampling import RandomUnderSampler
X_healthcare = healthcare.drop('stroke', axis=1)
y_healthcare = healthcare['stroke']
rus_healthcare = RandomUnderSampler(random_state=42)
X_healthcare_resampled_under, y_healthcare_resampled_under = rus_healthcare.fit_resample(X_healthcare, y_healthcare)
healthcare_resampled_under = pd.DataFrame(X_healthcare_resampled_under, columns=X_healthcare.columns)
healthcare_resampled_under['stroke'] = y_healthcare_resampled_under
print("\nUndersampling для Healthcare:")
print(healthcare_resampled_under['stroke'].value_counts())