<jupyter_start><jupyter_text>Урок 2  Линейное пространство. Основные понятия. Часть 2  Евклидово пространство __Определение__Линейное пространство над полем вещественных чисел называется _евклидовым пространством_, если на нем введено правило, согласно которому каждой упорядоченной паре векторов $x$ и $y$ поставлено в соответствие вещественное число, называемое _скалярным произведением_ и обозначаемое символом $(x, y)$.При этом указанное правило должно подчиняться четырем аксиомам:1) $(x,y)=(y,x);$2) $(\lambda x, y)=\lambda(x, y);$3) $(x_{1}+x_{2},y)=(x_{1},y)+(x_{2},y);$4) $(x, x)\geq0$, причем $(x,x)=0\Leftrightarrow x=0.$ __Пример__Из школьной программы известно, что в стандартном понимании в трехмерном пространстве скалярное произведение двух векторов определяется как произведение длин этих векторов на косинус угла между ними (см. рис.):$$(x, y) = \left|x\right|\cdot\left|y\right|\cdot cos\alpha.$$<jupyter_code># запустите последовательно код в ячейках, чтобы отобразить иллюстрации
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(1,1,1)

ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')

ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')

plt.axis('scaled')
plt.xlim(-2, 2)
plt.ylim(-2, 2)

ax.arrow(0, 0, 0.6, 2, head_width=0.15, head_length=0.2, length_includes_head=True, facecolor='black')
ax.arrow(0, 0, 2, 0.4, head_width=0.15, head_length=0.2, length_includes_head=True, facecolor='black')
ax.annotate("y", xy=(1.8, 0.6))
ax.annotate("x", xy=(0.7, 1.8))
ax.annotate("\u03B1", xy=(0.2, 0.2))

plt.show()<jupyter_output><empty_output><jupyter_text>Данное правило удовлетворяет введенным ранее аксиомам скалярного произведения. Таким образом, приведенное в примере пространство всех свободных векторов с так определенным скалярным произведением является евклидовым пространством. __Пример__Примером евклидова пространства будет выступать $n$-мерное линейное пространство $\mathbb{R}^{n}$ упорядоченных совокупностей $n$ вещественных чисел, скалярное произведение векторов $x=(a_{1},a_{2},...,a_{n})$ и $y=(b_{1},b_{2},...,b_{n})$ на котором определено как$$(x,y)=a_{1}b_{1}+a_{2}b_{2}+...+a_{n}b_{n}.$$ Очевидно, что определенные ранее аксиомы выполняются для этого правила. То есть скалярное произведение между двумя векторами $x=(1,2,3)$ и $y=(4,5,6)$, принадлежащими пространству $\mathbb{R}^{3}$, будет равняться $$(x,y)=1\cdot4+2\cdot5+3\cdot6=4 + 10 + 18=32.$$ В Python cкалярное произведение двух векторов можно вычислять с помощью функции `numpy.dot(a, b)` или метода `vec1.dot(vec2)`, где `vec1` и `vec2` — исходные векторы.<jupyter_code>import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(f'Скалярное произведение a и b:\n{np.dot(a, b)}')<jupyter_output>Скалярное произведение a и b:
32<jupyter_text>Введем теперь такие важные понятия, как _метрика_, _норма_ (или _длина_) вектора и _угол_ между векторами в произвольном евклидовом пространстве. Для этого нужно ввести понятие _линейных нормированных пространств._  Линейные нормированные пространства Для обобщения понятия длины вектора используется понятие _нормы_. __Определение__Линейное пространтсво $R$ называется _нормированным_, если на нем введено правило, согласно которому каждому элементу $x$ ставится в соответствие число, называемое _нормой_ (или _длиной_) этого элемента и обозначаемое символом $\left\|x\right\|$.Оно должно подчиняться трем аксиомам:1) $\left\|x\right\|\geq0$, причем $\left\|x\right\|=0\Leftrightarrow x=0;$2) $\left\|\lambda x\right\|$ = $|\lambda|\left\|x\right\|$;3) $\left\| x + y \right\|$ = $\left\|x\right\|$ + $\left\|y\right\|$.Последняя аксиома называется _неравенством треугольника_, или _неравенством Минковского_. __Примеры__Существует много способов определния нормы.- $p$-норма (норма Гёльдера) для вектора $x = (x_{1}, \dots, x_{n}) \in \mathbb{R}^{n}$ вычисляется по формуле:$$\left\| x \right\|_{p} = \left( \sum_{i} \left| x_{i} \right|^{p} \right)^{1 / p},~p \geq 1.$$В частных случаях при:- $p = 1$ получаем $\ell_{1}$ норму (_манхэттенская норма_, или _манхэттенское расстояние_)$$\left\|x\right\|_{1} = \sum_{i}|x_{i}|;$$- $p = 2$ получаем $\ell_{2}$ норму (_евклидова норма_, наиболее часто используемая)$$\left\|x\right\|_{2} = \sqrt{\sum_{i}|x_{i}|^{2}}.$$ Определим норму вектора вручную и при помощи Python.Для выполнения операций линейной алгебры в Python используется модуль `numpy.linalg`. Для вычисления различных норм используется функция `numpy.linalg.norm(x, ord=None)`, где `x` — исходный вектор, `ord` — параметр, обозначенный выше как $p$ и определяющий норму.<jupyter_code>from numpy.linalg import norm<jupyter_output><empty_output><jupyter_text>Зададим вектор $a=(1,2,-3)$:<jupyter_code>a = np.array([12, 3, 4])
norm(a, 2)<jupyter_output><empty_output><jupyter_text>Определим манхэттенскую норму вектора $a$:$$\left\|x\right\|_{1} = |1|+|2|+|-3|=6.$$<jupyter_code>print(f'l1 норма вектора a:\n{norm(a, ord=1)}')<jupyter_output>l1 норма вектора a:
6.0<jupyter_text>Определим евклидову норму вектора $a$:$$\left\|x\right\|_{2} = \sqrt{1^{2}+2^{2}+(-3)^{2}}=\sqrt{14}.$$<jupyter_code>print(f'l2 норма вектора a:\n{norm(a, ord=2)}')<jupyter_output>l2 норма вектора a:
3.7416573867739413<jupyter_text>Можем убедиться, что различные нормы дают разные значения для одного и того же вектора. __Теорема__Всякое евклидово пространство является нормированным, если норму любого элемента $x$ в нем определить как$$\left\|x\right\| = \sqrt{(x,x)}.$$ Для любых $x,y$, принадлежащих евклидову пространству $E$ с так определенной нормой, имеет место неравенство $$|(x,y)|\leq\left\|x\right\| \left\|y\right\|.$$Это выражение называется _неравенством Коши — Буняковского_. Докажем его. Возьмем вещественный элемент $\lambda$ и рассмотрим элемент $x- \lambda y\in E$. Согласно аксиоме 4 для евклидова пространства, $$0\leq(x-\lambda y, x-\lambda y)=(x,x)-2(x,y)\lambda +(y,y)\lambda^{2}.$$Полученный квадратный трехчлен относительно $\lambda$ является уравнением параболы. Геометрически тот факт, что он больше или равен нулю при всех $\lambda$, означает, что квадратное уравнение $$(y,y)\lambda^{2}-2(x,y)\lambda +(x,x)=0$$либо вовсе не имеет корней, либо имеет один корень. А это возможно только тогда, когда дискриминант такого уравнения меньше или равен нулю:$$D=4(x,y)^{2}-4(x,x)(y,y)\leq0,$$из чего следует, что$$(x,y)^{2}\leq\left\|x\right\|^{2}\left\|y\right\|^{2}.$$Неравенство Коши — Буняковского доказано. __Определение__В любом вещественном евклидовом пространстве можно ввести понятие _угла_ между двумя произвольными элементами $x$ и $y$. Углом $\varphi \in [0, \pi]$ между этими элементами назовем угол, косинус которого определяется соотношением$$cos\varphi = \frac{(x,y)}{\left \|x\right \|\cdot\left \|y\right \|}.$$ __Пример__Определим угол между векторами $a=(1,2,3)$, $b=(4,5,6)$.<jupyter_code>a = np.array([1, 0, 0])
b = np.array([0, 1, 0])
c = np.array([0, 0, 1])
norm(a)
norm(b)
np.dot(a, c)<jupyter_output><empty_output><jupyter_text>$$cos\varphi = \frac{1\cdot4+2\cdot5+3\cdot6}{\sqrt{1^{2}+2^{2}+3^{2}}\sqrt{4^{2}+5^{2}+6^{2}}}=\frac{32}{\sqrt{1078}}\approx 0.97$$<jupyter_code>cos_phi = np.dot(a, b) / norm(a) / norm(b)
print(f'Косинус угла между a и b: {cos_phi:.2f}')
print(f'Угол между a и b: {np.arccos(cos_phi):.2f}')<jupyter_output>Косинус угла между a и b: 0.90
Угол между a и b: 0.46<jupyter_text>Два произвольных элемента $x$ и $y$ евклидова пространства $E$ называются _ортогональными_, если их скалярное произведение равно нулю (в этом случае косинус угла $\varphi$ между этими элементами будет равен нулю).  Метрические пространства Понятие расстояния в контексте машинного обучения обобщается с помощью _метрики_. __Определение__Пара $(E, d)$, где $E$ — множество, а $d: E\times E \rightarrow \mathbb{R}$ — вещественнозначная функция, называется _метрическим пространством_, если для всех $x,y,z\in E$ выполняются условия:1) $d(x,y)=d(y,x);$2) $d(x,x)=0$; $d(x,y)>0$, если $x \neq y$;3) $d(x,z) \leq d(x,y) + d(y,z)$ (неравенство треугольника).Функция $d$ с такими свойствами иногда обозначается  $\left | x-y \right |$ и называется _метрикой_, а $d(x,y)$ — _расстоянием между точками $x,y$_. Любое нормированное пространство можно превратить в метрическое, определив $d(x,y) = \left\|x-y\right\|$. __Пример__Как и в случае нормы, существует ряд различных методик определения метрики, например, _евклидова метрика_ $$d_{2}(x,y) = \sqrt{\sum_{i}(x_{i}-y_{i})^{2}}$$и _манхэттенская метрика_:$$d_{1}(x,y) = \sum_{i}|x_{i}-y_{i}|.$$ Определим расстояние между векторами $a=(1,2,3)$, $b=(4,5,6)$.<jupyter_code>a = np.array([1, 2, 3])
b = np.array([4, 5, 6])<jupyter_output><empty_output><jupyter_text>Один способ — посчитать метрику как $\left\|a-b\right\|$, как было сказано выше:<jupyter_code>print(f'l1 расстояние между векторами a и b:\n{norm(a - b, ord=1)}')
print(f'l2 расстояние между векторами a и b:\n{norm(a - b, ord=2)}')<jupyter_output>l2 расстояние между векторами a и b:
5.196152422706632<jupyter_text>Второй способ посчитать расстояние — использовать функцию `scipy.spatial.distance.cdist(XA, XB, metric='euclidean', p=2, ...)` из модуля SciPy, предназначенного для выполнения научных расчетов. Параметры `XA, XB` — исходные векторы, а `metric` и `p` задают метрику расстояния.Эта функция требует, чтобы размерность массивов `XA` и `XB` была как минимум двумерная, поэтому для использования этой функции исходные векторы необходимо преобразовать в _вектор-строки_ (матрица размера $1\times m$) или _вектор-столбцы_ (матрица размера $n\times1$). Матрицы как струкутры данных будут рассмотрены нами в следующих уроках. Есть различные способы преобразования вектора в вектор-строку или вектор-столбец. Первый — использовать метод `array.reshape(shape)`, где кортеж `shape` задает размерность получаемого массива.<jupyter_code>print(f'Вектор а: {a}')
print(f'Его размерность: {a.shape}')
print(f'Вектор b: {b}')
print(f'Его размерность: {b.shape}')

a = a.reshape((1, 3))
b = b.reshape((1, 3))

print('\nПосле применения метода reshape:')
print(f'Вектор-строка a: {a}')
print(f'Его размерность: {a.shape}')
print(f'Вектор-строка b: {b}')
print(f'Его размерность: {b.shape}')
from scipy.spatial.distance import cdist
print(f'Манхэттенское расстояние между a и b:\n{cdist(a, b, metric="cityblock")}')<jupyter_output>Манхэттенское расстояние между a и b:
[[9.]]<jupyter_text>Еще один способ преобразования вектора для получения возможности определения расстояния при помощи cdist — использование функции `np.newaxis`.<jupyter_code>a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(f'Преобразование вектора a в вектор-строку:\n{a[np.newaxis, :]}')
print(f'Полученная размерность:{a[np.newaxis, :].shape}')

print(f'Преобразование вектора b в вектор-столбец:\n{b[:, np.newaxis]}')
print(f'Полученная размерность:{b[:, np.newaxis].shape}')
print(f'Евклидово расстояние между a и b:\n{cdist(a[np.newaxis, :], b[np.newaxis, :], metric="euclidean")}')<jupyter_output>Евклидово расстояние между a и b:
[[5.19615242]]
{'fraction_non_alphanumeric': 0.16107321509777173, 'fraction_numerical': 0.026102773988176443, 'mean_word_length': 6.330666666666667, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '60303', 'license': 'MIT', 'n_tokens_mistral': 4906, 'n_tokens_neox': 5496, 'n_words': 1073, 'path': 'Linear-Algebra/Manuals/Lesson_2_REVISED.ipynb', 'repo_name': 'dmitryrubtsov/Mathematics', 'size': '10995'}