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

Набор данных можно скачать с kaggle по следующей ссылке https://www.kaggle.com/gilsousa/habermans-survival-data-set. Если вы новичок в Kaggle, это веб-сайт, на котором есть множество наборов данных для выполнения, изучения машинного обучения, участия в соревнованиях и связи с сообществом. По ссылке вы можете скачать набор данных после входа в Kaggle.

После загрузки CSV-файла при его открытии вы увидите 4 столбца, заполненные какими-то числами без заголовка (имени столбца). Для этого вы можете снова перейти по приведенной выше ссылке и перейти к подробным сведениям для файла CSV.

В разделе сведений вы найдете всю важную информацию о наборе данных, такую ​​как источник набора данных, информацию о столбцах и их значениях. Набор данных Хабермана содержит информацию из тематического исследования, чтобы распознать любую закономерность для прогнозирования рака молочной железы среди 306 пациентов. Набор данных имеет возраст пациентов (числовое значение), год операции пациента (значение уменьшено до -> год-1900 для удобства, числовое), количество обнаруженных положительных подмышечных узлов (числовое) и метку класса, которая имеет 2 класса -> 1 и 2, где 1 присутствует, когда больной выжил более 5 лет после операции, и 2, когда больной умер в течение 5 лет после операции.

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

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

Теперь мы можем начать с импорта набора данных в блокнот Jupyter и продолжить анализ.

Сначала мы импортируем все необходимые библиотеки, а затем набор данных.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

Поскольку в нашем наборе данных нет имен столбцов, мы должны импортировать набор данных и присвоить имена столбцов каждому столбцу. После этого мы увидим 5 верхних строк просто для проверки.

haberman=pd.read_csv(r'C:\Users\u363200\Downloads\haberman dataset\haberman_columns.csv')
haberman.columns=['Age','Operation_Year','Positive_axillary_nodes_detected','Survived_5years_or_not']
haberman.head()

Выход-

Хорошо, теперь помните,наша цель — определить переменные/характеристики, которые имеют отношение к определению того, прожил ли пациент 5 лет или больше или нет. Итак, мы можем сказать, что наши входные данные - это возраст, год операции, обнаруженные положительные подмышечные узлы и выходные данные, пережившие 5 лет или нет.

Давайте проверим некоторую высокоуровневую информацию и статистику о наборе данных.

print(haberman.shape)

Выход-

(306,4)

Здесь dataset.shape дает нам размеры таблицы, то есть количество строк и количество столбцов. Мы можем сказать, что общее количество точек данных, которые у нас есть, составляет 306, а общее количество столбцов или функций (вход + вывод) равно 4.

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

haberman.describe()

Выход-

dataset.describe() дает нам всю высокоуровневую статистическую информацию о наборе числовых данных. Здесь стандартное отклонение означает стандартное отклонение, 25% — это значение 25-го процентиля (25% всех значений ниже этой точки) и аналогично с 50% и 75%.

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

haberman.info()

Выход-

Здесь мы видим, что все столбцы данных имеют целочисленный тип и все значения не равны нулю. Так как это проблема классификации по определению того, какие признаки могут помочь нам получить некоторую закономерность для успешного выживания пациентов в течение 5 или более лет, и мы не собираемся применять какую-либо модель машинного обучения, на данный момент мы можем изменить тип данных Survived_5years_or_not на строковый тип со значением «да», если пациент прожил 5 и более лет (=1), и «нет», если не прожил 5 лет.

Для этого мы можем создать простую функцию отображения, которая будет отображать все 1 с «да» и 2 с «нет».

boolean_convertor={1:'yes',2:'no'}
haberman['Survived_5years_or_not']=haberman['Survived_5years_or_not'].map(boolean_convertor)
haberman.head()

Выход-

Во-первых, я создал словарь с именем boolean_convertor, в котором есть ключи 1,2 (которые вводятся) и значения «да», «нет» (которые выводятся). Затем я использовал .map() для отображения этого словаря на Survived_5years_or_not. Наконец, я напечатал первые 5 строк, чтобы проверить, работает ли сопоставление. Оно работает!

Количество точек данных для каждой категории можно рассчитать с помощью .value_counts(). Эта функция даст нам количество точек данных (строк), доступных для каждой категории.

haberman['Survived_5years_or_not'].value_counts()

Выход-

Таким образом, имеется 225 точек данных из 306, где пациент прожил 5 или более лет, и 81 точка данных были неудачными пациентами, которые не могли выжить. Это несбалансированный набор данных (обе точки данных категории разные).

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

sns.set_style("whitegrid");
sns.pairplot(haberman, hue="Survived_5years_or_not", height=4);
plt.show()

Выход-

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

sns.FacetGrid() создает сетку/матрицу для ваших переменных и принимает данные из набора данных, категория берется в виде цвета (оттенка), т.е. ваши категории будут иметь разные цвета. .set_style("whitegrid") устанавливает фон/холст как белый с линиями сетки.

Если вы погуглите FacetGrid, определение TutorialPoints говорит:

«Объект FacetGrid принимает в качестве входных данных фрейм данных и имена переменных, которые будут формировать измерения строки, столбца или оттенка сетки. Переменные должны быть категориальными, и данные на каждом уровне переменной будут использоваться для аспекта вдоль этой оси. Объект FacetGrid принимает фрейм данных в качестве входных данных и имена переменных, которые будут формировать строку, столбца или оттенка сетки. Переменные должны быть категориальными, и данные на каждом уровне переменной будут использоваться для аспекта вдоль этой оси».

Он принимает входные данные в виде .pairplot(dataset,hue=categorical_column,height=size or shape), а в последней строке .add_legend() будет использовать легенду, чтобы понять, какой цвет представляет какую категорию.

Здесь мы видим, что графики этих диагональных элементов отличаются от графиков остальных. Графики, кроме диагональных, имеют 2 разные функции, которые можно увидеть по осям x и y, поэтому, когда мы строим 2 числовые разные функции, мы получаем графики рассеяния (https://www.mathsisfun.com/data/scatter). -xy-plots.html отличная статья для изучения точечных диаграмм).

Теперь диагональные элементы имеют оси x и y в виде одних и тех же столбцов, поэтому вместо графиков рассеяния присутствуют графики плотности. Графики плотности представляют собой сглаженные версии гистограммы на очень расплывчатом языке, но оба дают нам распределение точек данных (частоту значений в диапазоне).

Хорошо, давайте сосредоточимся на цели (найти график, который поможет нам легко отличить оранжевый цвет (нет) от синего (да)). В идеале нам нужен график, на котором четко видны оранжевая и синяя части. В нашем случае нет графа, удовлетворяющего нашему условию. Все показанные графики имеют хорошо смешанные категории, которые трудно разделить. Но функция плотности вероятности или график PDF для Positive_axillary_nodes_detected показывает некоторую разницу между оранжевым и синим цветом. Итак, мы можем попробовать выполнить одномерный анализ для Positive_axillary_nodes_detected, чтобы выделить столбец Survived_5years_or_not.

Давайте разделим наш набор данных на 2 набора данных (Survived_5years_or_not="yes" и Survived_5years_or_not="no"), чтобы упростить однофакторный анализ Positive_axillary_nodes_detected проще.

haberman_yes=haberman[haberman['Survived_5years_or_not']=="yes"]
haberman_no=haberman[haberman['Survived_5years_or_not']=="no"]

Теперь мы создадим функции плотности вероятности (PDF) и функции кумулятивной плотности (CDF) для обоих Positive_axillary_nodes_detected в обоих наших наборах данных haberman_yes и haberman_no.

PDF на очень простом языке - это сглаженные версии гистограмм, они дают вероятность наступления какого-либо конкретного небольшого интервала (потому что вероятность того, что какое-то событие произойдет в определенной точке, всегда равна 0, мы работаем для очень малых интервалов). Некоторые из всех значений оси Y в pdf приведут к 1, и все значения находятся между 0 и 1. Помните, что PDF имеет очень техническое определение, которое может быть не поглощено всеми, поэтому я изложил его очень простым языком. . (https://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm см. это для подробного определения)

Точно так же CDF (кумулятивные функции плотности) представляют собой интегралы PDF по интервалу. В любой точке x=c на кривой CDF она сообщает нам вероятность того, что событие произошло до CDF(x=c)=P(x≤c) (сумма всех вероятностей от x=0 до x=c). Интеграция PDF даст нам CDF, а дифференцирование CDF даст нам PDF за определенный интервал. Они оба помогают нам понять данные и их поведение в одномерном анализе.

Давайте построим cdf и pdf для haberman_yes[‘Positive_axillary_nodes_detected’]-

counts, bin_edges = np.histogram(haberman_yes['Positive_axillary_nodes_detected'], bins=np.arange(-2,22,2), density = True)
pdf = counts/(sum(counts))
cdf = np.cumsum(pdf)
plt.plot(bin_edges[1:],pdf)
plt.plot(bin_edges[1:], cdf)

Выход-

Показанный выше код сначала создает количество (частоту) и bin_edges, которые будут использоваться для создания гистограммы для нашего желаемого столбца («положительные узлы»), затем pdf (здесь список) может быть создан из гистограммы, просто разделив количество на сумму считает. И, наконец, NumPy имеет простую функцию .cumsum(), которая создает CDF (опять же список), получая ввод pdf. Наконец, я нарисовал их с помощью bin_edges (начало с [1:], чтобы количество элементов совпадало)

Статистика-

Из рисунка 8 видно, что CDF при Positive_axillary_nodes_detected =5 составляет почти 0,85, что означает, что 85 процентов всех пациентов, выживших через 5 и более лет после операции, имели положительные подмышечные узлы, обнаруженные менее 5. em>

Точно так же давайте создадим cdf и pdf для haberman_no[‘Positive_axillary_nodes_detected’]-

counts, bin_edges = np.histogram(haberman_no['Positive_axillary_nodes_detected'], bins=np.arange(-2,22,2), density = True)
pdf = counts/(sum(counts))
cdf = np.cumsum(pdf)
plt.plot(bin_edges[1:],pdf)
plt.plot(bin_edges[1:], cdf)

Выход-

Статистика-

CDF(x=5) составляет почти 0,6, а CDF(x=20) почти 1. Таким образом, отсюда мы можем сказать, что примерно 40 % всех пациентов, которые не могли выжить через 5 и более лет после во время операции было обнаружено от 5 до 20 положительных подмышечных узлов.

Теперь давайте соберем еще немного статистической информации из таких данных, как среднее значение, медиана, стандартное значение. Для этого мы можем использовать созданные нами наборы данных haberman_yes и haberman_no, но это невозможно, если у вас будет более 4 или 5 категорий. Поэтому вместо этого мы можем использовать .groupby(), который автоматически собирает информацию на основе категорий входного столбца. Например, если нам нужно среднее значение для категории «да» и «нет» выживших 5 или более лет для Positive_axillary_nodes_detected, мы можем выполнить следующую операцию.

haberman.groupby(‘Survived_5years_or_not’).Positive_axillary_nodes_detected.mean()

Выход-

Survived_5years_or_not
no     7.456790
yes    2.791111
Name: Positive_axillary_nodes_detected, dtype: float64

В нем говорится, что в среднем у пациентов, выживших более 5 лет после операции, было обнаружено в среднем 2,8 положительных подмышечных узла, в то время как у тех не могло быть обнаружено в среднем 7,46 положительных подмышечных узлов.

Но есть одна загвоздка, поскольку мы знаем, что средние значения могут быть легко искажены выбросами (т. е. чем больше выбросов, тем больше отклонение среднего), и мы можем видеть из pdf и CDF, что категории «да» и «нет» имеют выбросы.

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

haberman.groupby(‘Survived_5years_or_not’).Positive_axillary_nodes_detected.median()

Выход-

Survived_5years_or_not
no     4
yes    0
Name: Positive_axillary_nodes_detected, dtype: float64

Это дает довольно лучшую картину центральной тенденции обеих категорий.

Теперь мы должны увидеть, как разбросаны данные по обеим категориям. В идеале для этого мы используем стандартные отклонения (STD). STD представляет собой квадратный корень из среднего квадрата расстояния от среднего. Если разброс низкий, это означает, что они плотно сгруппированы, или если разброс высокий, это означает, что они широко представлены.

haberman.groupby(‘Survived_5years_or_not’).Positive_axillary_nodes_detected.std()

Выход-

Survived_5years_or_not
no     9.185654
yes    5.870318
Name: Positive_axillary_nodes_detected, dtype: float64

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

Вместо этого мы можем использовать медианное абсолютное отклонение (MAD), которое является медианой абсолютной разницы всех значений от медианы. Вот как мы можем импортировать его:

from statsmodels import robust
print(robust.mad(haberman_yes['Positive_axillary_nodes_detected']))
print(robust.mad(haberman_no['Positive_axillary_nodes_detected']))

Выход-

0.0
5.930408874022408

Понимание-

Это показывает, что для категории «да» разброс почти нулевой, т. е. все значения почти расположены вокруг центральной тенденции, в то время как для категории «нет» MAD составляет 5,93, значения которого широко разбросаны в этой категории.

Давайте проверим, видим ли выбросы из графика прямоугольника и усов. Box and Whiskers Plot — отличный инструмент для определения процентилей данных, например, каково значение 90-го процентиля? что означает, какое значение превышает 90 процентов данных. Коробчатая диаграмма делит данные на 4 группы: значения 0–25 процентилей (Q1), значения 25–50 процентилей (Q2), значения 50–75 процентилей (Q3) и значения 75–100 (Q4) процентилей. Затем он показывает поле для значений от 25-го до 75-го процентиля с линией для значения 50-го процентиля (медиана). А все остальные значения нанесены усами (например, кошачьими усами). Он также показывает нам выбросы в данных, если они присутствуют. Любое значение, которое меньше Q1–1,5 (IQR) или Q3+1,5 (IQR), где IQR=Q3–Q1, считается выбросом.

Давайте построим блочные графики -

sns.boxplot(x=’Survived_5years_or_not’,y=’Positive_axillary_nodes_detected’, data=haberman)
plt.show()

Выход-

Понимание-

На графике видно, что в категории «да» имеется достаточное количество выбросов, при этом 75 процентов значений находятся ниже 3. В категории «нет» данные более разбросаны по сравнению с «да» с IQR (75-е место). процентиль-25-й процентиль), равный 10.

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

sns.violinplot(x="Survived_5years_or_not", y="Positive_axillary_nodes_detected", data=haberman, size=8)
plt.show()

Выход-

Здесь мы видим, что категория «нет» с центральной тенденцией около 5 более рассеяна, чем категория «да» с центральной тенденцией около 0.

Окончательный вывод

  1. Из парного графика мы обнаружили, что наиболее важным признаком среди всех данных признаков для классификации выживших или не старше 5 лет являются положительные подмышечные узлы. Исследования также показывают, что это одна из основных переменных при выявлении рака молочной железы у женщин.
  2. Оттуда мы начали одномерный анализ положительных подмышечных узлов, обнаруженных с нашими метками класса «да» и «нет» для выживаемости в течение 5 лет или нет.
  3. PDF и CDF дали нам важную информацию о том, что около 80-85% всех пациентов, которые выжили более 5 лет, имели положительные подмышечные узлы от 0 до 4, в то время как около 40% пациентов, которые, к сожалению, не могли выжить более 5 лет, имели положительные подмышечные узлы. от 5 до 20.

Меня зовут Шивам Самайя, и недавно я начал изучать науку о данных. В настоящее время я работаю аналитиком-стажером в WNS Global Services. Если вы считаете, что необходимы некоторые улучшения или есть какие-то отзывы, пожалуйста, дайте мне знать или, если вы хотите связаться со мной, отправьте мне сообщение на LinkedIn. Ссылка на Jupyter Notebook для того же — здесь.

Рекомендации

  1. Kaggle-https://www.kaggle.com/gilsousa/habermans-survival-data-set
  2. https://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm
  3. https://towardsdatascience.com/will-habermans-survival-data-set-make-you-diagnose-cancer-8f40b3449673
  4. https://en.wikipedia.org/wiki/Positive_axillary_lymph_node#:~:text=A%20positive%20axillary%20lymph%20node, присутствуют ли%20рак%20клетки%20%20.
  5. https://www.mathsisfun.com/data/scatter-xy-plots.html
  6. https://www.tutorialspoint.com/seaborn/seaborn_facet_grid.htm