Шестаков А.В. Майнор по анализу данных - 12/01/2016
Этот IPython Notebook содержит вспомогательные указания для выполнения семинарских и домашних заданий. В течение курса мы будем преимущественно работать в подобных "тетрадках", но может быть иногда будем переключаться на другие среды\средства.
(Мы используем Python версии 2.x.x, а не 3.x.x)
Самый простой и надежный способ - воспользоваться готовым дистрибутивом Anaconda, включающий в себе практически все необходимые модули и утилиты, которые нам понадобятся - IPython, NumPy, SciPy, Matplotlib и Scikit-Learn. Просто следуйте указаниям установщика для вашей ОС.
2*7
6+4**2-1
4^4
# О боже, госпади, что это было?
Знак "#" символизирует начало комментариев в коде - всё что идет после этого знака до конца строки игнорируется Питоном.
Поехали дальше - что у нас с делением?
16/4
25/7
# Угадайте, что получится?
Для питона, в результате целочисленного деления должно тоже получится целое число. Т.е. остаток отбрасывается. Как же намекнуть питону, что мы хотим получить точный ответ?
25./7
25/7.
float(25)/7
Ну окей, пока всё это можно было посчитать в столбик.
Есть что посерьезнее? КАААНЕЧНО!
sqrt(4)
... Но не так сразу. Питон начал ругаться. По-умолчанию, он не знает, что такое извлечение квадратного корня. Однако можно показать ему, где искать.
В стандартном модуле math
есть такая функция. Давайте импортируем её в нашу программу
import math
math.sqrt(4)
А чтобы каждый раз не писать math
. перед вызовом конкретных фукнций можно поступить так:
from math import sin
sin(3.14)
Ну хорошо, что мы всё приближенно, давайте точно посчитаем, чему равено $sin(\pi)$. В модуле math можно найти это самое $\pi$
from math import pi
sin(pi)
Возникают вопросы:
В Python не надо как-то спецально объявлять переменную. Присвоил значение и поехали!
x = 4
x
# Инкрементация
x = x + 2
x+=2 # тоже самое
x
# Логические операции
x != 7
x > 7
x < 10
Числа Фибоначчи или последовательность Фибоначчи — последовательность чисел, начинающаяся с двух единиц, и такая, что очередное число в этой последовательности равно сумме двух предыдущих. Формально можно определить её следующим образом:
$a_1=1$;
$a_2=1$;
$a_{n+1}=a_n+a_{n-1}$ для всех $n>2$.
Например, $a_3=1+1=2$, $a_4=2+1=3$.
Задача: посчитать 15-е число Фибоначчи
a = 1 # первое число
b = 1 # второе число
i = 2 # номер того числа, которое находится в переменной b (сейчас это a_2)
c = a + b #нашли следующее число
i = i + 1 #увеличили i на 1
a = b
b = c
# или можно сделать в одну строчку
# a,b = b,c
print i, b
# команда print выводит на экран значение переменных
# и всякие другие штуки
Питон выполняет команды последовательно, строчку за строчкой, поэтому порядок следоавния команд очень важен. Выполняя эту ячейку несколько раз, вы будете получать каждый раз очередное число Фибоначчи.
До сих пор мы имели дело только с числами, но уже поняли, что вещественные числа отличаются от целых. Вообще в Python есть много разных типов данных, предназначенных для хранения информации разной природы. Каждый тип данных имеет название в Python, например, целые числа — это int
, вещественные (числа с плавающей запятой или правильнее сказать плавающей точкой) — float
.
Строки выглядят так:
print 'Hello, World!'
Вот эта штука в кавычках — это и есть строка (тип данных str
). Строки тоже можно сохранять в переменных и делать с ними разные операции (но совсем не такие, как с числами).
type('Blah-Blah')
a = "Hello"
b = "World"
print a + b
# Форматирование строк
x = 123
# Хочу:
# x is equal to 123
print 'x is equal to %i' % x
Здесь символ процента означает, что нужно взять переменную, которая написана справа, и подставить в строчку, написанную слева, вместо символов %i
. Буква i
здесь означает integer
, то есть что ожидается целое число.
'ABC' == 'abc'
'ABC' < 'DEF'
До сих пор мы работали с числовыми переменными — в каждой переменной лежало одно число. На практике нам зачастую приходится работать с большими массивами данных. Чтобы их хранить, нужно познакомиться со списками. Список — это такая переменная, которая содержит в себе сразу много элементов.
x = [2, 5, 1, 2, 3, 2, 4, 6]
# вот эта штука в квадратных скобках — это и есть список
Можно обращаться к отдельным элементам списка и работать с ними как с обычными переменными. Чтобы выбрать элемент, нужно указать его номер.
Нумерация начинается с нуля! По старой программистская традиции, чтобы запутать непосвященных.
x[0]
x[1] = 10
x
Список можно расширять!
x.append(2)
x
type(x)
Слово append
— это метод класса list
. У x
, как у любого списка, есть много методов. Можно набрать x.
, нажать табуляцию, и получить список доступных методов. Например:
x.count(2) # считаем количество "2"
x.reverse()
# пустые скобки означают, что мы вызываем функцию,
# но параметров ей не передаем
x
# Cписок можно попробовать отсортировать
x.sort(reverse=True)
print x
Иногда нам нужен не весь список, а его кусочек.
print x
print x[2:5]
print x[2:]
print x[:5]
Списки могут быть коварными.
y = x
y[0] = 15
# Что же лежит в первом элементе списка x?
# 10 ил 15?
x
ШТАА?! Когда мы изменили список y
, то изменился и список x
! Почему так произошло? Дело в том, что списки живут в своём собственном мире платоновских идей.
Когда мы присваиваем список переменной, то есть пишем что-нибудь вроде x = [1, 2, 3]
мы говорим, что теперь переменная x
будет указывать на этот список. Можно сказать, что мы создали список и дали ему имя x
. После этого в x
хранится не сам список, а указатель (ссылка) на него. Когда мы присваиваем значение x
новой переменной y
, мы не производим копирование списка, мы копируем только указатель. То есть y
просто стала другим именем для того же самого списка, что и y
. Поэтому изменение элементов x
приведет к изменению y
, и наоборот.
Если мы хотим создать новый список, скопировав существующий, нужно использовать вот такой синтаксис:
y = x[:]
y[1] = 10
print x
print y
a = 10.8
b = int(a)
print b
a = '213'
x = a + a
print int(x)
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
plt.plot([1,2,3,4],[4,2,3,1])
plt.bar([1,2,3,4,6],[1,2,3,4,10])
x = np.arange(-10, 10, 0.5)
y = x**2
plt.plot(x, y)
В "сыром" виде выглядит не так чтобы очень. Но всегда можно заморочиться. И себе приятно, и семенаристу (который будет смотреть твои домашнки)!
# Особый стриль графиков
plt.style.use('ggplot')
# Это надо, чтобы писать русскими буквами
font = {'family': 'Verdana',
'weight': 'normal'}
plt.rc('font', **font)
x = np.arange(0, 6*np.pi, 0.3)
y = np.sin(x)
z = np.cos(x)
plt.figure(figsize=(8, 6))
plt.plot(x, y)
plt.plot(x, z, 'b')
plt.xlabel('x')
plt.title(u'Тригонометрия!')
plt.legend(['sin', 'cos'])
Часто в программе возникают "развилки" - когда в зависимости от выполнения какого-то условия, программа должна пойти по тому или иному пути.
В Python, как и во многих языках программирования, такие развилки задаются словом if
:
x = 3
if x == 2:
print 'Okay'
print 'This is good number'
else:
print 'Oh, noooo!'
if x > 2:
print 'x is greater than 2'
else:
print 'x is lesser than 2'
Можно задавать несколько условий, объединяя их логическими операторами И,ИЛИ НЕ
x = 1.5
if x > 2 and x < 3:
print 'Okay'
if x < 2 or x < 3:
print 'Okay'
if 1 < x < 5:
print 'Ok'
for
¶Часто нужно сделать какое-то действие со всеми элементами списка. Для этого есть цикл for
.
x = [1, 4, 9, 1]
i = 1234
for i in x:
print i
print "One more"
# print i + 1
print "And finally"
print i
break
и continue
¶Говоря о циклах, нужно упомянуть два специальных способа прекратить обработку очередного элемента. Ключевое слово continue
означает, что нужно вернуться в начало цикла и взять следующй элемент.
for i in xrange(1, 10):
if i**2>10:
print 'Next'
continue
else:
print i
print 'Ok'
for i in xrange(1,10):
if i**2>50:
print "Stop"
break
else:
print i
print "Okay"
print "Stopped"
while
¶Иногда нужно выполнять какие-то команды до тех пор, пока что-то не произойдёт. Например, мы выводим на экран числа Фибоначчи, но только те из них, которые меньше 1000. Это делается с помощью цикла while
.
a = 1
b = 1
while b < 1000:
c = a + b
a = b
b = c
print a
Если условие не выполняется до входа в цикл, то тело цикла не выполнится ни разу. Если вы хотите цикл с постусловием (то есть условием, проверяющимся в конце), то мне придётся вас расстроить: в Python его нет. Есть только вот такая конструкция, его заменяющая.
x=10
while True:
print "Hello"
x=x+2
if not (x<5):
break
Задача 1. Ввести числа a
, d
и N
. Найти сумму первых N
членов арифметической прогрессии с первым членом a
и разностью d
, не пользуясь «школьной» формулой.
Задача 2. Ввести число N
с клавиатуры. Найти сумму первых N
членов гармонического ряда.
Задача 3. Ввести натуральное число N
с клавиатуры. Проверить, является ли оно простым.
Задача 4. Вывести N
первых простых чисел.
Задача 5. Даны три числа: a
, b
, c
. Не пользуясь функциями min
, max
и какими-либо библиотечными функциями, вывести на экран максимальное из них.
func = lambda x: x**2
# Это тоже самое, что и сверху
def func(x):
return x**2
func(4)
l = range(10)
l2 = map(func, l)
l2
reduce(lambda x, y: x+y, l)
filter(lambda x: x>=5, l)
string = 'lala. alala, dada'
no_punct = filter(lambda x: x not in ['.', ','], string)
no_punct
В общем случае, работа с файлами осуществляется через команду open
. Давайте попробуем создать файл с каким-то текстом:
fout = open('temp.txt', 'w')
string = 'this is very interesting text\n'
fout.write(string)
fout.close()
Попробуем записать несколько строк:
string_arr = ['Indeed, this text is very interesting,\n',
'You should read it again',
' and again']
with open('temp.txt', 'w') as fout:
fout.writelines(string_arr)
Теперь, загрузим содержание файла:
with open('temp.txt', 'r') as fin:
data = fin.readlines()
data = map(lambda (x): x.strip(), data)
Как правило, в зависимости от области применимости модуля Python, в нем есть свои функции загрузки из различных форматов файлов в нужный тип данных. В следующий раз мы поработаем с прекрасным модулем Pandas
, созданный для работы с таблицами всевозможных сортов. А сейчас - посмотрим что есть в NumPy
.
Загрузите файл 1 и файл 2 в папку с тетрадкой. С помощью функции loadtxt
в модуле NumPy загрузите табличные данные одного из файлов. Присвойте y = D[:,0] а X = D[:, 1:].
Оцените коэффициенты линейной регрессии $\hat{y} = X\hat{\beta}$, где
$$ \hat{\beta} = (X^T X)^{-1} X^T y $$Остатки модели рассчитываются как $$ \text{res} = y - \hat{y} $$
Итак, еще раз:
1. Загрузите данные
2. Обучите модель
3. Постройте два графика:
3.1. Выберите какой-нибудь признак (кроме x0) и на одном графике изобразите зависимость y~x и линию регрессии
3.2. Постройте график остатки~y
# Write your code here
#
#
#
# load data
D = np.loadtxt('tutorial_dataset.csv',
skiprows=1,
delimiter=',')