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/bg/2-Regression/3-Linear
localizeflow[bot] d2fe79afcf
chore(i18n): sync translations with latest source changes (chunk 1/1, 21 changes)
3 months ago
..
solution chore(i18n): sync translations with latest source changes (chunk 1/1, 300 changes) 4 months ago
README.md chore(i18n): sync translations with latest source changes (chunk 1/1, 21 changes) 3 months ago
assignment.md chore(i18n): sync translations with latest source changes (chunk 1/1, 300 changes) 4 months ago
notebook.ipynb 🌐 Update translations via Co-op Translator 9 months ago

README.md

Създаване на регресионен модел с помощта на Scikit-learn: регресия по четири начина

Забележка за начинаещи

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

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

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

Предварителен тест преди лекцията

Този урок е наличен и на R!

Въведение

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

Сега сте готови да навлезете по-дълбоко в регресията за машинното обучение. Докато визуализацията ви помага да разберете данните, истинската сила на машинното обучение идва от обучението на модели. Моделите се обучават на исторически данни, за да улавят автоматично зависимости в данните, и ви позволяват да предскажете резултати за нови данни, които моделът не е виждал преди.

В този урок ще научите повече за два вида регресия: базова линейна регресия и полиномиална регресия, заедно с част от математиката зад тези техники. Тези модели ще ни позволят да предскажем цените на тиквите в зависимост от различни входни данни.

Машинно обучение за начинаещи - Разбиране на линейната регресия

🎥 Натиснете върху изображението по-горе за кратко видео с обзор на линейната регресия.

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

Предварителни изисквания

Вече трябва да сте запознати със структурата на тиквените данни, които разглеждаме. Можете да ги намерите предварително заредени и почистени във файла notebook.ipynb към този урок. Във файла цената на тиквата е показана за бушел в нов DataFrame. Уверете се, че можете да стартирате тези ноутбуци в среди като Visual Studio Code.

Подготовка

Като напомняне, вие зареждате тези данни, за да можете да им задавате въпроси.

  • Кога е най-доброто време да купувам тикви?
  • Каква цена мога да очаквам за кашон с миниатюрни тикви?
  • Трябва ли да ги купувам в кошници от половин бушел или в кутия от 1 1/9 бушел?

Нека продължим да изследваме тези данни.

В предишния урок създадохте Pandas DataFrame и го напълнихте с част от оригиналния набор от данни, стандартизирайки цените по бушел. По този начин обаче събрахте около 400 точки данни и само за есенните месеци.

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

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

Както научихте в Урок 1, целта на упражнението по линейна регресия е да може да начертаете линия, която да:

  • Показва връзката между променливите. Показва връзката между променливите
  • Прави прогнози. Прави точни прогнози къде би попаднала нова точка в отношение към тази линия.

Типично за регресия с минимални квадрати е да се начертае такава линия. Терминът "Минимални квадрати" се отнася до процеса на минимизиране на общата грешка в нашия модел. За всяка точка измерваме вертикалното разстояние (наречено остатък) между реалната точка и нашата регресионна линия.

Тези разстояния се повдигат на квадрат по две основни причини:

  1. Магнитуда пред посока: Искаме да третираме грешката -5 по същия начин както грешката +5. Квадратирането прави всички стойности положителни.

  2. Налагане на наказание за отклонения: Квадратирането дава по-голяма тежест на по-големите грешки, карайки линията да стои по-близо до далечните точки.

След това събираме всички тези квадратирани стойности. Целта ни е да намерим конкретната линия, при която тази окончателна сума е най-малка (най-ниската възможна стойност) — откъдето идва името "Минимални квадрати".

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

Тази линия, наречена линия на най-добро напасване, може да бъде изразена чрез уравнение:

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) коефициент на корелация, използвайки метода на минимални квадрати с регресионна линия.

Стартирайте ноутбука към този урок и разгледайте разсейващата диаграма за връзката Месец - Цена. Изглежда ли, че данните свързващи Месец с Цена за продажбата на тикви имат висока или ниска корелация според вашата визуална интерпретация на диаграмата? Променя ли се това, ако използвате по-фина мярка вместо Month, напр. ден от годината (т.е. брой дни от началото на годината)?

В кода по-долу приемаме, че сме почистили данните и имаме DataFrame на име new_pumpkins, подобен на следния:

ID Month DayOfYear Variety City Package Low Price High Price Price
70 9 267 PIE TYPE BALTIMORE 1 1/9 bushel cartons 15.0 15.0 13.636364
71 9 267 PIE TYPE BALTIMORE 1 1/9 bushel cartons 18.0 18.0 16.363636
72 10 274 PIE TYPE BALTIMORE 1 1/9 bushel cartons 18.0 18.0 16.363636
73 10 274 PIE TYPE BALTIMORE 1 1/9 bushel cartons 17.0 17.0 15.454545
74 10 281 PIE TYPE BALTIMORE 1 1/9 bushel cartons 15.0 15.0 13.636364

Кодът за почистване на данните е наличен в notebook.ipynb. Извършихме същите стъпки за почистване като в предишния урок и изчислихме колоната DayOfYear със следното изразяване:

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

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

Търсене на корелация

Машинно обучение за начинаещи - Търсене на корелация: ключът към линейната регресия

🎥 Натиснете върху изображението по-горе за кратко видео с обзор на корелацията.

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

Средна цена по месеци

Това предполага, че трябва да има някаква корелация и можем да се опитаме да обучим модел за линейна регресия, за да предскажем връзката между Month и Price или между DayOfYear и Price. Ето графика на разсейване, показваща последната връзка:

Графика на разсейване на Цена спрямо Ден от годината

Нека проверим дали има корелация с функцията corr:

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

Изглежда, че корелацията е доста малка, -0.15 през Month и -0.17 през DayOfMonth, но може да има друга важна връзка. Изглежда, че има различни клъстъри с цени, отговарящи на различни видове тикви. За да потвърдим тази хипотеза, нека начертаем всяка категория тикви с различен цвят. Като подаваме параметър ax на функцията scatter, можем да начертаем всички точки на една и съща графика:

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') 
Графика на разсейване на Цена спрямо Ден от годината

Ако сега изчислим корелацията между Price и DayOfYear с функцията 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 в нашия случай, което индикира цената в началото на годината.

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

pred = lin_reg.predict(X_test)

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

Нашата грешка изглежда е около 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, защото съдържа нечислови стойности. Такива колони се наричат категориални.

Машинно обучение за начинаещи - Предсказване с категориални характеристики с линейна регресия

🎥 Кликнете върху изображението по-горе за кратко видео с обзор на използването на категориални характеристики.

Тук можете да видите как средната цена зависи от вида:

Средна цена по вид

За да вземем предвид вида, първо трябва да го преобразуваме в числова форма, или да го кодираме. Има няколко начина, по които можем да го направим:

  • Простото числово кодиране ще построи таблица с различните видове и след това ще замени името на вида с индекс в тази таблица. Това не е най-добрата идея за линейна регресия, защото линейната регресия взима действителната числова стойност на индекса и я добавя към резултата, умножавайки със съответния коефициент. В нашия случай връзката между числото на индекса и цената е ясно нелинейна, дори ако осигурим индексирането да е в някакъв определен ред.
  • One-hot encoding ще замести колоната 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']

Останалата част от кода е същата като използваната по-горе за обучение на Linear Regression. Ако го изпробвате, ще видите, че средно квадратичната грешка е приблизително същата, но получаваме много по-висок коефициент на детерминация (~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 кодирани категориални + числови) данни от горния пример заедно с полиномиална регресия. Ето пълния код за ваше удобство:

# настройте тренировъчните данни
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']

# направете разделяне на тренировъчни и тестови данни
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# настройте и обучете тръбопровода
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)

# предскажете резултатите за тестовите данни
pred = pipeline.predict(X_test)

# изчислете средната квадратична грешка и коефициента на детерминация
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

Задача

Създайте модел


Отказ от отговорност:
Този документ е преведен с помощта на AI услуга за превод Co-op Translator. Въпреки че се стремим към точност, имайте предвид, че автоматичните преводи могат да съдържат грешки или неточности. Оригиналният документ на неговия език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Не носим отговорност за каквито и да е недоразумения или погрешни тълкувания, произтичащи от използването на този превод.