Применение методов анализа формальных понятий для нахождения зависимости между анкетными показателями клиентов и фактом дефолта по кредиту
Алгоритм классификации по запросу. Анализ формальных понятий. Алгоритм ленивой классификации с помощью узорных структур. Модификация рандомизации алгоритма. Модификация с предварительным расчетом гипотез. Оценка возможности визуализации гипотез.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 04.08.2018 |
Размер файла | 578,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Содержание
1. Введение
2. Алгоритм классификации по запросу
2.1 Анализ формальных понятий
2.2 Алгоритм ленивой классификации с помощью узорных структур
2.3 Алгоритм классификации по запросу
2.4 Схема голосования
3. Эксперименты и результаты
3.1 Описание данных
3.2 Сравнение схем голосования
3.3 Модификация рандомизации алгоритма
3.4 Модификация с предварительным расчетом гипотез
3.5 Визуализация гипотез
3.6 Сравнение с другими методами
Заключение
Список литературы
Приложение
1.
1. Введение
Каждый день клиенты банка заполняют тысячи анкет на получение кредита в банке. Часть заявок банк одобряет, а часть - отказывает. Логика принятия решения в большей степени основана на скоринговой модели оценки будущей платёжеспособности заявителя.
Многие методы машинного обучения, например, глубокие нейронные сети или SVM применимы для задачи предсказания факта дефолта в задаче кредитного скоринга. Однако, решения, полученные с помощью этих методов, сложно интерпретировать. Интерпретация результатов в кредитном скоринге важна, так как в банке окончательное решение о выдаче кредита принимается экспертом на основании множества факторов, включая оценку, полученную с помощью классификатора. Методы АФП позволяют строить классификаторы, оценки которых хорошо интерпретируемы, так как они позволяют выявить группы объектов обучающей выборки, «похожих» на тестовый объект.
Целью данной работы является применение методов анализа формальных понятий (АФП) для нахождения зависимости между анкетными показателями клиентов и фактом дефолта по кредиту.
2. Алгоритм классификации по запросу
2.1 Анализ формальных понятий
В данном разделе будут рассмотрены понятия из теории формальных понятий, используемых в работе.
Пусть есть некоторое множество объектов, - нижняя полурешётка, а есть отображение, ставящее в соответствие каждому объекту из его описание из множества .
Пусть множество порождает полную подполурешетку полурешетки , то есть произвольное подмножество множества имеет наибольшую нижнюю грань (инфимум) в полурешетке , а есть множество этих инфимумов. Тогда тройка, состоящая из множества объектов, их описания с заданной операцией пересечения и отображения называется узорной структурой. Элементы называются узорами. Порядок на узорах задается обычным образом через операцию инфимума:
и называется порядком поглощения.
Условие существования полной подполурешетки, порождаемой множеством , выполняется автоматически, например, в следующих двух ситуациях: когда полурешетка полна и когда множество конечно.
Для узорной структуры введем следующие операторы для и :
.
Эти операторы задают соответствие Галуа между множествами и
Пары , удовлетворяющие условиям
,
называются узорными понятиями структуры . Множество называется объемом узорной структуры, множество называется узорным содержанием.
Модель обучения, основанная на стандартном объектно-признаковом представлении в виде формального контекста, естественно расширяется для узорных структур.
Пусть имеется множество положительных примеров (положительный контекст по отношению к целевому признаку) и множество отрицательных примеров (отрицательный контекст по отношению к целевому признаку), причем выполняется условие . Объекты из множества называются недоопределенными примерами (то есть это объекты для которых неизвестно значение целевой переменной). Узор называется ослабленной посылкой уровня (-слабой посылкой) тогда и только тогда, когда:
Узор называется ослабленной гипотезой уровня (-слабой гипотезой) тогда и только тогда, когда:
В задаче кредитного скоринга данные представлены, как правило, в виде объектно-признаковой табличной структуры, поэтому для моделирования будут использоваться узорные структуры, заданные на числовых интервалах. В этом случае для двух интервалов и оператор определяется следующим образом:
2.2 Алгоритм ленивой классификации с помощью узорных структур
Пусть, имеется обучающая выборка (положительные и отрицательные примеры) и множество недоопределенных примеров. Пусть также существует узорная структура , задающая описание объектов. Тогда можно вычислить замыкание описание тестового объекта с описанием каждого объекта из множества . Если для некоторого объекта замыкание содержит целевой признак, то относится к положительному классу, в противном случае, относится к отрицательному классу. Описание данной процедуры выглядит следующим образом:
1. Для каждого объекта вычислить , то есть выбрать все объекты из , описание которых содержит .
2. Если для некоторого объекта все объекты из относятся к положительному классу, то отнести объект положительному классу, в противном случае - к отрицательному.
Таким образом метод ленивой классификации сводится к вычислению множества объектов и проверки классов, к которым принадлежат объекты из данного множества. Алгоритм ленивой классификации легко распараллелить, если разбить обучающую выборку на непересекающихся подвыборок , где - число ядер процессора или число машин в кластере.
2.3 Алгоритм классификации по запросу
В задаче кредитного скоринга имеют дело, как правило, с числовыми табличными данными. Каждый признак может иметь произвольное распределение и принимать значение из очень широкого диапазона. В то же время среди признаков могут присутствовать категориальные, к которым применено dummy-кодирование. Если признаков достаточно много (больше 30), то описание будет слишком специфичным для любого , и, как следствие, только объекты и будут содержать это описание. Это происходит из-за того, что количество уникальных значений числовых признаков, особенно нецелых, сопоставимо с количеством объектов в массиве данных. Слишком «специфичные» описания, как правило, не фальсифицируются, то есть не содержат объектов противоположного класса. Это приводит к тому, что схема голосования, используемая в «ленивой классификации», не работает. Следовательно, имеет смысл модифицировать алгоритм ленивой классификации и искать узорные понятия с большим объемом и менее специфичным содержанием. При этом важно соблюсти баланс, так как узорное понятие вместе с чересчур «общим» описанием содержит также большую часть объектов из всего контекста , что также делают схему голосования бесполезной.
Чтобы увеличить объем узорных понятий, необходимо рассматривать пересечение описания тестового объекта с более чем одним объектом из обучающей выборки. Это число объектов из обучающей выборки является гиперпараметром алгоритма, и чтобы подобрать его оптимальное значение, необходим поиск по сетке. Параметр можно задавать, как долю обучающей выборки или как абсолютное значение числа объектов. С ростом значения гиперпараметра описание становится более «обобщенным», а значит, чаще фальсифицируется объектами из контекста противоположного класса.
Строго говоря, чтобы воспроизвести ленивый подход к классификации с использованием гиперпараметра «размер подвыборки», нужно было бы рассмотреть все возможные комбинации размера подвыборки объектов из положительного (отрицательного) контекста. Однако, это не применимо в случае больших наборов данных. Например, имея 10 000 объектов в положительном контексте и имеющих размер подвыборки, равный только двум объектам, будет производиться почти 50 миллионов комбинаций для пересечения с тестовым объектом. Поэтому стоит произвольно извлекать выбранное количество объектов из положительного (отрицательного) контекста в качестве кандидатов для пересечения с тестовым объектом. Количество раз (число итераций), которое мы произвольно извлекаем из контекста, является вторым гиперпараметром алгоритма, который также настраивается посредством поиска по сетке. Чем выше значение параметра «число итераций», тем выше будет качество классификации. Однако очевидным штрафом за увеличение значения этого параметра является время и ресурсы, необходимые для вычисления пересечений описаний объектов.
Как уже было упомянуто выше, чем больше размер подвыборки, тем больше вероятность того, что множество содержит объект противоположного класса. Чтобы решить эту проблему, добавляется третий гиперпараметр - уровень ослабленных посылок . Если доля объектов из положительного (отрицательного) контекста, которая фальсифицирует -слабую посылку , больше, чем гиперпараметр этого контекста, то описание будет считаться фальсифицированным, в противном случае описание будет -слабым и, впоследствии, будет использовано для классификации тестового объекта.
В полной мере идея алгоритма состоит в том, чтобы проверить, на группы объектов из какого контекста (положительного или отрицательного) больше похож тестовый объект. Алгоритм использует три гиперпараметра: размер подвыборки, число итераций и -порог.
Первый параметр задается как доля наблюдений в контексте или в виде абсолютного значения. На каждом шаге извлекается подвыборка, затем описания объектов в подвыборке пересекаются с описанием тестового объекта.
Число итераций является вторым параметром алгоритма, который также настраивается посредством поиска по сетке. Если процент объектов из положительного (отрицательного) контекста, который фальсифицирует описание , больше, чем -порог этого контекста чем предпосылка будет считаться фальсифицированной, в противном случае предпосылка будет -слабой и, впоследствии, использована в классификации тестового объекта.
Эти шаги выполняются для каждого тестового объекта отдельно для положительного и отрицательного контекстов, создавая набор положительных и отрицательных -слабых посылок.
2.4 Схема голосования
Окончательная классификация тестового объекта основана на схеме голосования среди -слабых посылок. В большинстве случаев схема голосования F является отображением
,
где - тестовый объект с неизвестным классом, - положительный предпосылки, - отрицательные предпосылки, а - число положительных и отрицательных предпосылок соответственно, использующихся для классификации тестового объекта . Другими словами, это решающее правило, которое принимает на вход тестовый объект и предпосылки и вычисляет по ним значение целевой переменной. При этом допускается оставить значение целевой переменной пустым, что означает «отказ» от классификации. При проверке качества работы модели для объектов, которым «отказано» в классификации, можно использовать наивную модель. В случае задачи кредитного скоринга имеет смысл использовать средний уровень дефолтов в обучающей выборке.
Схема голосования основана на весовой функции , агрегирующим операторе и операторе сравнения :
Конечным результатом для тестового объекта является ранжирующий скоринговый балл, характеризующий оценку вероятности дефолта в задаче кредитного скоринга. Данная оценка может быть использована для анализа порогов отсечения и вычисления метрик качества модели таких, как ROC-AUC.
Далее будут рассмотрены различные варианты модификаций алгоритма классификации по запросу, несколько вариантов агрегирующих операторов и операторов сравнения и приведены результаты экспериментов.
3 Эксперименты и результаты
3.1 Описание данных
Для исследования описанного подхода и его модификаций были взяты данные с Kaggle-соревнования «Give Me Some Credit». Весь исходный массив данных содержит 150 000 объектов и 11 признаков, включая целевой. Значение целевого признака определено как «факт наличия просрочки более 90 дней по кредиту в течение первого года после выдачи». Для тестирования и сравнения между собой алгоритмов классификации было взято по 1000 положительных и отрицательных примеров в качестве обучающей выборки, а также 300 объектов в качестве тестовой. Описание признаков приведено в следующей таблице:
Таблица 1. Результаты классификации. Значения коэффициентов Джини.
Название признака |
Описание |
Тип |
|
SeriousDlqin2yrs |
Факт наличия просрочки более 90 дней по кредиту в течение первого года после выдачи |
1/0 |
|
age |
Возраст в полных годах. |
целый |
|
RevolvingUtilizationOfUnsecuredLines |
Утилизаций всех кредитных карт |
% |
|
NumberOfTime30-59DaysPastDueNotWorse |
Число просрочек 30-59 дней (но не более) за последние 2 года. |
целый |
|
DebtRatio |
Ежемесячные расходы на проживание, делённые на месячный доход |
% |
|
MonthlyIncome |
Месячный доход |
веществ. |
|
NumberOfOpenCreditLinesAndLoans |
Число открытых кредитов |
целый |
|
NumberOfTimes90DaysLate |
Число просрочек более 90 дней |
целый |
|
NumberRealEstateLoansOrLines |
Число взятых ипотечных кредитов. |
целый |
|
NumberOfTime60-89DaysPastDueNotWorse |
Число просрочек 60-89 дней (но не более) за последние 2 года. |
целый |
|
NumberOfDependents |
Число родственников, находящихся на иждивении |
целый |
Был произведён перебор по сетке параметров в несколько этапов - от меньшего количества итераций к большему. Качество модели во всех случаях измерялась с помощью метрики «коэффициент Gini», который показывает, на сколько процентов значение метрики ROC-AUC лучше, чем у случайной модели, и связан с ROC-AUC формулой
_.
3.2 Сравнение схем голосования
Как было упомянуто выше, схема голосования основана на весовой функции , агрегирующим операторе и операторе сравнения :
В статье [3] в экспериментах используются следующие операторы:
В данном подходе каждая -слабая посылка добавляет один «голос» за свой класс, а оценка принадлежности к классу определяется, как разность между суммарным числом голосов за каждый класс. По мимо данного подхода были также исследованы другие варианты весовой функции, оператора сравнения, а также другое:
· Весовой функции:
·
· Оператора сравнения: ,
· Определения положительной -слабой посылки:
Здесь весовая функция задана так, что каждая -слабая посылка добавляет тестовому объекту столько голосов за свой класс, сколько объектов данного класса содержится в замыкании посылки. Оператор сравнения определяет долю голосов, отданных за свой класс. Посылка считается ослабленной посылкой уровня , если отношение числа объектов противоположного класса к числу объектов своего класса, нормированные на общее число объектов каждого класса в контексте, меньше заданного порога .
В таблице 2 представлен пример результатов классификации (метрика - коэффициент Джини) при запуске по сетке параметров. Размер подвыборки менялся от 1 до 10, порог менялся от 0.01 до 0.99, число итераций всегда было равным 1000. Объекты, у которых число положительных и отрицательных голосов оказалось равным нулю, автоматически классифицировались как отрицательные.
В таблице 3 представлены результаты поиска по той же сетке параметров, однако в этом случае использовалось альтернативное определение -слабой посылки, данное выше.
Таблица 2. Результаты классификации. Значения коэффициентов Джини.
Число итераций |
Размер подвыборки |
||||||
1000 |
0.01 |
1 |
50.75 |
50.55 |
18.43 |
20.02 |
|
1000 |
0.01 |
2 |
58.32 |
56.08 |
56.16 |
57.39 |
|
1000 |
0.01 |
3 |
59.64 |
58.34 |
59.39 |
59.58 |
|
1000 |
0.01 |
4 |
57.43 |
59.38 |
58.06 |
60.22 |
|
1000 |
0.01 |
5 |
57.28 |
55.24 |
58.52 |
56.31 |
|
1000 |
0.01 |
6 |
58.33 |
49.3 |
59.76 |
49.69 |
|
1000 |
0.01 |
7 |
53.23 |
43.63 |
54.93 |
43.98 |
|
1000 |
0.01 |
8 |
41.1 |
39.7 |
41.21 |
39.7 |
|
1000 |
0.01 |
9 |
27.5 |
27.51 |
27.65 |
27.51 |
|
1000 |
0.01 |
10 |
0.4 |
0 |
0.4 |
0 |
|
1000 |
0.02 |
1 |
40.85 |
40.62 |
-1.47 |
-2.43 |
|
1000 |
0.02 |
2 |
55.88 |
54.48 |
49.93 |
53.14 |
|
1000 |
0.02 |
3 |
58.71 |
56.12 |
57.84 |
57.4 |
|
1000 |
0.02 |
4 |
57.56 |
56.61 |
58.98 |
57.84 |
|
1000 |
0.02 |
5 |
56.3 |
56.52 |
58.12 |
58.03 |
|
1000 |
0.02 |
6 |
57.81 |
56.63 |
58.78 |
57.06 |
|
1000 |
0.02 |
7 |
56.84 |
42.56 |
57.79 |
42.56 |
|
1000 |
0.02 |
8 |
56.64 |
38.66 |
57.47 |
39.43 |
|
1000 |
0.02 |
9 |
44.4 |
37.02 |
44.71 |
37.02 |
|
1000 |
0.02 |
10 |
26.09 |
0 |
26.66 |
0 |
|
… |
… |
… |
… |
… |
… |
… |
|
1000 |
0.99 |
1 |
0 |
0 |
37.51 |
45.75 |
|
1000 |
0.99 |
2 |
0 |
0 |
43.06 |
53.57 |
|
1000 |
0.99 |
3 |
0 |
0 |
46.22 |
57.26 |
|
1000 |
0.99 |
4 |
0 |
0 |
48.36 |
58.19 |
|
1000 |
0.99 |
5 |
0 |
0 |
49.65 |
58.4 |
|
1000 |
0.99 |
6 |
0 |
0 |
49.81 |
58.68 |
|
1000 |
0.99 |
7 |
0 |
0 |
51.84 |
59.44 |
|
1000 |
0.99 |
8 |
0 |
0 |
53.04 |
59.39 |
|
1000 |
0.99 |
9 |
0 |
0 |
51.57 |
57.75 |
|
1000 |
0.99 |
10 |
0 |
0 |
55.47 |
59.87 |
Таблица 3. Результаты классификации. Значения коэффициентов Джини.
Число итераций |
Размер подвыборки |
||||||
1000 |
0.01 |
1 |
61.53 |
59.95 |
58.45 |
59.34 |
|
1000 |
0.01 |
2 |
62.13 |
62.3 |
61.42 |
62.61 |
|
1000 |
0.01 |
3 |
62.27 |
60.86 |
61.56 |
60.63 |
|
1000 |
0.01 |
4 |
53.69 |
48.1 |
53.44 |
47.95 |
|
1000 |
0.01 |
5 |
29.07 |
29.1 |
28.93 |
29.1 |
|
1000 |
0.01 |
6 |
1.6 |
0 |
1.6 |
0 |
|
1000 |
0.01 |
7 |
0 |
0 |
0 |
0 |
|
1000 |
0.01 |
8 |
0 |
0 |
0 |
0 |
|
1000 |
0.01 |
9 |
0 |
0 |
0 |
0 |
|
1000 |
0.01 |
10 |
0 |
0 |
0 |
0 |
|
1000 |
0.02 |
1 |
61.33 |
59.83 |
58.38 |
59.28 |
|
1000 |
0.02 |
2 |
61.87 |
61.26 |
60.71 |
61.56 |
|
1000 |
0.02 |
3 |
61.43 |
57.94 |
61.04 |
58.11 |
|
1000 |
0.02 |
4 |
55.76 |
49.85 |
55.44 |
48.92 |
|
1000 |
0.02 |
5 |
38.05 |
37.71 |
37.6 |
37.71 |
|
1000 |
0.02 |
6 |
13.57 |
13.57 |
13.57 |
13.57 |
|
1000 |
0.02 |
7 |
3.6 |
0 |
3.61 |
0 |
|
1000 |
0.02 |
8 |
0 |
0 |
0 |
0 |
|
1000 |
0.02 |
9 |
0 |
0 |
0 |
0 |
|
1000 |
0.02 |
10 |
0 |
0 |
0 |
0 |
|
… |
… |
… |
… |
… |
… |
… |
|
1000 |
0.99 |
1 |
59.42 |
59.28 |
6.72 |
18.04 |
|
1000 |
0.99 |
2 |
58.72 |
58.69 |
10.09 |
32.92 |
|
1000 |
0.99 |
3 |
58.2 |
58.17 |
15.25 |
38.11 |
|
1000 |
0.99 |
4 |
56.01 |
55.85 |
19 |
37.76 |
|
1000 |
0.99 |
5 |
56.49 |
56.46 |
19.64 |
37.51 |
|
1000 |
0.99 |
6 |
53.01 |
52.74 |
17.11 |
33.78 |
|
1000 |
0.99 |
7 |
53.54 |
53.46 |
20.48 |
37.03 |
|
1000 |
0.99 |
8 |
51.89 |
51.85 |
20.01 |
35.19 |
|
1000 |
0.99 |
9 |
47.96 |
47.85 |
17.32 |
30.87 |
|
1000 |
0.99 |
10 |
51.85 |
51.79 |
21.21 |
34.91 |
В названии полей таблиц индексы и определяют, какая весовая функция использовалась при классификации:
индексы diff и ratio определяют два варианта операторов сравнения
diff:
ratio:
Анализ таблиц показывает, что если размер подвыборки слишком большой, а порог низкий, то описания получаются слишком «общими» и фальсифицируются чаще, поэтому качество классификации падает вплоть до 0 (значение коэффициента Джини, равное нулю, соответствует случайному классификатору). В то же время если порог слишком высокий, то посылки не будут фальсифицироваться никогда, и в случае простейшей схемы голосования каждый тестовый объект получит равно число голосов, что также приведёт к нулевому значению коэффициента Джини. Лучший результат достигнут при применении альтернативного определения слабой посылки оператора сравнения, хотя оператор diff работает лучше в большинстве случаев при одинаковых гиперпараметрах.
3.3 Модификация рандомизации алгоритма
В данном разделе рассматривается альтернативный вариант генерации -слабых посылок, которые используются в схемах голосования, описанных в предыдущем разделе.
В классическом варианте алгоритма классификации по запросу присутствует три гиперпараметра: число итераций, -порог и размер подвыборки, и на каждой итерации из положительного (или отрицательного) контекста извлекается подвыборка фиксированного размера . При этом от размера подвыборки зависит, насколько «общим» получится описание и будет ли посылка ослабленной или нет. Таким образом на каждой итерации алгоритма строятся классификаторы, обладающие некоторой фиксированной мощностью, а значит их эффективность может быть выше для одних тестовых объектов и выше для других.
Для решения этой проблемы предлагается варьировать параметр размер подвыборки во время работы алгоритма, и на каждой итерации извлекать из контекста выборки разного размера. В данной работе было рассмотрено два способа задания размера подвыборки на каждой итерации:
1. Случайный выбор числа из равномерного распределения от до , где - размер подвыборки.
2. Выбор числа от до с вероятностью, пропорциональной числу сочетаний .
Стоит отметить, что второй способ эквивалентен тому, как если бы мы извлекали подвыборки равномерно из множества всех подмножеств контекста. Таким образом второй способ обеспечивает сходимость к классическому способу классификации через генерацию узорных понятий, так как рассматривает описания всех возможных комбинаций объектов (при большом числе итераций). Тем не менее, уже при небольшом размере обучающей выборки сходимость не будет достигнута, так как число всех подмножеств будет слишком велико.
На практике при больших значениях размера подвыборки описание окажется слишком «общим» и доля объектов противоположного класса в множестве превысит заданный порог на каждой итерации. То есть для любого значения порога имеет смысл извлекать подвыборки, размер которых не превышает некоторое максимальное значение .
Таким образом, описанные выше два способа задания размера подвыборки на каждой итерации можно немного модифицировать следующим образом:
1. Случайный выбор числа из равномерного распределения от до , где - вычисленное экспериментально число, зависящее от используемого массива данных.
3. Выбор числа от до с вероятностью, пропорциональной числу сочетаний .
Заметим, что во втором способе вероятности извлечь подвыборку размера и соотносятся следующим образом:
Это означает, что в процессе работы алгоритма выборка размера будет извлекаться приблизительно в раз чаще, чем выборка размера , что при малых значениях сопоставимо с размером контекста. Из этого следует, что при большом объёме массива данных и фиксированном числе итераций выборки малых размеров не будут использоваться в классификации. При этом наиболее вероятный размер подвыборки будет равным значению .
В результате экспериментов с анализируемым массивом данных было установлено, что в качестве оптимального максимального размера подвыборки имеет смысл взять значение В таблице 4 представлен фрагмент результатов классификации (метрика - коэффициент Джини) при запуске по сетке параметров. Размер подвыборки случайно выбирался из равномерного распределения, то есть использовался первый способ рандомизации, порог менялся от 0.01 до 0.99, число итераций всегда было равным 1000. Объекты, у которых число положительных и отрицательных голосов оказалось равным нулю, автоматически классифицировались как отрицательные.В таблице 5 представлен фрагмент с результатами классификации при поиске по аналогичной сетке параметров, но со вторым способом рандомизации.
Таблица 4. Результаты классификации. Значения коэффициентов Джини.
Число итераций |
||||||
1000 |
0.01 |
57.566 |
56.394 |
18.43 |
20.02 |
|
1000 |
0.02 |
57.5 |
55.943 |
56.16 |
57.39 |
|
1000 |
0.03 |
58.278 |
56.466 |
59.39 |
59.58 |
|
1000 |
0.04 |
58.276 |
56.492 |
58.06 |
60.22 |
|
1000 |
0.05 |
58.235 |
56.23 |
58.52 |
56.31 |
|
1000 |
0.06 |
58.381 |
56.349 |
59.76 |
49.69 |
|
1000 |
0.07 |
58.612 |
56.46 |
54.93 |
43.98 |
|
1000 |
0.08 |
58.969 |
56.483 |
41.21 |
39.7 |
|
1000 |
0.09 |
59.01 |
56.631 |
27.65 |
27.51 |
|
1000 |
0.1 |
59.245 |
56.631 |
0.4 |
0 |
|
1000 |
0.11 |
59.868 |
57.051 |
-1.47 |
-2.43 |
|
1000 |
0.12 |
59.739 |
56.732 |
49.93 |
53.14 |
|
1000 |
0.13 |
60.028 |
57.233 |
57.84 |
57.4 |
|
1000 |
0.14 |
60.15 |
56.953 |
58.98 |
57.84 |
|
1000 |
0.15 |
60.345 |
57.661 |
58.12 |
58.03 |
|
1000 |
0.16 |
60.301 |
57.366 |
58.78 |
57.06 |
|
1000 |
0.17 |
60.244 |
57.034 |
57.79 |
42.56 |
|
1000 |
0.18 |
60.627 |
57.538 |
57.47 |
39.43 |
|
1000 |
0.19 |
60.576 |
57.42 |
44.71 |
37.02 |
|
1000 |
0.2 |
60.563 |
57.461 |
26.66 |
0 |
|
… |
… |
… |
… |
… |
… |
|
1000 |
0.9 |
1.912 |
1.917 |
22.255 |
27.671 |
|
1000 |
0.91 |
1.622 |
1.622 |
20.189 |
26.082 |
|
1000 |
0.92 |
0.735 |
0.735 |
18.093 |
23.911 |
|
1000 |
0.93 |
0.6 |
0.6 |
16.65 |
22.915 |
|
1000 |
0.94 |
0.281 |
0.281 |
14.442 |
20.731 |
|
1000 |
0.95 |
0.16 |
0.16 |
11.649 |
17.574 |
|
1000 |
0.96 |
0 |
0 |
8.903 |
14.939 |
|
1000 |
0.97 |
0 |
0 |
7.329 |
13.535 |
|
1000 |
0.98 |
0 |
0 |
4.79 |
10.949 |
|
1000 |
0.99 |
0 |
0 |
4.036 |
9.896 |
Таблица 5. Результаты классификации. Значения коэффициентов Джини.
Число итераций |
||||||
1000 |
0.01 |
50.47 |
50.46 |
18.93 |
20.18 |
|
1000 |
0.02 |
58.19 |
56.25 |
56.57 |
57.32 |
|
1000 |
0.03 |
59.35 |
58.61 |
58.99 |
59.79 |
|
1000 |
0.04 |
57.4 |
59.26 |
57.95 |
59.88 |
|
1000 |
0.05 |
57.46 |
55.01 |
58.61 |
56.13 |
|
1000 |
0.06 |
58.45 |
49.68 |
59.88 |
49.83 |
|
1000 |
0.07 |
53.24 |
43.82 |
54.63 |
43.8 |
|
1000 |
0.08 |
41.18 |
39.29 |
41.09 |
39.87 |
|
1000 |
0.09 |
26.98 |
27.21 |
27.86 |
27.62 |
|
1000 |
0.1 |
41.1 |
40.15 |
-1.53 |
-2.68 |
|
1000 |
0.11 |
55.56 |
54.56 |
50.12 |
52.83 |
|
1000 |
0.12 |
58.67 |
56.01 |
57.61 |
57.46 |
|
1000 |
0.13 |
57.38 |
56.69 |
58.76 |
57.13 |
|
1000 |
0.14 |
55.99 |
56.12 |
58.34 |
58.34 |
|
1000 |
0.15 |
57.61 |
56.65 |
58.75 |
56.86 |
|
1000 |
0.16 |
56.79 |
42.62 |
57.99 |
42.45 |
|
1000 |
0.17 |
56.58 |
38.76 |
57.11 |
39.39 |
|
1000 |
0.18 |
44.63 |
36.86 |
45.04 |
37.27 |
|
… |
… |
… |
… |
… |
… |
|
1000 |
0.9 |
0 |
0 |
37.51 |
45.67 |
|
1000 |
0.91 |
0 |
0 |
43.36 |
53.82 |
|
1000 |
0.92 |
0 |
0 |
46.49 |
57.14 |
|
1000 |
0.93 |
0 |
0 |
49.06 |
58.13 |
|
1000 |
0.94 |
0 |
0 |
49.59 |
58.41 |
|
1000 |
0.95 |
0 |
0 |
50.23 |
59.04 |
|
1000 |
0.96 |
0 |
0 |
52.9 |
59.31 |
|
1000 |
0.97 |
0 |
0 |
53.16 |
59.46 |
|
1000 |
0.98 |
0 |
0 |
51.2 |
57.49 |
|
1000 |
0.99 |
0 |
0 |
55.47 |
59.87 |
Из результатов расчёта можно увидеть, что первый способ рандомизации увеличивает качество в одних случаях, но уменьшает в других. Из этого можно сделать вывод о том, что существует некоторое оптимальное значение размера подвыборки, обеспечивающее наилучшее качество модели при фиксированных -пороге и числе итераций. Качество классификации при втором способе сопоставимо с подходом, рассмотренном ранее, так как в большинстве итераций размер подвыборки был равен максимальному значению .
3.4 Модификация с предварительным расчётом гипотез
Как упоминалось в предыдущих разделах, одним из подводных камней алгоритма является сложность в оптимальном подборе гиперпараметров, так как описание может оказаться слишком общим на каждой итерации. Стоит заметить, что для любого тестового объекта , описаний и выполняется условие:
,
то есть описание является более «общим», чем описание , а следовательно, если не является -слабой гипотезой, то и не будет -слабой посылкой. В связи с этим появляется идея вычислять описание заранее, то есть независимо от недоопределенных тестовых объектов.
Для реализации идеи алгоритма предварительного расчёта гипотез на первом этапе следует избавиться от гиперпараметра число итераций, так как тестовый объект не будет участвовать в процессе. Далее следует зафиксировать размер подвыборки, извлекаемой из контекста и искать -слабые гипотезы заданного порога. Останавливать поиск гипотез имеет смысл тогда, когда их сгенерировано достаточное количество. Это число будет новым гиперпараметром. При этом стоит заранее проверить (эмпирически), что в массиве данных существует хотя бы одна -слабая гипотеза. Если эта проверка не проходит, то это может означать неудачный выбор гиперпараметров алгоритма, в результате чего описания получаются слишком общими. В таком случае имеет смысл повысить порог или уменьшить размер подвыборки.
На втором этапе можно приступить к непосредственной классификации тестового объекта, а именно для каждой гипотезы необходимо вычислить описание и проверить, является ли оно -слабой посылкой, то есть проверить выполнение условия:
после чего воспользоваться схемой голосования.
С одной стороны, алгоритму требуется больше времени, чтобы генерировать устойчивые -слабые положительные и отрицательные посылки. С другой стороны, особенность данной модификации заключается в том, что непосредственная классификация тестового объекта занимает в меньше времени, где - время вычисления операции пересечения для двух объектов.
Результат применения такого подхода представлен в таблице 6 для 500 заранее найденных положительных и отрицательных гипотез. После пересечения с описаниями тестовых объектов агрегирование проводилось с помощью двух вариантов оператора сравнения:
diff:
ratio:
Таблица 6. Результаты классификации. Значения коэффициентов Джини.
Число гипотез |
Размер подвыборки (для построения гипотезы) |
Gini (diff), % |
Gini (ratio), % |
||
500 |
0.001 |
1 |
65.9123 |
64.7316 |
|
2 |
67.0033 |
66.8254 |
|||
3 |
67.4244 |
68.0503 |
|||
0.002 |
1 |
63.9438 |
63.0415 |
||
2 |
66.7139 |
65.9735 |
|||
3 |
66.8916 |
67.3364 |
|||
0.003 |
1 |
63.2586 |
62.4976 |
||
2 |
66.5897 |
65.4303 |
|||
3 |
66.4087 |
66.761 |
|||
0.004 |
1 |
62.4069 |
61.7895 |
||
2 |
66.3919 |
64.8438 |
|||
3 |
66.3178 |
66.1725 |
|||
0.005 |
3 |
66.1363 |
65.8624 |
||
4 |
66.3276 |
66.8342 |
|||
5 |
67.3237 |
66.8193 |
|||
0.006 |
3 |
65.9055 |
65.3423 |
||
4 |
65.7168 |
66.3137 |
|||
5 |
66.9681 |
66.7852 |
Из результатов, представленных в таблице, можно сделать вывод, что оператор diff работает лучше в большинстве случаев, однако, самое высокое значение метрики качества было получено при использовании оператора ratio. Данные результаты можно сравнить с классическим подходом, описанным вначале, где вместо заранее рассчитанных гипотез используется такое же число итераций. При этом однозначно можно сказать, что качество классификации при использовании данной модификации оказывается выше.
3.5 Визуализация гипотез
Описания, которые генерируются в результате работы алгоритма, представляют собой набор числовых интервалов. Если размерность пространства признаков равна , то каждая -слабая посылка или гипотеза может быть представлена в виде гиперкуба в пространстве размерности d. Несмотря на то, что размерность признакового пространства, как правило, больше трех, есть возможность визуализировать гипотезы, если взять проекцию гиперкуба на пространство размерности два или три. Например, можно взять только те интервалы, которые соответствуют наиболее значимым признакам.
На изображениях ниже показаны проекции заранее сгенерированных -слабых гипотез на пространство двух признаков: Age и RevolvingUtilizationOfUnsecuredLines.
запрос алгоритм визуализация гипотеза
Рисунок 1. Проекция гипотез на двумерное подпространство.
Рисунок 2. Проекция гипотез на двумерное подпространство.
Рисунок 3. Проекция гипотез на двумерное подпространство.
Рисунок 4. Проекция гипотез на двумерное подпространство.
На представленных изображениях проекции положительных гипотез изображены красным цветом, отрицательных - синим. Чем больше гипотез изображается на одном графике, тем более отчётливой становится граница между «хорошими» и «плохими» заёмщиками. Тестовый объект, попавший в красную или синюю зону на графике, будет классифицирован соответствующим образом. Такая возможность визуализации в первую очередь отражает интерпретируемость построенной модели. График, на котором построены 1000 положительных и отрицательных также помимо этого отражает скрытую структуру данных, а именно указывает на некоторое количество объектов, у которых утилизация кредитной карты превысила значение 1. Это может указать на ошибки в данных.
На изображениях ниже показаны проекции гипотез на пространство признаков NumberOfTime30-59DaysPastDueNotWorse и DebtRatio.
Рисунок 5. Проекция гипотез на двумерное подпространство.
Рисунок 6. Проекция гипотез на двумерное подпространство.
В данном случае видно, что признак NumberOfTime30-59DaysPastDueNotWorse принимает только целочисленные значения. Стоит отметить, что в случае категориальных признаков и признаков, принимающих целочисленные значения, некоторые гипотезы не удастся визуализировать, так как в этом случае левая и правая границы интервалов с большой вероятностью будут равны. Тем не менее, возможность визуализации гипотез в первую очередь в значительной мере улучшает интерпретируемость построенной модели.
3.6 Сравнение с другими методами
Для оценки качества метода классификации было произведено сравнение с классическими методами машинного обучения: логистическая регрессия и случайный лес.
В таблице 7 представлены лучшие результаты (в смысле критерия Джини) по каждому методу.
Таблица 7. Сравнение методов классификации
Gini_best |
||
Логистическая регрессия |
0.397254 |
|
Случайный лес |
0.649409 |
|
АФП (преподсчёт предпосылок) |
0.680503 |
Из результатов следует, что алгоритм классификации по запросу, основанный на методах АФП сопоставим по качеству со случайным лесом и при этом также является хорошо интерпретируемым методом.
Для оценки устойчивости алгоритма была произведена классификация тестовой выборки (приблизительно тестовых объектов), предлагаемой на соревновании Kaggle. Для обучения использовалась вся доступная выборка, и использовалась модификация алгоритма с предварительным расчётом гипотез, причём использовались все доступные для соревнований данные. В результате было получено значение коэффициента Джини, равное , что позволяет сделать вывод о высокой устойчивости данного классификатора.
Стоит отметить, что в данном соревновании коэффициент Джини лучшего результата составил 0.73 и был получен с помощью градиентного бустинга Таким образом алгоритм, рассмотренный в данной работе алгоритм несущественно уступает по качеству градиентному бустингу, однако, является интерпретируемым.
Заключение
В данной работе был рассмотрен алгоритм классификации по запросу с помощью узорных структур в применении к задаче кредитного скоринга. Также были рассмотрены несколько модификаций алгоритма, касающиеся способов построения и агрегации слабых классификаторов, и проведено их сравнение между собой. Каждый рассмотренный алгоритм был реализован на языке Python и распараллелен.
В результате была показана применимость методов анализа формальных понятий к решению задачи кредитного скоринга. Также были проанализированы и разработаны оптимальные стратегии подбора гиперпараметров и генерации гипотез, что может быть легко использовано в других прикладных задачах.
Дальнейшая работа может заключаться в исследовании других способов построения узорных структур для классификации, а также в адаптации рассмотренных алгоритмов для работы с «большими» данными.
Список литературы
[1] Bernhard Ganter and Sergei Kuznetsov, “Pattern structures and their projections,” in Conceptual Structures: Broadening the Base, Harry Delugach and Gerd Stumme, Eds., vol. 2120 of Lecture Notes in Computer Science, pp. 129-142. Springer, Berlin/Heidelberg, 2001.
[2] Ganter, B., Wille, R.: Formal concept analysis: Mathematical foundations. Springer, Berlin, 1999.
[3] Masyutin A., Kashnitsky Y. Query-Based Versus Tree-Based Classification: Application to Banking Data, in: Foundations of Intelligent Systems. Warsz. : Springer International Publishing, 2017. P. 664-673.
[4] Masyutin A., Kashnitsky Y., Kuznetsov S. Lazy Classication with Interval Pattern Structures: Application to Credit Scoring, in: Proceedings of the International Workshop "What can FCA do for Artificial Intelligence?" (FCA4AI at IJCAI 2015) / Ed. by Sergei O. Kuznetsov, A. Napoli, S. Rudolph. Buenos Aires : , 2015. P. 43-54.
Приложение
В приложении содержится программный код на языке Python из файла jupyter-notebook, реализующий описанные выше алгоритмы.
# coding: utf-8
# ### Individual project by Alexander Ageev
#
# ### 1. Problem statement
# Banks play a crucial role in market economies. They decide who can get finance and on what terms and can make or break investment decisions. For markets and society to function, individuals and companies need access to credit.
#
# Credit scoring algorithms, which make a guess at the probability of default, are the method banks use to determine whether or not a loan should be granted. This competition requires participants to improve on the state of the art in credit scoring, by predicting the probability that somebody will experience financial distress in the next two years.
#
# The goal of this project is to build a model that borrowers can use to help make the best financial decisions.
# In[1]:
import numpy as np
import pandas as pd
import random
import sklearn
from sklearn import metrics
import sklearn.model_selection
import datetime
import time
import os
import math
random.seed(1)
# ### 2. Dataset summary
# Dataset of Kaggle's competition "Give Me Some Credit" was considered.
#
# https://www.kaggle.com/c/GiveMeSomeCredit
# Here's description of the features:
# In[2]:
data_dict = pd.read_excel('Data Dictionary.xls')
data_dict
# More details:
# In[3]:
for ind in range(data_dict.shape[0]):
print(data_dict.iloc[ind]['Variable Name'] + ' - '+data_dict.iloc[ind]['Description'], end="\n\n")
# **SeriousDlqin2yrs** - target variable.
# All the Kaggle's training dataset was divided in two parts (train 90% and test 10%) as long as there were no true values os the target variable in Kaggle's test set.
#
# The proportion of + and - objects was hold.
# Objects that contained missed values were excluded from the dataset in order to tune parameters of the main method better.
# In[4]:
df = pd.read_csv('cs-training.csv', index_col=0).dropna()
# In[5]:
X = df.drop('SeriousDlqin2yrs', axis=1)
y = df['SeriousDlqin2yrs']
X.shape
# Dividing in **train** and **test**:
# In[6]:
df_pos = df[df['SeriousDlqin2yrs']==1].drop('SeriousDlqin2yrs',axis=1)
df_neg = df[df['SeriousDlqin2yrs']==0].drop('SeriousDlqin2yrs',axis=1)
df_test_pos = df_pos.sample(frac=0.1, random_state=1)
df_test_neg = df_neg.sample(frac=0.1, random_state=1)
df_train_pos = df_pos.drop(df_test_pos.index)
df_train_neg = df_neg.drop(df_test_neg.index)
df_test = df_test_pos.append(df_test_neg)
# In[7]:
# df_train_pos.to_csv('df_train_pos.csv')
# df_train_neg.to_csv('df_train_neg.csv')
# df_test.to_csv('df_test.csv')
# In[8]:
df_train_pos = pd.read_csv('df_train_pos.csv',index_col=0)
df_train_neg = pd.read_csv('df_train_neg.csv',index_col=0)
df_test= pd.read_csv('df_test.csv',index_col=0)
# In[9]:
df_train_pos.head()
# In[10]:
df_train_neg.shape
# In[11]:
X_pos = df_train_pos.values
X_neg = df_train_neg.values
X_test = df_test.values
y_true = y[df_test.index].values
X_neg_true = X_neg.copy()
# In[12]:
X_test.shape
# In[13]:
X.shape[0] - X_test.shape[0]
# As a result there was *108242* obejcts in train dataset, *12027* objects in test dataset. Each of them contained 10 features.
# ### 3. Methodology
# The first (and the main) approach is described at
#
# *Masyutin A., Kashnitsky Y., Kuznetsov S. O. Lazy Classication with Interval Pattern Structures: Application to Credit Scoring, in: Proceedings of the International Workshop "What can FCA do for Artificial Intelligence?" (FCA4AI at IJCAI 2015) / Ed. by Sergei O. Kuznetsov, A. Napoli, S. Rudolph. Buenos Aires : , 2015. P. 43-54.*
# This approach is considered in two small variations and compared with Logistic regression and Random forest.
# ### 4. Experiment setup and results
# Next, here is the code that executed many times with different parameters.
# ###### Creating dirs
# In[12]:
N_OF_ITER = [100,200,1000]
ALPHA = [0.1]
SAMPLE_SIZES = [2,3,4,5,6,7,8,9,10]
for number_of_iterations in N_OF_ITER:
for alpha in ALPHA:
for subsample_size in SAMPLE_SIZES:
os.system("mkdir "+str(number_of_iterations)+'_'+str(alpha)+'_'+str(subsample_size))
# ###### MLCA (classic)
# The general moments of this approach are:
# * All the test set is divided into 8 parts and processed separately with 8 ipython notebooks in order not to go into details of multithreading.
# * Parameter "number of objects" is used instead of "sample size" as in original paper.
# * Every iteration we extract a sample from negative context in order to save time. The quality decreased slightly.
#
# In[77]:
N_OF_ITER = [2000]
ALPHA = [0.001]
SAMPLE_SIZES = [2]
MODIFICATION = ""
# MODIFICATION = "all_X_neg_"
for number_of_iterations in N_OF_ITER:
for alpha in ALPHA:
for subsample_size in SAMPLE_SIZES:
os.system("mkdir "+ MODIFICATION + str(number_of_iterations)+'_'+str(alpha)+'_'+str(subsample_size))
NUMBER_OF_MINI_TEST = 0
mini_test_size = df_test.shape[0]//8
start_index = mini_test_size*NUMBER_OF_MINI_TEST
end_index = start_index+mini_test_size
mini_test_index = df_test.index[start_index:end_index]
# mini_test_size = 100
# mini_test_index = np.concatenate((df_test_pos.index[np.random.choice(df_test_pos.shape[0], size=mini_test_size, replace=False)],\
# df_test_neg.index[np.random.choice(df_test_neg.shape[0], size=mini_test_size, replace=False)]))
for number_of_iterations in N_OF_ITER:
for alpha in ALPHA:
for subsample_size in SAMPLE_SIZES:
NUMBER_OF_POS_VOTES = []
NUMBER_OF_NEG_VOTES = []
start_time = datetime.datetime.now()
print("PARAMS: ", number_of_iterations, alpha, subsample_size)
print("STARTED AT:", start_time.ctime())
for test_index in mini_test_index:
test_obj = df_test.loc[test_index].values
neg_itersections_with_all_pos = np.zeros(number_of_iterations)
pos_itersections_with_all_neg = np.zeros(number_of_iterations)
# MODIFICATION = "all_X_neg_"
X_neg = X_neg_true[np.random.choice(X_neg_true.shape[0], size=X_pos.shape[0], replace=False)] #
# MODIFICATION = "all_X_neg_"
for i in range(number_of_iterations):
pos_sample_ind = np.random.choice(X_pos.shape[0], size=subsample_size)
while np.unique(pos_sample_ind).shape[0]!=subsample_size:
pos_sample_ind = np.random.choice(X_pos.shape[0], size=subsample_size)
pos_sample = X_pos[pos_sample_ind]
premise_min = np.min((pos_sample.min(axis=0),test_obj), axis=0)
premise_max = np.max((pos_sample.max(axis=0),test_obj), axis=0)
# X_neg = X_neg_true[np.random.choice(X_neg_true.shape[0], size=X_pos.shape[0], replace=False)]
pos_itersections_with_all_neg[i]=np.sum((np.sum(X_neg <= premise_max, axis=1) == 10) & (np.sum(X_neg >= premise_min, axis=1) == 10))
# X_neg = X_neg_true
neg_sample_ind = np.random.choice(X_neg.shape[0], size=subsample_size)
while np.unique(neg_sample_ind).shape[0]!=subsample_size:
neg_sample_ind = np.random.choice(X_neg.shape[0], size=subsample_size)
neg_sample = X_neg[neg_sample_ind]
premise_min = np.min((neg_sample.min(axis=0),test_obj), axis=0)
premise_max = np.max((neg_sample.max(axis=0),test_obj), axis=0)
neg_itersections_with_all_pos[i]=np.sum((np.sum(X_pos <= premise_max, axis=1) == 10) & (np.sum(X_pos >= premise_min, axis=1) == 10))
NUMBER_OF_POS_VOTES.append(np.sum(pos_itersections_with_all_neg/X_neg.shape[0] <= alpha))
NUMBER_OF_NEG_VOTES.append(np.sum(neg_itersections_with_all_pos/X_pos.shape[0] <= alpha))
print(datetime.datetime.now() - start_time)
print("ENDED AT:", datetime.datetime.now())
print("")
df_result = pd.DataFrame({'POS_VOTES':NUMBER_OF_POS_VOTES,'NEG_VOTES':NUMBER_OF_NEG_VOTES,'y_true':y[mini_test_index]}, index=mini_test_index)
FILE_NAME = str(NUMBER_OF_MINI_TEST)+".csv"
DIR_NAME = MODIFICATION+str(number_of_iterations)+'_'+str(alpha)+'_'+str(subsample_size)
PATH = ".\\"+DIR_NAME+"\\"+FILE_NAME
df_result.to_csv(PATH)
# ##### Scores
# In[44]:
COL1 = []
COL2 = []
COL3 = []
COL4 = []
COL5 = []
COL6 = []
COL7 = []
COL8 = []
COL9 = []
COL10 = []
N_OF_ITER = []
ALPHA = []
SAMPLE_SIZES = []
# def generate_grid(N_OF_ITER,ALPHA,SAMPLE_SIZES):
# X = [2000]
# Y = [0.001, 0.002,0.003, 0.004, 0.005]
# Z = [1,2,3,4,5]
# for x in X:
# for y in Y:
# for z in Z:
# N_OF_ITER.append(x)
# ALPHA.append(y)
# SAMPLE_SIZES.append(z)
# generate_grid(N_OF_ITER,ALPHA,SAMPLE_SIZES)
# MODIFICATION = "concepts_"
MODIFICATION = ""
for dir_name in os.listdir():
dir_name = dir_name.strip(MODIFICATION).split('_')
if len(dir_name)==3 and str.isnumeric(dir_name[0]) and str.isnumeric(dir_name[2]):
number_of_iterations = int(dir_name[0])
alpha = float(dir_name[1])
subsample_size = int(dir_name[2])
# CONDITIONS. Что печатать?
# if alpha == 0.002:
if True:
N_OF_ITER.append(number_of_iterations)
ALPHA.append(alpha)
SAMPLE_SIZES.append(subsample_size)
for number_of_iterations,alpha,subsample_size in zip(N_OF_ITER,ALPHA,SAMPLE_SIZES):
DIR_NAME = MODIFICATION+str(number_of_iterations)+'_'+str(alpha)+'_'+str(subsample_size)
result = pd.DataFrame()
for NUMBER_OF_MINI_TEST in range(8):
FILE_NAME = str(NUMBER_OF_MINI_TEST)+".csv"
PATH = ".\\"+DIR_NAME+"\\"+FILE_NAME
result_mini_test = pd.read_csv(PATH, index_col=0)
result = pd.concat((result,result_mini_test))
y_true = result.y_true
num_of_unclassified = np.sum((result.NEG_VOTES == 0) & (result.POS_VOTES == 0))
# Вычитаем голоса
y_pred_diff = result.POS_VOTES*1 - result.NEG_VOTES*1
y_pred_diff.loc[(result.NEG_VOTES == 0) & (result.POS_VOTES == 0)] = 0 # У КОГО СЧЕТ 0:0, тех относим к классу 0
# y_pred_diff = 1 / (1 + np.exp(-y_pred_diff))
y_pred_diff = y_pred_diff - np.min(y_pred_diff)/(np.max(y_pred_diff)-np.min(y_pred_diff))
roc_auc_diff = sklearn.metrics.roc_auc_score(y_true,y_pred_diff)
# Доля голосов
y_pred_div = result.POS_VOTES*1/(result.POS_VOTES*1+result.NEG_VOTES*1)
y_pred_div.loc[(result.NEG_VOTES == 0) & (result.POS_VOTES == 0)] = 0 # У КОГО СЧЕТ 0:0, тех относим к классу 0
roc_auc_div = sklearn.metrics.roc_auc_score(y_true,y_pred_div)
COL1.append(number_of_iterations)
COL2.append(alpha)
COL3.append(subsample_size)
COL5.append(roc_auc_div)
COL6.append(num_of_unclassified)
COL7.append(roc_auc_diff)
# 'ROC-AUC':COL4
summary = pd.DataFrame({'number_of_iterations':COL1,'alpha':COL2,'subsample_size':COL3, 'roc_auc_div':COL5,'roc_auc_diff':COL7,'num_of_unclassified':COL6
})
pd.set_option('display.max_rows', 1000)
summary.set_index(['number_of_iterations','alpha','subsample_size'])
# ##### MLCA (precalc concepts)
# The difference of this approach from the previous one is that premises are calculating beforehand.
# So there is no "bad" descriprions that are intersected with test objects.
# In[554]:
N_OF_NEEDED_CONCEPTS = [2000]
ALPHA = [0.002, 0.001]
SAMPLE_SIZES = [1]
MODIFICATION = "concepts_"
# MODIFICATION = "all_X_neg_"
for number_of_concepts in N_OF_NEEDED_CONCEPTS:
for alpha in ALPHA:
for subsample_size in SAMPLE_SIZES:
os.system("mkdir "+ MODIFICATION +str(alpha)+'_'+str(subsample_size))
X_neg = X_neg_true
for alpha in ALPHA:
for subsample_size in SAMPLE_SIZES:
for number_of_concepts in N_OF_NEEDED_CONCEPTS:
start_time = datetime.datetime.now()
print("PARAMS: ", number_of_concepts, alpha, subsample_size)
print("MINING PLUS (+) STARTED AT:", start_time.ctime())
n_of_iter_pos = 0
n_of_mined_concepts_pos = 0
concepts_min = []
concepts_max = []
numbers_of_iter = [] # номер итерации, на которой мы получили этот концепт
number_of_intersections = []
while n_of_mined_concepts_pos < number_of_concepts:
n_of_iter_pos += 1
pos_sample_ind = np.random.choice(X_pos.shape[0], size=subsample_size)
while np.unique(pos_sample_ind).shape[0]!=subsample_size:
pos_sample_ind = np.random.choice(X_pos.shape[0], size=subsample_size)
pos_sample = X_pos[pos_sample_ind]
premise_min = pos_sample.min(axis=0)
premise_max = pos_sample.max(axis=0)
pos_itersections_with_all_neg=np.sum((np.sum(X_neg <= premise_max, axis=1) == 10) & (np.sum(X_neg >= premise_min, axis=1) == 10))
if pos_itersections_with_all_neg/X_neg.shape[0] <= alpha:
concepts_min.append(premise_min)
concepts_max.append(premise_max)
numbers_of_iter.append(n_of_iter_pos)
number_of_intersections.append(pos_itersections_with_all_neg)
n_of_mined_concepts_pos += 1
positive_concepts_min = pd.DataFrame(concepts_min, columns=df_train_pos.columns, index=np.arange(1,len(concepts_min)+1))
positive_concepts_max = pd.DataFrame(concepts_max, columns=df_train_pos.columns, index=np.arange(1,len(concepts_max)+1))
positive_n_iter = pd.Series(numbers_of_iter, index=np.arange(1,len(numbers_of_iter)+1))
positive_n_intersections_with_neg = pd.Series(number_of_intersections, index=np.arange(1,len(numbers_of_iter)+1))
DIR_NAME = MODIFICATION+str(alpha)+'_'+str(subsample_size)
PATH = ".\\"+DIR_NAME+"\\"
positive_concepts_min.to_csv(PATH+str(number_of_concepts)+'_'+"positive_concepts_min.csv")
positive_concepts_max.to_csv(PATH+str(number_of_concepts)+'_'+"positive_concepts_max.csv")
positive_n_iter.to_csv(PATH+str(number_of_concepts)+'_'+"positive_n_iter.csv")
positive_n_intersections_with_neg.to_csv(PATH+str(number_of_concepts)+'_'+"positive_n_intersections_with_neg.csv")
print(datetime.datetime.now() - start_time)
print("MINING PLUS (+) ENDED AT:", datetime.datetime.now())
print("")
############################
start_time = datetime.datetime.now()
print("PARAMS: ", number_of_concepts, alpha, subsample_size)
print("MINING MINUS (-) STARTED AT:", start_time.ctime())
n_of_iter_neg = 0
n_of_mined_concepts_neg = 0
concepts_min = []
concepts_max = []
numbers_of_iter = [] # номер итерации, на которой мы получили этот концепт
number_of_intersections = []
while n_of_mined_concepts_neg < number_of_concepts:
n_of_iter_neg += 1
neg_sample_ind = np.random.choice(X_neg.shape[0], size=subsample_size)
while np.unique(neg_sample_ind).shape[0]!=subsample_size:
neg_sample_ind = np.random.choice(X_neg.shape[0], size=subsample_size)
neg_sample = X_neg[neg_sample_ind]
premise_min = neg_sample.min(axis=0)
premise_max = neg_sample.max(axis=0)
neg_itersections_with_all_pos=np.sum((np.sum(X_pos <= premise_max, axis=1) == 10) & (np.sum(X_pos >= premise_min, axis=1) == 10))
if neg_itersections_with_all_pos/X_pos.shape[0] <= alpha:
concepts_min.append(premise_min)
concepts_max.append(premise_max)
numbers_of_iter.append(n_of_iter_neg)
number_of_intersections.append(neg_itersections_with_all_pos)
n_of_mined_concepts_neg += 1
negative_concepts_min = pd.DataFrame(concepts_min, columns=df_train_neg.columns, index=np.arange(1,len(concepts_min)+1))
negative_concepts_max = pd.DataFrame(concepts_max, columns=df_train_neg.columns, index=np.arange(1,len(concepts_max)+1))
negative_n_iter = pd.Series(numbers_of_iter, index=np.arange(1,len(numbers_of_iter)+1))
negative_n_intersections_with_neg = pd.Series(number_of_intersections, index=np.arange(1,len(numbers_of_iter)+1))
DIR_NAME = MODIFICATION+str(alpha)+'_'+str(subsample_size)
PATH = ".\\"+DIR_NAME+"\\"
negative_concepts_min.to_csv(PATH+str(number_of_concepts)+'_'+"negative_concepts_min.csv")
negative_concepts_max.to_csv(PATH+str(number_of_concepts)+'_'+"negative_concepts_max.csv")
negative_n_iter.to_csv(PATH+str(number_of_concepts)+'_'+"negative_n_iter.csv")
negative_n_intersections_with_neg.to_csv(PATH+str(number_of_concepts)+'_'+"negative_n_intersections_with_neg.csv")
print(datetime.datetime.now() - start_time)
print("MINING MINUS (-) ENDED AT:", datetime.datetime.now())
print("")
# df_result = pd.DataFrame({'POS_VOTES':NUMBER_OF_POS_VOTES,'NEG_VOTES':NUMBER_OF_NEG_VOTES,'y_true':y[mini_test_index]}, index=mini_test_index)
# FILE_NAME = str(NUMBER_OF_MINI_TEST)+".csv"
# DIR_NAME = MODIFICATION+str(number_of_iterations)+'_'+str(alpha)+'_'+str(subsample_size)
# PATH = ".\\"+DIR_NAME+"\\"+FILE_NAME
# df_result.to_csv(PATH)
# ###### Classifying test objects
# In[567]:
ALPHA = [0.003]
SAMPLE_SIZES = [1,2,3,4,5]
N_OF_NEEDED_CONCEPTS = [2000]
for alpha in ALPHA:
for subsample_size in SAMPLE_SIZES:
for number_of_concepts in N_OF_NEEDED_CONCEPTS:
start_time = datetime.datetime.now()
print("PARAMS: ", number_of_concepts, alpha, subsample_size)
print("MINING PLUS (+) STARTED AT:", start_time.ctime())
DIR_NAME = "concepts_"+str(alpha)+'_'+str(subsample_size)
PATH = ".\\"+DIR_NAME+"\\"
positive_concepts_min = pd.read_csv(PATH+str(number_of_concepts)+'_'+"positive_concepts_min.csv",index_col=0).values
positive_concepts_max = pd.read_csv(PATH+str(number_of_concepts)+'_'+"positive_concepts_max.csv",index_col=0).values
negative_concepts_min = pd.read_csv(PATH+str(number_of_concepts)+'_'+"negative_concepts_min.csv",index_col=0).values
negative_concepts_max = pd.read_csv(PATH+str(number_of_concepts)+'_'+"negative_concepts_max.csv",index_col=0).values
positive_n_intersections_with_neg = pd.read_csv(PATH+str(number_of_concepts)+'_'+"positive_n_intersections_with_neg.csv",index_col=0, header=-1).values[:,0]
negative_n_intersections_with_pos = pd.read_csv(PATH+str(number_of_concepts)+'_'+"negative_n_intersections_with_neg.csv",index_col=0, header=-1).values[:,0]
NUMBER_OF_MINI_TEST = 0
mini_test_size = df_test.shape[0]//8
start_index = mini_test_size*NUMBER_OF_MINI_TEST
end_index = start_index+mini_test_size
mini_test_index = df_test.index[start_index:end_index]
NUMBER_OF_POS_VOTES = []
NUMBER_OF_NEG_VOTES = []
start_time = datetime.datetime.now()
for test_index in mini_test_index:
test_obj = df_test.loc[test_index].values
neg_itersections_with_all_pos = np.zeros(number_of_concepts)
pos_itersections_with_all_neg = np.zeros(number_of_concepts)
X_neg = X_neg_true[np.random.choice(X_neg_true.shape[0], size=X_pos.shape[0], replace=False)]
premises_min = np.minimum(positive_concepts_min,test_obj)
premises_max = np.maximum(positive_concepts_max,test_obj)
premises = np.concatenate((premises_min, premises_max), axis=1)
pos_itersections_with_all_neg = np.apply_along_axis(lambda row: np.sum( ((row[:10] <= X_neg) & (X_neg <= row[10:])).all(axis=1) ), 1, premises)
premises_min = np.minimum(negative_concepts_min,test_obj)
premises_max = np.maximum(negative_concepts_max,test_obj)
premises = np.concatenate((premises_min, premises_max), axis=1)
neg_itersections_with_all_pos = np.apply_along_axis(lambda row: np.sum( ((row[:10] <= X_pos) & (X_pos <= row[10:])).all(axis=1) ), 1, premises)
NUMBER_OF_POS_VOTES.append(np.sum(pos_itersections_with_all_neg/X_neg.shape[0] <= alpha))
NUMBER_OF_NEG_VOTES.append(np.sum(neg_itersections_with_all_pos/X_pos.shape[0] <= alpha))
df_result = pd.DataFrame({'POS_VOTES':NUMBER_OF_POS_VOTES,'NEG_VOTES':NUMBER_OF_NEG_VOTES,'y_true':y[mini_test_index]}, index=mini_test_index)
FILE_NAME = str(NUMBER_OF_MINI_TEST)+".csv"
PATH = ".\\"+DIR_NAME+"\\"+FILE_NAME
df_result.to_csv(PATH)
print(datetime.datetime.now() - start_time)
print("ENDED AT:", datetime.datetime.now())
print("")
# In[50]:
COL1 = []
Подобные документы
Программное обеспечение для получения исходных данных для обучения нейронных сетей и классификации товаров с их помощью. Алгоритм метода обратного распространения ошибки. Методика классификации товаров: составление алгоритма, программная реализация.
дипломная работа [2,2 M], добавлен 07.06.2012Модификация алгоритма RPC таким образом, чтобы он не требовал входного параметра, но сохранил свою гибкость при решении задачи нахождения максимальной клики для разных графов. Метод ветвей и границ. Построение функции-классификатора. Листинг алгоритма.
курсовая работа [197,8 K], добавлен 06.10.2016Изучение основных понятий и определений теории графов. Рассмотрение методов нахождения кратчайших путей между фиксированными вершинами. Представление математического и программного обоснования алгоритма Флойда. Приведение примеров применения программы.
контрольная работа [1,4 M], добавлен 04.07.2011Принципы реализации программы проверки статистических гипотез с использованием t-критерия Стьюдента, ее общий алгоритм. Особенности применения двухвыборочного критерия для независимых выборок. Функциональные модели решения задачи для различных функций.
курсовая работа [644,2 K], добавлен 25.01.2010Алгоритмы нахождения кратчайшего пути: анализ при помощи математических объектов - графов. Оптимальный маршрут между двумя вершинами (алгоритм Декстры), всеми парами вершин (алгоритм Флойда), k-оптимальных маршрутов между двумя вершинами (алгоритм Йена).
курсовая работа [569,6 K], добавлен 16.01.2012Постановка задачи сортировки. Анализ основных понятий сортировок слияниями. Алгоритм сортировки простым и естественным слиянием. Оценка сложности алгоритма. Программная реализация простого слияния. Тестирование меню на корректность входных данных.
курсовая работа [283,6 K], добавлен 22.06.2015Обзор существующих методов межпроцедурного анализа. Получение входных и выходных данных подпрограмм с помощью графа алгоритма. Описание входных и выходных данных подпрограммы в терминах фактических параметров. Определение параллелизма по графу алгоритма.
учебное пособие [77,5 K], добавлен 28.06.2009Задачи, решаемые методом динамического программирования. Основные этапы нахождения деревянного алгоритма решения задачи. Выполнение алгоритма Прима. Построение Эйлерового цикла. Решение задач средствами Excel. Алгоритм основной программы - Derevo.
курсовая работа [586,3 K], добавлен 04.04.2015Построение систем визуализации моделей раскроя и их модификации. Анализ способов и методов создания универсального хранилища данных, на примере построения динамически формируемого информационного файла. Графические возможностей языка высокого уровня С.
научная работа [355,5 K], добавлен 06.03.2009Особенности кодирования информации с помощью метода Хаффмана. Реализация кодера и декодера с использованием статического алгоритма Хаффмана. Структура программы, оценка ее эффективности (степени сжатия) в зависимости от типа и размера сжимаемых файлов.
курсовая работа [136,2 K], добавлен 15.06.2013