model = LogisticRegression(max_iter = 1000)
👨💻 Вам нужно понимать одно: регуляризация штука интересная, нужна для 'защиты от переобучения модельки', и ,грубо говоря, она 'штрафует большие веса модели' — это все про L2, еще есть L1 (но обо всем потом)
model.fit(X_train_scaled, y_train)
y_pred = model.predict(X_test_scaled) #выдаст 0 или 1
print("Classification Report:\n", classification_report(y_test, y_pred))print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred))🧑💻 Вот такой получится вывод для двух функций сверху
precision recall f1-score support
0 0.98 0.95 0.96 43
1 0.97 0.99 0.98 71
accuracy 0.97 114
macro avg 0.97 0.97 0.97 114
weighted avg 0.97 0.97 0.97 114
sns.heatmap(confusion_matrix(y_test, y_pred), annot=True, fmt='d', cmap='Blues')
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.title("Confusion Matrix")
plt.show()
Please open Telegram to view this post
VIEW IN TELEGRAM
import numpy as np
x_test = [(5, -3), (-3, 8), (3, 6), (0,0), (5, 3), (-3, -1), (-3, 3)]
w = np.array([-33, 9, 13])
a_sign = lambda x, w: -1 if np.dot(x, w) < 0 else 1
x_test_new = np.array([[1, x1, x2] for x1, x2 in x_test])
predict = [a_sign(x, w) for x in x_test_new]
wᵀ * x ≥ 0
wᵀ * x < 0
Мы уже имеем метки по ТЗ:
x_test = [(5, -3), (-3, 8), (3, 6), (0, 0), (5, 3), (-3, -1), (-3, 3)]
predict=[−1, +1, +1, −1, +1, −1, −1]
Please open Telegram to view this post
VIEW IN TELEGRAM
1 5 5 4 2
Please open Telegram to view this post
VIEW IN TELEGRAM
CodeLab
Друзья, у админа сессия, так что пока держите мем 👨💻
Media is too big
VIEW IN TELEGRAM
Фотка задания в комментах
Отступ (или margin или γ или M) — все это, так или иначе, относится к отступу.
🔵 Показывает margin насколько уверенно модель классифицировала точку а также, с какой стороны от разделяющей прямой она находится.
Please open Telegram to view this post
VIEW IN TELEGRAM
import numpy as np
w = np.array([15/7, -9/7, -1]) # [w0, w1, w2]
x_test = np.array([
(1, -8, -4),
(1, -2, 2),
(1, 4, 8),
(1, 6, 3)
])
y_test = np.sign(x_test @ w.T)
🔵 w — вектор весов: w = [w₀, w₁, w₂]🔵 xᵢ — вектор признаков: xᵢ = [1, x₁, x₂]🔵 w * xᵢ — это то, насколько объект далеко от прямой
margin = x_test @ w.T * y_test #Все по формуле
import numpy as np
w = np.array([15/7, -9/7, -1])
x_test = np.array([
(1, -8, -4),
(1, -2, 2),
(1, 4, 8),
(1, 6, 3),
])
y_test = np.sign(x_test @ w.T)
margin = x_test @ w.T * y_test
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Скажу сразу, что получилось у меня:
import numpy as np
w = np.array([-16, -4, 9])
x_test = np.array([
[1, -5, 2],
[1, -4, 6],
[1, 3, 2],
[1, 3, -3],
[1, 5, 6],
[1, 9, 2]
])
y_test = np.array([1, 1, 1, -1, -1])
y_test = np.sign(x_test @ w.T)
#y_test = np.array([1, 1, -1, -1, 1]) — А такой ответ не подойдет
margin = x_test @ w * y_test #Скалярное произведение
print(margin)
‼️ Чем больше отступ, тем увереннее классификация.🔵 В нашем случае, в точках 3 и 5 наша модель опростоволосилась
‼️ Сама формула🟰 margin — Mᵢ = wᵀ * xᵢ🟰 — это просто скалярное произведение между весами (это наши параметры в начале кода) и x-объектами (это и есть наши 6 точек).🔵 y_test — целевые значения. Говорит нам о том, каким должен быть знак margin, если классификация верная.
‼️ Вот как работает главная формула нашего кода:
w = np.array([-16, -4, 9])
x_test[0] = [1, -5, 2]
M₁ = (-16) * 1 + (-4) * (-5) + 9 * 2 = -16 + 20 + 18 = 22
y₁ = 1
margin₁ = 22 * 1 = 22
import numpy as np
w = np.array([-16, -4, 9])
x_test = np.array([
[1, -5, 2],
[1, -4, 6],
[1, 3, 2],
[1, 3, -3],
[1, 5, 6],
[1, 9, 2]
])
y_test = np.array([1, 1, 1, -1, -1, -1])
# y_test = np.sign(x_test @ w.T)
# print(y_test)
margin = x_test @ w * y_test
🔗 Ссылка на курс 🔗
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
import numpy as np
x_test = np.array([(-5, 2), (-4, 6), (3, 2), (3, -3), (5, 5), (5, 2), (-1, 3)])
y_test = np.array([1, 1, 1, -1, -1, -1, -1])
w = np.array([-8/3, -2/3, 1])
X = np.column_stack((np.ones(len(x_test)), x_test))
[[ 1. -5. 2.]
[ 1. -4. 6.]
[ 1. 3. 2.]
...
margin = y_test * (X @ w)
Q = np.sum(margin < 0)
print(int(Q))
Q = 2
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
import numpy as np
import matplotlib.pyplot as plt
x_train = [
[10, 50], [20, 30], [25, 30], [20, 60], [15, 75],
[40, 40], [30, 45], [20, 45], [40, 30], [7, 36]
]
x_train = [x + [1] for x in x_train]
умножений и тд.
x_train = np.array(x_train)
y_train = np.array([-1, 1, 1, -1, -1, 1, 1, -1, 1, 1])
sumvec = np.sum([x * y for x, y in zip(x_train, y_train)], axis = 0)
Please open Telegram to view this post
VIEW IN TELEGRAM
sumvec = np.sum([x * y for x, y in zip(x_train, y_train)], axis=0)
xxt = np.sum([np.outer(x, x) for x in x_train], axis=0)
x = [10, 50, 1]
np.outer(x, x) =
[[100, 500, 10],
[500, 2500, 50],
[10, 50, 1]]
w = np.dot(sumvec, np.linalg.inv(xxt))
print("Вектор весов w:", w.round(3))
line_x = np.linspace(0, 45, 100)
line_y = -(w[0] * line_x + w[2]) / w[1]
x_pos = x_train[y_train == 1]
x_neg = x_train[y_train == -1]
Визуализацию продолжим позже (PART 3 SOON)
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
CodeLab
🧑💻Разбираем код
🌷🔤🔤🔤
‼️ Ситуация примерно та же: нужно посчитать количество неправильно классифицированных объектов. Помимо этого, докрутим для кода визуал.
1⃣ Библиотеки:
import numpy as np
import matplotlib.pyplot as plt
2⃣ Теперь наши данные:
x_train…
🌷🔤🔤🔤
‼️ Ситуация примерно та же: нужно посчитать количество неправильно классифицированных объектов. Помимо этого, докрутим для кода визуал.
1⃣ Библиотеки:
import numpy as np
import matplotlib.pyplot as plt
2⃣ Теперь наши данные:
x_train…
x_pos = x_train[y_train == 1] # класс 1
x_neg = x_train[y_train == -1] # класс -1
plt.figure(figsize=(9, 7))
plt.scatter(x_pos[:, 0], x_pos[:, 1], color='blue', label='Класс +1', s=100, edgecolors='k')
plt.scatter(x_neg[:, 0], x_neg[:, 1], color='red', label='Класс -1', s=100, edgecolors='k')
for i, (x, y) in enumerate(zip(x_train, y_train)):
plt.text(x[0] + 0.5, x[1] + 0.5, f'{i+1}', fontsize=10)
x_train = [[10, 20], [15, 25], [30, 40]]
y_train = [+1, -1, +1]
zip(x_train, y_train) →
→ ([10, 20], +1), ([15, 25], -1), ([30, 40], +1)
plt.xlabel('$x_1$') # Подпись оси X как x1
plt.ylabel('$x_2$') # Аналогично но с Y и x2
plt.title('Классификация с разделяющей прямой')
plt.legend()
plt.grid(True) # Сетка
plt.xlim(0, 45) # Диапазон оси X (от 0 до 45)
plt.ylim(20, 80) # Аналогично но с Y
plt.show()Please open Telegram to view this post
VIEW IN TELEGRAM
import numpy as np
import matplotlib.pyplot as plt
#обучающие данные (10 точек, по 2 признака)
x_train = [
[10, 50], [20, 30], [25, 30], [20, 60], [15, 75],
[40, 40], [30, 45], [20, 45], [40, 30], [7, 36]
]
#точки только с 2 признаками [x1, #x2]
#учитываем свободный член: #свободный член w₀ в модели
x_train = [x + [1] for x in x_train] # теперь каждая точка вида [x1, x2, 1]
x_train = np.array(x_train) # (10, 3)
# Метки классов: -1 или +1
y_train = np.array([-1, 1, 1, -1, -1, 1, 1, -1, 1, 1])
#Считаем вектор pt = Σ (x_i * y_i)
# ДО: нет признака y
# ПОСЛЕ: каждый x умножается на соответствующее y, потом суммируются
sumvec = np.sum([x * y for x, y in zip(x_train, y_train)], axis=0)
# считаем xxt = Σ (x_i * x_i^T)
# сумма матриц Грама: x^T * x для каждой точки
xxt = np.sum([np.outer(x, x) for x in x_train], axis=0)
# w = pt · (X^T X)^(-1)
w = np.dot(sumvec, np.linalg.inv(xxt))
print("Вектор весов w:", w.round(3)) # округлим для удобства
# разделяющая прямая: w0 * x + w1 * y + w2 = 0
# Выразим y: y = -(w0 * x + w2) / w1
line_x = np.linspace(0, 45, 100)
line_y = -(w[0] * line_x + w[2]) / w[1]
# разделение точек по классам
x_pos = x_train[y_train == 1] # класс 1
x_neg = x_train[y_train == -1] # класс -1
# Визуал
plt.figure(figsize=(9, 7))
# Отрисовка точек классов
plt.scatter(x_pos[:, 0], x_pos[:, 1], color='blue', label='Класс +1', s=100, edgecolors='k')
plt.scatter(x_neg[:, 0], x_neg[:, 1], color='red', label='Класс -1', s=100, edgecolors='k')
# Подпишем точки
for i, (x, y) in enumerate(zip(x_train, y_train)):
plt.text(x[0] + 0.5, x[1] + 0.5, f'{i+1}', fontsize=10)
# Отрисовка разделяющей прямой
plt.plot(line_x, line_y, 'g--', label='Разделяющая граница')
plt.xlabel('$x_1$')
plt.ylabel('$x_2$')
plt.title('Классификация с разделяющей прямой')
plt.legend()
plt.grid(True)
plt.xlim(0, 45)
plt.ylim(20, 80)
plt.show()
Please open Telegram to view this post
VIEW IN TELEGRAM
coord_x = np.arange(-5.0, 5.0, 0.1)
0.1 * x**2 - np.sin(x) + 0.1 * np.cos(x * 5) + 1 # Это не сам код, скорее блок для понимания
‼️ Вместе эти два значения будут являться графиком функции f(x), график будет показывать как ведет себя функция в диапазоне от -5 до 5. Именно по этим данным будут считаться ошибки и средний эмпирический риск Q‼️
a(x, w) = w₀ + w₁ * x + w₂ * x² + w₃ * x³ + w₄ * x⁴
w = [1.11, -0.26, 0.061, 0.0226, 0.00178]
L_i(w, x_i) = (a(x_i, w) - f(x_i))² # Если что, это все есть в комментах в условии задачи
Q(a, X) = (1/n) * ∑[i=1 to n] L_i(w, x_i)
import numpy as np
def func(x):
return 0.1 * x**2 - np.sin(x) + 0.1 * np.cos(x * 5) + 1.
coord_x = np.arange(-5.0, 5.0, 0.1) #Значения X
coord_y = func(coord_x) # Ральные значения
sz = len(coord_x) # общее число отсчетов
w = [1.11, -0.26, 0.061, 0.0226, 0.00178] #Параметры модельки
model_y = (
w[0] +
w[1] * coord_x +
w[2] * coord_x**2 +
w[3] * coord_x**3 +
w[4] * coord_x**4
)
losses = (model_y - coord_y)**2 # Сравниваем нашу модель с 'идеальными значениями'
Q = np.mean(losses)
Please open Telegram to view this post
VIEW IN TELEGRAM