Рубрики
Без рубрики

Машинное обучение с разреженными, многомерными и большими наборами данных

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

Автор оригинала: Waqas Bukhari PhD.

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

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

В этой статье мы используем инструменты из Python, такие как Pandas, Numpy и Scikit-Learn, для использования хэширования функций и мини-пакетного обучения с разреженными, многомерными и большими наборами данных. Фрагменты кода с подробными комментариями включены для практической реализации в рамках науки о данных python.

Создание и хранение данных

Мы демонстрируем практическое использование хеширования функций и мини-пакетного обучения с использованием задачи бинарной классификации. Для решения этой проблемы создается поддельный набор данных, содержащий 1,0 миллиона точек данных. Каждая точка данных в наборе данных содержит пакет буквенно-цифровых маркеров вместе с меткой. При создании набора данных мы сначала создали 65464 буквенно-цифровых объекта путем случайной выборки из набора алфавитов и 10 цифр. Во-вторых, мы сгенерировали данные для каждого из двух классов (0 и 1) отдельно, используя половину числа функций, т. Е. исключительно 32732. Чтобы создать разреженность, ни одна из функций не назначается более чем 0,3% данных. Обратите внимание, что наше создание данных приводит к совершенно разделяемым классам.

Мини-пакетное обучение с хешированием функций

Следующий код демонстрирует практическую реализацию итеративного обучения с хэшированием функций. Функциональный поезд(модель, линии) обновляет модель в течение 1 эпохи с помощью мини-пакетного обучения. Обучающий набор данных хранится в строках в виде списка строк, каждая из которых является записью. Это универсальная функция, которая применяется к любому классу модели в sklearn, поддерживающему метод partial_fit (). Популярными вариантами моделей классификации, поддерживающими функцию partial_fit (), являются логистическая регрессия, машины опорных векторов и искусственные нейронные сети. Эта функция поддерживает мини-пакетное обучение; каждая партия размером 1000 образцов. На каждой итерации функция создает фрейм данных pandas из 1000 выборок из строк, вычисляет хэширование объектов в соответствии с заранее определенными размерами объектов и обновляет модель.

Вторая функция hash_representation(df) используется функцией train (). Он вычисляет хеширование объектов на входных строках, которые хранятся в виде столбца во входном df. Вычисленное представление объектов объединяется с фреймом данных df и возвращается.

См.Подробные комментарии в функциях для лучшего понимания.

def hash_representation(df):
    
    def vectorize(line):
        ''' This function transforms a line comprising bag to words to its hash representation. 
        Input to this function is a line that comprises , separated words.
        output is a numpy array which is the hash representation of line according to a hash 
        template (global object). 
        '''
        # Construct a dictionary comprising each word in the line as keys and 1 as its value. 
        D = [{key:1 for key in line.split('\n')[0].split(',')}]
        # tranform D to a numpy array according to a hash template h. 
        return h.transform(D).toarray()[0]
    
    # Obtain hash represntation of input strings. 
    s = df['inputs'].apply(vectorize)
    # Giving non-numeric names to the resulting data frame. 
    columns = ['col_'+str(i) for i in range(len(s.values[0]))]  
    new_df = pd.DataFrame.from_items(zip(s.index, s.values), orient='index', columns=columns)
    new_df['labels'] = df['labels']
    # Returning dataframe that has hash representation of inputs as features along with class labels. 
    return new_df    
def train(model, lines):

    ''' This function takes updates the model over 1 epoch of training data.     
    Inputs to this function are:    
    model ~ An sklearn model object over which partial_fit() method is valid.
    lines ~ a list of strings and each string is a record, example or a measurement.     
    Output of this function is     
    model ~ an updated model.     
    '''
    
    ''' We construct a pandas DataFrame out of these lines and use its str 
    functionality to create new columns; one for input strings and the other for 
    output labels. '''
    df = pd.DataFrame(lines, columns=['raw_data'])
    df['labels'] = df['raw_data'].str.split(',').apply(lambda x:x[0]).astype(int) #%[0][0]
    df['inputs'] = df['raw_data'].str.split(',').apply(lambda x:x[1]) #%[0][0]
    del df['raw_data']
    
    ''' We shuffle the data to ensure randomness to avoid any cycles in training. '''
    df = shuffle(df)
    ''' We specify the batch size that specifies the data size over which model update is based in one iteration. '''
    batch_size = 1000
    "total number of batches"
    total_batches = math.ceil(df.shape[0] / batch_size)
    
    # Iterating over each batch. 
    for batch_numb in range(total_batches):
        st = batch_numb * batch_size # starting index (inclusive) of the batch. 
        en = (1+batch_numb) * batch_size # End index (exclusive) of the batch. 
        ''' Last batch may comprise data points less than the batch_size. 
            Under such a scenario, the batch_size comprises remaining elements
            that are less than the batch_size and we modify the End index to 
            be the size of the lines. 
        '''
        en = min(en, df.shape[0]) 
        '''For the subset of lines comprising current batch, 
           we construct a new data frame that comprises hash representation of the 
           inputs along with outputs. 
        '''
        tmp_df = hash_representation(df.iloc[st:en])
        tmp_labels = tmp_df['labels'].copy()
        del tmp_df['labels']
        
        # model update using current batch. 
        model.partial_fit(np.array(tmp_df), np.array(tmp_labels), classes=[0,1])
        
    # returning model after updating with 1 epoch. 
    return model

Выбор модели и гиперпараметры

Чтобы продемонстрировать эффективность нашего Мини-пакетного обучения с хешированием функций подхода, мы разделили наш набор данных на 80% обучения, 10% проверки и 10% тестирования. следует отметить, что 10% тестовых данных содержат 100000 образцов, что достаточно для оценки производительности. Мы оценили логистическую регрессию, машину опорных векторов и искусственные нейронные сети с несколькими вариантами архитектуры. Было обнаружено, что искусственные нейронные сети дают наилучшую производительность проверки. В то время как производительность на более глубоких архитектурах немного выше, ANN с 1 скрытым слоем, состоящим из 100 нейронов, обеспечивает производительность проверки; достаточно хорошую, чтобы продемонстрировать наши идеи. Мы также обнаружили, что производительность валидации лишь незначительно меняется по сравнению с первой эпохой; предполагая, что производительность валидации с 1 эпохой является репрезентативной для производительности модели. В наших последующих экспериментах мы использовали ANN с 1 скрытым слоем, состоящим из 100 нейронов, в качестве нашей модели, и обучение проводилось всего за 1 эпоху.

Оптимальный размер хеширования

Хеширование объектов может привести к столкновению хеширования , которое относится к двум различным точкам данных, дающим одно и то же представление хеширования. Столкновение образцов одного класса с образцами другого ухудшает точность классификации. По мере увеличения размера хеширования все меньшие и меньшие различия во входных данных приводят к различным представлениям хеширования; следовательно, количество столкновений уменьшается. Недостатки в обучении, возможное смещение модели и коллизии хэширования являются важными источниками шума в этой задаче бинарной классификации. Хотя недостатки в обучении и возможная предвзятость модели могут быть исследованы, мы стремимся продемонстрировать влияние измерений хеширования на эффективность классификации. Более высокий размер хеширования, вероятно, повышает точность классификации, хотя и за счет вычислений и памяти.

Ниже приведен шаблон хеширования объектов из sklearn.feature_extraction с размером хеширования в качестве параметра.

h = FeatureHasher(n_features=hashing_dimension)

Мы провели численные эксперименты с различными размерами хеширования и получили следующую точность проверки.

1600 73.9%
3200 80.4%
6400 86.8%
12800 91.6%
19200 93.5%
25600 94.8%

Обратите внимание из таблицы, что производительность проверки улучшается с измерением хеширования, однако при уменьшении отдачи. Более высокие размеры хэширования приводят к вычислительно более дорогостоящему обучению и требуют большего объема памяти или меньшего размера пакета. Следовательно, оптимальный выбор размера хеширования зависит от вычислительных ресурсов и точки, после которой отдача незначительна. Для нашего случая мы выбрали размер хеширования 12800 и оценили производительность теста, которая составила 91,4%.

Выводы

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