Machine Learning: Как да прогнозираме цени на автомобили?

Автор: Десислава Христова

Регресията е един от методите, прилагани от специалистите в областта на машинното обучение за решаване на конкретни бизнес задачи. В зависимост от начина на използване, можем да разделим задачите в 2 категории:

  • изследване на връзката на всяка от отделните характеристики с целевата променлива
  • прогнозиране на непрекъснати числови стойности (например заплата, цена, тегло и др.) на база на вече известни данни.

В тази статия с практически пример ще разгледаме решение на регресионна задача за прогнозиране на цени на автомобили. Ще използваме езика за програмиране Python и неговите библиотеки за анализ на данни и машинно обучение.

С какви данни ще работим?

Данните съдържат 4041 реда и 74 колони и включват обяви за продажба на автомобили от различни български сайтове. Извлечени са на 01.07.2021г.

5 случайно избрани реда изглеждат по следния начин:

 brandmodelmonth_prodyear_prodcolorengine_typehpgearboxcategorymileagegpsadaptive_flantiblock_sysairbags_backairbags_fronttire_pressure_controlparktronicisofixauto_start_stopdvd_tvstep_tipno_key_ignitionusb_av_inaux_outputsdiff_blockageboardcomplight_sensorel_mirrorsel_susp_adjclimatronicmf_steering_wheelsw_heating7seatsbuy_backbartergas_syslbsaved_soldsbleasingmethane_syspartsnew_importcreditservice_booktuning2_3_doorsxenon_lightsalloy_wheelsmetalicheated_wipersrollbartowbarhalogen_lightsmoving_roofoffroadalarmarmoredcascowinchreinforced_glass_windowssuederight_swtaxidate_createdtime_createddaymonthyearviewsdealercityregionprice
526Mercedes-BenzMLфевруари2015ЧервенБензинов333АвтоматичнаДжип67000ДаНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНе26 април 202118:0326април202111923АвтокъщаПловдивЮжен централен49950
1049AudiA3ноември2013СивБензинов140АвтоматичнаСедан190000ДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНе15 юни 202122:1415юни2021183АвтокъщаДупницаЮгозападен23500
649PorschePanameraсептември2012ЧеренБензинов400АвтоматичнаХечбек187000ДаНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНе11 юни 202116:4211юни20212469АвтокъщаПловдивЮжен централен54000
974AudiA3февруари2006СребъренДизелов105РъчнаХечбек186000НеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНе17 юни 202121:0117юни202117АвтокъщаРусеСеверен централен7500
920AudiA3май2003ЧеренДизелов101РъчнаХечбек200000НеНеДаНеНеНеНеНеНеНеНеНеНеНеДаДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНе10 юни 202115:4410юни2021691АвтокъщаСофияЮгозападен4500

Преглед на данните

За да добием представа за данните, с които разполагаме, ще създадем няколко визуализации. Те ще ни помогнат да намерим отговор на следните въпроси:

  • Кои марки и модели са най-предлагани?
  • В кои части на България има най-много обяви и на какви цени са автомобилите?
  • Какъв е процентът на обявите от Частно лице и Автокъща според типа двигател?
  • Какво е разпределението на променливите?
  1. Кои марки и модели са най-предлагани?

Най-предлаганото превозно средство е Audi A4, като има 324 обяви за този автомобил. На 10-то място е Mercedes-Benz C с 81 обяви.

Най-предлаганите превозни средства са на марките Audi и BMW, съответно 1029 и 633 на брой обяви. На 10-то място е марката Ford с 62 обяви.

  1. В кои части на България има най-много обяви и на какви цени са автомобилите?

Изчислена е средната претеглена стойност на броя обяви за всеки регион, като теглата са броя население на градовете в съответния регион. Има най-много обяви в Югозападния регион на България - 1526 обяви средно, а най-малко в Северен централен - 85. Има и 1 единствена обява за автомобил, който се намира извън България.

Тук отново е изчислена средна претеглена стойност, но този път за цената на автомобилите. Най-висока е средната цена на автомобил в Югозападния регион - 28389.80 лв. При Североизточния, Югоизточния и Южен централен са близки като стойности. За единствената обява извън България, цената на автомобила е 8900 лв.

  1. Какъв е процентът на обявите от частно лице и автокъща според типа двигател?

За обявите на автомобили от Автокъща най-предлагани са превозни средства с дизелов двигател - 2170 на брой обяви (69.6%), а най-малко с електрически - 13 обяви или 0.42%.

От частни лица се предлагат също най-много автомобили с дизелов двигател - 578 обяви или 62.6%. Има само 1 обява за автомобил с електрически двигател.

  1. Какво е разпределението на променливите?

Хистограмите представят разпределенията на числовите променливи в извадката, като с червената пунктирана вертикална линия е означена средната стойност, а със зелената е медианата.

Следната таблица представя средните и медианните стойности за всяка от числовите променливи.

 VariableMeanMedian
0year_prod2009.522009.00
1age11.4812.00
2hp194.22170.00
3mileage175794.17179890.00
4price22942.4912999.00
5views2841.96581.00

Някои изводи:

  • Разпределенията на годините на производство и възрастта на автомобила са близки до нормалното. При тях медианата и средната стойност са почти равни - 2009 и 2009.52.
  • При конските сили и пробега също няма толкова голяма разлика между средната стойност и медианата.
  • По-големи разлики се забелязват при цената и броя преглеждания на обявите. Двете разпределения не са нормално разпределени, а са асиметрични и дясно изтеглени.

Тъй като променливите цена (price) и брой преглеждания (views) не са нормално разпределени, ще ги трансформираме чрез логаритмичната функция, предоставена от библиотеката NumPy. В противен случай можем да получим подвеждащи резултати от регресионните модели.

Тъй като имаме много на брой бинарни променливи в извадката, ще разгледаме разпределението само на някои от тях. За да определим точно на кои, ще използваме класът Variance Threshold на библиотеката Scikit-learn, за да премахнем тези бинарни променливи, при които едната категория заема над 75% от данните.

 gpsauto_start_stopxenon_lightsmetalic
253НеНеНеНе
822НеНеНеНе
558НеДаДаНе
352ДаНеНеДа
3809НеНеНеНе

След прилагане на VarianceThreshold, оставаме с 4 бинарни променливи - наличие на GPS, наличие на Auto Start Stop функционалност, дали превозното средство има ксенонови фарове и дали е в цвят металик. На стълбовидните диаграми по-надолу, можете да видите тяхното разпределение.

Обявите, на които стойността на променливите е "Не", са повече.

Кодиране на категорийни променливи и стандартизация на данните

Необходимо е категорийните променливи да ги превърнем в числови, тъй като регресионните модели изискват входните данни да са числа. Нужно е също така те да бъдат и мащабирани, тъй като при използване на регресионните модели, които изчисляват коефициенти, можем да получим резултати с голяма грешка.

След обработката на данните, колоните в извадката ни стават 510 на брой. Следващата стъпка е да открием дали има аномалии в данните и кои са по-важните характеристики, които да използваме при изграждане на моделите за машинно обучение.

Обработка на отличителни стойности и избор на по-важни характеристики

За откриване на аномалии ще използваме методът k най-близки съседи (KNN) на библиотеката PyOD.

Алгоритъмът KNN e открил 404 обяви, в които се срещат аномалии. Тях ще ги премахнем от извадката, тъй като може да повлияят негативно на моделите за машинно обучение.

Следващата стъпка е да използваме класа SelectKBest на библиотеката Scikit-learn, за да открием 5-те характеристики, които оказват най-голямо влияние при при определяне на цената. Той получава като параметър статистически тест. В нашия случай това е f_regression, който първо открива корелацията между всяка характеристика и целевата променлива и конвентира получените резултати в F score и p-value. Накрая се извеждат тези променливи, получили най-добри оценки от теста.

SelectKBest e определил година на производство, конски сили, това дали превозното средство е с ръчна скоростна кутия, дали има ксенонови фарове и Auto Start Stop функционалност като най-важните променливи, определящи цената.

На следващата графика можете да видите корелационна матрица, която ни показва колко е силна зависимостта между отделните характеристики.

Премахваме променливите наличие на Auto Start Stop функционалност и ръчна скоростна кутия, тъй като между първата и година на производство има 60% положителна корелация, а между втората и променливата конски сили има 59% отрицателна корелация.

Изграждане на модели за машинно обучение с параметри по подразбиране

По време на тази стъпка ще създадем модели за машинно обучение, използващи различни регресионни алгоритми, като ще оставим параметрите, които са им зададени по подразбиране.

Първо е необходимо да разделим извадката на 2 части - 70% от данните ще са за обучение на моделите, а 30% за тест. Ще използваме train_test_split на библиотеката Scikit-learn.

След като сме разделили данните, трябва да създадем и обучим моделите. Ще използваме 12 различни регресионни алгоритми при изграждане на моделите, след което ще тестваме до колко добре те прогнозират стойностите на целевата променлива.

Получените прогнозирани стойности е необходимо да бъдат съпоставени с действителните. За тази цел ще разгледаме някои често използвани метрики за оценка на регресионни алгоритми. Това ще ни позволи да добием представа до колко добре моделите с параметри по подразбиране са прогнозирали цените на превозните средства.

Метриките, които ще разгледаме са:

  • R-квадрат (R-squared) и Изравнен R-квадрат (Adjusted R-squared)
  • Средна абсолютна грешка (MAE) и Средна абсолютна процентна грешка (MAPE)
  • Средна квадратична грешка (Mean Squared Error) & Корен от средната квадратична
    грешка (Root Mean Squared Error)
 ModelR2_scoreAdj R2MSERMSEMAEMAPE
7ExtraTreesRegressor0.880.88123842231.5511128.444694.3822.86
10RandomForestRegressor0.880.88124523408.5711159.014787.3422.39
11DecisionTreeRegressor0.880.88120830168.1410992.284789.5324.04
8GradientBoostingRegressor0.880.88123208997.3611099.955015.9122.27
0KNeighborsRegressor0.840.84163466018.5812785.385425.2323.23
2SGDRegressor0.710.71294067408.7217148.396255.4424.45
4Ridge0.680.68323521437.0517986.706331.0924.58
5BayesianRidge0.680.68323748351.9717993.016331.5124.58
1LinearRegression0.680.68324008977.9218000.256331.9924.58
3HuberRegressor0.650.65350406954.5418719.166412.7324.87
9AdaBoostRegressor0.690.69305244621.7717471.257002.4127.06
6OrthogonalMatchingPursuit0.440.44556220119.7123584.3210120.7842.96

Алгоритмите използващи дървете на решенията се справят най-добре от всички модели, като коефициентите им на детерминация са 0.88. ExtraTreesRegressor е на първо място според средна абсолютна грешка, а GradientBoostingRegressor е с най-нисък резултат за средна абсолютна процентна грешка - 22.27%, но стойностите на останалите грешки са по-високи. Най-лошо се е справил OrthogonalMatchingPursuit с 0.44 коефициент на детерминация и много високи грешки.

Избор на модел и откриване на оптимални параметри

Ще изберем модела, използващ алгоритъма ExtraTreesRegressor, защото като цяло даде най-добри резултати при теста с параметри по подразбиране. В тази стъпка ще използваме библиотеката Hyperopt, за да открием оптималните параметри за модела, при които средната абсолютна процентна грешка е най-ниска.

Първо ще зададем какво да бъде пространството от параметри, след което ще създадем и приложим целева фукнция.

Тъй като целевата променлива е преминала през трансформация с логаритъм, откриването на оптималните параметри е на база стойността на MAPE, а не MAE.

Оптималните параметри, които е открихме чрез функцията fmin(), са следните:

HyperparameterValue
criterionMAE
max_depth53
max_featuresNone
min_samples_leaf2
min_samples_split6
n_estimators200

След като вече имаме оптималните параметри, е необходимо да тестваме до колко добре моделът ще прогнозира стойностите на целевата променлива.

Получените резултати от модела са следните:

 MetricsScores
0R2_score0.84
1Adj R20.84
2MSE162523237.78
3RMSE12748.46
4MAE5093.31
5MAPE22.15

Резултатите са малко по-лоши от тези, получени при модела с параметрите по подразбиране по отношение на всички метрики освен средна абсолютна процентна грешка, но това е, защото търсихме оптимални параметри, при които тя да е най-ниска. Също така моделът не е обучен върху цялата обучаваща извадка наведнъж, а при оптимизиране на параметрите се използва кръстосана валидация и моделът се обучава и тества всеки път върху различни по-малки части от данните. Това позволява генерализация и ни помага да избегнем преобучение на модела (проблем, който би довел до лоши резултати при постъпване на нови данни).

Средната цена на превозно средство е 23383.51 лв, така че средна абсолютна грешка от 5093.31 лв можем да кажем, че е приемлива. Моделът може допълнително да се оптимизира, за да се намали тази грешка, като се добавят още стойности в пространството от параметри и чрез Hyperopt (или някоя друга библиотека за избор на оптимални параметри) да се открият по-подходящи стойности за параметрите на модела. Всичко е въпрос на множество експерименти докато се достигне до оптимално решение.

Коефициентът на детерминация е 0.84, което означава, че 84% от дисперсията на цената се обяснява от стойностите на независимите променливи.

Средната абсолютна процентна грешка е 22.15%, което я прави приемлива според интерпретацията на C. D. Lewis в книгата "Industrial and business forecasting methods: a practical guide to exponential smoothing and curve fitting".

Следната графика съпоставя пронозираните и действителните стойности и ни позволява да видим до колко те се разминават като стойности.

В сравнение с предишната графика, тази диаграма на разсейването ни показва точно колко са разликите между пронозираните и действителните стойности. Когато те са с отрицателен знак, тогава моделът е поставил по-ниска цена за автомобила от действителната, а когато е с положителен знак, е поставил по-висока цена.

Запазване на модела и тест върху нови данни

Ще използваме библиотеката joblib, за да съхраним както модела, така и функцията с предварителната обработка на данните в отделни файлове, които да можем след това да използваме директно върху новите данни и да правим прогнози.

След като сме съхранили файловете, ще приложим модела върху извадка с данни, които той не е виждал до този момент. Тя съдържа 473 реда с обяви за превозни средства, на които липсва поставена цена.

Първо е необходимо данните да преминат през съответната предварителна обработка, за да може да бъдат използвани от модела за машинно обучение.

5 случайни реда от данните след прилагане на предварителната обработка изглеждат по следния начин:

 year_prodxenon_lightshp
11-0.24632300.0636255
127-1.278920-0.738607
119-0.41842200.14162
218-0.2463231-0.827744
165-1.7952100.319894

Следната таблица представя 5 реда от новите данни, но вече с прогнозираните от модела цени.

 brandmodelmonth_prodyear_prodagecolorengine_typehpgearboxcategorymileagegpsadaptive_flantiblock_sysairbags_backairbags_fronttire_pressure_controlparktronicisofixauto_start_stopdvd_tvstep_tipno_key_ignitionusb_av_inaux_outputsdiff_blockageboardcomplight_sensorel_mirrorsel_susp_adjclimatronicmf_steering_wheelsw_heating7seatsbuy_backbartergas_syslbsaved_soldsbleasingmethane_syspartsnew_importcreditservice_booktuning2_3_doorsxenon_lightsalloy_wheelsmetalicheated_wipersrollbartowbarhalogen_lightsmoving_roofoffroadalarmarmoredcascowinchreinforced_glass_windowssuederight_swtaxidate_createdtime_createddaymonthyearviewsdealercityregionprice
427VWSciroccoдекември199031Тъмно син мет.Бензинов112РъчнаКупе223445НеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеДаНеНеНеНеНеНеНеНе1 юли 20219:311юли202125Частно лицеРусеСеверен централен9100
118ToyotaCorollaфевруари200615Тъмно син мет.Дизелов116РъчнаВан172000НеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНе1 юли 202111:231юли202115АвтокъщаВарнаСевероизточен9250.36
346BMW535юни20147МеталикБензинов306АвтоматичнаСедан128500ДаНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНе1 юли 202110:061юли202111Частно лицеСофияЮгозападен78271.8
2NissanX-trailсептември200516СивДизелов136РъчнаДжип184000НеНеНеДаНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНе1 юли 202111:571юли2021124Частно лицеРусеСеверен централен11352.8
106SkodaSuperbюни20183БялДизелов190АвтоматичнаКомби167000ДаНеНеНеНеНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеДаНеНеНеДаНеНеНеНеНеНеНеНеНеНеНеНеНеНеНеНе1 юли 202111:271юли202189АвтокъщаВарнаСевероизточен28540.2

Извод

В този практически пример успяхме да изградим модел, който да прогнозира цени на превозни средства. Това обаче не означава, че те трябва да са напременно такива, каквито моделът е определил, тъй като той прави прогнози с известна грешка. Резултатите могат винаги да бъдат подобрени след допълнителни по-задълбочени анализи, експериментиране с различни параметри и прилагане на допълнителни обработки върху данните.

Цялостният пример можете да изтеглите от тук.

Ако искате да научите повече за метриките за оценка на регресионни модели, можете да прочетете в статията Machine Learning: Метрики за оценка на регресионни модели.

Искате да научите повече за машинното обучение?

Включете се в курса по машинно обучение и анализ на данни с Python.

© Copyright 2019 DeviseExpert Всички права запазени
envelopephone-handsetmap-marker linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram