Сравнение значений одного хэша со многими хэшами, чтобы получить обратную частоту документов в рубине
Я пытаюсь найти частоту инверсного документа для алгоритма категоризации, и у меня возникают проблемы с его структурированием (с вложенными хэшами) и в целом сравниваю один хэш со многими хэшами.
Мой тренировочный код выглядит так:
def train!
@data = {}
@all_books.each do |category, books|
@data[category] = {
words: 0,
books: 0,
freq: Hash.new(0)
}
books.each do |filename, tokens|
@data[category][:words] += tokens.count
@data[category][:books] += 1
tokens.each do |token|
@data[category][:freq][token] += 1
end
end
@data[category][:freq].map { |k, v| v = (v / @data[category][:freq].values.max) }
end
end
По сути, у меня есть хэш с 4 категориями (могут быть изменены), и для каждой из них есть количество слов, счетчик книг и хэш частоты, который показывает частоту терминов для категории. Как я могу получить частоту отдельных слов из одной категории по сравнению с частотой слов, показанных во всех категориях? Я знаю, как сделать сравнение для одного набора ключей хеша с другим, но я не уверен, как пройти через вложенный хэш, чтобы получить частоту терминов против всех других терминов, если это имеет смысл.
Изменить, чтобы включить прогнозируемый результат - я хотел бы вернуть хэш вложенных хэшей (по одному для каждой категории), который показывает слово в качестве ключа и число других категорий, в которых оно отображается в качестве значения. т.е. {:category1 = {:word => 3,:other => 2,:third => 1},:category2 => {:another => 1, ...}} Альтернативно массив имен категорий в качестве значения, а не количество категорий, также будет работать.
Я попытался создать новый хеш следующим образом, но он оказался пустым:
def train!
@data = {}
@all_words = Hash.new([]) #new hash for all words, default value is empty array
@all_books.each do |category, books|
@data[category] = {
words: 0,
books: 0,
freq: Hash.new(0)
}
books.each do |filename, tokens|
@data[category][:words] += tokens.count
@data[category][:books] += 1
tokens.each do |token|
@data[category][:freq][token] += 1
@all_words[token] << category #should insert category name if the word appears, right?
end
end
@data[category][:freq].map { |k, v| v = (v / @data[category][:freq].values.max) }
end
end
Если кто-то может помочь мне выяснить, почему хеш @all_words пуст при выполнении кода, я могу получить остальное.
1 ответ
Я не прошел через все это, но у вас наверняка есть ошибка:
@all_words[token] << category #should insert category name if the word appears, right?
Нету. @all_words[token]
вернет пустой массив, но не создаст новый слот с пустым массивом, как вы предполагаете. Так что это утверждение не изменяет @all_words
хеш вообще.
Попробуйте эти 2 изменения и посмотрите, поможет ли это:
@all_words = {} # ditch the default value
...
(@all_words[token] ||= []) << category # lazy-init the array, and append