Oracle 11g R2’de SHA-256 ile Veri Hashleme

Herkese Selam,

Bu yazıda Oracle 11g R2 veritabanı üzerinde SHA-256 metodu ile veri hashleyeceğim. Umarım farkındalık anlamında faydalı bir yazı olur.

Bilindiği üzere Oracle veritabanı içerisinde şifreleme ve hashing ile ilgili bazı destekler sunuyor. Oracle’ın sunmuş olduğu bu alt yapıdan faydalanmak, bu tarz ihtiyaçlarımızın olduğu durumlarda işimizi oldukça hızlandırıyor ve etkin bir şekilde çözmemize olanak sağlıyor.

Oracle 11g R2 ile sunulan at yapıya bakacak olursak bir çok yöntemin kullanıcılara sunulduğunu görmekteyiz.

Listeye baktığımızda Oracle 11g R2 ile sunulan alt yapıda bazı yöntemlerin olmadığını görmekteyiz. Bu yöntemlerden biride SHA-256 Hashing algoritması. Oracle 12c ile bu destek var ancak elimizdeki veritabanı Oracle 11g R2 ise ve veritabanımızı upgrade etme opsiyonumuz yok ise bu yöntemi workaround bir şekilde datamız üzerine uygulayabiliriz.

Bu yöntemi uygulamak için Oracle veritabanı içerisinde Java Class yaratabilme ve bunu SQL içerisinde kullanabilme alt yapısından faydalanacağım.  Yani özet olarak veriyi hashleme işlemini, veritabanı içerisinde yazacağım bir java kodu yardımı ile yapacağım. Daha sonra bu java kodunu bir PL/SQL fonksiyonu ile wrap edip normal bir SQL fonksiyonu olarak kullanacağım.

İlk olarak SHA-256 metodunu uygulayacak Java Classını veritabanı içerisinde  yaratalım.

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED test."calcsha"
   AS import java.security.MessageDigest; 
public class calcsha2 
{
    static public String fncsha(String inputVal) throws Exception
    {           
        MessageDigest myDigest = MessageDigest.getInstance("SHA-256");        
        myDigest.update(inputVal.getBytes());
        byte[] dataBytes = myDigest.digest();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < dataBytes.length; i++) {
         sb.append(Integer.toString((dataBytes[i])).substring(1));
        }        
        
        StringBuffer hexString = new StringBuffer();
        for (int i=0;i<dataBytes.length;i++) {
            String hex=Integer.toHexString(0xff & dataBytes[i]);
                if(hex.length()==1) hexString.append('0');
                hexString.append(hex);
        }
        String retParam = hexString.toString();
        return retParam;           
    }    
}

Veritabanı içerisinde java kaynağımızı create ettik. Şimdi bu kaynağı wrap edecek PL/SQL fonksiyonunu yazalım.

CREATE OR REPLACE FUNCTION test.hash_sha256 (txt varchar2)
RETURN VARCHAR2
AS
LANGUAGE JAVA
NAME 'calcsha2.fncsha(java.lang.String) return String';

PL/SQL fonksiyonunu yazdık. Şimdi yazdığımız alt yapıyı test edebiliriz.

select hash_sha256('123456789') from dual;

HASH_SHA256('123456789')                                                        
-----------------------------------------------------------------
15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225                
1 row selected.

Evet bu örnek ile Oracle 11g R2 ile desteklenmeyen bir hashleme yöntemini workaround bir şekilde kullanmış olduk.

Advertisements
Posted in Oracle, Uncategorized | Tagged , , , , , , , , | Leave a comment

Gambler’s Ruin (Random Walk) Probleminin R ile Çözümü

Herkese Selam,

Gambler’s Ruin Problemi, yöneylem alanının araştırma konusundan biridir. Problemin hikayesi şöyledir;

Bir kumar oyuncusunun p olasılıkla 1 dolar kazandığı 1-p olasılıkla da 1 dolar kaybettiği bir oyun düşünelim. Oyuncu elinde X dolar ile bu oyunu oynamaya başlasın. Oyuncunun elindeki para N (N>X) dolara çıkarana kadar veya elinde hiç para kalmadığı duruma kadar bu oyunu oynayacaktır. Oyuncunun kazanmayı amaçladığı N değerine ulaşana kadar oyunu bırakmayacağını bildiğimize göre , oyuncunun arzu ettiği paraya (N) ulaşma ihtimali nedir?

Yukarıda hikayesini anlattığım problem, literatürde “Gambler’s Ruin” veya “Random Walk ” olarak bilinir. Bu yazıda bu problemi farklı ayarlar ile R programlama dili ile simüle edip, oyun sonuçlarının farklı ayarlar ile nasıl değiştiğini inceleyeceğim.

Bu simülasyonu yaparken kullanacağım parametreler;

  • Oyuncunun, oyuna girerken elinde bulundurduğu para.
  • Oyunun biteceği alt para limiti.
  • Oyunun biteceği üst para limiti.
  • Oyuncunun 1 dolar kazandığı durumun olasılığı. (p)
  • Yukarıda belirttiğimiz parametreler ile deneyi tekrarlama sayımız (n).

Şimdi tanımladığımız parametrelerden bir kaç senaryo üretelim ve simülasyonu bu senaryolar ile gerçekleştirelim.

Senaryo 1 :  

  • Oyuncunun, oyuna girerken elinde bulundurduğu para : $6
  • Oyunun biteceği alt para limiti: $2
  • Oyunun biteceği üst para limiti: $10
  • Oyuncunun 1 dolar kazandığı durumun olasılığı:  (p: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9) (Her olasılık değeri için oyunu ayrı ayrı oynayacağız)
  • Deneyi tekrarlama sayımız n: 100

Senaryo 2 :  

  • Oyuncunun, oyuna girerken elinde bulundurduğu para : $7
  • Oyunun biteceği alt para limiti: $1
  • Oyunun biteceği üst para limiti: $10
  • Oyuncunun 1 dolar kazandığı durumun olasılığı:  (p: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9) (Her olasılık değeri için oyunu ayrı ayrı oynayacağız)
  • Deneyi tekrarlama sayımız n: 100

Senaryo 3 :  

  • Oyuncunun, oyuna girerken elinde bulundurduğu para : $10
  • Oyunun biteceği alt para limiti: $3
  • Oyunun biteceği üst para limiti: $20
  • Oyuncunun 1 dolar kazandığı durumun olasılığı:  (p: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9) (Her olasılık değeri için oyunu ayrı ayrı oynayacağız)
  • Deneyi tekrarlama sayımız: n: 100

Yukarıda tariflediğimiz 3 temel senaryomuz var. Ancak farklı olasılık değerleri için (9) aynı senaryoyu tekrar tekrar çalıştıracağımız için, her bir senaryo toplamda 9 kez çalışacak.  Gün sonunda 9X3 = 27 farklı senaryo çalıştıracağız.

Şimdi simülasyonu yapacak R koduna geçelim. Bu simülasyonun tamamını gerçeklemek için toplam 5 fonksiyon yazacağım. Bunlar;

ReadInstances: Bu fonksiyon ile oyuncunun elindeki para miktarını ve oyunun hangi üst ve alt limitte biteceğini .csv dosyaları aracılığı ile okuma işlemini yapacağım.

Örnek dosya formatı (,Lower Limit,Upper Limit):  6,2,10

GamblerRuin: Oyunu, verilen parametreler ile 1 kez oynayan ve sonucu döndüren fonksiyon (win/loss).

Simulator: GamblerRuin fonksiyonunu tüm olası senaryoların sayısı kadar çalıştıran ve sonuçları kayıt edecek fonksiyon.

ExportResults: Simulasyon sonuçlarını dosyaya yazan fonksiyon.

Analyzer:  Dosyaya yazılan simülasyon sonuçlarını okuyup, bir tahmin ve bu tahmine bağlı hata hesaplayan fonksiyon.

Error = |Pactual-Pestimated|/Pactual

Şimdi R’da kod yazma kısmına geçebiliriz.

İlk etapta değişkenlerimiz initialize ediyoruz.

#Initializing Parameters
instancesFolder = "ProblemInstances"
options(warn = -1)
options(max.print = 100000000)
probabilities = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)
n = c(100)

Şimdi fonksiyonların yazımımına başlayabiliriz.

ReadInstances

# Function ReadInstances(input FilesFolderPaths)
# Return: DataFrame, each record in seperate files
ReadInstances <- function(instancesFolder) {
  mydata = data.frame()
  files <- as.list(list.files(path = instancesFolder))
  for (i in 1:length(files))
  {
     line <-
          read.csv(
                   paste("ProblemInstances", .Platform$file.sep, files[i], sep = ""),
                   header = F,
                   sep = ",",
                   quote = ""
                  )
        line$UL > line$currentState && line$UL > line$LL)
    {
      mydata = rbind(mydata, line)
    }
  }
  colnames(mydata) = c('currentState', 'LL', 'UL', 'fileName')
  return(as.data.frame(mydata))
}

GamblerRuin: Bu fonksiyonda oyunu bir bernoulli trial olarak gerçekleştiriyoruz. Bu olayı gerçeklemek için rbinom fonksiyonundan faydalanıyoruz.

# Function GamblerRuin(inputs currentState, UL, LL, p)
# Return: string, game result win or lose
GamblerRuin <- function(currentState, UL, LL, p) { while (currentState > LL && currentState < UL)
  {
    coin = rbinom(1, 1, p)
    
    if (coin == 1)
    {
      currentState = currentState + 1
    }
    else
    {
      currentState = currentState - 1
    }
  }
  
  if (currentState == UL)
  {
    return("win")
  }
  else  
  {
    return("lose")
  }
}

Simulator

# Function Simulator(inputs problemInstances, probabilities, n)
# Saving Scenarios and SimulationResults to Files
# Return: data frame, results of all possible scenarios (resultTable)
Simulator <- function(problemInstances, probabilities, n) {
 set.seed(0)
 resultTable = data.frame()
 scenarioID = 0
 scenarioTable = data.frame()
 
 for (instance in 1:nrow(problemInstances)) {
 for (prob in 1:as.integer(length(probabilities)))
 {
 for (j in 1:as.integer(length(n)))
 {
 scenarioID = scenarioID + 1
 scenrow = data.frame(problemInstances[instance,]$fileName,
 scenarioID,
 probabilities[prob],
 n[j])
 scenarioTable = rbind(scenarioTable, scenrow)
 
 for (k in 1:n[j])
 {
 gameResult = GamblerRuin(
 problemInstances[instance, ]$currentState,
 problemInstances[instance, ]$UL,
 problemInstances[instance, ]$LL,
 probabilities[prob]
 )
 row = data.frame(problemInstances[instance, ]$fileName,
 scenarioID,
 probabilities[prob],
 n[j],
 k,
 gameResult)
 resultTable = rbind(resultTable, row)
 }
 }
 }
 scenarioID = 0
 }
 
 
 colnames(scenarioTable) = c('instanceFileName', 'ScenarioID', 'p', 'n')
 #Save Scenario to File
 ExportResults(scenarioTable, "ScenarioFormatted.txt", 2)
 ExportResults(scenarioTable, "Scenario.txt", 1)
 
 colnames(resultTable) = c('instanceFileName',
 'ScenarioID',
 'p',
 'n',
 'ReplicationID',
 'Result')
 
 
 SimulationResults <-
 subset(resultTable,
 select = c(instanceFileName, ScenarioID, ReplicationID, Result))
 #Save SimulationResults to File
 ExportResults(SimulationResults, "SimulationResultsFormatted.txt", 2)
 ExportResults(SimulationResults, "SimulationResults.txt", 1)
 
 
 return(resultTable)
}

ExportResults

# Function ExportResults(inputs dataFrame, fileName, type)
# Saving to file (data and filename are parameters)
#type1: standart csv output, type2: formatted output
ExportResults <- function(dataFrame, fileName, type)
{
  #type1: standart csv output
  if (type == 1)
  {
    write.table(
      dataFrame,
      file = fileName,
      append = FALSE,
      quote = TRUE,
      sep = ",",
      eol = "\n",
      na = "NA",
      dec = ".",
      row.names = FALSE,
      col.names = TRUE,
      qmethod = c("escape", "double"),
      fileEncoding = ""
    )
    
  }
  else
    #type2: formatted output
  {
    capture.output(print(dataFrame, print.gap = 3, row.names = FALSE), file =
                     fileName)
  }
}

ReadFilesFromCsv <- function(fileName)
{
  myData = read.csv(fileName,
                    header = T,
                    sep = ",",
                    quote = "")
  return(myData)
}

Analyzer

# Function Analyzer()
# Read recorded files and Analysis Estimation Errors
# Saving and Plotting Result of Analysis
Analyzer <- function() {
  #Read Simulation Result
  simulationResults = ReadFilesFromCsv("SimulationResults.txt")
  
  #converting formatted data frame
  simResults = (data.frame(
    table(
      simulationResults$X.instanceFileName,
      simulationResults$X.ScenarioID,
      simulationResults$X.Result
    )
  ))
  colnames(simResults) = c('instanceFileName', 'ScenarioID', 'Result', 'Count')
  
  #Seprating "win" and "lose" records to calculating p value.(using external libarary dplyr)
  library(dplyr)
  simResults_win  =  filter(simResults, Result == as.character('"win"'))
  simResults_lose =  filter(simResults, Result == as.character('"lose"'))
  
  #Join 2 data frame and calculate p_estimated value (using sqldf external libarary)
  library(sqldf)
  simResultsWithPestimated <-
    sqldf(
      "SELECT instanceFileName,ScenarioID,
      round((cast(simResults_win.Count as real)/(simResults_lose.Count+simResults_win.Count)),3) p_estimated
      FROM simResults_win
      JOIN simResults_lose USING(instanceFileName,ScenarioID)"
    )
  
  
  #Read Scenario Result
  scenarios = ReadFilesFromCsv("Scenario.txt")
  
  #changing column name
  colnames(scenarios) = c('instanceFileName', 'ScenarioID', 'p', 'n')
  
  
  #Caclulation Percentage Error using sqldf external libarary
  library(sqldf)
  estimationErrors = sqldf(
    "SELECT instanceFileName,ScenarioID,sc.p p_actual, sim.p_estimated p_estimated,
    round(abs(cast(sc.p - sim.p_estimated as real)/ sc.p),3) PercentageError
    FROM scenarios sc
    JOIN simResultsWithPestimated sim USING(instanceFileName,ScenarioID)"
  )
  
  #dump out staging and final data frames
  ExportResults(simResultsWithPestimated,
                "SimulationResultWithPestimated.txt",
                2)
  ExportResults(estimationErrors, "estimationErrors.txt", 2)
  
  #plotting estimationErrors vector
  countOfPercentageError <- table(estimationErrors$PercentageError)
  barplot(
    countOfPercentageError,
    main = "Percentage Distribution",
    xlab = "ErrorRates",
    ylab = "Number of Counts"
  )
  
}

Tüm fonksiyonlarımızın yazımını tamamladık. Şimdi simülasyonu çalıştıracak kod parçasını yazalım ve sonuçları inceleyelim.

instances = ReadInstances(instancesFolder)
resultTable = Simulator(instances, probabilities, n)
Analyzer()
ExportResults(resultTable, 'ResultTable.txt', 2)

Kodumuz çalıştıktan sonra ürettiğimiz çıktılardan biri hangi senaryoların çalıştığı.

Üretilen bir diğer çıktı, oynanan oyunların sonuçları(sadece örnek bir küme listelenmiştir.)

Ürettilen son çıktı ise her bir senaryo için hesaplanan tahmin değerleri.

 

Aşağıdaki grafikte ise hesaplanan hatanın dağılımını görmekteyiz.

Posted in Root, Uncategorized | Tagged , , , , , , , , | Leave a comment

Apache Spark ile Oracle Veritabanından Veri Okumak

Herkese Selam,

Bu yazıda Apache Spark ile Oracle DB’ye bağlanıp doğrudan veri okuyup bir data frame’e yazacağım umarım farkındalık anlamında faydalı bir yazı olur.

Hepimizin şahit olduğu gibi günlük hayatta ürettiğimiz verinin miktarının hızlı bir şekilde artmasını takiben, Big Data teknolojileri hayatımıza çok hızlı bir şekilde giriş yaptı. Artık ihtiyaçlarımızı karşılayabilme adına geleneksel çözümleri bir kenara bırakıp işlerimizi hızlı ve etkin bir şekilde çözebilme kapasitesine sahip araçları kullanmaya başladık. Apache Spark’da bu ihtiyaçlarımızı karşılayabilen kullanımı yaygın bir teknoloji .

Apache Spark çok hızlı ve dağıtık olarak veri işleyebilen bir framework esasında. Bu yazıda Apache Spark teknolojisini ayrıntılı bir şekilde anlatmayacağım için detaylarını merak edenler aşağıdaki linkten Apach Spark ile ilgili dokümantasyona ulaşabilirler.

APACHE SPARK_DOCUMENTATION

Apache Spark ile RDBS veritabanlarımızda sakladığımız verileri işlemek için genellikle tercih edilen yöntem, işleyeceğimiz veriyi önce  hadoop ortamımıza inmek (HDFS) daha sonra dağıtık olarak hadoop’ta  (HDFS) sakladığımız veriyi okuyarak Apache Spark ile işlemek şeklinde gelişiyor.  Hadoop ekosistem deneyimi olanların iyi bildiği üzere, Hadoop ekosistemi ile diğer sistemler  (RDBMS-NOSQL) arasındaki veri alış verişini hadoop ekosisteminde entegre olan araçlardan SQOOP ile gerçekleştiriyoruz. Sqoop, kullanımı oldukça kolay, yaygın ve etkin çalışan bir veri transfer aracı.

İşleyeceğimiz veriyi RDBMS’den önce Hadoop ortamına taşımak, daha sonra buradaki veriyi Apache Spark ile işlenebilcek formata getirmenin bir miktar zahmeti bulunmakta. Özellikle HDFS’e indiğimiz veri daha sonra çok kullanılmayacaksa hem HDFS’te belli bir miktar yer tutacak hemde veri hazırlığı sürecimi uzatacaktır. Bu yöntem yerine özellikle daha sonra çok kullanılmayacak verileri hdfs’e inip orada saklamadan, doğrudan RDBMS’den okuyup kullanmanın Apache Spark ile bir yolu mevcut.

Şimdi bu işlemi nasıl yapacağımıza bakalım.

Örneğe geçmeden önce kullandığım teknolojiler ve versiyonları aşağıdaki gibidir.

Hadoop : Hadoop 2.7.1

Apache Spark: Apache Spark-2.1.0

Oracle Database : Oracle 11g R2 – Enterprise Edition

Linux : SUSE Linux

Bu işlemi yapabilmek için sistemimizde ojdbc6.jar dosyasının olması gerekmekte. Bunu indirmek için aşağıdaki linki kullanabilirsiniz.

http://www.oracle.com/technetwork/apps-tech/jdbc-112010-090769.html

İlk etapta Oracle’dan okuyacağımız tabloları veritabanında yaratalım ve içerisine örnek data koyalım.

CREATE TABLE EMP
(
   EMPNO      NUMBER,
   ENAME      VARCHAR (10),
   JOB        VARCHAR (9),
   MGR        NUMBER,
   SAL        NUMBER,
   COMM       NUMBER,
   DEPTNO     NUMBER
);

INSERT INTO EMP VALUES
(7369, 'SMITH', 'CLERK', 7902, 800, 50, 20);

INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698, 1600, 300, 30);

INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698, 1250, 500, 30);

INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839, 2975, NULL, 20);

INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698, 1250, 1400, 30);

INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839, 2850, NULL, 30);

INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839, 2450, NULL, 10);

INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566, 3000, NULL, 20);

INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL, 5000, NULL, 10);

INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698, 1500, 0, 30);

INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788, 1100, NULL, 20);

INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698, 950, NULL, 30);

INSERT INTO EMP VALUES
(7902, 'FORD', 'ANALYST', 7566, 3000, NULL, 20);

INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782, 1300, NULL, 10);

CREATE TABLE DEPT
(
   DEPTNO   NUMBER,
   DNAME    VARCHAR (14),
   LOC      VARCHAR (13)
);

INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');

COMMIT;

Şimdi Apache Spark’ı Pyspark arayüzü ile (Python Interface) linux terminalinden başlatıyoruz.

/spark-2.1.0-bin-hadoop2.7/bin/pyspark 
--jars "/home/jars/ojdbc6.jar" 
--master yarn-client 
--num-executors 10 
--driver-memory 16g 
--executor-memory 8g

Evet Apache Spark’ı başlattık. Şimdi veritabanından okuma yapacağımız Python kodunu yazalım ve çalıştıralım.

empDF = spark.read \
    .format("jdbc") \
    .option("url", "jdbc:oracle:thin:username/password@//hostname:portnumber/SID") \
    .option("dbtable", "hr.emp") \
    .option("user", "db_user_name") \
    .option("password", "password") \
    .option("driver", "oracle.jdbc.driver.OracleDriver") \
    .load()

Tablodaki veriyi empDF dataframe’ine yazdık şimdi bu dataframe’in içeriğine göz atalım.

 
empDF.printSchema()

empDF.show()

Evet görüldüğü üzere Apache Spark ile Oracle veritabanına doğrudan bağlanıp veriyi hdfs’e inmeden, işlemek için kullanıma hazırladım.

Benzer şekilde bir sorgu sonucunu da aynı şekilde almak mümkün.

query = "(select empno,ename,dname from emp, dept where emp.deptno = dept.deptno) emp"

empDF = spark.read \
    .format("jdbc") \
    .option("url", "jdbc:oracle:thin:username/password@//hostname:portnumber/SID") \
    .option("dbtable", query) \
    .option("user", "db_user_name") \
    .option("password", "password") \
    .option("driver", "oracle.jdbc.driver.OracleDriver") \
    .load()

empDF.printSchema()

empDF.show()


Yukarıda yaptığımız örneklerden de görüleceği üzere kullanımı oldukça kolay ve pratik.

Bu yöntem ile büyük boyutlu tabloları da doğrudan ve paralel bir şekilde yüklemek mümkün ancak bunun performans değerlendirmesini başka bir yazıda yapacağım.

 

Posted in Oracle, Uncategorized | Tagged , , , , , , , | Leave a comment

Oracle Data Mining ile Veri Profilleme

Herkese Selam,

Bu yazıda Oracle Data Mining ile elimizdeki bir veriyi nasıl profilleyeceğimizi göstereceğim. Umarım farkındalık anlamında faydalı bir yazı olur.

Veri profilleme bir veri kümesini anlamlandırmak için oldukça önemli bir adımdır. Genellikle bir işe başlamadan önce uğraşacağımız veri içerisinde ne tarz kolonların bulunduğunu, bu kolonların barındırdığı değerlerin hangi aralıkta dağıldığını, mininmum/maximum noktalarının neler olduğunu, ne kadar distinct değerler içerdiğini, ne kadar null kayıt bulundurduğunu bilmek veriyi kullanmadan önce yapacağımız analize ve iş sonunda üreteceğimiz faydayı doğrudan etkileyecek bilgiler olmakta. Bu nedenle bir işe başlamadan önce veriyi profillememiz oldukça önemli bir adım.

Veri profillemek için birden çok metot bulunmakta. Bunun işi gerçekleştirebilmek için kendi scriptlerinizi yazabileceğiniz gibi hazır yazılmış kütüphanelerde kullanmak mümkün. Ben bu çalışmayı hazır ve Oracle SQL Developer içerisinden kolayca uygulayabileceğim yöntemlerden biri olan Oracle Data Mining ile yapacağım.

Öncelikle Oracle SQL Developer üzerinde Oracle Data Mining penceresini açalım.

Şimdi var olan bir ODM bağlantımız üzerinden yeni bir proje ve workflow oluşturuyoruz.

Evet yeni workflow’umuzu oluşturduk ve şimdi data profile etmemiz için gerekli olan komponentleri toolbox’dan workflow’a doğru sürükleyip bırakıyoruz.

İlk olarak datasource komponentini workflow üzerine bırakalım ve datasource’umuzun ayarlarını yapalım. (Datasource komponenetineprofilleyeceğim datanın bulunduğu tabloyu gireceğim)

Datasource komponentine inceleyeceğim veri setini girdim (HR_DATA). Bu data seti seçtikten sonra bu set ile ilgili kolon ve data bilgileri, pencerenin alt kısımındaki grid de listelendi.

Şimdi data profillemeyi yapacak komponentimiz Explore Data komponentini workflow üzerine sürükleyip bırakalım ve datasource komponenti ile bağlantısını kuralım.

Evet bağlantımızı yaptıktan sonra şimdi workflow’u çalıştıralım.

Workflow’u çalıştırdıktan sonra incelediğimiz verinin boyutuna göre bu iş bir miktar sürebilir. Profillemenin bittiğini ekran üzerinden takip edebiliyoruz. Bu işlem bittikten sonra sonuçları gözlemlemek için Explore Data komponentine sağ tıklayıp View Data diyoruz.

Evet sonuç ekranında her bir veri setimizdeki  her bir kolon için ayrı bir satır kayıt bulunmakta. Veri setimizdeki her bir kolon için bazı istatistikler ve hesaplamalar yapıldığını gözlemleyebiliyoruz.  Kolon bazında  aşağıdaki sonuçlara bu ekran üzerinden ulaşabiliyoruz.

  • NULL Percent
  • Distinct Count
  • Distinct Percent
  • Mode Value
  • Average
  • Average Date
  • Median Value
  • Median Date
  • Min Value
  • Max Value
  • Standart Deviation
  • Variance
  • Skewness
  • Kurtosis
  • Histogram

Buna ek olarak açılan pencerenin Statistics tabına geçerekte kolonlar üzerindeki veri dağılımlarını görsel olarak histogramlar aracılığı ile görüntülenebiliyor.

Bu histogramlar aracılığı ile verinin hangi değerler arasında nasıl dağıldığını rahatça gözlemleyebiliyoruz.

Yapmış olduğumuz örnekten da anlaşılacağı üzere veri profilleme sonucunda olduka kullanışlı değerler elde edebiliyorum. Bu değerler üzerinden yapacağım analizler ve üreteceğim faydanın daha fazla olacağı aşikar.

Posted in Oracle, Root, Uncategorized | Tagged , , , , | Leave a comment

Oracle Data Miner ile Birliktelik Analizi

Herkese Selam,

Bu yazıda Oracle Data Mining ile bir birliktelik  (Association Rules – Market Basket Analysis ) analizi yapacağım. Umarım farkındalık anlamında faydalı bir yazı olur.

Veri Bilimi ve Makine Öğrenmesi gibi konular günümüzde hakkında çokça söz ettiren başlıkların başında gelmekte. Öğrenmesi ve uygulaması uzmanlık gerektiren bu başlıklar için adreslenen problemleri ve yöntemleri günümüzde bir çok ürün veya yazılım ile gerçekleyebilmekteyiz. Oracle’da bu başlıklar altındaki problemlerin çözümüne ilişkin yöntem ve algoritmaları DBMS_DATA_MINING paketi ile desteklemekte.

DBMS_DATA_MINING paketi ile Custering, Classification, Regression, Anomaly Detection, Feature Extraction ve Assosication gibi modeller kurup, verimizi bu modellerden geçirip yorumlayabiliyoruz. Bu modellerden elde ettiğimiz sonuçları ise business kurgularımızda input olarak kullanabilmekteyiz.

DBMS_DATA_MINING paketi Oracle veritabanı üzerinde default kurulu olarak gelmiyor. Bu nedenle bu destekten faydalanabilmek için öncelikle bu paketi kurmak gerekiyor. Aşağıdaki linki takip ederek veritabanınıza Oracle Data Mining’ı kurabilirsiniz.

https://docs.oracle.com/cd/E11882_01/datamine.112/e16807/install_odm.htm#DMADM117

Oracle Data Mining paketi kurulumu ile beraber gelen 3 yeni dictionary tablomuz bulunmakta.

SELECT * FROM  ALL_MINING_MODELS;

SELECT * FROM ALL_MINING_MODEL_SETTINGS;

SELECT * FROM ALL_MINING_MODEL_ATTRIBUTES;

ALL_MINING_MODELS tablosunda Oracle’ın bu alt yapı ile bize sunmuş olduğu tüm modeller listesi ve modeller hakkında bilgiler bulunuyor.

ALL_MINING_MODEL_SETTINGS ve ALL_MINING_MODEL_ATTRIBUTES tablolarında ise bu modeller ile ilgili parametreler ve spesifik detaylar bulunmakta.

Şimdi bu alt yapının nasıl kullanıldığını görmek için bir örnek yapalım.

Örneği yapabilmek için bir veri setine ihtiyaç duyuyorum. Örneği uygulayacağım veri setini UCI üzerinde bulunan veri setlerinden Online Retail Data Set üzerinden yapacağım.

Öncelikle Online Retail Data Set i tanıyalım.

Online Retail veri seti 8 (3 numeric, 5 string) kolondan oluşan ve içerisinde 541909 kayıt bulunduran bir veri seti. Online Retail veri setinde bulunan her bir kolonun açıklaması aşağıda verilmiştir.

Column Name Description Data Type
InvoiceNo Invoice number. Nominal, a 6-digit integral number uniquely assigned to each transaction. If this code starts with letter ‘c’, it indicates a cancellation. String
StockCode Product (item) code. Nominal, a 5-digit integral number uniquely assigned to each distinct product. String
Description Product (item) name. Nominal. String
Quantity The quantities of each product (item) per transaction. Numeric. Numeric
InvoiceDate Invice Date and time. Numeric, the day and time when each transaction was generated. Date
UnitPrice Unit price. Numeric, Product price per unit in sterling. Numeric
CustomerID Customer number. Nominal, a 5-digit integral number uniquely assigned to each customer. Numeric
Country Country name. Nominal, the name of the country where each customer resides. String

Evet veri setimiz ile ile ilgili detaylara baktıktan sonra indirdiğimiz veri setini Oracle veritabanımıza yükleyelim.

Öncelikle indirdiğimiz veri setini (.xls) yükleyeceğimiz Oracle tablosunu yaratalım.

CREATE TABLE ONLINE_RETAIL
(
  INVOICENO    VARCHAR2(100 BYTE),
  STOCKCODE    VARCHAR2(100 BYTE),
  DESCRIPTION  VARCHAR2(200 BYTE),
  QUANTITY     NUMBER,
  INVOICEDATE  DATE,
  UNITPRICE    NUMBER,
  CUSTOMERID   NUMBER,
  COUNTRY      VARCHAR2(100 BYTE)
);

Tablomuzu yarattık, şimdi .xls olarak indirdiğimiz veri setimizi içeriye yükleyeceğiz, bunu yapmak için birden çok yöntemimiz bulunuyor. Bunlardan bazıları;

  • Oracle External Table yardımı ile yüklemek.
  • Oracle SQL Loader kullanarak yüklemek.
  • Kullandığımız editörlerden faydalanarak yüklemek.

Ben veri setini kullandığım editör yardımı ile yükleyeceğim. Editör olarak Toad kullanmaktayım. Toad ile aşağıdaki yolu takip ederek yükleme işlemini gerçekleştirebilirsiniz.

Database –> Import –> Import Table Data 

Toad ürünü ücretli olduğu için bu editörü kullanıyor olabilirsiniz. Ancak diğer editörlerin de bu özelliği mevcut, diğer editörlerle de bu işlemi kolaylıkla yapabilirsiniz. Örneğin ücretsiz olan Oracle SQL Developer ile veri yüklemesini aşağıdaki gibi yapabilirsiniz.

SELECT * FROM ONLINE_RETAIL;

Evet veri seti yükleme işlemini tamamladık.

Veriyi gözlemlediğimizde müşterilerin yaptığı alış verişlere ait detayları görmekteyiz. Her bir satırda hangi üründen alındığı,  ne kadar alındığı, bu ürünün kim tarafından aldığı, hangi tarihte aldığı, fiyatının ne kadar olduğu ve hangi ülkeden yapıldığına ait bilgiler bulunuyor. Ayrıca her bir satırda bulunan InvoiceNo bilgisi de o ürünün hangi fatura ile satıldığını göstermekte.  Veriyi detaylı incelediğimizde aynı InvoiceNo ya ait bir veya birden çok kayıt olduğunu da gözlemliyoruz. Müşterinin herhangi bir alış verişine ait satın almış olduğu tüm ürünleri InvoiceNo üzerinden görüntüleyebiliriz. Yani InvoiceNo bilgisini ilgili alış verişe ait bir sepet gibi düşünebiliriz.

Şimdi örnek bir alış verişe ait sepeti görüntüleyelim.

SELECT * FROM ONLINE_RETAIL WHERE INVOICENO = '536368';

Evet örnek bir alış veriş sepetimizi gördük. Şimdi bu veriden birliktelik analizi yaparak birlikte en çok satılan ürünleri tespit edelim.

Birliktelik analizine başlamadan önce konunun daha iyi anlaşılması için kullanılan algoritma hakkında biraz bilgi vereceğim.

DBMS_DATA_MINING paketi birliktelik analizini APRIORI algoritması ile gerçeklemekte.  Bu algoritmayı kullanmak içinse bizim bazı parametreleri tanımlamamız gerekiyor. Bu parametreler ve parametrelere ait default değerler aşağıdaki gibidir;

 Algoritma parametrelerini ve ne anlama geldiklerini daha detaylı anlayabilmek için linkteki makale incelenebilir.

Şimdi model ayarlarını okuyacağımız tabloyu oluşturalım ve içerisine algoritma parametrelerini insert edelim.

CREATE TABLE SETTINGS_ASSOCIATION_RULES
AS
   SELECT *
     FROM TABLE (DBMS_DATA_MINING.GET_DEFAULT_SETTINGS)
    WHERE SETTING_NAME LIKE 'ASSO_%';


BEGIN
   UPDATE SETTINGS_ASSOCIATION_RULES
      SET SETTING_VALUE = 3
    WHERE SETTING_NAME = DBMS_DATA_MINING.ASSO_MAX_RULE_LENGTH;
    
   UPDATE SETTINGS_ASSOCIATION_RULES
      SET SETTING_VALUE = 0.03
    WHERE SETTING_NAME = DBMS_DATA_MINING.ASSO_MIN_SUPPORT;
    
       UPDATE SETTINGS_ASSOCIATION_RULES
      SET SETTING_VALUE = 0.03
    WHERE SETTING_NAME = dbms_data_mining.asso_min_confidence;

   INSERT INTO SETTINGS_ASSOCIATION_RULES
        VALUES (DBMS_DATA_MINING.ODMS_ITEM_ID_COLUMN_NAME, 'STOCKCODE');

   COMMIT;
END;

Evet algoritma parametrelerimizi okuyacağımız tabloyu oluşturduk. Şimdi modelimizi oluşturma adımına geçebiliriz.

CREATE VIEW VW_ONLINE_RETAIL AS SELECT INVOICENO,STOCKCODE FROM ONLINE_RETAIL;

BEGIN 
   DBMS_DATA_MINING.CREATE_MODEL(
      model_name            => 'MD_ASSOC_ANLYSIS',
      mining_function       =>  DBMS_DATA_MINING.ASSOCIATION,
      data_table_name       => 'VW_ONLINE_RETAIL',
      case_id_column_name   => 'INVOICENO',
      target_column_name    =>  NULL,
      settings_table_name   => 'SETTINGS_ASSOCIATION_RULES');
END;

Modelimiz oluştu, şimdi modelimiz ile ilgili oluşan detaylara dictionary’den bakalım.

SELECT MODEL_NAME,
       ALGORITHM,
       COMMENTS,
       CREATION_DATE,
       MINING_FUNCTION,
       MODEL_SIZE
  FROM ALL_MINING_MODELS
 WHERE MODEL_NAME = 'MD_ASSOC_ANLYSIS';

SELECT SETTING_NAME, SETTING_VALUE
FROM ALL_MINING_MODEL_SETTINGS
WHERE MODEL_NAME = 'MD_ASSOC_ANLYSIS';

Şimdi analizim sonucunda oluşan çıktılara bakalım.

SELECT RULE_ID,
       B.ATTRIBUTE_SUBNAME ANTECEDENT_STOCKCODE,
       C.ATTRIBUTE_SUBNAME CONSEQUENT_STOCKCODE,
       RULE_SUPPORT,
       RULE_CONFIDENCE
  FROM TABLE (DBMS_DATA_MINING.GET_ASSOCIATION_RULES ('MD_ASSOC_ANLYSIS')) A,
       TABLE (A.ANTECEDENT) B,
       TABLE (A.CONSEQUENT) C;


Algoritmaya verdiğimiz parametreler ile oluşturduğumuz model sonucunda beraber satılma oranı yüksek olan ürünlere ulaştık ve görüntüledik.
Algoritma parametrelerinde değişiklik yapılarak daha farklı analizlerde yapmak mümkün.

Posted in Oracle, Root, Uncategorized | Tagged , , , , , , , , , | Leave a comment

Oracle 18c Sürümünü Duyurdu

Herkese Selam,

Geçtiğimiz hafta boyunca Oracle’ın Dünya çapındaki en büyük etkinliği Oracle Open World 2017, San Francisco’da gerçekleşti. Yine Dünyanın dört bir yanından katılan binlerce katılımı ile gerçekleşen bu etkinlikte yine birbirinden önemli duyurular yapıldı.

Bu duyuruların ve haberlerin en önemlisi keynote oturumunda Oracle’ın CTO’su ve kurucusu Larry Ellison tarafından yapıldı. Duyurulan yenilik Oracle’ın bir sonraki veritabanı sürümü olan Oracle 18c ‘idi. Sürüm numarası olarak 12’den 18’e atlanması ilginç bir detay olarak kalsa da Oracle 18c çarpıcı özellikler ile geliyor.

Oracle 18c ile ilgili atılacak en büyük başlaık Oracle’ında ana özellik olarak duyurduğu “Autononomous Database” özelliği. Otonom veri tabanının en büyük özelliği olarak Oracle, veri tabanı yönetimi konusunda harcanan insan eforunu bir otomasyona çevirerek, bu tarafta harcanan insan gücünden  tasarruf etme ve insan gücünün yapma ihtimali olan hataların ortadan kaldırılmasına yönelik pozitif katkıların olacağını belirtti. Otonom veritabanı özellikleri ile beraber artık daha düşük veri tabanı yönetim maliyeti ile daha güvenli, daha performanslı ve daha erişilebilir bir veritabanı oluşturulması hedefleniyor.

Oracle 18c veritabanı otonomluğu ile aşağıdaki özelliklere sahip olması bekleniyor.

Self Driving:  Makine öğrenmesine dayalı sürekli olarak adaptif performans iyileştirmelerinin yapılacağı bir sistem planlanıyor. Veritabanı aynı zamanda otomatik olarak güncellemeleri alarak gerektiğinde otomatik olarak yeni patchleri kurabilecek. Buna ek olarak siber saldırılara karşı koruma sağlamak için otomatik olarak güvenlik güncellemelerini de yapması amaçlanıyor..

Self Scaling: Sistemde herhangi bir downtime olmadan depolama ve işlem gücünün otomatik olarak ayarlanması sağlanacak. Resource tüketiminin ihtiyaca göre ayarlanması maddi giderleri oldukça azaltarak rakiplerine karşı büyük avantaj sağlamayı hedefliyor.

Self Repearing: Oracle yeni sürümü ile beraber %99.995 oranında SLA’leri tuturarak downtime’lara karşı sistemi koruyacak. Ayrıca planlanmamış ve yaşanması olası olan downtime süresinin yılda 30 dakikadan daha fazla olmaması öngörülüyor.

Oracle’ın ilk otonom veritabanı opsiyonu olarak “Oracle Autonomous Data Warehouse Cloud” piyasaya sürecek. Oracle’ın açıklamasına göre bu yıl içerisinde bu sürüm kullanıma hazır olacak.

Oldukça iddialı söylemler ve özellikler ile duyurulan Oracle 18c ‘nin sahada neler göstereceği şimdiden merak konusu.

Posted in Oracle, Uncategorized | Tagged , , , , , | Leave a comment

DBMS_DATA_MINING ile Classification Problemi Çözmek

Herkese Selam,

Bu yazıda Oracle Data Mining ile bir classification problemi çözeceğim. Umarım farkındalık anlamında faydalı bir yazı olur.

Veri Bilimi ve Makine Öğrenmesi gibi konular günümüzde hakkında çokça söz ettiren başlıkların başında gelmekte. Öğrenmesi ve uygulaması uzmanlık gerektiren bu başlıklar için adreslenen problemleri ve yöntemleri günümüzde bir çok ürün veya yazılım ile gerçekleyebilmekteyiz. Oracle’da bu başlıklar altındaki problemlerin çözümüne ilişkin yöntem ve algoritmaları DBMS_DATA_MINING paketi ile desteklemekte.

DBMS_DATA_MINING paketi ile Custering, Classification, Regression, Anomaly Detection, Feature Extraction ve Assosication gibi modeller kurup, verimizi bu modellerden geçirip yorumlayabiliyoruz. Bu modellerden elde ettiğimiz sonuçları ise business kurgularımızda input olarak kullanabilmekteyiz.

DBMS_DATA_MINING paketi Oracle veritabanı üzerinde default kurulu olarak gelmiyor. Bu nedenle bu destekten faydalanabilmek için öncelikle bu paketi kurmak gerekiyor. Aşağıdaki linki takip ederek veritabanınıza Oracle Data Mining’ı kurabilirsiniz.

https://docs.oracle.com/cd/E11882_01/datamine.112/e16807/install_odm.htm#DMADM117

Oracle Data Mining paketi kurulumu ile beraber gelen 3 yeni dictionary tablomuz bulunmakta.

SELECT * FROM  ALL_MINING_MODELS;

SELECT * FROM ALL_MINING_MODEL_SETTINGS;

SELECT * FROM ALL_MINING_MODEL_ATTRIBUTES;

ALL_MINING_MODELS tablosunda Oracle’ın bu alt yapı ile bize sunmuş olduğu tüm modeller listesi ve modeller hakkında bilgiler bulunuyor.

ALL_MINING_MODEL_SETTINGS ve ALL_MINING_MODEL_ATTRIBUTES tablolarında ise bu modeller ile ilgili parametreler ve spesifik detaylar bulunmakta.

Şimdi bu alt yapının nasıl kullanıldığını görmek için bir örnek yapalım.

Örneği yapabilmek için bir veri setine ihtiyaç duyuyorum. Örneği uygulayacağım veri setini www.kaggle.com üzerinde bulunan veri setlerinden HR_ANALYTICS veri seti üzerinden yapacağım.

Öncelikle HR_ANALYTICS veri setini tanıyalım.

HR_ANALYTICS veri seti 10 (8 numeric, 2 string) kolondan oluşan ve içerisinde 15.000 kayıt bulunduran bir veri seti. HR_ANALYTICS veri setinde bulunan her bir kolonun açıklaması aşağıda verilmiştir.

Column Name Description Data Type
satisfaction_level Level of satisfaction (0-1) Numeric
last_evaluation Time since last performance evaluation (in Years) Numeric
number_project Number of projects completed while at work Numeric
average_montly_hours Average monthly hours at workplace Numeric
time_spend_company Number of years spent in the company Numeric
Work_accident Whether the employee had a workplace accident Numeric
left Whether the employee left the workplace or not (1 or 0) Factor Numeric
promotion_last_5years Whether the employee was promoted in the last five years Numeric
sales Department in which they work for String
salary Relative level of salary (high) String

Kaynak

Evet veri setimiz ile ile ilgili detaylara baktıktan sonra indirdiğimiz veri setini Oracle veritabanımıza yükleyelim.

Öncelikle indirdiğimiz veri setini (.csv) yükleyeceğimiz Oracle tablosunu yaratalım.

CREATE TABLE hr_data
(
   satisfaction_level      NUMBER,
   last_evaluation         NUMBER,
   number_project          NUMBER,
   average_montly_hours    NUMBER,
   time_spend_company      NUMBER,
   Work_accident           NUMBER,
   left                    NUMBER,
   promotion_last_5years   NUMBER,
   sales                   VARCHAR2 (20),
   salary                  VARCHAR2 (20)
);

Tablomuzu yarattık, şimdi .csv olarak indirdiğimiz veri setimizi içeriye yükleyeceğiz, bunu yapmak için birden çok yöntemimiz bulunuyor. Bunlardan bazıları;

  • Oracle External Table yardımı ile yüklemek.
  • Oracle SQL Loader kullanarak yüklemek.
  • Kullandığımız editörlerden faydalanarak yüklemek.

Ben veri setini kullandığım editör yardımı ile yükleyeceğim. Editör olarak Toad kullanmaktayım. Toad ile aşağıdaki yolu takip ederek yükleme işlemini gerçekleştirebilirsiniz.

Database –> Import –> Import Table Data 

Toad ürünü ücretli olduğu için bu editörü kullanıyor olabilirsiniz. Ancak diğer editörlerin de bu özelliği mevcut, diğer editörlerle de bu işlemi kolaylıkla yapabilirsiniz. Örneğin ücretsiz olan Oracle SQL Developer ile veri yüklemesini aşağıdaki gibi yapabilirsiniz.

SELECT * FROM HR_DATA;

Evet veri seti yükleme işlemini tamamladık. Şimdi veriyi hangi kolona göre sınıflandıracağımızı belirleyelim.

Veri setimizi incelediğimizde her bir çalışan ile ilgili bir takım bilgiler var olduğunu görüyoruz. Bu bilgilerin en sonunda ise bu çalışanın maaşı (SALARY) ile ilgili bir bilgi verilmiş (low-medium-high). Biz elimizdeki verinin bir kısmı (training set) ile üreteceğimiz sınıflandırma modeli ile, verinin kalan kısmının (test set) maaş (SALARY) kolonu hakkında bir sınıflandırma sonucu üreteceğiz.  Son olarak ise kurduğumuz model ile ürettiğimiz sonuçlar ile  gerçek sonuçlara bakıp karşılaştıracağız.

Öncelikle verimizi eğitim (training %70) ve test (%30) olarak 2 ayrı kümeye ayıralım.

CREATE TABLE HR_DATA_MAIN AS
SELECT *
  FROM (SELECT ROWNUM RN,
               SATISFACTION_LEVEL,
               LAST_EVALUATION,
               NUMBER_PROJECT,
               AVERAGE_MONTLY_HOURS,
               TIME_SPEND_COMPANY,
               WORK_ACCIDENT,
               LEFT,
               PROMOTION_LAST_5YEARS,
               SALES,
               SALARY
          FROM HR_DATA); 
          
          

CREATE TABLE HR_DATA_TRAINING
AS
   SELECT SATISFACTION_LEVEL,
          LAST_EVALUATION,
          NUMBER_PROJECT,
          AVERAGE_MONTLY_HOURS,
          TIME_SPEND_COMPANY,
          WORK_ACCIDENT,
          LEFT,
          PROMOTION_LAST_5YEARS,
          SALES,
          SALARY
     FROM HR_DATA_MAIN
    WHERE RN < 10500;


CREATE TABLE HR_DATA_TEST
AS
   SELECT SATISFACTION_LEVEL,
          LAST_EVALUATION,
          NUMBER_PROJECT,
          AVERAGE_MONTLY_HOURS,
          TIME_SPEND_COMPANY,
          WORK_ACCIDENT,
          LEFT,
          PROMOTION_LAST_5YEARS,
          SALES,
          SALARY
     FROM HR_DATA_MAIN
    WHERE RN >= 10500; 

Eğitim ve test veri setimizi hazırladık. Şimdi algoritma ayarlarını okuyacağımız tablomuzu oluşturalım ve bu tabloya kullanacağımız algoritma parametrelerini girelim. Algoritmanın çalışması için gerekli tüm parametreleri girmek durumunda değiliz, opsiyonel olan parametreleri tanımlamadığımız takdirde Oracle bu parametreleri sistemde default tanımlı değerleri ile kullanmakta. Aşağıdaki tabloda Decision Tree algoritması için tanımlı parametreleri ve bu parametrelerin default değerlerini bulabilirsiniz.

KAYNAK

CREATE TABLE DTSETTINGS
(
   SETTING_NAME    VARCHAR2 (200),
   SETTING_VALUE   VARCHAR2 (200)
);


BEGIN
INSERT INTO DTSETTINGS
VALUES ('ALGO_NAME', 'ALGO_DECISION_TREE');

INSERT INTO DTSETTINGS
VALUES (dbms_data_mining.tree_impurity_metric, 'TREE_IMPURITY_ENTROPY');

COMMIT;
END;

Veri setimizi eğitim ve test olarak ayırdık, ardından algoritma ayarlarımızı oluşturduk. Şimdi modelimizi oluşturma adımına geçebiliriz.
(Eğitim için ayırdığımız veri setinin bulunduğu tablo adını ve algoritma parametrelerini kullanmak için oluşturduğumuz tablo adını DBMS_DATA_MINING.CREATE_MODEL metoduna parametre olarak gönderiyoruz.)

BEGIN
   DBMS_DATA_MINING.CREATE_MODEL (
      model_name            => 'DT_MODEL',
      mining_function       => DBMS_DATA_MINING.CLASSIFICATION,
      data_table_name       => 'HR_DATA_TRAINING',
      case_id_column_name   => NULL,
      target_column_name    => 'SALARY',
      settings_table_name   => 'DTSETTINGS');
END;

Modelimiz oluştu, şimdi modelimiz ile ilgili oluşan detaylara dictionary’den bakalım.

SELECT MODEL_NAME,
       ALGORITHM,
       COMMENTS,
       CREATION_DATE,
       MINING_FUNCTION,
       MODEL_SIZE
  FROM ALL_MINING_MODELS
 WHERE MODEL_NAME = 'DT_MODEL';

SELECT SETTING_NAME, SETTING_VALUE
FROM ALL_MINING_MODEL_SETTINGS
WHERE MODEL_NAME = 'DT_MODEL';

Modelimiz ile ilgili oluşmuş detayları da gördükten sonra şimdi modelimizi kullanarak test veri setimiz üzerinden prediction yapabiliriz.

SELECT T.SALARY ACTUAL,
 PREDICTION (DT_MODEL USING *) MODEL_PREDICT_RESPONSE,
 PREDICTION_PROBABILITY (DT_MODEL USING *) MODEL_PROBABILTY_RESPONSE
FROM HR_DATA_TEST T;

Evet test veri setimize modelimizi uyguladık ve modelimizin ürettiği tahminleri gözlemledik.

Kurduğumuz modelin başarımını kendimiz hesaplayabileceğimiz gibi DBMS_DATA_MINING.COMPUTE_CONFUSION_MATRIX metodu ile de hesaplayabiliriz.

DBMS_DATA_MINING.COMPUTE_CONFUSION_MATRIX (
      accuracy                     OUT NUMBER,
      apply_result_table_name      IN  VARCHAR2,
      target_table_name            IN  VARCHAR2,
      case_id_column_name          IN  VARCHAR2,
      target_column_name           IN  VARCHAR2,
      confusion_matrix_table_name  IN  VARCHAR2,
      score_column_name            IN  VARCHAR2 DEFAULT 'PREDICTION',
      score_criterion_column_name  IN  VARCHAR2 DEFAULT 'PROBABILITY',
      cost_matrix_table_name       IN  VARCHAR2 DEFAULT NULL,
      apply_result_schema_name     IN  VARCHAR2 DEFAULT NULL,
      target_schema_name           IN  VARCHAR2 DEFAULT NULL,
      cost_matrix_schema_name      IN  VARCHAR2 DEFAULT NULL,
      score_criterion_type         IN  VARCHAR2 DEFAULT 'PROBABILITY');

DBMS_DATA_MINING.COMPUTE_CONFUSION_MATRIX metodunun kullanımına ait detaylı açıklamaları linke tıklayarak ulaşabilirsiniz.

Posted in Oracle, Uncategorized | Tagged , , , , , , , , | Leave a comment