Skip to main content

Small pacakge with various algorithms

Project description

SmartAlgo: Облегченная библиотека машинного обучения

SmartAlgo — это Python-пакет с реализацией основных алгоритмов машинного обучения "с нуля". Разработан в целях обучения, включает линейную регрессию, k-средних и логистическую регрессию с L2-регуляризацией. Работает с минимальными зависимостями (numpy и scipy), идеально подходит для изучения основ ML.

Установка

Установите пакет через pip:

pip install sm_algo  

Зависимости:

  • numpy
  • scipy

Алгоритмы

1. Линейная регрессия с градиентным спуском

Класс: LinearRegression
Линейная регрессия, обученная методом градиентного спуска.

Параметры:

  • learning_rate (float, по умолчанию=0.01): Шаг градиентного спуска.
  • epochs (int, по умолчанию=1000): Количество итераций обучения.

Методы:

  • fit(X, y): Обучает модель на данных X и целевых значениях y.
  • predict(X): Возвращает предсказания для входных данных X.

Пример:

from sm_algo.linreg import LinearRegression
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import StandardScaler


# Загрузка датасета diabetes из sklearn
data = load_diabetes()
X, y = data.data, data.target  # X - признаки, y - целевая переменная

# Разделение данных на обучающую и тестовую выборки (80% / 20%)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42  # random_state для воспроизводимости
)

# Нормализация данных (приведение к нулевому среднему и единичной дисперсии)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)  # обучение scaler и трансформация тренировочных данных
X_test = scaler.transform(X_test)  # трансформация тестовых данных (без повторного обучения)

# Создание и обучение модели линейной регрессии
model = LinearRegression(learning_rate=0.1, epochs=1000)  # задаем скорость обучения и кол-во эпох
model.fit(X_train, y_train)  # обучение модели на тренировочных данных

# Получение предсказаний на тестовых данных
y_pred = model.predict(X_test)

# Оценка качества модели:
# - MSE (среднеквадратичная ошибка, чем меньше - тем лучше)
# - R² (коэффициент детерминации, 1 - идеальное предсказание)
print(f"MSE: {mean_squared_error(y_test, y_pred):.2f}")
print(f"R²: {r2_score(y_test, y_pred):.2f}")

# Вывод обученных весов модели
print("\nВеса модели:")
for i, w in enumerate(model.weights):
    print(f"Feature {i}: {w:.3f}")  # вес i-го признака
print(f"Intercept (bias): {model.bias:.3f}")  # свободный член (смещение)

# Для сравнения с реализацией линейной регрессии из sklearn
from sklearn.linear_model import LinearRegression as SklearnLR

sklearn_model = SklearnLR()  # создание модели sklearn
sklearn_model.fit(X_train, y_train)  # обучение
y_pred_sklearn = sklearn_model.predict(X_test)  # предсказание

# Вывод метрик sklearn модели для сравнения
print("\nSklearn Results:")
print(f"MSE: {mean_squared_error(y_test, y_pred_sklearn):.2f}")
print(f"R²: {r2_score(y_test, y_pred_sklearn):.2f}")
C:\Users\yashe\PycharmProjects\SmartAlgo\.venv\Scripts\python.exe C:\Users\yashe\PycharmProjects\SmartAlgo\test\linreg_test.py 
MSE: 2889.92
R²: 0.45

Веса модели:
Feature 0: 1.844
Feature 1: -11.477
Feature 2: 25.925
Feature 3: 16.727
Feature 4: -27.944
Feature 5: 11.731
Feature 6: 0.396
Feature 7: 10.872
Feature 8: 28.828
Feature 9: 2.471
Intercept (bias): 153.737

Sklearn Results:
MSE: 2900.19
R²: 0.45

2. Кластеризация K-средних

Класс: KMeans
Алгоритм K-средних с инициализацией центроидов методом k-means++.

Параметры:

  • n_clusters (int, по умолчанию=8): Число кластеров.
  • max_iter (int, по умолчанию=300): Максимальное число итераций.
  • tol (float, по умолчанию=1e-4): Допуск для определения сходимости.
  • random_state (int, опционально): Seed для инициализации центроидов.

Методы:

  • fit(X): Выполняет кластеризацию для данных X.
  • predict(X): Возвращает индексы кластеров для новых данных.

Пример:

from sklearn.datasets import load_iris
from sm_algo.kmeans import KMeans
import matplotlib.pyplot as plt


# Загрузка данных Iris (150 samples, 4 features)
iris = load_iris()
X = iris.data  # Данные в виде матрицы [150x4]

# Создание модели с 3 кластерами (по числу видов ирисов)
kmeans = KMeans(n_clusters=3)

# Обучение модели на масштабированных данных
kmeans.fit(X)

# Получение меток кластеров для каждой точки
labels = kmeans.labels_

# Рисуем точки по первым двум признакам, раскрашивая по кластерам
plt.scatter(
    X[:, 0],  # Ось X: первый признак (длина чашелистика)
    X[:, 1],  # Ось Y: второй признак (ширина чашелистика)
    c=labels,        # Цвет точек = номер кластера
    cmap='viridis'   # Палитра цветов
)

# Рисуем центроиды
plt.scatter(
    kmeans.centroids[:, 0],  # X координата центроидов
    kmeans.centroids[:, 1],  # Y координата центроидов
    marker='X',              # Форма — крестик
    s=200,                   # Размер
    c='red',                 # Цвет
    edgecolor='black'        # Обводка
)

# Подписи осей и заголовок
plt.xlabel('Sepal Width')
plt.ylabel('Sepal Length')
plt.title('K-means Clustering on Iris Dataset')
plt.show()

K-means Clustering on Iris Dataset

3. Логистическая регрессия с L2-регуляризацией

Класс: LogisticRegressionRidge
Логистическая регрессия с L2-регуляризацией, обучение градиентным спуском.

Параметры:

  • learning_rate (float, по умолчанию=0.01): Шаг градиентного спуска.
  • lambda_ (float, по умолчанию=0.1): Сила L2-регуляризации.
  • epochs (int, по умолчанию=1000): Число итераций обучения.
  • fit_intercept (bool, по умолчанию=True): Добавлять ли свободный член.
  • verbose (bool, по умолчанию=False): Вывод лога потерь каждые 100 эпох.

Методы:

  • fit(X, y): Обучает модель.
  • predict_proba(X): Возвращает вероятности классов.
  • predict(X, threshold=0.5): Возвращает метки классов.

Пример:

from sm_algo.logisticreg import LogisticRegressionRidge
from sklearn.metrics import accuracy_score
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np


def score(model, X, y, threshold=0.5):
    """
    Вычисляет точность (accuracy) модели.

    Параметры:
    ----------
    X : ndarray, shape (n_samples, n_features)
        Матрица признаков.
    y : ndarray, shape (n_samples,)
        Истинные метки классов.
    threshold : float, default=0.5
        Порог классификации.

    Возвращает:
    -----------
    float
        Точность модели (accuracy).
    """
    y_pred = model.predict(X, threshold)
    return accuracy_score(y, y_pred)


def plot_loss_history(loss_history):
    """Визуализирует историю потерь во время обучения."""
    plt.plot(loss_history)
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.title('Training Loss')
    plt.show()


def plot_decision_boundary(model, X, y):
    """
    Визуализирует разделяющую границу (работает только для 2D-данных).

    Параметры:
    ----------
    X : ndarray, shape (n_samples, 2)
        Матрица признаков (только 2 признака).
    y : ndarray, shape (n_samples,)
        Метки классов.
    """
    if X.shape[1] != 2:
        raise ValueError("plot_decision_boundary работает только для 2D-данных!")

    # Сетка для визуализации
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))

    # Предсказание для сетки
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    # Визуализация
    plt.contourf(xx, yy, Z, alpha=0.4)
    plt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k')
    plt.title("Decision Boundary")
    plt.show()

X, y = make_classification(
        n_samples=10000,
        n_features=2,
        n_classes=2,
        n_redundant=0,
        class_sep=2.0,
        flip_y=0.1,
        random_state=42
    )

# Разделение на train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Создание и обучение модели
model = LogisticRegressionRidge(learning_rate=0.001, lambda_=0.1, verbose=True, epochs=1000)
model.fit(X_train, y_train)

# Оценка модели
print("Веса модели:", model.get_weights())
train_accuracy = score(model, X_train, y_train)
test_accuracy = score(model, X_test, y_test)
print(f"Train Accuracy: {train_accuracy:.4f}")
print(f"Test Accuracy: {test_accuracy:.4f}")

# Визуализация
plot_loss_history(model.loss_history)
plot_decision_boundary(model, X_test, y_test)
C:\Users\yashe\PycharmProjects\SmartAlgo\.venv\Scripts\python.exe C:\Users\yashe\PycharmProjects\SmartAlgo\test\logisticreg_test.py 
Epoch 0, Loss: 0.6923
Epoch 100, Loss: 0.6202
Epoch 200, Loss: 0.5641
Epoch 300, Loss: 0.5202
Epoch 400, Loss: 0.4855
Epoch 500, Loss: 0.4577
Epoch 600, Loss: 0.4353
Epoch 700, Loss: 0.4170
Epoch 800, Loss: 0.4020
Epoch 900, Loss: 0.3896
Epoch 999, Loss: 0.3793
Веса модели: [0.00071847 0.55072918 0.01111198]
Train Accuracy: 0.9345
Test Accuracy: 0.9390

Traning Loss

Decision Boundary

4. Симплекс-метод для линейного программирования

Класс: SimplexMethod
Реализация симплекс-метода для решения задач линейного программирования с обработкой вырожденных случаев.

Параметры конструктора:

  • c (list/numpy.ndarray): Коэффициенты целевой функции (n элементов)
  • A (list/numpy.ndarray): Матрица ограничений (m x n)
  • b (list/numpy.ndarray): Правые части ограничений (m элементов)

Метод:

  • solve(): Решает задачу и возвращает словарь с результатами

Возвращаемые значения (словарь):

  • success (bool): Успешность решения
  • message (str): Описание результата
  • x (numpy.ndarray): Вектор решения (None если не успешно)
  • value (float): Значение целевой функции (None если не успешно)

Пример использования:

from sm_algo.simplex import SimplexMethod

# Задача: максимизировать 3x1 + 2x2 при ограничениях:
# x1 + x2 ≤ 4
# x1 - x2 ≤ 2
c = [3, 2]  # Целевая функция
A = [[1, 1],  # Матрица ограничений
     [1, -1]]
b = [4, 2]    # Правые части

solver = SimplexMethod(c, A, b)
result = solver.solve()

if result['success']:
    print(f"Оптимальное решение: {result['x']}")
    print(f"Значение целевой функции: {result['value']}")
else:
    print("Решение не найдено:", result['message'])

Особенности реализации:

  • Автоматически удаляет линейно зависимые ограничения
  • Использует правило Бланда для предотвращения зацикливания
  • Обрабатывает вырожденные случаи и неограниченные задачи
  • Численно устойчив (использует пороговые значения 1e-10)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sm_algo-0.1.2.tar.gz (16.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sm_algo-0.1.2-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file sm_algo-0.1.2.tar.gz.

File metadata

  • Download URL: sm_algo-0.1.2.tar.gz
  • Upload date:
  • Size: 16.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for sm_algo-0.1.2.tar.gz
Algorithm Hash digest
SHA256 0247fc495ed4fa0dbafe6a2743be18b6bfbcc7320141c8d98716f4b4396a10d3
MD5 5697658bd790bb17ba0fb590ade09bd6
BLAKE2b-256 96f0016ccec8f77d50529203502775ff86d9961272dc072620ee7f2a6ad300f0

See more details on using hashes here.

File details

Details for the file sm_algo-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: sm_algo-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 13.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for sm_algo-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3d68ae0443cf46f4b41a87949ae55015b8462717893cebcb90d523906e8e8e2c
MD5 2ab492ce085ac46f017902672dcb8e59
BLAKE2b-256 98290970e1c419caa3263a878ce8b639e59447e8ab28973dfc4a940dcc718ed4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page