You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/sr/2-Regression/3-Linear/README.md

34 KiB

Изградите регресиони модел користећи Scikit-learn: регресија на четири начина

Инфографика линеарне и полиномске регресије

Инфографика од Dasani Madipalli

Квиз пре предавања

Ова лекција је доступна на R!

Увод

До сада сте истраживали шта је регресија користећи пример података из скупа података о ценама бундева, који ћемо користити током ове лекције. Такође сте је визуализовали користећи Matplotlib.

Сада сте спремни да дубље уђете у регресију за машинско учење. Док визуализација омогућава разумевање података, права моћ машинског учења долази из тренирања модела. Модели се тренирају на историјским подацима како би аутоматски ухватили зависности података и омогућили предвиђање исхода за нове податке које модел раније није видео.

У овој лекцији, научићете више о две врсте регресије: основна линеарна регресија и полиномска регресија, заједно са неким математичким основама ових техника. Ови модели ће нам омогућити да предвидимо цене бундева у зависности од различитих улазних података.

Машинско учење за почетнике - Разумевање линеарне регресије

🎥 Кликните на слику изнад за кратак видео преглед линеарне регресије.

Кроз овај курикулум претпостављамо минимално знање математике и настојимо да га учинимо доступним студентима из других области, па обратите пажњу на белешке, 🧮 позиве, дијаграме и друге алате за учење који помажу у разумевању.

Предуслов

До сада би требало да сте упознати са структуром података о бундевама које испитујемо. Можете их пронаћи унапред учитане и очишћене у датотеци notebook.ipynb ове лекције. У датотеци, цена бундева је приказана по бушелу у новом оквиру података. Уверите се да можете покренути ове бележнице у језгрима у Visual Studio Code-у.

Припрема

Као подсетник, учитавате ове податке како бисте постављали питања о њима.

  • Када је најбоље време за куповину бундева?
  • Коју цену могу очекивати за кутију минијатурних бундева?
  • Да ли да их купим у корпама од пола бушела или у кутијама од 1 1/9 бушела? Хајде да наставимо са истраживањем ових података.

У претходној лекцији, креирали сте Pandas оквир података и попунили га делом оригиналног скупа података, стандардизујући цене по бушелу. Међутим, тиме сте успели да сакупите само око 400 података и то само за јесење месеце.

Погледајте податке које смо унапред учитали у пратећој бележници ове лекције. Подаци су унапред учитани, а почетни распршени графикон је направљен да покаже податке по месецима. Можда можемо добити мало више детаља о природи података ако их боље очистимо.

Линија линеарне регресије

Као што сте научили у Лекцији 1, циљ вежбе линеарне регресије је да се нацрта линија која:

  • Показује односе између променљивих. Показује однос између променљивих
  • Прави предвиђања. Прави тачна предвиђања о томе где би нова тачка података могла пасти у односу на ту линију.

Типично је за регресију методом најмањих квадрата да се нацрта ова врста линије. Термин 'најмањи квадрати' значи да су све тачке података око линије регресије квадриране и затим сабране. Идеално, тај коначни збир је што је могуће мањи, јер желимо низак број грешака, или најмањи квадрати.

То радимо јер желимо да моделирамо линију која има најмању кумулативну удаљеност од свих наших тачака података. Такође квадрирамо термине пре него што их саберемо јер нас занима њихова величина, а не њихов смер.

🧮 Покажите ми математику

Ова линија, названа линија најбољег уклапања, може се изразити једначином:

Y = a + bX

X је 'објашњавајућа променљива'. Y је 'зависна променљива'. Нагиб линије је b, а a је пресек са Y-осом, који се односи на вредност Y када је X = 0.

израчунајте нагиб

Прво, израчунајте нагиб b. Инфографика од Jen Looper

Другим речима, и позивајући се на оригинално питање о подацима о бундевама: "предвидите цену бундеве по бушелу по месецу", X би се односио на цену, а Y би се односио на месец продаје.

завршите једначину

Израчунајте вредност Y. Ако плаћате око $4, мора да је април! Инфографика од Jen Looper

Математика која израчунава линију мора показати нагиб линије, који такође зависи од пресека, или где се Y налази када је X = 0.

Можете посматрати метод израчунавања ових вредности на веб сајту Math is Fun. Такође посетите овој калкулатор најмањих квадрата да видите како вредности бројева утичу на линију.

Корелација

Још један термин који треба разумети је коефицијент корелације између датих X и Y променљивих. Користећи распршени графикон, можете брзо визуализовати овај коефицијент. Графикон са тачкама података распршеним у уредној линији има високу корелацију, али графикон са тачкама података распршеним свуда између X и Y има ниску корелацију.

Добар модел линеарне регресије биће онај који има висок (ближи 1 него 0) коефицијент корелације користећи метод регресије најмањих квадрата са линијом регресије.

Покрените бележницу која прати ову лекцију и погледајте распршени графикон Месец према Цени. Да ли се подаци који повезују Месец са Ценом за продају бундева чине да имају високу или ниску корелацију, према вашој визуелној интерпретацији распршеног графикона? Да ли се то мења ако користите прецизнију меру уместо Месец, нпр. дан у години (тј. број дана од почетка године)?

У коду испод, претпоставићемо да смо очистили податке и добили оквир података назван new_pumpkins, сличан следећем:

ID Месец ДанУГодини Врста Град Паковање Најнижа цена Највиша цена Цена
70 9 267 PIE TYPE BALTIMORE 1 1/9 бушел кутије 15.0 15.0 13.636364
71 9 267 PIE TYPE BALTIMORE 1 1/9 бушел кутије 18.0 18.0 16.363636
72 10 274 PIE TYPE BALTIMORE 1 1/9 бушел кутије 18.0 18.0 16.363636
73 10 274 PIE TYPE BALTIMORE 1 1/9 бушел кутије 17.0 17.0 15.454545
74 10 281 PIE TYPE BALTIMORE 1 1/9 бушел кутије 15.0 15.0 13.636364

Код за чишћење података доступан је у notebook.ipynb. Извршили смо исте кораке чишћења као у претходној лекцији и израчунали колону ДанУГодини користећи следећи израз:

day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)

Сада када имате разумевање математике иза линеарне регресије, хајде да креирамо регресиони модел да видимо да ли можемо предвидети који пакет бундева ће имати најбоље цене бундева. Неко ко купује бундеве за празничну фарму бундева можда жели ове информације како би оптимизовао своје куповине пакета бундева за фарму.

Тражење корелације

Машинско учење за почетнике - Тражење корелације: Кључ за линеарну регресију

🎥 Кликните на слику изнад за кратак видео преглед корелације.

Из претходне лекције вероватно сте видели да просечна цена за различите месеце изгледа овако:

Просечна цена по месецу

Ово сугерише да би требало да постоји нека корелација, и можемо покушати да обучимо модел линеарне регресије да предвиди однос између Месец и Цена, или између ДанУГодини и Цена. Ево распршеног графикона који показује овај други однос:

Распршени графикон Цена према Дан у години

Хајде да видимо да ли постоји корелација користећи функцију corr:

print(new_pumpkins['Month'].corr(new_pumpkins['Price']))
print(new_pumpkins['DayOfYear'].corr(new_pumpkins['Price']))

Изгледа да је корелација прилично мала, -0.15 за Месец и -0.17 за ДанУГодини, али можда постоји друга важна веза. Изгледа да постоје различити кластери цена који одговарају различитим врстама бундева. Да потврдимо ову хипотезу, хајде да нацртамо сваку категорију бундева користећи различиту боју. Прослеђивањем параметра ax функцији за цртање распршених графикона можемо нацртати све тачке на истом графикону:

ax=None
colors = ['red','blue','green','yellow']
for i,var in enumerate(new_pumpkins['Variety'].unique()):
    df = new_pumpkins[new_pumpkins['Variety']==var]
    ax = df.plot.scatter('DayOfYear','Price',ax=ax,c=colors[i],label=var)
Распршени графикон Цена према Дан у години

Наша истрага сугерише да врста има већи утицај на укупну цену него стварни датум продаје. То можемо видети помоћу стубног графикона:

new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar')
Стубни графикон цена према врсти

Фокусирајмо се за тренутак само на једну врсту бундева, 'pie type', и видимо какав ефекат датум има на цену:

pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
pie_pumpkins.plot.scatter('DayOfYear','Price') 
Распршени графикон Цена према Дан у години

Ако сада израчунате корелацију између Цена и ДанУГодини користећи функцију corr, добићемо нешто попут -0.27 - што значи да тренирање предиктивног модела има смисла.

Пре тренирања модела линеарне регресије, важно је осигурати да су наши подаци чисти. Линеарна регресија не функционише добро са недостајућим вредностима, па има смисла уклонити све празне ћелије:

pie_pumpkins.dropna(inplace=True)
pie_pumpkins.info()

Други приступ би био да се те празне вредности попуне просечним вредностима из одговарајуће колоне.

Једноставна линеарна регресија

Машинско учење за почетнике - Линеарна и полиномска регресија користећи Scikit-learn

🎥 Кликните на слику изнад за кратак видео преглед линеарне и полиномске регресије.

Да бисмо обучили наш модел линеарне регресије, користићемо библиотеку Scikit-learn.

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

Почињемо раздвајањем улазних вредности (карактеристика) и очекиваног излаза (ознаке) у одвојене numpy низове:

X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1)
y = pie_pumpkins['Price']

Напомена да смо морали да извршимо reshape на улазним подацима како би пакет за линеарну регресију правилно разумео. Линеарна регресија очекује 2D-низ као улаз, где сваки ред низа одговара вектору улазних карактеристика. У нашем случају, пошто имамо само један улаз - потребан нам је низ облика N×1, где је N величина скупа података.

Затим, потребно је да поделимо податке на тренирајући и тестирајући скуп података, како бисмо могли да валидирамо наш модел након тренирања:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

На крају, тренирање стварног модела линеарне регресије траје само два реда кода. Дефинишемо објекат LinearRegression и прилагођавамо га нашим подацима користећи метод fit:

lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)

Објекат LinearRegression након fit-овања садржи све коефицијенте регресије, који се могу приступити користећи својство .coef_. У нашем случају, постоји само један коефицијент, који би требало да буде око -0.017. То значи да цене изгледа падају мало током времена, али не превише, око 2 цента дневно. Такође можемо приступити тачки пресека регресије са Y-осом користећи lin_reg.intercept_ - она ће бити око 21 у нашем случају, што указује на цену на почетку године.

Да бисмо видели колико је наш модел тачан, можем Нашa грешка изгледа да се врти око 2 тачке, што је ~17%. Није баш добро. Још један показатељ квалитета модела је коефицијент детерминације, који можемо добити овако:

score = lin_reg.score(X_train,y_train)
print('Model determination: ', score)

Ако је вредност 0, то значи да модел не узима у обзир улазне податке и делује као најгори линеарни предиктор, што је једноставно просечна вредност резултата. Вредност 1 значи да можемо савршено предвидети све очекиване излазе. У нашем случају, коефицијент је око 0.06, што је прилично ниско.

Такође можемо приказати тест податке заједно са регресионом линијом да бисмо боље видели како регресија функционише у нашем случају:

plt.scatter(X_test,y_test)
plt.plot(X_test,pred)
Линеарна регресија

Полиномијална регресија

Још један тип линеарне регресије је полиномијална регресија. Иако понекад постоји линеарна веза између променљивих - што је већа запремина бундеве, то је већа цена - понекад те везе не могу бити приказане као раван или права линија.

Ево неколико примера података који би могли користити полиномијалну регресију.

Погледајте поново однос између датума и цене. Да ли овај распоред тачака изгледа као да би нужно требало да се анализира правом линијом? Зар цене не могу да варирају? У овом случају можете пробати полиномијалну регресију.

Полиноми су математички изрази који могу садржати једну или више променљивих и коефицијената.

Полиномијална регресија ствара закривљену линију да би боље одговарала нелинеарним подацима. У нашем случају, ако укључимо квадратну променљиву DayOfYear у улазне податке, требало би да можемо да прилагодимо наше податке параболичном кривом, која ће имати минимум у одређеном тренутку у години.

Scikit-learn укључује корисни pipeline API за комбиновање различитих корака обраде података. Pipeline је ланац процесора. У нашем случају, направићемо pipeline који прво додаје полиномијалне карактеристике нашем моделу, а затим тренира регресију:

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline

pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())

pipeline.fit(X_train,y_train)

Коришћење PolynomialFeatures(2) значи да ћемо укључити све полиноме другог степена из улазних података. У нашем случају то ће значити само DayOfYear2, али ако имамо две улазне променљиве X и Y, то ће додати X2, XY и Y2. Можемо користити и полиноме вишег степена ако желимо.

Pipeline се може користити на исти начин као оригинални објекат LinearRegression, тј. можемо fit pipeline, а затим користити predict за добијање резултата предвиђања. Ево графикона који приказује тест податке и криву апроксимације:

Полиномијална регресија

Коришћењем полиномијалне регресије можемо добити нешто нижи MSE и већи коефицијент детерминације, али не значајно. Морамо узети у обзир и друге карактеристике!

Можете видети да су минималне цене бундева примећене негде око Ноћи вештица. Како то можете објаснити?

🎃 Честитамо, управо сте направили модел који може помоћи у предвиђању цене бундева за питу. Вероватно можете поновити исти поступак за све типове бундева, али то би било заморно. Сада ћемо научити како да узмемо у обзир сорту бундева у нашем моделу!

Категоријалне карактеристике

У идеалном свету, желимо да будемо у могућности да предвиђамо цене за различите сорте бундева користећи исти модел. Међутим, колона Variety је нешто другачија од колона као што је Month, јер садржи ненумеричке вредности. Такве колоне се називају категоријалне.

ML за почетнике - Предвиђање категоријалних карактеристика са линеарном регресијом

🎥 Кликните на слику изнад за кратак видео преглед коришћења категоријалних карактеристика.

Овде можете видети како просечна цена зависи од сорте:

Просечна цена по сорти

Да бисмо узели сорту у обзир, прво је морамо претворити у нумерички облик, или кодирати. Постоји неколико начина на који то можемо урадити:

  • Једноставно нумеричко кодирање ће направити табелу различитих сорти, а затим заменити име сорте индексом у тој табели. Ово није најбоља идеја за линеарну регресију, јер линеарна регресија узима стварну нумеричку вредност индекса и додаје је резултату, множећи је неким коефицијентом. У нашем случају, однос између броја индекса и цене је очигледно нелинеаран, чак и ако се побринемо да индекси буду поређани на одређени начин.
  • One-hot кодирање ће заменити колону Variety са 4 различите колоне, једну за сваку сорту. Свака колона ће садржати 1 ако одговарајући ред припада датој сорти, и 0 у супротном. То значи да ће постојати четири коефицијента у линеарној регресији, један за сваку сорту бундева, одговоран за "почетну цену" (или боље речено "додатну цену") за ту конкретну сорту.

Код испод показује како можемо one-hot кодирати сорту:

pd.get_dummies(new_pumpkins['Variety'])
ID FAIRYTALE MINIATURE MIXED HEIRLOOM VARIETIES PIE TYPE
70 0 0 0 1
71 0 0 0 1
... ... ... ... ...
1738 0 1 0 0
1739 0 1 0 0
1740 0 1 0 0
1741 0 1 0 0
1742 0 1 0 0

Да бисмо тренирали линеарну регресију користећи one-hot кодиране сорте као улаз, само треба да правилно иницијализујемо X и y податке:

X = pd.get_dummies(new_pumpkins['Variety'])
y = new_pumpkins['Price']

Остатак кода је исти као што смо користили горе за тренирање линеарне регресије. Ако пробате, видећете да је средња квадратна грешка отприлике иста, али добијамо много већи коефицијент детерминације (~77%). Да бисмо добили још прецизнија предвиђања, можемо узети у обзир више категоријалних карактеристика, као и нумеричке карактеристике, као што су Month или DayOfYear. Да бисмо добили један велики низ карактеристика, можемо користити join:

X = pd.get_dummies(new_pumpkins['Variety']) \
        .join(new_pumpkins['Month']) \
        .join(pd.get_dummies(new_pumpkins['City'])) \
        .join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']

Овде узимамо у обзир и City и тип Package, што нам даје MSE 2.84 (10%) и детерминацију 0.94!

Све на једном месту

Да бисмо направили најбољи модел, можемо користити комбиноване (one-hot кодиране категоријалне + нумеричке) податке из горњег примера заједно са полиномијалном регресијом. Ево комплетног кода за вашу удобност:

# set up training data
X = pd.get_dummies(new_pumpkins['Variety']) \
        .join(new_pumpkins['Month']) \
        .join(pd.get_dummies(new_pumpkins['City'])) \
        .join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']

# make train-test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# setup and train the pipeline
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)

# predict results for test data
pred = pipeline.predict(X_test)

# calculate MSE and determination
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')

score = pipeline.score(X_train,y_train)
print('Model determination: ', score)

Ово би требало да нам да најбољи коефицијент детерминације од скоро 97% и MSE=2.23 (~8% грешке у предвиђању).

Модел MSE Детерминација
DayOfYear Линеарни 2.77 (17.2%) 0.07
DayOfYear Полиномијални 2.73 (17.0%) 0.08
Variety Линеарни 5.24 (19.7%) 0.77
Све карактеристике Линеарни 2.84 (10.5%) 0.94
Све карактеристике Полиномијални 2.23 (8.25%) 0.97

🏆 Браво! Направили сте четири модела регресије у једном часу и побољшали квалитет модела до 97%. У последњем делу о регресији, научићете о логистичкој регресији за одређивање категорија.


🚀Изазов

Тестирајте неколико различитих променљивих у овом нотебооку да видите како корелација одговара тачности модела.

Квиз након предавања

Преглед и самостално учење

У овом часу смо научили о линеарној регресији. Постоје и други важни типови регресије. Прочитајте о техникама Stepwise, Ridge, Lasso и Elasticnet. Добар курс за даље учење је Stanford Statistical Learning course.

Задатак

Направите модел


Одрицање од одговорности:
Овај документ је преведен коришћењем услуге за превођење помоћу вештачке интелигенције Co-op Translator. Иако тежимо тачности, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не сносимо одговорност за било каква неспоразумевања или погрешна тумачења која могу произаћи из коришћења овог превода.