ブラックフライデーの販売顧客データを使って顧客の傾向を分析する

>こちらの記事は、[Jonathan Cabreira](https://towardsdatascience.com/@cabreirajm) 氏により2019年12月に公開された『 [An Analysis of Consumer Behavior on Black Friday](https://towardsdatascience.com/an-analysis-of-consumer-behavior-on-black-friday-9dd7952fc172) 』の和訳です。
本記事は原著者から許可を得た上で記事を公開しています。


あなたが勤めているところがB2C企業でもD2C企業であろうと、予測モデルを作成したり消費者の行動を理解するために、販売データを分析するよう求められる事があるでしょう。この記事では、データによって答えられる質問、とその答えをできる限り早く抽出する方法を見ていきます。異なる質問に答えるためにいくつかの棒グラフと、生活を楽にするための2つの関数を作成します。

今回我々は、[Analytics Vidhyaのウェブサイト](https://datahack.analyticsvidhya.com/contest/black-friday/)上から利用できるブラックフライデーのデータセットを使用します。データの情報を扱うツールについては以下から確認できます。

開発で使用したすべてのコードは、私の[Githubページ](https://github.com/jmcabreira)から確認することができます

#使用するツール:

- データ可視化にseabornとmatplotlib
- データ分析にpandasとnumpy

#今回データによって答えられる質問:
**年齢層の分析:**

- 年齢層別の購入数
- 年齢層と都市別の平均購入額

**製品カテゴリの分析:**

- 製品カテゴリーごとの都市別購入数
- 製品カテゴリー1の都市別平均購入額
- 製品カテゴリー2の都市別平均購入額
- 製品カテゴリー3の都市別平均購入額

**性別の分析:**

- 性別ごとの平均購入額
- 性別と年齢層別の平均購入額
- 性別と都市別の平均購入額

**職業の分析:**

- 職業別の平均購入額
- 職業と都市別の平均購入額

**順序変数間の相関:**

- ヒートマップ
- クラスターマップ

#変数:

![](https://miro.medium.com/max/966/1*qqvRq9c60habZNi6a7foug.png)

#DataFrame:
![](https://miro.medium.com/max/2000/1*TBTijabIT6gDlWvLBS9sKA.png)


データの第一印象としては、整理されているように見えるものの、まだいくつかの値が不足しています。Product_Category(2と3)の列には、数値表現ではなく大量のNaN変数があります。これは、それぞれのNaNのある列の製品が、特定のカテゴリに属していないことを表しています。例えば、最初の行の製品(Product_id = P00069042)は、製品3として識別され、カテゴリ1にのみ属しています。一方、2行目の製品はカテゴリ1に製品1として、カテゴリ2に製品6として、カテゴリ3に製品14として識別されており、これは2列目の製品がすべてのカテゴリに属していることを意味します。

これに加えて、**groupbyとpivot_tableは自動的にNaNを無視する**という事にも注意しなければなりません。この2つのテクニックを利用してデータをグループ化した上で、それらのデータに対して演算を行うため、作業は非常に楽になります。このデータにはいくつかの外れ値があるかもしれませんが、この問題に関してはすでにマイニングされていると考えることも重要です。

#年齢層別の分析:
##年齢層別の購入数

まずは、年齢層別の購入数の合計と、年齢層別・都市別の購入手段を特定することから始めようと思います。そのためには、まずvalue_counts()メソッドを使用して各グループの購入数をカウントし、簡単な棒グラフを作成する必要があります。次に、インデックスがAgeと City_Categoryの列になっているマルチレベルのピボットテーブルDataFrameを作成し、棒グラフをプロットします。

下のプロットを見ると、購入数では26～35歳がトップです。次いで36～45歳とそれに続く18～25歳の購入数が、どちらも、トップグループの約半分であることがわかります。

```python
# Bar Colors
color_1 = ['lightslategray', 'mediumvioletred', 'sandybrown', 'sienna' , 'navy', 'olive', 'darkgreen']

# Number of Purchase by Age roup
df.Age.value_counts().plot(kind = 'bar', color = color_1, title = 'Number of Purchase by Age Group', figsize =(8,6))
plt.xlabel('Age Group', fontsize = 13)
plt.ylabel('Number of Purchase', fontsize = 13)# Bar Colors
```

![](https://miro.medium.com/max/1054/1*S-jGhZ-tnXvGHbsEyvvhhQ.png)

##年齢層と都市別の平均購入額

この答えを出すため、簡単にデータを可視化すると次のようなグラフが出てきます。

```python
# Select Dataframe
age_group_city = df.loc[:,['Age', 'City_Category', 'Purchase']] 

# Pivot Table with Purchase Mean - datafame
age_group_city = age_group_city.pivot_table(age_group_city, index = ['Age', 'City_Category'], aggfunc = 'mean')
```

```python
# Bar Colors
color = ('lightslategray','mediumvioletred','sandybrown')

age_group_city.sort_index(ascending=False).plot(
    kind='barh',
    figsize=(10, 8),
    cmap='viridis',
    edgecolor='black',
    fontsize=14,
    legend = False,
    title='Purchase Mean by Age Group and City',
    color = color
    ).yaxis.label.set_visible(False)
plt.ylabel('Age_Group, City')
plt.xlabel('Purchase Mean')
```

![](https://miro.medium.com/max/1302/1*T1Ji1HAQLk73kEPQXNpzmw.png)

上記のプロットは、私たちが欲しい情報は与えてくれていますが、少々分かりにくいです。 私たちはプロットが分かりやすいほど、それを見る人にとって「幸せ」になるということを心に留めておかなければなりません。プロットやダッシュボードを、見た人がすぐに理解できるよう、メッセージをできるだけ明確に伝えるのがデータサイエンティストやデータアナリストとしての義務です。そこで、これらのグループ間の明確な比較を行うために、それぞれのグループを別々にプロットしてみましょう。

「それぞれのプロットごとにいちいちコードなんて書いてられない！」とお思いかもしれません。ええ、その通りですね！誰だってそんなことをしている時間はないでしょう。時は金なりです！なので、私たちの代わりにこれを自動でしてくれる関数と、それに加えてそれぞれのビジュアライゼーションで軸リストを正確で同じ長さに設定してくれる関数を書いてみましょう。

```python
 "This function takes the an axes list, the number of plots and sets  the axes list with correct length"
def trim_axs(axs, N):
    axs = axs.flatten()
    for ax in axs[N:]:
        ax.remove()
    return axs[:N]
```
```python
def individual_bar_plots(dataframe, item, title, ax = None):
    

    obj = dataframe.loc[item,:]  # Select item

    obj.plot( kind = 'barh',
            color = color,
            edgecolor = 'black', 
            ax = ax,   
            legend = None,              
            ).set_title(f'{title} {item}')
    
    ax.set_xlabel('Purchase Mean [$]')
```

```python
# Setup for the 4x2 subplot grid
# We don't want to share the x axis, only the y axis 
fig, ax = plt.subplots(nrows=4, ncols=2, figsize=(12, 12), sharey=True)

# Correct the lenght of the ax
ax = trim_axs(ax, len(df.Age.unique()))

# Age Groups list
age_list = ['0-17','18-25','26-35','36-45', '46-50','51-55','55+']

# ax.flatten() collapses the ax into one dimension array
for subplot, Age in zip(ax.flatten(), age_list):
    individual_bar_plots(age_group_city, Age, ax=subplot, title = 'Age')
    
plt.tight_layout()
```

![](https://miro.medium.com/max/1284/1*dG1k4EmCkkDK-5OMv9Sa-w.png)

#製品カテゴリの分析:
次はカテゴリーと製品を分析します。まず、各都市における各カテゴリーの製品購入数の合計を棒グラフにプロットします。そして、私たちが先ほど作った関数を利用し、各カテゴリーの全製品の個別チャートをプロットします。ここで注意したいのは、1つの製品が複数の異なるカテゴリーやグループに属している場合があるということです。例えば、**P00248942**という製品は全てのカテゴリーに属していますが、カテゴリー1ではグループ1、カテゴリー1ではグループ6、カテゴリー3ではグループ14という名前になっています。それを踏まえた上で、早速分析を始めましょう。

![](https://miro.medium.com/max/2000/1*TBTijabIT6gDlWvLBS9sKA.png)

##製品カテゴリーごとの都市別購入数:
下のグラフを見ていただくと、購入数にはある種のパターンがあることがわかります。ご覧のように、どの都市でも製品カテゴリー1がトップで、次いで製品カテゴリー2、製品カテゴリー3と並んでいます。ここで各都市が異なるのは、都市Bが全てのカテゴリーにおいて都市Aや都市Cよりも多くの製品を購入していることです。

```python
# Number of purchases of each product category by city

# Select Dataframe
Purchase_by_City_df = df.loc[:,[ 'City_Category','Product_Category_1', 'Product_Category_2','Product_Category_3']] 

# Pivot Table
Purchase_by_City_Pivt = Purchase_by_City_df.pivot_table(Purchase_by_City_df, index = ['City_Category'], aggfunc = 'count')

#Barplot
Purchase_by_City_Pivt.plot( kind = 'barh',figsize =(10,8), color = color)


#Create Legend
plt.xlabel('Total of Purchases', fontsize = 13)
plt.ylabel('City, Product_category', fontsize = 13)
plt.title('Purchases of Each Product Category by City', fontsize = 14 )
```

![](https://miro.medium.com/max/1208/1*FIMBz6kVLjmH1dM_ibmp7Q.png)

##製品カテゴリー1の都市別平均購入額:
ここからは、それぞれのビジュアライゼーションごとにDataFrameを結合し、可視化するデータを選択した上で、作成した2つの関数を適用します。

```python
# Access rows and columns by city
df_city_A = df.loc[df.City_Category == 'A', :]
df_city_B = df.loc[df.City_Category == 'B', :]
df_city_C = df.loc[df.City_Category == 'C', :]
```

```python
# Groupby each dataframe - Series with the number of purchases
City_A_Category_1 = df_city_A.groupby('Product_Category_1').mean()['Purchase']
City_B_Category_1 = df_city_B.groupby('Product_Category_1').mean()['Purchase']
City_C_Category_1 = df_city_C.groupby('Product_Category_1').mean()['Purchase']

# Concatenate all series
prod1_df = pd.concat([City_A_Category_1,City_B_Category_1, City_C_Category_1], axis = 1)
# Set columns name
prod1_df.columns = ['City_A', 'City_B', 'City_C']
```

```python
#setup 4 x 5 subplot grid
fig, ax = plt.subplots(nrows = 4 , ncols= 5, figsize = (15,12), sharey = True)

#correct the lenght of the ax
#ax = trim_axs(ax, len(df.Product_Category_1.unique()))

color = ['lightslategray','mediumvioletred','sandybrown']

product_category_1_list = sorted(list(df.Product_Category_1.unique()))

for subplot, product in zip(ax.flatten(),product_category_1_list ):
    individual_bar_plots(prod1_df,product,ax = subplot, title = 'Product Group')
    
plt.tight_layout()
```

![](https://miro.medium.com/max/1400/1*9a1kg_dvAvlRFTqhZxfs4Q.png)

ここで全てのプロットを精査するつもりはありませんが、代わりにそれらから分かる主な情報に注目してみましょう。まず私の目に飛び込んできたのは、平均40ドル未満の他の製品と比較して、その平均購入額が圧倒的に少ない製品19です。また、製品4の平均購入額は都市Cがトップで、それに続く都市Bは都市A(*)をわずかに上回っています。

**訳注)原文では都市Cとなっていますが、文脈から都市Aの間違いであると思われるため改変しています。**

##製品カテゴリー2の都市別平均購入額:
それではカテゴリ2の全製品を分析してみましょう。データの説明で述べたように、製品は他のカテゴリーにも属している場合があり、以下のプロットでも実際にそれが分かると思います。ここにはカテゴリ1にも属する製品が17あり、ご覧の通り製品10は最大の平均購入額を持っています。ここでも(製品カテゴリ1と同様に)再び都市Cがトップを取り、都市BとAがそれに続いています。

```python
# Select Series with Purchase Means
City_A_Category_2 = df_city_A.groupby('Product_Category_2').mean()['Purchase']
City_B_Category_2 = df_city_B.groupby('Product_Category_2').mean()['Purchase']
City_C_Category_2 = df_city_C.groupby('Product_Category_2').mean()['Purchase']

# Product 2 DataFrame
prod2_df = pd.concat([City_A_Category_2,City_B_Category_2,City_C_Category_2], axis = 1)
# Naming Columns
prod2_df.columns =['City_A', 'City_B', 'City_C']
```

```python
# Setup for the 6 X 3 subplot grid
fig, ax = plt.subplots(nrows=6 , ncols=3, sharey = True, figsize = (15,12))

#Correct the lenght of the ax
ax = trim_axs(ax, len(df.Product_Category_2.unique()[1:]) )

product_category_2_list = sorted(list(df.Product_Category_2.unique()[1:]))

for subplot, product in zip(ax.flatten(), product_category_2_list):
    individual_bar_plots(prod2_df,product,ax = subplot, title = 'Product Group')

plt.tight_layout()
````

![](https://miro.medium.com/max/1400/1*YXl8Z9wv63H4wL4wiSBgiQ.png)

##製品カテゴリー3の都市別平均購入額:
以下のプロットは、製品カテゴリー3に関する情報を示しています。このカテゴリーには15の製品があり、製品3はすべての都市において最大の平均購入額値を持っていることがわかります。

```python
# Select Series with Purchase Means
City_A_Category_3 = df_city_A.groupby('Product_Category_3').mean()['Purchase']
City_B_Category_3 = df_city_B.groupby('Product_Category_3').mean()['Purchase']
City_C_Category_3 = df_city_C.groupby('Product_Category_3').mean()['Purchase']

# Product 3 DataFrame
prod3_df = pd.concat([City_A_Category_3,City_B_Category_3,City_C_Category_3] , axis =1 )
# Naming Columns
prod3_df.columns = ['City_A', 'City_B', 'City_C']
```

```python
#Setup for 5 x 3 subplot grid
fig, ax  = plt.subplots( nrows= 5, ncols=3, sharey = True, figsize = (15,12))

product_category_3_list = sorted(list(df.Product_Category_3.unique()[1:]))

for subplot, product in zip(ax.flatten(), product_category_3_list):
    individual_bar_plots(prod3_df,product, ax = subplot, title = 'Product')

plt.tight_layout()
```

![](https://miro.medium.com/max/1400/1*c4LUkxiPwoh68ldye6sbAA.png)

#性別の分析:

性別が購入意思決定に与える影響を理解することの重要性は誰もが知っていることでしょう。実際、例えば家庭内で誰が購入の意思決定をするのかといった問題は多くの研究で取り上げられています。また、製品カテゴリーや価格といった特性に対する購入意思決定のスタイルやパターンの性別による違いを調べることも重要です。

これを踏まえた上で、顧客の行動についての簡単かつ関連性の高い洞察をデータ分析によって得てみましょう。まず、購入数の合計と各性別の平均購入額をプロットします。次に、年齢層別の平均購入額をプロットし、最後にA,B,Cの都市での商品購入について、男性と女性でどのように異なるかを見てみましょう。

##性別ごとの購入数および平均購入額
さて、以下のグラフを見ると、男性消費者による購入数合計(**414259**)は、女性による購入数(**135809**)の約3倍であることが分かります。ですが、意外にも男女の平均購入額には大きな差がないことがわかります。男性と女性の購入数には明らかな格差があるのにもかかわらず、男性消費者の平均購入額は、女性の平均購入額(700ドル)をわずかに上回るに過ぎません。このことから、女性消費者はこのビジネスにとって非常に重要な存在であり、例えば、特別なマーケティングキャンペーンの対象にできる可能性があると言えるでしょう。

```python
# Purchase Mean by Gender grouny
df.groupby('Gender').mean()['Purchase'].sort_values(ascending = False)

# Plotting Purchase by Gender
plt.subplot(221)

# Number of Males and Females
df.Gender.value_counts().plot(kind= 'bar', title = 'Purchases by Gender', color = color)

plt.xlabel('Gender', fontsize = 13)
plt.ylabel('Number of Purchases', fontsize = 13)
import matplotlib.patches as mpatches
gray_patch = mpatches.Patch(color ='lightslategray', label = 'Male')
violet_patch = mpatches.Patch(color = 'mediumvioletred', label = 'Female')
plt.legend(handles = [gray_patch,violet_patch], loc = 'best')

#Plotting Purchase Mean by Gender
plt.subplot(222)

df.groupby('Gender').mean()['Purchase'] .sort_values(ascending = False).plot(kind = 'bar',
                                                                         color = color,
                                                                         title = 'Purchase Mean by Gender')
                                                                    
plt.ylabel('Purchase Mean [$]', fontsize = 13)
plt.xlabel('Gender', fontsize = 13)
plt.legend(handles = [gray_patch,violet_patch], loc = 'best')
plt.tight_layout()

plt.rcParams['figure.figsize'] =(12,8)
```

![](https://miro.medium.com/max/1400/1*_sWi97M4kMD1gJ1dpiFsBA.png)

##性別と年齢層別の平均購入額:
以下の棒グラフから異なる年齢層と性別の購入パターンを比較してみましょう。このグラフは18歳〜25歳の顧客において、男性のグループの平均購入額は女性のグループのよりも1000ドル以上多いことを示しています。また、18～25歳の年齢層ほどその差は顕著ではありませんが、すべての年齢層においても男性消費者の方が平均購入額が多いこともわかります。

```python
# DataFrme selection
gender_age_pvt = df.pivot_table(df , index = ['Age', 'Gender'], aggfunc = 'mean')['Purchase']

#Plot
fig, ax = plt.subplots(nrows = 3 , ncols= 3, figsize = (15,12), sharey = False)

#correct the lenght of the ax
ax = trim_axs(ax, len(df.Age.unique()))

# set colors
color = ['mediumvioletred','lightslategray']

for subplot, Age in zip(ax.flatten(),age_list ):
    individual_bar_plots(gender_age_pvt,Age,ax = subplot, title = 'Age')
    
plt.tight_layout()
```

![](https://miro.medium.com/max/1400/1*hzDtQ_D5MiPE8DtC85xAew.png)

##性別と都市別の平均購入額:

最後の性別による分析では、各都市の男女による購入状況の違いを把握します。そのために以下の棒グラフを分析してみましょう。まず、全ての都市において男性の方が女性よりもお金を使っており(その差が大きいのは都市Cのみ)、都市Cは男女ともに平均購入額の一位になっています。また、都市Bの男性は都市Aの男性よりも多くを購入しているのに対し、都市Aの女性は都市Bの女性よりも多く購入しているのも注目すべき点です。

```python
# Select Dataframe
purchase_mean_by_gender_city = df.loc[:,['Gender', 'City_Category','Purchase']]
# Pivot Table with Purchase Mean
pvt_purchase_mean_by_gender_city = purchase_mean_by_gender_city.pivot_table(purchase_mean_by_gender_city, 
                                                                           index = ['Gender','City_Category'],
                                                                           aggfunc = 'mean')
```

```python
fig, ax = plt.subplots(nrows = 1 , ncols= 2, figsize = (8,6), sharey = False)

# Bar Colors
color = ('lightslategray','mediumvioletred','sandybrown')

gender_list = ['F','M']

for subplot, gender in zip(ax.flatten(),gender_list ):
    individual_bar_plots(pvt_purchase_mean_by_gender_city, gender, ax = subplot, title = 'Gender:')
    
plt.tight_layout()
```

![](https://miro.medium.com/max/1148/1*Bh-qoBu8fObtmL6AbVR4yg.png)

#職業の分析:
消費者の職業が購買行動に影響を与える事はあるのでしょうか？まあ、職業と消費者の支出額には何かしらの関連性があると私は思います。これを棒グラフにプロットして検証してみましょう。

まず、各職業の平均購入額をプロットしてみましょう。この棒グラフは消費者の職業による購買習慣の違いについての一般的な情報を示しています。

下のグラフを見てみると、平均購入額については職業12、15、17が上位3位に入っていることがわかります。また、職業9、19、20は他の職業よりもお金を使わないことがわかります。これらの情報が何の役に立つのでしょうか？各職業の消費者が都市ごとに費やす金額に関する洞察を活用することはできるのでしょうか？これはまさに次のビジュアライゼーションで見ることができます。

最初の棒グラフは私たちに重要な情報を示してくれていますが、2番目のデータビジュアライゼーションは、私たちが都市A、B、Cにおける各職業による消費額の違いについてのより良い理解を与えてくれるでしょう。

```python
plt.figure(figsize=(8, 6))

sns.barplot(x = df.groupby('Occupation').mean()['Purchase'].index ,
           y = df.groupby('Occupation').mean()['Purchase'].values,
            orient = 'v',
            edgecolor = 'black')
plt.title('Purchase Means by Occupation')
plt.xlabel('Occupation')
plt.ylabel('Purchase Mean')
```

![](https://miro.medium.com/max/1028/1*fxXTwwwoiMG9EOlbi2e6TQ.png)

##都市別の職業:
下の棒グラフは、各都市の各職業の平均購入額を示したものです。興味深いのは、都市Cがほぼ全ての職業において平均購入額が最も高くなっていることです。このパターンに変化が見られるのは職業8、9、19のみです。もう一つの興味深いのは、都市Aで最も多くのお金を使っているのは、職業8番の人たちということです。

それぞれの職種を別々のチャートに分けることで、洞察をより柔軟に活用できます。言い換えれば、他のチーム(例えばマーケティング部門)の同僚たちが我々の分析結果を利用するのが特に簡単になるということです。グラフをプロットフォルダにエクスポートするだけで、画像を閲覧したり、PowerPointプレゼンテーションやその他のレポートにドラッグ＆ドロップしたりすることができます。

![](https://miro.medium.com/max/1400/1*aiVDlsXRGvnjYpzOMzw2pQ.png)

#ヒートマップ:
ヒートマップとは、色分けしたスキームを使用して異なる値を表すグラフィカルなデータ表現です。今回のケースでは、データセットの各特の相関関係を示すヒートマップを生成します。

ヒートマップを生成するには、各特徴のデータを数値化する必要があります。つまり、Product_ID、Gender、Age、City_Cat、Stay_In_Current_City_Years列のデータを下記のようなコードを使用して数値に変換しなければなりません。

```python

# Encoding Age Group
def age_encoder(age_group):
    
    if age_group == '0-17':
        x = 1
        
    elif age_group == '18-25':
        x = 2
    
    elif age_group == '26-35':
        x = 3
        
    elif age_group == '36-45':
        x = 4 
        
    elif age_group == '46-50':
        x = 5
        
    elif age_group == '51-55':
        x = 6
        
    elif age_group == '55+':
        x = 7
        
    return x
```

```python
# Convert categorical columns into numerical
df.Gender = df.Gender.map({'F': 0 , 'M': 1 })
df.City_Cat = df.City_Cat.map({ 'A':10, 'B':20, 'C':30})
df.Product_ID = df.Product_ID.str.replace("P","").astype(int)
df.Stay_In_Current_City_Years = df.Stay_In_Current_City_Years.map({'0':int(0),'1':int(1),'2': int(2),'3':int(3), '4+': int(4)})
```

```python
#Encoding Age Group
df.Age = df.Age.apply(age_encoder)

# Remaning columns to shorter names
df.columns = [ 'User_ID','Prod_ID','Gender','Age','Occupation', 'City', 'Years_In_Citys', 'Marital_St', 
       'Prod_Cat1', 'Prod_Cat2', 'Prod_Cat3','Purchase'
        ]
```

```python
# Use Spearman instead of default Pearson, since we are working with
# ordinal variables!
corr_matrix = ordinal_df.corr(method='spearman')

# Setup
fig, ax = plt.subplots(figsize=(10, 8))

# vmin and vmax control the range of the colormap
sns.heatmap(corr_matrix, cmap='RdBu', annot=True, fmt='.2f',
           vmin=-1, vmax=1)

plt.title("Correlations Between Features")

# Add tight_layout to ensure the labels don't get cut off
plt.tight_layout()
plt.show()
```

エンコードすると、下記のようなグラフになります。 興味深いのは、別のカテゴリーに分類されるので、製品間に正の相関関係があること、さらに年齢と配偶者の有無に相関関係があることです。

![](https://miro.medium.com/max/1400/1*_y_fQ2_TULi0OCrxvTeXvw.png)

#クラスターマップ:
最後にクラスターマップをプロットして今回の分析を終わりにしましょう。 クラスターマップは、階層的なクラスタリングを用いり、各特徴がどれだけ密接に関連しているかによってそれぞれの特徴をグループ化します。これにより、変数間の相関関係を分析する際の情報の有用性がさらに高くなります。この例では、分析したい特徴が11個あるので、どの変数が正または負に関連しているかをヒートマップではなく、グラフをクラスターに分割することで分析しやすくしています。

```python
sns.clustermap(corr_matrix, method='ward', cmap='RdBu', annot=True,
               vmin=-1, vmax=1, figsize=(10,8))

plt.title("Correlations Between Variables")
#plt.tight_layout()
plt.show()
```

![](https://miro.medium.com/max/1400/1*mWVtGHXHumc4IR6EPQENxQ.png)

上のプロットを見てみると、クラスタリングアルゴリズムはproduct_category2と3が同一のクラスターであると考えており、一方で年齢と配偶者の有無の2つによる、強い関連性のあるクラスターがまた別に形成されていることがわかります。これは各特徴間のリンクを見ることで確認できます。これらのクラスターは、形成されるとそこにさらに細かい分岐が形成され、より高い階層に分岐を持つクラスターよりも類似していることを示しています。

私が今回楽しめたように、あなたもこの分析を楽しんでいただけたなら幸いです。今回私たちは、あるデータに対する洞察・分析が出来るだけ早く必要な時に、発見した結果を素早く可視化できる関数を書くことで、いかに作業が楽になるかを見てきました。もっと効率的な方法があれば是非コメントで教えてください。

![](https://miro.medium.com/proxy/1*V0c7eqLKiTL-9iFNNY-3Fw.png)



# 翻訳協力
Original Author:  **[Jonathan Cabreira](https://towardsdatascience.com/@cabreirajm)** 
Thank you for letting us share your knowledge! 

この記事は以下の方々のご協力により公開する事が出来ました。
改めて感謝致します。
選定担当:yumika tomita
翻訳担当: shiro1
監査担当: takujio
公開担当: @aoharu

# ご意見・ご感想をお待ちしております
今回の記事は、いかがだったでしょうか？
・こうしたら良かった、もっとこうして欲しい、こうした方が良いのではないか
・こういったところが良かった
などなど、率直なご意見を募集しております。
いただいたお声は、今後の記事の質向上に役立たせていただきますので、お気軽にコメント欄にてご投稿ください。
みなさまのメッセージをお待ちしております。