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.
ML-For-Beginners/translations/ja/5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb

637 lines
31 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"nbformat": 4,
"nbformat_minor": 0,
"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"
},
"colab": {
"name": "lesson_14.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"coopTranslator": {
"original_hash": "ad65fb4aad0a156b42216e4929f490fc",
"translation_date": "2025-09-04T02:15:24+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "ja"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## RとTidyデータの原則を使ったK-Meansクラスタリングの探求\n",
"\n",
"### [**講義前クイズ**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"このレッスンでは、TidymodelsパッケージやRエコシステム内の他のパッケージ友達と呼びましょう 🧑🤝🧑を使ってクラスタを作成する方法と、以前インポートしたナイジェリア音楽データセットを使用する方法を学びます。K-Meansクラスタリングの基本について説明します。前のレッスンで学んだように、クラスタを扱う方法は多岐にわたり、使用する方法はデータに依存します。ここでは、最も一般的なクラスタリング手法であるK-Meansを試してみましょう。それでは始めましょう\n",
"\n",
"このレッスンで学ぶ用語:\n",
"\n",
"- シルエットスコアリング\n",
"- エルボー法\n",
"- 慣性Inertia\n",
"- 分散Variance\n",
"\n",
"### **イントロダクション**\n",
"\n",
"[K-Meansクラスタリング](https://wikipedia.org/wiki/K-means_clustering)は、信号処理の分野から派生した手法です。この手法は、データの特徴の類似性に基づいて、データを`k個のクラスタ`に分割・区分するために使用されます。\n",
"\n",
"クラスタは、[ボロノイ図](https://wikipedia.org/wiki/Voronoi_diagram)として視覚化することができ、これは点(または「シード」)とその対応する領域を含みます。\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Jen Looperによるインフォグラフィック</figcaption>\n",
"\n",
"K-Meansクラスタリングの手順は以下の通りです:\n",
"\n",
"1. データサイエンティストが作成したいクラスタの数を指定します。\n",
"\n",
"2. 次に、アルゴリズムがデータセットからランダムにK個の観測値を選択し、それをクラスタの初期中心すなわちセントロイドとして使用します。\n",
"\n",
"3. 次に、残りの各観測値を最も近いセントロイドに割り当てます。\n",
"\n",
"4. 次に、各クラスタの新しい平均を計算し、セントロイドをその平均に移動させます。\n",
"\n",
"5. セントロイドが再計算されたので、すべての観測値を再度確認し、別のクラスタに近いかどうかを確認します。すべてのオブジェクトは、更新されたクラスタ平均を使用して再割り当てされます。このクラスタ割り当てとセントロイド更新のステップは、クラスタ割り当てが変化しなくなるまで(すなわち、収束が達成されるまで)繰り返されます。通常、各新しい反復でセントロイドの移動がわずかになり、クラスタが静的になるとアルゴリズムは終了します。\n",
"\n",
"<div>\n",
"\n",
"> 初期のk個の観測値をランダムに選択するため、手順を適用するたびに結果が若干異なる可能性があることに注意してください。このため、ほとんどのアルゴリズムでは複数の*ランダムスタート*を使用し、最も低いWCSSを持つ反復を選択します。そのため、*望ましくない局所最適解*を避けるために、常に複数の*nstart*値でK-Meansを実行することを強くお勧めします。\n",
"\n",
"</div>\n",
"\n",
"この短いアニメーションは、Allison Horstの[アートワーク](https://github.com/allisonhorst/stats-illustrations)を使用してクラスタリングプロセスを説明しています:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>@allison_horstによるアートワーク</figcaption>\n",
"\n",
"クラスタリングにおいて基本的な疑問が生じます。それは、データをいくつのクラスタに分けるべきかということです。K-Meansの欠点の1つは、`k`、つまり`セントロイド`の数を事前に決める必要がある点です。幸いなことに、`エルボー法`を使えば、`k`の良い初期値を推定するのに役立ちます。これをすぐに試してみましょう。\n",
"\n",
"### \n",
"\n",
"**前提条件**\n",
"\n",
"[前回のレッスン](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb)でデータセットを分析し、多くの可視化を行い、興味のある観測値にデータセットをフィルタリングしました。このレッスンをぜひ確認してください!\n",
"\n",
"このモジュールを進めるにはいくつかのパッケージが必要です。以下のコマンドでインストールできます: \n",
"`install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"または、以下のスクリプトを使用すると、このモジュールを完了するために必要なパッケージがインストールされているか確認し、不足している場合は自動的にインストールします。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "ah_tBi58LXyi"
},
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork')\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "7e--UCUTLXym"
},
"source": [
"さあ、始めましょう!\n",
"\n",
"## 1. データとのダンス: 最も人気のある音楽ジャンルを3つに絞る\n",
"\n",
"これは前回のレッスンで行った内容の復習です。データを切り分けて分析してみましょう!\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Ycamx7GGLXyn"
},
"source": [
"# Load the core tidyverse and make it available in your current R session\n",
"library(tidyverse)\n",
"\n",
"# Import the data into a tibble\n",
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\", show_col_types = FALSE)\n",
"\n",
"# Narrow down to top 3 popular genres\n",
"nigerian_songs <- df %>% \n",
" # Concentrate on top 3 genres\n",
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \n",
" # Remove unclassified observations\n",
" filter(popularity != 0)\n",
"\n",
"\n",
"\n",
"# Visualize popular genres using bar plots\n",
"theme_set(theme_light())\n",
"nigerian_songs %>%\n",
" count(artist_top_genre) %>%\n",
" ggplot(mapping = aes(x = artist_top_genre, y = n,\n",
" fill = artist_top_genre)) +\n",
" geom_col(alpha = 0.8) +\n",
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\n",
" ggtitle(\"Top genres\") +\n",
" theme(plot.title = element_text(hjust = 0.5))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "b5h5zmkPLXyp"
},
"source": [
"🤩 これはうまくいきましたね!\n",
"\n",
"## 2. データをさらに探索する\n",
"\n",
"このデータはどれくらいクリーンでしょうか?ボックスプロットを使って外れ値を確認してみましょう。外れ値が少ない数値列に注目します(もちろん、外れ値を除去することも可能です)。ボックスプロットはデータの範囲を示し、どの列を使用するか選ぶのに役立ちます。ただし、ボックスプロットは分散を示さないため、クラスタリングに適したデータを評価する上で重要な要素である分散については別途考慮が必要です。詳しくは[この議論](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot)をご覧ください。\n",
"\n",
"[ボックスプロット](https://en.wikipedia.org/wiki/Box_plot)は、`数値`データの分布を視覚的に表現するために使用されます。それでは、人気のある音楽ジャンルとともに、すべての数値列を*選択*することから始めましょう。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "HhNreJKLLXyq"
},
"source": [
"# Select top genre column and all other numeric columns\n",
"df_numeric <- nigerian_songs %>% \n",
" select(artist_top_genre, where(is.numeric)) \n",
"\n",
"# Display the data\n",
"df_numeric %>% \n",
" slice_head(n = 5)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "uYXrwJRaLXyq"
},
"source": [
"選択ヘルパー`where`がどれだけ簡単にしてくれるか分かりますか💁?他の便利な関数については[こちら](https://tidyselect.r-lib.org/)をチェックしてください。\n",
"\n",
"数値特徴ごとにボックスプロットを作成する予定ですが、ループを使うのは避けたいので、データを*縦長*の形式に再整形しましょう。これにより、`facets`(データの各サブセットを表示するサブプロット)を活用できるようになります。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "gd5bR3f8LXys"
},
"source": [
"# Pivot data from wide to long\n",
"df_numeric_long <- df_numeric %>% \n",
" pivot_longer(!artist_top_genre, names_to = \"feature_names\", values_to = \"values\") \n",
"\n",
"# Print out data\n",
"df_numeric_long %>% \n",
" slice_head(n = 15)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "-7tE1swnLXyv"
},
"source": [
"もっと長くなります!さあ、`ggplot`を使う時間です!では、どの`geom`を使いましょうか?\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "r88bIsyuLXyy"
},
"source": [
"# Make a box plot\n",
"df_numeric_long %>% \n",
" ggplot(mapping = aes(x = feature_names, y = values, fill = feature_names)) +\n",
" geom_boxplot() +\n",
" facet_wrap(~ feature_names, ncol = 4, scales = \"free\") +\n",
" theme(legend.position = \"none\")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "EYVyKIUELXyz"
},
"source": [
"簡単だね!\n",
"\n",
"さて、このデータは少しノイズがあることがわかります。各列をボックスプロットで観察すると、外れ値が見られます。この外れ値をデータセットから取り除くこともできますが、それではデータがかなり少なくなってしまいます。\n",
"\n",
"とりあえず、クラスタリングの演習で使用する列を選びましょう。範囲が似ている数値列を選びます。`artist_top_genre`を数値にエンコードすることもできますが、今回はそれを除外します。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "-wkpINyZLXy0"
},
"source": [
"# Select variables with similar ranges\n",
"df_numeric_select <- df_numeric %>% \n",
" select(popularity, danceability, acousticness, loudness, energy) \n",
"\n",
"# Normalize data\n",
"# df_numeric_select <- scale(df_numeric_select)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "D7dLzgpqLXy1"
},
"source": [
"## 3. Rでk-meansクラスタリングを計算する\n",
"\n",
"Rでは、組み込みの`kmeans`関数を使用してk-meansを計算できます。詳細は`help(\"kmeans()\")`を参照してください。`kmeans()`関数は、すべての列が数値型であるデータフレームを主な引数として受け取ります。\n",
"\n",
"k-meansクラスタリングを使用する際の最初のステップは、最終的なソリューションで生成されるクラスタ数kを指定することです。データセットから抽出した3つの音楽ジャンルがあることを知っているので、3を試してみましょう:\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "uC4EQ5w7LXy5"
},
"source": [
"set.seed(2056)\n",
"# Kmeans clustering for 3 clusters\n",
"kclust <- kmeans(\n",
" df_numeric_select,\n",
" # Specify the number of clusters\n",
" centers = 3,\n",
" # How many random initial configurations\n",
" nstart = 25\n",
")\n",
"\n",
"# Display clustering object\n",
"kclust\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "hzfhscWrLXy-"
},
"source": [
"kmeansオブジェクトには、`help(\"kmeans()\")`で詳しく説明されているいくつかの情報が含まれています。ここでは、その中のいくつかに焦点を当ててみましょう。このデータは、サイズがそれぞれ65、110、111の3つのクラスターにグループ化されていることがわかります。また、出力には、5つの変数にわたる3つのグループのクラスター中心平均値も含まれています。\n",
"\n",
"クラスタリングベクトルは、各観測値のクラスター割り当てを示しています。`augment`関数を使用して、元のデータセットにクラスター割り当てを追加してみましょう。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "0XwwpFGQLXy_"
},
"source": [
"# Add predicted cluster assignment to data set\n",
"augment(kclust, df_numeric_select) %>% \n",
" relocate(.cluster) %>% \n",
" slice_head(n = 10)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "NXIVXXACLXzA"
},
"source": [
"完璧ですこれでデータセットを3つのグループに分割しました。それでは、クラスタリングの結果はどれくらい良いのでしょうか 🤷?`Silhouetteスコア`を見てみましょう。\n",
"\n",
"### **Silhouetteスコア**\n",
"\n",
"[Silhouette分析](https://en.wikipedia.org/wiki/Silhouette_(clustering))は、得られたクラスタ間の分離距離を調べるために使用できます。このスコアは-1から1の範囲で変動し、スコアが1に近い場合、クラスタは密集しており、他のクラスタと明確に分離されています。一方、スコアが0に近い場合、クラスタは重なり合っており、サンプルが隣接するクラスタの境界付近に非常に近いことを示します。[参考](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam)。\n",
"\n",
"平均Silhouette法では、異なる*k*の値に対して観測値の平均Silhouetteを計算します。平均Silhouetteスコアが高いほど、良好なクラスタリングを示します。\n",
"\n",
"クラスタパッケージの`silhouette`関数を使用して、平均Silhouette幅を計算します。\n",
"\n",
"> Silhouetteは、[ユークリッド距離](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\")や[マンハッタン距離](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\")など、任意の[距離](https://en.wikipedia.org/wiki/Distance \"Distance\")メトリックで計算することができます。これらの距離については[前のレッスン](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb)で説明しました。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Jn0McL28LXzB"
},
"source": [
"# Load cluster package\n",
"library(cluster)\n",
"\n",
"# Compute average silhouette score\n",
"ss <- silhouette(kclust$cluster,\n",
" # Compute euclidean distance\n",
" dist = dist(df_numeric_select))\n",
"mean(ss[, 3])\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "QyQRn97nLXzC"
},
"source": [
"私たちのスコアは **.549** で、ちょうど中間に位置しています。これは、私たちのデータがこのタイプのクラスタリングに特に適しているわけではないことを示しています。この推測を視覚的に確認できるかどうか見てみましょう。[factoextra パッケージ](https://rpkgs.datanovia.com/factoextra/index.html)は、クラスタリングを視覚化するための関数(`fviz_cluster()`)を提供しています。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "7a6Km1_FLXzD"
},
"source": [
"library(factoextra)\n",
"\n",
"# Visualize clustering results\n",
"fviz_cluster(kclust, df_numeric_select)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "IBwCWt-0LXzD"
},
"source": [
"クラスターの重なりは、今回のデータがこのタイプのクラスタリングに特に適していないことを示していますが、続けてみましょう。\n",
"\n",
"## 4. 最適なクラスター数の決定\n",
"\n",
"K-Meansクラスタリングでよく出てくる基本的な疑問の一つは、「既知のクラスラベルがない場合、データをいくつのクラスターに分ければよいのか」という点です。\n",
"\n",
"これを調べる一つの方法として、データサンプルを使って`クラスター数を増やしながら一連のクラスタリングモデルを作成`(例: 110までし、**シルエットスコア**のようなクラスタリング指標を評価する方法があります。\n",
"\n",
"最適なクラスター数を決定するために、異なる*k*の値に対してクラスタリングアルゴリズムを計算し、**クラスター内平方和WCSS: Within Cluster Sum of Squares**を評価してみましょう。クラスター内平方和WCSSはクラスタリングのコンパクトさを測る指標で、値が小さいほどデータポイントが近いことを意味します。そのため、WCSSはできるだけ小さい方が望ましいです。\n",
"\n",
"それでは、1から10までの異なる`k`の選択がこのクラスタリングに与える影響を調べてみましょう。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "hSeIiylDLXzE"
},
"source": [
"# Create a series of clustering models\n",
"kclusts <- tibble(k = 1:10) %>% \n",
" # Perform kmeans clustering for 1,2,3 ... ,10 clusters\n",
" mutate(model = map(k, ~ kmeans(df_numeric_select, centers = .x, nstart = 25)),\n",
" # Farm out clustering metrics eg WCSS\n",
" glanced = map(model, ~ glance(.x))) %>% \n",
" unnest(cols = glanced)\n",
" \n",
"\n",
"# View clustering rsulsts\n",
"kclusts\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "m7rS2U1eLXzE"
},
"source": [
"各クラスタリングアルゴリズムにおける中心 *k* の総クラスタ内平方和 (tot.withinss) を求めたので、[肘法](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) を使用して最適なクラスタ数を見つけます。この方法では、クラスタ数の関数としてWCSSをプロットし、[曲線の肘](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") をクラスタ数として選択します。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "o_DjHGItLXzF"
},
"source": [
"set.seed(2056)\n",
"# Use elbow method to determine optimum number of clusters\n",
"kclusts %>% \n",
" ggplot(mapping = aes(x = k, y = tot.withinss)) +\n",
" geom_line(size = 1.2, alpha = 0.8, color = \"#FF7F0EFF\") +\n",
" geom_point(size = 2, color = \"#FF7F0EFF\")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "pLYyt5XSLXzG"
},
"source": [
"プロットは、クラスタ数が1から2に増加するにつれてWCSSが大幅に減少つまり、*密集度*が向上し、さらに2から3クラスタへの増加でも顕著な減少を示しています。その後、減少はそれほど顕著ではなくなり、約3クラスタのところでチャートに`肘` 💪が現れます。これは、データポイントが23の適度に分離されたクラスタに分かれている良い指標です。\n",
"\n",
"ここで、`k = 3`のクラスタリングモデルを抽出する準備が整いました:\n",
"\n",
"> `pull()`: 単一の列を抽出するために使用\n",
">\n",
"> `pluck()`: リストなどのデータ構造をインデックスするために使用\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "JP_JPKBILXzG"
},
"source": [
"# Extract k = 3 clustering\n",
"final_kmeans <- kclusts %>% \n",
" filter(k == 3) %>% \n",
" pull(model) %>% \n",
" pluck(1)\n",
"\n",
"\n",
"final_kmeans\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "l_PDTu8tLXzI"
},
"source": [
"素晴らしいですね!取得したクラスターを視覚化してみましょう。`plotly`を使ってインタラクティブにしてみませんか?\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "dNcleFe-LXzJ"
},
"source": [
"# Add predicted cluster assignment to data set\n",
"results <- augment(final_kmeans, df_numeric_select) %>% \n",
" bind_cols(df_numeric %>% select(artist_top_genre)) \n",
"\n",
"# Plot cluster assignments\n",
"clust_plt <- results %>% \n",
" ggplot(mapping = aes(x = popularity, y = danceability, color = .cluster, shape = artist_top_genre)) +\n",
" geom_point(size = 2, alpha = 0.8) +\n",
" paletteer::scale_color_paletteer_d(\"ggthemes::Tableau_10\")\n",
"\n",
"ggplotly(clust_plt)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "6JUM_51VLXzK"
},
"source": [
"おそらく、各クラスタ(異なる色で表される)がそれぞれ異なるジャンル(異なる形で表される)を持つことを期待していたかもしれません。\n",
"\n",
"モデルの精度を確認してみましょう。\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "HdIMUGq7LXzL"
},
"source": [
"# Assign genres to predefined integers\n",
"label_count <- results %>% \n",
" group_by(artist_top_genre) %>% \n",
" mutate(id = cur_group_id()) %>% \n",
" ungroup() %>% \n",
" summarise(correct_labels = sum(.cluster == id))\n",
"\n",
"\n",
"# Print results \n",
"cat(\"Result:\", label_count$correct_labels, \"out of\", nrow(results), \"samples were correctly labeled.\")\n",
"\n",
"cat(\"\\nAccuracy score:\", label_count$correct_labels/nrow(results))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "C50wvaAOLXzM"
},
"source": [
"このモデルの精度は悪くはありませんが、特別良いとも言えません。このデータは、K-Meansクラスタリングに適していない可能性があります。データが不均衡で、相関が少なく、列の値の間に大きな分散があるため、うまくクラスタリングできないのです。実際、形成されるクラスタは、上で定義した3つのジャンルカテゴリに大きく影響されている、または偏っている可能性が高いです。\n",
"\n",
"それでも、これは非常に学びの多いプロセスでした!\n",
"\n",
"Scikit-learnのドキュメントでは、このようにクラスタがあまり明確に区別されていないモデルは「分散」の問題を抱えていると説明されています。\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Scikit-learnのインフォグラフィック</figcaption>\n",
"\n",
"\n",
"\n",
"## **分散**\n",
"\n",
"分散は、「平均からの二乗差の平均」と定義されます [出典](https://www.mathsisfun.com/data/standard-deviation.html)。このクラスタリング問題の文脈では、データセットの数値が平均から少し離れすぎる傾向があることを指します。\n",
"\n",
"✅ ここで、この問題を解決するためのさまざまな方法を考える良い機会です。データをもう少し調整しますか?別の列を使用しますか?別のアルゴリズムを試しますか?ヒント: データを正規化するために[スケーリング](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/)を試し、他の列をテストしてみてください。\n",
"\n",
"> この '[分散計算機](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' を使って、概念をもう少し理解してみてください。\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀チャレンジ**\n",
"\n",
"このノートブックで時間をかけてパラメータを調整してみてください。データをさらにクリーンアップする(例えば外れ値を削除する)ことで、モデルの精度を向上させることができますか?特定のデータサンプルに重みを付けることもできます。他にどのような方法でより良いクラスタを作成できますか?\n",
"\n",
"ヒント: データをスケーリングしてみてください。ノートブックには、データ列を範囲的により似たものにするための標準スケーリングを追加するコメント付きコードがあります。シルエットスコアは下がりますが、エルボーグラフの「折れ目」が滑らかになります。これは、データをスケーリングしないままにすると、分散の少ないデータがより大きな重みを持つようになるためです。この問題についてもう少し読みたい場合は、[こちら](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226)をご覧ください。\n",
"\n",
"## [**講義後のクイズ**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **復習と自己学習**\n",
"\n",
"- K-Meansシミュレーター [こちら](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/) を見てみてください。このツールを使ってサンプルデータポイントを視覚化し、そのセントロイドを決定できます。データのランダム性、クラスタ数、セントロイド数を編集できます。これにより、データがどのようにグループ化できるかのアイデアが得られますか?\n",
"\n",
"- また、スタンフォード大学の [K-Meansに関するハンドアウト](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) も見てみてください。\n",
"\n",
"K-Meansクラスタリングに適したデータセットで新たに習得したクラスタリングスキルを試してみたいですか以下をご覧ください\n",
"\n",
"- [クラスタリングモデルのトレーニングと評価](https://rpubs.com/eR_ic/clustering)Tidymodelsとその関連ツールを使用\n",
"\n",
"- [K-meansクラスタ分析](https://uc-r.github.io/kmeans_clustering)、UC Business Analytics R Programming Guide\n",
"\n",
"- [tidyデータの原則を用いたK-meansクラスタリング](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **課題**\n",
"\n",
"[異なるクラスタリング手法を試してみる](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## 感謝の言葉:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) さん、Python版のオリジナルモジュールを作成していただきありがとうございます ♥️\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) さん、Rをより親しみやすく魅力的にする素晴らしいイラストを作成していただきありがとうございます。彼女の[ギャラリー](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM)でさらに多くのイラストをご覧ください。\n",
"\n",
"楽しい学びを!\n",
"\n",
"[Eric](https://twitter.com/ericntay)、Gold Microsoft Learn Student Ambassador\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"500\"/>\n",
" <figcaption>@allison_horstによるアートワーク</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免責事項**: \nこの文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確さが含まれる可能性があります。元の言語で記載された原文が正式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当社は一切の責任を負いません。\n"
]
}
]
}