Я прочитал кучу руководств о правильном способе создания логарифмического распределения весов облаков тегов. Большинство из них группируют теги по шагам. Мне это кажется несколько глупым, поэтому я разработал свой собственный алгоритм, основанный на том, что я прочитал, чтобы он динамически распределял количество тегов по логарифмической кривой между порогом и максимумом. Вот суть этого в питоне:
from math import log
count = [1, 3, 5, 4, 7, 5, 10, 6]
def logdist(count, threshold=0, maxsize=1.75, minsize=.75):
countdist = []
# mincount is either the threshold or the minimum if it's over the threshold
mincount = threshold<min(count) and min(count) or threshold
maxcount = max(count)
spread = maxcount - mincount
# the slope of the line (rise over run) between (mincount, minsize) and ( maxcount, maxsize)
delta = (maxsize - minsize) / float(spread)
for c in count:
logcount = log(c - (mincount - 1)) * (spread + 1) / log(spread + 1)
size = delta * logcount - (delta - minsize)
countdist.append({'count': c, 'size': round(size, 3)})
return countdist
По сути, без логарифмического расчета индивидуального количества будет создана прямая линия между точками (mincount, minsize) и (maxcount, maxsize).
Алгоритм хорошо аппроксимирует кривую между двумя точками, но имеет один недостаток. Mincount — это особый случай, и его логарифм дает ноль. Это означает, что размер mincount будет меньше, чем minsize. Я пробовал придумывать числа, чтобы попытаться решить этот особый случай, но, похоже, не могу понять это правильно. В настоящее время я рассматриваю mincount как особый случай и добавляю «or 1
» в строку logcount.
Есть ли более правильный алгоритм для рисования кривой между двумя точками?
Обновление от 3 марта: если я не ошибаюсь, я беру журнал подсчета, а затем подставляю его в линейное уравнение. Другими словами, если описать частный случай, то в y=lnx при x=1, y=0. Вот что происходит на минкаунте. Но mincount не может быть равен нулю, тэг не использовался 0 раз.
Попробуйте код и введите свои собственные числа для проверки. Отношение к mincount как к частному случаю меня вполне устраивает, мне кажется, это будет проще, чем какое бы то ни было реальное решение этой проблемы. Я просто чувствую, что должно быть решение этой проблемы и что кто-то, вероятно, придумал решение.
ОБНОВЛЕНИЕ от 6 апреля: простое google поиск выдает множество руководств, которые я читал, но это, вероятно, наиболее полное пример ступенчатого облака тегов.
ОБНОВЛЕНИЕ 28 апр. В ответ на решение antti.huima: на графике кривая, созданная вашим алгоритмом, лежит ниже линии между двумя точками. Я пытался жонглировать числами, но до сих пор не могу придумать способ перевернуть эту кривую на другую сторону линии. Я предполагаю, что если бы функция была изменена на некоторую форму логарифма вместо экспоненты, она сделала бы именно то, что мне нужно. Это правильно? Если да, то может ли кто-нибудь объяснить, как этого добиться?