Логистическая регрессия — это один из многих статистических методов, которые вы можете использовать для объяснения или классификации вашей качественной переменной отклика с помощью ваших количественных/качественных переменных-предикторов. Логистическая регрессия — это своего рода обучение под наблюдением, которое можно легко выполнить с помощью библиотеки Python sklearn.

Scikit-learn или sklearn — одна из ведущих библиотек Python для машинного обучения. С помощью sklearn вы можете выполнять различные алгоритмы машинного обучения от дерева решений до MLP (многослойного персептрона). Сегодня мы проведем простую логистическую регрессию, чтобы классифицировать финиковые фрукты. Получить данные и ознакомиться с документацией можно здесь.

Теперь мы собираемся импортировать данные и понять, что это такое.

# importing data
import pandas as pd
df = pd.read_excel('/content/Date_Fruit_Datasets.xlsx')
#df.head()
df.info()

Как видите, здесь у нас 35 признаков. Все 34 предиктора являются числовыми, а переменная ответа является категориальной. И хорошо, что нет пропущенного значения!

Согласно документации, ранняя форма данных — изображения. С помощью алгоритмов обработки изображений им удается извлечь из изображения 34 различных признака. Итак, что представляют собой эти 34 функции?

Все характеристики извлекаются из внешнего вида собранных финиковых плодов. Есть 3 основных признака, то есть морфологические признаки, которые состоят из 12 признаков, признаки формы, которые состоят из 4 признаков, и цветовые признаки, самые сложные, которые состоят из 18 признаков.

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

# count of each class
df['Class'].value_counts().plot(kind='bar')

Мы собираемся классифицировать 7 видов финиковых фруктов, а именно ДОКОЛ, САФАВИ, РОТАНА, ДЕГЛЕТ, СОГАЙ, ИРАКИ и БЕРХИ. Итак, это случай многоклассовой классификации.

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

# removing outliers
import numpy as np
from scipy import stats
from scipy.stats import zscore
X = df.iloc[:,:-1]
y = df.iloc[:,-1]
z_scores = stats.zscore(X)
abs_z_scores = np.abs(z_scores)
filtered_entries = (abs_z_scores < 3).all(axis=1)
df_clean = df[filtered_entries]
df_clean

Видите, что у нас сейчас 793 наблюдения, это означает, что исходные данные содержат 105 выбросов. Теперь давайте посмотрим, изменилось ли что-нибудь после того, как мы удалили выбросы.

dateschar = df.groupby(by='Class').mean()
dateschar_clean = df_clean.groupby(by='Class').mean()
#dateschar
dateschar_clean

Вы можете сами сравнить различия, изменив вывод (dateschar или datechar_clean). Вот «истинные» характеристики каждого сорта/класса.

Как показано в таблице выше, мы можем вывести несколько данных:

  • Вариант IRAQI является самым большим среди других, а вариант DOKOL - самым маленьким.
  • Вариант BERHI имеет самую прочную форму.
  • и т. д.

Обратите внимание, что у нас есть много функций для использования (34), и значения каждой функции значительно отличаются от других. Поэтому мы собираемся уменьшить наши данные с помощью анализа основных компонентов (PCA) и масштабировать наши данные с помощью StandardScaler. Используя StandardScaler, мы собираемся стандартизировать наши данные, удалив их среднее значение и масштабируя их до единичной дисперсии.

# StandardScaler
from sklearn.preprocessing import StandardScaler
X_clean = df_clean.iloc[:,:-1]
y_clean = df_clean.iloc[:,-1]
sc = StandardScaler()
X_scaled = sc.fit_transform(X_clean)
X_scaled_df = pd.DataFrame(X_scaled)
X_scaled_df

Обратите внимание, что после того, как мы стандартизировали наши данные, их диапазон стал намного меньше. Обратите внимание, что после того, как мы используем StandardScaler, среднее значение каждой функции будет равно 0 (или близко к нулю), а стандартное отклонение будет равно 1. StandardScaler полезен, если вы хотите выполнять визуализацию данных, PCA, алгоритмы машинного обучения и т. д.

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

# PCA
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
pca = PCA()
pca.fit(X_scaled)
components = len(pca.explained_variance_ratio_)
plt.plot(range(1,components+1), np.cumsum(pca.explained_variance_ratio_ * 100))
plt.xlabel("Number of components")
plt.ylabel("Explained variance (%)")

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

pca = PCA(n_components = 0.90)
pca.fit(X_scaled)
print("Cumulative Variances (Percentage):")
print(np.cumsum(pca.explained_variance_ratio_ * 100))
components = len(pca.explained_variance_ratio_)
print(f'Number of components: {components}')

Приведенный выше вывод показывает, что 6 основных компонентов достаточно, чтобы представить 90% соотношения исходных данных. Что представляет собой каждый главный компонент? Из чего это сделано?

pca_components = abs(pca.components_)
print('Top 3 most important features in each component')
print('===============================================')
for row in range(pca_components.shape[0]):
    # get the indices of the top 4 values in each row
    temp = np.argpartition(-(pca_components[row]), 3)

    # sort the indices in descending order
    indices = temp[np.argsort((-pca_components[row])[temp])][:3]

    # print the top 4 feature names
    print(f'Component {row}: {df.columns[indices].to_list()}')

Вышеприведенный вывод показывает, какие функции вносят наибольший вклад в каждый из основных компонентов. MeanRR, ALLdaub4RR и SkewRG вносят наибольший вклад в компонент 0, что означает, что компонент 0 представляет цветовые признаки исходного набора данных, а также компоненты 3 и компоненты 5. В то время как компоненты 1, компоненты 2 и компоненты 4 представляют морфологию и форму. особенности исходного набора данных.

Тогда как наши данные выглядят теперь после того, как мы выполнили PCA?

X_pca = pca.transform(X_scaled)
df_pca = pd.DataFrame(X_pca)
df_pca['Class'] = y
df_pca

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

# modelling
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
sc_pl = StandardScaler()
pca_pl = PCA(n_components = 0.9)
model_pl = LogisticRegression(max_iter = 150)
logreg = Pipeline([
    ('std_scaler', sc_pl),
    ('pca', pca_pl),
    ('regressor', model_pl)
])
X_train, X_test, y_train, y_test = train_test_split(X_clean, y_clean, test_size=0.3, shuffle=True, random_state=42)
logreg.fit(X_train,y_train)

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

from sklearn.metrics import classification_report
y_pred = logreg.predict(X_test)
print(classification_report(y_test, y_pred))

Здесь наша модель работает достаточно хорошо с точностью 87%. Существуют различные показатели для измерения того, насколько хорошо работает наша модель, такие как точность, точность, полнота и т. д. У каждого из этих показателей есть свои условия, когда вы должны их использовать. Например, когда у вас несбалансированные данные, лучше использовать метрики точности вместо точности.

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

import seaborn as sns
from sklearn.metrics import confusion_matrix
cf_matrix = confusion_matrix(y_test, y_pred)
ax = sns.heatmap(cf_matrix, annot=True, cmap='Blues')
sns.set(rc={'figure.figsize':(12, 9)})
ax.set_title('Seaborn Confusion Matrix with labels\n\n');
ax.set_xlabel('\nPredicted Category')
ax.set_ylabel('Actual Category ');
ax.xaxis.set_ticklabels(['Barhee','Deglet', 'Rotab', 'Ruthana', 'Safawi', 'Sagai', 'Sukkary'])
ax.yaxis.set_ticklabels(['Barhee','Deglet', 'Rotab', 'Ruthana', 'Safawi', 'Sagai', 'Sukkary'])

plt.show()

Приведенная выше визуализация называется матрицей путаницы. Он используется для сопоставления фактической категории с прогнозируемой категорией. Следовательно, вы можете видеть, когда ваша модель испытывает трудности с прогнозированием или когда ваша модель работает хорошо. Из приведенной выше матрицы путаницы мы видим, что нашей модели трудно предсказать класс SUKKARY, и наша модель демонстрирует выдающиеся результаты при предсказании ROTAB, SAFAWI и SAGAI.

Я надеюсь, что эта статья даст вам представление о логистической регрессии. О логистической регрессии есть еще много чего, чего я здесь не рассмотрел. Но ура, мы успешно создали простую модель логистической регрессии.

Похлопайте мне и поделитесь ею с друзьями, если вам понравилась эта статья, если нет, то нет ничего плохого в том, чтобы похлопать и поделиться ею, чтобы подбодрить меня, верно? 😁✌️

Кроме того, не стесняйтесь связаться со мной в LinkedIn.

Привет! Товарищ данные сайянтист!