Pull to refresh
10
0

Senior Software Developer

Send message

Решение, в основе которого лежит только матстат, в принципе порочно.

Дело в том, что то, что вы описываете как порок это как раз красота и сила статистики. Она как раз в том, что для определения важных свойств системы ей не требуется строить ее детальную модель - то, что вы, как я понимаю, и предлагаете как итог рассуждений в статье.

К примеру, важно ли то, что дождей в последние пять лет меньше? Классическая инженерия должна построить сложнейшую модель дождей, почему они идут, откуда, что на них влияет. Статистика скажет - да, это важно, различие статистически значимо. Думайте ребята над глобальным потеплением. То есть, когда в Виллабаджо уже будут пировать, лирический герой Вашей статьи в банке все еще будет строить детальную модель заемщика.

( Если девять рыжих пришли и купили квартиру, то десятый купит квартиру с вероятностью 9/10. ! )

Это не бред, если в городе есть клуб рыжих и они там обсудили, то если 9, то там же и 10. А если клуба нет! Но этого не знает никакой ИИ. Нет в матстате такого инструмента определения зависимости из газет. С матстатом набираем знания только из накопленных ошибок !


Кстати, ровно так и в Вашем примере. Как раз статистика-то и определит, что этот самый клуб рыжих любителей покупать квартиры в городе N с какой-то вероятностью существует без необходимости для Вашего лирического героя бегать по подъездам и салонам в его поисках. Я сейчас, разумеется, не касаюсь специфических технических деталей, что выборка должна быть одинаково распределена и т.п. Если все нужные технические критерии соблюдены, то мат. стат. , не имея детальной модели укажет Вам на закономерность между рыжим цветом волос в данном городе и вероятностью покупки квартиры. "Не имея детальной модели" - это главный посыл и главная сила статистики.
Далее, вы как-то не научно рассуждаете, хотя блог вроде бы о датасайенсе. Мол, если в городе клуб рыжих, то это не бред, а если там это клуба нет, то вроде как это бред. Это откуда такая уверенность? Вы, раз отвергаете статистику, простите, построили детальную физическую модель происходящего? А, может быть, в этом городе рыжий цвет волос определяется (коррелирует) единственной национальностью, а эта национальность испокон веков занимается бизнесом по сдаче квартир, а для этого им нужно их покупать? И таких вариантов вагон и телегу можно за минуту можно нагенерировать. Статистика их распознает, а Ваш лирический герой на основе видимо "жизненного опыта" будет делать голословные (потому что нет модели и детального исследования) умозрительные заключения о том бред это или нет.

А то, что вы описали с раззорившимся заводом это называется изменением распределения исходного признака или, по-модному, "Черный лебедь". Даже если зависимость не задана явно, она все равно существует, то есть признак "место работы" в банковской модели на самом деле определяет признак "стабильность получения заработной платы" и, возможно, другие - "частота повышения зарплаты" и т.п. И вот эта случайная величина из "места работы" в "стабильность" поменяла свое распределение. Очевидно, что в случае такого изменения модель перестает работать, как и случае, когда вы в формулу 2+2=4 подставите вместо двоек тройки. Я специально привел такой простой пример, чтобы показать, что вы, в общем, сказали абсолютно тривиальную вещь с которой, в общем, понятно как бороться - постоянно дообучать модель, иметь сбалансированный набор признаков, компенсирующих такие изменения. Например, если добавить частоту обращения сотрудников за кредитом именно из этого завода, то при проблемах с зарплатой эта частота сразу повысится, что понизит вероятность выдачи кредита (если, конечно, в модели эта частота обратно зависима от вероятности выдачи кредита). Чтобы не вдаваться в технические обсуждения, которые могут возникнуть в комментариях, сразу скажу, что, да, я понимаю, что очень часто наличие таких компенсирующих признаков говорит о наличии корреляции между исходными признаками, которые, по-хорошему, должны быть независимы, но в данном случае, я просто пытаюсь за минуту "закостылить" модель с уже не очень хорошо подобранным признаком "место работы". То есть, выдача кредита, конечно, некоторым образом должна зависить от места работы, но не в таком прямом виде, а скорее должна зависить от некоторого независимого (действительно) параметра, который определяет "качество" данного места работы. Например, входным параметром может быть текущая кредиторская задолженность предприятия по заработной плате (вероятно, каким-то образом нормированная по кол-ву сотрудников и т.п., не будем углубляться в технические детали) и тогда вышеописанной автором проблемы модель иметь не будет.

В общем, скоринговая статистическая модель это не что-то, что вам сделала год назад какая-то сторонняя консалтинговая фирма и потом вы этим пользуетесь10 лет без изменений. Она требует постоянного дообучения и, как и почти во всех моделях, иногда и вмешательства оператора (человека) в ее работу - в случае "Черных лебедей". Ваш пример с обанкротившимся заводом, это, очевидно, не самый страшный Черный лебедь, который мог произойти. Тут, знаете, такие сейчас Черные лебеди, что впору создавать модели предсказания на само существование той или иной кредитной организации. Поэтому, конечно, иногда вмешательство оператора нужно. Это тоже очевидно.

В общем, вы меня извините, но для статьи с тегом "Data Mining*Машинное обучение*Исследования и прогнозы в IT* " это очень низкое техническое качество материала. Статья целиком и полностью основана на каких-то тривиальных умозрительных заключениях с цепочками if else, описываются слабые плохо продуманные модели, на основе которых делается общее заключение о порочности использования статистики.

В общем, ни о чем статья. Извините. Но заголовок кликбейтный, я и сам на него, признаюсь, купился. Даже "AI" ни к ночи упомянуто. Отмечу по этому поводу, что даже прекрасная скоринговая модель, отлично переживающая закрытия заводов, основанная на выборе признаков и обучении на их основе в современном понимании (да, мне кажется, что и в любом) не является AI. В связи с этим, чтобы не вводить читателей хабра в заблуждение предлагаю поменять заголовок, убрав оттуда AI, но сохранив кликбейтность. Думаю, отличным вариантом будет "Если бы у бабушки был..., то ей бы дали кредит".


Из довольно простых, но хороших для базового понимания теории вероятности и мат. статистики на уровне, достаточном для практического применения в "дата сайенс" можно начать с двух следующих учебников:

  1. Чистяков "Курс теории вероятностей"

  2. George Casella, Roger L.Berger "Statistical Inference"

детерминанты матриц не ищу

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

Ребята с «вышкой» всё время умничают, что в Data Science нужна «математика», но стоит копнуть глубже, оказывается, что это не математика, а вышмат.

Простите меня, но Вы сами понимаете, что вы сказали? Если возможно переформулируйте, пожалуйста, желательно с учетом какой-то элементарной хотя бы википедии, которая, может быть, скажет, что "вышмат" - это название курса (как правило слабого, и поверхностного) в техническом вузе и более ничего. А математика - это серьrзная наука в виде всей совокупности ее подразделов. Если лично вам какой-то раздел математики в работе не нужен, то хотелось бы, чтобы из этого не следовали неграмотные утверждения и определения на обложке вашей статьи и в вашем телеграм канале.

Никакие интегралы не считаю, детерминанты матриц не ищу, а нужные хитрые формулы и алгоритмы мне оперативнее просто загуглить.

Вы знаете, наверное, в дата сайенс есть своя специфика, которая больше использует определенные разделы математики такие как математическая статистика и теория вероятностей, а не те тривиальные примеры из первого курса вот этого самого так называемого "вышмата". Более того, тем, кому в вузе довелось слушать не "вышмат", а все-таки курсы с более интересными названиями, например, математическая статистика, понимают, что весь этот ваш датасайенс это обычный университетский курс мат. статистики и почти даже ничего более, просто с новыми "современными" названиями и без глубоких доказательств. Например, какая-нибудь ваша линейная регрессия это получение параметров по методу максимального правдоподобия - достаточно тривиальный и понятный метод, изучаемый в самом простом курсе правда не "вышмата", а математической статистики. Я специально взял простейший пример, чтобы не залезать в дебри, хотя, может быть, стоило бы написать статью на этот счет. Никакие курсы по датасайенсу не нужны, если вы нормально учились в более-менее математическом вузе. А, вообще, я просто о том, что если, например, я в чем-то некомпетентен и чего-то не понимаю, то это не означает, что мне стоит транслировать эту некомпетентность в массы, чтобы случайно не оказаться под воздействием эффекта  Даннинга — Крюгера.

Мне казалось, главная-то фишка GraphQL в гибкой настройке возвращаемых объектов, способ организации фильтров — далеко вторичен. Мобилка подтягивает только user {id, firstName}, десктоп — сразу еще и фамилию и вообще весь профиль да еще и всех френдов friends {id, firstName}. GraphQL — это очень удобный способ удовлетворить очень разных потребителей API.
Нет, конечно ребята не отказались от IQueryable. IQueryable — это по-прежнему единственный дешевый способ получить фильтрацию и пейджинг в HotChocolate из коробки (естественно, в предположении, что эта фильтрация и пейджинг должны в итоге уйти в базу), в остальных — нужно имплементировать фильтрацию самому и, действительно, в HotChocolate v.11 для этого появились точки расширения. Но IQueryable по-прежнему занимает и будет занимать свое место в их архитектуре. На самом деле они отказались (именно об этом говорится в приведенной вами ссылке) от старого АПИ фильтрации — это подробно разбирается здесь. И, разумеется, новое АПИ фильтрации прекрасно работает с IQueryable.

Но в остальном вы правы, GraphQL не влечет за собой рассмотренных утечек автоматически и не требует выдавать IQueryable наружу.
Нет, конечно ребята не отказались от IQueryable. IQueryable — это по-прежнему единственный дешевый способ получить фильтрацию и пейджинг в HotChocolate из коробки (естественно, в предположении, что эта фильтрация и пейджинг должны в итоге уйти в базу), в остальных — нужно имплементировать фильтрацию самому и, действительно, в HotChocolate v.11 для этого появились точки расширения. Но IQueryable по-прежнему занимает и будет занимать свое место в их архитектуре. На самом деле они отказались (именно об этом говорится в приведенной вами ссылке) от старого АПИ фильтрации — это подробно разбирается здесь. И, разумеется, новое АПИ фильтрации прекрасно работает с IQueryable.

Но в остальном вы правы, GraphQL не влечет за собой рассмотренных утечек автоматически и не требует выдавать IQueryable наружу.
По поводу archive_command не соглашусь. Во-первых, для скрипта это достаточно короткий и тривиальный функционал. Если что-то (а в данном случае это «что-то» — это, в основном, только потеря связи с сервером бекапов, так как падение sync — исчезающе редко, как мне кажется) отломается, то получим запись в логах postgres об ошибке архивирования. Во-вторых, действительно, один из подходов — это 1) archive_command только складывает wal-ы локально, а 2) какой-то процесс их подбирает и отправляет в безопасное место. Мы этот подход осознанно не используем, считая его гораздо менее надежным с точки зрения сохранения консистентности бекапа. Думаю очевидно, что описанный в статье подход «железобетонен» и это гарантируется средствами postgres — wal не ушли, значит, не будут удалены, wal ушли, значит они точно в безопасном месте лежат на диске. В предлагаемом же вами подходе — во второй стадии — достаточно широкое поле для ошибок, связанное с устройством и качеством этого самого процесса слежения за локальной папкой (если это свои скрипты — то нет ли в них ошибок и т.п.). Ну просто логически даже давайте посмотрим — если это скрипты — то они будут примерно такие же, как в archive_command — тогда зачем выделять вторую стадию. Если это какая-то программа типа rsync, то нужно быть уверенным, что она не отвалилась, что она работает именно как ожидаемо — то есть, удаляет здесь файл, когда убедится, что там он «synced to disk», что она синхронизирует файлы в правильном порядке — если имеется A1, А2, A3 — то желательно, чтобы файлы уходили в верном порядке, иначе при сбое может оказаться, что на сервере бекапов у вас уже есть A2 и A3, но нет A1, потому что какой-нибудь аналог rsync решил, что будет синкать, к примеру, по размеру, а не по времени сохранения. Готов согласиться, что все это можно реализовать, но это не бесплатно и уж точно не по той причине, какую вы указали — «прозрачность». Скорее это может быть связано с: А) Возможность нагрузкой на worker'ы postgres'а и, как следствие, impact на производительность самой базы (но мы после достаточно долгого использования этого подхода этого не наблюдаем) Б) Работой с альтернативными storages бекапов — например, по API и т.п., где уже действительно в одной строке archive_command команду сохранения будет выразить сложно или вовсе невозможно. Единственное, чего тут нет, но, возможно, было бы полезно добавить — это, действительно, мониторинг того, архивируются ли файлы в нужные промежутки — автоматически анализируя логи postgres или факт исчезновения wal-файлов.
А нельзя ли делать бота по poll-модели? Как-то не очень хочется делать callback url, который должен быть виден всем в интернете. В телеграме в этом смысле хорошо — можно веб хуком делать, а можно и просто делать запросы по таймеру на наличие новых сообщений.
RaisePropertyChanged — это не обработка.
В частности:
Например, в случае Replace не совершается переподписка на новый элемент, а, значит, при изменениях его свойств не будет рейзится событие об изменении зависимого свойства.
И обладает всем набором недостатков (глубоко не копал, так что поправьте, если ошибаюсь):
Не поддерживает цепочек свойств и зависимостей от элементов коллекций.
: ReactiveObject

Требует наследования от специального класса.

ObservableAsPropertyHelper _fullName

Требует оберток над полями.
read-only свойство использовать нельзя

read-only нельзя, а приватный сеттер можно. Это, конечно, не read-only, но наличие а) private setter б) возможности того, что «property changed» диссонанса не вызывает, а скорее даже наоборот — кажется вполне логичным. Проперти должны вести себя как поля? ОК, если проперти меняется, значит, его кто-то поменял, значит, должен быть сеттер. Но это так, пространные размышления. А на практике, согласитесь, не ограчение это вовсе :-) (уж в случае вью-моделей точно).
добавляется поле типа IDisposable

Ну уж :-) В жирной-то вью-модели добавление одного свойства — это усложнение? Особенно в канонической реализации MVVM по статьям MS, где view model — это вообще God Object. Но вообще-то можно это поле и не добавлять — хранить его нужно только в случае, если хочется в какой-то из моментов жизненного цикла view model трекинг остановить. Если не нужно — то и поля не нужно.
Например, хотелось бы, чтобы код можно было оставить в свойстве, а трекер только кидал уведомления об изменении.

Я бы не сказал, что подход совсем плохой. Думаю, он вполне заслуживает права на жизнь. Более того, некоторые конкуренты так и делают. Просто очевидных плюсов, достаточных для того, чтобы все переделать нет, а вот некоторые проблемы видны сразу. А именно, если есть сеттер, куда значение кладется, то совершенно забесплатно, можно получить следующие вещи:
1. Кеширование вычисленного значения. TotalCost = Orders.Sum(o => o.Price * o.Quantity) вообще-то имеет O(n) сложность вычисления.
2. Рейз события только когда значение поменялось, благодаря стандартному if (_property != value). А можно и всегда рейзить — если эту проверку не написать. В любом случае — слово за тем, кто написал сеттер, а не за трекером. Что, конечно, хорошо, так как без навязывания. Иногда проверка на новое значение не нужна, а иногда проверка очень даже нужна — когда зависимости настолько нетривиальны, что появляются циклы, когда A --> B, а B --> A через какие-нибудь сложные цепочки. И простой способ сделать так, чтобы «колебание затухло» — это не рейзить новых событий, если ничего не поменялось.

Если коллекция одна, то можно обойтись какой-нибудь коллекцией «NotifyingCollection where T: INPC»

Разве эту коллекцию не нужно реализовать также, как трекер? Чем подход проще, когда уже есть трекер?

где у коллекции бросается какое-нибудь событие при изменении любого элемента.

А дальше что с ним делать? Событие нестандартное (надеюсь, вы не собираетесь бросать какой-нибудь CollectionChanged с Reset'ом), биндинг его не поймет. Надо, значит, внутри вью-модели подписываться на него и обновлять вычислимое свойство. А если инстанс коллекции поменяли? :-) :-) Надо переподписаться на событие :-) :-) Ну это как-то тот же трекер и получается :-)
Что касается слабых ссылок, то, это, по моему, вообще из пушки по воробьям. Чтобы использовать слабые ссылки, нужна еще реализация «слабых подписок», где этот код возьмем? Тоже сами напишем? Или библиотекой сторонней воспользуемся? :-) Если сами, то чего уж там, давайте и этот код в студию :-).
Вы меня, конечно, извините, но код пока не очень даже на прототип тянет.
Мешает серия багов:
1. Нет отписок при изменениях в цепочке — внутреннего объекта, коллекции. Результат этого понятен: изменения в объектах, которые уже нашей цепочки не принадлежат, будут инициировать уведомления об изменении цепочки, что неверно.
2. В коллекции обрабатывается только добавление элемента. А как же остальные 4 действия — Remove, Move, Replace и Reset?

Если будете фиксить эти баги, учтите, пожалуйста, следующие моменты (в частности, потому, что интересно сколько еще времени займет эта работа) по п.2:
1. Проблема обработки Remove, Move, Replace и Reset не только проблема утечек. В некоторых случаях дело и в корректности вычислений тоже. Например, в случае Replace не совершается переподписка на новый элемент, а, значит, при изменениях его свойств не будет рейзится событие об изменении зависимого свойства.
2. Не забудьте реализовать отписку от уже ненужных элементов коллекции в случае Reset (когда OldValues = null).
Вы думаете, что незначительное увеличение cohesion окупает усложнение кода путём добавления нового проекта?

Использование KSO — это тоже добавление нового проекта :-)
Cohesion тут, конечно, почти не при чем. Как и написано в статье решается проблема сложности ручной поддержки нетривиальных зависимостей. KSO решает только одну проблему — простые одноуровневые зависимости. Если у вас только такие зависимости, то без особых проблем можно использовать как KSO, так и любой из конкурентов. Как и в предыдущем комментарии, хотелось бы увидеть код, который «научил» бы простым образом KSO работать с коллекциями. В частности, интересно сколько времени займет аккуратная реализация обработки каждого из типов событий INotifyCollectionChanged.
Сделать так, как вы пишете, разумеется, можно. Но на мой взгляд это достаточно трудоемко. Было бы интересно увидеть актуальный код от вас, который поддерживает, допустим, цепочку с коллекцией типа TotalCost = o.OrderProperties.Orders.Sum(o => o.Price * o.Quantity), а также оценку сколько по времени у вас заняла реализация всего этого.
Собственно, NotifyPropertyChangeWeaver описан в «Конкурентах», его возможности там рассмотрены. На мой взгляд, возможностей у него меньше, а трекер не менее прост в использовании. По поводу соотношения 95% и 5% — это, все же, определяется «жирностью» ViewModel и, в зависимости, от опыта, может варьироваться. Мне вот, например, в одно время, часто требовались вычислимые свойства «поверх» ObservableCollection, NotifyPropertyChangeWeaver мало мог в этом помочь.
Да, вы все верно написали. Наверное, вы правы по поводу необходимых уточнений в статье.
По поводу п.4 в разных примерах у меня по разному (и это конечно, огрехи при написании статьи) — где-то ссылка на трекер есть, где-то ее нет внутри класса. В первом случае, от подписок ничего не зависит, во втором — зависит. Замечу, что второй случай тоже безопасен. Если трекер не смог создать ни одной подписки на путь (например, когда в пути только readonly-поля, это тоже поддерживается), значит, и отслеживать никаких изменений ему не удастся. Значит, можно его собирать :-)
1

Information

Rating
Does not participate
Location
Ижевск, Удмуртия, Россия
Registered
Activity

Specialization

Chief Technology Officer (CTO)