Познакомьтесь с машинным обучением

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

Машинное обучение делится на контролируемое и неконтролируемое обучение. Под наблюдением – это контролируемое машинное обучение, которое создает модели, делающие прогнозы на основе доказательств неопределенности. Алгоритмы контролируемого обучения берут набор входных данных и известные реакции на данные (выходные данные) и обучают модель выработке разумных прогнозов реакции на новые данные. Обучение без учителя используется для получения выводов на основе наборов данных, состоящих из входных данных без помеченных ответов. Кластеризация — это распространенный метод обучения без наблюдения, используемый для исследовательского анализа данных с целью поиска закономерностей или закрытых группировок в данных.

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

Алгоритм k-ближайших соседей, также известный как K-NN, представляет собой непараметрический классификатор с контролируемым обучением, который использует близость для классификации или прогнозирования группировки отдельной точки данных. Хотя его можно использовать как для задач регрессии, так и для задач классификации, обычно он используется в качестве алгоритма классификации, исходя из предположения, что похожие точки могут быть найдены рядом друг с другом.

Наивный Байес — это алгоритм классификации, который использует теорему вероятности Байеса для прогнозирования неизвестных классов. Он использует вероятность для определения класса, к которому принадлежит контрольная точка. Наивный Байес — это чисто статистическая модель. Этот алгоритм называется «наивным» из-за предположения, что признаки/атрибуты в наборах данных взаимно независимы.

В этой статье мы сравним эффективность K-NN и Naive Bayes для классификации сахарного диабета с использованием языка программирования Python в Google Colab.

О данных

Для демонстрации мы будем использовать набор данных о диабете в Индии Пима. Данные доступны на Kaggle, их можно скачать здесь.

Набор данных состоит из девяти столбцов: «Беременность», «Глюкоза», «Кровяное давление», «Толщина кожи», «Инсулин», «ИМТ», «Диабетическая функция родословной», «Возраст» и «Исход». Первые восемь столбцов представляют особенности, а последний столбец (Результат) служит меткой и имеет два различных типа: 0 (без диабета) и 1 ( Диабетик).

Узнайте больше об индейцах пима и диабете

Племя индейцев пима — одно из индейских племен Америки. Пима (Акимел О'одхам, также может писаться как Акимел О'отам), прозванные «Речными людьми», — это группа коренных американцев, проживающая в южной Аризоне вдоль рек Хила и Колорадо.

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

Входные данные

Сначала мы импортируем библиотеку pandas, а затем передадим имя файла в функцию pd.read_csv(), которая вернет фрейм данных.

import pandas as pd
df = pd.read_csv("diabetes.csv")
df

Чтобы просмотреть тип данных в наборе данных, мы можем использовать функцию data.info. Это покажет тип данных для каждого столбца.

df.info()

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

Кроме того, есть две переменные с плавающим типом данных, а именно BMI и DiabetesPedigreeFunction.

Важно отметить, что переменная «Результат» в наборе данных имеет категориальный тип и представлена ​​числами 0 и 1.

Визуализация данных

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

  1. Женщины с многоплодной беременностью имеют более высокий шанс заболеть диабетом.
  2. У человека с высокой концентрацией глюкозы в плазме больше шансов заболеть диабетом.
  3. У человека с высоким кровяным давлением больше шансов заболеть диабетом.
  4. Человек с более высоким средним значением трицепса (жировой клетчатки) будет иметь более высокий шанс заболеть диабетом.
  5. У человека с большим количеством инсулина больше шансов заболеть диабетом.
  6. У человека с высоким ИМТ будет больше шансов заболеть диабетом.
  7. У людей старшего возраста больше шансов заболеть диабетом.

Для усиления предположений, выдвинутых автором, анализ и визуализация данных были проведены следующим образом:

palette = {0: 'blue', 1: 'red'}
def look_at_distr_hist(*args, df_num=None, df_cat=None, class_feature="Outcome"):
    if df_num is not None:
        plt.figure(figsize = [20, 15])
        counter = 0
        print('look at the distribution for all numeric variables')
        for i in df_num.columns:
            counter += 1
            print(counter, ':', i)
            plt.subplot(3, 3, counter)
            sns.histplot(data = df, x = df[str(i)], hue = df[class_feature], multiple  = 'dodge', palette=palette, kde=True)
            plt.title(str(i))
        plt.plot()

    #Melihat distribusi untuk semua variabel kategori
    if df_cat is not None:
        print('look at the distribution for all categorical variables')
        plt.figure(figsize = [20, 15])
        counter = 0
        for i in df_cat.columns:
            counter += 1
            print(counter, ':', i)
            plt.subplot(3, 3, counter)
            sns.histplot(data = df, x = df[str(i)], hue = df[class_feature], multiple  = 'dodge', palette=palette)
            plt.title(str(i))
    plt.plot();

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

  1. Известно, что у 500 (66,84%) пациентов тест на диабет оказался отрицательным, а у 268 (33,16%) пациентов тест на диабет оказался положительным.
  2. Чем выше уровень глюкозы, тем больше вероятность положительного диагноза диабета.
  3. Более высокое кровяное давление увеличивает вероятность положительного диагноза диабета.
  4. Большая толщина кожной складки трицепса (жировой жир) связана с повышенной вероятностью положительного диагноза диабета.
  5. Более высокие уровни инсулина коррелируют с повышенной вероятностью положительного диагноза диабета.
  6. Более высокий ИМТ связан с повышенной вероятностью положительного диагноза диабета.
  7. Больше людей в возрастной группе 20–25 лет дали отрицательный результат на диабет по сравнению с людьми в возрастной группе 30 лет, у которых была более высокая вероятность положительного результата теста на диабет.

Классификация анализа с использованием K-ближайшего соседа

Определение независимых переменных и зависимых переменных

Нам нужно разделить столбцы на зависимые (Результаты или данные метки) и независимые переменные (Восемь функций). X содержит независимую переменную, а y содержит зависимую переменную.

x = df.drop(["Outcome"], axis = 1)
x.head()

Результаты для независимой переменной (x) были получены следующим образом:

Затем определите зависимую переменную (y) с помощью следующей команды:

y = df['Outcome']
y.head()

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

Разделение данных

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

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.30, random_state = 123)
print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)

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

Чтобы избежать переобучения, набор данных был разделен на обучающий и тестовый наборы. Размер теста был установлен на уровне 0,30, что привело к разделению 70% для обучающих данных и 30% для тестовых данных. В предоставленном синтаксисе использовался случайный ключ «123».

Масштабировать данные

from sklearn.preprocessing import StandardScaler  
scaler = StandardScaler()  
scaler.fit(x_train)
x_train = scaler.transform(x_train)  
x_test = scaler.transform(x_test)

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

Затем мы начинаем прогнозирование, используя K = 10 (где k определяется каждым исследователем).

from sklearn.neighbors import KNeighborsClassifier 
classifier = KNeighborsClassifier(n_neighbors=10) 
classifier.fit(x_train, y_train)
y_pred = classifier.predict(x_test)
print(y_pred)

Матрица путаницы

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

На основе анализа с использованием K-NN были получены следующие результаты матрицы путаницы:

from sklearn.metrics import classification_report, confusion_matrix , accuracy_score
print(confusion_matrix(y_test, y_pred))  
print(classification_report(y_test, y_pred)) 
pd.crosstab(y_test, y_pred, rownames=['Actual'], colnames=['Predicted'], margins=True)

import seaborn as sns
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize = (8, 5))
sns.heatmap(confusion_matrix(y_test, y_pred), annot = True, fmt = ".0f", ax = ax)
plt.xlabel("y_head")
plt.ylabel("y_true")
plt.show()

Основываясь на приведенных выше выводах матрицы путаницы, мы можем наблюдать следующие результаты, используя метод K-ближайших соседей для K = 10:

  1. Частота True Positive/TP (у человека диабет и прогнозируемый диабет) составляет 127 .
  2. Частота Истинно отрицательный результат/TN (у человека не было диабета и прогнозируемое отсутствие диабета) составляет 41.
  3. Частота ложноположительного результата/FP (у человека не было диабета, но прогнозировался диабет) составляет 16.
  4. Частота ложноотрицательных результатов/FN (у человека был диабет, но предполагаемое отсутствие диабета) составляет 47.

Оценить модель с K = 10

Чтобы оценить модель, мы проверим точность, используя фактические и прогнозируемые значения. Сначала мы импортируем accuracy_score для расчета точности из sklearn и проверим, как часто классификатор правильно идентифицирует человека с диабетом или нет.

from sklearn.metrics import accuracy_score
print("Train Set Accuracy : "+str(accuracy_score(y_train, classifier.predict(x_train))*100))
print("Test Set Accuracy : "+str(accuracy_score(y_test, classifier.predict(x_test))*100))

Как повысить точность?

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

error = []
# Calculating error for K values between 1 and 40
for i in range(1, 30): 
 knn = KNeighborsClassifier(n_neighbors=i)
 knn.fit(x_train, y_train)
 pred_i = knn.predict(x_test)
 error.append(np.mean(pred_i != y_test))
plt.figure(figsize=(12, 6))  
plt.plot(range(1, 30), error, color='green', linestyle='-', marker='o',  
         markerfacecolor='yellow', markersize=10)
plt.title('Error Rate K Value')  
plt.xlabel('K Value')  
plt.ylabel('Mean Error')

Согласно приведенному выше графику, наименьшая средняя ошибка возникает, когда значение K равно 3. Следующий тест также будет проводиться с K = 3.

from sklearn.neighbors import KNeighborsClassifier 
classifier = KNeighborsClassifier(n_neighbors=3) 
classifier.fit(x_train, y_train)
y_pred = classifier.predict(x_test)
print(y_pred)

from sklearn.metrics import classification_report, confusion_matrix , accuracy_score
print(confusion_matrix(y_test, y_pred))  
print(classification_report(y_test, y_pred)) 
pd.crosstab(y_test, y_pred, rownames=['Actual'], colnames=['Predicted'], margins=True)

import seaborn as sns
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize = (8, 5))
sns.heatmap(confusion_matrix(y_test, y_pred), annot = True, fmt = ".0f", ax = ax)
plt.xlabel("y_head")
plt.ylabel("y_true")
plt.show()

Основываясь на выводе матрицы путаницы, приведенной выше, мы можем наблюдать следующие результаты, используя метод K-ближайших соседей для K = 3:

  1. Частота True Positive/TP (у человека диабет и прогнозируемый диабет) составляет 118 .
  2. Частота Истинно отрицательный результат/TN (у человека не было диабета и прогнозируемое отсутствие диабета) составляет 58.
  3. Частота ложноположительного результата/FP (у человека не было диабета, но прогнозировался диабет) составляет 25.
  4. Частота ложноотрицательных результатов/FN (у человека был диабет, но прогнозировалось отсутствие диабета) составляет 30.

Оценить модель с K = 3

print("Train Set Accuracy : "+str(accuracy_score(y_train, classifier.predict(x_train))*100))
print("Test Set Accuracy : "+str(accuracy_score(y_test, classifier.predict(x_test))*100))

Полученное значение точности было довольно хорошим, а именно 76% при K = 3, что превосходит использование других значений K.

Классификация анализа с использованием наивного метода Байеса

Разделение данных

from sklearn.model_selection import train_test_split
x = df.drop("Outcome", axis = 1)
y = df[["Outcome"]]

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

#Import Gaussian Naive Bayes Model
from sklearn.naive_bayes import GaussianNB
#Create a Gaussian Classifier
model = GaussianNB()
#Train the model using the training sets
model.fit(x_train, y_train)
#Predict the response for test datasets
y_pred = model.predict(x_test)

Оценка модели

from sklearn.metrics import accuracy_score 
print("Train Set Accuracy : "+str(accuracy_score(y_train, model.predict(x_train))*100))
print("Test Set Accuracy : "+str(accuracy_score(y_test, model.predict(x_test))*100))

мы также создали отчет о классификации для измерения качества прогноза на основе наивной байесовской модели.

test_pred = model.predict(x_test)
print(classification_report(y_test, test_pred))
print(confusion_matrix(y_test, test_pred))
pd.crosstab(y_test, test_pred, rownames=['Actual'], colnames=['Predicted'], margins=True)

import seaborn as sns
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize = (8, 5))
sns.heatmap(confusion_matrix(y_test, y_pred), annot = True, fmt = ".0f", ax = ax)
plt.xlabel("y_head")
plt.ylabel("y_true")
plt.show()

Основываясь на выводе матрицы путаницы, приведенной выше, мы можем наблюдать следующие результаты, используя наивный метод Байеса:

  1. Частота True Positive/TP (у человека диабет и прогнозируемый диабет) составляет 124 .
  2. Частота Истинно отрицательный результат/TN (у человека не было диабета и прогнозируемое отсутствие диабета) составляет 56.
  3. Частота ложноположительных результатов/FP (у человека не было диабета, но прогнозировался диабет) составляет 19.
  4. Частота ложноотрицательных результатов/FN (у человека был диабет, но прогнозировалось отсутствие диабета) составляет 32.

Заключение

В этом исследовании сравнивались два алгоритма: K-Nearest Neighbor (KNN) и Naive Bayes для классификации диагнозов диабета. Тесты показали, что алгоритм Наивного Байеса достиг более высокого уровня точности по сравнению с алгоритмом K-ближайшего соседа (KNN). В частности, алгоритм Наивного Байеса достиг наилучшей точности 78%, тогда как алгоритм KNN достиг точности 76% при K = 3 (поскольку K давал более высокую точность по сравнению с другими значениями). Кроме того, примечательно, что алгоритм Наивного Байеса имел самое высокое значение полноты 0,87, а алгоритм KNN имел более высокое значение точности 0,80.

Проведение этого исследования дает ценную информацию о классификации диабета и превосходстве алгоритмов Наивного Байеса и KNN. Эта информация служит справочной информацией и способствует расширению знаний для последующих исследований.