Python: деректен өз есебіңізге дейін 44-сабақ (барлығы 56)
Бірінші модель: сызықтық регрессия
Python курсының қырық үшінші сабағы. Он алты жылдық баға арқылы жүргізілген түзу R² 0.927 береді әрі «өткен жылдағыдай» деген ережеден жүздік тармаққа ұтылады. Оның қатесі кездейсоқ емес, пішіні бар: плюс, минус, плюс. Логарифмдегі түзу екі есе аз қателеседі, өйткені баға көбейтіледі.
Не үшін керек
Өткен сабақтағы байланыс «бұл екі баған бірге қозғалды» дейді. Модель одан көбін айтады: қаншаға және мынадай мәнде не болады. Олардың біріншісі әрі ең адалы — түзу.
Оның бағасы — енді санмен атауға болатын қате. Сабақ модельді қалай үйрету керегі (екі жол) туралы емес, оның қателеріне қалай қарау керегі және әдемі R²-ға қалай алданбау керегі туралы.
Бірден тұтас
model.py файлы. Қатар нағыз: Қазақстанның 2010 жылдан бергі тұтыну бағасының индексі, Дүниежүзілік банк. Кітапхана жаңа — scikit-learn, pip install scikit-learn==1.9.1.
"""43-сабақ: бірінші модель — баға арқылы өтетін түзу.
Қатар нағыз: Қазақстанның тұтыну бағасының индексі, 2010 = 100, Дүниежүзілік
банктің FP.CPI.TOTL көрсеткіші. Кітапхана — scikit-learn.
"""
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, r2_score
CPI = pd.Series({
2010: 100.00, 2011: 108.45, 2012: 114.09, 2013: 120.87, 2014: 129.15,
2015: 137.77, 2016: 157.56, 2017: 169.28, 2018: 179.72, 2019: 189.30,
2020: 202.02, 2021: 218.27, 2022: 251.07, 2023: 287.54, 2024: 312.53,
2025: 348.12,
})
# sklearn белгілер кестесін күтеді: жол — бақылау, баған — белгі.
# Мұнда белгі біреу, жыл, сондықтан баған да біреу — бірақ баған, қатар емес.
X = CPI.index.to_numpy().reshape(-1, 1)
y = CPI.to_numpy()
print("== Он алты жыл арқылы өтетін түзу")
line = LinearRegression().fit(X, y)
print(" жылына индекс қосады:", round(float(line.coef_[0]), 2), "тармақ")
print(" R²:", round(r2_score(y, line.predict(X)), 3))
print(" орташа қате:", round(mean_absolute_error(y, line.predict(X)), 2), "тармақ")
print()
print("== Сәйкестік қана емес, қате де")
table = pd.DataFrame({"индекс": CPI, "түзу": line.predict(X).round(1)})
table["қате"] = (table["индекс"] - table["түзу"]).round(1)
print(table.to_string())
worst = table["қате"].abs().idxmax()
print(" ең нашар жыл:", worst, "— қателік", round(float(table.loc[worst, "қате"]), 1), "тармақ")
print()
print("== Қатенің пішіні бар")
signs = "".join("+" if e > 0 else "-" for e in table["қате"])
print(" жылдар бойынша қате таңбалары:", signs)
print(" қатар келген таңба топтары:", 1 + sum(1 for a, b in zip(signs, signs[1:]) if a != b))
print(" кездейсоқ қатеде олар шамамен", round(len(signs) / 2 + 1), "болар еді")
print()
print("== Логарифмдегі түзу")
log_line = LinearRegression().fit(X, np.log(y))
growth = float(np.exp(log_line.coef_[0]) - 1)
predicted = np.exp(log_line.predict(X))
print(" жылына баға көбейтіледі:", round(float(np.exp(log_line.coef_[0])), 4),
"— бұл жылына", round(growth * 100, 2), "%")
print(" орташа қате:", round(mean_absolute_error(y, predicted), 2), "тармақ")
print(" ең үлкен қателік:", round(float(np.max(np.abs(y - predicted))), 2), "тармақ")
print()
print("== Болжам және оның бағасы")
next_year = np.array([[2026]])
print(" түзу 2026 жылға уәде етеді:", round(float(line.predict(next_year)[0]), 1))
print(" логарифмдегі түзу:", round(float(np.exp(log_line.predict(next_year)[0])), 1))
print(" уәделер арасындағы айырма:",
round(float(np.exp(log_line.predict(next_year)[0]) - line.predict(next_year)[0]), 1), "тармақ")
Шығысы:
== Он алты жыл арқылы өтетін түзу
жылына индекс қосады: 15.45 тармақ
R²: 0.927
орташа қате: 17.17 тармақ
== Сәйкестік қана емес, қате де
индекс түзу қате
2010 100.00 73.2 26.8
2011 108.45 88.7 19.8
2012 114.09 104.1 10.0
2013 120.87 119.6 1.3
2014 129.15 135.0 -5.8
2015 137.77 150.5 -12.7
2016 157.56 165.9 -8.3
2017 169.28 181.4 -12.1
2018 179.72 196.8 -17.1
2019 189.30 212.3 -23.0
2020 202.02 227.7 -25.7
2021 218.27 243.2 -24.9
2022 251.07 258.6 -7.5
2023 287.54 274.1 13.4
2024 312.53 289.5 23.0
2025 348.12 305.0 43.1
ең нашар жыл: 2025 — қателік 43.1 тармақ
== Қатенің пішіні бар
жылдар бойынша қате таңбалары: ++++---------+++
қатар келген таңба топтары: 3
кездейсоқ қатеде олар шамамен 9 болар еді
== Логарифмдегі түзу
жылына баға көбейтіледі: 1.0849 — бұл жылына 8.49 %
орташа қате: 7.39 тармақ
ең үлкен қателік: 24.09 тармақ
== Болжам және оның бағасы
түзу 2026 жылға уәде етеді: 320.4
логарифмдегі түзу: 351.5
уәделер арасындағы айырма: 31.1 тармақ
Талдау
Модель — бұл екі жол
model = LinearRegression().fit(X, y)
model.predict(X)
fit түзуді іріктейді, predict одан сұрайды. Сабақтағы қалғанының бәрі — оның жарайтын-жарамайтынын қалай түсіну керегі туралы.
Деректің пішінінде бір нәзіктік бар: X белгілер кестесі болуға тиіс — бақылауға бір жол, белгіге бір баған, — сондықтан reshape(-1, 1). Мұндағы белгі біреу, жыл, бірақ баған бәрібір керек: sklearn сізде бір белгі ме, әлде жүз бе, соны болжамайды.
R² әдемі әрі дерлік ештеңе білдірмейді
R²: 0.927
орташа қате: 17.17 тармақ
R² — модель түсіндірген шашыраудың үлесі: 0.927 деген «модель 93 %-ға дұрыс» сияқты естіледі. Шын мәнінде оның қасында жүзден басталған индексте 17 тармақтық орташа қате тұр.
Себебі қарапайым: R² модельді орташа мәнді болжайтын базалық үлгімен салыстырады. R² = 0 сол базаға тең, ал теріс мән базадан нашар екенін білдіреді; бұл мүмкін болатын ең әлсіз модель емес. Өсіп келе жатқан кез келген қатарда оны ұту оңай. Сондықтан R² «модель жақсы ма» деген сұраққа жауап бола алмайды.
Қатенің пішіні бар
жылдар бойынша қате таңбалары: ++++---------+++
қатар келген таңба топтары: 3
кездейсоқ қатеде олар шамамен 9 болар еді
Бұл — пайдалы эвристика, бірақ түпкілікті диагноз емес. Қалдықтар тәуелсіз болса, олардың таңбалары жиірек алмасады; сериялардың күтілетін саны оң және теріс қалдықтардың санына тәуелді. Ресми қорытынды үшін сериялар тесті мен қалдықтар графигі керек, ал «нүктелердің шамамен жартысы» — таңбалар теңгерілгендегі жуық бағдар ғана. Мұнда топ үшеу: модель алдымен жүйелі түрде асыра болжайды, сосын сонша жыл кемітіп болжайды, сосын тағы асырады.
Бұл шу емес, модельдің жетіспейтін бөлігі осылай көрінеді. Түзу иіле алмайды, ал қатар иіледі.
Баға көбейтіледі — демек, түзу логарифмде керек
Отыз сегізінші сабақ: пайыздар қосылмайды, көбейтіледі. Жыл сайын шамамен бірдей санға көбейтілетін қатар — түзу емес, экспонента. Логарифм көбейтуді қосуға айналдырады, әрі логарифмде сол түзу дұрыс пішінге айналады:
жылына баға көбейтіледі: 1.0849 — бұл жылына 8.49 %
орташа қате: 7.39 тармақ
Қате екі еседен астам азайды, ал коэффициент оқылатын болды: жылына 8.49 % — бұл отыз сегізінші сабақтағы сол жылдық орташа мөлшерлеме, тек модельмен алынған.
Оның да қателесетінін байқаңыз: орташа 7.39 тармақ, ең нашар жылы 24. Ішінде 2022 жыл бар қатар бір тұрақты мөлшерлемемен сипатталмайды — әрі бұл екі модельдің де адал шегі, үшіншісін іздеуге себеп емес.
Болжам — бір сан емес, екі сан
түзу 2026 жылға уәде етеді: 320.4
логарифмдегі түзу: 351.5
Отыз бір тармақ айырма — бұл дерек емес, модель пішінін таңдау: қатар сол бір қатар. Осыдан кез келген формуладан бұрын түсінетін ереже шығады: модель мен оның қатесі аталмаған болжам — бұл пікір, әрі үтірден кейінгі цифр оған салмақ қоспайды.
Бұл есеп нені істей алмайды
Екі модель де өздері үйренген жылдарда өлшенді. Былай өлшеу тек қатенің пішінін көру үшін жарайды; «жаңа жылмен қалай справится» деген сұраққа мүлде жарамайды — модель жауаптарды әлдеқашан көрген. Қатарды адал бөлу — келесі сабақ.
Сабақ картасы
Өз сөзіңізбен айтыңыз
Қарамай, дауыстап немесе қағазға жауап беріңіз. Жауаптар — сабақтың соңында.
Xне үшін бір бағаннан тұратын кестеге айналдырылады?- R² 0.927 модельдің жақсы екенін неге білдірмейді?
- Қатедегі тоғыздың орнына үш топ нені білдіреді?
Жаттығу
Тапсырмаға дейінгі үш қысқа қадам: болжау, толықтыру, түзету. Жауаптар — сабақтың соңында, бірақ алдымен өзіңіз жауап беріңіз.
1. Болжаңыз. Нүктелер идеал түзуде жатса, бағдарлама не басып шығарады?
import numpy as np
from sklearn.linear_model import LinearRegression
x = np.array([[1], [2], [3], [4]])
y = np.array([3.0, 5.0, 7.0, 9.0])
model = LinearRegression().fit(x, y)
print("көлбеу:", round(float(model.coef_[0]), 3))
print("жылжу:", round(float(model.intercept_), 3))
print("10 үшін:", round(float(model.predict(np.array([[10]]))[0]), 3))
2. Бос орынды толтырыңыз. ... орнына жылдарды sklearn күтетін пішінге келтіріңіз.
# sklearn белгілер кестесін күтеді, қатарды емес
import numpy as np
from sklearn.linear_model import LinearRegression
years = np.array([2020, 2021, 2022, 2023])
index = np.array([100.0, 108.0, 117.0, 126.0])
X = ...
model = LinearRegression().fit(X, index)
print("жылына қосады:", round(float(model.coef_[0]), 2))
3. Түзетіңіз. Бағдарлама қатені орташа айырмамен өлшейді де, модельді мінсіз деп жариялайды.
# қателер таңбасымен қосылады, ал түзуде олар бірін-бірі жояды
import numpy as np
index = np.array([100.0, 108.0, 117.0, 126.0])
guess = np.array([99.0, 109.0, 118.0, 125.0])
print("орташа қате:", round(float((index - guess).mean()), 2))
Тапсырма
Міндетті. Баға индексі үшін жылдар бойынша түзу тұрғызып, жылдар бойынша индексті, болжамды және қатені басып шығарыңыз. Көлбеуді, R²-ты және қателік мөлшерімен бірге ең нашар жылды хабарлаңыз. Бөлек: қате таңбаларын және қатар келген таңба топтарының санын — кездейсоқ қатеде топ қанша болатынының қасында — санаңыз. Соңында бір жылдарда үш болжау тәсілін салыстырыңыз: түзу, логарифмдегі түзу және «өткен жылдағыдай» ережесі, — әрі ең жақсысын атаңыз.
Күтілетін шығыс:
== Жылдар бойынша түзу
индекс түзу қате
2010 100.00 73.2 26.8
2011 108.45 88.7 19.8
2012 114.09 104.1 10.0
2013 120.87 119.6 1.3
2014 129.15 135.0 -5.8
2015 137.77 150.5 -12.7
2016 157.56 165.9 -8.3
2017 169.28 181.4 -12.1
2018 179.72 196.8 -17.1
2019 189.30 212.3 -23.0
2020 202.02 227.7 -25.7
2021 218.27 243.2 -24.9
2022 251.07 258.6 -7.5
2023 287.54 274.1 13.4
2024 312.53 289.5 23.0
2025 348.12 305.0 43.1
жылына қосады: 15.45 тармақ
R²: 0.927
ең нашар жыл: 2025 — қателік 43.1 тармақ
== Қатенің пішіні
таңбалар: ++++---------+++
топтар: 3 — кездейсоқ қатеде 9
== Бір жылдарда салыстыру
түзу 16.53
логарифмдегі түзу 7.58
өткен жылдағыдай 16.54
салыстырудағы жыл: 15
ең жақсысы: логарифмдегі түзу
түзу «ештеңе істемеуді» ұтады: 0.01 тармаққа
Дайын болғаны: шығыс жол-жолымен сәйкес келеді; салыстыру әр модельде бар барлық жылда емес, бір жылдарда жүреді; қате модуль бойынша өлшенеді; ең жақсы тәсілді көз емес, код таңдайды.
Өз деректеріңізде. Уақыт бойынша кез келген өз қатарыңызды алыңыз — айлар бойынша шығыс, салмақ, километр, шоттар. Түзу тұрғызып, қате таңбаларына қарап, өзіңізге бір сұраққа жауап беріңіз: олар кезектесе ме, әлде жолақпен жүре ме? Жолақпен жүрсе, түзу — дұрыс пішін емес, логарифмді көріңіз.
Қалауыңыз бойынша.
- Түзуді тек 2010–2019 жылдарда үйретіп, оның 2022 жылға не уәде ететінін қараңыз. Бұл — келесі сабақтың репетициясы.
- Екінші белгі қосыңыз — мысалы, жылдың квадратын — әрі қатенің қалай азаятынын және таңбалар пішініне не болатынын қараңыз.
LinearRegressionменnumpy.polyfit(x, y, 1)нәтижесін салыстырыңыз: коэффициенттер сәйкес келуге тиіс, әрі бұл модель дәл сіз ойлағанды істеп тұрғанына көз жеткізудің жақсы тәсілі.
Жобада бұл қайда тұрады
Жиырма екінші қадам: жиынтықта бірінші модель пайда болады.
esep.trend әр елдің индексінің логарифмі бойынша түзу тұрғызып, екі сан басады: осы түзу білдіретін жылдық көбейткіш және индекс тармағымен ең үлкен қателік. Екіншісі біріншісінің қасында әдемілік үшін тұрған жоқ — қатесіз тренд бағасы аталмаған тұжырым, ал елдер әртүрлі сипатталады: Қазақстан жылына 1.12, қателігі 3.56; Өзбекстан 1.10, қателігі 1.02.
Болжамды жиынтық баспайды. Ол үшін бір жол керек, әрі оны жазбаудың себебі дәл сол: модель өзі көрмеген жылдарда тексерілгеннен кейін ғана болжамға лайық. Ондай тексеру жоқ кезде жиынтық өзіне берілген жылдар туралы айтады да, берілмегендері туралы үндемейді.
Жобаның requirements.txt файлына scikit-learn бекітілген нұсқасымен қосылды: кітапханасының нұсқасы жазылмаған модель — ешкім қайталай алмайтын модель.
Жауаптар
Жауаптарды көрсету
Сұрақтарға
- Өйткені sklearn «бақылаулар × белгілер» кестесін қабылдайды әрі он алты саннан тұратын қатармен нені меңзегеніңізді болжамайды: он алты бақылауы бар бір белгі ме, әлде бір бақылауы бар он алты белгі ме.
reshape(-1, 1)мұны анық айтады. - Өйткені R² модельді орташа деңгейдегі көлденең түзумен салыстырады, ақылға қонымды бірдеңемен емес. Өсіп келе жатқан қатарда оны кез келген нәрсе ұтады. Мұндағы R² 0.927-нің қасында 17 тармақтық орташа қате және «өткен жылдағыдай» ережесінен ұтылу тұр.
- Қатенің кездейсоқ емес екенін: модель бір бөлікте жүйелі асыра, екіншісінде кемітіп болжайды. Кездейсоқ қатеде таңба жиі ауысар еді — топ саны нүкте санының жартысындай болар еді. Үш топ модельдің пішіні дұрыс емес екенін білдіреді.
Жаттығуға
- Нүктелер
y = 2x + 1түзуінде жатыр, сондықтан көлбеуі дәл 2, жылжуы дәл 1, ал ондыққа модель 21 береді.
көлбеу: 2.0
жылжу: 1.0
10 үшін: 21.0
years.reshape(-1, 1). Минус бір — «бұл өлшем өзі есептеледі» дегені, ал бір — «бір баған».
# sklearn белгілер кестесін күтеді, қатарды емес: жол — бақылау, баған — белгі
import numpy as np
from sklearn.linear_model import LinearRegression
years = np.array([2020, 2021, 2022, 2023])
index = np.array([100.0, 108.0, 117.0, 126.0])
X = years.reshape(-1, 1)
model = LinearRegression().fit(X, index)
print("жылына қосады:", round(float(model.coef_[0]), 2))
жылына қосады: 8.7
- Қатені модуль бойынша алу керек. Түзуде орташа айырма құрылысы бойынша нөлге тең — ол «жақсы модель» емес, ол сапа өлшемі де емес.
# қатені модуль бойынша өлшейді: түзуде плюс пен минус бірін-бірі жояды
import numpy as np
index = np.array([100.0, 108.0, 117.0, 126.0])
guess = np.array([99.0, 109.0, 118.0, 125.0])
errors = index - guess
print("модуль бойынша орташа:", round(float(np.abs(errors).mean()), 2))
print("ал жай орташа:", round(float(errors.mean()), 2))
модуль бойынша орташа: 1.0
ал жай орташа: 0.0
Тапсырмаға
Тапсырманың басты саны — соңғысы. R² 0.927 түзу «өткен жылды қайтала» ережесін жүздік тармаққа ұтады, яғни мүлде ұтпайды. Әр модель үшін төлеуге тұрарлық баға осы: нөлмен емес, модельсіз істеуге болатын ең қарапайым нәрсемен салыстыру.
Логарифмдегі түзу шынымен ұтады — 16.5-ке қарсы 7.58, — әрі күрделірек болғандықтан емес, пішіні дұрыс болғандықтан. Деректің пішініне қарай іріктелген модель сан алу тілегіне қарай іріктелген модельді дерлік әрқашан басып озады.
Дереккөздер
- LinearRegression, scikit-learn — модельдің өзі, оның
coef_,intercept_жәнеpredict. - Регрессия метрикалары, scikit-learn —
r2_scoreпенmean_absolute_errorнені санайды. - Тұтыну бағасының индексі, Дүниежүзілік банк — сабақ тұрғызылған қатар.
Пікірлер (0)
Пікір қалдыру үшін кіріңіз →
Әзірге пікір жоқ. Бірінші болыңыз.