Предметна область тут інша, ніж у лекції, — навмисно: якщо ти зможеш повторити ту саму
механіку на своїх даних, значить, справа не в завченому прикладі. Працюємо з
показаннями фітнес-браслета: скільки кроків людина зробила за кожен із девʼяноста
днів. Усе роби в окремому файлі kroky.py або в новому зошиті — практику не редагуй,
вона знадобиться для звірки.
Дані генеруй саме цією формулою, без випадковості, щоб числа збіглися з критеріями нижче:
import numpy as np
дні = np.arange(90)
шум = (дні * 1103515245 + 12345) % 2 ** 31 % 1201 - 600 # від -600 до +600 кроків
вихідний = np.isin(дні % 7, [5, 6]) # субота й неділя
кроки = 6000 + 40 * дні + вихідний * 2500 + шум
рівень 1Рівень 1 — База
Побудуй один графік, у якого є все, чого лекція вимагала від читабельної картинки.
- Лінія
крокив часі плюс друга лінія —кроки_торік = кроки - 1500. - Заголовок, підпис осі
x, підпис осіyз одиницями, легенда з двома записами, напівпрозора сітка. - Горизонтальна лінія на рівні 10 000 кроків (
ax.axhline) з власним підписом у легенді. - Збережи результат у файл
kroky.pngзdpi=200іbbox_inches="tight"— і зроби це доplt.show(). - Надрукуй, скільки днів із девʼяноста перевищили 10 000 кроків.
Зроблено, якщо:
- проходить
assert list(кроки[:5]) == [5735, 6190, 5876, 6331, 6017]— формула саме та; - проходить
assert (кроки > 10000).sum() == 13, і це число надруковане в консолі; - проходить
assert ax.get_ylabel() != "" and ax.get_xlabel() != ""; - проходить
assert len(ax.get_legend().get_texts()) == 3— дві лінії плюс поріг; - файл
kroky.pngіснує, і його ширина в пікселях більша за 1500 (перевір черезPIL.Image.open("kroky.png").size).
рівень 2Рівень 2 — Плюс
Одні дані, три різні питання — і три різні типи графіка в одній сітці.
- Сітка
plt.subplots(2, 2, constrained_layout=True). - Ліворуч угорі — лінія по днях: чи є зростання за три місяці.
- Праворуч угорі — гістограма всіх девʼяноста значень: як вони розподілені.
- Ліворуч унизу — стовпчики: середня кількість кроків по днях тижня
(
дні % 7, сім стовпчиків). - Праворуч унизу — точки: кроки проти номера тижня (
дні // 7), щоб побачити розкид усередині кожного тижня. - Кожна область має власний заголовок і підписи обох осей.
- Під сіткою надрукуй три речення: що видно на кожному типі й чого на ньому не видно.
Зроблено, якщо:
- проходить
assert axes.shape == (2, 2)— і в коді видно, що це масивnumpy; - проходить
assert round(кроки[~вихідний].mean()) == 7788іassert round(кроки[вихідний].mean()) == 10299, а обидва числа підписані на стовпчиковому графіку; - у стовпчиках по днях тижня два останні стовпчики помітно вищі, і
assertце підтверджує:assert середні_по_днях[5] > середні_по_днях[:5].max(); - у трьох реченнях висновку названо принаймні одну річ, яку кожен тип приховує.
рівень 3Рівень 3 — Виклик
Зроби власний «квартет»: чотири набори з однаковими числами й різними формами.
- Придумай і згенеруй чотири набори по 40 точок, у яких збігаються до другого знака:
середнє
x, середнєy, стандартне відхиленняyі коефіцієнт кореляції. Форми мають бути різні: пряма з шумом, дуга, дві окремі хмари, пряма з одним викидом. Підганяти можна масштабом і зсувом: якщо взяти будь-яку форму й перерахувати її якy_нове = (y - y.mean()) / y.std() * потрібне_відхилення + потрібне_середнє, середнє й відхилення стануть точно такими, як треба, а форма не зміниться. - Надрукуй таблицю показників усіх чотирьох наборів і доведи
assert-ом, що вони однакові до другого знака. - Намалюй усі чотири в сітці
1×4зі спільними межами осей і однією й тією самою прямою регресії. - Окремо зроби пару «оманливо / чесно» на своїх даних кроків: візьми середнє за перший і за останній місяць, покажи їх стовпчиками двічі — з віссю від нуля й з обрізаною віссю — і порахуй числом, у скільки разів перебільшене враження.
- Опиши одним абзацом третій спосіб збрехати графіком, якого не було в лекції, і покажи його кодом.
Зроблено, якщо:
- проходить
assert (показники.round(2).nunique() == 1).all()для таблиці з чотирьох рядків — усі показники однакові; - кореляція в усіх чотирьох наборів не менша за 0.6 за модулем (інакше «однаковість» досягнута тим, що звʼязку немає ніде);
- на картинці всі чотири форми справді різні, і в коментарі до кожної написано, яке рішення вона диктує;
- для пари «оманливо / чесно» надруковано два числа: справжня різниця у відсотках і візуальне відношення довжин стовпчиків, а також коефіцієнт перебільшення;
- третій спосіб збрехати описано словами й відтворено кодом на тих самих даних.
Підказки
- Рівень 1.
ax.axhline(10000, label="поріг 10 000")додає лінію й одразу її підпис. Легенда збирає підписи звідусіль, де бувlabel=, — тому три записи виходять самі. - Рівень 1, файл. Якщо
kroky.pngвийшов порожнім, найімовірніша причина —savefigпісляshow(). Порядок має бути зворотним. - Рівень 2. Середнє по днях тижня зручно рахувати без циклу:
np.array([кроки[дні % 7 == д].mean() for д in range(7)])— сім чисел, кожне з одного зрізу за умовою. - Рівень 3, підгонка. Спершу зроби чотири різні форми, а вже потім кожну окремо перерахуй так, щоб середнє й відхилення стали потрібними. Кореляцію підганяти важче: найпростіше змішувати «чистий звʼязок» і шум у пропорції, яку підбираєш кількома спробами в циклі.
- Рівень 3, викид. Одна точка, віднесена далеко вбік, змінює кореляцію сильніше за решту тридцяти девʼяти разом узятих. Це і є причина, чому четвертий набір Анскомба виглядає так, як виглядає.
- Рівень 3, пункт 5. Подумай про подвійну вісь
y(ax.twinx()), про пропущені дні на осі часу й про порядок категорій, підібраний під потрібний висновок.