Алгоритмы неформально. Инструкция для начинающих питонистов - [23]
def revenue_flipped(tax):
return(0 - revenue(tax))
После этого график инвертированной функции строится так:
import matplotlib.pyplot as plt
xs = [x/1000 for x in range(1001)]
ys = [revenue_flipped(x) for x in xs]
plt.plot(xs,ys)
plt.title('The Tax/Revenue Curve - Flipped')
plt.xlabel('Current Tax Rate')
plt.ylabel('Revenue - Flipped')
plt.show()
На рис. 3.4 изображена перевернутая кривая.
Итак, если мы хотим найти максимум кривой ставки налога/поступлений, то в одном из способов минимизируем перевернутую кривую. А если хотим найти минимум перевернутой кривой, то один из вариантов заключается в максимизации перевернутой перевернутой кривой — другими словами, исходной кривой. Каждая задача минимизации является задачей максимизации инвертированной функции, а каждая задача максимизации — задачей минимизации инвертированной функции. Если вы можете решить одну задачу, то сможете решить и другую (после
Рис. 3.4. Инвертированная, то есть «перевернутая» версия кривой ставки налога/поступлений
инвертирования). Вместо того чтобы учиться минимизировать функции, достаточно научиться максимизировать их. Тогда каждый раз, когда вам потребуется минимизировать функцию, вы можете максимизировать инвертированную функцию и получить правильный ответ.
Инвертирование — не единственное решение. Процесс поиска минимума очень похож на процесс поиска максимума: вместо градиентного подъема используется градиентный спуск. Единственное отличие — направление смещения на каждом шаге; при градиентном спуске мы двигаемся вниз, а не вверх. Напомню: чтобы найти максимум кривой ставки налога/поступлений, мы двигались по направлению градиента. Чтобы найти минимум, следует двигаться в обратном направлении. Это означает, что мы можем изменить исходный код градиентного подъема так, как показано в листинге 3.3.
Листинг 3.3. Реализация градиентного спуска
threshold = 0.0001
maximum_iterations = 10000
def revenue_derivative_flipped(tax):
return(0-revenue_derivative(tax))
current_rate = 0.7
keep_going = True
iterations = 0
while(keep_going):
rate_change = step_size * revenue_derivative_flipped(current_rate)
current_rate = current_rate - rate_change
if(abs(rate_change) < threshold):
keep_going = False
if(iterations >= maximum_iterations):
keep_going = False
iterations = iterations + 1
Все осталось тем же самым, не считая того, что знак + при изменении current_rate превратился в -. Ограничиваясь очень малыми изменениями, мы преобразовали код градиентного подъема в код градиентного спуска. В каком-то смысле эти два метода можно назвать эквивалентными: оба используют градиент для определения направления, а затем двигаются в данном направлении к определенной цели. В наше время обычно говорят о градиентном спуске, а градиентный подъем рассматривается как его слегка измененная версия — такой подход прямо противоположен тому, как два метода были представлены в текущей главе.
О пользе подъема
Назначение на должность премьер-министра — редкое событие, и выбор ставки налога для максимизации налоговых сборов не входит в повседневные обязанности премьер-министров. (Если вы хотите увидеть реальную версию зависимости поступлений от ставки налога, то рекомендую поискать информацию о кривой Лаффера.) Тем не менее идея максимизации или минимизации чего-либо встречается очень часто. Компании стараются выбирать цены для максимизации прибыли. Производители стремятся выбирать практики, которые максимизируют эффективность и минимизируют количество дефектов. Инженеры стараются выбирать конструктивные особенности, которые максимизируют производительность или минимизируют затраты. Экономика в значительной мере структурирована на задачах максимизации и минимизации, прежде всего максимизации эффективности и денежных сумм (ВВП, налоговые поступления) и минимизации ошибок оценки. Машинное обучение и статистика во многих своих методах опираются на минимизацию; они минимизируют «функцию потерь», или метрику ошибок. Во всех этих задачах заложен потенциал для использования методов поиска экстремума (таких как градиентный подъем или спуск) для поиска оптимального решения.
Даже в повседневной жизни мы выбираем, сколько денег потратить и как распределить доход. Мы стараемся максимизировать счастье, удовольствие и любовь и минимизировать боль, неудобства и огорчения.
Если вам нужен яркий и узнаваемый пример, то представьте, что вы за шведским столом, как и все мы, пытаетесь выбрать оптимальное количество еды. Если съедите слишком мало, то останетесь голодным и будете считать, что слишком дорого заплатили за небольшое количество еды и деньги были потрачены зря. Если съедите слишком много, то вам будет тяжело ходить, а может быть, вы нарушите установленную для себя диету, а то и заболеете. Существует «золотая середина», аналог пика на кривой ставке налога/поступлений, которая определяет оптимальное количество еды для максимизации удовлетворения.
Мы, люди, чувствуем и интерпретируем ощущения в своем животе, который сообщает нам, что мы голодны или сыты; иногда они становятся чем-то вроде физического аналога вычисления градиента кривой. Если мы слишком голодны, то делаем шаг заранее определенного размера (например, один кусочек) в направлении «золотой середины». Если слишком сыты, то просто перестаем есть; отменить что-то уже съеденное не получится. При достаточно малом размере шага можно быть уверенными в том, что нам удастся избежать слишком значительного перекрытия оптимума. Решая, сколько нужно съесть за шведским столом, мы тоже проходим итеративный процесс, в котором многократно проверяется направление и совершаются небольшие шаги в изменяющихся направлениях, — иначе говоря, происходит практически то же, что и в алгоритме градиентного подъема, рассмотренного в этой главе.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.