import pandas as pd
import numpy as np
df = pd.read_csv("../input/churn-in-telecoms-dataset/bigml_59c28831336c6604c800002a.csv")
df.head().T
print(df['churn'].value_counts())
by_churn = df['churn'].value_counts()
by_churn.plot(kind='bar', colormap='cividis')
"""
Рассматривается задача классификации.
"""
"""
**Предобработка данных**
"""
df['churn'] = df['churn'].map({False: 0, True: 1})
df2 = pd.get_dummies(df, columns=['state', 'area code'])
df2['international plan'] = df2['international plan'].map({'no': 0, 'yes': 1})
df2['voice mail plan'] = df2['voice mail plan'].map({'no': 0, 'yes': 1})
df3 = df2.drop(['phone number'], axis=1)
y = df3['churn']
df4 = df3.drop('churn', axis=1)
df4.info()
"""
**Масштабирование данных**
"""
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X = scaler.fit_transform(df4)
print(X[:5])
"""
**Разобъем набор данных на обучающую и валидационную (тестовую) выборки**
"""
from sklearn.model_selection import train_test_split
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.25, random_state=42)
"""
**Обучим алгоритм классификации**
"""
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(X_train, y_train)
y_pred = knn.predict(X_valid)
print(y_pred[:5])
print(y_valid[:5])
"""
**Оценим качество модели на валидационной выборке**
"""
from sklearn.metrics import accuracy_score
print(accuracy_score(y_valid, y_pred))
"""
Как видим, модель способна угадать 4 раза из 5, или ее эффективность равна около 85%.
"""
"""
***Настройка оптимального числа ближайших
соседей в методе kNN***
"""
"""
**Создаем генератор разбиений, который перемешивает выборку перед созданием блоков**
"""
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
kf = KFold(n_splits=5, shuffle=True, random_state=42)
knn = KNeighborsClassifier(n_neighbors=5)
scores = cross_val_score(knn, X, y, 
                         cv=kf, scoring='accuracy')
print('Массив значений метрики:', scores)
print('Средняя метрика на кросс-валидации:', np.mean(scores))
"""
**Отыщем оптимальное количество соседей в методе kNN**
"""
from sklearn.model_selection import GridSearchCV

knn_params = {'n_neighbors': np.arange(1, 51)}
kf = KFold(n_splits=5, shuffle=True, random_state=42)

knn_grid = GridSearchCV(knn, knn_params, cv=kf, scoring='accuracy')
knn_grid.fit(X_train, y_train)
# Смотрим лучшие значения параметров
print(knn_grid.best_params_)

# Лучшая модель
print(knn_grid.best_estimator_)
# Результаты кросс-валидации в виде таблицы
pd.DataFrame(knn_grid.cv_results_).T
"""
Качество получилось наилучшим при k=7 с оценкой качества 0.859551
"""
import matplotlib.pyplot as plt
results_df = pd.DataFrame(knn_grid.cv_results_)
plt.plot(results_df['param_n_neighbors'], results_df['mean_test_score'])

plt.xlabel('n_neighbors')
plt.ylabel('Test accuracy')
plt.title('Validation curve')
plt.show()
"""
***Выбор метрики в методе kNN***
"""
knn = KNeighborsClassifier(n_neighbors=7, weights='distance')

knn_params = {'p': np.linspace(1, 10, 20)}

knn_grid = GridSearchCV(knn, knn_params, cv=kf, scoring='accuracy')
knn_grid.fit(X_train, y_train)
# Смотрим лучшие значения параметров
print(knn_grid.best_params_)

# Лучшая модель
print(knn_grid.best_estimator_)
# Результаты кросс-валидации в виде таблицы
pd.DataFrame(knn_grid.cv_results_).T
"""
Качество получилось наилучшим при k=7 и p=3.8421052631578947 с оценкой качества 0.859149
"""
results_df = pd.DataFrame(knn_grid.cv_results_)
plt.plot(results_df['param_p'], results_df['mean_test_score'])

plt.xlabel('p')
plt.ylabel('Test accuracy')
plt.title('Validation curve')
plt.show()
"""
**Другие метрические методы**
"""
"""
Используем RadiusNeighborsClassifier
"""
from sklearn.neighbors import RadiusNeighborsClassifier
rnc = RadiusNeighborsClassifier(radius=6.77)
rnc.fit(X_train, y_train)
y_pred = rnc.predict(X_valid)
print(accuracy_score(y_valid, y_pred))
rnc = RadiusNeighborsClassifier()

rnc_params = {'radius': np.linspace(8, 50, 30)}
kf = KFold(n_splits=5, shuffle=True, random_state=42)

rnc_grid = GridSearchCV(rnc, rnc_params, cv=kf, scoring='accuracy')
rnc_grid.fit(X_train, y_train)
# Смотрим лучшие значения параметров
print(rnc_grid.best_params_)

# Лучшая модель
print(rnc_grid.best_estimator_)
results_df = pd.DataFrame(rnc_grid.cv_results_)
plt.plot(results_df['param_radius'], results_df['mean_test_score'])

plt.xlabel('radius')
plt.ylabel('Test accuracy')
plt.title('Validation curve')
plt.show()
"""
Воспользуемся NearestCentroid
"""
from sklearn.neighbors import NearestCentroid
clf = NearestCentroid()
clf.fit(X_train, y_train)
y_pred = clf.predict(X_valid)
print(accuracy_score(y_valid, y_pred))
kf = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(clf, X, y, 
                         cv=kf, scoring='accuracy')
print('Массив значений метрики:', scores)
print('Средняя метрика на кросс-валидации:', np.mean(scores))