Понятие функции ⚙️
Открой любой ноутбук с кодом на PyTorch или scikit-learn — и ты увидишь одно и то же слово буквально в каждой строчке: def, model.predict(x), loss_fn(y_true, y_pred), activation(z). Всё это — функции. Модель целиком, от входного слоя до выходного, — это одна большая функция, собранная из множества маленьких. Когда ты подаёшь на вход фотографию кота, а на выходе получаешь вероятность 0.94 — где-то внутри работает цепочка операций «вход → правило → выход», и именно эту цепочку математики называют функцией уже почти четыреста лет.
Давай разберёмся, что стоит за этим словом на самом деле — не на уровне «функция это когда y зависит от x», а строго: что делает соответствие функцией, а что нет, чем вход отличается от области, в которой он живёт, и какими способами вообще можно описать зависимость одной величины от другой. Это тот самый фундамент, без которого дальше — графики, производные, функции активации, feature engineering — превращается в зазубривание формул без понимания, что они означают.
Представь, что ты только начинаешь путь в data science и постоянно натыкаешься на фразы вроде «признак — это функция от сырых данных», «нейросеть — универсальный аппроксиматор функций», «функция потерь должна быть дифференцируемой». Все эти фразы опираются на одно и то же строгое определение, которое мы разберём в этом уроке. Как только оно уляжется в голове, вся остальная терминология ML перестанет казаться магией и станет частным случаем одной простой идеи.
План урока простой: сначала — откуда вообще взялось слово «функция» и зачем оно понадобилось математикам. Потом — что такое функция как правило соответствия, и почему не любая зависимость — это функция. Дальше — аргумент, значение, область определения и область значений на интуитивном уровне (подробный разбор — уже в следующем уроке). И в конце — четыре способа, которыми можно задать одну и ту же функцию: формулой, таблицей, графиком и словами. А завершим всё это тридцатью заданиями, где придётся не просто вычислять, но и рассуждать, что перед тобой — функция или нет.
История: откуда это взялось?
Слово «функция» ввёл в математику Готфрид Лейбниц в конце XVII века — тот самый Лейбниц, который вместе с Ньютоном придумал математический анализ. Слово он взял из латыни: «functio» значит «исполнение», «осуществление», «выполнение обязанности». Лейбницу нужно было как-то называть величины, которые «выполняют свою роль» относительно кривой — например, длину касательной или радиус кривизны в конкретной точке графика. Поначалу «функция» означала вовсе не то, что сейчас: не правило вычисления, а просто некоторую геометрическую характеристику кривой.
Понадобилось ещё сто с лишним лет, чтобы понятие дозрело до привычного нам вида. Иоганн Бернулли и особенно Леонард Эйлер в XVIII веке начали понимать функцию как аналитическое выражение — формулу, составленную из переменных и констант. Именно Эйлер ввёл обозначение $f(x)$, которым мы пользуемся до сих пор. А окончательный, по-настоящему общий взгляд на функцию — как на произвольное соответствие, а не обязательно формулу — сформулировал в XIX веке немецкий математик Петер Дирихле. Его определение и легло в основу того, что ты видишь в учебниках сегодня: функция — это не обязательно «красивая» запись со степенями и корнями, это вообще любое правило, которое каждому входу однозначно сопоставляет выход, пусть даже это правило описано словами или таблицей.
А теперь мостик к сегодняшнему дню. Когда программист пишет def celsius_to_fahrenheit(c): return c * 1.8 + 32, он делает ровно то же самое, что Эйлер записывал как $f(x) = 1.8x + 32$ — задаёт правило соответствия. Когда специалист по данным описывает признак log_price = np.log(price + 1), он определяет функцию от переменной price. А когда архитектор нейросети складывает слои друг на друга — nn.Sequential(Linear, ReLU, Linear, Softmax) — он строит композицию функций, то есть функцию, полученную последовательным применением нескольких более простых функций. Идея, придуманная для описания кривых на бумаге триста лет назад, оказалась ровно тем языком, на котором сегодня описывают устройство искусственного интеллекта.
Функция — это правило соответствия
Интуиция: чёрный ящик и автомат с газировкой
Представь автомат с газировкой. Ты кидаешь монету определённого номинала, нажимаешь на кнопку — и автомат выдаёт бутылку. Ключевое свойство исправного автомата: если ты дважды бросишь монету одного и того же номинала и нажмёшь одну и ту же кнопку, ты дважды получишь один и тот же напиток. Автомат не может в понедельник выдать колу, а во вторник — при точно тех же действиях — воду. Это было бы поломкой.
Функция устроена так же. Есть входы (их называют аргументами), есть выходы (значения), и есть правило, которое переводит вход в выход. Условие исправности этого «автомата» одно, но очень строгое: каждому допустимому входу соответствует ровно один выход. Не два, не ни одного — ровно один. Если это условие нарушается, перед тобой не функция, а просто какое-то соответствие — более общее и менее полезное понятие.
В мире данных та же логика: признак is_weekend(date) для каждой даты должен возвращать либо True, либо False — не «иногда True, иногда False» для одной и той же даты. Модель model.predict(x) для одного и того же входа x (при фиксированных весах, без случайности) обязана возвращать одно и то же предсказание. Именно детерминированность — «один вход, один выход» — и есть математическое содержание слова «функция».
Строгое определение
Определение: Функцией называется правило (соответствие) $f$, которое каждому элементу $x$ некоторого множества $X$ ставит в соответствие ровно один элемент $y$ из множества $Y$.
Записывается так: $f: X \to Y$ или $y = f(x)$.
Множество $X$ называется областью определения функции, обозначается $D(f)$. Множество всех значений, которые фактически принимает $y$, называется областью значений, обозначается $E(f)$.
Обозначения:
- $x$ — аргумент функции (независимая переменная, «вход»);
- $f(x)$ — значение функции в точке $x$ («выход»);
- $f$ — сама функция, то есть правило преобразования;
- $D(f)$ — область определения (что можно подавать на вход);
- $E(f)$ — область значений (что может получиться на выходе).
Обрати внимание на порядок слов в определении: каждому $x$ — ровно один $y$. Это два разных требования, и оба обязательны. «Каждому» означает, что правило должно работать для любого $x$ из области определения — не может быть исключений без явного сужения множества $X$. «Ровно один» означает отсутствие неоднозначности: недопустимо, чтобы одному входу соответствовали два разных выхода.
Примеры с подробным разбором
Пример 1 (простой): проверка соответствия «каждому человеку — год его рождения».
Разберём по шагам, является ли это функцией.
Шаг 1. Определим множество $X$ — это люди, множество $Y$ — годы.
Шаг 2. Проверим условие «каждому x — хотя бы один y»: да, у каждого человека есть год рождения, исключений нет.
Шаг 3. Проверим условие «ровно один y»: у человека не может быть двух разных лет рождения одновременно. Значение единственно.
Ответ: это функция. Обозначим её $f: \text{Человек} \to \text{Год}$.
А теперь обратное соответствие: «каждому году — человек, родившийся в этом году». В 2000 году родились миллионы разных людей, значит, одному входу (году) соответствует множество разных выходов. Условие «ровно один» нарушено — это не функция.
Пример 2 (средний): окружность $x^2 + y^2 = 25$ как соответствие между $x$ и $y$.
Шаг 1. Выразим $y$ через $x$: $y^2 = 25 - x^2$, значит $y = \pm\sqrt{25 - x^2}$.
Шаг 2. Возьмём конкретное значение, например $x = 3$. Подставим:
$$y^2 = 25 - 9 = 16 \implies y = 4 \text{ или } y = -4$$Шаг 3. Одному входу $x = 3$ соответствуют два разных выхода: $y = 4$ и $y = -4$. Условие «ровно один выход» нарушено.
Ответ: уравнение окружности не задаёт $y$ как функцию от $x$. Геометрически это легко проверить: если провести вертикальную прямую $x = 3$, она пересечёт окружность в двух точках. Такая проверка называется признаком вертикальной прямой — если вертикальная линия пересекает график больше чем в одной точке, перед тобой не график функции.
Пример 3 (сложный, ML-контекст): признак «нормализованная цена» как функция от сырых данных.
В датасете о недвижимости есть колонка price — цена квартиры в рублях. Инженер данных создаёт новый признак:
где $\mu$ — среднее значение цены по всему датасету, а $\sigma$ — стандартное отклонение (оба числа фиксированы и посчитаны один раз на обучающей выборке).
Шаг 1. Проверим: для каждой конкретной квартиры значение price — одно число. Значит, вход $x = \text{price}$ определён однозначно.
Шаг 2. Формула $\frac{x - \mu}{\sigma}$ при фиксированных $\mu$ и $\sigma$ для каждого $x$ выдаёт ровно одно число — простое арифметическое действие, никакой неоднозначности.
Шаг 3. Значит, соответствие «цена → нормализованная цена» — функция. Более того, эта функция — линейная (это будет понятнее после урока про линейную функцию), просто с зафиксированными коэффициентами $\frac{1}{\sigma}$ и $-\frac{\mu}{\sigma}$.
Ответ: нормализация — это функция $f(x) = \frac{x-\mu}{\sigma}$, и почти вся предобработка данных в ML устроена именно так: каждый признак после трансформации — это функция от исходного признака.
Важное уточнение: если бы нормализация делалась «на лету» — с пересчётом $\mu$ и $\sigma$ каждый раз по разным подвыборкам, то для одного и того же значения price результат мог бы отличаться в зависимости от того, какая подвыборка попалась. Формально это уже была бы не функция одной переменной price, а функция двух переменных — цены и статистики выборки. Отслеживание того, от чего именно зависит результат, — привычка, которая экономит часы отладки пайплайнов данных.
Почему это важно
Условие «один вход — один выход» — это не педантичная формальность, а инструмент диагностики. Когда модель в продакшене вдруг начинает выдавать разные предсказания на одинаковых данных, первая гипотеза опытного инженера: «где-то нарушилось свойство функции» — возможно, в код закралась случайность без фиксированного seed, или предсказание зависит от скрытого состояния (порядка вызовов, кеша, часового пояса сервера), о котором никто не подумал. Понимание функции как строгого соответствия — это не абстракция ради абстракции, а способ мыслить о коде и данных без сюрпризов.
Аргумент, значение, область определения и область значений
Интуиция: что можно скормить машине, и что она может выдать
Вернёмся к образу функции как машины. У любой реальной машины есть два ограничения: какие «детали» можно в неё загрузить (не всякая монета подходит автомату с газировкой — банкнота или иностранная монета застрянут), и что машина вообще способна произвести на выходе (автомат с газировкой не выдаст пиццу, как бы ты ни старался).
Первое ограничение — это область определения: множество всех $x$, для которых правило $f$ вообще имеет смысл и производит результат. Второе — область значений: множество всех $y$, которые реально могут получиться, если перебрать все допустимые $x$.
Представь, что ты пишешь функцию на Python, которая делит одно число на другое: def divide(a, b): return a / b. Область определения по переменной b — все числа, кроме нуля: подставишь ноль — получишь ZeroDivisionError, программа просто откажется работать. Это ровно то же самое, что происходит в математике: деление на ноль не определено, и точка $b=0$ выпадает из области определения.
Строгое определение
Определение: Областью определения функции $f$ называется множество всех значений аргумента $x$, при которых функция $f(x)$ имеет смысл (определена). Обозначается $D(f)$.
Областью значений функции $f$ называется множество всех значений $y$, которые функция принимает при $x$, пробегающем всю область определения. Обозначается $E(f)$.
$$E(f) = \{\, f(x) \mid x \in D(f) \,\}$$
На интуитивном уровне запомни три главные причины, по которым точка может «выпасть» из области определения:
-
деление на ноль — знаменатель дроби не должен обращаться в ноль;
-
извлечение квадратного (и вообще любого чётного) корня из отрицательного числа — в вещественных числах такого корня не существует;
-
логарифм от нуля или отрицательного числа — тоже не определён в вещественных числах.
Полный алгоритм нахождения области определения для сложных выражений — тема следующего урока. Здесь важно закрепить сам принцип: у функции есть законная «территория» входов, и выходить за неё нельзя.
Примеры с подробным разбором
Пример 1 (простой): $f(x) = 4x - 7$.
Шаг 1. Формула — обычное умножение и вычитание. Такие операции определены для любого действительного числа $x$: не важно, какое число подставить, ошибки не возникнет.
Шаг 2. Значит, $D(f) = \mathbb{R}$ — всё множество действительных чисел.
Шаг 3. Найдём область значений. При изменении $x$ от $-\infty$ до $+\infty$ выражение $4x - 7$ тоже пробегает все значения от $-\infty$ до $+\infty$ (линейная функция с ненулевым коэффициентом «растягивает» всю числовую прямую на всю числовую прямую).
Ответ: $D(f) = \mathbb{R}$, $E(f) = \mathbb{R}$.
Пример 2 (средний): $g(x) = \dfrac{1}{x - 4}$.
Шаг 1. Здесь есть деление, а значит, знаменатель не должен быть равен нулю:
$$x - 4 \neq 0 \implies x \neq 4$$Шаг 2. Значит, $D(g) = \mathbb{R} \setminus \{4\}$ — все действительные числа, кроме четвёрки.
Шаг 3. Найдём область значений. Дробь $\dfrac{1}{x-4}$ может быть сколь угодно большим положительным числом (если $x$ чуть больше 4) или сколь угодно большим по модулю отрицательным (если $x$ чуть меньше 4), но никогда не станет равна нулю — числитель всегда равен 1, а дробь обращается в ноль только если числитель равен нулю.
Ответ: $D(g) = \mathbb{R} \setminus \{4\}$, $E(g) = \mathbb{R} \setminus \{0\}$.
Пример 3 (сложный, ML-контекст): сигмоида $\sigma(x) = \dfrac{1}{1 + e^{-x}}$ как функция активации.
Шаг 1. Проверим область определения. Выражение $e^{-x}$ определено для абсолютно любого действительного $x$ — экспонента не имеет ограничений на аргумент. Прибавление единицы тоже ничего не ограничивает: $1 + e^{-x}$ всегда строго больше нуля (экспонента всегда положительна), значит, деления на ноль не возникает никогда.
Шаг 2. Значит, $D(\sigma) = \mathbb{R}$ — сигмоиду можно применить к любому числу: sigmoid(-1000000) и sigmoid(1000000) в коде отработают без ошибки.
Шаг 3. А вот с областью значений всё интереснее. Разберём предельные случаи:
$$x \to +\infty \implies e^{-x} \to 0 \implies \sigma(x) \to \frac{1}{1+0} = 1$$$$x \to -\infty \implies e^{-x} \to +\infty \implies \sigma(x) \to \frac{1}{1+\infty} \to 0$$Но обе эти границы — недостижимы: сигмоида приближается к 0 и к 1, но никогда не достигает их в точности, потому что $e^{-x}$ никогда не равен в точности нулю или бесконечности при конечном $x$.
Ответ: $D(\sigma) = \mathbb{R}$, $E(\sigma) = (0, 1)$ — открытый интервал.
Почему это критично на практике: именно поэтому сигмоиду используют как выходной слой в задачах бинарной классификации — она гарантированно «сжимает» любой сырой выход нейросети (logit) в диапазон вероятностей от 0 до 1, никогда не выдавая точный 0 или точную 1. И именно поэтому в функции потерь cross-entropy добавляют маленькое $\varepsilon$: код -log(p) при p, вычисленном как sigmoid, теоретически никогда не получит p = 0 ровно, но из-за ограниченной точности чисел с плавающей запятой (float32) на практике иногда получает — и тогда log(0) даёт -inf, ломая обучение.
Почему это важно
Область определения — это контракт функции: «я гарантированно работаю здесь и только здесь». Каждый раз, когда ты вызываешь чужую функцию (будь то np.sqrt, np.log или API стороннего сервиса), ты неявно полагаешься на то, что подаёшь вход из её области определения. Ошибки вроде ValueError: math domain error или NaN в тензорах PyTorch в девяти случаях из десяти — это именно нарушение области определения где-то в цепочке вычислений. Умение быстро прикинуть область определения «в уме» — это умение предвидеть баги до того, как они случились. Подробную технику её нахождения для сложных составных выражений разберём в следующем уроке.
Способы задания функции
Одну и ту же зависимость можно описать по-разному — и в математике, и в разработке ты постоянно переключаешься между этими способами. Разберём четыре основных.
Аналитический способ — формулой
Самый компактный способ: одна строчка, из которой можно вычислить $f(x)$ для любого $x$ из области определения. Именно так чаще всего задаются функции в коде: f = lambda x: x**2 + 3*x - 1.
Плюс: можно вычислить значение в любой точке, можно анализировать свойства (монотонность, экстремумы) методами анализа. Минус: не всегда удобно «увидеть» поведение функции сразу, особенно для сложных формул.
Табличный способ — набором пар значений
Функция задаётся списком конкретных пар «вход → выход». Так устроены, например, таблицы Брадиса, результаты экспериментов, а в ML — эмбеддинги: таблица embedding_table, где каждому индексу слова соответствует конкретный вектор чисел, — это в чистом виде табличное задание функции «слово → вектор».
Плюс: не нужна формула вообще, подходит для эмпирических данных. Минус: известны значения только в конечном числе точек — про то, что происходит «между» ними, без дополнительных предположений сказать ничего нельзя.
Графический способ — линией на координатной плоскости
Функция задаётся кривой на плоскости $Oxy$: каждая точка кривой — это пара $(x, f(x))$. Так работает любой дашборд: TensorBoard рисует loss как функцию от номера эпохи, не выписывая формулу — просто линия на графике.
Плюс: мгновенно видно поведение целиком — рост, падение, экстремумы, асимптоты. Минус: трудно снять точное числовое значение, трудно использовать график напрямую в вычислениях без оцифровки.
Признак, который мы уже использовали в примере с окружностью, — вертикальная прямая должна пересекать график функции не более чем в одной точке. Это графический эквивалент условия «один вход — один выход».
Словесный способ — описанием на естественном языке
Функция описывается правилами на обычном языке, без формулы и без таблицы: «комиссия банка составляет 1% от суммы перевода, но не менее 50 рублей». Это тоже полноценное задание функции — просто перед использованием его обычно приходится перевести в формулу.
Плюс: естественен для описания бизнес-правил и требований. Минус: может содержать неоднозначности («что считать «около 10 часов»?»), которые нужно устранить перед тем, как превращать описание в код.
Примеры с подробным разбором
Пример 1 (простой): от аналитического способа — к табличному.
Дана функция стоимости поездки на такси: $f(x) = 150 + 40x$, где $x$ — количество километров.
Шаг 1. Выберем несколько значений $x$ и вычислим $f(x)$ по формуле:
$$f(0) = 150 + 40 \cdot 0 = 150$$$$f(2) = 150 + 40 \cdot 2 = 230$$
$$f(5) = 150 + 40 \cdot 5 = 350$$
$$f(10) = 150 + 40 \cdot 10 = 550$$
Шаг 2. Соберём результаты в таблицу:
| x (км) | 0 | 2 | 5 | 10 |
|---|---|---|---|---|
| f(x) (руб.) | 150 | 230 | 350 | 550 |
Ответ: та же самая функция теперь представлена таблично. Обрати внимание: таблица — это «снимок» функции только в этих четырёх точках, формула же описывает её сразу во всех точках области определения.
Пример 2 (средний): от табличного способа — к аналитическому.
Дана таблица значений функции:
| x | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| f(x) | 5 | 8 | 11 | 14 | 17 |
Шаг 1. Проверим разницу между соседними значениями $f(x)$: $8-5=3$, $11-8=3$, $14-11=3$, $17-14=3$. Разница постоянна и равна 3 — это признак линейной зависимости вида $f(x) = 3x + b$.
Шаг 2. Найдём $b$, подставив известную пару, например $x=1$, $f(1)=5$:
$$3 \cdot 1 + b = 5 \implies b = 2$$Шаг 3. Получили гипотезу $f(x) = 3x + 2$. Проверим на оставшихся точках:
$$f(3) = 3 \cdot 3 + 2 = 11 \checkmark \qquad f(5) = 3 \cdot 5 + 2 = 17 \checkmark$$Ответ: $f(x) = 3x + 2$. Это классическая задача «восстановления паттерна» — именно так устроена простейшая линейная регрессия: у тебя есть таблица наблюдений, а модель ищет формулу, которая эту таблицу лучше всего объясняет.
Пример 3 (сложный, ML-контекст): от словесного описания — к аналитической (кусочной) функции.
Облачный сервис берёт плату за хранение данных по такому правилу: «первые 10 гигабайт — бесплатно; за каждый следующий гигабайт свыше 10, но не более 100 — по 5 рублей; за каждый гигабайт свыше 100 — по 3 рубля (оптовая скидка)». Нужно перевести это словесное описание в формулу $f(x)$, где $x$ — объём данных в гигабайтах, а $f(x)$ — стоимость в рублях.
Шаг 1. Выделим три «зоны» аргумента, о которых говорит описание: $x \le 10$, $10 < x \le 100$, $x > 100$.
Шаг 2. Для первой зоны стоимость нулевая по определению:
$$f(x) = 0, \quad 0 \le x \le 10$$Шаг 3. Для второй зоны платим по 5 рублей только за гигабайты сверх первых десяти бесплатных, то есть за $(x - 10)$ гигабайт:
$$f(x) = 5(x - 10), \quad 10 < x \le 100$$Шаг 4. Для третьей зоны первые 90 «платных» гигабайт (от 10 до 100) уже оплачены по старой ставке, посчитаем их стоимость отдельно: $5 \cdot (100 - 10) = 5 \cdot 90 = 450$ рублей. А всё, что свыше 100, — по 3 рубля за гигабайт:
$$f(x) = 450 + 3(x - 100), \quad x > 100$$Шаг 5. Соберём кусочную формулу:
$$f(x) = \begin{cases} 0, & 0 \le x \le 10 \\ 5(x-10), & 10 < x \le 100 \\ 450 + 3(x-100), & x > 100 \end{cases}$$Проверка: при $x=50$ (вторая зона): $f(50) = 5 \cdot 40 = 200$ рублей — логично, 40 «платных» гигабайт по 5 рублей. При $x=150$: $f(150) = 450 + 3 \cdot 50 = 600$ рублей.
Ответ: словесное правило превратилось в строгую кусочную функцию, которую теперь можно один в один перенести в код на Python как цепочку if / elif / else.
Почему это важно
Умение свободно переходить между четырьмя способами — это ровно тот навык, которым каждый день пользуется дата-сайентист. Продакт-менеджер описывает правило скидок словами в тикете; ты переводишь его в формулу (аналитический способ); проверяешь формулу на исторических данных, представленных таблицей; а потом рисуешь график зависимости, чтобы наглядно показать команде, как ведёт себя правило на разных значениях. Один и тот же объект — функция — путешествует между всеми четырьмя представлениями, и то, что математика гарантирует их эквивалентность (при аккуратном переводе), — это не случайность, а прямое следствие строгого определения функции, с которого мы начали урок.
Практика: 30 заданий
Базовые (задания 1-10)
Задание 1. Дана функция $f(x) = 5x - 2$. Найди $f(3)$, $f(0)$, $f(-2)$.
Задание 2. Является ли соответствие «каждому студенту — номер его студенческого билета» функцией? Обоснуй.
Задание 3. Является ли функцией соответствие «числу $x \ge 0$ — число $y$ такое, что $y^2 = x$»?
Задание 4. Функция задана таблицей:
| x | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| f(x) | 10 | 8 | 6 | 4 | 2 |
Найди $f(2) + f(4)$.
Задание 5. График функции $f(x)$ проходит через точку $(3, 7)$. Чему равно $f(3)$?
Задание 6. Функция задана словесно: «объём куба равен кубу длины его ребра». Запиши формулу и найди объём куба с ребром 4 см.
Задание 7. Является ли функцией зависимость «цена товара со скидкой 20%» от исходной цены $x$? Запиши формулу.
Задание 8. При каком значении $x$ функция $f(x) = \dfrac{1}{x - 4}$ не определена?
Задание 9. Функция активации ReLU задана как $f(x) = \max(0, x)$. Найди $f(-5)$, $f(0)$, $f(3.2)$.
Задание 10. Дана функция $g(x) = x^2$. Точки $(2, 4)$ и $(-2, 4)$ обе лежат на её графике. Является ли это нарушением определения функции? Объясни.
Средние (задания 11-20)
Задание 11. Дана функция $f(x) = 2x^2 - 3x + 1$. Найди $f(-1)$, $f(2)$, $f(1/2)$.
Задание 12. Известно, что график функции $f(x) = kx + b$ — прямая, проходящая через точки $(0, 3)$ и $(2, 7)$. Найди формулу функции и вычисли $f(5)$.
Задание 13. Проверь: являются ли функции $f(x) = \dfrac{x^2 - 1}{x - 1}$ и $g(x) = x + 1$ одной и той же функцией?
Задание 14. Функция потерь $L(w) = (w - 4)^2$ измеряет ошибку модели с параметром $w$. Вычисли $L(1)$, $L(4)$, $L(6)$ и сделай вывод, какое из трёх значений $w$ — лучшее.
Задание 15. Дана таблица зависимости точности модели от количества эпох обучения:
| эпох | 1 | 5 | 10 | 20 | 50 |
|---|---|---|---|---|---|
| accuracy | 0.62 | 0.78 | 0.85 | 0.90 | 0.90 |
Является ли эта зависимость функцией? Строго ли возрастает accuracy?
Задание 16. Найди область определения функции $f(x) = \sqrt{x + 7}$.
Задание 17. Курьерская служба платит 300 рублей за первый час работы и по 250 рублей за каждый следующий полный час. Запиши формулу зарплаты $W(n)$ за $n$ часов ($n \ge 1$, целое) и вычисли зарплату за 5 часов.
Задание 18. Выход нейрона вычисляется как $y = \sigma(2x - 1)$, где $\sigma$ — сигмоида. Является ли $y$ функцией от $x$? Обоснуй, опираясь на определение функции.
Задание 19. На графике вертикальная прямая $x = 2$ пересекает кривую в двух точках: $(2, 3)$ и $(2, -3)$. Является ли эта кривая графиком функции? Почему?
Задание 20. Функция задана рекуррентно: $f(1) = 2$, $f(n) = f(n-1) + 3$ для целых $n > 1$. Найди $f(5)$.
Продвинутые (задания 21-30)
Задание 21. Признак в датасете задан как $f(\text{price}) = \log(\text{price} + 1)$. Определён ли этот признак при price = -1? Укажи область определения по переменной price.
Задание 22. Даны формула $f(x) = x^2 - 4x + 3$ и таблица:
| x | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| f(x) | 3 | 0 | -1 | 0 | 3 |
Проверь, соответствует ли таблица формуле.
Задание 23. Модель регрессии: $\hat{y} = w_1 x_1 + w_2 x_2 + b$, где $w_1=2$, $w_2=-1$, $b=5$. Вычисли $\hat{y}$ для $(x_1, x_2) = (3, 4)$ и $(x_1, x_2) = (-2, 0)$. От скольких переменных зависит эта функция?
Задание 24. Оценка студента зависит от баллов $x \in [0; 100]$ по правилу: 90 и выше — «5», от 75 до 89 — «4», от 60 до 74 — «3», ниже 60 — «2». Найди оценку для $x=74$ и $x=75$.
Задание 25. Докажи, что зависимость $y^2 = x$ (при $x \ge 0$) не является функцией $y$ от $x$, но является функцией $x$ от $y$.
Задание 26. Логистическая регрессия: $p(x) = \dfrac{1}{1 + e^{-(2x-3)}}$. Вычисли $p(0)$, $p(1.5)$, $p(3)$ (используй $e \approx 2.718$). Проверь, что функция монотонно возрастает.
Задание 27. Функция потерь для одного примера: $L(\hat{y}) = (\hat{y} - 10)^2$. Заполни таблицу для предсказаний $\hat{y} = 6, 8, 10, 12, 14$ и найди, при каком $\hat{y}$ достигается минимум.
Задание 28. Кусочная функция: $f(x) = x^2$ при $x < 0$, и $f(x) = 2x$ при $x \ge 0$. Вычисли $f(-3)$, $f(0)$, $f(2)$. Проверь, что функция определена однозначно в каждой точке.
Задание 29. Нейросеть как композиция функций: $y = f_3(f_2(f_1(x)))$, где $f_1(x) = 3x$, $f_2(u) = u - 2$, $f_3(v) = v^2$. Вычисли $y$ при $x = 4$, выполняя вычисления послойно.
Задание 30. Отладка. Проверь, является ли функцией в математическом смысле следующий код, и объясни, как это исправить:
import random
def mystery(x):
return x + random.randint(0, 1)
Частые ошибки
❌ Ошибка 1: считать любую формулу с $y$ и $x$ функцией
Неправильно: «$x^2 + y^2 = 25$ — это функция, потому что там есть $y$ и $x$». Правильно: проверить признак вертикальной прямой или подставить конкретное $x$ и посмотреть, сколько получится значений $y$. У окружности при большинстве $x$ получается два значения $y$ — это не функция. Почему важно: путаница между «уравнением, связывающим две переменные» и «функцией» — источник ошибок на всех следующих темах, от графиков до производных.
❌ Ошибка 2: путать область определения с областью значений
Неправильно: для $f(x) = x^2$ сказать «область определения — $y \ge 0$». Правильно: $y \ge 0$ — это область значений ($E(f)$), а область определения ($D(f)$) здесь — все действительные числа, потому что в $x^2$ можно подставить любое $x$. Почему важно: одно множество описывает допустимые входы, другое — возможные выходы; это принципиально разные объекты, и в задачах на построение графиков и на исследование функций их регулярно путают.
❌ Ошибка 3: думать, что функция обязана задаваться одной формулой
Неправильно: «раз функция описана таблицей или словами, а не формулой — значит, это не настоящая функция». Правильно: определение Дирихле, на котором основана вся современная математика, требует только соответствия «один вход — один выход»; способ описания (формула, таблица, график, слова) значения не имеет. Почему важно: в реальных данных функции сплошь и рядом заданы таблично (эмбеддинги, справочники, экспериментальные измерения) — недооценка табличного и словесного способов задания мешает узнавать функцию там, где формулы нет.
❌ Ошибка 4: считать, что одинаковый выход при разных входах нарушает определение функции
Неправильно: «$f(2)=4$ и $f(-2)=4$ у функции $x^2$ — это противоречит определению функции». Правильно: запрет действует только в одну сторону — одному входу нельзя давать два выхода. Двум разным входам одинаковый выход давать можно и часто нужно (это как раз то, что отличает функцию от взаимно однозначного соответствия). Почему важно: эта путаница мешает понять, почему у функции $x^2$ существует обратная только на ограниченной области — тема следующих уроков про обратную функцию.
❌ Ошибка 5: забывать проверять область определения при переходе между способами задания
Неправильно: упростить $f(x) = \dfrac{x^2-1}{x-1}$ до $f(x) = x+1$ и считать это той же самой функцией на всей числовой прямой. Правильно: после сокращения нужно явно указать, что $x \neq 1$ остаётся исключённым из области определения, даже если после упрощения деление на ноль формально исчезло из записи. Почему важно: в коде такая ошибка выглядит как «тихий» баг — формула сокращается автоматически (например, символьными библиотеками), а точка разрыва теряется, и модель или расчёт получают неверный результат именно в этой точке.
❌ Ошибка 6: считать недетерминированный код функцией по умолчанию
Неправильно: «раз в Python есть слово def, значит, это математическая функция».
Правильно: проверить, зависит ли результат исключительно от переданных аргументов, — если внутри используется случайность без фиксации состояния, глобальные переменные или обращения к внешним изменяющимся ресурсам (время, сеть, файл), результат может отличаться при одинаковых аргументах, и это уже не функция в строгом смысле.
Почему важно: отладка «плавающих» багов в ML-пайплайнах почти всегда сводится к поиску места, где нарушилось это условие — где def перестал быть функцией.
Главное запомнить
✅ Функция — это правило, а не формула. Определение требует только одного: каждому входу — ровно один выход. Формула, таблица, график, слова — просто разные способы это правило записать.
✅ Обозначение $f: X \to Y$ или $y=f(x)$ — читается как «функция $f$ переводит элементы множества $X$ в элементы множества $Y$».
✅ «Один вход — один выход» — обязательное условие, но только в одну сторону. Разным входам можно и часто нужно давать одинаковый выход.
✅ Область определения $D(f)$ — все допустимые значения аргумента; область значений $E(f)$ — все значения, которые функция реально принимает. Это разные множества, их нельзя путать.
✅ Признак вертикальной прямой — быстрый графический способ проверить, является ли кривая графиком функции: вертикальная прямая должна пересекать её не более чем в одной точке.
✅ Четыре способа задания функции — аналитический (формула), табличный (список пар), графический (кривая), словесный (описание) — равноправны и переводятся друг в друга.
✅ Композиция функций — это тоже функция. Если каждое звено цепочки удовлетворяет определению, вся цепочка (например, слои нейросети) тоже ему удовлетворяет.
✅ Недетерминированный код — не функция в строгом смысле, пока случайность не зафиксирована явным параметром (seed).
✅ Кусочные функции корректны, если условия на разных участках не пересекаются и вместе покрывают всю область определения — тогда для любого входа подходит ровно одна из формул.
✅ Признаки, слои нейросети и функции потерь — всё это функции в строгом математическом смысле: у каждой есть своя область определения (что можно подать на вход) и область значений (что может получиться на выходе).
Связь с другими темами курса
Что было до этого урока: в курсе алгебры ты уже работал с буквенными выражениями, уравнениями и корнями — в частности, с извлечением корня из обеих частей уравнения. Всё это — операции над числами и переменными, из которых как раз и строятся формулы, задающие функции.
Что дальше: следующий урок — область определения и множество значений — берёт интуицию из этого занятия и превращает её в чёткий алгоритм для любых, сколь угодно сложных выражений с корнями, дробями и логарифмами. После этого — график функции, а затем разбор конкретных семейств: линейная, квадратичная, степенная функции, обратная функция, композиция функций, чётность и периодичность, монотонность и экстремумы. Всё это — частные случаи одного общего понятия, которое ты только что изучил.
Где это применяется в жизни и в ML:
-
💻 В программировании: каждая функция в коде (
def,lambda, метод класса) — это прямая реализация математического понятия функции, с теми же требованиями к однозначности результата. -
🤖 В машинном обучении: модель — это функция от признаков к предсказанию; функция потерь — функция от предсказаний и истинных ответов к одному числу; функция активации — функция, применяемая к выходу каждого нейрона. Обучение нейросети — это подбор параметров одной большой составной функции так, чтобы она как можно точнее приближала неизвестную зависимость в данных.
-
📊 В data science: feature engineering — это построение новых функций от сырых данных (нормализация, логарифмирование, кодирование категорий); понимание области определения объясняет, почему перед логарифмированием цену увеличивают на единицу, а перед делением проверяют знаменатель на ноль.
-
💰 В финансах и повседневной жизни: любое правило вида «сумма зависит от количества», «стоимость зависит от объёма», «оценка зависит от баллов» — это функция, и умение записать словесное правило формулой экономит массу времени при автоматизации расчётов.
Интересные факты
💡 Слово «функция» старше самого понятия. Лейбниц ввёл термин в конце XVII века для геометрических величин, связанных с кривой, а привычное нам определение «правило, которое каждому x сопоставляет одно y» появилось только через полтора века, у Дирихле. Получается, что слово и смысл, который мы сегодня в него вкладываем, формировались независимо и встретились не сразу.
💡 Функция необязательно связана с числами вообще. Формальное определение работает для любых множеств: можно построить функцию из множества фотографий в множество меток классов («кот», «собака»), из множества слов в множество векторов (эмбеддинги), из множества пользователей в множество рекомендованных товаров. Именно поэтому определение через соответствие, а не через формулу, оказалось таким долговечным — оно легко переносится за пределы арифметики.
💡 Лямбда-исчисление Алонзо Чёрча — фундамент всех языков программирования — построено целиком вокруг понятия функции. Ключевое слово lambda в Python — это прямая отсылка к работе логика Чёрча 1930-х годов, где функции были не просто инструментом вычислений, а основным «строительным материалом» математики. Функциональное программирование (Haskell, элементы Python и JavaScript) — это попытка писать код так, как если бы каждая часть программы была честной математической функцией без побочных эффектов.
💡 Теорема Цыбенко (1989) об универсальной аппроксимации утверждает, что нейросеть с одним скрытым слоем и достаточным числом нейронов может приблизить практически любую непрерывную функцию с любой точностью. Это одна из причин, почему нейросети называют «универсальными аппроксиматорами функций» — вся идея глубокого обучения строится на предположении, что за сложными данными скрывается некоторая функция, и задача обучения — подобрать параметры так, чтобы её приблизить.
Лайфхаки и полезные трюки
1. Всегда задавай себе один и тот же вопрос. Перед тем как назвать что-либо функцией, спроси: «Может ли для одного и того же входа получиться два разных выхода?» Если ответ «нет» — перед тобой функция, если «да» (или «не уверен») — присмотрись внимательнее.
2. Используй признак вертикальной прямой как быструю проверку на графике. Мысленно проведи несколько вертикальных линий через график — если хотя бы одна пересекает его больше одного раза, это не график функции.
3. Держи в голове три классические «дыры» в области определения. Деление на ноль, чётный корень из отрицательного числа, логарифм от неположительного числа — почти все ошибки области определения в школьной и вузовской алгебре сводятся к этим трём случаям.
4. При написании кода думай о своей функции как о математической. Спроси себя: зависит ли результат исключительно от входных параметров? Если внутри функции используются глобальные переменные, случайность без seed или обращения к внешним ресурсам — это тревожный звоночек, который аукнется трудноуловимыми багами.
5. Переводи словесные бизнес-правила в кусочные функции до того, как садишься писать код. Выпиши формулу на бумаге, отдельно определи границы каждого участка и проверь, что участки не пересекаются и вместе покрывают весь диапазон входов — это займёт пять минут и убережёт от классического бага «граничного случая» (off-by-one).
6. Проверяй восстановленную по таблице формулу минимум на двух точках, которые не использовал при выводе. Как в примере с линейной функцией — если формула верна, она обязана совпасть со всеми точками таблицы, а не только с теми двумя, по которым ты её вывел.
7. Когда встречаешь новую функцию активации или loss-функцию в статье, сразу выпиши её область определения и область значений. Это заранее подскажет, нужна ли защита от log(0), нормализация входа или клиппинг выхода — прежде чем баг проявится на реальном обучении.
Понимание функции как строгого правила соответствия — это не финальная точка, а стартовая площадка. Дальше в курсе ты научишься быстро находить область определения любых, даже самых закрученных выражений, строить и читать графики, узнавать функции по их характерным «портретам» — и увидишь, как одни и те же четыре способа задания снова и снова всплывают в реальной работе с данными. А теперь попробуй сам: возьми любую формулу, программу или бизнес-правило, которое встретишь сегодня, и проверь её на условие «один вход — один выход». Скорее всего, ты обнаружишь, что функции окружают тебя гораздо плотнее, чем казалось до этого урока.
Понял тему? Закрепи в боте! 🚀
Попрактикуйся на задачах и получи персональные рекомендации от AI
💪 Начать тренировку