{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_2-R.ipynb", "provenance": [], "collapsed_sections": [], "toc_visible": true }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "f3c335f9940cfd76528b3ef918b9b342", "translation_date": "2025-09-03T19:47:44+00:00", "source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb", "language_code": "pl" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Budowa modelu regresji: przygotowanie i wizualizacja danych\n", "\n", "## **Regresja liniowa dla dyń - Lekcja 2**\n", "#### Wprowadzenie\n", "\n", "Teraz, gdy masz już narzędzia potrzebne do rozpoczęcia budowy modeli uczenia maszynowego za pomocą Tidymodels i Tidyverse, jesteś gotowy, aby zacząć zadawać pytania dotyczące swoich danych. Pracując z danymi i stosując rozwiązania ML, bardzo ważne jest, aby umieć zadawać właściwe pytania, które pozwolą w pełni wykorzystać potencjał Twojego zbioru danych.\n", "\n", "W tej lekcji dowiesz się:\n", "\n", "- Jak przygotować dane do budowy modelu.\n", "\n", "- Jak używać `ggplot2` do wizualizacji danych.\n", "\n", "Pytanie, na które chcesz uzyskać odpowiedź, określi, jaki typ algorytmów ML zastosujesz. Jakość odpowiedzi, którą otrzymasz, będzie w dużej mierze zależała od charakteru Twoich danych.\n", "\n", "Przyjrzyjmy się temu, wykonując praktyczne ćwiczenie.\n", "\n", "\n", "
\n",
" \n",
"
\n",
"\n",
"> Przypomnienie: Operator pipe (`%>%`) wykonuje operacje w logicznej kolejności, przekazując obiekt dalej do funkcji lub wyrażenia. Możesz myśleć o operatorze pipe jako o powiedzeniu \"a następnie\" w swoim kodzie.\n"
],
"metadata": {
"id": "REWcIv9yX29v"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Sprawdź brakujące dane\n",
"\n",
"Jednym z najczęstszych problemów, z jakimi muszą się zmierzyć analitycy danych, są niekompletne lub brakujące dane. W R brakujące lub nieznane wartości są reprezentowane za pomocą specjalnej wartości: `NA` (Not Available).\n",
"\n",
"Jak więc możemy sprawdzić, czy ramka danych zawiera brakujące wartości? \n",
"
\n",
"- Jednym z prostych sposobów jest użycie funkcji bazowej R `anyNA`, która zwraca logiczne wartości `TRUE` lub `FALSE`.\n"
],
"metadata": {
"id": "Zxfb3AM5YbUe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" anyNA()"
],
"outputs": [],
"metadata": {
"id": "G--DQutAYltj"
}
},
{
"cell_type": "markdown",
"source": [
"Świetnie, wygląda na to, że brakuje pewnych danych! To dobry punkt wyjścia.\n",
"\n",
"- Innym sposobem byłoby użycie funkcji `is.na()`, która wskazuje, które poszczególne elementy kolumny są brakujące, zwracając wartość logiczną `TRUE`.\n"
],
"metadata": {
"id": "mU-7-SB6YokF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "W-DxDOR4YxSW"
}
},
{
"cell_type": "markdown",
"source": [
"Ok, zadanie wykonane, ale przy tak dużej ramce danych jak ta, byłoby to nieefektywne i praktycznie niemożliwe, aby przejrzeć wszystkie wiersze i kolumny indywidualnie😴.\n",
"\n",
"- Bardziej intuicyjnym sposobem byłoby obliczenie sumy brakujących wartości dla każdej kolumny:\n"
],
"metadata": {
"id": "xUWxipKYY0o7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" colSums()"
],
"outputs": [],
"metadata": {
"id": "ZRBWV6P9ZArL"
}
},
{
"cell_type": "markdown",
"source": [
"Dużo lepiej! Brakuje danych, ale może nie będzie to miało znaczenia dla realizacji zadania. Zobaczmy, jakie wnioski przyniesie dalsza analiza.\n",
"\n",
"> Oprócz świetnych zestawów pakietów i funkcji, R posiada bardzo dobrą dokumentację. Na przykład, użyj `help(colSums)` lub `?colSums`, aby dowiedzieć się więcej o tej funkcji.\n"
],
"metadata": {
"id": "9gv-crB6ZD1Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Dplyr: Gramatyka manipulacji danymi\n",
"\n",
"
\n",
" \n",
"
\n"
],
"metadata": {
"id": "nIgLjNMCZ-6Y"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new column Price\n",
"pumpkins <- pumpkins %>% \n",
" mutate(Price = (`Low Price` + `High Price`)/2)\n",
"\n",
"# View the first few rows of the data\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "Zo0BsqqtaJw2"
}
},
{
"cell_type": "markdown",
"source": [
"Tak!💪\n",
"\n",
"„Ale chwileczkę!”, powiesz po szybkim przejrzeniu całego zestawu danych za pomocą `View(pumpkins)`, „Coś tu jest dziwnego!”🤔\n",
"\n",
"Jeśli spojrzysz na kolumnę `Package`, dynie są sprzedawane w różnych konfiguracjach. Niektóre są sprzedawane w miarach `1 1/9 bushel`, inne w miarach `1/2 bushel`, niektóre na sztuki, niektóre na wagę, a jeszcze inne w dużych pudełkach o różnych szerokościach.\n",
"\n",
"Sprawdźmy to:\n"
],
"metadata": {
"id": "p77WZr-9aQAR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Verify the distinct observations in Package column\n",
"pumpkins %>% \n",
" distinct(Package)"
],
"outputs": [],
"metadata": {
"id": "XISGfh0IaUy6"
}
},
{
"cell_type": "markdown",
"source": [
"Niesamowite!👏\n",
"\n",
"Dynie wydają się być bardzo trudne do ważenia w sposób spójny, więc przefiltrujmy je, wybierając tylko te dynie, które mają ciąg znaków *bushel* w kolumnie `Package` i umieśćmy je w nowej ramce danych `new_pumpkins`.\n"
],
"metadata": {
"id": "7sMjiVujaZxY"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::filter() i stringr::str_detect()\n",
"\n",
"[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html): tworzy podzbiór danych zawierający tylko **wiersze**, które spełniają określone warunki, w tym przypadku dynie z ciągiem *bushel* w kolumnie `Package`.\n",
"\n",
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): wykrywa obecność lub brak wzorca w ciągu znaków.\n",
"\n",
"Pakiet [`stringr`](https://github.com/tidyverse/stringr) dostarcza proste funkcje do typowych operacji na ciągach znaków.\n"
],
"metadata": {
"id": "L8Qfcs92ageF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Retain only pumpkins with \"bushel\"\n",
"new_pumpkins <- pumpkins %>% \n",
" filter(str_detect(Package, \"bushel\"))\n",
"\n",
"# Get the dimensions of the new data\n",
"dim(new_pumpkins)\n",
"\n",
"# View a few rows of the new data\n",
"new_pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "hy_SGYREampd"
}
},
{
"cell_type": "markdown",
"source": [
"Możesz zobaczyć, że ograniczyliśmy się do około 415 wierszy danych zawierających dynie na korzec.🤩\n"
],
"metadata": {
"id": "VrDwF031avlR"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::case_when()\n",
"\n",
"**Ale chwileczkę! Jest jeszcze jedna rzecz do zrobienia**\n",
"\n",
"Zauważyłeś, że ilość buszli różni się w zależności od wiersza? Musisz znormalizować ceny, aby pokazać cenę za buszel, a nie za 1 1/9 czy 1/2 buszla. Czas na trochę matematyki, aby to ustandaryzować.\n",
"\n",
"Użyjemy funkcji [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html), aby *zmodyfikować* kolumnę Price w zależności od pewnych warunków. `case_when` pozwala na wektoryzację wielu instrukcji `if_else()`.\n"
],
"metadata": {
"id": "mLpw2jH4a0tx"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Convert the price if the Package contains fractional bushel values\n",
"new_pumpkins <- new_pumpkins %>% \n",
" mutate(Price = case_when(\n",
" str_detect(Package, \"1 1/9\") ~ Price/(1 + 1/9),\n",
" str_detect(Package, \"1/2\") ~ Price/(1/2),\n",
" TRUE ~ Price))\n",
"\n",
"# View the first few rows of the data\n",
"new_pumpkins %>% \n",
" slice_head(n = 30)"
],
"outputs": [],
"metadata": {
"id": "P68kLVQmbM6I"
}
},
{
"cell_type": "markdown",
"source": [
"Teraz możemy przeanalizować cenę za jednostkę na podstawie ich miary w buszlach. Całe to badanie buszli dyni pokazuje, jak `ważne` jest `zrozumienie charakteru swoich danych`!\n",
"\n",
"> ✅ Według [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308), waga buszla zależy od rodzaju produktu, ponieważ jest to miara objętości. \"Buszel pomidorów, na przykład, powinien ważyć 56 funtów... Liście i zielenina zajmują więcej miejsca przy mniejszej wadze, więc buszel szpinaku waży tylko 20 funtów.\" To wszystko jest dość skomplikowane! Nie zawracajmy sobie głowy przeliczaniem buszli na funty, zamiast tego ustalmy cenę za buszel. Całe to badanie buszli dyni pokazuje, jak bardzo ważne jest zrozumienie charakteru swoich danych!\n",
">\n",
"> ✅ Zauważyłeś, że dynie sprzedawane na pół buszla są bardzo drogie? Czy potrafisz wyjaśnić dlaczego? Podpowiedź: małe dynie są znacznie droższe niż duże, prawdopodobnie dlatego, że jest ich znacznie więcej w buszlu, biorąc pod uwagę niewykorzystaną przestrzeń zajmowaną przez jedną dużą pustą dynię na ciasto.\n"
],
"metadata": {
"id": "pS2GNPagbSdb"
}
},
{
"cell_type": "markdown",
"source": [
"Na koniec, dla czystej przyjemności przygody 💁♀️, przenieśmy kolumnę Miesiąc na pierwszą pozycję, czyli `przed` kolumnę `Pakiet`.\n",
"\n",
"Do zmiany pozycji kolumn używamy `dplyr::relocate()`.\n"
],
"metadata": {
"id": "qql1SowfbdnP"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new data frame new_pumpkins\n",
"new_pumpkins <- new_pumpkins %>% \n",
" relocate(Month, .before = Package)\n",
"\n",
"new_pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "JJ1x6kw8bixF"
}
},
{
"cell_type": "markdown",
"source": [
"Dobra robota!👌 Masz teraz czysty, uporządkowany zestaw danych, na którym możesz zbudować swój nowy model regresji!\n",
"
\n"
],
"metadata": {
"id": "y8TJ0Za_bn5Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Wizualizacja danych za pomocą ggplot2\n",
"\n",
"
\n",
" \n",
"
\n"
],
"metadata": {
"id": "Ml7SDCLQcPvE"
}
},
{
"cell_type": "markdown",
"source": [
"### **Jak uczynić to przydatnym?**\n",
"\n",
"Aby wykresy przedstawiały użyteczne dane, zazwyczaj trzeba jakoś pogrupować dane. Na przykład w naszym przypadku, obliczenie średniej ceny dyni dla każdego miesiąca dostarczyłoby więcej informacji o ukrytych wzorcach w naszych danych. To prowadzi nas do kolejnego szybkiego przeglądu funkcji **dplyr**:\n",
"\n",
"#### `dplyr::group_by() %>% summarize()`\n",
"\n",
"Grupowanie i agregacja w R mogą być łatwo wykonane za pomocą\n",
"\n",
"`dplyr::group_by() %>% summarize()`\n",
"\n",
"- `dplyr::group_by()` zmienia jednostkę analizy z całego zbioru danych na poszczególne grupy, takie jak miesiące.\n",
"\n",
"- `dplyr::summarize()` tworzy nową ramkę danych z jedną kolumną dla każdej zmiennej grupującej oraz jedną kolumną dla każdej statystyki podsumowującej, którą określisz.\n",
"\n",
"Na przykład, możemy użyć `dplyr::group_by() %>% summarize()` do pogrupowania dyni według kolumny **Month**, a następnie obliczyć **średnią cenę** dla każdego miesiąca.\n"
],
"metadata": {
"id": "jMakvJZIcVkh"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price))"
],
"outputs": [],
"metadata": {
"id": "6kVSUa2Bcilf"
}
},
{
"cell_type": "markdown",
"source": [
"Zwięźle!✨\n",
"\n",
"Kategoryczne cechy, takie jak miesiące, lepiej przedstawiać za pomocą wykresu słupkowego 📊. Warstwy odpowiedzialne za wykresy słupkowe to `geom_bar()` i `geom_col()`. Sprawdź `?geom_bar`, aby dowiedzieć się więcej.\n",
"\n",
"Zróbmy jeden!\n"
],
"metadata": {
"id": "Kds48GUBcj3W"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month then plot a bar chart\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price)) %>% \r\n",
" ggplot(aes(x = Month, y = mean_price)) +\r\n",
" geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n",
" ylab(\"Pumpkin Price\")"
],
"outputs": [],
"metadata": {
"id": "VNbU1S3BcrxO"
}
},
{
"cell_type": "markdown",
"source": [
"🤩🤩 To bardziej przydatna wizualizacja danych! Wygląda na to, że najwyższe ceny dyni występują we wrześniu i październiku. Czy to odpowiada Twoim oczekiwaniom? Dlaczego tak lub dlaczego nie?\n",
"\n",
"Gratulacje z ukończenia drugiej lekcji 👏! Przygotowałeś dane do budowy modelu, a następnie odkryłeś więcej informacji dzięki wizualizacjom!\n"
],
"metadata": {
"id": "zDm0VOzzcuzR"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Zastrzeżenie**: \nTen dokument został przetłumaczony za pomocą usługi tłumaczenia AI [Co-op Translator](https://github.com/Azure/co-op-translator). Chociaż dokładamy wszelkich starań, aby tłumaczenie było precyzyjne, prosimy pamiętać, że automatyczne tłumaczenia mogą zawierać błędy lub nieścisłości. Oryginalny dokument w jego rodzimym języku powinien być uznawany za wiarygodne źródło. W przypadku informacji o kluczowym znaczeniu zaleca się skorzystanie z profesjonalnego tłumaczenia przez człowieka. Nie ponosimy odpowiedzialności za jakiekolwiek nieporozumienia lub błędne interpretacje wynikające z użycia tego tłumaczenia.\n"
]
}
]
}