Введение

Добро пожаловать в увлекательный мир науки о данных, где мы погружаемся в наборы данных, чтобы раскрыть ценные идеи. В этой статье мы отправляемся в захватывающее путешествие, используя четыре мощные модели машинного обучения — KNeighborsClassifier, Decision Tree, Logistic Regression и простую нейронную сеть с четырьмя слоями — для анализа знаменитого набора данных Iris. Но сначала давайте разберемся, что делает набор данных Iris таким важным.

Набор данных Iris — это классический эталонный набор данных в области машинного обучения. Он содержит измерения длины чашелистиков, ширины чашелистиков, длины лепестков и ширины лепестков для трех разных видов цветков ириса: setosa, versicolor и virginica. Каждый вид представлен 50 образцами, в результате чего всего 150 образцов. Значение набора данных Iris заключается в его роли в качестве основы для оценки и сравнения различных алгоритмов машинного обучения. Прогнозируя вид цветка ириса на основе его измерений, мы можем оценить точность и эффективность различных моделей.

Проект

1. Очистка данных

Набор данных, используемый в этом проекте, был получен от Kaggle, популярной платформы для доступа к различным наборам данных. Для обеспечения качества и надежности данных важным шагом была очистка данных. Для этого была использована новая библиотека под названием ydata-profiling, которая предоставила всесторонний обзор набора данных. Эта библиотека облегчила идентификацию повторяющихся записей, отсутствующих значений и типов переменных, присутствующих в базе данных, так что в данном случае все было в порядке. Кроме того, профилирование ydata создало информативные графики, демонстрирующие отношения и корреляции между переменными. Эти визуализации помогли глубже понять структуру набора данных и позволили провести более точный и глубокий анализ. В целом, использование возможностей ydata-профилирования значительно упростило процесс очистки данных, что позволило нам работать с надежным набором данных для нашего анализа.

# importing library

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from ydata_profiling import ProfileReport
import warnings


%matplotlib inline
sns.set(style="white", color_codes=True)
warnings.filterwarnings('ignore')


df = pd.read_csv("../data/Iris.csv") 
profile = ProfileReport(df, title="Profiling Report")
profile.to_widgets()

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

2. Визуализация

2.1 SepalLengthCm и SepalWidthCm

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

# Relationship between SepalLengthCm and SepalWidthCm features, colored by iris species, 
sns.jointplot(x="SepalLengthCm", y="SepalWidthCm", data=df, hue="Species",  kind="scatter", s=30)

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

2.2 Отношения

На последнем графике мы визуализируем только взаимосвязь между SepalLengthCm и SepalWidthCm, но на этом втором графике показан парный график, также с использованием Seaborn. Этот график обеспечивает комплексное представление набора данных, отображая попарные отношения между всеми комбинациями признаков, за исключением столбца «Id». Каждая диаграмма рассеяния на парной диаграмме представляет взаимосвязь между двумя функциями, причем разные цвета указывают на разные виды ирисов. Кроме того, диагональные графики отображают оценки плотности ядра (KDE), чтобы проиллюстрировать распределение каждого признака для каждого вида.

# Relationships between different iris features, colored by species, 
# and includes kernel density estimates on the diagonal.

sns.pairplot(df.drop("Id", axis=1), hue="Species", size=3, diag_kind="kde")

Этот график позволяет нам выявить корреляции и получить представление о том, как различные признаки влияют на классификацию видов. Демонстрация того, что у видов iris-setosa меньшие значения PetalLengthCm и PetalWidthCm, чем у двух других видов, облегчает идентификацию.

2.3 Коробчатый сюжет

Чтобы иметь в виду распределение мер, была использована серия диаграмм, каждая из которых представляет отдельную функцию набора данных Iris. Используя библиотеку seaborn, мы создаем отдельные диаграммы для длины чашелистиков, ширины чашелистиков, длины лепестков и ширины лепестков каждого вида ирисов. Ящичные диаграммы обеспечивают визуальное представление распределения указанного признака среди разных видов.

def graph_box(y):
    """
    Plots a boxplot of the specified feature 'y' for each iris species in the 'df' DataFrame using Seaborn.

    Parameters:
    - y: str, the name of the feature to be plotted on the y-axis.

    Returns:
    - None
    """
    sns.boxplot(x="Species", y=y, data=df)
 
plt.figure(figsize=(10,10))
     
# Adding the subplot at the specified
# grid position
plt.subplot(221)
graph_box('SepalLengthCm')
 
plt.subplot(222)
graph_box('SepalWidthCm')
 
plt.subplot(223)
graph_box('PetalLengthCm')
 
plt.subplot(224)
graph_box('PetalWidthCm')
 
plt.show()

Это позволяет нам наблюдать любые присутствующие вариации или выбросы, облегчая демонстрацию предыдущей гипотезы об отличительных характеристиках вида Iris setosa в его лепестках, но также можно увидеть, что существуют различия у iris-versicolor и iris_virginica также в лепестках. лепестки. И ширина чашелистика у радужки-сетозы больше, чем у других видов, даже когда другие его признаки незначительны.

2.4 Участок Радивз

Радиальный график также можно использовать для наблюдения за тем, как каждый набор данных ведет себя в зависимости от каждой переменной, для этого используется метод визуализации, называемый радиальной визуализацией (радиальная визуализация). Он использует библиотеки pandas.plotting и seaborn для представления каждой точки данных в виде точки на 2D-плоскости. Точки окрашены в зависимости от вида ириса. Объекты набора данных представлены в виде радиальных осей, где каждая ось соответствует определенному объекту.

from pandas.plotting import radviz

sns.set_palette("colorblind", n_colors=len(df['Species'].unique()))
colors = sns.color_palette()

fig, ax = plt.subplots(figsize=(8, 8))

# each data point is represented as a point on a 2D plane, 
# colored according to the iris species, and the features are represented as radial axes.

radviz(df.drop("Id", axis=1), 'Species', ax=ax, color=colors)

legend = ax.legend()
legend.get_frame().set_alpha(0.5) # optional: set the transparency of the legend box
legend.set_bbox_to_anchor((.65, 0.15))

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

2.5 Корреляционная матрица

Пятый график демонстрирует тепловую карту корреляционной матрицы. Вычисляя коэффициенты корреляции между числовыми характеристиками набора данных Iris, мы получаем матрицу, которая количественно определяет отношения между парами переменных. Библиотека seaborn позволяет нам создать тепловую карту из этой корреляционной матрицы. Тепловая карта имеет цветовую кодировку для представления силы и направления корреляции: более светлые оттенки указывают на более высокую положительную корреляцию, а более темные оттенки указывают на отрицательную корреляцию.

corr_mat = df.drop(columns='Id').corr(numeric_only=True).round(2)

# Create a mask for the upper triangle of the heatmap
mask = np.triu(np.ones_like(corr_mat, dtype=bool))


# Create a heatmap plot using seaborn
sns.heatmap(corr_mat, mask=mask, cmap='YlGnBu',
                annot=True, cbar=False)
plt.title('Correlation Matrix', fontsize=18)

Этот график позволяет нам определить, какие функции сильно коррелированы, как в этом случае PetalWidthCm и PetalLengthCm, обеспечивая понимание взаимозависимостей в наборе данных.

3. Предварительная обработка

Преобразование категорийных меток в числовой формат с использованием LabelEncoder из sklearn.preprocessing необходимо для анализа данных. Это преобразование позволяет интерпретировать данные и облегчает использование моделей машинного обучения, требующих числовых входных данных. Изменяя такие метки, как ['Setosa', 'Versicolor', 'Virginica'] на их соответствующие числовые значения [0, 1, 2], мы закладываем основу для дальнейшего анализа и шагов предварительной обработки, таких как горячее кодирование. Это преобразование расширяет диапазон аналитических методов и алгоритмов, которые можно применять к набору данных, открывая ценную информацию и повышая эффективность прогностических моделей.

from sklearn.preprocessing import LabelEncoder

# Change from ['Setosa', 'Versicolor', 'Virginica'] --> [0, 1, 2]
le = LabelEncoder()
df['Species'] = le.fit_transform(df['Species'])

4. Разделение на обучающие и тестовые наборы данных

Чтобы обеспечить надежную оценку моделей машинного обучения и нейронной сети, набор данных был разделен на наборы для обучения и тестирования с размером теста, значительно превышающим обычный диапазон. Это решение было принято благодаря исключительной точности этих моделей, поскольку меньший размер теста неизменно обеспечивал бы 100% точность. Сократив набор обучающих данных, можно было бы добиться более точной оценки их эффективности.

from sklearn.model_selection import train_test_split

#Splitting the data for NN
X = df.iloc[:,1:5].values
y = df.iloc[:,5].values
Y = pd.get_dummies(y).values

X_train,X_test, Y_train,Y_test = train_test_split(X,Y,test_size=0.85,random_state=42)

# Splitting data for ML
X1 = df.drop(columns=['Species'])
Y1 = df['Species']
x_train, x_test, y_train, y_test = train_test_split(X1, Y1, test_size=0.85,random_state=42)

Для нейронной сети (NN) были извлечены признаки (X) и определены метки (y). Затем данные были разделены на обучающую и тестовую выборки с размером теста 85%. Этот больший размер теста позволил более надежно оценить точность NN. Точно так же для традиционных моделей машинного обучения (ML) были определены функции (X1) и метки (Y1), а набор данных был разделен на наборы для обучения и тестирования, также с размером теста 85%.

5. Обучение машинному обучению

5.1 Логистическая регрессия

Логистическая регрессия — это тип линейной регрессии, используемый для оценки вероятности бинарного результата (например, «пройдено/не пройдено») на основе одной или нескольких переменных-предикторов (признаков). Алгоритм вычисляет границу решения, которая разделяет классы. Новые наблюдения классифицируются в зависимости от того, по какую сторону границы они попадают.

# logistic regression 
from sklearn.linear_model import LogisticRegression
modellog = LogisticRegression()
modellog.fit(x_train, y_train)
print("Accuracy: ",modellog.score(x_test, y_test) * 100)

Полученная точность составляет 93,75 %, что означает, что модель может предсказывать виды цветков ириса с точностью 93,75 %.

5.2 КНН

K-ближайшие соседи (KNN) — это алгоритм непараметрической классификации, в котором хранятся все доступные случаи и классифицируются новые наблюдения на основе меры сходства (например, функции расстояния). Алгоритм KNN вычисляет расстояние между новым наблюдением и всеми доступными наблюдениями, затем выбирает K ближайших наблюдений на основе заданной меры расстояния. Наконец, он относит новое наблюдение к наиболее частому классу среди K-ближайших наблюдений.

from sklearn.neighbors import KNeighborsClassifier
modelKN = KNeighborsClassifier()
modelKN.fit(x_train, y_train)
print("Accuracy: ",modelKN.score(x_test, y_test) * 100)

Модель обучается с использованием обучающих данных, и полученная точность составляет 95,31%, что указывает на то, что модель может предсказывать виды цветов ириса с точностью 95,31%.

5.3 Дерево решений

Деревья решений — это древовидные модели, которые рекурсивно разбивают данные на подмножества на основе наиболее важных признаков, чтобы классифицировать новые наблюдения. На каждом уровне алгоритм выбирает функцию, обеспечивающую наибольшую информационную выгоду для разделения данных. Процесс повторяется до тех пор, пока листовые узлы не станут чистыми (т. е. содержат только один класс наблюдений) или пока не будет выполнен заданный критерий остановки.

from sklearn.tree import DecisionTreeClassifier
modelDT = DecisionTreeClassifier()
modelDT.fit(x_train, y_train)
print("Accuracy: ",modelDT.score(x_test, y_test) * 100)

На этом изображении показано, как можно создать дерево решений в этом конкретном случае, но это могут быть и другие способы разделения с более сложными условиями. Модель обучается с использованием обучающих данных, и полученная точность составляет 89,84%. Это означает, что модель дерева решений может предсказывать виды цветов ириса с точностью 89,84%.

6. Результаты машинного обучения

Следующие результаты были получены с использованием функции ниже,

from sklearn.metrics import confusion_matrix, classification_report

def corr_maz(model):
    """
    Generates a confusion matrix heatmap and classification report for the 
    specified classification model, using the test dataset 'x_test' and 'y_test' 
    from the global environment.

    Parameters:
    - model: a trained classification model.

    Returns:
    - None
    """
    
    y_predict = model.predict(x_test).round()
    report = classification_report(y_test, y_predict)
    model_name = type(model).__name__
    score= model.score(x_test, y_test) * 100
    
    labels = ['Setosa', 'Versicolor', 'Virginica']
    
    sns.heatmap(confusion_matrix(y_test, y_predict), linewidth=0.5, annot=True, 
            cmap="YlGnBu", cbar=False, xticklabels=labels, yticklabels=labels)

    plt.ylabel("Real Labels")
    plt.xlabel("Predicted Labels")
    plt.title(f"The {model_name} model had {score:.2f}% accuracy")
    plt.show()
    
    print("Classification report:\n", report)

6.1. Логистическая регрессия

Модель логистической регрессии достигла точности 94% в предсказании видов цветков ириса.

corr_maz(modellog)

Глядя на отчет о классификации, мы наблюдаем высокую точность и полноту значений для каждого класса. Класс 0 и класс 2 имеют точность и полноту 100 %, что указывает на то, что модель хорошо справляется с правильной идентификацией этих классов. Класс 1 имеет немного более низкую точность 84%, но идеальный отзыв 100%. В целом модель демонстрирует хорошую производительность во всех классах со средним показателем f1 0,94. Это говорит о том, что модель логистической регрессии эффективна для различения разных видов цветков ириса на основе размеров их чашелистиков и лепестков.

6.2 KNeighboursClassifier

Модель K-ближайших соседей (KNN) достигла точности 95% в предсказании видов цветков ириса.

corr_maz(modelKN)

В отчете о классификации указываются высокая точность, полнота и значения f1-оценки для каждого класса. Все три класса демонстрируют превосходную точность, полноту и показатели f1 выше 0,90, что указывает на высокую производительность. Модель демонстрирует особенно высокие значения точности и полноты для класса 0 и класса 2, оба на уровне 100%. Класс 1 показывает немного более низкую точность 91%, но отзыв 95%. Эти результаты подчеркивают эффективность модели KNN в точной классификации видов цветков ириса на основе размеров их чашелистиков и лепестков.

6.3 Классификатор дерева решений

Классификатор дерева решений достиг точности 90% в предсказании видов цветов ириса.

Отчет о классификации демонстрирует относительно высокие значения точности, отзыва и оценки f1 для каждого класса. Класс 0 и класс 2 демонстрируют точность и скорость отзыва выше 88%, в то время как класс 1 имеет точность 83% и отзыв 88%. Показатель f1 варьируется от 0,85 до 0,94 по классам. Несмотря на несколько более низкую производительность по сравнению с логистической регрессией и KNN, классификатор дерева решений по-прежнему обеспечивает разумную точность и успешно различает разные виды цветов ириса.

В заключение, все три модели (логистическая регрессия, K-ближайшие соседи и дерево решений) демонстрируют хорошие результаты при классификации видов цветков ириса на основе размеров их чашелистиков и лепестков,
даже если они имеют только 20% (30 данных). ) данных, чтобы иметь возможность классифицировать остальные. Модель KNN достигла наивысшей точности 95%, за ней последовала логистическая регрессия с 94% и классификатор дерева решений с 90%. Каждая модель демонстрирует сильные стороны в различных показателях оценки, таких как точность, полнота и оценка f1, для соответствующих классов. В целом, эти модели предоставляют надежные инструменты для точной классификации видов в наборе данных по радужной оболочке, демонстрируя универсальность и эффективность различных алгоритмов машинного обучения.

7. Нейронная сеть

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

from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD,Adam
from keras import regularizers

# Creaction
model = Sequential()
model.add(Dense(10, input_shape=(4,), activation='elu', kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(8, activation='elu', kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(6, activation='elu', kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(3, activation='softmax'))

model.compile(Adam(lr=0.04), 'categorical_crossentropy', metrics=['accuracy'])

model.summary()

Но подождите, а что там с регуляризацией L2? Ну, это как тренерский свисток, который предотвращает переобучение. Видите ли, иногда наша сеть может стать слишком зацикленной на обучающих данных и упустить из виду общую картину. Регуляризация L2 вмешивается и говорит: «Эй, давайте держать эти веса под контролем!» Добавляя член регуляризации к функции потерь, он мягко подталкивает сеть в пользу меньших весов, обеспечивая более плавный и более общий процесс обучения. Это похоже на тренировку нашей сети, чтобы она оставалась сосредоточенной и не увлекалась ненужной сложностью.

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

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

Но вот настоящая фишка: мы компилируем нашу сеть с помощью оптимизатора Adam, интеллектуального алгоритма, который динамически регулирует веса, чтобы максимизировать эффективность обучения. Скорость обучения 0,04 гарантирует, что наша сеть может адаптироваться и улучшаться с течением времени. Мы выбираем категориальную функцию кросс-энтропийной потери, подходящую для задач классификации нескольких классов, таких как идентификация видов ирисов. Кроме того, мы внимательно следим за точностью измерения производительности нашей сети.

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

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

8. Результаты нейронной сети

В процессе обучения нейронной сети код

history = model.fit(X_train,Y_train,epochs=90, batch_size=16)

Этот фрагмент кода указывает, что модель была обучена в течение 90 эпох с размером пакета 16. Обучение включало обновление параметров модели на основе предоставленных обучающих данных (X_train и Y_train) для минимизации функции потерь. На протяжении всего обучения отслеживалась производительность модели, и для каждой эпохи записывались ключевые показатели, такие как потери и точность.

# Plotting the accuracy and loss
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'])
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')

plt.subplot(1, 2, 2)
plt.plot(history.history['loss'])
plt.title('Model Loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.show()

Анализируя записанные показатели, становится очевидным, что производительность модели улучшилась в ходе обучения. Значение потерь постепенно уменьшалось, что указывало на то, что прогнозы модели лучше соответствовали фактическим целевым значениям. Метрика точности неуклонно увеличивалась, что означает, что способность модели правильно классифицировать экземпляры улучшалась с каждой эпохой. Эти наблюдения предполагают, что модель научилась на данных обучения и стала более опытной в том, чтобы делать точные прогнозы.

y_pred = model.predict(X_test)

y_test_class = np.argmax(Y_test,axis=1)
y_pred_class = np.argmax(y_pred,axis=1)

print("Test items: {}".format(y_test_class.shape[0]))
print("Errors: {}".format((y_test_class != y_pred_class).sum()))
porcentaje_error = ((y_test_class != y_pred_class).sum() * 100) / y_test_class.shape[0]
print("Error Percentage: {} %".format(porcentaje_error))

labels = ['Setosa', 'Versicolor', 'Virginica']
sns.heatmap(confusion_matrix(y_test_class, y_pred_class), linewidth=0.5, annot=True, 
            cmap="YlGnBu", cbar=False, xticklabels=labels, yticklabels=labels)

plt.ylabel("Real Labels")
plt.xlabel("Predicted Labels")
plt.show()
print(classification_report(y_test_class,y_pred_class))

Судя по представленным результатам, производительность нейронной сети довольно высока. Процент ошибок 3,125% относительно низок, что указывает на то, что модель способна правильно классифицировать большую часть тестового набора. Кроме того, значения точности и полноты для каждого класса высоки, причем большинство значений выше 0,9, а значения f1-оценки также высоки, что указывает на хорошую общую производительность.

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

9. Заключение

Нейронная сеть (NN) продемонстрировала отличную производительность с точностью 97% и сбалансированной точностью, полнотой и f1-баллами выше 0,9 для большинства классов. Для сравнения, модели логистической регрессии и дерева решений достигли более низкой точности 94 % и 90 % соответственно, в то время как KNeighborsClassifier показал производительность, аналогичную NN, с точностью 95 %. В целом, NN превзошла модели ML с точки зрения точности и общей производительности, подчеркнув свою эффективность в этой задаче классификации. Тем не менее, рекомендуется дальнейшая оценка и тестирование, чтобы гарантировать надежность и обобщаемость этих результатов.