• Модель машинного обучения, которая обучается на наборе данных Red Wine из репозитория StatLib.
  • Здесь мы проводим контролируемое обучение, и наша цель — проводить прогнозный анализ.
  • Во время нашего путешествия мы поймем важные инструменты, необходимые для разработки мощной модели машинного обучения.
  • Наша модель поможет нам в прогнозировании качества вина.
  • Мы проверим его на нашем тестовом наборе данных.

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

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

1. Понять постановку задачи для бизнеса

Мы увлеченные специалисты по данным, и прежде чем начать, нам нужно задать несколько фундаментальных вопросов.

2. Получить набор данных

Получите набор данных в формате CSV здесь и сохраните его в папке. Откройте Jupyter Notebook и начните импорт основных библиотек.

# data processing
import pandas as pd
#Linear Algebra
import numpy as np
#Data Visualization
import seaborn as sns
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib import style

# Algorithms
from sklearn.svm import SVC, LinearSVC
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import SGDClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler,LabelEncoder
from sklearn.metrics import confusion_matrix,classification_report,accuracy_score,roc_curve,roc_auc_score
from sklearn.model_selection import train_test_split,cross_val_score,GridSearchCV
import warnings
warnings.filterwarnings(‘ignore’)

Получение и чтение набора данных

wine=pd.read_csv("winequality_red.csv")
wine.head()

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

#to know shape of the dataset
wine.shape

(1599,12)

Здесь мы можем заметить, что в этом наборе данных присутствует 1599 строк и 12 признаков.

#Number of unique valuesin this dataset
for col in wine.columns.values:
    print("Number of unique values of {}:{}".format(col,wine[col].nunique()))

вывод:

Количество уникальных значений фиксированной кислотности:96
Количество уникальных значений летучей кислотности:143
Количество уникальных значений лимонной кислоты:80
Количество уникальных значений остаточного сахара:91
Количество уникальных значений хлоридов: 153
Количество уникальных значений свободного диоксида серы: 60
Количество уникальных значений общего диоксида серы: 144
Количество уникальных значений плотности: 436
Количество уникальных значений pH:89
Количество уникальных значений сульфатов:96
Количество уникальных значений спирта:65
Количество уникальных значений качества:6

Признак фиксированной кислотности имеет большее количество уникальных значений, а признак качества имеет меньшее количество уникальных значений.

wine.info()

wine.describe(include='all')

1. Среднее значение больше медианы (50-й процентиль) во всех столбцах.

2. Существует большая разница в процентиле 75% и максимальном уровне остаточного сахара, свободного диоксида серы, общего диоксида серы.

3.Наблюдения 1 и 2 предполагают наличие экстремальных выбросов.

wine.tail()

Исследовательский анализ данных

#check weather null values present or not
sns.heatmap(wine.isnull())

Есть еще один способ проверить нулевые значения, см. ниже…

wine.isnull().sum()

sns.countplot(wine['quality'])

Качество наблюдений
имеет большинство значений, сосредоточенных в категориях 5,6,7
несколько наблюдений, сосредоточенных в категориях 4,8,3

Создание бинов для функции качества

bins=(2,6.5,8)
group=['Bad','Good']
wine['quality']=pd.cut(wine['quality'],bins=bins,labels=group)
#now assign kabels to quality
label_quality=LabelEncoder()
#Bad becomes 0,and good becomes 1
wine['quality']=label_quality.fit_transform(wine['quality'])

Теперь давайте проверим

Были созданы новые лейблы.

plt.scatter(wine['chlorides'],wine['alcohol'],cmap='orange')

#to check correlation
sns.heatmap(wine.corr())

  • плотность имеет сильную положительную корреляцию с остаточным сахаром, тогда как она имеет сильную отрицательную корреляцию с алкоголем.
  • pH и фиксированная кислотность имеют отрицательную корреляцию.
  • плотность и фиксированная кислотность имеют положительную корреляцию.
  • лимонная кислота и фиксированная кислотность имеют положительную корреляцию.
  • лимонная кислота и летучие кислоты имеют отрицательную корреляцию.
  • свободный диоксид серы и общий диоксид серы имеют положительную корреляцию.
  • Колонку pH лучше убрать
wine.drop('pH',axis=1,inplace=True)

#distribution plots
sns.FacetGrid(wine,hue='quality',size=5).map(sns.distplot,'chlorides').add_legend()
sns.FacetGrid(wine,hue='quality',size=6).map(sns.distplot,'alcohol').add_legend()

Отсюда диапазон хлоридов находится между (0,0–0,1) качество вина больше, а при значении хлорида 0,5 качество вина низкое. Наконец, я заметил одну вещь: если диапазон хлоридов увеличивается, качество вина снижается.

Отсюда диапазон содержания алкоголя находится между (9–12) качество вина Больше и количество алкоголя 9 качество вина больше

#boxplot for to check outliers
sns.boxplot(x='quality',y='citric acid',data=wine)

sns.pairplot(wine ,hue ='quality', vars =['fixed acidity','volatile acidity', 'citric acid', 'residual sugar',
       'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density',
       'sulphates', 'alcohol'])

  1. Светлые оттенки тесно связаны
  2. качество сильно коррелирует с алкоголем
  3. спирт сильно отрицательно с плотностью -0,5 (см. в темно-бордовом оттенке)
  4. плотность сильно положительно коррелирует с остаточным сахаром
  5. летучая кислотность отрицательно коррелирует с качеством
  6. свободная серная кислота сильно коррелирует с общим диоксидом серы
  7. здесь мы можем исключить летучую кислотность из набора данных, если мы делаем линейную регрессию

Идентификация и удаление выбросов

wine['fixed acidity'].plot.box()

collist=wine.columns.values
ncol=12
nrows=10
plt.figure(figsize=(ncol,5*ncol))
for i in range(1,len(collist)):
    plt.subplot(nrows,ncol,i+1)
    sns.boxplot(wine[collist[i]],color='green',orient='v')
    plt.tight_layout()

#Removing Outliers
from scipy.stats import zscore
z=np.abs(zscore(wine))
z
threshold=3
np.where(z>3)

wine_new=wine[(z<3).all(axis=1)]
wine_new.shape
wine.shape

141 строка была удалена как выбросы

Проверка и удаление - Распределение асимметрии

plt.figure(figsize=(20,20))
for i in range(0,len(collist)):
    plt.subplot(nrows,ncol,i+1)
    sns.distplot(wine_new[collist[i]])

wine_new.skew()

Отсюда мы можем заметить, что большинство функций имеет асимметрию, поэтому лучше поработать над этим….

x=wine_new.iloc[:,:-1]
y=wine_new.iloc[:,-1]

Сверху мы видим, что x и y y являются целевой переменной, а функция качества назначается y, а все остальные функции, кроме качества, назначаются x.

#removal of skew-ness using log function
for col in x.columns:
    if x.skew().loc[col]>0.55:
        x[col]=np.log1p(x[col])

Снова проверьте асимметрию

x.skew()

только данные плотности имеют нормальное распределение
другие независимые переменные смещены вправо/положительно

Построение модели машинного обучения

x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=43)

Отсюда мы можем заметить, что 80% данных идут на обучение и 20% данных идут на тестирование….

#Applying Standard Scaling to get optimized result
sc=StandardScaler()
x_train=sc.fit_transform(x_train)
x_test=sc.fit_transform(x_test)

| Применение алгоритмов машинного обучения

dtc=DecisionTreeClassifier()
rfc=RandomForestClassifier()
lg=LogisticRegression()
knc=KNeighborsClassifier()
sgc=SGDClassifier()
seed=7
#prepare models
models=[]
models.append(('DecisionTreeClassifier',dtc))
models.append(('RandomForestClassifier',rfc))
models.append(('KNeighborsClassifier',knc))
models.append(('SGDClassifier',sgc))
models.append(('LogisticRegression',lg))
#evaluate each model in turn
Model=[]
cvs=[]
score=[]
rocscore=[]
for name,model in models:
    print('**************',name,'***********')
    print('\n')
    Model.append(name)
    model.fit(train_X,train_Y)
    print(model)
    pred=model.predict(test_X)
    print('\n')
    acc=accuracy_score(test_Y,pred)
    print('accuracy score',acc)
    score.append(acc*100)
    kfold=model_selection.KFold(n_splits=10,random_state=seed)
    cv=model_selection.cross_val_score(model,X,Y,cv=10,scoring='accuracy').mean()
    print('Cross-val-score=',cv)
    cvs.append(cv*100)
    print('\n')
    false_positive_rate,true_positive_rate,thresholds=roc_curve(test_Y,pred)
    roc_auc=roc_auc_score(test_Y,pred)
    print('roc_auc_score',roc_auc)
    rocscore.append(roc_auc*100)
    print('\n')
    print(classification_report(test_Y,pred))
    print('\n')
    cm=confusion_matrix(test_Y,pred)
    print(cm)
    print('\n')
    plt.figure(figsize=(10,15))
    plt.subplot(911)
    plt.title(name)
    print(sns.heatmap(cm,annot=True))
    plt.subplot(912)
    plt.title(name)
    plt.plot(false_positive_rate,true_positive_rate,label='AUC'%roc_auc)
    plt.plot([0,1],[0,1],'k--')
    plt.xlabel('false_positive_rate')
    plt.ylabel('true_positive_rate')
    plt.show()

Результат вы можете увидеть ниже

Выбор лучшей модели

  1. Из таблицы выше мы можем наблюдать одну вещь, то есть точность для RandomForestClassifier составляет 92%, я думаю, что это хороший результат.
  2. И Cross-val-score 88 это неплохо, а Roc-score 75…..
  3. Общая производительность этого алгоритма лучше по сравнению со всеми другими алгоритмами.

Сетка Поиск параметра Настройка

param_grid ={'C':[0.1,1,10,100],'gamma':[1,0.1,0.01,0.001],'kernel':['rbf']}
from sklearn.model_selection import GridSearchCV, cross_val_score
rfc = RandomForestClassifier( random_state=1)
grid=GridSearchCV(SVC(),param_grid,refit=True,verbose=4)
grid.fit(x_train, y_train)
grid.best_params_

Мы можем найти лучший оценщик из поиска по сетке, как это. Подчеркивание в конце предназначено для параметров, которые модель изучила.

grid_predictions=grid.predict(x_test)
grid_predictions

Прогнозирование значений

rfc.fit(x_train,y_train)
pred=rfc.predict(x_test)
print('predicted insurance claim:',pred)
print('actual insurance claim',y_test)

Важность функции

importances = pd.DataFrame({'feature':X.columns,'importance':np.round(rfc.feature_importances_,3)})
importances = importances.sort_values('importance',ascending=False).set_index('feature')

Вывод

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

Сохранение модели

from sklearn.externals import joblib
#save the model as a pickle in a file
joblib.dump(rfc,'quality of wine.obj')
#load the model from a file
lg_from_joblib=joblib.load('quality of wine.obj')
#use the loaded model to make prediction
lg_from_joblib.predict(test_X)

Я думаю, что пока это хорошо.

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