[Машинное обучение] Визуализация низкоразмерных данных

машинное обучение

Это 30-й день моего участия в августовском испытании обновлений. Узнайте подробности события:Испытание августовского обновления

Введение

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

2. Рассеянный дисплей

image.png

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

1. Установка зависимостей

Основные шаги здесь таковы:

  1. Создайте новую виртуальную среду (для предотвращения конфликтов с исходной версией библиотеки)
  2. изменить источник
  3. Установить
# 永久换源(清华源)
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 安装
pip install -r requirements.txt

Вот мои библиотеки зависимостей для этого эксперимента:

# requirements.txt
numpy
pandas
matplotlib
seaborn
scipy
sklearn

2. Сгенерировать разброс

Генерация кругового рассеяния

Использование sklearn.datasetsmake_circlesфункция.

Эта функция вернет два списка numpy.narray, первый элемент списка — это координаты (x, y) сгенерированной точки, а второй список — это тег метки точки.

Среди них значение тега появляется попеременно от 0 до 1, указывая точку внутреннего круга и точку внешнего круга (мы можем покрасить это, чтобы различить).

Вот реализация кода:

from sklearn import datasets
points, tags = datasets.make_circles(
    n_samples=400,
    shuffle=True,
    noise=.1,
    random_state=4103,
    factor=.1
)

Некоторые настройки параметров:

  • n_samples: количество точек
  • shuffle: перетасовать образцы -True
  • Шум: Гаусский шум стандартного отклонения
  • random_state: Случайное семя
  • фактор: можно понимать как интервал внутреннего и внешнего круга

Затем идет часть отображения страницы:

colors = ["b" if tag else "m" for tag in tags]
plot = figure.add_subplot(location)
plot.set_title('data by make_circles()')
plot.scatter(
    x=points[:, 0],
    y=points[:, 1],
    s=100,
    marker="o",
    c=colors,
)

Сначала установите цвет (см. первую строку), тип данных точки — numpy.narray, используйтеpoints[:, 0]``points[:, 1]Может быстро составить список координат точек x, y (синтаксический сахар numpy).

Кроме того, параметр s представляет размер точки маркера, marker представляет форму точки маркера ("o" представляет собой круг), а c представляет цвет точки маркера (в дополнение к списку, вы также можете передать строку, указывающую, что все используют один цвет).

Эффект следующий:

image.png

Генерация серповидного рассеяния

По сути, он очень похож на предыдущий, ноmake_moonsзаменятьmake_circlesПросто сделай это.

points, tags = datasets.make_moons(
    n_samples=400,
    shuffle=True,
    noise=.1,
    random_state=4103,
)

Остальные части такие же, как указано выше.

Код после простой отделки выглядит следующим образом

import matplotlib.pyplot as plt
from sklearn import datasets


def build_circle_figure(figure: plt.Figure, location=211) -> None:
    points, tags = datasets.make_circles(
        n_samples=400,
        shuffle=True,
        noise=.1,
        random_state=4103,
        factor=.1
    )
    colors = ["b" if tag else "m" for tag in tags]
    plot = figure.add_subplot(location)
    plot.set_title('data by make_circles()')
    plot.scatter(
        x=points[:, 0],
        y=points[:, 1],
        s=100,
        marker="o",
        c=colors,
    )


def build_make_moons(figure: plt.Figure, location=212) -> None:
    points, tags = datasets.make_moons(
        n_samples=400,
        shuffle=True,
        noise=.1,
        random_state=4103,
    )
    colors = ["b" if tag else "m" for tag in tags]
    plot = figure.add_subplot(location)
    plot.set_title('data by make_moons()')
    plot.scatter(
        x=points[:, 0],
        y=points[:, 1],
        s=100,
        marker="o",
        c=colors,
    )


if __name__ == '__main__':
    fig = plt.figure()
    build_circle_figure(fig)
    build_make_moons(fig)
    plt.tight_layout()
    plt.show()

Результат выглядит следующим образом:

image.png

Мышление: как визуализировать многомерные данные?

О: Вы можете попробовать уменьшить размерность данных и использовать для обработки алгоритмы PCA, LCA и другие.

3. Загрузите набор данных

image.pngссылка для скачивания:archive.ICS.UCI.quote/beauty/index.fit…

набор данных документа

Я загрузил самый популярный набор данных радужной оболочки в наборе данных UCI, с размером данных 150 и единичной длиной 4 метки + вывод результата:

  • Этикетка
    • sepal_length
    • sepal_width
    • petal_length
    • petal_width
  • вывод
    • class

image.png

Выше приведен список загруженных файлов:

Среди них Index — это каталог папки, а iris.name — некоторая базовая информация о данных, которая не влияет на обучение и может быть проигнорирована.

В то же время bezdekIris.data и iris.data абсолютно одинаковы, поэтому нам нужно обратить внимание только на iris.data, который является файлом данных:

image.png

использовать иАналогичная операция при отображении диаграммы рассеяния данных:

image.png

Большая точка — это данные о длине и ширине чашелистика, а маленькая точка — это данные о длине и ширине лепестка.

Код реализован следующим образом:

import matplotlib.pyplot as plt
import numpy


if __name__ == '__main__':
    with open("./iris.data") as f:
        lines = f.readlines()
    dataset = []
    for line in lines[:-1]:
        dataset.append(line.split(","))
    dataset = numpy.array(dataset)
    colors = []
    for label in dataset[:, 4]:
        if "setosa" in label:
            colors.append("r")
        elif "versicolor" in label:
            colors.append("g")
        else:
            colors.append("b")

    plt.scatter(
        x=dataset[:, 0],
        y=dataset[:, 1],
        s=100,
        marker="o",
        c=colors
    )
    plt.scatter(
        x=dataset[:, 2],
        y=dataset[:, 3],
        s=20,
        marker="o",
        c=colors
    )
    plt.show()

Набор данных изображения

Набор данных изображений, который я выбрал, — это набор данных распознавания кошек и собак kaggle (12 500 кошек и собак) (представленный в предыдущих блогах)Resnet18 - Распознавание кошек и собак)

Ниже приведен метод чтения данных изображения в pytorch:

def get_data(input_size, batch_size):
    """获取文件数据并转换"""
    from torchvision import transforms
    from torchvision.datasets import ImageFolder
    from torch.utils.data import DataLoader

    # 串联多个图片变换的操作(训练集)
    # transforms.RandomResizedCrop(input_size) 先随机采集,然后对裁剪得到的图像缩放为同一大小
    # RandomHorizontalFlip()  以给定的概率随机水平旋转给定的PIL的图像
    # transforms.ToTensor()  将图片转换为Tensor,归一化至[0,1]
    # transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])  归一化处理(平均数,标准偏差)
    transform_train = transforms.Compose([
        transforms.RandomResizedCrop(input_size),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
    ])
    # 获取训练集(通过上面的方面操作)
    train_set = ImageFolder('train', transform=transform_train)
    # 封装训练集
    train_loader = DataLoader(dataset=train_set,
                              batch_size=batch_size,
                              shuffle=True)

    # 串联多个图片变换的操作(验证集)
    transform_val = transforms.Compose([
        transforms.Resize([input_size, input_size]),  # 注意 Resize 参数是 2 维,和 RandomResizedCrop 不同
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
    ])
    # 获取验证集(通过上面的方面操作)
    val_set = ImageFolder('val', transform=transform_val)
    # 封装验证集
    val_loader = DataLoader(dataset=val_set,
                            batch_size=batch_size,
                            shuffle=False)
    # 输出
    return transform_train, train_set, train_loader, transform_val, val_set, val_loader

Сгенерируйте миниатюру одиночного изображения 10*10 размером 100*100, код реализации выглядит следующим образом:

import PIL.Image as Image
import os


def image_compose(label):
    image_names = [name for name in os.listdir(label + "/")]
    to_image = Image.new('RGB', (10 * 100, 10 * 100))
    for y in range(1, 10 + 1):
        for x in range(1, 10 + 1):
            from_image = Image.open(label + "/" + image_names[10 * (y - 1) + x - 1]).resize(
                (100, 100), Image.ANTIALIAS)
            to_image.paste(from_image, ((x - 1) * 100, (y - 1) * 100))
    return to_image.save(label + ".jpg")

Эффект следующий:

image.png

image.png