47 KiB
Бизнес-цели для набора данных своего варианта:
Прогнозирование опасности столкновения астероидов с планетой; Прогнозирование опасности астероидов для природных явлений. Цели технического проекта для каждой бизнес-цели:
Для второй бизнес-цели целью является определение включения астероидов в состав системы мониторинга столкновений. Для первой бизнес-цели целью является определение ближайших к Земле астероидов. Загрузка данных и получение сведений о датафрейме с данными
import pandas as pd
# Загрузка датасета
df = pd.read_csv("data/neo.csv")
df.head()
display(df.isnull().sum())
display()
from sklearn.model_selection import train_test_split
data1 = df[["miss_distance", "relative_velocity", "absolute_magnitude", "sentry_object"]].copy()
df1_train, df1_temp = train_test_split(
data1,
stratify=data1["sentry_object"],
test_size=0.4,
random_state=42
)
df1_val, df1_test = train_test_split(
df1_temp,
stratify=df1_temp["sentry_object"],
test_size=0.5,
random_state=42
)
X1_train = df1_train.drop(columns=["sentry_object"])
y1_train = df1_train["sentry_object"]
X1_val = df1_val.drop(columns=["sentry_object"])
y1_val = df1_val["sentry_object"]
X1_test = df1_test.drop(columns=["sentry_object"])
y1_test = df1_test["sentry_object"]
display(X1_train)
display(y1_train)
display(X1_test)
display(y1_test)
data2 = df[["miss_distance", "est_diameter_max", "hazardous"]].copy()
df2_train, df2_temp = train_test_split(
data2,
stratify=data2["hazardous"],
test_size=0.4,
random_state=42
)
df2_val, df2_test = train_test_split(
df2_temp,
stratify=df2_temp["hazardous"],
test_size=0.5,
random_state=42
)
X2_train = df2_train.drop(columns=["hazardous"])
y2_train = df2_train["hazardous"]
X2_val = df2_val.drop(columns=["hazardous"])
y2_val = df2_val["hazardous"]
X2_test = df2_test.drop(columns=["hazardous"])
y2_test = df2_test["hazardous"]
display("Обучающая выборка первого набора данных: ", df1_train.shape)
display(df1_train.absolute_magnitude.value_counts())
display("Контрольная выборка первого набора данных: ", df1_val.shape)
display(df1_val.absolute_magnitude.value_counts())
display("Тестовая выборка первого набора данных: ", df1_test.shape)
display(df1_test.absolute_magnitude.value_counts())
display("Обучающая выборка второго набора данных: ", df2_train.shape)
display(df2_train.est_diameter_max.value_counts())
display("Контрольная выборка второго набора данных: ", df2_val.shape)
display(df2_val.est_diameter_max.value_counts())
display("Тестовая выборка второго набора данных: ", df2_test.shape)
display(df2_test.est_diameter_max.value_counts())
from sklearn.preprocessing import OneHotEncoder
import pandas as pd
encoder = OneHotEncoder(sparse_output=False, drop='first')
target_col1 = "sentry_object"
encoded_1 = encoder.fit_transform(data1[[target_col1]])
encoded_cols_1 = encoder.get_feature_names_out([target_col1])
encoded_df1 = pd.DataFrame(encoded_1, columns=encoded_cols_1, index=data1.index)
target_col2 = "hazardous"
encoded_2 = encoder.fit_transform(data2[[target_col2]])
encoded_cols_2 = encoder.get_feature_names_out([target_col2])
encoded_df2 = pd.DataFrame(encoded_2, columns=encoded_cols_2, index=data2.index)
encoded_df1, encoded_df2
import numpy as np
import pandas as pd
labels_1 = ["included", "not_included"]
num_bins_1 = 2
abs_mag_filled = data1["absolute_magnitude"].fillna(data1["absolute_magnitude"].median())
hist_1, bins_1 = np.histogram(abs_mag_filled, bins=num_bins_1)
cut_no_labels_1 = pd.cut(abs_mag_filled, bins=bins_1)
cut_with_labels_1 = pd.cut(abs_mag_filled, bins=bins_1, labels=labels_1)
display_1 = pd.concat([data1["absolute_magnitude"], cut_no_labels_1, cut_with_labels_1], axis=1).head(20)
labels_2 = ["potentially_dangerous", "not_dangerous"]
num_bins_2 = 2
miss_dist_filled = data2["miss_distance"].fillna(data2["miss_distance"].median())
hist_2, bins_2 = np.histogram(miss_dist_filled, bins=num_bins_2)
cut_no_labels_2 = pd.cut(miss_dist_filled, bins=bins_2)
cut_with_labels_2 = pd.cut(miss_dist_filled, bins=bins_2, labels=labels_2)
display_2 = pd.concat([data2["miss_distance"], cut_no_labels_2, cut_with_labels_2], axis=1).head(20)
display_1, display_2
data1_cl = data1.copy()
data2_cl = data2.copy()
data1_cl["is_included"] = data1_cl["sentry_object"].apply(lambda x: 1 if x == "True" else 0)
data2_cl["is_close"] = data2_cl["hazardous"].apply(lambda x: 1 if x == "True" else 0)
from sklearn import preprocessing
min_max_scaler = preprocessing.MinMaxScaler()
data1["absolute_magnitude_Norm"] = min_max_scaler.fit_transform(data1["absolute_magnitude"].to_numpy().reshape(-1, 1)).reshape(data1["absolute_magnitude"].shape)
data2["miss_distance_Norm"] = min_max_scaler.fit_transform(data2["miss_distance"].to_numpy().reshape(-1, 1)).reshape(data2["miss_distance"].shape)
data1[["absolute_magnitude", "absolute_magnitude_Norm"]].head(20)
data2[["miss_distance", "miss_distance_Norm"]].head(20)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
abs_mag_array = data1["absolute_magnitude"].to_numpy().reshape(-1, 1)
data1["absolute_magnitude_Stand"] = scaler.fit_transform(abs_mag_array).flatten()
miss_dist_array = data2["miss_distance"].to_numpy().reshape(-1, 1)
data2["miss_distance_Stand"] = scaler.fit_transform(miss_dist_array).flatten()
data1[["absolute_magnitude", "absolute_magnitude_Stand"]].head(20), data2[["miss_distance", "miss_distance_Stand"]].head(20)
from sklearn.model_selection import train_test_split
# Берем нормализованные признаки
X2_scaled = data2[["miss_distance_Norm", "est_diameter_max"]]
y2 = data2["hazardous"]
# Стратифицированное разбиение
X2_train, X2_temp, y2_train, y2_temp = train_test_split(
X2_scaled, y2, stratify=y2, test_size=0.4, random_state=42)
X2_val, X2_test, y2_val, y2_test = train_test_split(
X2_temp, y2_temp, stratify=y2_temp, test_size=0.5, random_state=42)
from imblearn.over_sampling import SMOTE
sm = SMOTE(random_state=42)
X2_train_bal, y2_train_bal = sm.fit_resample(X2_train, y2_train)
print("До балансировки:")
print(y2_train.value_counts())
print("После балансировки:")
print(pd.Series(y2_train_bal).value_counts())
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
display(X2_train_bal)
clf = RandomForestClassifier(random_state=42)
clf.fit(X2_train_bal, y2_train_bal)
y2_pred_val = clf.predict(X2_val)
print("Валидация:")
print(classification_report(y2_val, y2_pred_val))
y2_pred_test = clf.predict(X2_test)
print("Тест:")
print(classification_report(y2_test, y2_pred_test))
Для первого набора данных предсказательная способность достаточно хорошая, довольно быстрая скорость вычислений, достаточная надежность и вполне хорошая корреляция и цельность.
Для второго набора данных предсказательная способность довольно хорошая, крайне быстрая скорость вычислений, хорошая надежность, хорошая корреляция и цельность данных.