16 KiB
- Были выбраны следующие датасеты:
- Данные о автомобилях (17)
- Данные о мобильных устройствах (18)
- Данные о миллиордерах (19)
import pandas as pd
cars_df = pd.read_csv("./car_price_prediction.csv")
phones_df = pd.read_csv("./mobile phone price prediction.csv")
rich_df = pd.read_csv("./Forbes Billionaires.csv")
- Проблемные области: car_price_prediction.csv - цены на автомобили mobile phone price prediction.csv - цены на мобильные телефоны Forbes Billionaires.csv - данные о миллиордерах
- Объекты наблюдения car_price_prediction.csv: автомобили; mobile phone price prediction.csv: телефоны; Forbes Billionaires.csv: миллиардеры;
Атрибуты:
print(phones_df.columns)
print(phones_df.columns)
print(rich_df.columns)
Связи между объектами не прослеживаю
car_price_prediction.csv и mobile phone price prediction.csv бизнес-целью будует являться формирование цены, которая будет соответсвовать существующему рынку и атрибутам объекта. Forbes Billionaires.csv - выявление наиболее прибыльных видов бизнеса и проверенных спосов создания капитала
Формирование цены: на вход характеристики продукта; целевой признак - цена Выявление...: на вход вид бизнеса, страна, источники дохода; целевой признак - место в форбс
6, 7. Проблемы наборов данных Зашумленность:
print(cars_df.shape[0])
print(phones_df.shape[0])
print(rich_df.shape[0])
Так как набо дастаточно быльшие (более 1000 строк), то зашкмленность не будет иметь сильного влияние на качество, шумы усреднятся
Смещение данных, актуальность и просачивание данных проверить представляетяс невозможным, так как был взят готовый сет данных
print("было ", phones_df.shape[0])
for column in phones_df.select_dtypes(include=['int', 'float']).columns:
mean = cars_df[column].mean()
std_dev = cars_df[column].std()
print(column, mean, std_dev)
lower_bound = mean - 3 * std_dev
upper_bound = mean + 3 * std_dev
cars_df = cars_df[(cars_df[column] <= upper_bound) & (cars_df[column] >= lower_bound)]
print("стало ", cars_df.shape[0])
print("\n------------------\n")
print("было ", phones_df.shape[0])
for column in phones_df.select_dtypes(include=['int', 'float']).columns:
mean = phones_df[column].mean()
std_dev = phones_df[column].std()
print(column, mean, std_dev)
lower_bound = mean - 3 * std_dev
upper_bound = mean + 3 * std_dev
phones_df = phones_df[(phones_df[column] <= upper_bound) & (phones_df[column] >= lower_bound)]
print("стало ", phones_df.shape[0])
print("\n------------------\n")
print("было ", rich_df.shape[0])
for column in rich_df.select_dtypes(include=['int', 'float']).columns:
mean = rich_df[column].mean()
std_dev = rich_df[column].std()
print(column, mean, std_dev)
lower_bound = mean - 3 * std_dev
upper_bound = mean + 3 * std_dev
rich_df = rich_df[(rich_df[column] <= upper_bound) & (rich_df[column] >= lower_bound)]
print("стало ", rich_df.shape[0])
Выше были устранены выбросы, которые могли повлиять на качество данных. При этом выбока осталась достаточного размера для работы с ней
- На мой взгляд наборы довольно информативные учитывая кол-во строк и атрибутов. Степень покрытия, соответсвие реальным данным и согласованность меток проверить не представляется возможным (но я верю составителям сетов)
- Проверка на пропущенные значения:
print(cars_df.isnull().sum().loc[lambda x: x>0])
print("--------------")
print(phones_df.isnull().sum().loc[lambda x: x>0])
print("--------------")
print(rich_df.isnull().sum().loc[lambda x: x>0])
в датасете с телефонами нашлись пустые значения. Жаль, но они все не числовые, поэтому просто заменим на моду
columns = ["Android_version", "Inbuilt_memory", "fast_charging", "Screen_resolution", "Processor"]
for column in columns:
mode = phones_df[column].mode()[0]
phones_df[column].fillna(mode, inplace=True)
print(phones_df.isnull().sum().loc[lambda x: x>0])
Не знаю насколько это правильно и как отразиться на качестве данных, но удалять 400+ строк их 1300 явно было бы хуже
- Разбиение данных на выборки
from sklearn.model_selection import train_test_split
cars_train_df, cars_temp_df = train_test_split(cars_df, test_size=0.3, random_state=52)
cars_val_df, cars_test_df = train_test_split(cars_temp_df, test_size=0.5, random_state=52)
phones_train_df, phones_temp_df = train_test_split(phones_df, test_size=0.3, random_state=52)
phones_val_df, phones_test_df = train_test_split(phones_temp_df, test_size=0.5, random_state=52)
rich_train_df, rich_temp_df = train_test_split(rich_df, test_size=0.3, random_state=52)
rich_val_df, rich_test_df = train_test_split(rich_temp_df, test_size=0.5, random_state=52)
print(cars_df.shape[0], cars_train_df.shape[0], cars_test_df.shape[0], cars_val_df.shape[0])
print(cars_val_df.shape[0] + cars_test_df.shape[0] + cars_train_df.shape[0])
print('\n', phones_df.shape[0], phones_train_df.shape[0], phones_test_df.shape[0], phones_val_df.shape[0])
print(phones_val_df.shape[0] + phones_test_df.shape[0] + phones_train_df.shape[0])
print('\n', rich_df.shape[0], rich_train_df.shape[0], rich_test_df.shape[0], rich_val_df.shape[0])
print(rich_val_df.shape[0] + rich_test_df.shape[0] + rich_train_df.shape[0])
Данные были разбиты на обучающую, тестовую и контрольную выборки в отношении 70%-15%-15%
- Взял проценты из лекции, наверное это сбалансированно
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
cars_df['old_type'] = pd.cut(cars_df['Prod. year'], bins=[1900, 2004, 2015, 2025],
labels=['Old', 'Normal', 'New'])
y = cars_df['old_type']
x = cars_df.drop(columns=['Prod. year', 'old_type'])
oversampler = RandomOverSampler(random_state=52)
x_resampled, y_resampled = oversampler.fit_resample(x, y)
undersampler = RandomUnderSampler(random_state=52)
x_resampled_under, y_resampled_under = undersampler.fit_resample(x, y)
print("oversampling:")
print(pd.Series(y_resampled).value_counts())
print("undersampling:")
print(pd.Series(y_resampled_under).value_counts())
phones_df['rating_type'] = pd.cut(phones_df['Rating'], bins=[0, 4.0, 4.5, 5.0],
labels=["bad", "normal", "good"])
y = phones_df['rating_type']
x = phones_df.drop(columns=['Rating', 'rating_type'])
oversampler = RandomOverSampler(random_state=42)
x_resampled, y_resampled = oversampler.fit_resample(x, y)
undersampler = RandomUnderSampler(random_state=42)
x_resampled_under, y_resampled_under = undersampler.fit_resample(x, y)
print("oversampling:")
print(pd.Series(y_resampled).value_counts())
print("undersampling:")
print(pd.Series(y_resampled_under).value_counts())
rich_df['age_type'] = pd.cut(rich_df['Age'], bins=[0, 20, 60, 100],
labels=["young", "grown", "old"])
y = rich_df['age_type']
x = rich_df.drop(columns=['Age', 'age_type'])
oversampler = RandomOverSampler(random_state=42)
x_resampled, y_resampled = oversampler.fit_resample(x, y)
undersampler = RandomUnderSampler(random_state=42)
x_resampled_under, y_resampled_under = undersampler.fit_resample(x, y)
print("oversampling:")
print(pd.Series(y_resampled).value_counts())
print("undersampling:")
print(pd.Series(y_resampled_under).value_counts())