import numpy as np
import pandas
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import scale
import matplotlib.pyplot as plt
# Названия признаков
column_names = ['Sort','Alcohol','Malic acid','Ash','Alcalinity of ash',
'Magnesium', 'Total phenols', 'Flavanoids', 'Nonflavanoid phenols',
'Proanthocyanins', 'Color intensity', 'Hue', 'OD280/OD315 of diluted wines', 'Proline']
data = pandas.read_csv('wine.data', header=None, names=column_names);
# Выделение ответов и матрицы объекты-признаки
answers = data['Sort']
features = data.drop(columns='Sort')
# Нормировка матрицы объекты-признаки
features = scale(features)
# Создание генератора разбиений для проверки качества кросс-валидацией на пяти блоках
folding = KFold(n_splits=5, shuffle=True)
metrics_errors = {'euclidean':[], 'manhattan':[], 'chebyshev':[]}
for metric_ in metrics_errors.keys():
for k_neighbors in range(1,120):
# Создание классификатора и его обучение для различныз метрик
clf = KNeighborsClassifier(n_neighbors=k_neighbors, metric=metric_)
clf.fit(features, answers)
# Оценка точности классификатора кросс-валидацией
accuracy = cross_val_score(clf, features, answers, scoring='accuracy', cv=folding)
accuracy = accuracy.mean()
metrics_errors[metric_].append(1 - accuracy)
# Вывод результата работы алгоритма
min_error = min(metrics_errors[metric_])
min_neighbor = metrics_errors[metric_].index(min_error)
print('Minimal error for', metric_, 'metric is', '%.3f' % min_error, 'with', min_neighbor, 'neigbors')
Minimal error for euclidean metric is 0.022 with 21 neigbors Minimal error for manhattan metric is 0.017 with 12 neigbors Minimal error for chebyshev metric is 0.050 with 11 neigbors
plt.figure(figsize=(12,7))
plt.xlabel('Number of neighbors', fontsize=22)
plt.ylabel('Error', fontsize=22)
for metric_ in metrics_errors.keys():
plt.plot(metrics_errors[metric_], label=metric_)
plt.legend(fontsize=18)
plt.savefig(fname='Problem12_Task2_graph.png',format='png')
num_of_objects = np.shape(features)[0]
num_of_neighbors = 20
means = []; stds = []
for i in range(num_of_neighbors, num_of_objects):
# Создание случайной тренировочной подвыборки с n = i объектами
train_subset = data.sample(n=i)
# Выделение ответов и матрицы объекты-признаки с нормировкой признаков
train_answers = train_subset['Sort']
train_features = scale(train_subset.drop(columns='Sort'))
# Отделение тестовой подвыборки от тренировочной в исходных данных
test_subset = pandas.concat([data, train_subset, train_subset]).drop_duplicates(keep=False)
# Выделение ответов и матрицы объекты-признаки с нормировкой признаков
test_answers = test_subset['Sort']
test_features = scale(test_subset.drop(columns='Sort'))
# Создание и обучение классификатора
clf = KNeighborsClassifier(n_neighbors=num_of_neighbors, metric='euclidean')
clf.fit(train_features, train_answers)
# Определение точночти классификатора
prediction = clf.predict(test_features)
mean_acc = np.mean(prediction == test_answers); means.append(mean_acc)
mean_std = np.std(prediction == test_answers); stds.append(mean_std)
plt.figure(figsize=(12,7))
plt.xlabel('Size of train subset', fontsize=22)
plt.ylabel('Accuracy', fontsize=22)
plt.errorbar(list(range(num_of_neighbors, num_of_objects)), means,
yerr=stds, linewidth=2, elinewidth=0.5, ecolor='red', capsize=1.5)
plt.savefig(fname='Problem12_Task3_graph.png',format='png')