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

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

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

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

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

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

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

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

Вторая функция hash_representation(df) используется функцией train(). Он вычисляет хеширование признаков для входных строк, которые хранятся в виде столбца во входном файле df. Вычисленное представление объекта объединяется с DataFrame 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% тестовых данных содержат 100 000 образцов, что достаточно для оценки производительности. Мы оценили логистическую регрессию, метод опорных векторов и искусственные нейронные сети с несколькими вариантами архитектуры. Было обнаружено, что искусственные нейронные сети дают наилучшие результаты проверки. В то время как производительность более глубоких архитектур немного лучше, ИНС с 1 скрытым слоем, состоящим из 100 нейронов, дает производительность проверки; достаточно хорошо, чтобы продемонстрировать наши идеи. Мы также обнаружили, что производительность проверки незначительно меняется после первой эпохи; предлагая производительность проверки с 1 эпохой, чтобы представить производительность модели. В наших последующих экспериментах мы использовали ИНС с 1 скрытым слоем, состоящим из 100 нейронов, поскольку наша модель и обучение проводились всего за 1 эпоху.

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

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

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

h = FeatureHasher(n_features=hashing_dimension)

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

Измерение хешированияТочность проверки
160073,9%
320080,4%
640086,8%
1280091,6%
1920093,5%
2560094,8%

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

Выводы

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

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *