dk78.ru

Matrix палитра цветов


Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

« Older posts

В заметке http://kbroman.wordpress.com/2014/09/04/error-notifications-from-r/|http://kbroman.wordpress.com/2014/09/04/error-notifications-from-r/ был опубликован удобный способ уведомления об ошибках в R.

Идея чрезвычайно проста. В R любая ошибка обязательно вызывает триггер ‘//error//’, к которому можно привязать любую функцию, в данном случае функцию уведомления. Для привязки функции уведомления, достаточно включить в скрипт код следующего вида:

{{{ lang=rsplus
options(error = function(){
# Тело функции, осуществляющей уведомление об ошибке
})
}}}

Содержание ошибки можно получить используя функцию ‘//geterrmessage()//’. Таким образом, код, который используюет сервис https://github.com/eddelbuettel/rpushbullet|PushBullet будет выглядеть как-то так

{{{ lang=rsplus
options(error = function() {
require(RPushbullet)
pbPost(“note”, “Error”, geterrmessage())
})
}}}

Tagged R

==Введение==

Данная заметка является переводом http://www.everydayanalytics.ca/2014/09/5-ways-to-do-2d-histograms-in-r.html|http://www.everydayanalytics.ca/2014/09/5-ways-to-do-2d-histograms-in-r.html.

http://www.mylesharrison.com/|Myles Harrison решил собрать как можно больше примеров создания качественных 2D гистограмм в R, для чего изучал различные форумы, блоги и задавал вопросы на http://stackoverflow.com/questions/18089752/r-generate-2d-histogram-from-raw-data|Stackoverflow. Эти примеры изложены ниже, с тем, чтобы их можно было использовать в работе, а также была наглядно видна разница между ними.

Для сведения, 2D гистограммы – это расширение обычных http://en.wikipedia.org/wiki/Histogram|гистограмм, показывающих распределение частотности двух количественных показателей по некоторым интервалам группировки показателей. Их можно рассматривать как особый случай http://en.wikipedia.org/wiki/Heat_map|тепловых карт, где цвет или интенсивность цвета показывает количество наблюдений попавших в соответствующий сегмент данных.

Во-первых, на протяжении всего текста будет использоваться цветовая палитра, созданная с помощью пакета http://cran.r-project.org/web/packages/RColorBrewer/index.html|RColorBrewer, и нормально распределённые данные, объединённые в датафрейм. Во-вторых, для демонстрации полезности 2D гистограмм продемонстрируем соответствующую диаграмму рассеяния.

{{{ lang=rsplus
# Color housekeeping
library(RColorBrewer)
rf <- colorRampPalette(rev(brewer.pal(11,'Spectral'))) r <- rf(32) # Create normally distributed data for plotting x <- rnorm(mean=1.5, 5000) y <- rnorm(mean=1.6, 5000) df <- data.frame(x,y) # Plot plot(df, pch=16, col='black', cex=0.5) }}} image:scatterplot.jpeg|medium|center|link=source ==Вариант 1: hexbin== Пакет http://cran.r-project.org/web/packages/hexbin/index.html|hexbin разбивает пространство на 2D шестигранные соты и затем подсчитывает количество попаданий в каждую соту. Удобством использования пакета //hexbin// является то, что он автоматически добавляет легенду в график, так как ручное добавление легенды в R вещь достаточно проблематичная. Если использовать функции с параметрами по умолчанию, то получится простой монохромный график. Использование параметра //colramp// с нужной палитрой цветов немного улучшает картинку. К сожалению, положение легенды оставляет желать лучшего. {{{ lang=rsplus #----- OPTION 1: hexbin from package 'hexbin' -----------image:kde2d_1.jpeg|center|large|link=source library(hexbin) # Create hexbin object and plot h <- hexbin(df) plot(h) plot(h, colramp=rf) }}} image:hexbin_1.jpeg|large|center|link=source Функции //hexbinplot// дает большую гибкость, позволяя настройку границ бинирования, к тому же поддерживает использование функций трансформации, к примеру, на одном из нижеследующих графиков была использована логарифмическая шкала. Только не стоит забывать, что необходимо передать как прямую, так и обратную функцию трансформации. Дополнительным плюсом данной функции является то, что корректно вычисляется положение легенды. {{{ lang=rsplus # hexbinplot function allows greater flexibility hexbinplot(yx, data=df, colramp=rf) # Setting max and mins hexbinplot(yx, data=df, colramp=rf, mincnt=2, maxcnt=60) }}} image:hexbin_2.jpeg|large|center|link=source {{{ lang=rsplus # Scaling of legend - must provide both trans and inv functions hexbinplot(yx, data=df, colramp=rf, trans=log, inv=exp) }}} image:hexbin_3-e1409740343841.jpeg|center|link=source ==Вариант 2: hist2d== Пакет http://cran.r-project.org/web/packages/gplots/index.html|gplots помимо всего прочего содержит функцию //hist2d//, которая позволяет быстро строить 2D гистограммы. И вновь, функция с параметрами по умолчанию даёт не очень эффектный график {{{ lang=rsplus #----- OPTION 2: hist2d from package 'gplots' --------- library(gplots) # Default call h2 <- hist2d(df) }}} image:hist2d_1.jpeg|center|medium|link=source Настройка цветовой палитры и размера сегментов даёт более хороший результат. И так же, как и в предыдущем случае можно настроить логарифмическую шкалу. {{{ lang=rsplus # Coarser binsizing and add colouring h2 <- hist2d(df, nbins=25, col=r) # Scaling with log as before h2 <- hist2d(df, nbins=25, col=r, FUN=function(x) log(length(x))) }}} image:hist2d_adj.jpeg|center|large|link=source ==Вариант 3: stat_2bin из пакета ggplot2== Конечно же, разве может какая-либо статья по R обойтись без упоминания пакета http://cran.r-project.org/web/packages/ggplot2/index.html|ggplot2? При построении 2D гистограмм в этом пакете можно использовать функцию //stat_2bin// либо добавляя её к //ggplot//-объекту, либо передавая в качестве параметра типа геометрии в функции //qplot//. {{{ lang=rsplus #----- OPTION 3: stat_bin2d from package 'ggplot' ------- library(ggplot2) # Default call (as object) p <- ggplot(df, aes(x,y)) (h3 <- p + stat_bin2d()) # Default call (using qplot) qplot(x,y,data=df, geom='bin2d') }}} image:ggplot_1-e1409741740122.jpeg|center|link=source И вновь, имеет смысл поменять сегментирование и использовать свою цветовую палитру. Последнее можно сделать при помощи функции //scale_fill_gradientn// с нужным вектором цветов. Логарифмическую шкалу можно задать в той же функции, передав её в параметр //trans//. {{{ lang=rsplus # Add colouring and change bins (h3 <- p + stat_bin2d(bins=25) + scale_fill_gradientn(colours=r)) # Log scaling (h3 <- p + stat_bin2d(bins=25) + scale_fill_gradientn(colours=r, trans="log")) }}} image:ggplot_2.jpeg|center|large|link=source ==Вариант 4: kde2d== В этом варианте используется ядерная оценка плотности (англ. kernel denisty estimation) при помощи функции //kde2d// из пакета http://cran.r-project.org/web/packages/MASS/index.html|MASS. Здесь стоит учесть, что получаемый результат не является в точности 2D гистограммой, так как функция интерполирует данные для получения соответствующей оценки плотности распределения. По умолчанию используется значение количества сегментов n = 25, что совпадает с тем, что использовалось ранее, а потому этот параметр не будет указываться явно. Изображение строится при помощи функции //image()//. Увеличение числа n фактически будет приближать результат к ядерной оценке плотности, так как в какой-то момент размер сегмента станет меньше, чем шаг в имеющихся данных. Hadley Wickham написал статью, в которой указал, что в R http://vita.had.co.nz/papers/density-estimation.pdf|более 20 пакетов (PDF), при помощи которых можно строить оценки плотности распределения, поэтому мы не будем углубляться в эту тему. {{{ lang=rsplus #----- OPTION 4: kde2d from package 'MASS' ------------- # Not a true heatmap as interpolated (kernel density estimation) library(MASS) # Default call k <- kde2d(df$x, df$y) image(k, col=r) # Adjust binning (interpolate - can be computationally intensive for large datasets) k <- kde2d(df$x, df$y, n=200) image(k, col=r) }}} image:kde2d_1.jpeg|center|large|link=source ==Вариант 5: Использование базовых библиотек== И, наконец, бесстрашный пользователь R продемонстрировал на http://stackoverflow.com/questions/18089752/r-generate-2d-histogram-from-raw-data/18103689#18103689|Stackoverflow как можно решить эту задачу "в лоб", с использованием только базовых библиотек. {{{ lang=rsplus #----- OPTION 5: The Hard Way (DIY) ----------------- # http://stackoverflow.com/questions/18089752/r-generate-2d-histogram-from-raw-data nbins <- 25 x.bin <- seq(floor(min(df[,1])), ceiling(max(df[,1])), length=nbins) y.bin <- seq(floor(min(df[,2])), ceiling(max(df[,2])), length=nbins) freq <- as.data.frame(table(findInterval(df[,1], x.bin),findInterval(df[,2], y.bin))) freq[,1] <- as.numeric(freq[,1]) freq[,2] <- as.numeric(freq[,2]) freq2D <- diag(nbins)0 freq2D[cbind(freq[,1], freq[,2])] <- freq[,3] # Normal image(x.bin, y.bin, freq2D, col=r) # Log image(x.bin, y.bin, log(freq2D), col=r) }}} image:hardway_1.jpeg|center|large|link=source Не тот способ, которым стоит это делать, особенно с учётом вышеописанных возможностей, но если есть настоятельная необходимость не использовать дополнительные пакеты, то это рабочий вариант. ==Бонусный вариант== И напоследок, есть смысл добавить эту, очень хорошую диаграмму из книги http://books.google.ca/books?id=YWcLBAAAQBAJ&printsec=frontcover&dq=Computational+Actuarial+Science+with+R&hl=en&sa=X&ei=0hYHVOhrgZrKA5S9gLAI&ved=0CDEQ6AEwAA#v=onepage&q=Computational%20Actuarial%20Science%20with%20R&f=false|Computational Actuarial Science with R. Эта диаграмма используется не очень часто и состоит из 2D гистограммы и двух обычных 1D гистограмм, показывающих распределение величины в каждом из измерений. {{{ lang=rsplus #----- Addendum: 2D Histogram + 1D on sides (from Computational ActSci w R) ------ #http://books.google.ca/books?id=YWcLBAAAQBAJ&pg=PA60&lpg=PA60&dq=kde2d+log&source=bl&ots=7AB-RAoMqY&sig=gFaHSoQCoGMXrR9BTaLOdCs198U&hl=en&sa=X&ei=8mQDVPqtMsi4ggSRnILQDw&redir_esc=y#v=onepage&q=kde2d%20log&f=false h1 <- hist(df$x, breaks=25, plot=F) h2 <- hist(df$y, breaks=25, plot=F) top <- max(h1$counts, h2$counts) k <- kde2d(df$x, df$y, n=25) # margins oldpar <- par() par(mar=c(3,3,1,1)) layout(matrix(c(2,0,1,3),2,2,byrow=T),c(3,1), c(1,3)) image(k, col=r) #plot the image par(mar=c(0,2,1,0)) barplot(h1$counts, axes=F, ylim=c(0, top), space=0, col='red') par(mar=c(2,0,0.5,1)) barplot(h2$counts, axes=F, xlim=c(0, top), space=0, col='red', horiz=T) }}} image:addendum.jpeg|center|medium|link=source ==Заключение== Итак, было предоставлено 5 различных способов построения 2D гистограмм в R, плюс некоторый дополнительный код. В качестве самостоятельного задания остаётся задача добавления легенд в те гистограммы, в которых её нет. Надеюсь, что пользователи R найдут эту заметку полезной. Весь код, описанный в тексте можно скачать [wpfilebase tag="fileurl" id=10 linktext="здесь"/].

Tagged R, visualization

==Улучшение классификатора==

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

# создать сетку желаемых параметров
# передать эту сетку в обучающий алгоритм.

Делается это следующим образом

{{{ lang=rsplus
modelGrid <- expand.grid(iter = c(100, 200, 300, 400, 500), maxdepth = c(1, 2, 3, 4), nu = 0.1) model_tuned <- train( target ., data = train, method = "ada", trControl = ctrl, tuneGrid = modelGrid, metric = 'ROC' ) }}} Передача сетки производится при помощи параметра 'tuneGrid' в команде 'train'. Сама же сетка формируется при помощи команды 'expand.grid', которая составляет все возможные комбинации входных параметров {{{ lang=rsplus > head(modelGrid, n = 10)
iter maxdepth nu
1 100 1 0.1
2 200 1 0.1
3 300 1 0.1
4 400 1 0.1
5 500 1 0.1
6 100 2 0.1
7 200 2 0.1
8 300 2 0.1
9 400 2 0.1
10 500 2 0.1
}}}

Результат вычислений выглядит следующим образом

image:ada_tuned.jpeg|link=source

Как видно из графика, после того, как количество используемых деревьев переходит 300 единиц, алгоритм выходит на плато и по всей видимости уже не может улучшать свою работу. Самым выигрышным набором гиперпараметров становится комбинация с iter = 400, maxdepth = 3, nu = 0.1 и значением ROC = 0.944. Соответствующий график ROC-кривой на проверочной выборке выглядит следующим образом

image:ada_tuned_roc.jpeg|link=source

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

{{{ lang=rsplus
> testClasses <- predict(model_tuned, newdata = test) > confusionMatrix(data = testClasses, test$target)

Confusion Matrix and Statistics
Reference
Prediction M R
M 25 4
R 2 20

Accuracy : 0.8824
95% CI : (0.7613, 0.9556)
No Information Rate : 0.5294
P-Value [Acc > NIR] : 8.488e-08

Kappa : 0.7628
Mcnemar’s Test P-Value : 0.6831

Sensitivity : 0.9259
Specificity : 0.8333
Pos Pred Value : 0.8621
Neg Pred Value : 0.9091
Prevalence : 0.5294
Detection Rate : 0.4902
Detection Prevalence : 0.5686
Balanced Accuracy : 0.8796

‘Positive’ Class : M
}}}

Тем не менее, это не противоречит тому факту, что ROC для такой модели выше. Из результатов видно, что алгоритм чаще ошибается занося ‘R’ в класс ‘M’. Таким образом, если перекалибровать модель, есть возможность понизить количество ошибок такого типа.

{{{ lang=rsplus
> tc_calibrated <- factor(ifelse(testProbs_tuned$M >= 0.7, ‘M’, ‘R’))
> confusionMatrix(data = tc_calibrated, test$target)

Confusion Matrix and Statistics
Reference
Prediction M R
M 25 2
R 2 22

Accuracy : 0.9216
95% CI : (0.8112, 0.9782)
No Information Rate : 0.5294
P-Value [Acc > NIR] : 1.407e-09

Kappa : 0.8426
Mcnemar’s Test P-Value : 1

Sensitivity : 0.9259
Specificity : 0.9167
Pos Pred Value : 0.9259
Neg Pred Value : 0.9167
Prevalence : 0.5294
Detection Rate : 0.4902
Detection Prevalence : 0.5294
Balanced Accuracy : 0.9213

‘Positive’ Class : M
}}}

Сдвиг порога обнаружения металла до 70% позволяет повысить //accuracy// до 92%!

==Сравнение с другим классификатором (Random Forest)==

Для демонстрации удобства работы с пакетом ‘caret’, построим решение той же задачи при помощи классификатора https://ru.wikipedia.org/wiki/Random_forest|RandomForest.

{{{ lang=rsplus
modelGrid <- expand.grid(mtry = seq(2, 60, 1)) ctrl <- trainControl( method = "repeatedcv", repeats = 10, number = 10, classProbs = T, verboseIter = T, summaryFunction = twoClassSummary ) model_rf <- train( target ., data = train, method = "rf", tuneGrid = modelGrid, trControl = ctrl, metric = 'ROC' ) }}} Настройка данного алгоритма выглядит следующим образом image:rf.jpeg|link=source И из графика видно, что увеличение числа предикторов ухудшает точность работы алгоритма, и наилучший результат получается при числе предикторов равном 4 с ROC=0.935, что немного хуже, чем в случае AdaBoost. Более низкое качество показывается и на проверочной выборке {{{ lang=rsplus > testClasses <- predict(model_rf, newdata = test) > confusionMatrix(data = testClasses, test$target)

Confusion Matrix and Statistics
Reference
Prediction M R
M 26 9
R 1 15

Accuracy : 0.8039
95% CI : (0.6688, 0.9018)
No Information Rate : 0.5294
P-Value [Acc > NIR] : 4.341e-05

Kappa : 0.5991
Mcnemar’s Test P-Value : 0.02686

Sensitivity : 0.9630
Specificity : 0.6250
Pos Pred Value : 0.7429
Neg Pred Value : 0.9375
Prevalence : 0.5294
Detection Rate : 0.5098
Detection Prevalence : 0.6863
Balanced Accuracy : 0.7940

‘Positive’ Class : M
}}}

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

{{{ lang=rsplus
> summary(resamps <- resamples(list(ada = model_tuned, rf = model_rf))) Call: summary.resamples(object = resamps <- resamples(list(ada = model_tuned, rf = model_rf))) Models: ada, rf Number of resamples: 100 ROC Min. 1st Qu. Median Mean 3rd Qu. Max. NA's ada 0.7500 0.9092 0.9531 0.9435 0.9883 1 0 rf 0.7143 0.9009 0.9524 0.9353 0.9842 1 0 Sens ... > summary(diffs <- diff(resamps)) Call: summary.diff.resamples(object = diffs <- diff(resamps)) p-value adjustment: bonferroni Upper diagonal: estimates of the difference Lower diagonal: p-value for H0: difference = 0 ROC ada rf ada 0.008202 rf 0.3594 ... }}} Первая команда сравнивает набранные статистики по ROC метрике между разными методами. Как можно видеть, RandomForest в целом смещён влево по сравнению с AdaBoost. Вторая команда производит сравнение распределений по теории гипотез. Из этого сравнения видно, что AdaBoost немного лучше RandomForest (на 0.008), но значимость нулевой гипотезы (что модели равносильны) равна 36%, то есть разница есть, но она может быть статистической ошибкой.

Tagged AdaBoost, caret, cross validation, data mining, R, RandomForest, ROC

==Подготовка данных==

В данной задаче используется набор данных Sonar. Это задача, которая решалась в статье https://papers.cnl.salk.edu/PDFs/Analysis%20of%20Hidden%20Units%20in%20a%20Layered%20Network%20Trained%20to%20Classify%20Sonar%20Targets%201988-2996.pdf|”Analysis of Hidden Units in a Layered Network Trained to Classify Sonar Targets” и представляют собой набор значений звуковых сигналов отражённых от металлических(M) и каменных(R) объектов. Каждая запись представляет собой строку из 60 чисел и значением “M” или “R”. Данные подготавливаются следующим кодом

{{{ lang=rsplus
#——- Packages ————————-
require(caret)
require(mlbench)

#——- Data preparation —————–
data(Sonar)
df <- Sonar names(df)[names(df) == "Class"] <- 'target' set.seed(1234) idx <- createDataPartition(df$target, p = 0.75, list = F) train <- df[idx, ] test <- df[-idx, ] }}} Здесь для удобства данные сохраняются в новую переменную и удобства ради, название целевого признака заменяется на 'target'. После чего фиксируется рандомизация и создаётся разбиение исходных данных на две части, обучающую выборку train и проверочную test. Индексы при этом формируются при помощи команды createDataPartition, в которой в данном случае размер обучающей выборки задаётся параметром p в 75% от исходного размера. Команда createDataPartition помимо всего прочего старается создать сбалансированные выборки, то есть доля положительных/отрицательных ответов в обучающей выборке должна быть приблизительно равна доле положительных/отрицательных ответов в исходной выборке. Это можно проверить следующим образом {{{ lang=rsplus #--- Test sample balance ------------------ mean(df$target == "R") # доля ответов 'R' в исходной выборке [1] 0.4663462 mean(train$target == "R") # доля ответов 'R' в обучающей выборке [1] 0.4649682 mean(test$target == "R") # доля ответов 'R' в проверочной выборке [1] 0.4705882 nrow(train)/nrow(df) # относительный объём обучающей выборки [1] 0.7548077 }}} Как можно видеть, данные получились корректными. ==Построение бинарного классификатора (AdaBoost)== Первый бинарный классификатор, который мы построим, будет использовать алгоритм https://ru.wikipedia.org/wiki/AdaBoost|AdaBoost. Наверное после такой длинной подготовки сам код будет разочаровывающе коротким, но стоит отметить, что такая краткость возможно лишь благодаря пакету caret. {{{ lang=rsplus #--- Default Modelling ---------------------------- ctrl <- trainControl( method = "repeatedcv", repeats = 10, number = 10, classProbs = T, verboseIter = T, summaryFunction = twoClassSummary ) model_default <- train( target ., data = train, method = "ada", trControl = ctrl, metric = 'ROC' ) }}} Само построение модели производится командой train. В данном примере использованы далеко не все её возможности, позже будут использоваться дополнительные параметры. Имеющиеся же означают следующее # target . - это объект R-формула, который означает, что мы строим зависимость параметра 'target' от всех остальных параметров, которые присутствуют в данных, '.' в данном случае это wildcard, который означает "в правой части формулы стоят все названия столбцов, которые встречаются в данных" . При этом R исключает названия, которые стоят в левой части формулы. Подобная форма записи удобнее, чем указывать в явном виде название каждого отдельного параметра, так как к примеру в данном случае их 60 штук, а вообще их могут быть тысячи. # data = train означает, что в качестве данных на основе которых будет строиться модель должна быть использована обучающая выборка. Если бы было написано data = df, то использовалась бы вся выборка. # method = 'ada' означает, что необходимо использовать метод AdaBoost, который имеет ярлык 'ada' в рамках пакета 'caret'. Полный список готовых для использовония методов можно посмотреть командой "?train_model_list". Так же 'caret' позволяет добавлять свои собственные алгоритмы. # metric = 'ROC' означает, что нужно использовать AUC метрику ROC-кривых. Если опустить этот параметр, то по умолчанию будет использоваться accuracy. Параметр 'trControl' позволяет установить дополнительные настройки работы обучения, не связанные непосредственно с алгоритмами обучения. Контроль задается командой 'trainControl' и параметры имеют следующий смысл # method = 'repeatedcv' означает, что будет использоваться повторная кросс-валидация. Так же возможна обычная кросс-валидация, leave-one-out и так далее. # repeats = 10 означает, что повторная кросс-валидация должна быть запущена 10 раз. # number = 10 означает, что в процессе кросс-валидации выборку надо разбивать на 10 равных частей. # classProbs = T означает, что в процессе вычислений алгоритм будет сохранять данные о вероятностях попадания объекта в каждый класс, а не только конечные метки класса. Этот параметр необходим для использования метрики ROC-кривой. # verboseIter = T означает, что в ходе вычислений caret будет показывать на каком этапе он находится. Это удобно для оценки оставшегося времени вычислений, которое зачастую бывает очень большим. # summaryFunction = twoClassSummary означает, что для оценки эффективности алгоритма необходимо использовать встроенную функцию twoClassSummary, это необходимое требование при использовании метрики ROC. Процесс вычисления выглядит следующим образом {{{ lang=rsplus + Fold01.Rep01: iter= 50, maxdepth=1, nu=0.1 - Fold01.Rep01: iter= 50, maxdepth=1, nu=0.1 + Fold01.Rep01: iter=100, maxdepth=1, nu=0.1 - Fold01.Rep01: iter=100, maxdepth=1, nu=0.1 ... + Fold10.Rep10: iter=150, maxdepth=3, nu=0.1 - Fold10.Rep10: iter=150, maxdepth=3, nu=0.1 Aggregating results Selecting tuning parameters Fitting iter = 150, maxdepth = 3, nu = 0.1 on full training set }}} Знаки + и - означают начало и окончание соответствующего этапа вычислений. Значения iter, maxdepth и nu означают набор гиперпараметров AdaBoost, соответственно количество деревьев, максимальная глубина дерева и параметр сжатия. Их точный смысл можно найти в интернете, однако в рамках данной статьи он не важен, а важно лишь то, что caret по умолчанию создал семейство алгоритмов с различными значениями гиперпараметров и автоматически выбирает наилучший при помощи повторной кросс-валидации. В данном случае обучающий алгоритм выбрал модель с гиперпараметрами iter = 150, maxdepth = 3, nu = 0.1 и произвёл обучение этой модели на всей обучающей выборке. Почему было принято именно такое решение легко понять, если показать результат вычислений {{{ lang=rsplus > model_default

Boosted Classification Trees
157 samples
60 predictors
2 classes: ‘M’, ‘R’
No pre-processing
Resampling: Cross-Validated (10 fold, repeated 10 times)
Summary of sample sizes: 141, 141, 142, 142, 140, 142, …
Resampling results across tuning parameters:
iter maxdepth ROC Sens Spec ROC SD Sens SD Spec SD
50 1 0.846 0.832 0.685 0.117 0.124 0.179
50 2 0.889 0.846 0.725 0.0851 0.135 0.179
50 3 0.904 0.853 0.751 0.0693 0.124 0.162
100 1 0.889 0.852 0.744 0.0829 0.127 0.164
100 2 0.918 0.867 0.761 0.0645 0.12 0.174
100 3 0.918 0.877 0.769 0.0652 0.116 0.178
150 1 0.907 0.872 0.776 0.0691 0.121 0.165
150 2 0.923 0.867 0.791 0.0614 0.126 0.167
150 3 0.927 0.881 0.782 0.0583 0.117 0.161
Tuning parameter ‘nu’ was held constant at a value of 0.1
ROC was used to select the optimal model using the largest value.
The final values used for the model were iter = 150, maxdepth = 3 and nu = 0.1.
}}}

Как видно, параметр nu не менялся, поэтому он не показан в виде отдельного столбца. Значение ROC для iter = 150, maxdepth = 3 равно 0.927 и является лучшим результатом. На втором месте стоит iter = 150, maxdepth = 2 со значением ROC 0.923. Остальные столбцы означают Sens=Sensitivity, Spec=Specificity, то есть точность определения классов ‘M’ и ‘R’ отдельно, а следующие три столбца показывают стандартные отклонения для соответствующих величин (ROC SD = standard deviation of ROC и так далее). Как видно, кстати, ROC с наилучшим значением имеет к тому же и наименьшее отклонение 0.0583, что дополнительно говорит в пользу этого выбора.

Эти данные удобнее показывать в виде графика при помощи команды ‘ggplot(model_default)’

image:ada_default.jpeg|link=source

Как видно увеличение количества деревьев улучшает предсказательную силу всех алгоритмов, но явным фаворитом является алгоритм с глубиной 3.

Теперь можно оценить качество работы алгоритма на проверочной выборке
{{{ lang=rsplus
> testClasses <- predict(model_default, newdata = test) > confusionMatrix(data = testClasses, test$target)

Confusion Matrix and Statistics
Reference
Prediction M R
M 25 3
R 2 21

Accuracy : 0.902
95% CI : (0.7859, 0.9674)
No Information Rate : 0.5294
P-Value [Acc > NIR] : 1.209e-08

Kappa : 0.8028
Mcnemar’s Test P-Value : 1

Sensitivity : 0.9259
Specificity : 0.8750
Pos Pred Value : 0.8929
Neg Pred Value : 0.9130
Prevalence : 0.5294
Detection Rate : 0.4902
Detection Prevalence : 0.5490
Balanced Accuracy : 0.9005

‘Positive’ Class : M
}}}

Применение построенной модели к тестовым данным производится при помощи команды ‘predict’. Оценка эффективности алгоритма на проверочной выборке в читабельном виде показывается командой ‘confusionMatrix’. Как видно, на тестовой выборке алгоритм ошибся всего лишь 3 + 2 = 5 раз, что дало accuracy 90%. Смысл остальных параметров читателю предлагается выяснить самостоятельно.

Как было уже сказано, настройка модели производилась по ROC-кривой, и её вид и параметры выглядят следующим образом
{{{ lang=rsplus
> testProbs_default <- predict(model_default, newdata = test, type = 'prob') > head(testProbs_default)
M R
1 0.42626815 0.5737319
2 0.49835861 0.5016414
3 0.42028321 0.5797168
4 0.63866396 0.3613360
5 0.01186840 0.9881316
6 0.09051109 0.9094889

> (roc_default <- roc(test$target test_probs_default$M)) Call: roc.formula(formula = test$target test_probs_default$M) Data: test_probs_default$M in 27 controls (test$target M) > 24 cases (test$target R).
Area under the curve: 0.9444

> plot(roc_default) # построение графика ROC-кривой
}}}

Как видно площадь под кривой равна 0.9444, что является достаточно хорошим значением, но при этом выше чем значение 0.927 полученное в результате кросс-валидации. Это связано как с относительно малым объёмом проверочной выборки, так и с тем фактом, что в обучающую выборку по всей видимости попало достаточно много шумовых данных. Также test_probs_default содержит теперь не метки классов, а вероятности принадлежности к тому или иному классу. К примеру 5 объект практически 100% является камнем, в то время как принадлежность объекта 4 к металлу в принципе может вызывать сомнения. График ROC-кривой выглядит следующим образом

image:ada_default_roc.jpeg|link=source

Tagged AdaBoost, caret, cross validation, data mining, R, RandomForest, ROC

==ROC-кривая==

Перед введением понятия ROC-кривой необходимо предварительно объяснить из какой задачи оно появляется. Вообще, при решении проблемы классификации объекты имеют маркировку либо “Да”, либо “Нет”, и предсказаний также возможно только два, что приводит к четырём возможностям: “Да” для самого объекта и “Да” в предсказании, “Да” для самого объекта и “Нет” в предсказании и так далее. В целом, истинные значения и предсказания складываются в матрицу 2×2 (ниже пример такой матрицы для ста объектов)

|=|=”Да” объекта |=”Нет” объекта|
|=”Да” предсказания| 60| 10|
|=”Нет” предсказания| 5| 25|

Естественно, что классификатор тем лучше, чем меньше у него внедиагональных элементов. И потому достаточно часто используемой характеристикой является так называемая //accuracy// (более подробно можно прочитать http://en.wikipedia.org/wiki/Accuracy_and_precision|здесь)

//accuracy// = {количество правильно распознанных объектов} / {количество всех объектов}

В вышеприведённом примере, //accuracy// = (60 + 25)/(60 + 10 + 5 + 25) = 85%

Однако, несмотря на интуитивную понятность этой характеристики, существуют задачи, которые с её помощью решить нельзя. Допустим, что в задаче фрода нам важно не столько правильно распознать ситуации нарушения/не нарушения пользователем правил, сколько с высокой надёжностью выявить всех возможных нарушителей. Возможно, что выявленное множество будет достаточно малым, чтобы позволить дополнительную ручную проверку. В этом случае мы готовы пожертвовать точностью “Нет” предсказания ради того, чтобы точно идентифицировать все “Да” объекта, или другими словами, чтобы в вышеприведённом примере во второй строке первого столбца стоял 0 или число как можно меньшее. Но так как при этом мы всё же не хотим все объекты записывать в положительно определённые, необходимо найти какой-то баланс и эту задачу и решает ROC-кривая.

ROC расшифровывается как Receiver Operating Characteristic, т.е. рабочая характеристика приёмника и более-менее полное введение в это понятие можно прочитать на https://ru.wikipedia.org/wiki/ROC-%D0%BA%D1%80%D0%B8%D0%B2%D0%B0%D1%8F|вики. Для целей данной статьи достаточно понимать, что практически все классификаторы возвращают не метку объекта, а вероятность принадлежности объекта к тому или иному классу, то есть типичный ответ выглядит так

|=Объекты|=Вероятность “Да”|=Вероятность “Нет”|
|объект 1| 80%| 20%|
|объект 2| 49%| 51%|
|объект 3| 30%| 70%|

В этом случае для того, чтобы отнести объект к тому или иному классу, нужно выбрать какой-то порог вероятности, по которому будет происходить конечная классификация. В простейшем случае такой порог выбирается равным 50% и в этом примере объекты 2 и 3 будут промаркированы как “Нет”. Однако, с точки зрения фрода объект 2 является подозрительным и поэтому имеет смысл сдвинуть порог до 48%. Естественно, что выбирая различные пороги, будем получать разное количество правильно и неправильно определённых объектов и если нанести все точки на график, то как раз и получится ROC-кривая

image:roc_example.jpeg|link=source

Здесь по оси Y отложена //sensitivity//(чувствительность) – доля правильно идентифицированных объектов класса “Да” (в первом примере эта величина равна 60/(60 + 5) 0.92), а по оси X доля правильно идентифицированных объектов класса “Нет” (в первом примере эта величина равна 25/(25 + 10) 0.71). Как видно, чем больше правильно идентифицированных объектов класса “Да”, тем хуже определение объектов класса “Нет” и наоборот. При этом всегда есть две предельные точки, с //sensitivity// 0 и 1, соответственно когда все объекты маркируются “Нет” или все объекты маркируются “Да”. Классификатор получается тем лучше, чем сильнее ROC-кривая прижимается к верхнему левому углу, и идеальная кривая выглядит следующим образом

image:ideal_roc.jpeg|link=source

Таким образом задачей будет построение не просто классификаторов обладающих высокой //accuracy//, а классификаторов с наилучшей ROC-кривой, так как это позволит убить сразу двух зайцев: построить хороший классификатор и при этом дать возможность оптимизации классификатора под конкретную задачу. Более того, как будет показано ниже, перекалибровка результатов классификатора позволяет повысить конечную точность вычислений.

Для сравнения различных ROC-кривых используется метрика AUC – Area Under Curve (площадь под кривой), чем она больше, тем лучше ROC-кривая. Допуская некоторую вольность речи в ходе вычислений вместо AUC будет использовать слово ROC. Никакой несогласованности при этом не возникает, так как ROC-кривая означает график ROC-кривой, а число, называемое ROC обозначает площадь под этой кривой.

==Тестирование и кросс-валидация==

Одной из основных проблем различных методов классификации является переобучение, то есть ситуация, когда алгоритм настолько хорошо обучается на имеющихся данных, что производит правильную идентификацию в 100% случаев. И это было бы хорошо, но к сожалению практика показывает, что столь хорошо обученные методы начинают сильно ошибаться, когда их пытаются применить к новым данным. Это связано обычно с тем, что в исходных данных содержатся не имеющие значения шумы и попросту неправильные значения. Поэтому первый шаг, который имеет смысл сделать – это разбить исходные данные на две выборки, обучающую и проверочную. После обучения модели на обучающей выборке необходимо проверить её на проверочной выборке и в качестве меры качества обучения оценивать результаты полученные на проверочной выборке.

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

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

Подытоживая, процедура оценки эффективности алгоритмов и выбор наилучшего метода будет осуществляться по следующей схеме

# Выборка разибвается на обучающую и проверочную.
# Выбирается семейство алгоритмов и на обучающей выборке производится процедура повторной кросс-валидации. По результатам проверки выбирается наилучший алгоритм.
# Лучший алгоритм из пункта 2 проверяется на проверочной выборке и производится сравнение данных кросс-валидации с данными полученными на тестовой выборки. Если результат не устраивает, то выбирается новое семейство алгоритмов и повторяются пункты 2-3.

Tagged AdaBoost, caret, cross validation, data mining, R, RandomForest, ROC

В данной серии заметок будет показан пример построения бинарных классификаторов в R с использованием пакета caret и ROC-кривой. Основная цель состоит в понимании шагов, которые нужно совершить, чтобы получить правильный конечный результат, а также методов оценки качества построенных классификаторов и способов их улучшения. При этом предполагается базовое понимание работы с R. Все вычисления можно скачать здесь.

В самом простейшем понимании бинарный классификатор – это конструкция, которая каждому объекту по совокупности его признаков ставит в соответствие один из двух ответов: “Да” или “Нет”. Необходимость в построении бинарных классификаторов появляется достаточно часто, например в задаче определения фрода (является ли совокупность действий пользователя фродом), в задаче определения ухода пользователя из проекта (ушел или нет пользователь в зависимости от его активности на проекте) и многих других.

Бинарные классификаторы умеют строить все классификационные алгоритмы, но их количество огромно и в R существует ещё большее количество их реализаций. При этом каждый пакет имеет свои особенности построения моделей, из-за чего заблудитьсяв этом многообразии очень легко и исследователь, к сожалению, зачастую склоняется к использованию одного-двух алгоритмов, которые для него привычнее и проще использовать. С целью решения этой проблемы, Max Kuhn разработал пакет http://topepo.github.io/caret/index.html|caret, который унифицирует использование самых различных классификаторов, а также даёт достаточно мощные и универсальные методы для оценки и сравнения работы разных моделей.

Однако, прежде чем начать построение моделей, необходимо немного теории о том, что такое ROC-кривая и кросс-валидация и почему именно эти конструкции будут использованы при построении классификаторов. Те, кто знает, что это такое или кого интересуют конкретные примеры работы с R, могут пропустить http://blog.arkoniak.com/?p=270|следующую заметку и перейти сразу к http://blog.arkoniak.com/?p=280|построению классификатора.

Tagged AdaBoost, caret, cross validation, data mining, R, RandomForest, ROC

При изучении пакета для tex http://www.ctan.org/tex-archive/macros/latex/contrib/curve натолкнулся на проблему установки собранного пакета в [TEXMF] директорию, она была мне попросту неизвестна. Городить огород с собственноручно придуманными путями тоже не очень хотелось, но решение нашлось и оно оказалось достаточно простым.

Во-первых, необходимо воспользоваться утилитой //kpsepath//, которая идёт в комплекте с основной поставкой tex. Для удобства, я воспользовался командой //tr//, о которой рассказывал в http://blog.arkoniak.com/?p=221|Разделение строки на составляющие в шелле

{{{ lang=bash line=1
> kpsepath tex | tr “:” “\n”
/home/skoffer/.texlive/texmf-config/tex/kpsewhich//
/home/skoffer/.texlive/texmf-var/tex/kpsewhich//
/home/skoffer/texmf/tex/kpsewhich//
!!//etc/texmf/tex/kpsewhich//
!!//var/lib/texmf/tex/kpsewhich//
!!/usr/share/../local/share/texmf/tex/kpsewhich//
!!/usr/share/texmf-site/tex/kpsewhich//
!!/usr/share/texmf-dist/tex/kpsewhich//
/home/skoffer/.texlive/texmf-config/tex/generic//
/home/skoffer/.texlive/texmf-var/tex/generic//
/home/skoffer/texmf/tex/generic//
!!//etc/texmf/tex/generic//
!!//var/lib/texmf/tex/generic//
!!/usr/share/../local/share/texmf/tex/generic//
!!/usr/share/texmf-site/tex/generic//
!!/usr/share/texmf-dist/tex/generic//
/home/skoffer/.texlive/texmf-config/tex///
/home/skoffer/.texlive/texmf-var/tex///
/home/skoffer/texmf/tex///
!!//etc/texmf/tex///
!!//var/lib/texmf/tex///
!!/usr/share/../local/share/texmf/tex///
!!/usr/share/texmf-site/tex///
!!/usr/share/texmf-dist/tex///
}}}

Этот достаточно длинный список и есть список путей, по которым //tex// ищет пакеты. Часть из них являются системными, часть – локальными. Многократные “/” на конце не случайны и означают, что поиск будет происходить на соответствующей глубине от корневого пути. Дело в том, что стандартный пакет устроен следующим образом
{{{
[TEXMF]/tex/latex//.cls
[TEXMF]/doc/latex//.pdf
etc…
}}}

Соответственно, если есть желание поставить пакет в “/usr/share/texmf-site”, то в конечном итоге пакет будет скопирован в
{{{
/usr/share/texmf-site/tex/latex//.cls
/usr/share/texmf-site/doc/latex//.pdf
etc…
}}}

Собственно говоря на этом и всё. Выбираем любой понравившийся путь из //kpsepath//, создаем при необходимости директории и копируем файлы пакета. После этого надо обновить хэш командой
{{{ lang=bash line=1
texhash
}}}

И маленькое замечание. В случае Gentoo, директория usr/share/texmf/// будет замещаться при обновлении пакета, поэтому туда лучше ничего не устанавливать.

Tagged latex, texmf

Стандартный календарь в Ubuntu вызывается командой cal, но для русскоязычного населения вывод не очень удобен, так как недели начинаются с воскресенья. У команды ncal есть ключ “-M”, который принудительно начинает недели с понедельника, но формат вывода у неё достаточно странный. К счастью, у той же команды есть ключ “-b”, который представляет календарь в более привычном виде. Дополнительно мне нравится добавлять ключ “-3”, который показывает предыдущий и следующий месяц относительно текущего. Так что в конечном виде на алиас вешается команда
{{{ lang=bash line=1
ncal -bM3
}}}

Tagged linux, tips

При использовании вима во время написания программ на питоне может быть масса проблем, связанных с отступами. В принципе это может лечиться установкой соответствующих плагинов, но если нет желания тратить время на это, то стандартизировать отступы можно таким набором команд в .vimrc
{{{ line=1 lang=vim
autocmd BufRead,BufNewFile .py set expandtab
autocmd BufRead,BufNewFile .py set tabstop=4
autocmd BufRead,BufNewFile .py set shiftwidth=4
}}}

Если же уже имеется некоторый код, в котором перемешаны табуляции и пробелы, то привести всё к унифицированному виду (с учётом того, что нужные строки уже прописаны) можно командой

{{{ lang=vims line=1
:%retab
}}}

Tagged python, vim

Во многих языках программирования есть удобная команда split, которая позволяет разбить строку на составляющие. Для осуществления этой операции в шелле, есть удобная утилита tr, с помощью которой можно делать то же самое. Этим, например, можно пользоваться чтобы преобразовать содержимое переменной $PATH к читабельному виду

{{{ lang=bash line=1
> echo $PATH | tr “:” “\n”
/usr/local/bin
/usr/bin
/bin
/opt/bin
/usr/games/bin
}}}

Первый аргумент (в данном случае “:”) это литера которую нужно заменить, второй аргумент это литера на которую нужно заменить. В данном случае символ-разделитель отдельных элементов $PATH, заменяется на символ перевода строки, что и приводит к нужному результату.

Tagged zsh

1234


Источник: http://blog.arkoniak.com/

Matrix палитра цветов фото



Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов

Matrix палитра цветов



Меню

Главная

Витражи тиффани своими руками
Как сделать виза в лондон
Стрижка каре-боб на короткие
Стрижки для тонких и светлых волос
Как сделать прикольный
Поздравление девушку с юбилеем 35 лет
Диван и кресла разных цветов для гостиной
Смс поздравление с днем рождения друга прикольные
Заправка баллонов краской
Установка своими руками межкомнатной раздвижной двери



ЗАКРЫТЬ X