Отправьтесь вместе со мной в захватывающее путешествие, основанное на данных, поскольку мы демистифицируем удовлетворенность авиапассажиров с помощью алгоритма кластеризации K-средних. В этом пошаговом руководстве я проведу вас через весь процесс, убедившись, что у вас есть все инструменты и знания, необходимые для навигации в этом исследовании науки о данных.

Привет, я Da Data Guy! Прежде чем я начну, если вас интересуют Power BI, Python, Data Science и SQL, подпишитесь на меня на Medium и в моем LinkedIn. Я сосредотачиваюсь на написании качественных статей с разбивкой по каждому этапу процесса, чтобы вы могли следить за ним и тоже учиться. Вы также можете посетить мою страницу GitHub, чтобы просмотреть все мои опубликованные ресурсы.

Для начала вот ссылка на мой репозиторий GitHub, где вы найдете все необходимые ресурсы, чтобы следовать им и убедиться, что у вас настроена среда ноутбука Jupyter. Из репозитория загрузите два файла Excel, расположенные в папке Vanilla_Data, а также K-Means file из папки Jupyter Notebook. После загрузки настройте записную книжку и путь к папке, чтобы импортировать ванильный набор данных в локальную записную книжку.

Какова цель?

Цель этого анализа состоит в том, чтобы определить, какое «лицо/идентификатор» принадлежит к определенному кластеру или аналогичной группе, на основе их ответов на опрос пассажиров авиакомпаний. Вместо того, чтобы пытаться выполнить анализ по столбцам с помощью Power BI или статики на основе отдельных столбцов, K-средние стремятся найти центроиды кластера, которые минимизируют сумму квадратов внутри кластера, эффективно группируя схожие точки данных, сохраняя при этом разные кластеры.

Зачем использовать K-Means?

Использование K-Means простое, масштабируемое и легкое для извлечения результатов и важности признаков. По моему опыту, прогон данных через алгоритм бесполезен, если вы не можете определить, какие функции имеют больший вес, чем другие, или не можете определить, какая строка в наборе данных принадлежит какому кластеру. K-Means позволяет вам генерировать и извлекать эти данные и добавлять их обратно в исходный набор данных. В конце этого урока вы увидите, как это делается.

Давай начнем

  1. Загрузите библиотеки и набор данных в блокнот Jupiter.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import xgboost as xgb
import seaborn as sns
#sns.set(color_codes = True)
#sns.set(style="whitegrid")
#sns.set_palette("Set3")

# Get multiple outputs in the same cell
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

# Ignore all warnings
import warnings
warnings.filterwarnings('ignore')
warnings.filterwarnings(action='ignore', category=DeprecationWarning)
pd.set_option('display.max_columns', None)
# For cluster analysis
df = pd.read_csv("airline_passenger_satisfaction.csv")

2. Определите нулевые значения, которые имеют только 1 столбец «Задержка прибытия» со значением 393.

df.isnull().sum()

3. Заполнение нулевых значений с помощью интерполяции. Интерполяция заполняет нулевые значения оценками, основанными на окружающих ненулевых значениях.

df['Arrival Delay'].interpolate(method='linear', inplace=True)

4. Создайте копию кадра данных в качестве резервной копии, а также добавьте окончательные результаты кластера.

df2=df.copy()

5. Примените One-Hot Encoding к параметрам «Удовлетворенность» (цель), «Класс», «Тип путешествия», «Тип клиента», «Пол».

columns_to_encode = ['Gender', 'Customer Type', 'Type of Travel', 
'Class', 'Satisfaction']

# Perform one-hot encoding
df_encoded = pd.get_dummies(df, columns=columns_to_encode)

# Overwrite original dataframe 
df=df_encoded

6. Нормируйте данные для небинарных столбцов и столбцов не по шкале Лайкерта (шкала 1–5). Это столбцы «Возраст, Дистанция боя, Задержка вылета, Задержка прибытия».

Почему после использования стандартного масштабатора появляются отрицательные значения?
Ожидаются отрицательные значения после нормализации с помощью StandardScaler, поскольку этот масштабатор выполняет стандартизацию, которая преобразует данные так, чтобы среднее значение равнялось нулю, а стандартное отклонение равнялось единице. Результирующие значения могут быть как положительными, так и отрицательными, в зависимости от их исходного распределения.

Цель стандартизации состоит в том, чтобы масштабировать данные до стандартного нормального распределения, где среднее значение сосредоточено на нуле, а стандартное отклонение равно 1. Этот метод нормализации помогает в случаях, когда абсолютные значения или величины признаков не так важны, как их относительное положение или распределение.

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

from sklearn.preprocessing import StandardScaler

#first 4 columns after the ID column
columns_to_normalize = df.columns[1:5] 

# Initialize the StandardScaler
scaler = StandardScaler()

# Fit and transform the selected columns
df[columns_to_normalize] = scaler.fit_transform(df[columns_to_normalize])

7. Удаление столбца «ID» перед запуском набора данных через алгоритм K-Means. Это устранит ненужную информацию, уменьшит размерность и улучшит интерпретируемость.

df_without_id = df.drop('ID', axis=1)

8. Проверка алгоритма и расчет количества используемых кластеров.

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

# Assuming your preprocessed DataFrame is named df

# Remove any non-numeric columns if present
df_numeric = df_without_id.select_dtypes(include='number')

# Determine the range of cluster numbers to consider
max_clusters = 23  # 23 Maximum number of clusters to consider

# Run K-means clustering and calculate distortions
distortions = []
for i in range(1, max_clusters+1):
    kmeans = KMeans(n_clusters=i, random_state=42)
    kmeans.fit(df_numeric)
    distortions.append(kmeans.inertia_)

# Calculate the differences in distortions
differences = [distortions[i]-distortions[i-1] for i in range(1,len(distortions))]

# Find the cluster number with the significant change in distortion
elbow_index = differences.index(max(differences)) + 1
elbow_cluster_num = elbow_index + 1

Построение кривой локтя

# Plot the distortions and mark the elbow point
plt.plot(range(1, max_clusters+1), distortions, marker='o')
plt.xlabel('Number of Clusters')
plt.ylabel('Distortion')
plt.title('Elbow Curve')
plt.axvline(x=elbow_cluster_num, color='r', linestyle='--',
 label='Elbow Point')
plt.legend()
plt.show()

# Use the cluster number at the elbow point for further analysis
print("Selected Number of Clusters:", elbow_cluster_num)

Примечание. Приведенный ниже имидж-сканер обработал максимальное количество 25 кластеров, и из них он определил на основе различий в искажениях между каждым центроидом, что 24 было наиболее оптимальным числом кластеров на основе расчета. Вы не обязаны всегда следовать этому методу, так как он может быть не лучшим для данных, с которыми вы работаете. Как всегда, изучите свои данные, прежде чем следовать тому, что сделали/предложили другие.

9. Применение PCA перед визуализацией кластеров K-средних снижает размерность и улучшает интерпретируемость, способствуя более четкому пониманию структуры кластера в пространстве меньшей размерности.

from sklearn.cluster import KMeans
from sklearn.decomposition import PCA

# Assuming your preprocessed DataFrame is named df

# Remove any non-numeric columns if present
df_numeric = df_without_id.select_dtypes(include='number')

# Apply dimensionality reduction using Principal Component Analysis (PCA)
pca = PCA(n_components=25)
df_pca = pca.fit_transform(df_numeric)

На графике осыпи будет отображаться линейный график, где ось x представляет количество компонентов, а ось y представляет объясненный коэффициент дисперсии. Найдите точку «локтя» на графике, где выравнивается объясненное отношение дисперсии. Эта точка указывает на убывающую отдачу с точки зрения захвата дополнительной изменчивости.

# Calculate the explained variance ratio
explained_var = pca.explained_variance_ratio_

# Print the explained variance ratio for each principal component
for i, ratio in enumerate(explained_var):
    print(f"Explained Variance Ratio for Principal Component {i+1}:{ratio}")

# Plot the explained variance ratio
plt.bar(range(len(explained_var)), explained_var)
plt.xlabel('Principal Component')
plt.ylabel('Explained Variance Ratio')
plt.title('Explained Variance Ratio per Principal Component')
plt.show()

10. Выбор количества PCA, которые мы хотим использовать в нашем алгоритме K-Means, может быть основан на этой диаграмме. Вы можете поиграть с тем, сколько вы хотите использовать, обычно вы выбираете количество PCA в зависимости от того, когда оно выравнивается. Вы можете подумать, что 17 будет ответом, но после того, как я прогнал его через алгоритм K-средних, я получил слишком большую размерность. Я уменьшил его до 9 и обнаружил, что эти результаты мне больше нравятся. Это основано на моем понимании данных. Опять же, очень важно.

# Redo the amount of PCA n_compoents based on where it levels off. 
pca = PCA(n_components=9) #standard is 2
df_pca = pca.fit_transform(df_numeric)
# Apply K-means clustering algorithm
kmeans = KMeans(n_clusters=15, random_state=42)
cluster_labels = kmeans.fit_predict(df_pca)

# Add the cluster labels to the DataFrame
df_without_id['Cluster'] = cluster_labels

11. Добавление столбца ID обратно в исходный фрейм данных

df = pd.concat([df['ID'], df_without_id], axis=1)

12. Добавьте «df_with_cluster в df2, который я создал ранее. Это позволяет нам поместить кластеры обратно в фрейм данных до того, как мы нормализуем и закодируем наш фрейм данных (df).

# Add the last column DataFrame back to the original DataFrame
df_with_cluster = pd.concat([df_with_cluster,df2], axis=1)

13. Визуализация подсчета в каждом кластере.

# Assuming your DataFrame is named df
cluster_counts = df['Cluster'].value_counts()

# Generate the bar chart
plt.bar(cluster_counts.index, cluster_counts.values)
plt.xlabel('Cluster')
plt.ylabel('Count')
plt.title('Cluster Distribution')
plt.show()

14. Визуализируйте кластеры на диаграмме рассеивания

plt.scatter(df_pca[:, 0], df_pca[:, 1], c=cluster_labels)
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.title('K-Means Clustering')
plt.colorbar(cmap='bwr', label='Cluster')

15. Экспорт фрейма данных с кластерами.

# File pathway may need to be updated to whatever pathway you've created.
df_with_cluster.to_csv('Cleaned DF\Cluster_K-Means_DF.csv', index=False)

16. Экспорт фрейма данных с кластерами на очищенный и нормализованный фрейм данных.

# File pathway may need to be updated to whatever pathway you've created.
df.to_csv('Cleaned DF\Cleaned_K-Means_DF.csv', index=False)

Вы сделали это!

Поздравляем с завершением этого захватывающего путешествия по очистке, нормализации и обработке набора данных с помощью PCA и алгоритма K-средних!

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

Спасибо!

Если вам понравилась эта статья, пожалуйста, подпишитесь на меня, а если вы заинтересованы в создании собственной модели прогнозирования оттока, нажмите здесь: «Создайте свою собственную модель прогнозирования оттока | Середина""."