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

K-классификация ближайших соседей

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

Алгоритм KNN можно обобщить старой пословицей

Рыбы одного полета

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

Реализация алгоритма проходит

  1. Загрузка данных
  2. Инициализация k выбранным вами числом соседей.

Подробное объяснение можно найти здесь.

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

Вы также можете получить те же наборы данных от Kaggle.

Загрузка библиотек…

import itertools
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import pandas as pd
import numpy as np
import matplotlib.ticker as ticker
import seaborn as sns
from sklearn import preprocessing
%matplotlib inline

Теперь читаем файлы,

df = pd.read_csv('C:/breast-cancer-wisconsin-data/data.csv')
df.head()

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

Во-первых, мы проверяем размер набора данных, который у нас есть.

df['radius_mean'].value_counts()
print(df.shape)
>>
(569, 33)

Теперь мы делаем часть анализа

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

def diagnosis_value(diagnosis): 
    if diagnosis == 'M': 
        return 1
    else: 
        return 0
  
    df['diagnosis'] = df['diagnosis'].apply(diagnosis_value)
    df.drop(['Unnamed: 32','id'],axis=1)

Обратите внимание, что в приведенном выше коде мы удалили столбец «Безымянный», так как в нем было слишком много значений NaN с помощью метода .drop().

plt.hist(df['radius_mean']
>> (array([ 19.,  79., 185., 129.,  55.,  50.,  38.,   7.,   4.,   3.]),
 array([ 6.981 ,  9.0939, 11.2068, 13.3197, 15.4326, 17.5455, 19.6584,
        21.7713, 23.8842, 25.9971, 28.11  ]),
 <a list of 10 Patch objects>)

Давайте определим наши наборы функций,

X = df[[ 'radius_mean', 'texture_mean', 'perimeter_mean',
       'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean',
       'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean',
       'radius_se', 'texture_se', 'area_se', 'smoothness_se',
       'compactness_se', 'concavity_se', 'concave points_se', 'symmetry_se',
       'fractal_dimension_se', 'radius_worst', 'texture_worst',
       'perimeter_worst', 'area_worst', 'smoothness_worst',
       'compactness_worst', 'concavity_worst', 'concave points_worst',
       'symmetry_worst', 'fractal_dimension_worst']] .values  #.astype(float)
X[0:4]
y= np.array(df['diagnosis'])

Нормализация данных

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

Для этого мы импортируем StandardScaler из библиотеки sklearn и создаем экземпляр, а также подгоняем модель.

X = preprocessing.StandardScaler().fit(X).transform(X.astype(float))
X[0:5]
>>array([[ 1.09706398e+00, -2.07333501e+00,  1.26993369e+00,
         9.84374905e-01,  1.56846633e+00,  3.28351467e+00,
         2.65287398e+00,  2.53247522e+00,  2.21751501e+00,
         2.25574689e+00,  2.48973393e+00, -5.65265059e-01,
         2.48757756e+00, -2.14001647e-01,  1.31686157e+00,
         7.24026158e-01,  6.60819941e-01,  1.14875667e+00,
         9.07083081e-01,  1.88668963e+00, -1.35929347e+00,
         2.30360062e+00,  2.00123749e+00,  1.30768627e+00,
         2.61666502e+00,  2.10952635e+00,  2.29607613e+00,
         2.75062224e+00,  1.93701461e+00],
       [ 1.82982061e+00, -3.53632408e-01,  1.68595471e+00,
         1.90870825e+00, -8.26962447e-01, -4.87071673e-01,
        -2.38458552e-02,  5.48144156e-01,  1.39236330e-03,
        -8.68652457e-01,  4.99254601e-01, -8.76243603e-01,
         7.42401948e-01, -6.05350847e-01, -6.92926270e-01,
        -4.40780058e-01,  2.60162067e-01, -8.05450380e-01,
        -9.94437403e-02,  1.80592744e+00, -3.69203222e-01,
         1.53512599e+00,  1.89048899e+00, -3.75611957e-01,
        -4.30444219e-01, -1.46748968e-01,  1.08708430e+00,
        -2.43889668e-01,  2.81189987e-01],
       [ 1.57988811e+00,  4.56186952e-01,  1.56650313e+00,
         1.55888363e+00,  9.42210440e-01,  1.05292554e+00,
         1.36347845e+00,  2.03723076e+00,  9.39684817e-01,
        -3.98007910e-01,  1.22867595e+00, -7.80083377e-01,
         1.18133606e+00, -2.97005012e-01,  8.14973504e-01,
         2.13076435e-01,  1.42482747e+00,  2.37035535e-01,
         2.93559404e-01,  1.51187025e+00, -2.39743838e-02,
         1.34747521e+00,  1.45628455e+00,  5.27407405e-01,
         1.08293217e+00,  8.54973944e-01,  1.95500035e+00,
         1.15225500e+00,  2.01391209e-01],
       [-7.68909287e-01,  2.53732112e-01, -5.92687167e-01,
        -7.64463792e-01,  3.28355348e+00,  3.40290899e+00,
         1.91589718e+00,  1.45170736e+00,  2.86738293e+00,
         4.91091929e+00,  3.26373441e-01, -1.10409044e-01,
        -2.88378148e-01,  6.89701660e-01,  2.74428041e+00,
         8.19518384e-01,  1.11500701e+00,  4.73268037e+00,
         2.04751088e+00, -2.81464464e-01,  1.33984094e-01,
        -2.49939304e-01, -5.50021228e-01,  3.39427470e+00,
         3.89339743e+00,  1.98958826e+00,  2.17578601e+00,
         6.04604135e+00,  4.93501034e+00],
       [ 1.75029663e+00, -1.15181643e+00,  1.77657315e+00,
         1.82622928e+00,  2.80371830e-01,  5.39340452e-01,
         1.37101143e+00,  1.42849277e+00, -9.56046689e-03,
        -5.62449981e-01,  1.27054278e+00, -7.90243702e-01,
         1.19035676e+00,  1.48306716e+00, -4.85198799e-02,
         8.28470780e-01,  1.14420474e+00, -3.61092272e-01,
         4.99328134e-01,  1.29857524e+00, -1.46677038e+00,
         1.33853946e+00,  1.22072425e+00,  2.20556166e-01,
        -3.13394511e-01,  6.13178758e-01,  7.29259257e-01,
        -8.68352984e-01, -3.97099619e-01]])

Обучение и тестирование данных

Для этого мы выполняем train, test split на нашей модели,

from sklearn.model_selection import train_test_split, cross_val_score
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2)
print ('Train set:', X_train.shape,  y_train.shape)
print ('Test set:', X_test.shape,  y_test.shape)
>> Train set: (455, 29) (455,)
   Test set: (114, 29) (114,)

Классификация

Теперь мы используем алгоритм KNN из библиотеки sklearn.

from sklearn.neighbors import KNeighborsClassifier

Обучение алгоритма с k равным 4 и прогнозирование.

Мы создали экземпляр KNN для нашей модели с помощью KNeighborsClassifier(n_neighbors = k).

k = 4
#Train Model and Predict  
neigh = KNeighborsClassifier(n_neighbors = k).fit(X_train,y_train)
print(neigh)
#predicting part
yhat = neigh.predict(X_test)
yhat[0:5]
>>KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=None, n_neighbors=4, p=2,
           weights='uniform')
array(['B', 'B', 'B', 'B', 'M'], dtype=object)

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

Теперь для приведенной выше модели давайте проведем оценку точности…

from sklearn import metrics
print("Train set Accuracy: ", metrics.accuracy_score(y_train, neigh.predict(X_train)))
print("Test set Accuracy: ", metrics.accuracy_score(y_test, yhat))
>>Train set Accuracy:  0.9714285714285714
Test set Accuracy:  0.9473684210526315

Таким образом, мы получили точность 94,7% на тестовых данных, что довольно много.

Теперь давайте повторим описанную выше процедуру, но на этот раз с k равным 6.

k=6
neigh1=KNeighborsClassifier(n_neighbors=k).fit(X_train,y_train)
print(neigh1)
#predicting
yhat6=neigh1.predict(X_test)
print('Train Accuracy is : ',metrics.accuracy_score(y_train, neigh1.predict(X_train)))
print('test accuracy is : ', metrics.accuracy_score(y_test, yhat6))
>>KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=None, n_neighbors=6, p=2,
           weights='uniform')
Train Accuracy is :  0.9714285714285714
test accuracy is :  0.9649122807017544

Оценка точности для k = 6 на данных тестирования больше, чем k = 4.

Теперь я включил оценку точности для всех значений k до 10.

Ks = 10
mean_acc = np.zeros((Ks-1))
std_acc = np.zeros((Ks-1))
for n in range(1,Ks):
    #Train Model and Predict  
    neigh = KNeighborsClassifier(n_neighbors = n).fit(X_train,y_train)
    yhat=neigh.predict(X_test)
    mean_acc[n-1] = metrics.accuracy_score(y_test, yhat)
std_acc[n-1]=np.std(yhat==y_test)/np.sqrt(yhat.shape[0])
mean_acc
>>array([0.95614035, 0.94736842, 0.95614035, 0.94736842, 0.96491228,
       0.96491228, 0.96491228, 0.96491228, 0.96491228])

Построение показателей точности для различных значений k

plt.plot(range(1,Ks),mean_acc,'g')
plt.fill_between(range(1,Ks),mean_acc - 1 * std_acc,mean_acc + 1 * std_acc, alpha=0.10)
plt.legend(('Accuracy ', '+/- 3xstd'))
plt.ylabel('Accuracy ')
plt.xlabel('Number of estimators (K)')
plt.tight_layout()
plt.show()

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

print( "The best accuracy was with", mean_acc.max(), "with k=", mean_acc.argmax()+1)
>>The best accuracy was with 0.9649122807017544 with k= 5

Полные коды предоставлены из моего репозитория Github здесь.

использованная литература

  1. https://medium.com/analytics-vidhya/detecting-breast-cancer-using-machine-learning-ab23e719f7fa
  2. https://labs.cognitiveclass.ai/tools/jupyterlab/lab/tree/labs/edX/ML0101EN/ML0101EN-Clas-K-Nearest-neighbors-CustCat-py-v1.ipynb
  3. https://towardsdatascience.com/machine-learning-basics-with-the-k-nearest-neighbors-algorithm-6a6e71d01761.