Поделиться через


Загрузка данных из файлов и других источников

Узнайте, как загружать данные в ML.NET для обработки и обучения с помощью API. Изначально данные хранились в файлах или других источниках данных, таких как базы данных, JSON, XML или коллекции в памяти.

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

Создание модели данных

ML.NET позволяет определять модели данных с помощью классов. Допустим, у нас есть следующие входные данные:

Size (Sq. ft.), HistoricalPrice1 ($), HistoricalPrice2 ($), HistoricalPrice3 ($), Current Price ($)
700, 100000, 3000000, 250000, 500000
1000, 600000, 400000, 650000, 700000

Создайте модель данных, представляющую следующий фрагмент кода:

public class HousingData
{
    [LoadColumn(0)]
    public float Size { get; set; }

    [LoadColumn(1, 3)]
    [VectorType(3)]
    public float[] HistoricalPrices { get; set; }

    [LoadColumn(4)]
    [ColumnName("Label")]
    public float CurrentPrice { get; set; }
}

Заметите модель данных с атрибутами столбцов

Атрибуты предоставляют ML.NET дополнительные сведения о модели и источнике данных.

Атрибут LoadColumn определяет индексы столбцов свойств.

Внимание

LoadColumn требуется только при загрузке данных из файла.

Загрузите столбцы как:

  • Отдельные столбцы, такие как Size и CurrentPrices в HousingData классе.
  • Несколько столбцов за раз в виде вектора, как HistoricalPrices и в HousingData классе.

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

ML.NET работает с именами столбцов. Если вы хотите изменить имя столбца, чтобы оно отличалось от имени свойства, используйте атрибут ColumnName. При создании объектов в памяти тоже можно создавать объекты, используя имя свойства. Однако для обработки данных и создания моделей машинного обучения ML.NET переопределяет свойство со значением, указанным в атрибуте ColumnName и ссылается на него.

Загрузка данных из отдельного файла

Чтобы загрузить данные из файла, используйте LoadFromTextFile метод с моделью данных для загрузки данных. Поскольку параметр separatorChar по умолчанию разделяется знаками табуляции, измените его, если нужно для файла данных. Если в файле есть заголовок, присвойте параметру hasHeader значение true, чтобы игнорировать первую строку в файле и начать загрузку данных со второй строки.

//Create MLContext
MLContext mlContext = new MLContext();

//Load Data
IDataView data = mlContext.Data.LoadFromTextFile<HousingData>("my-data-file.csv", separatorChar: ',', hasHeader: true);

Загрузка данных из нескольких файлов

Если ваши данные хранятся в нескольких файлах с одинаковой схемой данных, в ML.NET можно загрузить данные из нескольких файлов, которые находятся в одном или нескольких каталогах.

Загрузка данных из файлов в одном каталоге

Если все файлы данных находятся в одном и том же каталоге, используйте в методе LoadFromTextFile подстановочные знаки.

//Create MLContext
MLContext mlContext = new MLContext();

//Load Data File
IDataView data = mlContext.Data.LoadFromTextFile<HousingData>("Data/*", separatorChar: ',', hasHeader: true);

Загрузка из файлов в нескольких каталогах

Чтобы загрузить данные из нескольких каталогов, с помощью метода CreateTextLoader создайте TextLoader. Затем с помощью метода TextLoader.Load укажите пути к отдельным файлам (подстановочные знаки использовать нельзя).

//Create MLContext
MLContext mlContext = new MLContext();

// Create TextLoader
TextLoader textLoader = mlContext.Data.CreateTextLoader<HousingData>(separatorChar: ',', hasHeader: true);

// Load Data
IDataView data = textLoader.Load("DataFolder/SubFolder1/1.txt", "DataFolder/SubFolder2/1.txt");

Загрузка данных из реляционной базы данных

ML.NET поддерживает загрузку данных из различных реляционных баз данных , поддерживаемых System.Data, включая SQL Server, базу данных SQL Azure, Oracle, SQLite, PostgreSQL, Progress, IBM DB2 и многие другие.

Примечание.

Чтобы использовать DatabaseLoader, необходимо сослаться на пакет NuGet System.Data.SqlClient.

Имеется база данных с таблицей House и следующей схемой:

CREATE TABLE [House] (
    [HouseId] INT NOT NULL IDENTITY,
    [Size] INT NOT NULL,
    [NumBed] INT NOT NULL,
    [Price] REAL NOT NULL
    CONSTRAINT [PK_House] PRIMARY KEY ([HouseId])
);

Можно моделировать данные с помощью класса, например HouseData:

public class HouseData
{
    public float Size { get; set; }
    public float NumBed { get; set; }
    public float Price { get; set; }
}

Затем в приложении создайте DatabaseLoader.

MLContext mlContext = new MLContext();

DatabaseLoader loader = mlContext.Data.CreateDatabaseLoader<HouseData>();

Определите строку подключения, а также команду SQL для выполнения в базе данных и создайте экземпляр DatabaseSource. В этом примере используется база данных LocalDB SQL Server с путем к файлу. Однако DatabaseLoader поддерживает любые другие допустимые строки подключения для баз данных в локальной среде и в облаке.

string connectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=<YOUR-DB-FILEPATH>;Database=<YOUR-DB-NAME>;Integrated Security=True;Connect Timeout=30";

string sqlCommand = "SELECT CAST(Size as REAL) as Size, CAST(NumBed as REAL) as NumBed, Price FROM House";

DatabaseSource dbSource = new DatabaseSource(SqlClientFactory.Instance, connectionString, sqlCommand);

Числовые данные, которые не имеют типа Real , необходимо преобразовать в Real. Тип Real представлен значением с плавающей запятой одиночной точности или Single (тип входных данных, ожидаемый алгоритмами ML.NET). В этом примере столбцы Size и NumBed являются целыми числами в базе данных. С помощью встроенной функции CAST выполняется преобразование в Real. Price Так как свойство уже имеет типReal, он загружается как есть.

Используйте метод Load для загрузки данных в IDataView.

IDataView data = loader.Load(dbSource);

Загрузка образов

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

public class ImageData
{
    [LoadColumn(0)]
    public string ImagePath;

    [LoadColumn(1)]
    public string Label;
}

public static IEnumerable<ImageData> LoadImagesFromDirectory(string folder,
            bool useFolderNameAsLabel = true)
{
    string[] files = Directory.GetFiles(folder, "*", searchOption: SearchOption.AllDirectories);

    foreach (string file in files)
    {
        if (Path.GetExtension(file) != ".jpg")
            continue;

        string label = Path.GetFileName(file);

        if (useFolderNameAsLabel)
            label = Directory.GetParent(file).Name;
        else
        {
            for (int index = 0; index < label.Length; index++)
            {
                if (!char.IsLetter(label[index]))
                {
                    label = label.Substring(0, index);
                    break;
                }
            }
        }

        yield return new ImageData()
        {
            ImagePath = file,
            Label = label
        };
    }
}

Затем загрузите изображение:

IEnumerable<ImageData> images = LoadImagesFromDirectory(
                folder: "your-image-directory-path",
                useFolderNameAsLabel: true
                );

Чтобы загрузить необработанные образы из каталога, создайте модель для хранения массива байтов и меток необработанных образов:

public class InMemoryImageData
{
    [LoadColumn(0)]
    public byte[] Image;

    [LoadColumn(1)]
    public string Label;
}

static IEnumerable<InMemoryImageData> LoadInMemoryImagesFromDirectory(
    string folder,
    bool useFolderNameAsLabel = true
    )
{
    string[] files = Directory.GetFiles(folder, "*",
        searchOption: SearchOption.AllDirectories);
    foreach (string file in files)
    {
        if (Path.GetExtension(file) != ".jpg")
            continue;

        string label = Path.GetFileName(file);
        if (useFolderNameAsLabel)
            label = Directory.GetParent(file).Name;
        else
        {
            for (int index = 0; index < label.Length; index++)
            {
                if (!char.IsLetter(label[index]))
                {
                    label = label.Substring(0, index);
                    break;
                }
            }
        }

        yield return new InMemoryImageData()
        {
            Image = File.ReadAllBytes(file),
            Label = label
        };

    }
}

Загрузка данных из других источников

Помимо загрузки данных, хранящихся в файлах, ML.NET поддерживает загрузку данных из источников, которые включают:

  • Коллекции оперативной памяти
  • располагаться в коде JSON или XML;

При работе с источниками потоковой передачи ML.NET ожидает, что входные данные будут находиться в виде коллекции в памяти. Это значит, что при работе с такими источниками, как JSON/XML, данные должны быть переведены в формат коллекции в памяти.

Допустим, у нас есть следующая коллекция в памяти:

HousingData[] inMemoryCollection = new HousingData[]
{
    new HousingData
    {
        Size =700f,
        HistoricalPrices = new float[]
        {
            100000f, 3000000f, 250000f
        },
        CurrentPrice = 500000f
    },
    new HousingData
    {
        Size =1000f,
        HistoricalPrices = new float[]
        {
            600000f, 400000f, 650000f
        },
        CurrentPrice=700000f
    }
};

Загрузите эту коллекцию в памяти в IDataView с помощью метода LoadFromEnumerable:

Внимание

LoadFromEnumerable предполагает, что IEnumerable, откуда он загружается, является потокобезопасным.

// Create MLContext
MLContext mlContext = new MLContext();

//Load Data
IDataView data = mlContext.Data.LoadFromEnumerable<HousingData>(inMemoryCollection);

Следующие шаги