Amazon Web Services ブログ

Amazon SageMaker を使用して、人口区分のために米国の国勢調査データを分析する

米国では 2018 年の中間選挙に向けて、人々は投票プロセスについてより多くの情報を求めています。このブログ記事では、有権者を理解するタスクに科学を有効に統合するために、機械学習 (ML) を適用する方法を探っています。

通常、機械学習アプリケーションでは、ラベルの付いたデータから明確なユースケースが得られます。例えば、古さや型番などデバイスの属性に基づいて、障害の可能性を予測できます。特定の結果を予測する際に監督またはガイドがあるため、これは教師あり学習と呼ばれます。

しかし、現実世界では、きれいなラベルを定義するのが難しい場合、予測する特定の結果が存在しない大規模なデータセットがしばしば存在します。適切な結果が予測するものを、正確に特定することは困難です。この種類のユースケースはしばしば探索的です。これはデータセットの作成と、どのような自然パターンが存在するかを理解することが目的です。この種類のユースケースは、教師なし学習です。この一例は、属性セットに基づいて類似の個人をグループ化する試みです。

このブログ記事で紹介するユースケースは、人口区分です。私たちは次のサイトから一般公開されている、米国の国勢調査から得られた米国の郡ごと匿名化された人口統計データを入手できます。この製品は Census Bureau Data API を使用していますが、国勢調査局による保証または認定は行われていません。この分析結果は、変換された特徴空間における類似した郡の自然なグループ化です。例えば、ある集団に共鳴するメッセージをハイライトすることで、類似する郡のグループに到達する方法を理解するなど、郡が所属するクラスターを活用して選挙運動を計画することが可能です。より一般的には、この技術は企業が対象を定めたマーケティングキャンペーンを作成するために、顧客やユーザー区分に対して適用できます。この種類の分析には、CA-Fresno 郡と AZ-Yuma 郡という同じグループにされた、表向きは分からない類似点を明らかにする能力があります。直感的には人口サイズや人種構成など一般的に調べられる属性が異なりますが、雇用タイプの組み合わせなど、軸に沿って調べたときには類似しています。

ブログ記事に従って、サンプルノートブックを使用してコードを実行し、データをやり取りすることができます。

この演習には 2 つの目標があります。

1) PCA と Kmeans モデリング技術を使用して教師なし学習のための Amazon SageMaker を使用したデータ科学ワークフローを説明する。

2) 有用なモデル属性を抽出するために、Amazon SageMaker 内に構築された基礎モデルにユーザーがどのようにアクセスできるかを説明する。教師なし学習から結論を引き出すことが難しい場合が往々にしてあり、PCA と Kmeans のモデルにアクセスできることが単にモデルを使用して予測を生成する以上に重要になります。

データ科学ワークフローには 4 つのメインステップがあります。

  1. Amazon S3 からのデータの読み込み
  2. 探索的データ分析 (EDA) – データのクリーニングと探索
    • データのクリーニング
    • データの可視化
    • 特徴エンジニアリング
  3. データモデリング
    • 次元縮退
    • PCA モデル属性へのアクセス
    • PCA モデルのデプロイ
    • 教師なしクラスタリングを使用した人口区分
  4. モデリングから結論を導く
    • KMeans モデル属性へのアクセス

ステップ 1: Amazon S3 からのデータの読み込み

Amazon S3 バケットから Amazon SageMaker ノートブックにデータセットを読み込む必要があります。

AWS コンソールから AWS SageMaker ノートブックインスタンスを起動し、ノートブックインスタンスを開きます。このノートブックの例は、sample-notebooks フォルダにあります。また、新しいノートブックを conda_mxnet_p36 カーネルで起動し、このブログからコードをノートブックにコピーして実行できます。後で作成される SageMaker モデルファイルを格納する同じリージョンに S3 バケットを作成したいので、SageMaker ノートブックインスタンスが起動されているリージョンをメモしておいてください。

最初に Amazon SageMaker ノートブックに関連するライブラリをインポートします。

import os
import boto3
import io
import sagemaker

%matplotlib inline 

import pandas as pd
import numpy as np
import mxnet as mx
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
matplotlib.style.use('ggplot')
import pickle, gzip, urllib, json
import csv

Amazon SageMaker は Amazon S3 とシームレスに統合されています。ノートブック作成の最初のステップでは、ノートブックの「AmazonSageMakerFullAccess」ロールを指定しました。これで、このノートブックは、この AWS アカウントの Amazon S3 バケットに「sagemaker」という名前でアクセスすることが許可されます。

get_execution_role 関数は、ノートブックインスタンスの作成時に作成した IAM ロールを取得します。

from sagemaker import get_execution_role
role = get_execution_role()

私たちのロール AmazonSageMaker-ExecutionRole が表示されます。

role
'arn:aws:iam::003161157487:role/service-role/AmazonSageMaker-ExecutionRole-20171217T230500'

データセットの読み込み

アクセス可能な公開 S3 パケットにすでにデータをダウンロードし、格納しています。Boto3 クライアントを使用して、AWS と対話するために Python SDK を使用できます。

最初にクライアントを起動します。

s3_client = boto3.client('s3')
data_bucket_name='<public_s3_bucket_name_here>'

バケットに含まれるオブジェクトのリストが取得されます。バケットに「acs2015_county_data.csv」というファイルがあります。

obj_list=s3_client.list_objects(Bucket=data_bucket_name)
file=[]
for contents in obj_list['Contents']:
    file.append(contents['Key'])
print(file)
['acs2015_county_data.csv', 'counties/']
file_data=file[0]

バケット内の CSV ファイルからデータを取得します。

response = s3_client.get_object(Bucket=data_bucket_name, Key=file_data)
response_body = response["Body"].read()
counties = pd.read_csv(io.BytesIO(response_body), header=0, delimiter=",", low_memory=False) 

このデータの最初の 5 行は次のようになっています。

counties.head()
国勢調査 ID 全人口 ヒスパニック 黒人 ネイティブ 徒歩 その他の輸送手段 自宅仕事 平均通勤 雇われ 内職 公務員 自営業 家内労働 無職
0 1001 アラバマ Autauga 55221 26745 28476 2.6 75.8 18.5 0.4 0.5 1.3 1.8 26.5 23986 73.6 20.9 5.5 0.0 7.6
1 1003 アラバマ Baldwin 195121 95314 99807 4.5 83.1 9.5 0.6 1.0 1.4 3.9 26.4 85953 81.5 12.3 5.8 0.4 7.5
2 1005 アラバマ Barbour 26932 14497 12435 4.6 46.2 46.7 0.2 1.8 1.5 1.6 24.1 8597 71.8 20.8 7.3 0.1 17.6
3 1007 アラバマ Bibb 22604 12073 10531 2.2 74.5 21.4 0.4 0.6 1.5 0.7 28.8 8294 76.8 16.1 6.7 0.4 8.3
4 1009 アラバマ Blount 57710 28512 29198 8.6 87.9 1.5 0.3 0.9 0.4 2.3 34.9 22189 82.0 13.5 4.2 0.4 7.7

5 行 × 37 列

ステップ 2: 探索的データ分析 EDA – データのクリーニングと探索

a. データのクリーニング

ノートブックインスタンスでは、ノートブックのコンピューティングインスタンスを使用してこれらの計算を実行するだけで、簡単なデータのクリーニングと処理が可能です。

どのくらいのデータを扱っていますか?

3220 行 × 37 列あります。

counties.shape
(3220, 37)

解析を簡単にするために、不完全なデータをすべて削除してみましょう。2 行の不完全データが削除でき、現在 3218 行のデータがあります。

counties.dropna(inplace=True)
counties.shape
(3218, 37)

州や郡など説明的な参照列のいくつかを組み合わせて、数値列を残します。

これで「州-郡」がインデックスとして設定でき、残りの数値は各ユニークな郡の属性となります。

counties.index=counties['State'] + "-" + counties['County']
counties.head()
drop=["CensusId" , "State" , "County"]
counties.drop(drop, axis=1, inplace=True)
counties.head()
全人口 ヒスパニック 黒人 ネイティブ アジア人 太平洋 国民 徒歩 その他の輸送手段 自宅仕事 平均通勤 雇われ 内職 公務員 自営業 家内労働 無職
Alabama-Autauga 55221 26745 28476 2.6 75.8 18.5 0.4 1.0 0.0 40725 0.5 1.3 1.8 26.5 23986 73.6 20.9 5.5 0.0 7.6
Alabama-Baldwin 195121 95314 99807 4.5 83.1 9.5 0.6 0.7 0.0 147695 1.0 1.4 3.9 26.4 85953 81.5 12.3 5.8 0.4 7.5
Alabama-Barbour 26932 14497 12435 4.6 46.2 46.7 0.2 0.4 0.0 20714 1.8 1.5 1.6 24.1 8597 71.8 20.8 7.3 0.1 17.6
Alabama-Bibb 22604 12073 10531 2.2 74.5 21.4 0.4 0.1 0.0 17495 0.6 1.5 0.7 28.8 8294 76.8 16.1 6.7 0.4 8.3
Alabama-Blount 57710 28512 29198 8.6 87.9 1.5 0.3 0.1 0.0 42345 0.9 0.4 2.3 34.9 22189 82.0 13.5 4.2 0.4 7.7

5 行 × 34 列

b. データの可視化

これで数値とカテゴリー列を混合したデータセットができました。いくつかの数値列のデータを視覚化し、その分布を見ることができます。

import seaborn as sns

for a in ['Professional', 'Service', 'Office']:
    ax=plt.subplots(figsize=(6,3))
    ax=sns.distplot(counties[a])
    title="Histogram of " + a
    ax.set_title(title, fontsize=12)
    plt.show()

例えば、上図では、郡の労働者に占める専門職、サービス、事務職の割合を見ることができます。ヒストグラムを表示すると、平均や歪度などこれらの特徴の特性を視覚的に示すことができます。例えば専門職労働者の分布は、一般的な郡では 25-30% の専門職労働者がおり、右側に歪んでおり、ロングテールです。いくつかの郡では専門職労働者の割合がほぼ 80% であるように突出しています。

c. 特徴エンジニアリング

データスケーリング – 異なる特徴列間の相対距離を比較できるように、距離ベースの分析メソッドを使用するための数値列スケーリングを標準化する必要があります。minmaxscaler を使用して数値列を変換し、0 ~ 1 の間に収まるようにすることもできます。

from sklearn.preprocessing import MinMaxScaler
scaler=MinMaxScaler()
counties_scaled=pd.DataFrame(scaler.fit_transform(counties))
counties_scaled.columns=counties.columns
counties_scaled.index=counties.index

すべての数値列では、最小が 0、最大が 1 であることが分かります。

counties_scaled.describe()
全人口 ヒスパニック 黒人 ネイティブ アジア人 太平洋 国民 徒歩 その他の輸送手段 自宅仕事 平均通勤 雇われ 内職 公務員 自営業 家内労働 無職
総数 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000 3218.000000
平均 0.009883 0.009866 0.009899 0.110170 0.756024 0.100942 0.018682 0.029405 0.006470 0.011540 0.046496 0.041154 0.124428 0.470140 0.009806 0.760810 0.194426 0.216744 0.029417 0.221775
標準偏差 0.031818 0.031692 0.031948 0.192617 0.229682 0.166262 0.078748 0.062744 0.035446 0.033933 0.051956 0.042321 0.085301 0.143135 0.032305 0.132949 0.106923 0.106947 0.046451 0.112138
最低 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
25% 0.001092 0.001117 0.001069 0.019019 0.642285 0.005821 0.001086 0.004808 0.000000 0.001371 0.019663 0.023018 0.072581 0.373402 0.000948 0.697279 0.120861 0.147541 0.010204 0.150685
50% 0.002571 0.002591 0.002539 0.039039 0.842685 0.022119 0.003257 0.012019 0.000000 0.003219 0.033708 0.033248 0.104839 0.462916 0.002234 0.785714 0.172185 0.188525 0.020408 0.208219
75% 0.006594 0.006645 0.006556 0.098098 0.933868 0.111758 0.006515 0.028846 0.000000 0.008237 0.056180 0.048593 0.150538 0.560102 0.006144 0.853741 0.243377 0.256831 0.030612 0.271233
最大 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000

8 行 × 34 列

ステップ 3: データモデリング

a. 次元縮退

主成分分析 (PCA) を使用して、データの次元を減らします。この方法は、データ行列を互いに直交する特徴に分解します。結果として得られる直交する特徴は、元の特徴セットの線形結合です。あなたはこの方法を、多くの機能を利用し、同様または冗長機能を組み合わせて新しい、より小さな機能セットを作成するものとして考えることができます。

内蔵された PCA 用 Amazon SageMaker アルゴリズムを使用することで、次元を縮退することができます。

最初に PCA SageMaker モデルのインスタンスをインポートして、呼び出します。次に、モデルのさまざまなパラメータを指定します。これらはトレーニング中に使用するインスタンス数や使用するインスタンスの種類など、リソース構成パラメータにすることができます。また、PCA を実行するときに使用する成分数など、モデル計算ハイパーパラメータにすることもできます。PCA モデルについての説明文書は http://sagemaker.readthedocs.io/en/latest/pca.html から入手できます。

SageMaker モデルパラメータを保存するアカウントのバケットに、バケット名を指定することを忘れないでください。バケットはこのノートブックと同じリージョンにする必要があります。

from sagemaker import PCA
bucket_name='<my_s3_bucket_name_here>'
num_components=33

pca_SM = PCA(role=role,
          train_instance_count=1,
          train_instance_type='ml.c4.xlarge',
          output_path='s3://'+ bucket_name +'/counties/',
            num_components=num_components)

次に、DataFrame から numpy 配列を抽出し、明示的に float32 にキャストして Amazon SageMaker のデータを準備します。

train_data = counties_scaled.values.astype('float32')

Amazon SageMaker PCA モデルの record_set 関数は、numpy 配列をレコードセット形式 (入力データをトレーニングするために必要なフォーマット) に変換します。これはすべての Amazon SageMaker 内蔵モデルの要件です。このデータの種類を使用する理由の 1 つは、sklearn の実装など、同じモデルの他の実装と比較してより大きなデータセットに対して Amazon SageMaker でのモデルのトレーニングを高速に実行できることです。

PCA モデルの fit 関数を呼び出し、トレーニングデータを渡して、トレーニングインスタンスまたはクラスターをスピンアップして、トレーニングジョブを実行します。

%%time
pca_SM.fit(pca_SM.record_set(train_data))

b. PCA モデル属性へのアクセス

モデル作成後は、基本のモデルパラメータにアクセスすることもできます。

トレーニングジョブが完了したら、Amazon SageMaker コンソールの Training サブセクションにある Jobs からジョブを見つけることができます。トレーニングジョブにリストされているジョブ名を見つけることができます。検査するモデルを指定するときには、次のコードでそのジョブ名を使用します。

モデル成果物はトレーニング後に Amazon S3 に保存されます。これは Amazon SageMaker を使用してトレーニングされたモデルをデプロイするために使用されるモデル成果物と同じです。多くの Amazon SageMaker アルゴリズムは計算速度の理由で MXNet を使用するため、モデル成果物は ND 配列として保存されます。トレーニング呼び出し中に指定された出力パスでは、モデルは GNU zip (gzip) 圧縮された TAR アーカイブファイルである「トレーニングジョブ名」 –> output –> model.tar.gz ファイルに存在します。

job_name='<your_SageMaker_PCA_job_name_here>'
model_key = "counties/" + job_name + "/output/model.tar.gz"

boto3.resource('s3').Bucket(bucket_name).download_file(model_key, 'model.tar.gz')
os.system('tar -zxvf model.tar.gz')
os.system('unzip model_algo-1')
2304

モデルを unzip して解凍後、MXNet を使用して ND 配列をロードできます。

import mxnet as mx
pca_model_params = mx.ndarray.load('model_algo-1')

これら 3 つのグループのモデルパラメータが PCA モデルにはあります。

mean: これはオプションであり、元の PCA SageMaker 関数からトレーニングステップを呼び出すときに、「subtract_mean」ハイパーパラメータが真である場合にのみ使用できます。

v: 主成分を含みます(sklearn PCA モデルの「components_」と同じ)。

s: PCA 変換のための成分の特異値。これは元の特徴空間の % 分散を正確には与えないが、投影された特徴空間の % 分散を与えることができます。

explained-variance-ratio ~= square(s) / sum(square(s))

必要に応じて正確な explained-variance-ratio ベクトルを計算するには、元のデータ (N と呼ぶ)の二乗和を保存し、explained-variance-ratio = square(s) / N を計算する必要があります。

s=pd.DataFrame(pca_model_params['s'].asnumpy())
v=pd.DataFrame(pca_model_params['v'].asnumpy())

ここで保持したい上位 n 成分によって説明される分散を計算できます。この例では、上位 5 成分を取り上げます。

私たちのデータセットでは上位 5 成分が合計分散の ~72% であることを説明していることが分かります。

s.iloc[28:,:].apply(lambda x: x*x).sum()/s.apply(lambda x: x*x).sum()
0    0.717983
dtype: float32

上位 5 成分の保持を決定後、元の s と v マトリックスから上位 5 成分のみを取り出すことができます。

s_5=s.iloc[28:,:]
v_5=v.iloc[:,28:]
v_5.columns=[0,1,2,3,4]

成分に含まれる元の特徴の重み付けに基づいて、各 PCA 成分の構成を調べることができます。例えば、次のコードは最初の成分を示しています。この成分は、高い貧困率と失業者、低所得および少ない一人あたり所得、高いヒスパニック/黒人人口、少ない白人人口の郡の属性を表していることが分かります。

これは v_5[4] または v_5 の成分リストの最後の成分ですが、実際成分は最小から最大に順番付けされるため、これは最大の成分です。したがって v_5[0] が最小成分となります。同様に、component_num の値を各成分を循環させるように変更します。

component_num=1

first_comp = v_5[5-component_num]
comps = pd.DataFrame(list(zip(first_comp, counties_scaled.columns)), columns=['weights', 'features'])
comps['abs_weights']=comps['weights'].apply(lambda x: np.abs(x))
ax=sns.barplot(data=comps.sort_values('abs_weights', ascending=False).head(10), x="weights", y="features", palette="Blues_d")
ax.set_title("PCA Component Makeup: #" + str(component_num))
plt.show()

同様にして、各 PCA 成分の構成を調べ、各成分の主要なプラスおよびマイナス属性が何であるかを理解することができます。次のコードは成分に名前を付けていますが、各成分のユニークな構成を理解するためにユーザーが自由に変更可能です。

PCA_list=['comp_1', 'comp_2', 'comp_3', 'comp_4', 'comp_5']

#PCA_list=["Poverty/Unemployment", "Self Employment/Public Workers", "High Income/Professional & Office Workers", \
#         "Black/Native Am Populations & Public/Professional Workers", "Construction & Commuters"]

c. PCA モデルのデプロイ

このモデルエンドポイントをデプロイし、予測を行うために使用できるようになりました。このモデルは現在稼働中であり、指定した instance_type でホストされています。

%%time
pca_predictor = pca_SM.deploy(initial_instance_count=1, 
                                 instance_type='ml.t2.medium')

元のデータセットをモデルに渡し、作成したモデルを使用してデータを変換することもできます。次に 上位 5 成分を取り、データ次元を 34 から 5 に減らします。

%%time
result = pca_predictor.predict(train_data)
counties_transformed=pd.DataFrame()
for a in result:
    b=a.label['projection'].float32_tensor.values
    counties_transformed=counties_transformed.append([list(b)])
counties_transformed.index=counties_scaled.index
counties_transformed=counties_transformed.iloc[:,28:]
counties_transformed.columns=PCA_list

これで以前分析した 5 つの主成分によって記述されたデータセットを郡ごとに作成しました。これらの 5 成分のそれぞれは、元の特徴スペースの線形結合です。以前に示した成分構成を分析することで、これら 5 つの成分を解釈できます。

counties_transformed.head()
貧困/失業 自営業/公務員 高収入/専門職および会社員 黒人/ネイティブアメリカン人口および公務員/専門職 建設および通勤者
Alabama-Autauga -0.010824 0.120480 -0.088356 0.160527 -0.060274
Alabama-Baldwin -0.068677 -0.023092 -0.145743 0.185969 -0.149684
Alabama-Barbour 0.093111 0.297829 0.146258 0.296662 0.506202
Alabama-Bibb 0.283526 0.011757 0.224402 0.190861 0.069224
Alabama-Blount 0.100738 -0.193824 0.022714 0.254403 -0.091030

d. 教師なしクラスタリングを使用した人口区分

次に、Kmeans アルゴリズムを使用して、作成済みの 5 つの PCA 属性で郡の人口を区分化します。Kmeans は属性に基づいて類似した郡のクラスターを識別するクラスタリングアルゴリズムです。元のデータセットには約 3000 の郡と 34 属性があるため、大きな特徴空間では効果的な郡のクラスタリングが困難であった可能性があります。代わりに特徴空間を 5 PCA 成分に減らし、この変換されたデータセットでクラスター化します。

train_data = counties_transformed.values.astype('float32')

最初に、PCA モデルで行ったように、KMeans モデルのハイパーパラメータを呼び出して定義します。Kmeans アルゴリズムを使うと、ユーザーが識別するクラスター数を指定できます。この例では、データセットから上位 7 クラスターを探してみましょう。

from sagemaker import KMeans

num_clusters = 7
kmeans = KMeans(role=role,
                train_instance_count=1,
                train_instance_type='ml.c4.xlarge',
                output_path='s3://'+ bucket_name +'/counties/',              
                k=num_clusters)

次に、トレーニングデータでモデルをトレーニングします。

%%time
kmeans.fit(kmeans.record_set(train_data))

これでモデルをデプロイし、元のトレーニングセットを渡して、各エントリのラベルを取得できます。これで各郡がどのクラスターに属しているかが分かります。

%%time
kmeans_predictor = kmeans.deploy(initial_instance_count=1, 
                                 instance_type='ml.t2.medium')
%%time
result=kmeans_predictor.predict(train_data)
CPU times: user 204 ms, sys: 0 ns, total: 204 ms
Wall time: 438 ms

クラスター数の内訳とクラスターの分布を見ることができます。

cluster_labels = [r.label['closest_cluster'].float32_tensor.values[0] for r in result]
pd.DataFrame(cluster_labels)[0].value_counts()
5.0    928
3.0    851
2.0    401
4.0    364
6.0    332
0.0    227
1.0    115
Name: 0, dtype: int64
ax=plt.subplots(figsize=(6,3))
ax=sns.distplot(cluster_labels, kde=False)
title="Histogram of Cluster Counts"
ax.set_title(title, fontsize=12)
plt.show()

しかし、説明能力を向上させるためには、基礎となるモデルにアクセスしてクラスターの中心値を取得する必要があります。これらの中心値は各クラスターの特徴を説明するのに役立ちます。

ステップ 4: モデリングから結論を導く

モデリングの結果を説明することは、分析を利用する際の重要なステップです。PCA と Kmeans、および Amazon SageMaker トレーニングモデル内のモデル属性に含まれる情報を組み合わせて、データに基づいて具体的な結論を導き出すことができます。

a. KMeans モデル属性へのアクセス

最初に、kmeans モデルが格納されているバケットに移動して抽出します。

job_name='<your_SageMaker_KMeans_job_name_here>'
model_key = "counties/" + job_name + "/output/model.tar.gz"

boto3.resource('s3').Bucket(bucket_name).download_file(model_key, 'model.tar.gz')
os.system('tar -zxvf model.tar.gz')
os.system('unzip model_algo-1')
2304
Kmeans_model_params = mx.ndarray.load('model_algo-1')

KMeans モデルには 1 組のモデルパラメータが含まれています。

クラスター重心位置: Kmeans アルゴリズムによって同定された各クラスターの重心位置。モデルに変換された PCA データを渡したため、クラスター位置は 5 つの成分を持つ PCA 変換空間で与えられます。

cluster_centroids=pd.DataFrame(Kmeans_model_params[0].asnumpy())
cluster_centroids.columns=counties_transformed.columns
cluster_centroids
貧困/失業 自営業/公務員 高収入/専門職および会社員 黒人/ネイティブアメリカン人口および公務員/専門職 建設および通勤者
0 0.025268 0.018374 0.040258 -0.356033 0.317980
1 -0.023942 -0.369325 -0.181284 -0.240269 1.045534
2 -0.019848 0.059698 -0.354655 0.047747 -0.064816
3 -0.012187 -0.063721 -0.007848 0.035607 -0.248565
4 0.103763 0.269017 0.084220 0.241475 0.390270
5 -0.029940 -0.054422 0.132807 0.086195 -0.020860
6 0.029929 0.110788 0.084239 -0.411732 -0.217632

重心のヒートマップと変換された特徴空間の位置をプロットできます。これによって、各クラスターをどのような特性で定義するかについて洞察を得ることができます。教師なし学習では、しばしば結果の解釈が難しい場合があります。これは PCA の結果とクラスタリング技術を一緒に使用する 1 つの方法です。各 PCA 成分の構成を調べることができたので、以前に解釈した PCA 成分の観点から、各重心が何を表しているのか理解することができます。

例えば、クラスター 1 は「建設と通勤者」属性で最高値であり、一方で他のクラスターと比較して、クラスター 1 は「自営業/公務員」属性で最低値となります。同様にして、クラスター 4 は「建設と通勤者」、「高収入/専門職および会社員」、「自営業/公務員」で高い値となります。

plt.figure(figsize = (16, 6))
ax = sns.heatmap(cluster_centroids.T, cmap = 'YlGnBu')
ax.set_xlabel("Cluster")
plt.yticks(fontsize = 16)
plt.xticks(fontsize = 16)
ax.set_title("Attribute Value by Centroid")
plt.show()

また、クラスターラベルを各個別の郡にマップして、どの郡が自然にグループ化されているかを調べることができます。

counties_transformed['labels']=list(map(int, cluster_labels))
counties_transformed.head()
貧困/失業 自営業/公務員 高収入/専門職および会社員 黒人/ネイティブアメリカン人口および公務員/専門職 建設および通勤者 labels
Alabama-Autauga -0.010824 0.120480 -0.088356 0.160527 -0.060274 5
Alabama-Baldwin -0.068677 -0.023092 -0.145743 0.185969 -0.149684 3
Alabama-Barbour 0.093111 0.297829 0.146258 0.296662 0.506202 4
Alabama-Bibb 0.283526 0.011757 0.224402 0.190861 0.069224 5
Alabama-Blount 0.100738 -0.193824 0.022714 0.254403 -0.091030 5

これで、例えばクラスター 1 のようにあるクラスターの詳細を調べることができます。重心位置では、「建設と通勤者」属性が最高値であることが分かります。これで、どの郡がその説明に適合しているか分かるようになりました。

cluster=counties_transformed[counties_transformed['labels']==1]
cluster.head(5)
貧困/失業 自営業/公務員 高収入/専門職および会社員 黒人/ネイティブアメリカン人口および公務員/専門職 建設および通勤者 labels
Arizona-Santa Cruz -0.014149 -0.347113 -0.386305 -0.284937 0.753071 1
Arizona-Yuma -0.019377 -0.260098 -0.200252 -0.188408 0.585572 1
California-Fresno 0.016950 -0.198805 -0.260822 -0.090927 0.590060 1
California-Imperial -0.015831 -0.291125 -0.296619 -0.279273 0.885126 1
California-Merced 0.170347 -0.304941 -0.154338 -0.072953 0.644423 1

まとめ

PCA を使用して次元を減らした後に、特に KMeans を使用してデータセットをクラスター化するための教師なし学習のためのデータ科学ワークフローを説明してきました。Amazon SageMaker で作成した基礎モデルにアクセスすることで、モデリングの説明能力を向上させ、実行可能な結論を導き出すことができました。これらの手法を使用して、米国のさまざまな郡の本質的特性をより理解でき、それに従って有権者をグループに区分けできました。

エンドポイントは永続的であるため、AWS の料金の過剰請求を避けるため、終了したエンドポイントを削除しましょう。

sagemaker.Session().delete_endpoint(pca_predictor.endpoint)
sagemaker.Session().delete_endpoint(kmeans_predictor.endpoint)

今回のブログ投稿者について

Han Man は AWS プロフェッショナルサービスのデータサイエンティストです。彼はノースウェスタン大学で工学博士号を取得し、製造、金融サービス、エネルギー分野の顧問顧問として数年の経験を持ちます。現在、AWS の機械学習と AI ソリューションを開発し実装するために、さまざまな業界の顧客と一緒に熱心に取り組んでいます。彼は NBA のファンで、バスケットボールが趣味です。