Plotly+Pandas+Sklearn: первый выстрел Kaggle

Kaggle сбор данных
Plotly+Pandas+Sklearn: первый выстрел Kaggle

Общественный номер: You Er Hut
Автор: Питер
Редактор: Питер

Всем привет, меня зовут Питер~

Многие читатели спрашивали меня:Есть ли хорошие примеры анализа данных и интеллектуального анализа данных?? Ответ, конечно, это все на Kaggle.

Просто вам нужно найти время, чтобы учиться и даже играть в игры. У самого Питера нет опыта участия в соревнованиях, но он часто посещает Kaggle, чтобы изучить идеи и методы воротил соревнований.

Чтобы записать хорошие методы больших парней, а также улучшить себя, Питер решил открыть колонку:Обмен делами Kaggle.

Анализ ситуации будет время от времени обновляться позже. Все идеи исходят от крупных интернет-пользователей, особенно за распространение Top1. В основном Питер отвечает за:Систематизируйте идеи, изучайте технологии.

Сегодня я решил начать делиться статьей окластеризацияДело с использованием:Набор данных сегментации пользователей супермаркетов, пожалуйста, перейдите на официальный адрес сайта:супермаркет

Для того, чтобы облегчить всем практиковать, справочный ответ общедоступного номерасупермаркет, вы можете получить этот набор данных~

Ниже приведен исходный код Notebook, занимающий первое место, добро пожаловать, чтобы ознакомиться и изучить ~

библиотека импорта

# 数据处理
import numpy as np
import pandas as pd
# KMeans聚类
from sklearn.cluster import KMeans

# 绘图库
import matplotlib.pyplot as plt
import seaborn as sns
import plotly as py
import plotly.express as px
import plotly.graph_objects as go
py.offline.init_notebook_mode(connected = True)

Данные ЭДА

Импорт данных

Сначала мы импортируем набор данных:

Мы обнаружили, что в данных есть 5 атрибутивных полей, а именно идентификатор клиента, пол, возраст, средний доход, уровень потребления.

исследование данных

1. Форма формы данных

df.shape

# 结果
(200,5)

Всего 200 строк и 5 столбцов данных.

2. Ситуация с недостающим значением

df.isnull().sum()

# 结果
CustomerID                0
Gender                    0
Age                       0
Annual Income (k$)        0
Spending Score (1-100)    0
dtype: int64

Вы видите: все поля заполнены, пропущенных значений нет.

3. Тип данных

df.dtypes

# 结果
CustomerID                 int64
Gender                    object
Age                        int64
Annual Income (k$)         int64
Spending Score (1-100)     int64
dtype: object

В типе поля, кроме Пола, который является строкой, все остальные являются числовыми типами int64.

4. Описательная статистика

Описательная статистика в основном просматриваетсяЧисловойЗначение соответствующих статистических параметров данных, таких как: число, медиана, дисперсия, максимальное значение, квартиль и т. д.

Для удобства и отображения последующей обработки данных обрабатываются две точки:

# 1、设置绘图风格
plt.style.use("fivethirtyeight")

# 2、取出重点分析的3个字段
cols = df.columns[2:].tolist()
cols
# 结果
['Age', 'Annual Income (k$)', 'Spending Score (1-100)']

3 гистограммы атрибутов

Посмотрите на гистограммы «Возраст», «Годовой доход (тыс. долл.)», «Оценка расходов (1–100)», чтобы увидеть общее распределение:

# 绘图
plt.figure(1,figsize=(15,6))  # 画布大小
n = 0

for col in cols:
    n += 1 # 子图位置
    plt.subplot(1,3,n)  # 子图
    plt.subplots_adjust(hspace=0.5,wspace=0.5)  # 调整宽高
    sns.distplot(df[col],bins=20)  # 绘制直方图
    plt.title(f'Distplot of {col}')  # 标题
plt.show()  # 显示图形

гендерный фактор

гендерная демография

Посмотрите, сколько мужчин и женщин в этом наборе данных. В последующем будет рассмотрен вопрос о том, влияет ли пол на общий анализ.

Распределение данных по полу

sns.pairplot(df.drop(["CustomerID"],axis=1),
             hue="Gender",  # 分组字段
             aspect=1.5)
plt.show()

На приведенном выше графике двумерного распределения мы наблюдаем, что гендерный фактор мало влияет на другие 3 поля.

Взаимосвязь между возрастом и средним доходом по полу

plt.figure(1,figsize=(15,6))  # 绘图大小

for gender in ["Male", "Female"]:
    plt.scatter(x="Age", y="Annual Income (k$)", # 指定两个分析的字段
                data=df[df["Gender"] == gender],  # 待分析的数据,某个gender下
                s=200,alpha=0.5,label=gender  # 散点的大小、透明度、标签分类
               )
   
# 横纵轴、标题设置 
plt.xlabel("Age")  
plt.ylabel("Annual Income (k$)")
plt.title("Age vs Annual Income w.r.t Gender")
# 显示图形
plt.show()

Взаимосвязь между средним доходом и показателями потребления в разбивке по полу

plt.figure(1,figsize=(15,6))

for gender in ["Male", "Female"]:  # 解释参考上面
    plt.scatter(x = 'Annual Income (k$)',y = 'Spending Score (1-100)',
                data=df[df["Gender"] == gender],
                s=200,alpha=0.5,label=gender)
    
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)') 
plt.title("Annual Income vs Spending Score w.r.t Gender")
plt.show()

Распределение данных по полу

Наблюдайте за распределением данных с помощью графика скрипки и кластеризованного графика рассеяния:

# 分簇散点图:Swarmplots
# 小提琴图:violinplot

plt.figure(1,figsize=(15,7))
n = 0

for col in cols:
    n += 1  # 子图顺序
    plt.subplot(1,3,n)  # 第n个子图
    plt.subplots_adjust(hspace=0.5,wspace=0.5)  # 调整宽高
    # 绘制某个col下面的两种图形,通过Gender进行分组显示
    sns.violinplot(x=col,y="Gender",data=df,palette = "vlag") 
    sns.swarmplot(x=col, y="Gender",data=df)
    # 轴和标题设置
    plt.ylabel("Gender" if n == 1 else '')
    plt.title("Violinplots & Swarmplots" if n == 2 else '')
    
plt.show()

Результат выглядит следующим образом:

  • Просмотр распределения различных полей по разным гендерным группам
  • Наблюдайте, есть ли выбросы, выбросы и т. д.

Анализ корреляции атрибутов

Главное, соблюдать регрессию между атрибутами:

cols = ['Age', 'Annual Income (k$)', 'Spending Score (1-100)']  # 这3个属性的相关性分析
plt.figure(1,figsize=(15,6))
n = 0

for x in cols:
    for y in cols:
        n += 1  # 每循环一次n增加,子图移动一次
        plt.subplot(3,3,n)  # 3*3的矩阵,第n个图形
        plt.subplots_adjust(hspace=0.5, wspace=0.5)  # 子图间的宽、高参数
        sns.regplot(x=x,y=y,data=df,color="#AE213D")  # 绘图的数据和颜色
        plt.ylabel(y.split()[0] + " " + y.split()[1] if len(y.split()) > 1 else y)
        
plt.show()

Конкретные графики:

На схеме выше показаны две точки:

  • Главная диагональ представляет собой отношение между собой и самой собой и пропорциональна
  • Другие графики находятся между атрибутами, с разбросанным распределением данных и соответствующими графиками тенденций для моделирования.

Кластеризация между двумя атрибутами

Принцип и процесс алгоритма кластеризации здесь подробно не объясняются, и по умолчанию есть базовая основа.

Выбор значения К

Мы определяем значение k, строя график данных ELBOW. Выпуск больших данных:

1. Объяснение параметра с официального сайта:SCI kit-learn.org/stable/Modu…

2. Ссылка на объяснение на китайском языке:blog.CSDN.net/QQ_34104548…

df1 = df[['Age' , 'Spending Score (1-100)']].iloc[:,:].values  # 待拟合数据
inertia = []   # 空列表,用来存储到质心的距离之和

for k in range(1,11):  # k值的选取默认是在1-10之间,经验值是5或者10
    algorithm = (KMeans(n_clusters=k,  # k值
                       init="k-means++",  # 初始算法选择
                       n_init=10,  # 随机运行次数
                       max_iter=300,  # 最多迭代次数
                       tol=0.0001,  # 容忍最小误差
                       random_state=111,  # 随机种子
                       algorithm="full"))  # 算法选择 auto、full、elkan
    algorithm.fit(df1)  # 拟合数据
    inertia.append(algorithm.inertia_)  # 质心之和

Постройте изменение значения K в зависимости от суммы расстояний до центра тяжести:

plt.figure(1,figsize=(15,6))
plt.plot(np.arange(1,11), inertia, 'o')  # 数据绘制两次,标记不同
plt.plot(np.arange(1,11), inertia, '-', alpha=0.5)

plt.xlabel("Choose of K")
plt.ylabel("Interia")
plt.show()

В конце концов мы обнаружили, что k=4 больше подходит. Таким образом, k = 4 используется для выполнения реального процесса подбора данных.

Кластерное моделирование

algorithm = (KMeans(n_clusters=4,  # k=4
                       init="k-means++",
                       n_init=10,
                       max_iter=300,
                       tol=0.0001,
                       random_state=111,
                       algorithm="elkan"))
algorithm.fit(df1)  # 模拟数据

После того, как данные подходят, мы получаем метку label и 4 центроида:

labels1 = algorithm.labels_  # 分类的结果(4类)
centroids1 = algorithm.cluster_centers_  # 最终质心的位置

print("labels1:", labels1)
print("centroids1:", centroids1)

Чтобы показать эффект классификации исходных данных, в случае с официальным сайтом выполняется следующая операция, которую я лично считаю немного громоздкой:

Чтобы объединить данные:

Показать эффект классификации:

plt.figure(1,figsize=(14,5))
plt.clf()

Z = Z.reshape(xx.shape)

plt.imshow(Z,interpolation="nearest",
           extent=(xx.min(),xx.max(),yy.min(),yy.max()),
           cmap = plt.cm.Pastel2, 
           aspect = 'auto', 
           origin='lower')

plt.scatter(x="Age",
            y='Spending Score (1-100)', 
            data = df , 
            c = labels1 , 
            s = 200)

plt.scatter(x = centroids1[:,0], 
            y =  centroids1[:,1], 
            s = 300 , 
            c = 'red', 
            alpha = 0.5)

plt.xlabel("Age")
plt.ylabel("Spending Score(1-100)")

plt.show()

Что, если это был я? Конечно, идеальное решение — использовать Pandas+Plolty:

Взгляните на результаты визуализации классификации:

px.scatter(df3,x="Age",y="Spending Score(1-100)",color="Labels",color_continuous_scale="rainbow")

Вышеупомянутый процесс основан на оценке возраста и расходов (1-100) для кластеризации. По той же методике на официальном сайте также была проведена кластеризация полей Годовой доход (k$) и Spending Score (1-100).

Эффект заключается в следующем, разделенном на 5 категорий:

Кластеризация 3 атрибутов

Кластеризация выполняется в соответствии с возрастом, годовым доходом и показателем расходов, и, наконец, строится трехмерный график.

Выбор значения К

Способы те же, за исключением того, что выбираются 3 поля (выше каких-то 2)

X3 = df[['Age' , 'Annual Income (k$)' ,'Spending Score (1-100)']].iloc[: , :].values  # 选取3个字段的数据
inertia = []
for n in range(1 , 11):
    algorithm = (KMeans(n_clusters = n,
                        init='k-means++', 
                        n_init = 10 ,
                        max_iter=300, 
                        tol=0.0001,  
                        random_state= 111  , 
                        algorithm='elkan') )
    algorithm.fit(X3)   # 拟合数据
    inertia.append(algorithm.inertia_)

Нарисуйте диаграмму колена, чтобы определить k:

plt.figure(1 , figsize = (15 ,6))
plt.plot(np.arange(1 , 11) , inertia , 'o')
plt.plot(np.arange(1 , 11) , inertia , '-' , alpha = 0.5)
plt.xlabel('Number of Clusters') , plt.ylabel('Inertia')
plt.show()

Наконец, мы выбираем k = 6 для кластеризации

Модельная посадка

algorithm = (KMeans(n_clusters=6,  # 确定的k值
                    init="k-means++",
                    n_init=10,
                    max_iter=300,
                    tol=0.0001,
                    random_state=111,
                    algorithm="elkan"))
algorithm.fit(df2)

labels2 = algorithm.labels_
centroids2 = algorithm.cluster_centers_

print(labels2)
print(centroids2)

Получить метки и центроиды:

labels2 = algorithm.labels_
centroids2 = algorithm.cluster_centers_

Рисование

Для трехмерной кластеризации мы, наконец, выбираем график для отображения:

df["labels2"] = labels2

trace = go.Scatter3d(
    x=df["Age"],
    y= df['Spending Score (1-100)'],
    z= df['Annual Income (k$)'],
    mode='markers',
    
    marker = dict(
        color=df["labels2"],
        size=20,
        line=dict(color=df["labels2"],width=12),
        opacity=0.8
    )
)

data = [trace]
layout = go.Layout(
    margin=dict(l=0,r=0,b=0,t=0),
    title="six Clusters",
    scene=dict(
        xaxis=dict(title="Age"),
        yaxis = dict(title  = 'Spending Score'),
        zaxis = dict(title  = 'Annual Income')
    )
)

fig = go.Figure(data=data,layout=layout)

fig.show()

Ниже приведен окончательный эффект кластеризации: