Как я могу улучшить RMSE при оценке цены моего автомобиля?
`
new_condition_df = df[df['condition'].map(condition_mapping) == 2]
top_1000_highest_mileage = new_condition_df.nlargest(1000, 'mileage')['mileage']
average_top_1000_highest_mileage = top_1000_highest_mileage.mean()
# Filter the DataFrame for rows where condition is null or unspecified
null_condition_df = df[df['condition'].isnull() | (df['condition'] == '')]
# Update 'condition' based on mileage condition
null_condition_df.loc[null_condition_df['mileage'] >= average_top_1000_highest_mileage, 'condition'] = 'CONDITION_USED'
null_condition_df.loc[null_condition_df['mileage'] < average_top_1000_highest_mileage, 'condition'] = 'CONDITION_NEW'
# Update the original DataFrame with the modified rows
df.update(null_condition_df)
`
columns_with_null = ['color', 'vat_reclaimable', 'cubic_capacity', 'seller_country', 'feature']
df.dropna(subset=columns_with_null, inplace=True)
df['air_conditioning'].fillna('AIRCONDITIONING_NONE', inplace=True)
df['parking_camera'].fillna('PARKINGCAMERA_NONE', inplace=True)
df['parking_sensors'].fillna('PARKINGSENZOR_NONE', inplace=True)
features = ['mileage', 'cubic_capacity', 'power', 'year'] + list(df.columns[df.columns.str.startswith('car_style_')]) + list(df.columns[df.columns.str.startswith('transmission_')]) + list(df.columns[df.columns.str.startswith('fuel_type_')])
train_data = df.dropna(subset=['drive']) # Odstranění řádků s chybějícími hodnotami sloupce 'drive'
X_train, X_test, y_train, y_test = train_test_split(train_data[features], pd.get_dummies(train_data['drive']), test_size=0.2, random_state=42)
model = LinearRegression()
model.fit(X_train, y_train)
missing_data = df[df['drive'].isnull()]
X_missing = missing_data[features]
predicted_values = model.predict(X_missing)
df_imputed = df.copy()
predicted_df = pd.DataFrame(predicted_values, columns=y_train.columns, index=missing_data.index)
df_imputed.loc[df_imputed['drive'].isnull(), y_train.columns] = predicted_df.values
predicted_df_encoded = pd.DataFrame(predicted_values, columns=y_train.columns, index=missing_data.index)
predicted_df_encoded = (predicted_df_encoded > 0.5).astype(int)
for column in predicted_df_encoded.columns:
df_imputed[column] = 0 # Přidání sloupce se všemi hodnotami 0
df_imputed.loc[predicted_df_encoded.index, column] = predicted_df_encoded[column].values
unique_values_imputed_encoded = df_imputed['drive'].unique()
df = df_imputed
df.drop(columns=['drive'], inplace=True)
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
df = df.join(pd.DataFrame(mlb.fit_transform(df['feature']),columns=mlb.classes_))
df.fillna(0, inplace=True)
df = df.drop(columns=['feature'])
df_encoded = pd.get_dummies(df)
X_train, X_test, y_train, y_test = train_test_split(df_encoded.drop(columns=['price_with_vat_czk']), df_encoded['price_with_vat_czk'], test_size=0.25, random_state=42)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
Вся программа: https://onecompiler.com/python/42brp9a4r Набор данных https://filetransfer.io/data-package/a0mFEfg4#link
Мой RMSE составляет около 64 тысяч.
Любой ответ будет коротким, предстоит много дел, и именно в этом, я думаю, и заключается роль одного специалиста по данным. Несколько вопросов, которые вы можете задать себе для начала:
Я думаю, что существует некоторый исследовательский анализ недостающих данных, например, вы можете увидеть, что ваша диаграмма рассеяния говорит вам, что, возможно, линейная регрессия - не лучший подход. Я только что попробовал себя с sklearn.ensemble.RandomForestRegressor
с гиперпараметрами по умолчанию, и поведение полученного графика стало лучше, RMSE уменьшилось примерно до 45 КБ, а R2 переместился с 0,88 до 0,94 (см. sklearn.metrics.r2_score
).
Вы можете, например, получить корреляцию между вашим вектором функций и вашей целью, чтобы увидеть, что происходит с переменными, прежде чем выполнять любую модель, и вы увидите, что это высокая корреляция с «годом»:
df_encoded.corr(method = "spearman")["price_with_vat_czk"].sort_values()
Вы можете попробовать исследовательский анализ данных, чтобы лучше настроить свои функции (статистика — ваш друг), также вы можете попробовать несколько алгоритмов, а после этого поиграть с разными гиперпараметрами (см. sklearn.model_selection.GridSearchCV
), затем поместить свои модели в конвейеры и попытаться получить важность функции, чтобы уменьшить размерность количества имеющихся у вас функций (для этого см. SHAP или GINI)... Подводя итог, еще многое предстоит сделать...
Сама идея выглядит неплохо, но теперь вам нужно повторить то, что вы сделали, это самое забавное :). Некоторые вещи, которые вы могли бы попробовать:
Улучшите предварительную обработку: В общем, я бы постарался лучше понять данные, построить их график, проанализировать распределения, увидеть корреляцию. Данные — это друг, а не еда. Вы можете попробовать нормализовать данные (в зависимости от модели, которую вы собираетесь использовать, это имеет большое значение, мало или ничего). Попробуйте удалить выбросы, если их слишком много. Если распределения перекошены (как нормальное распределение, но «перемещены»), вы можете попробовать применить логарифмическое преобразование.
Попробуйте разные модели: Здесь вы можете попробовать много чего. Я бы рекомендовал начать с древовидной модели. По моему личному опыту, XGboost обычно дает действительно хорошие результаты, но я приглашаю вас попробовать разные варианты и изучить разные методы! Если вы действительно хотите набрать очки, вы можете даже собрать свою собственную сборку моделей. То есть обучение, например, 5 разных моделей, каждая со своими сильными и слабыми сторонами, и средний (или что-то в этом роде) результат всех них. Но для этого вам сначала нужно 5 хороших моделей и подумать, улучшит ли их объединение или просто уменьшит RMSE лучшей модели.
Затем вы можете попробовать все скучные вещи: использовать поиск по сетке, чтобы изменить гиперпараметры, такие как скорость обучения, условия регулирования и все такое, но если вы пытаетесь учиться, я бы сказал, что это вторично.