You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
493 lines
29 KiB
493 lines
29 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## **스포티파이에서 수집된 나이지리아 음악 - 분석**\n",
|
|
"\n",
|
|
"클러스터링은 데이터셋이 라벨이 없거나 입력값이 미리 정의된 출력값과 일치하지 않는다고 가정하는 [비지도 학습](https://wikipedia.org/wiki/Unsupervised_learning)의 한 유형입니다. 클러스터링은 다양한 알고리즘을 사용하여 라벨이 없는 데이터를 분류하고 데이터에서 발견된 패턴에 따라 그룹을 제공합니다.\n",
|
|
"\n",
|
|
"[**강의 전 퀴즈**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\n",
|
|
"\n",
|
|
"### **소개**\n",
|
|
"\n",
|
|
"[클러스터링](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124)은 데이터 탐색에 매우 유용합니다. 나이지리아 청중들이 음악을 소비하는 방식에서 트렌드와 패턴을 발견하는 데 클러스터링이 도움이 되는지 살펴봅시다.\n",
|
|
"\n",
|
|
"> ✅ 클러스터링의 용도에 대해 잠시 생각해 보세요. 현실에서 클러스터링은 빨래 더미를 가족 구성원의 옷으로 분류해야 할 때 발생합니다 🧦👕👖🩲. 데이터 과학에서는 사용자의 선호도를 분석하거나 라벨이 없는 데이터셋의 특성을 결정하려고 할 때 클러스터링이 발생합니다. 클러스터링은 일종의 혼란 속에서 질서를 찾는 데 도움을 줍니다. 마치 양말 서랍을 정리하는 것처럼요.\n",
|
|
"\n",
|
|
"전문적인 환경에서는 클러스터링을 사용하여 시장 세분화를 결정하거나, 예를 들어 어떤 연령대가 어떤 아이템을 구매하는지 파악할 수 있습니다. 또 다른 용도로는 신용카드 거래 데이터셋에서 사기를 탐지하는 이상치 감지가 있을 수 있습니다. 또는 의료 스캔 데이터에서 종양을 식별하는 데 사용할 수도 있습니다.\n",
|
|
"\n",
|
|
"✅ 은행, 전자상거래, 또는 비즈니스 환경에서 클러스터링을 '자연스럽게' 접한 경험이 있는지 생각해 보세요.\n",
|
|
"\n",
|
|
"> 🎓 흥미롭게도, 클러스터 분석은 1930년대 인류학과 심리학 분야에서 시작되었습니다. 당시에는 어떻게 사용되었을지 상상해 보세요.\n",
|
|
"\n",
|
|
"또한 검색 결과를 그룹화하는 데 사용할 수도 있습니다. 예를 들어 쇼핑 링크, 이미지, 리뷰 등을 그룹화하는 방식입니다. 클러스터링은 대규모 데이터셋을 줄이고 더 세부적인 분석을 수행하려는 경우에 유용하며, 다른 모델을 구축하기 전에 데이터를 학습하는 데 사용할 수 있습니다.\n",
|
|
"\n",
|
|
"✅ 데이터가 클러스터로 정리되면 클러스터 ID를 할당할 수 있습니다. 이 기술은 데이터셋의 프라이버시를 보호하는 데 유용할 수 있습니다. 더 구체적이고 식별 가능한 데이터를 사용하는 대신 클러스터 ID로 데이터 포인트를 참조할 수 있기 때문입니다. 클러스터 ID를 다른 요소 대신 사용하는 이유를 더 생각해 볼 수 있을까요?\n",
|
|
"\n",
|
|
"### 클러스터링 시작하기\n",
|
|
"\n",
|
|
"> 🎓 클러스터를 생성하는 방식은 데이터 포인트를 그룹으로 묶는 방식과 밀접한 관련이 있습니다. 몇 가지 용어를 살펴봅시다:\n",
|
|
">\n",
|
|
"> 🎓 ['전이적' vs. '귀납적'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n",
|
|
">\n",
|
|
"> 전이적 추론은 특정 테스트 사례와 일치하는 관찰된 학습 사례에서 도출됩니다. 귀납적 추론은 일반적인 규칙으로 매핑되는 학습 사례에서 도출된 후 테스트 사례에 적용됩니다.\n",
|
|
">\n",
|
|
"> 예: 데이터셋이 부분적으로만 라벨이 지정되어 있다고 가정해 봅시다. 일부는 '레코드', 일부는 'CD', 일부는 공백입니다. 공백에 라벨을 제공하는 것이 여러분의 작업입니다. 귀납적 접근 방식을 선택하면 '레코드'와 'CD'를 찾는 모델을 학습시키고 해당 라벨을 라벨이 없는 데이터에 적용합니다. 이 접근 방식은 실제로 '카세트'인 항목을 분류하는 데 어려움을 겪을 수 있습니다. 반면, 전이적 접근 방식은 유사한 항목을 그룹화한 다음 그룹에 라벨을 적용하는 방식으로 이와 같은 미지의 데이터를 더 효과적으로 처리합니다. 이 경우 클러스터는 '둥근 음악 물건'과 '네모난 음악 물건'을 반영할 수 있습니다.\n",
|
|
">\n",
|
|
"> 🎓 ['평면' vs. '비평면' 기하학](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n",
|
|
">\n",
|
|
"> 수학 용어에서 파생된 평면 vs. 비평면 기하학은 점들 간의 거리를 '평면'([유클리드](https://wikipedia.org/wiki/Euclidean_geometry)) 또는 '비평면'(비유클리드) 기하학적 방법으로 측정하는 것을 의미합니다.\n",
|
|
">\n",
|
|
"> 여기서 '평면'은 유클리드 기하학(일부는 '평면' 기하학으로 가르침)을 의미하며, '비평면'은 비유클리드 기하학을 의미합니다. 기하학이 기계 학습과 무슨 관련이 있을까요? 두 분야 모두 수학에 뿌리를 두고 있기 때문에 클러스터 내 점들 간의 거리를 측정하는 공통된 방법이 필요하며, 데이터의 특성에 따라 '평면' 또는 '비평면' 방식으로 측정할 수 있습니다. [유클리드 거리](https://wikipedia.org/wiki/Euclidean_distance)는 두 점 사이의 선분 길이로 측정됩니다. [비유클리드 거리](https://wikipedia.org/wiki/Non-Euclidean_geometry)는 곡선을 따라 측정됩니다. 데이터가 시각화되었을 때 평면에 존재하지 않는 것처럼 보인다면, 이를 처리하기 위해 특수 알고리즘이 필요할 수 있습니다.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/flat-nonflat.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>다사니 마디팔리의 인포그래픽</figcaption>\n",
|
|
"\n",
|
|
"> 🎓 ['거리'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n",
|
|
">\n",
|
|
"> 클러스터는 점들 간의 거리 행렬, 즉 점들 간의 거리로 정의됩니다. 이 거리는 몇 가지 방법으로 측정될 수 있습니다. 유클리드 클러스터는 점 값의 평균으로 정의되며, '중심점' 또는 중심점을 포함합니다. 거리는 따라서 그 중심점까지의 거리로 측정됩니다. 비유클리드 거리는 '클러스트로이드', 즉 다른 점들에 가장 가까운 점을 참조합니다. 클러스트로이드는 다양한 방식으로 정의될 수 있습니다.\n",
|
|
">\n",
|
|
"> 🎓 ['제약'](https://wikipedia.org/wiki/Constrained_clustering)\n",
|
|
">\n",
|
|
"> [제약 클러스터링](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf)은 이 비지도 방법에 '반지도 학습'을 도입합니다. 점들 간의 관계는 '연결 불가' 또는 '연결 필수'로 표시되어 데이터셋에 몇 가지 규칙이 강제됩니다.\n",
|
|
">\n",
|
|
"> 예: 알고리즘이 라벨이 없거나 부분적으로 라벨이 지정된 데이터 배치에서 자유롭게 작동하도록 설정되면 생성된 클러스터의 품질이 낮을 수 있습니다. 위의 예에서 클러스터는 '둥근 음악 물건', '네모난 음악 물건', '삼각형 물건', '쿠키'를 그룹화할 수 있습니다. 일부 제약 조건이나 따라야 할 규칙(\"항목은 플라스틱으로 만들어져야 한다\", \"항목은 음악을 생성할 수 있어야 한다\")이 주어지면 알고리즘이 더 나은 선택을 하도록 '제약'할 수 있습니다.\n",
|
|
">\n",
|
|
"> 🎓 '밀도'\n",
|
|
">\n",
|
|
"> '노이즈'가 많은 데이터는 '밀도가 높다'고 간주됩니다. 각 클러스터 내 점들 간의 거리는 더 밀도가 높거나 낮은 것으로 나타날 수 있으며, 따라서 이러한 데이터는 적절한 클러스터링 방법으로 분석해야 합니다. [이 기사](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html)는 불균일한 클러스터 밀도를 가진 노이즈 데이터셋을 탐색하기 위해 K-Means 클러스터링과 HDBSCAN 알고리즘을 사용하는 차이를 보여줍니다.\n",
|
|
"\n",
|
|
"클러스터링 기술에 대한 이해를 심화하려면 이 [학습 모듈](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)을 확인하세요.\n",
|
|
"\n",
|
|
"### **클러스터링 알고리즘**\n",
|
|
"\n",
|
|
"100개 이상의 클러스터링 알고리즘이 있으며, 그 사용은 데이터의 특성에 따라 달라집니다. 주요 알고리즘 몇 가지를 살펴봅시다:\n",
|
|
"\n",
|
|
"- **계층적 클러스터링**. 객체가 멀리 떨어진 객체보다 가까운 객체와의 근접성에 따라 분류되는 경우, 클러스터는 다른 객체와의 거리로 인해 형성됩니다. 계층적 클러스터링은 두 클러스터를 반복적으로 결합하는 방식으로 특징지어집니다.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/hierarchical.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>다사니 마디팔리의 인포그래픽</figcaption>\n",
|
|
"\n",
|
|
"- **중심점 클러스터링**. 이 인기 있는 알고리즘은 'k', 즉 형성할 클러스터 수를 선택한 후, 알고리즘이 클러스터의 중심점을 결정하고 해당 점 주위에 데이터를 모읍니다. [K-평균 클러스터링](https://wikipedia.org/wiki/K-means_clustering)은 중심점 클러스터링의 인기 있는 버전으로, 데이터셋을 미리 정의된 K 그룹으로 분리합니다. 중심은 가장 가까운 평균에 의해 결정되며, 따라서 이름이 붙여졌습니다. 클러스터에서의 제곱 거리가 최소화됩니다.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/centroid.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>다사니 마디팔리의 인포그래픽</figcaption>\n",
|
|
"\n",
|
|
"- **분포 기반 클러스터링**. 통계 모델링에 기반을 둔 분포 기반 클러스터링은 데이터 포인트가 클러스터에 속할 확률을 결정하고 이에 따라 할당합니다. 가우시안 혼합 방법이 이 유형에 속합니다.\n",
|
|
"\n",
|
|
"- **밀도 기반 클러스터링**. 데이터 포인트는 밀도, 즉 서로 주위에 그룹화된 정도에 따라 클러스터에 할당됩니다. 그룹에서 멀리 떨어진 데이터 포인트는 이상치 또는 노이즈로 간주됩니다. DBSCAN, Mean-shift, OPTICS가 이 유형에 속합니다.\n",
|
|
"\n",
|
|
"- **그리드 기반 클러스터링**. 다차원 데이터셋의 경우, 그리드를 생성하고 데이터를 그리드의 셀에 나누어 클러스터를 생성합니다.\n",
|
|
"\n",
|
|
"클러스터링을 배우는 가장 좋은 방법은 직접 시도해 보는 것입니다. 이번 연습에서 바로 그렇게 해볼 것입니다.\n",
|
|
"\n",
|
|
"이 모듈을 완료하려면 몇 가지 패키지가 필요합니다. 다음 명령어로 설치할 수 있습니다: `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork'))`\n",
|
|
"\n",
|
|
"또는 아래 스크립트를 사용하여 필요한 패키지가 설치되어 있는지 확인하고, 누락된 경우 설치할 수 있습니다.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\r\n",
|
|
"\r\n",
|
|
"pacman::p_load('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork')\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 연습 - 데이터를 클러스터링하기\n",
|
|
"\n",
|
|
"클러스터링은 적절한 시각화를 통해 크게 도움을 받을 수 있는 기술입니다. 따라서 음악 데이터를 시각화하는 것부터 시작해 봅시다. 이 연습은 이 데이터의 특성에 가장 효과적으로 사용할 수 있는 클러스터링 방법을 결정하는 데 도움을 줄 것입니다.\n",
|
|
"\n",
|
|
"데이터를 가져오는 것으로 바로 시작해 봅시다.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Load the core tidyverse and make it available in your current R session\r\n",
|
|
"library(tidyverse)\r\n",
|
|
"\r\n",
|
|
"# Import the data into a tibble\r\n",
|
|
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\")\r\n",
|
|
"\r\n",
|
|
"# View the first 5 rows of the data set\r\n",
|
|
"df %>% \r\n",
|
|
" slice_head(n = 5)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"때로는 데이터에 대해 조금 더 많은 정보를 알고 싶을 때가 있습니다. [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html) 함수를 사용하여 `데이터`와 `그 구조`를 살펴볼 수 있습니다:\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Glimpse into the data set\r\n",
|
|
"df %>% \r\n",
|
|
" glimpse()\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"잘했어요!💪\n",
|
|
"\n",
|
|
"`glimpse()`를 사용하면 총 행(관측치)과 열(변수)의 수를 확인할 수 있으며, 변수 이름 뒤에 각 변수의 첫 몇 개 항목이 행 단위로 표시됩니다. 또한, 변수의 *데이터 유형*은 각 변수 이름 바로 뒤에 `< >` 안에 표시됩니다.\n",
|
|
"\n",
|
|
"`DataExplorer::introduce()`는 이 정보를 깔끔하게 요약해줍니다:\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Describe basic information for our data\r\n",
|
|
"df %>% \r\n",
|
|
" introduce()\r\n",
|
|
"\r\n",
|
|
"# A visual display of the same\r\n",
|
|
"df %>% \r\n",
|
|
" plot_intro()\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"멋져요! 우리의 데이터에 누락된 값이 없다는 것을 방금 확인했어요.\n",
|
|
"\n",
|
|
"이 기회에, 일반적인 중심 경향 통계(예: [평균](https://en.wikipedia.org/wiki/Arithmetic_mean)과 [중앙값](https://en.wikipedia.org/wiki/Median)) 및 산포도 측정(예: [표준편차](https://en.wikipedia.org/wiki/Standard_deviation))를 `summarytools::descr()`를 사용하여 탐색해볼 수 있어요.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Describe common statistics\r\n",
|
|
"df %>% \r\n",
|
|
" descr(stats = \"common\")\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"데이터의 일반적인 값을 살펴봅시다. 인기(popularity)가 `0`일 수 있다는 점에 주의하세요. 이는 순위가 없는 곡들을 나타냅니다. 곧 이러한 곡들을 제거할 예정입니다.\n",
|
|
"\n",
|
|
"> 🤔 클러스터링은 라벨이 없는 데이터를 필요로 하지 않는 비지도 학습 방법인데, 왜 라벨이 있는 데이터를 보여주고 있을까요? 데이터 탐색 단계에서는 라벨이 유용할 수 있지만, 클러스터링 알고리즘이 작동하는 데 필수적인 것은 아닙니다.\n",
|
|
"\n",
|
|
"### 1. 인기 있는 장르 탐색\n",
|
|
"\n",
|
|
"이제 가장 인기 있는 장르 🎶를 찾아봅시다. 이를 위해 해당 장르가 등장하는 횟수를 세어보겠습니다.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Popular genres\r\n",
|
|
"top_genres <- df %>% \r\n",
|
|
" count(artist_top_genre, sort = TRUE) %>% \r\n",
|
|
"# Encode to categorical and reorder the according to count\r\n",
|
|
" mutate(artist_top_genre = factor(artist_top_genre) %>% fct_inorder())\r\n",
|
|
"\r\n",
|
|
"# Print the top genres\r\n",
|
|
"top_genres\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"그거 잘 됐네요! 사진 한 장이 데이터 프레임의 천 줄보다 더 가치 있다는 말이 있죠 (사실 아무도 그런 말 안 해요 😅). 하지만 무슨 말인지 감은 오시죠?\n",
|
|
"\n",
|
|
"범주형 데이터(문자형 또는 팩터 변수)를 시각화하는 한 가지 방법은 막대 그래프를 사용하는 것입니다. 상위 10개의 장르를 막대 그래프로 만들어 봅시다:\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Change the default gray theme\r\n",
|
|
"theme_set(theme_light())\r\n",
|
|
"\r\n",
|
|
"# Visualize popular genres\r\n",
|
|
"top_genres %>%\r\n",
|
|
" slice(1:10) %>% \r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5),\r\n",
|
|
" # Rotates the X markers (so we can read them)\r\n",
|
|
" axis.text.x = element_text(angle = 90))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"이제 `missing` 장르가 있다는 것을 훨씬 쉽게 확인할 수 있네요 🧐!\n",
|
|
"\n",
|
|
"> 좋은 시각화는 예상하지 못했던 것을 보여주거나 데이터에 대한 새로운 질문을 제기합니다 - Hadley Wickham과 Garrett Grolemund, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n",
|
|
"\n",
|
|
"참고로, 최상위 장르가 `Missing`으로 표시된 경우, 이는 Spotify가 이를 분류하지 않았다는 것을 의미하므로 제거해 봅시다.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Visualize popular genres\r\n",
|
|
"top_genres %>%\r\n",
|
|
" filter(artist_top_genre != \"Missing\") %>% \r\n",
|
|
" slice(1:10) %>% \r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5),\r\n",
|
|
" # Rotates the X markers (so we can read them)\r\n",
|
|
" axis.text.x = element_text(angle = 90))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"간단한 데이터 탐색을 통해 상위 세 장르가 이 데이터셋에서 큰 비중을 차지한다는 것을 알 수 있습니다. 이제 `afro dancehall`, `afropop`, `nigerian pop`에 집중하고, 인기도 값이 0인 항목(즉, 데이터셋에서 인기도로 분류되지 않았으며 우리의 목적상 노이즈로 간주될 수 있는 항목)을 제거하도록 데이터셋을 필터링해 봅시다.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"nigerian_songs <- df %>% \r\n",
|
|
" # Concentrate on top 3 genres\r\n",
|
|
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \r\n",
|
|
" # Remove unclassified observations\r\n",
|
|
" filter(popularity != 0)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Visualize popular genres\r\n",
|
|
"nigerian_songs %>%\r\n",
|
|
" count(artist_top_genre) %>%\r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"우리 데이터 세트의 수치형 변수들 간에 어떤 명확한 선형 관계가 있는지 살펴봅시다. 이 관계는 [상관 통계량](https://en.wikipedia.org/wiki/Correlation)에 의해 수학적으로 정량화됩니다.\n",
|
|
"\n",
|
|
"상관 통계량은 -1에서 1 사이의 값으로, 관계의 강도를 나타냅니다. 0보다 큰 값은 *양의* 상관관계(한 변수의 값이 높을수록 다른 변수의 값도 높은 경향이 있음)를 나타내며, 0보다 작은 값은 *음의* 상관관계(한 변수의 값이 높을수록 다른 변수의 값이 낮은 경향이 있음)를 나타냅니다.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Narrow down to numeric variables and fid correlation\r\n",
|
|
"corr_mat <- nigerian_songs %>% \r\n",
|
|
" select(where(is.numeric)) %>% \r\n",
|
|
" cor()\r\n",
|
|
"\r\n",
|
|
"# Visualize correlation matrix\r\n",
|
|
"corrplot(corr_mat, order = 'AOE', col = c('white', 'black'), bg = 'gold2') \r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"데이터는 `energy`와 `loudness` 사이에서만 강한 상관관계를 보이며, 이는 큰 소리의 음악이 일반적으로 에너지가 넘친다는 점에서 이해할 수 있습니다. `Popularity`는 `release date`와도 연관이 있는데, 이는 더 최근에 발매된 곡들이 아마도 더 인기가 많을 것이라는 점에서 역시 이해할 수 있습니다. 길이와 에너지 또한 상관관계를 보이는 것 같습니다.\n",
|
|
"\n",
|
|
"이 데이터를 클러스터링 알고리즘이 어떻게 처리할지 보는 것도 흥미로울 것 같습니다!\n",
|
|
"\n",
|
|
"> 🎓 상관관계가 인과관계를 의미하지 않는다는 점을 유념하세요! 우리는 상관관계의 증거는 있지만 인과관계의 증거는 없습니다. 이 점을 강조하는 [재미있는 웹사이트](https://tylervigen.com/spurious-correlations)가 몇 가지 시각 자료를 제공하고 있습니다.\n",
|
|
"\n",
|
|
"### 2. 데이터 분포 탐색\n",
|
|
"\n",
|
|
"좀 더 미묘한 질문을 던져봅시다. 장르별로 인기도를 기준으로 춤 가능성에 대한 인식이 크게 다를까요? 주어진 x축과 y축을 따라 [밀도 그래프](https://www.khanacademy.org/math/ap-statistics/density-curves-normal-distribution-ap/density-curves/v/density-curves)를 사용하여 상위 세 개 장르의 인기도와 춤 가능성에 대한 데이터 분포를 살펴보겠습니다.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Perform 2D kernel density estimation\r\n",
|
|
"density_estimate_2d <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre)) +\r\n",
|
|
" geom_density_2d(bins = 5, size = 1) +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" xlim(-20, 80) +\r\n",
|
|
" ylim(0, 1.2)\r\n",
|
|
"\r\n",
|
|
"# Density plot based on the popularity\r\n",
|
|
"density_estimate_pop <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, fill = artist_top_genre, color = artist_top_genre)) +\r\n",
|
|
" geom_density(size = 1, alpha = 0.5) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" theme(legend.position = \"none\")\r\n",
|
|
"\r\n",
|
|
"# Density plot based on the danceability\r\n",
|
|
"density_estimate_dance <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = danceability, fill = artist_top_genre, color = artist_top_genre)) +\r\n",
|
|
" geom_density(size = 1, alpha = 0.5) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Patch everything together\r\n",
|
|
"library(patchwork)\r\n",
|
|
"density_estimate_2d / (density_estimate_pop + density_estimate_dance)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"우리는 장르에 상관없이 동심원이 정렬되는 것을 볼 수 있습니다. 이 장르에서 나이지리아인의 취향이 특정 수준의 춤추기 좋은 정도에서 수렴하는 것일까요?\n",
|
|
"\n",
|
|
"일반적으로, 세 가지 장르는 인기도와 춤추기 좋은 정도 측면에서 일치합니다. 이 느슨하게 정렬된 데이터에서 클러스터를 결정하는 것은 도전 과제가 될 것입니다. 산점도가 이를 뒷받침할 수 있는지 확인해 봅시다.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# A scatter plot of popularity and danceability\r\n",
|
|
"scatter_plot <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre, shape = artist_top_genre)) +\r\n",
|
|
" geom_point(size = 2, alpha = 0.8) +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"futurevisions::mars\")\r\n",
|
|
"\r\n",
|
|
"# Add a touch of interactivity\r\n",
|
|
"ggplotly(scatter_plot)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"같은 축의 산점도는 유사한 수렴 패턴을 보여줍니다.\n",
|
|
"\n",
|
|
"일반적으로, 클러스터링을 위해 산점도를 사용하여 데이터의 클러스터를 시각화할 수 있습니다. 따라서 이러한 유형의 시각화를 숙달하는 것은 매우 유용합니다. 다음 강의에서는 이 필터링된 데이터를 사용하여 k-평균 클러스터링을 통해 흥미로운 방식으로 겹치는 그룹을 발견할 것입니다.\n",
|
|
"\n",
|
|
"## **🚀 도전 과제**\n",
|
|
"\n",
|
|
"다음 강의를 준비하며, 프로덕션 환경에서 발견하고 사용할 수 있는 다양한 클러스터링 알고리즘에 대한 차트를 만들어 보세요. 클러스터링이 해결하려는 문제는 어떤 종류인가요?\n",
|
|
"\n",
|
|
"## [**강의 후 퀴즈**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/28/)\n",
|
|
"\n",
|
|
"## **복습 및 자기 학습**\n",
|
|
"\n",
|
|
"우리가 배운 것처럼, 클러스터링 알고리즘을 적용하기 전에 데이터셋의 특성을 이해하는 것이 중요합니다. 이 주제에 대해 더 알아보세요: [여기](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html)\n",
|
|
"\n",
|
|
"클러스터링 기법에 대한 이해를 심화하세요:\n",
|
|
"\n",
|
|
"- [Tidymodels와 관련 도구를 사용하여 클러스터링 모델 학습 및 평가하기](https://rpubs.com/eR_ic/clustering)\n",
|
|
"\n",
|
|
"- Bradley Boehmke & Brandon Greenwell, [*Hands-On Machine Learning with R*](https://bradleyboehmke.github.io/HOML/)*.*\n",
|
|
"\n",
|
|
"## **과제**\n",
|
|
"\n",
|
|
"[클러스터링을 위한 다른 시각화 방법 조사하기](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/assignment.md)\n",
|
|
"\n",
|
|
"## 감사의 말씀:\n",
|
|
"\n",
|
|
"[Jen Looper](https://www.twitter.com/jenlooper) - 이 모듈의 원래 Python 버전을 만들어 주신 분 ♥️\n",
|
|
"\n",
|
|
"[`Dasani Madipalli`](https://twitter.com/dasani_decoded) - 머신러닝 개념을 더 쉽게 이해할 수 있도록 멋진 일러스트를 제작해 주신 분.\n",
|
|
"\n",
|
|
"즐거운 학습 되세요,\n",
|
|
"\n",
|
|
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**면책 조항**: \n이 문서는 AI 번역 서비스 [Co-op Translator](https://github.com/Azure/co-op-translator)를 사용하여 번역되었습니다. 정확성을 위해 최선을 다하고 있으나, 자동 번역에는 오류나 부정확성이 포함될 수 있습니다. 원본 문서(원어로 작성된 문서)를 권위 있는 자료로 간주해야 합니다. 중요한 정보의 경우, 전문적인 인간 번역을 권장합니다. 이 번역 사용으로 인해 발생하는 오해나 잘못된 해석에 대해 당사는 책임을 지지 않습니다. \n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"anaconda-cloud": "",
|
|
"kernelspec": {
|
|
"display_name": "R",
|
|
"language": "R",
|
|
"name": "ir"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": "r",
|
|
"file_extension": ".r",
|
|
"mimetype": "text/x-r-source",
|
|
"name": "R",
|
|
"pygments_lexer": "r",
|
|
"version": "3.4.1"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "99c36449cad3708a435f6798cfa39972",
|
|
"translation_date": "2025-09-04T02:03:56+00:00",
|
|
"source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb",
|
|
"language_code": "ko"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
} |