Минимизация квадратичной ошибки python

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

tsopronyuk/Linear_Regression_Python

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

Readme.md

Task 1. Primary data analysis with Pandas

The dataset contains 25,000 records of human heights and weights. These data were obtained in 1993 by a Growth Survey of 25,000 children from birth to 18 years of age recruited from Maternal and Child Health Centres (MCHC) and schools.

[1]. Если у Вас не установлена библиотека Seaborn — выполните в терминале команду conda install seaborn. (Seaborn не входит в сборку Anaconda, но эта библиотека предоставляет удобную высокоуровневую функциональность для визуализации данных).

import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline

Считаем данные по росту и весу (weights_heights.csv, приложенный в задании) в объект Pandas DataFrame:

data = pd.read_csv('weights_heights.csv', index_col='Index')

Построим гистограмму распределения роста подростков из выборки data. Используем метод plot для DataFrame data c аргументами y=’Height’ (это тот признак, распределение которого мы строим)

data.plot(y='Height', kind='hist', color='red', title='Height (inch.) distribution')

png

  • y=’Height’ — тот признак, распределение которого мы строим
  • kind=’hist’ — означает, что строится гистограмма
  • color=’red’ — цвет

[2]. Посмотрите на первые 5 записей с помощью метода head Pandas DataFrame. Нарисуйте гистограмму распределения веса с помощью метода plot Pandas DataFrame. Сделайте гистограмму зеленой, подпишите картинку.

Height Weight
Index
1 65.78331 112.9925
2 71.51521 136.4873
3 69.39874 153.0269
4 68.21660 142.3354
5 67.78781 144.2971
data.plot(y='Weight', kind='hist', color='green', title='Weight (f.) distribution')

png

Один из эффективных методов первичного анализа данных — отображение попарных зависимостей признаков. Создается $m \times m$ графиков (m — число признаков), где по диагонали рисуются гистограммы распределения признаков, а вне диагонали — scatter plots зависимости двух признаков. Это можно делать с помощью метода $scatter_matrix$ Pandas Data Frame или pairplot библиотеки Seaborn.

Читайте также:  Html таблица всех синих цветов

Чтобы проиллюстрировать этот метод, интересней добавить третий признак. Создадим признак Индекс массы тела (BMI). Для этого воспользуемся удобной связкой метода apply Pandas DataFrame и lambda-функций Python.

def make_bmi(height_inch, weight_pound): METER_TO_INCH, KILO_TO_POUND = 39.37, 2.20462 return (weight_pound / KILO_TO_POUND) / \ (height_inch / METER_TO_INCH) ** 2
data['BMI'] = data.apply(lambda row: make_bmi(row['Height'], row['Weight']), axis=1)

[3]. Постройте картинку, на которой будут отображены попарные зависимости признаков , ‘Height’, ‘Weight’ и ‘BMI’ друг от друга. Используйте метод pairplot библиотеки Seaborn.

png

Часто при первичном анализе данных надо исследовать зависимость какого-то количественного признака от категориального (скажем, зарплаты от пола сотрудника). В этом помогут «ящики с усами» — boxplots библиотеки Seaborn. Box plot — это компактный способ показать статистики вещественного признака (среднее и квартили) по разным значениям категориального признака. Также помогает отслеживать «выбросы» — наблюдения, в которых значение данного вещественного признака сильно отличается от других.

[4]. Создайте в DataFrame data новый признак weight_category, который будет иметь 3 значения: 1 – если вес меньше 120 фунтов. (~ 54 кг.), 3 — если вес больше или равен 150 фунтов (~68 кг.), 2 – в остальных случаях. Постройте «ящик с усами» (boxplot), демонстрирующий зависимость роста от весовой категории. Используйте метод boxplot библиотеки Seaborn и метод apply Pandas DataFrame.

# Ваш код здесь def weight_category(weight): pass # Ваш код здесь if weight120: return 1 elif weight >=150: return 3 else: return 2 data['weight_cat'] = data['Weight'].apply(weight_category) #sns.boxplot(data=data, x="weight_cat", y="Height").set(xlabel = u"Весовая категория", ylabel = u"Рост") sns.boxplot(data=data, x='weight_cat' , y= 'Height')

png

[5]. Постройте scatter plot зависимости роста от веса, используя метод plot для Pandas DataFrame с аргументом kind=’scatter’. Подпишите картинку.

# Ваш код здесь data.plot(y='Height',x='Weight', kind='scatter', color='blue', title='Height (Weight) depending')

png

Task 2. Minimizing the squared error

В простейшей постановке задача прогноза значения вещественного признака по прочим признакам (задача восстановления регрессии) решается минимизацией квадратичной функции ошибки.

[6]. Напишите функцию, которая по двум параметрам $w_0$ и $w_1$ вычисляет квадратичную ошибку приближения зависимости роста $y$ от веса $x$ прямой линией $y = w_0 + w_1 * x$ : $$error(w_0, w_1) = \sum_^n <(y_i - (w_0 + w_1 * x_i))>^2 $$ Здесь $n$ – число наблюдений в наборе данных, $y_i$ и $x_i$ – рост и вес $i$ -ого человека в наборе данных.

Итак, мы решаем задачу: как через облако точек, соответсвующих наблюдениям в нашем наборе данных, в пространстве признаков «Рост» и «Вес» провести прямую линию так, чтобы минимизировать функционал из п. 6. Для начала давайте отобразим хоть какие-то прямые и убедимся, что они плохо передают зависимость роста от веса.

[7]. Проведите на графике из п. 5 Задания 1 две прямые, соответствующие значениям параметров ( $w_0, w_1) = (60, 0.05)$ и ( $w_0, w_1) = (50, 0.16)$ . Используйте метод plot из matplotlib.pyplot, а также метод linspace библиотеки NumPy. Подпишите оси и график.

def error(w0, w1): s=0. x=data['Weight'] y=data['Height'] for i in range(1,len(data.index)): s+=(y[i]-w0-w1*x[i])**2 return s 
x=np.array(data['Weight']) w0,w1=60,0.05 y1 = [w0+t*w1 for t in x] w0,w1=50,0.16 y2 = [w0+t*w1 for t in x] data.plot(y='Height',x='Weight', kind='scatter', color='blue', title='Height (Weight) depending') plt.plot(x, y1, color="red", label="line1") plt.plot(x, y2, color="green", label="line2") plt.grid(True) plt.legend(loc='upper left')

png

Минимизация квадратичной функции ошибки — относительная простая задача, поскольку функция выпуклая. Для такой задачи существует много методов оптимизации. Посмотрим, как функция ошибки зависит от одного параметра (наклон прямой), если второй параметр (свободный член) зафиксировать.

[8]. Постройте график зависимости функции ошибки, посчитанной в п. 6, от параметра $w_1$ при $w_0$ = 50. Подпишите оси и график.

# Ваш код здесь w0=50. w = np.arange(-0.5, 0.8, 0.1) err = [error(w0,w1) for w1 in w] plt.title('Error') plt.xlabel('w1 ') plt.ylabel('error(50,w1)') plt.plot(w, err, color="red", label="function of error") plt.legend()

png

Теперь методом оптимизации найдем «оптимальный» наклон прямой, приближающей зависимость роста от веса, при фиксированном коэффициенте $w_0 = 50$ .

[9]. С помощью метода minimize_scalar из scipy.optimize найдите минимум функции, определенной в п. 6, для значений параметра $w_1$ в диапазоне [-5,5]. Проведите на графике из п. 5 Задания 1 прямую, соответствующую значениям параметров ( $w_0$ , $w_1$ ) = (50, $w_1_opt$ ), где $w_1_opt$ – найденное в п. 8 оптимальное значение параметра $w_1$ .

import scipy from scipy.optimize import minimize_scalar def error50(w1): return error(50,w1) min=minimize_scalar(error50, bounds=(-5,5), method='bounded') w1_opt=min.x min.x, min.fun
(0.14109165115062905, 79510.632440047964) 
x=np.array(data['Weight']) w0,w1=50,w1_opt y = [w0+t*w1 for t in x] #xx = np.linspace(np.min(data['Weight']),np.max(data['Weight']),data.count) data.plot(y='Height',x='Weight', kind='scatter', color='blue', title='Height (Weight) depending') plt.plot(x, y, color="red", label="lineOptimum") plt.grid(True) plt.legend(loc='upper left')

png

from mpl_toolkits.mplot3d import Axes3D

Создаем объекты типа matplotlib.figure.Figure (рисунок) и matplotlib.axes._subplots.Axes3DSubplot (ось).

[10]. Постройте 3D-график зависимости функции ошибки, посчитанной в п.6 от параметров $w_0$ и $w_1$ . Подпишите ось $x$ меткой «Intercept», ось $y$ – меткой «Slope», a ось $z$ – меткой «Error».

fig = plt.figure() ax = fig.gca(projection='3d') # get current axis w0 = np.arange(-5, 5, 0.25) w1 = np.arange(-5, 5, 0.25) W0, W1 = np.meshgrid(w0, w1) E = error(W0,W1) # используем метод *plot_surface* объекта # типа Axes3DSubplot. Также подписываем оси. surf = ax.plot_surface(W0, W1, E) ax.set_xlabel('Intercept') ax.set_ylabel('Slope') ax.set_zlabel('Error') plt.show()

png

[11]. С помощью метода minimize из scipy.optimize найдите минимум функции, определенной в п. 6, для значений параметра $w_0$ в диапазоне [-100,100] и $w_1$ — в диапазоне [-5, 5]. Начальная точка – ( $w_0$ , $w_1$ ) = (0, 0). Используйте метод оптимизации L-BFGS-B (аргумент method метода minimize). Проведите на графике из п. 5 Задания 1 прямую, соответствующую найденным оптимальным значениям параметров $w_0$ и $w_1$ . Подпишите оси и график.

def error1(w): s=0. x=data['Weight'] y=data['Height'] for i in range(1,len(data.index)): s+=(y[i]-w[0]-w[1]*x[i])**2 return s import scipy.optimize as optimize min = optimize.minimize(error1, np.array([0,0]), method = 'L-BFGS-B', bounds=((-100,100),(-5, 5))) min.x, min.fun
(array([ 57.57161437, 0.08200743]), 67544.152054243299) 
# Ваш код здесь x=np.array(data['Weight']) w0,w1=min.x y = [w0+t*w1 for t in x] data.plot(y='Height',x='Weight', kind='scatter', color='blue', title='Height (Weight) depending') plt.plot(x, y, color="red", label="lineOptimum") plt.grid(True) plt.legend(loc='upper left')

Источник

Линейная регрессия и основные библиотеки Python для анализа данных и научных вычислений¶

Это задание посвящено линейной регрессии. На примере прогнозирования роста человека по его весу Вы увидите, какая математика за этим стоит, а заодно познакомитесь с основными библиотеками Python, необходимыми для дальнейшего прохождения курса.

  • Лекции данного курса по линейным моделям и градиентному спуску
  • Документация по библиотекам NumPy и SciPy
  • Документация по библиотеке Matplotlib
  • Документация по библиотеке Pandas
  • Pandas Cheat Sheet
  • Документация по библиотеке Seaborn

Задание 1. Первичный анализ данных c Pandas¶

В этом заданиии мы будем использовать данные SOCR по росту и весу 25 тысяч подростков.

[1]. Если у Вас не установлена библиотека Seaborn — выполните в терминале команду conda install seaborn. (Seaborn не входит в сборку Anaconda, но эта библиотека предоставляет удобную высокоуровневую функциональность для визуализации данных).

import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline

Считаем данные по росту и весу (weights_heights.csv, приложенный в задании) в объект Pandas DataFrame:

data = pd.read_csv('weights_heights.csv', index_col='Index') 

Чаще всего первое, что надо надо сделать после считывания данных — это посмотреть на первые несколько записей. Так можно отловить ошибки чтения данных (например, если вместо 10 столбцов получился один, в названии которого 9 точек с запятой). Также это позволяет познакомиться с данными, как минимум, посмотреть на признаки и их природу (количественный, категориальный и т.д.).

После этого стоит построить гистограммы распределения признаков — это опять-таки позволяет понять природу признака (степенное у него распределение, или нормальное, или какое-то еще). Также благодаря гистограмме можно найти какие-то значения, сильно не похожие на другие — «выбросы» в данных. Гистограммы удобно строить методом plot Pandas DataFrame с аргументом kind=’hist’.

Пример. Построим гистограмму распределения роста подростков из выборки data. Используем метод plot для DataFrame data c аргументами y=’Height’ (это тот признак, распределение которого мы строим)

data.plot(y='Height', kind='hist', color='red', title='Height (inch.) distribution') 

Источник

Оцените статью