k-meansクラスタリングにおいて最適なクラスター数を決定する際、エルボー法(Elbow Method)は最も一般的で直感的な手法です。この記事では、Stataを使ってエルボー法を実装し、WSS(Within-cluster Sum of Squares)をもとに最適なクラスター数を決定する方法を詳しく解説します。 ## エルボー法とは エルボー法は、異なるクラスター数でk-meansクラスタリングを実行し、各クラスター数におけるWSS(クラスター内平方和)をプロットする手法です。WSSの減少が急激から緩やかに変わる点(「肘」のように見える点)が最適なクラスター数とされます。 ## 完全なコード 以下のコードをStataにコピペして実行してください: ```stata * K-means クラスタリング:エルボー法による最適クラスター数の決定 * auto.dta を使用 clear all set more off * データの読み込み sysuse auto, clear * 分析に使用する変数を標準化(price, mpg, weight, length を使用) * 欠損値を除外 drop if missing(price) | missing(mpg) | missing(weight) | missing(length) * 標準化のための変数作成 egen zprice = std(price) egen zmpg = std(mpg) egen zweight = std(weight) egen zlength = std(length) * WSS結果を保存するマトリックス準備 matrix wss_results = J(10, 2, .) * k=1から10まで各クラスター数でk-meansを実行しWSSを計算 forvalues k = 1/10 { quietly { * k-means クラスタリング実行 cluster kmeans zprice zmpg zweight zlength, k(`k') name(cluster_k`k') * 各観測値のクラスター重心からの距離の二乗を計算 tempvar wss_temp gen `wss_temp' = 0 * 各クラスターについて重心を計算しWSSを求める forvalues c = 1/`k' { * クラスターcの重心を計算 sum zprice if cluster_k`k' == `c' local mean_price = r(mean) sum zmpg if cluster_k`k' == `c' local mean_mpg = r(mean) sum zweight if cluster_k`k' == `c' local mean_weight = r(mean) sum zlength if cluster_k`k' == `c' local mean_length = r(mean) * クラスターc内の各点から重心までの距離の二乗を計算 replace `wss_temp' = `wss_temp' + /// (zprice - `mean_price')^2 + /// (zmpg - `mean_mpg')^2 + /// (zweight - `mean_weight')^2 + /// (zlength - `mean_length')^2 /// if cluster_k`k' == `c' } * 総WSSを計算 sum `wss_temp' local total_wss = r(sum) * マトリックスに結果を保存 matrix wss_results[`k', 1] = `k' matrix wss_results[`k', 2] = `total_wss' * クラスター変数を削除(次の反復のため) drop cluster_k`k' `wss_temp' } display "k = `k' completed" } * 結果をデータセットに変換 drop _all svmat wss_results, names(col) rename c1 k rename c2 wss * WSS値の表示 list * エルボープロットの作成 twoway connected wss k, /// title("Elbow Method for Optimal Number of Clusters") /// xtitle("Number of Clusters (k)") /// ytitle("Within-cluster Sum of Squares (WSS)") /// xlabel(1(1)10) display "" display "エルボープロットを確認して、曲線が「肘」のように曲がる点を見つけてください。" display "その点が最適なクラスター数(k)です。" ``` ## 結果の見方 コードを実行すると、k=1から10までのWSS値の表と、エルボープロットが表示されます。プロット上で曲線が急激な減少から緩やかな減少に変わる点(肘のように見える点)が最適なクラスター数です。 ## 詳細な解説 ### 1. データ準備 ```stata sysuse auto, clear drop if missing(price) | missing(mpg) | missing(weight) | missing(length) ``` Stataの標準データセットauto.dtaを読み込み、分析に使用する4つの変数(price, mpg, weight, length)に欠損値がある観測値を除外します。 ### 2. 変数の標準化 ```stata egen zprice = std(price) egen zmpg = std(mpg) egen zweight = std(weight) egen zlength = std(length) ``` k-meansクラスタリングでは変数のスケールが結果に大きく影響するため、すべての変数を標準化(平均0、標準偏差1)します。`egen`コマンドの`std()`関数を使用しています。 ### 3. 結果保存用マトリックス ```stata matrix wss_results = J(10, 2, .) ``` WSS結果を保存するため、10行2列のマトリックスを作成します。1列目にクラスター数k、2列目にWSSを保存します。 ### 4. メインループ ```stata forvalues k = 1/10 { quietly { cluster kmeans zprice zmpg zweight zlength, k(`k') name(cluster_k`k') ... } } ``` k=1から10まで、各クラスター数でk-meansクラスタリングを実行します。`quietly`オプションで中間出力を抑制しています。 ### 5. WSS計算 ```stata forvalues c = 1/`k' { sum zprice if cluster_k`k' == `c' local mean_price = r(mean) ... replace `wss_temp' = `wss_temp' + /// (zprice - `mean_price')^2 + /// (zmpg - `mean_mpg')^2 + /// (zweight - `mean_weight')^2 + /// (zlength - `mean_length')^2 /// if cluster_k`k' == `c' } ``` 各クラスターについて重心を計算し、各観測値から重心までの距離の二乗和を求めます。これがWSSの定義です。 ### 6. データセット変換とプロット ```stata svmat wss_results, names(col) rename c1 k rename c2 wss twoway connected wss k, ... ``` マトリックスをデータセットに変換し、変数名を設定してからプロットを作成します。`connected`オプションで線とマーカーの両方を表示します。 ## 応用のためのヒント ### 他のデータセットに応用する場合 このコードを他のデータセットに応用したい場合は、以下の部分を変更するだけです: 1. **データ読み込み部分**:`sysuse auto, clear` を自分のデータファイルに変更 2. **変数選択部分**:`price mpg weight length` を分析したい変数に変更 3. **クラスター数の範囲**:必要に応じて `forvalues k = 1/10` の範囲を調整 ### ChatGPTやClaude等のAIアシスタントを活用する ご自身のデータや分析要件に合わせてコードを修正したい場合は、このコードをChatGPTやClaude等に貼り付けて「このコードと同じようにして、自分のデータセット(データの詳細を説明)でエルボー法を実行したい」と依頼すると、適切に修正されたコードを提供してもらえます。 例:「このコードと同じようにして、売上データ(変数:売上高、広告費、従業員数)でクラスタリングしたい」など、具体的な変数名や要件を伝えると効果的です。 ## まとめ エルボー法は最適クラスター数決定の標準的手法です。このStataコードを使えば、簡単にエルボープロットを作成し、データに最適なクラスター数を視覚的に判断できます。重要なのはプロットの形状を注意深く観察し、急激な減少から緩やかな減少に変わる点を見つけることです。