Giter VIP home page Giter VIP logo

Comments (2)

MarcinKosinski avatar MarcinKosinski commented on September 13, 2024

Przepisać tę motywację do winietki

Ale po co w ogóle taki projekt i pakiet?

Selekcja zmiennych w modelach klasyfikacyjnych i regresyjnych, to wciąż aktywne pole badań.
Co chwila powstają nowe pakiety, narzędzia i metody, które są coraz bardziej skomplikowane i skuteczniejsze.

Metody selekcji oparte na entropii nie są nowymi metodami (pierwsza wersja na CRAN pojawiłą się już w 2009 roku https://cran.r-project.org/src/contrib/Archive/FSelector/).
Nie są to nawet metody skomplikowane, ale czasami są to jedyne narzędzia, z których analityk może skorzystać, gdy analiza powinna być zrobiona 'na wczoraj' i nie ma czasu uruchamiać algorytmu Boruta czy jednego z dostępnych w pakiecie caret, których wyniki otrzymalibyśmy dopiero po kilku dniach. Gdy analiza ma być zrobiona na za 3 godziny, to czasem prosta metoda jest jedyną dostępną formą ,z racji na szybkość działania wynikającą z jej prostoty.

O co chodzi z entropią?

O entropii napisano już wiele (mi osobiście ostatnio spodobał się ten wpis http://www.deltami.edu.pl/temat/matematyka/rachunek_prawdopodobienstwa/2015/10/23/Prawdopodobienstwo_a_informacja/). Ja rozumiem entropię jako miarę dającą nam informacje o pewności rozkładu pewnej zmiennej losowej. Im mniejsza (monotoniczność jest tutaj wspaniałą cechą), tym jesteśmy bardziej pewni jakie wartości (i z jakim prawdopodobieństwem) może przyjmować zmienna losowa. Gdyby rozważać entropię warunkową jednej zmiennej względem drugiej, której wartości są nam znane, to można wykorzystać entropię warunkową jako miarę zaleźności między zmienną której wartości znamy a drugą, której wartości chcemy móc przewidywać. Obecnie pakiet FSelector korzysta z pakietu entropy do wyliczania entropii (https://cran.r-project.org/web/packages/entropy/index.html).

Jakie metody?

Pakiet FSelector udostępnia wiele metod selekcji zmiennych (help(package = "FSelector")), ale problem jaki z nim jest opiszę na podstawie funkcji information.gain, która wykorzystuję metodę wielokrokową wstępującą opartą na entropii w poniższych wersjach (gdzie H to entropia)

  • information.gain - H(Class) + H(Attribute) - H(Class, Attribute)
  • gain.ratio - (H(Class) + H(Attribute) - H(Class, Attribute)) / H(Attribute)
  • symmetrical.uncertainty - 2 * (H(Class) + H(Attribute) - H(Class, Attribute)) / (H(Attribute) + H(Class))

Metoda selekcji przebiega na zasadzie:

  • w pierwszym kroku stwórz modele z jedną zmienną i wylicz jedną z wyżej wymienionych statystyk
  • wybierz model, który daje największą (albo najmniejszą-teraz nie jestem pewny) z nich
  • zmienna z wybranego modelu zostaje uznana za zaakceptowaną w procesie selekcji
  • w kolejnym kroku stwórz modele z wybraną zmienną i jedną dodatkową
  • wylicz statystyki
  • jeżeli któryś model z obecnie dwoma zmiennymi, ma wyższą statystykę to zaakceptuj drugą zmienną (nową w tym modelu) i kontynuuj procesm
    a jeżeli nie, to przerwij proces

Metoda prosta i wygląda jakby dało się ją łatwo zrównoleglić.

Ale jakie są problemy z FSelector'em,

Gdyby zajrzeć do wnętrza funkcji information.gain

> FSelector:::information.gain.body
function (formula, data, type = c("infogain", "gainratio", "symuncert"))
{
    type = match.arg(type)
    new_data = get.data.frame.from.formula(formula, data)   - tutaj wejściowe dane przerabiane są na ramkę danych i reorganizowane by atrybut był w    pierwszej kolumnie, sic! tutaj w pętli następuje też konwersja typów (więcej o masakrze tu: https://github.com/larskotthoff/fselector/issues/3)
    new_data = discretize.all(formula, new_data) - tutaj zmienne ciągłe są dyskretyzowane wg. kwantyli rzędu 0, 0.2, 0.4, 0.6, 0.8, 1 i nie da się zmienić liczby grup ani kwantyli, sic ! a w ogóle na początku znowu wywoływana jest funkcja (new_data = get.data.frame.from.formula(formula, data)) -> można to łatwo poprawić - https://github.com/MarcinKosinski/fselector/commit/494ad50c5b37946e4187159d924d31244e790ce7#diff-c83bdf369b2a9527932b646b68d7eed9 https://github.com/MarcinKosinski/fselector/commit/797ec8e513dc4662a5f54c6421d1a37ad13aa09c
    attr_entropies = sapply(new_data, entropyHelper) - sapply, a przecież można lepiej, a jest jeszcze wiele nieprzemyślanych for'ów
  1. to największym jej minusem jest to, że nie wspiera macierzy rzadkich, gdyż każdy input przerabia na zwykłą macierz/ramkę danych (problem opisałem też tutaj larskotthoff/fselector#1).
  2. problemem są założenia autora co do formy danych i usilnie stara się przerobić wszystkie dane na factory, nawet gdy one tymi factorami już są
  3. kod ma wiele sztywnych parametrów jak discretize.all, które można by udostępnić użytkownikom

Więcej problemów

  1. Pakiet korzysta z RWeki, która wymaga rJavy, a instalacje jej i konfiguracja jest wielkim problemem pod windowsem, a w wielu wypadkach praca z rJavą wymaga zwiększenia heap.space/limitu-pamięcie Javy powyżej ustawionego domyślnie limitu 512 MB. (options( java.parameters = "-Xmx4g" )) . Nie jest to wygodne, jasne, ani nigdzie opisane, a raczej R to narzędzie dla statystyków i biologów niż dla profesjonalnych wyjadaczy Javy.
  2. W wielu miejscach metody selekcji dałoby się zrównoleglić chociażby funkcją mclapply (pod linuxem) parLalpply (pod windowsem) zamiast sapply, a fory chociażby zamienić na foreach'e
  3. Większość kodu napisane jest w R, a w dzisiejszych czasach można skorzystać z dobrodziejstwa Rcpp (https://cran.r-project.org/web/packages/Rcpp/index.html) a nawet RcppParallel (https://github.com/RcppCore/RcppParallel sic^2!).

FSelector jest piękny

Na małych danych pakiet działa świetnie i udostępnia możliwość wprowadzania własnych kryteriów akceptacji zmiennych objaśnianych w procedurze wielokrokowej, jak chociażby

library(rpart)
  data(iris)

  evaluator <- function(subset) {
    #k-fold cross validation
    k <- 5
    splits <- runif(nrow(iris))
    results = sapply(1:k, function(i) {
      test.idx <- (splits >= (i - 1) / k) & (splits < i / k)
      train.idx <- !test.idx
      test <- iris[test.idx, , drop=FALSE]
      train <- iris[train.idx, , drop=FALSE]
      tree <- rpart(as.simple.formula(subset, "Species"), train)
      error.rate = sum(test$Species != predict(tree, test, type="c")) / nrow(test)
      return(1 - error.rate)
    })
    print(subset)
    print(mean(results))
    return(mean(results))
  }

  subset <- best.first.search(names(iris)[-5], evaluator)
  f <- as.simple.formula(subset, "Species")
  print(f)

gdzie evaluator jest funkcją, która w procesie kross-walidacji 5-ciokrokowej zwraca średni błąd poprawnej klasyfikacji dla kolejnych zestawów zmiennych w drzewie klasyfikacyjnym i wybiera ten model który uzyska najmniejszy średni błąd. Mnie to urzekło, ale zabrakło mi wsparcia macierzy rzadkich, przyspieszonego kodu z C++, wciąż odpycha mnie konfiguracja Javy podczas instalacji, brakuje zrównoleglenia a kod po przejrzeniu nie jest optymalny.

Gdyby dalej interesowało Was przepisanie tego pakietu od nowa, albo nawet z wieloma udogodnieniami i nowymi pomysłami, to zapraszam do współpracy.

Przyda się umieć, ale można się też tego uczyć w trakcie:

from fselectorrcpp.

MarcinKosinski avatar MarcinKosinski commented on September 13, 2024

Ok this is not an issue that can be solved.
This is my personal goal.

from fselectorrcpp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.