import numpy as np
# исходная функция, которую нужно аппроксимировать моделью a(x)
def func(x):
return 0.1 * x**2 - np.sin(x) + 5
# здесь объявляйте необходимые функции
coord_x = np.arange(-5.0, 5.0, 0.1) # значения по оси абсцисс [-5; 5] с шагом 0.1
coord_y = func(coord_x) # значения функции по оси ординат
sz = len(coord_x) # количество значений функций (точек)
eta = np.array([0.1, 0.01, 0.001, 0.0001]) # шаг обучения для каждого параметра w0, w1, w2, w3
w = np.array([0., 0., 0., 0.]) # начальные значения параметров модели
N = 200 # число итераций градиентного алгоритма
def features(x):
x = np.asarray(x)
return np.stack([np.ones_like(x), x, x**2, x**3], axis=1)
🔵 Функция np.asarray() в библиотеке NumPy — используется для преобразования входных данных в объект ndarray.🔵 ndarray (N-dimensional array) — класс многомерных массивов в библиотеке NumPy🔵 Входные данные могут быть в виде списков, кортежей или других объектов, похожих на массивы. Если входные данные уже являются массивом NumPy, функция не создаёт копию🔵 В нашем коде делает из входа (список/массив) numpy-вектор формы (n,).
А нужно это, чтобы дальше работали векторные операции x**2, x**3
np.ones_like(x) — делает массив единиц такой же формы и типа, как x. Это столбец для свободного члена w₀ — форма также (n, ) — т.е вектор из n единиц. В нашей функции признаков этот вектор из единиц идёт как первый столбецЧто такое формы (n,), (n,1), (n,4)
Я уже как-то разбирал данный момент, но вернуться стоит:
Please open Telegram to view this post
VIEW IN TELEGRAM
x = np.array([10., 20., 30.])
x.shape # (3, )
------------
[10. 20. 30.]
x_col = x.reshape(-1, 1)
x_col.shape # (3, 1)
------------
[[10.]
[20.]
[30.]]
S = np.column_stack([np.ones_like(x), x, x**2, x**3])
S.shape
-------------
[[ 1. 10. 100. 1000.]
[ 1. 20. 400. 8000.]
[ 1. 30. 900. 27000.]]
Please open Telegram to view this post
VIEW IN TELEGRAM
Что хотите дальше ❓
Anonymous Poll
36%
18%
9%
36%
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
CodeLab
👀 Всем ку, подписичники прибавились, а значит пора выложить пост. Я вдруг понял, что задачки с бинарной классификацией закончились, но поводов расстраиваться нет, ведь мы переходим к градиентному спуску.
Здесь, здесь, здесь и здесь мы уже рассмотрели эту…
Здесь, здесь, здесь и здесь мы уже рассмотрели эту…
Anonymous Quiz
0%
2.4
0%
3.4
80%
2.8
0%
3.2
0%
3.8
0%
3.6
20%
2.0
0%
1.8
def predict(w, x):
S = features(x)
return S @ w
S = features(x)
return S @ w
import numpy as np
def func(x): # Функция
return 0.1 * x ** 2 - np.sin(x) + 5
def features(x): # Матрица признков
x = np.asarray(x)
return np.stack([np.ones_like(x), x, x ** 2, x ** 3], axis = 1)
def predict(w, x): # a(x) = Sw
S = features(x)
return S @ w
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Love. Death. Transformers.
- так и че ты дум чат жпт нас всех убьет не
- аэээм бляяя юр тут как бы две стороны есть
- а программисты с ними че будет м
- нууу смотря какие тип там крутые или не оч там с опытом без
- а вот другие профессии чат жпт с ними что сделает а
- да тут яхззз на самом деле оно как то всегда само там разруливается
- оке я пон тя. в чем сила
- в любви
- аэээм бляяя юр тут как бы две стороны есть
- а программисты с ними че будет м
- нууу смотря какие тип там крутые или не оч там с опытом без
- а вот другие профессии чат жпт с ними что сделает а
- да тут яхззз на самом деле оно как то всегда само там разруливается
- оке я пон тя. в чем сила
- в любви
Друзья, сегодня пост, начинайте ждать ⌛️
Please open Telegram to view this post
VIEW IN TELEGRAM
def risk(w, x, y):
y_hat = predict(w, x) # считаем предсказания: S @ w
n = len(x) # количество точек (должно равняться len(y))
return (1.0 / n) * np.sum((y_hat - y) ** 2) # MSE
y_hat = predict(w, x)
x = [0, 1, 2]
ones_like = [1, 1, 1]
x**2 = [0, 1, 4]
x**3 = [0, 1, 8]
S = stack(ones, x, x**2, x**3, axis=1) =
[[1, 0, 0, 0],
[1, 1, 1, 1],
[1, 2, 4, 8]] # shape (3, 4) - форма массива
w = [1, 2, 0, 0] # shape (4,)
Предсказания равны:
y_hat = [1, 3, 5] # shape (3,)
func(0) = 0.1*0 - sin(0) + 5 = 5.00000
func(1) = 0.1*1 - sin(1) + 5 ≈ 0.1 - 0.84147 + 5 = 4.25853
func(2) = 0.1*4 - sin(2) + 5 ≈ 0.4 - 0.90930 + 5 = 4.49070
y ≈ [5.00000, 4.25853, 4.49070]
Ошибка e = y_hat - y ≈ [1-5, 3-4.25853, 5-4.49070] ≈ [-4.00000, -1.25853, 0.50930]
Квадраты: e**2 ≈ [16.00000, 1.5839, 0.2594]
Сумма: ≈ 16 + 1.5839 + 0.2594 = 17.8433
Среднее (делим на n=3): Q ≈ 17.8433 / 3 ≈ 5.9478
Please open Telegram to view this post
VIEW IN TELEGRAM
Друзья, занимался делами, теперь допишем пост для кода:
🧑💻 На данный момент наш код выглядит как-то так:
🟢 Давайте еще раз быстро пробежимся и закончим:
🔵 Функция? — Есть, за нее отвечает функция func()
🔵 Признаки мы тоже предусмотрели, за нее отвечает функция features(), входные признаки мы преобразовываем в numpy массив, и возвращаем матрицу признаков S (в матрице у нас столбец единиц — для bias, x, x², x³ ), короче говоря, features превращала каждый скаляр xᵢ в вектор признаков в вектор признаков.
🔵 Теперь нужна функция для прогноза — predict(). Функция вычисляет 🟰 a(x) = Sw 🟰 — по сути, умножение нашей матрицы S (переменной мы присваиваем значение матрицу) на вектор признаков w.
🔵 Теперь функция risk() — возвращает по-сути MSE — среднеквадратическая между предсказаниями и истинными значениями. Здесь подаем в функцию аж 3 аргумента — w (параметры модели, и это единственное, что мы меняем, risk() будет зависеть от w ⏺ x (входные данные по которым мы считаем признаки) и делаем предсказания y_hat — это вектор предсказаний (результат матричного умножения S @ w) ⏺ y — это истинные значения. Логика примерно такая: минимизируем функцию потерь по w, а x, y — это данные.
import numpy as np
def func(x):
return 0.1 * x ** 2 - np.sin(x) + 5
def features(x):
x = np.asarray(x)
return np.stack([np.ones_like(x), x, x ** 2, x ** 3], axis = 1)
def predict(w, x):
S = features(x)
return S @ w
def risk(w, x, y):
y_hat = predict(w, x)
n = len(x)
return (1.0 / n) * np.sum((y_hat - y) ** 2)
Please open Telegram to view this post
VIEW IN TELEGRAM
grad_risk() сам себя не разберет def grad_risk(w, x, y):
S = features(x)
err = S @ w - y
n = len(x)
return (2.0 / n) * (S.T @ err)
S = features(x)🟰; 🟰y_hat = S @ w🟰 return (2.0 / n) * (S.T @ err) np.linspace(-5, 5, 100, endpoint=False) y = 0.1*x^2 - sin(x) + 5 coord_x = np.arange(-5.0, 5.0, 0.1)
coord_y = func(coord_x)
sz = len(coord_x) # это просто 100
eta = np.array([0.1, 0.01, 0.001, 0.0001])
w = np.array([0., 0., 0., 0.])
N = 200
for _ in range(N):
g = grad_risk(w, coord_x, coord_y)
w = w - eta * g
Q = risk(w, coord_x, coord_y)
w = list(w)
Такие вот дела
Please open Telegram to view this post
VIEW IN TELEGRAM
🔵 Здесь два вида — вещественные (могут принимать любое значение в диапазоне) и целочисленные (принимают только целые значения). Численные признаки мы используем постоянно в задачах регрессии. Если приводить пример с визуализацией, гистограмма как раз про численные признаки, столбчатая диаграмма — для категориальных
🔵 При работе с такими данными, используют one-hot encoding (метод преобразования категориальных данных (городов, цветов, профессий) в числовой формат, понятный алгоритмам машинного обучения) — превращают в набор бинарных признаков
Пол: «мужской» / «женский»
Наличие подписки: «да» / «нет»
Результат теста: «успех» / «провал»
Включение функции: 1 / 0
🔵 Бинарные признаки можно обрабатывать как численные (например, усреднять — тогда получим долю "1"), так и как категориальные. Часто их оставляют как есть (0 и 1), особенно в моделях машинного обучения.
Курс студента: 1, 2, 3, 4, 5
Please open Telegram to view this post
VIEW IN TELEGRAM