Автомобили являются одним из видов транспорта, который есть у людей. Некоторые люди покупают автомобили для ежедневного использования. Некоторые люди покупают автомобили, потому что у них остались хорошие воспоминания о прошлом. Некоторые даже купили машину, чтобы пополнить свою коллекцию.
Чтобы купить машину, нужно много думать, например, о цене. Какова правильная цена автомобиля? Чтобы ответить на этот вопрос, я попытался помочь, построив модель машинного обучения, которая предсказывает цену автомобиля. При изготовлении этой модели машинного обучения я использовал набор данных от Kaggle.

Профилирование данных

Прежде чем строить модель машинного обучения, я сделаю профилирование данных. Что такое профилирование данных?

Профилирование данных — это обобщение данных с использованием описательной статистики. Создание профилирования данных направлено на то, чтобы иметь четкое представление о данных для компиляции анализа структуры и визуализации данных.

Импорт данных

#DATA PROFILING
#Importing Data
import pandas as pd
pd.set_option('display.max_columns',None)
df = pd.read_csv('Data Harga Mobil Sesuai Spesifikasi.csv')

Первый шаг — инициализировать библиотеку и импортировать набор данных в Python с помощью Pandas и назначить его как df. Данные, загруженные с Kaggle, будут сохранены как Data Harga Mobil Sesuai Spesifikasi.csv.

Отображение длины данных

#Showing The Length of The Data
print("\nThe Length of The Data: ", len(df))

Второй шаг — показать, сколько данных содержится в наборе данных, используя len(). В результате размер этих данных равен 11914.

Отображение формы данных

#Showing The Shape of The Data
print("\nThe Shape of The Data: ", df.shape)

Третий шаг — отобразить форму данных с помощью .shape. В результате эти данные имеют 11914 строк и 16 столбцов.

Отображение информации о данных

#Showing The Information of The Data
print("\nThe Information of The Data: ")
print(df.info())

Четвертый шаг — получение информации из данных с помощью функции .info().

Отображение статистических расчетов

#Showing The Statistical Calculations
print("\nThe The Statistical Calculations: ")
print(df.describe().T)

Пятый шаг — отобразить статистический анализ данных с помощью .describe().

Отображение уникальных данных

#Showing The Unique Data
print("\nThe The Unique Data: ")
print(df.nunique())

Шестой шаг профилирования данных — отображение уникальных данных из каждого столбца с помощью функции .nunique().

Изменение имени столбца и значения столбца

#Changing The Column's Name And The Column's Value
kolom_string = list(df.dtypes[df.dtypes == 'object'].index)
for col in kolom_string:
    df[col] = df[col].str.lower().str.replace(' ', '_')

df.rename(columns ={'MSRP': 'Price',
                    'Make': 'Car Brand',
                    'Engine HP': 'HP',
                    'Driven_Wheels':'Driven Mode',
                    'highway MPG':'KML-H',
                    'city mpg':'KML-C'}, inplace=True)

Как показано на Рис. 1, имя столбца в наборе данных неоднозначно. Например, столбец MSRP содержит цену автомобиля. Поэтому я собираюсь изменить имя столбца. Для значения столбца я изменю его на нижний регистр и использую подчеркивание.

В поисках корреляции

#Looking For A Correlation
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(17, 15))
corr_mask = np.triu(df.corr())
h_map = sns.heatmap(df.corr(), mask=corr_mask, annot=True, cmap='Blues')
plt.yticks(rotation=360)
plt.show()

Последним этапом профилирования данных является поиск корреляции между каждыми данными. В этой части я буду использовать Seaborn, Matplotlib и Numpy.

Очистка данных

После профилирования данных я займусь очисткой данных. Что такое очистка данных?

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

Перед очисткой данных я создам функцию hapus_outliers, которая получает параметры data и x. Цель этой функции — облегчить удаление выбросов. Я объясню, что такое выбросы?

Выбросы — это экстремальные значения, которые значительно выделяются из общего набора значений в наборе данных или на графике.

Вот функция для удаления выбросов.

#DATA CLEANSING
#Create a function to remove the outliers
def hapus_outliers(data, x):
    Q1 = data[x].quantile(0.25)
    Q3 = data[x].quantile(0.75)
    IQR = Q3 - Q1
    data = data[~((data[x] < (Q1 - 1.5 * IQR)) | (data[x] > (Q3 + 1.5 * IQR)))]
    return data

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

Поиск пропущенного значения в каждом столбце

#Looking For The Missing Value in Each Column
print("\nLooking For The Missing Value in Each Column: ")
print(df.isnull().sum())

Я использую isnull() и sum(), чтобы узнать, сколько пропущенного значения. Отсутствуют три значения в Тип топлива для двигателя, 69отсутствуют значения в HP, 30 пропущенные значения в Цилиндрах двигателя, шестьотсутствующих значений в Число дверей и 3742пропущенных значения в strong>Категория рынка.

Удаление ненужного столбца

#Removing Unnecessary Column
df = df.drop(['Popularity','Number of Doors','KML-H','KML-C','Market Category'], axis=1)

Проверка столбца цены

#Checking The Price Column
print("\nChecking The Price Column")
sns.histplot(df['Price'])
plt.show()

Первым шагом было изучение столбца «Цена» путем визуализации данных с помощью seaborn и matplotlib. Как видно на рис. 6, в столбце Цена есть выбросы. Чтобы преодолеть эти выбросы, я удалю их, используя предыдущую функцию, которую я создал под названием hapus_outliers.

df = hapus_outliers(df, 'Price')

После удаления выбросов в столбце «Цена» я буду искать недостающее значение в каждом столбце.

print("\nThe Amount of Missing Value in Each Column After Removing The Outliers in The Price Column:")
print(df.isnull().sum())

На рис. 7 после удаления выбросов отсутствующее значение в столбце HP изменилось на 56.

print("\nThe Shape of The Data After Removing The Outliers: ", df.shape)

После удаления выбросов в столбце «Цена» эти данные содержат 10 918 строк и 11 столбцов.

Проверка столбца марки автомобиля

#Checking The Car Brand Column
print("\nChecking The Car Brand Column")
sns.catplot(x='Car Brand', y='Price', data=df, height=5, aspect=2)
plt.xticks(rotation=90)
plt.show()

Проверка столбца года

#Checking The Year Column
print("\nChecking The Year Column")
sns.catplot(x='Year', y='Price', data=df, height=5, aspect=2)
plt.xticks(rotation=90)
plt.show()

Проверка колонки типа топлива двигателя

#Checking The Engine Fuel Type Column
print("\nChecking The Engine Fuel Type Column")
sns.catplot(x='Engine Fuel Type', y='Price', data=df, height=5, aspect=2)
plt.xticks(rotation=90)
plt.show()

Количество отсутствующих значений в столбце «Тип топлива для двигателя» равно трем. На Рис. 10 в столбце "Тип моторного топлива" представлено 10 типов данных:
- "премиум_неэтилированный_(обязательно)"
- "обычный_неэтилированный"
- "премиум_неэтилированный_ (рекомендуется)'
 – 'гибкое топливо_(неэтилированный/e85)'
 – 'дизельный двигатель'
 – "электрический"
 – 'гибкое топливо_(премиум_неэтилированный_рекомендуется/e85)'
- 'природный_газ'
- 'гибкое топливо_(премиум_неэтилированный_требуется/e85)'
- 'гибкое топливо_(неэтилированный/природный_газ)'

После того, как я узнаю, какие данные заполняются в колонке «Тип топлива двигателя», я посмотрю на отсутствующее значение в этой колонке.

print("\nThe Data on The Engine Fuel Type Column That Has A Missing Value:")
print(df.loc[(df['Engine Fuel Type'].isnull())])

На Рис. 11 автомобилем с отсутствующим значением является Suzuki Verona. Suzuki Verona использует обычный неэтилированный двигатель. Поэтому я собираюсь превратить это отсутствующее значение в 'regular_unleaded'.

df['Engine Fuel Type'] = df['Engine Fuel Type'].fillna('regular_unleaded')

После замены отсутствующего значения на regular_unleaded я буду искать отсутствующее значение в каждом столбце.

print("\nThe Amount of Missing Value in Each Column After Handling Missing Value in The Engine Fuel Type Column: ")
print(df.isnull().sum())

На Рис. 12 после обработки отсутствующего значения отсутствующее значение в столбце Тип топлива для двигателя изменилось на 0.

Проверка колонки цилиндров двигателя

#Checking The Engine Cylinders Column
print("\nChecking The Engine Cylinders Column")
sns.catplot(x='Engine Cylinders', y='Price', data=df, height=5, aspect=2)
plt.show()

После того, как я узнаю, какие данные заполняются в колонке «Цилиндры двигателя», я посмотрю на отсутствующее значение в этой колонке.

print("\nThe Data on The Engine Cylinders Column That Has A Missing Value:")
print(df.loc[(df['Engine Cylinders'].isnull())])

В приведенном выше коде автомобили с отсутствующим значением: Chevrolet Bolt EV, Volkswagen E-Golf, Toyota Rav4 EV, Mazda RX. -7 и Mazda RX-8. Chevrolet Bolt EV, Volkswagen E-Golf и Toyota Rav4 EV — это электромобили, поэтому у них нет цилиндров. Mazda RX-7 и Mazda RX-8 не используют цилиндр двигателя, а используют роторный двигатель. Поэтому я превращу это отсутствующее значение в 0.

df['Engine Cylinders'] = df['Engine Cylinders'].fillna(0)

После замены отсутствующего значения на 0 я буду искать отсутствующее значение в каждом столбце.

print("\nThe Amount of Missing Value in Each Column After Handling Missing Value in The Engine Cylinders Column:")
print(df.isnull().sum())

На Рис. 14 после обработки отсутствующего значения отсутствующее значение в столбце Цилиндры двигателя изменилось на 0.

Проверка колонки HP

В столбце HP пропущено 56 значений; Я посмотрю на недостающее значение.

#Checking the HP Column
print("\nChecking the HP Column")
print(df.loc[(df['HP'].isnull())])

Уже упомянутый в Таблице 1 автомобиль имеет следующую мощность (л.с.):
- мощность Fiat 500e составляет 111 л.с.
- мощность Lincoln Continental составляет 305
- Мощность Lincoln MKZ 245 л.с.
- Мощность Ford Escape 179 л.с.
- Мощность Ford Freestar 201 л.с.
- Ford Мощность Focus составляет 160 л.с.
- Мощность Chevrolet Impala составляет 305 л.с.
- Мощность Nissan Leaf составляет 150 л.с.
- Мощность Tesla Model S составляет 1020 л.с.
- Мощность KIA Soul EV составляет 109 л.с.
- Мощность Toyota Rav4 EV составляет 154 л.с.
- Мощность Honda Fit EV составляет 123 л.с.
- Мощность Mitsubishi I-Miev составляет 66 л.с.
- Мощность Mercedes-Benz M-Class составляет 200 л.с.

df.loc[(df['Car Brand'] == 'fiat') & (df['Model'] == '500e')] = df.loc[(df['Car Brand'] == 'fiat') & (df['Model'] == '500e')].fillna(111)
df.loc[(df['Car Brand'] == 'lincoln') & (df['Model'] == 'continental')] = df.loc[(df['Car Brand'] == 'lincoln') & (df['Model'] == 'continental')].fillna(305)
df.loc[(df['Car Brand'] == 'lincoln') & (df['Model'] == 'mkz')] = df.loc[(df['Car Brand'] == 'lincoln') & (df['Model'] == 'mkz')].fillna(245)
df.loc[(df['Car Brand'] == 'ford') & (df['Model'] == 'escape')] = df.loc[(df['Car Brand'] == 'ford') & (df['Model'] == 'escape')].fillna(179)
df.loc[(df['Car Brand'] == 'ford') & (df['Model'] == 'freestar')] = df.loc[(df['Car Brand'] == 'ford') & (df['Model'] == 'freestar')].fillna(201)
df.loc[(df['Car Brand'] == 'ford') & (df['Model'] == 'focus')] = df.loc[(df['Car Brand'] == 'ford') & (df['Model'] == 'focus')].fillna(160)
df.loc[(df['Car Brand'] == 'chevrolet') & (df['Model'] == 'impala')] = df.loc[(df['Car Brand'] == 'chevrolet') & (df['Model'] == 'impala')].fillna(305)
df.loc[(df['Car Brand'] == 'nissan') & (df['Model'] == 'leaf')] = df.loc[(df['Car Brand'] == 'nissan') & (df['Model'] == 'leaf')].fillna(150)
df.loc[(df['Car Brand'] == 'tesla') & (df['Model'] == 'model_s')] = df.loc[(df['Car Brand'] == 'tesla') & (df['Model'] == 'model_s')].fillna(1020)
df.loc[(df['Car Brand'] == 'kia') & (df['Model'] == 'soul_ev')] = df.loc[(df['Car Brand'] == 'kia') & (df['Model'] == 'soul_ev')].fillna(109)
df.loc[(df['Car Brand'] == 'toyota') & (df['Model'] == 'rav4_ev')] = df.loc[(df['Car Brand'] == 'toyota') & (df['Model'] == 'rav4_ev')].fillna(154)
df.loc[(df['Car Brand'] == 'honda') & (df['Model'] == 'fit_ev')] = df.loc[(df['Car Brand'] == 'honda') & (df['Model'] == 'fit_ev')].fillna(123)
df.loc[(df['Car Brand'] == 'mitsubishi') & (df['Model'] == 'i-miev')] = df.loc[(df['Car Brand'] == 'mitsubishi') & (df['Model'] == 'i-miev')].fillna(66)
df.loc[(df['Car Brand'] == 'mercedes-benz') & (df['Model'] == 'm-class')] = df.loc[(df['Car Brand'] == 'mercedes-benz') & (df['Model'] == 'm-class')].fillna(200)

После замены пропущенного значения я буду искать пропущенное значение в каждом столбце.

print("\nThe Amount of Missing Value in Each Column After Handling Missing Value in The HP Column:")
print(df.isnull().sum())

На Рис. 15 после обработки отсутствующего значения отсутствующее значение в столбце HP изменилось на 0.

Удаление повторяющихся данных

#Removing Duplicated Data
print("\nRemoving Duplicated Data")
df.drop_duplicates(inplace=True)
print('\nThe Shape of The Data After Removing The Duplicated Data: ', df.shape)

В этом разделе я собираюсь удалить повторяющиеся данные. После удаления повторяющихся данных эти данные содержат 10189 строк и 11 столбцов.

Преобразование меток в наборе данных

print("\nLabel Encoding on The Dataset")
car_brand = pd.get_dummies(df['Car Brand'], drop_first=True)
model = pd.get_dummies(df['Model'], drop_first=True)
engine_fuel_type = pd.get_dummies(df['Engine Fuel Type'], drop_first=True)
transmission_type = pd.get_dummies(df['Transmission Type'], drop_first=True)
driven_mode = pd.get_dummies(df['Driven Mode'], drop_first=True)
vehicle_size = pd.get_dummies(df['Vehicle Size'], drop_first=True)
vehicle_style = pd.get_dummies(df['Vehicle Style'], drop_first=True)
df = df.drop(['Car Brand',
              'Model',
              'Engine Fuel Type',
              'Transmission Type',
              'Driven Mode',
              'Vehicle Size',
              'Vehicle Style'], axis=1)
df = pd.concat([car_brand,
                model,
                engine_fuel_type,
                transmission_type,
                driven_mode,
                vehicle_size,
                vehicle_style,
                df], axis=1)

Разделение функций и меток

#Separating Features and Labels
X = df.drop('Price', axis=1)
y = df['Price'].astype(int)

Функции — это описательные атрибуты, а метка — это то, что вы пытаетесь предсказать или спрогнозировать. Итак, я сделаю две переменные; первая переменная - это X только с функциями и y только с меткой.

Подготовка обучения, тестирования и проверки набора данных

#Preparing Training, Testing, And Validating Dataset
from sklearn.model_selection import train_test_split
X_train_full, X_test, y_train_full, 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_full, y_train_full, test_size=0.2, random_state=42)

Создайте модель машинного обучения

Следующим шагом является построение модели машинного обучения. В этой части я проведу A/B-тестирование. Что такое A/B-тестирование?

Согласно Harvard Business Review, A/B-тестирование — это способ сравнить две версии чего-либо, чтобы выяснить, какая из них работает лучше.

Я буду сравнивать между LinearRegression, DecissionTreeRegressor, RandomForestRegressor, Lasso и Ridge.

Линейная регрессия

#Build a Machine Learning Model LinearRegression
from sklearn.linear_model import LinearRegression
model_linreg = LinearRegression()
model_linreg = model_linreg.fit(X_train, y_train)
y_pred_linreg = model_linreg.predict(X_test)

#Evaluating The Machine Learning Model
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np

#Mean Squared Error
mse = mean_squared_error(y_test, y_pred_linreg)
print('\nMean squared error dari Testing Set:', round(mse))

#Mean Absolute Error
mae = mean_absolute_error(y_test, y_pred_linreg)
print('Mean absolute error dari Testing Set:', round(mae))

#Root Mean Squared Error
rmse = np.sqrt(mse)
print('Root Mean Squared Error dari Testing Set:', round(rmse))

Дерево решений

#Build a Machine Learning Model DecisionTree
from sklearn.tree import DecisionTreeRegressor
model_dtr = DecisionTreeRegressor(random_state=42)
model_dtr = model_dtr.fit(X_train, y_train)
y_pred_dtr = model_dtr.predict(X_test)

#Evaluating The Machine Learning Model
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np

#Mean Squared Error
mse = mean_squared_error(y_test, y_pred_dtr)
print('\nMean squared error dari Testing Set:', round(mse))

#Mean Absolute Error
mae = mean_absolute_error(y_test, y_pred_dtr)
print('Mean absolute error dari Testing Set:', round(mae))

#Root Mean Squared Error
rmse = np.sqrt(mse)
print('Root Mean Squared Error dari Testing Set:', round(rmse))

Случайный лес

#Build a Machine Learning Model RandomForest
from sklearn.ensemble import RandomForestRegressor
model_rfr = RandomForestRegressor(random_state=42)
model_rfr = model_rfr.fit(X_train, y_train)
y_pred_rfr = model_rfr.predict(X_test)

#Evaluating The Machine Learning Model
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np

#Mean Squared Error
mse = mean_squared_error(y_test, y_pred_rfr)
print('\nMean squared error dari Testing Set:', round(mse))

#Mean Absolute Error
mae = mean_absolute_error(y_test, y_pred_rfr)
print('Mean absolute error dari Testing Set:', round(mae))

#Root Mean Squared Error
rmse = np.sqrt(mse)
print('Root Mean Squared Error dari Testing Set:', round(rmse))

Лассо

#Build a Machine Learning Model Lasso
from sklearn.linear_model import Lasso
model_lasso = Lasso(random_state=42)
model_lasso = model_lasso.fit(X_train, y_train)
y_pred_lasso = model_lasso.predict(X_test)

#Evaluating The Machine Learning Model
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np

#Mean Squared Error
mse = mean_squared_error(y_test, y_pred_lasso)
print('\nMean squared error dari Testing Set:', round(mse))

#Mean Absolute Error
mae = mean_absolute_error(y_test, y_pred_lasso)
print('Mean absolute error dari Testing Set:', round(mae))

#Root Mean Squared Error
rmse = np.sqrt(mse)
print('Root Mean Squared Error dari Testing Set:', round(rmse))

хребет

#Build a Machine Learning Model Ridge
from sklearn.linear_model import Ridge
model_ridge = Ridge(random_state=42)
model_ridge = model_ridge.fit(X_train, y_train)
y_pred_ridge = model_ridge.predict(X_test)

#Evaluating The Machine Learning Model
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np

#Mean Squared Error
mse = mean_squared_error(y_test, y_pred_ridge)
print('\nMean squared error dari Testing Set:', round(mse))

#Mean Absolute Error
mae = mean_absolute_error(y_test, y_pred_ridge)
print('Mean absolute error dari Testing Set:', round(mae))

#Root Mean Squared Error
rmse = np.sqrt(mse)
print('Root Mean Squared Error dari Testing Set:', round(rmse))

Оценка модели машинного обучения

Следующим этапом после построения модели машинного обучения является оценка этой модели. В этом процессе оценки я рассмотрю значения среднеквадратичной ошибки, средней абсолютной ошибки и среднеквадратичной ошибки. Я возьму наименьшее значение RMSE, чтобы решить, какое из них лучше.

Линейная регрессия

Результат использования линейной регрессии: 12227717 MSE, 2495 MAE и 3497 RMSE.

Регрессор дерева решений

Результат использования регрессора дерева решений: 16094808 MSE, 2667 MAE и 4012 RMSE.

Случайный лесной регрессор

Результат использования регрессора случайного леса: 12398483 MSE, 2380 MAE и 3521 RMSE.

Лассо

Результат использования Lasso: 13948854 MSE, 2789 MAE и 3735 RMSE.

хребет

Результат использования Ridge: 13800444 MSE, 2763 MAE и 3715 RMSE.

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

Визуализируйте модель машинного обучения

#Visualize The Machine Learning Model
fig = plt.figure(figsize=(17, 10))
df = df.sort_values(by=['Price'])
plt.scatter(range(X.shape[0]), y, color='red', label='Real')
plt.scatter(range(X.shape[0]), model.predict(X), marker='.', label='Predict')
plt.legend(loc='best', prop={'size': 8})
plt.show()

Проверка модели машинного обучения

#Validating The Machine Learning Model
for i in range(5):
    real = y_val.iloc[i]
    pred = int(model_linreg.predict(X_val.iloc[i].to_frame().T)[0])
    print(f'Real Value      ----->>>>> {real} $\n'
          f'Predicted Value ----->>>>> {pred} $')
    print()

Это от меня; Вы можете связаться со мной, если у вас есть критика, совет или вопрос об этом проекте. Спасибо, я очень ценю, что вы нашли время, чтобы прочитать это.