Oracle Data Mining ile Regreson Uygulaması

Herkese Selam,

Bu yazıda Oracle Data Mining ile basit bir regresyon (Regression) 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, kaggle üzerinde bulunan veri setlerinden Boston Housing üzerinde yapacağım.

Öncelikle Boston Housing veri setini tanıyalım.

Column Name Description Data Type
crim per capita crime rate by town. Number
zn proportion of residential land zoned for lots over 25,000 sq.ft. Number
indus proportion of non-retail business acres per town. Number
chas Charles River dummy variable (= 1 if tract bounds river; 0 otherwise). Number
nox nitrogen oxides concentration (parts per 10 million). Number
rm average number of rooms per dwelling. Number
age proportion of owner-occupied units built prior to 1940. Number
dis weighted mean of distances to five Boston employment centres. Number
rad index of accessibility to radial highways. Number
tax full-value property-tax rate per \$10,000. Number
ptratio pupil-teacher ratio by town. Number
black 1000(Bk – 0.63)^2 where Bk is the proportion of blacks by town. Number
lstat lower status of the population (percent). Number
medv median value of owner-occupied homes in \$1000s. Number

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 (training.csv) yükleyeceğimiz Oracle tablosunu yaratalım.

CREATE TABLE BOSTON_HOUSING
(
   ID        NUMBER,
   CRIM      NUMBER,
   ZN        NUMBER,
   INDUS     NUMBER,
   CHAS      NUMBER,
   NOX       NUMBER,
   RM        NUMBER,
   AGE       NUMBER,
   DIS       NUMBER,
   RAD       NUMBER,
   TAX       NUMBER,
   PTRATIO   NUMBER,
   BLACK     NUMBER,
   LSTAT     NUMBER,
   MEDV      NUMBER
);

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 BOSTON_HOUSING;

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

Veriyi gözlemlediğimizde evlerin çeşitli özelliklerine göre detayları görmekteyiz. Her bir satırda ilgili evin spesifik özelliklerine ait bilgiler bulunuyor. Regresyon analizine girecek temel parametrelerimiz bu tablodaki gibi. Bu tabloda regresyon analizi sonucu tahminleyeceğimiz değer ise en sondaki MEDV kolonu. MEDV kolonu bu analizde kullanacağımız target değişkeni.

Regresyon 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 Generalized Linear Model algoritması ile gerçeklemekte.  Bu algoritmayı kullanmak içinse bizim bazı parametreleri tanımlamamız gerekiyor. Bu parametreler aşağıdaki gibidir;

Şimdi algoritma ayarlarını okuyacağımız tabloyu yaratalım.

 

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

BEGIN
   INSERT INTO SETTINGS_GLM
        VALUES (DBMS_DATA_MINING.ALGO_NAME, 'ALGO_GENERALIZED_LINEAR_MODEL');

   INSERT INTO SETTINGS_GLM
        VALUES (DBMS_DATA_MINING.PREP_AUTO, 'ON');

   INSERT INTO SETTINGS_GLM
        VALUES (
                  DBMS_DATA_MINING.GLMS_RIDGE_REGRESSION,
                  'GLMS_RIDGE_REG_DISABLE');

   INSERT INTO SETTINGS_GLM
        VALUES (
                  DBMS_DATA_MINING.ODMS_MISSING_VALUE_TREATMENT,
                  'ODMS_MISSING_VALUE_MEAN_MODE');

   COMMIT;
END;

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

CREATE OR REPLACE VIEW VW_BOSTON_HOUSING AS SELECT * FROM BOSTON_HOUSING;

BEGIN 
   DBMS_DATA_MINING.CREATE_MODEL(
      model_name            => 'MD_GLM_MODEL',
      mining_function       =>  DBMS_DATA_MINING.REGRESSION,
      data_table_name       => 'VW_BOSTON_HOUSING',
      case_id_column_name   => 'ID',
      target_column_name    =>  'MEDV',
      settings_table_name   => 'SETTINGS_GLM');
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_GLM_MODEL';

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

Evet yarattığımız Regresyon modeline ait Anova tablosuna aşağıdaki gibi erişlebilir.

 

SELECT * FROM TABLE (DBMS_DATA_MINING.GET_MODEL_DETAILS_GLM ('MD_GLM_MODEL'));

Evet şimdi modelimizle nasıl test yapabileceğimize bakalım. Öncelikle bunun için kaggle’dan indirdiğimiz test.csv dosyasını yüklemek için gerekli olan tablomuzu yaratıyoruz ve datayı içerisinde import ediyoruz.

CREATE TABLE BOSTON_HOUSING_TEST
(
   ID        NUMBER,
   CRIM      NUMBER,
   ZN        NUMBER,
   INDUS     NUMBER,
   CHAS      NUMBER,
   NOX       NUMBER,
   RM        NUMBER,
   AGE       NUMBER,
   DIS       NUMBER,
   RAD       NUMBER,
   TAX       NUMBER,
   PTRATIO   NUMBER,
   BLACK     NUMBER,
   LSTAT     NUMBER,
   MEDV      NUMBER
);

Database –> Import –> Import Table Data (test.csv)

SELECT * FROM BOSTON_HOUSING_TEST;

Şimdi yüklediğimiz test verisi ile oluşturduğumuz modeli çalıştırıp sonuçlara bakalım.

SELECT T.*,
 PREDICTION (MD_GLM_MODEL USING *) MODEL_PREDICT_RESPONSE
FROM BOSTON_HOUSING_TEST T;

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

Veritabanı İçerisindeki JSON Değerlerin Karşılaştırılması

Herkese Selam,

Bu yazıda Oracle 18c ile beraber gelen bazı yeni SQL fonksyonlarından bahsedeceğim umarım farkındalık anlamında faydalı bir yazı olur.

Bilindiği üzere Oracle 18c geçtiğimiz Şubat ayında duyuruldu ve kullanıcılara Cloud ortamlarda kullanımlarına açıldı. Bu gelişmeyi takiben Oracle, LiveSQL platformu üzerinden de son kullanıcıların denemeleri üzerine yeni sürümü kullanıma açtı.

Bu yazıya konu olan fonksiyon denemelerini LiveSQL platformu üzerinden gerçekleştireceğim.

Yazımıza konu olan yeni SQL fonksyonları veritabanına kaydettiğimiz json içeriklerin içerik kontrollerini yapıp jsonların uyuşup uyuşmadığını anlayabilmektedir. Mevcut alt yapı ile jsonların içerik kontrollerini yapabilmek için karmaşık sql sorguları geliştirmemiz gerekirken yeni geliştirilen fonskyonlar ile bu kontrol oldukça hızlı ve kolay yapılabilmektedir.

Şimdi bir kaç farklı senaryo deneyerek neler yapabildiğimize bir bakalım.  Öncelikle işe örnek bir tablo ve veri oluşturarak başlayalım.

CREATE TABLE comp_json_values
(
   json_val_1   VARCHAR2 (2000),
   json_val_2   VARCHAR2 (2000),
   use_case_desc VARCHAR2(2000)
);

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"key":"k1","value":"v1"}',
               'Exactly Same');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"key":"k1" ,  "value":"v1"   }',
               'Exactly Same but having whitespaces');    

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"key":"k2","value":"v2"}',
               'Format:Same - Order:Same - Values:Different');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"key":"k2","value":"v2","value2":"v3"}',
               'Format:Different - Order:Different - Values:Different');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"value":"v1","key":"k1"}',
               'Format:Same - Order:Different - Values:Same');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"value":"v21","key":"k21"}',
               'Format:Same - Order:Different - Values:Different');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"value2":"v2","key2":"k2"}',
               'Format:Different - Order:Different - Values:Different');

COMMIT;

select * from comp_json_values;

Şimdi yeni alt yapının sunmuş olduğu fonksiyonlar ile json veriyi kontrol edelim. Hangi senaryoda ne gibi sonuçlar alıyoruz.

SELECT json_val_1,
       json_val_2,
       use_case_desc,
       CASE
          WHEN json_equal (json_val_1, json_val_2) THEN 'Match'
          ELSE 'Mismatch'
       END
          json_comp
FROM comp_json_values;

Bu alt yapıyı CASE..WHEN ile kullanabildiğimiz gibi WHERE cümlesinde de kullanabiliyoruz.

SELECT json_val_1, json_val_2, use_case_desc
  FROM comp_json_values
 WHERE json_equal (json_val_1, json_val_2);

select json_val_1, 
       json_val_2, 
       use_case_desc
from comp_json_values
where not json_equal(json_val_1,json_val_2);

Yeni alt yapı ile gelen  yeni fonksiyonlar aynı zamanda PL/SQL içerisinde de basit bir şekilde kullanılabilmektedir.

 

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

Approximate Query Processing

Herkese Selam,

Bu yazıda Oracle 18c ile beraber gelen bazı yeni SQL fonksyonlarından bahsedeceğim umarım farkındalık anlamında faydalı bir yazı olur.

Bilindiği üzere Oracle 18c geçtiğimiz Şubat ayında duyuruldu ve kullanıcılara Cloud ortamlarda kullanımlarına açıldı. Bu gelişmeyi takiben Oracle, LiveSQL platformu üzerinden de son kullanıcıların denemeleri üzerine yeni sürümü kullanıma açtı.

Bu yazıya konu olan fonksiyon denemelerini LiveSQL platformu üzerinden gerçekleştireceğim.

İlk olarak üzerinde çalışacağımız tabloyu yaratalım ve içerisine veri girelim.

CREATE TABLE employees
(
   employee_id      NUMBER (6),
   first_name       VARCHAR2 (20),
   last_name        VARCHAR2 (25) CONSTRAINT emp_last_name_nn NOT NULL,
   email            VARCHAR2 (25) CONSTRAINT emp_email_nn NOT NULL,
   phone_number     VARCHAR2 (20),
   hire_date        DATE CONSTRAINT emp_hire_date_nn NOT NULL,
   job_id           VARCHAR2 (10) CONSTRAINT emp_job_nn NOT NULL,
   salary           NUMBER (8, 2),
   commission_pct   NUMBER (2, 2),
   manager_id       NUMBER (6),
   department_id    NUMBER (4),
   CONSTRAINT emp_salary_min CHECK (salary > 0),
   CONSTRAINT emp_email_uk UNIQUE (email)
);

INSERT INTO employees
     VALUES (100,'Steven','King','SKING','515.123.4567',TO_DATE ('17-HAZ-1987', 'dd-MON-yyyy'),'AD_PRES',24000,NULL,NULL,90);

INSERT INTO employees
     VALUES (101,'Neena','Kochhar','NKOCHHAR','515.123.4568',TO_DATE ('21-SEP-1989', 'dd-MON-yyyy'),'AD_VP',17000,NULL,100,90);

INSERT INTO employees
     VALUES (102,'Lex','De Haan','LDEHAAN','515.123.4569',TO_DATE ('13-JAN-1993', 'dd-MON-yyyy'),'AD_VP',17000,NULL,100,90);

INSERT INTO employees
     VALUES (103,'Alexander','Hunold','AHUNOLD','590.423.4567',TO_DATE ('03-JAN-1990', 'dd-MON-yyyy'),'IT_PROG',9000,NULL,102,60);

INSERT INTO employees
     VALUES (104,'Bruce','Ernst','BERNST','590.423.4568',TO_DATE ('21-MAY-1991', 'dd-MON-yyyy'),'IT_PROG',6000,NULL,103,60);

INSERT INTO employees
     VALUES (105,'David','Austin','DAUSTIN','590.423.4569',TO_DATE ('25-JUN-1997', 'dd-MON-yyyy'),'IT_PROG',4800,NULL,103,60);

INSERT INTO employees
     VALUES (106,'Valli','Pataballa','VPATABAL','590.423.4560',TO_DATE ('05-FEB-1998', 'dd-MON-yyyy'),'IT_PROG',4800,NULL,103,60);

INSERT INTO employees
     VALUES (107,'Diana','Lorentz','DLORENTZ','590.423.5567',TO_DATE ('07-FEB-1999', 'dd-MON-yyyy'),'IT_PROG',4200,NULL,103,60);

INSERT INTO employees
     VALUES (108,'Nancy','Greenberg','NGREENBE','515.124.4569',TO_DATE ('17-AUG-1994', 'dd-MON-yyyy'),'FI_MGR',12000,NULL,101,100);

INSERT INTO employees
     VALUES (109,'Daniel','Faviet','DFAVIET','515.124.4169',TO_DATE ('16-AUG-1994', 'dd-MON-yyyy'),'FI_ACCOUNT',9000,NULL,108,100);

INSERT INTO employees
     VALUES (110,'John','Chen','JCHEN','515.124.4269',TO_DATE ('28-SEP-1997', 'dd-MON-yyyy'),'FI_ACCOUNT',8200,NULL,108,100);

INSERT INTO employees
     VALUES (111,'Ismael','Sciarra','ISCIARRA','515.124.4369',TO_DATE ('30-SEP-1997', 'dd-MON-yyyy'),'FI_ACCOUNT',7700,NULL,108,100);

INSERT INTO employees
     VALUES (112,'Jose Manuel','Urman','JMURMAN','515.124.4469',TO_DATE ('07-MAR-1998', 'dd-MON-yyyy'),'FI_ACCOUNT',7800,NULL,108,100);

INSERT INTO employees
     VALUES (113,'Luis','Popp','LPOPP','515.124.4567',TO_DATE ('07-DEC-1999', 'dd-MON-yyyy'),'FI_ACCOUNT',6900,NULL,108,100);

INSERT INTO employees
     VALUES (114,'Den','Raphaely','DRAPHEAL','515.127.4561',TO_DATE ('07-DEC-1994', 'dd-MON-yyyy'),'PU_MAN',11000,NULL,100,30);

INSERT INTO employees
     VALUES (115,'Alexander','Khoo','AKHOO','515.127.4562',TO_DATE ('18-MAY-1995', 'dd-MON-yyyy'),'PU_CLERK',3100,NULL,114,30);

INSERT INTO employees
     VALUES (116,'Shelli','Baida','SBAIDA','515.127.4563',TO_DATE ('24-DEC-1997', 'dd-MON-yyyy'),'PU_CLERK',2900,NULL,114,30);

INSERT INTO employees
     VALUES (117,'Sigal','Tobias','STOBIAS','515.127.4564',TO_DATE ('24-JUL-1997', 'dd-MON-yyyy'),'PU_CLERK',2800,NULL,114,30);

INSERT INTO employees
     VALUES (118,'Guy','Himuro','GHIMURO','515.127.4565',TO_DATE ('15-NOV-1998', 'dd-MON-yyyy'),'PU_CLERK',2600,NULL,114,30);

INSERT INTO employees
     VALUES (119,'Karen','Colmenares','KCOLMENA','515.127.4566',TO_DATE ('10-AUG-1999', 'dd-MON-yyyy'),'PU_CLERK',2500,NULL,114,30);

INSERT INTO employees
     VALUES (120,'Matthew','Weiss','MWEISS','650.123.1234',TO_DATE ('18-JUL-1996', 'dd-MON-yyyy'),'ST_MAN',8000,NULL,100,50);

INSERT INTO employees
     VALUES (121,'Adam','Fripp','AFRIPP','650.123.2234',TO_DATE ('10-APR-1997', 'dd-MON-yyyy'),'ST_MAN',8200,NULL,100,50);

INSERT INTO employees
     VALUES (122,'Payam','Kaufling','PKAUFLIN','650.123.3234',TO_DATE ('01-MAY-1995', 'dd-MON-yyyy'),'ST_MAN',7900,NULL,100,50);

INSERT INTO employees
     VALUES (123,'Shanta','Vollman','SVOLLMAN','650.123.4234',TO_DATE ('10-OCT-1997', 'dd-MON-yyyy'),'ST_MAN',6500,NULL,100,50);

INSERT INTO employees
     VALUES (124,'Kevin','Mourgos','KMOURGOS','650.123.5234',TO_DATE ('16-NOV-1999', 'dd-MON-yyyy'),'ST_MAN',5800,NULL,100,50);

INSERT INTO employees
     VALUES (125,'Julia','Nayer','JNAYER','650.124.1214',TO_DATE ('16-JUL-1997', 'dd-MON-yyyy'),'ST_CLERK',3200,NULL,120,50);

INSERT INTO employees
     VALUES (126,'Irene','Mikkilineni','IMIKKILI','650.124.1224',TO_DATE ('28-SEP-1998', 'dd-MON-yyyy'),'ST_CLERK',2700,NULL,120,50);

INSERT INTO employees
     VALUES (127,'James','Landry','JLANDRY','650.124.1334',TO_DATE ('14-JAN-1999', 'dd-MON-yyyy'),'ST_CLERK',2400,NULL,120,50);

INSERT INTO employees
     VALUES (128,'Steven','Markle','SMARKLE','650.124.1434',TO_DATE ('08-MAR-2000', 'dd-MON-yyyy'),'ST_CLERK',2200,NULL,120,50);

INSERT INTO employees
     VALUES (129,'Laura','Bissot','LBISSOT','650.124.5234',TO_DATE ('20-AUG-1997', 'dd-MON-yyyy'),'ST_CLERK',3300,NULL,121,50);

INSERT INTO employees
     VALUES (130,'Mozhe','Atkinson','MATKINSO','650.124.6234',TO_DATE ('30-OCT-1997', 'dd-MON-yyyy'),'ST_CLERK',2800,NULL,121,50);

INSERT INTO employees
     VALUES (131,'James','Marlow','JAMRLOW','650.124.7234',TO_DATE ('16-FEB-1997', 'dd-MON-yyyy'),'ST_CLERK',2500,NULL,121,50);

INSERT INTO employees
     VALUES (132,'TJ','Olson','TJOLSON','650.124.8234',TO_DATE ('10-APR-1999', 'dd-MON-yyyy'),'ST_CLERK',2100,NULL,121,50);

INSERT INTO employees
     VALUES (133,'Jason','Mallin','JMALLIN','650.127.1934',TO_DATE ('14-JUN-1996', 'dd-MON-yyyy'),'ST_CLERK',3300,NULL,122,50);

INSERT INTO employees
     VALUES (134,'Michael','Rogers','MROGERS','650.127.1834',TO_DATE ('26-AUG-1998', 'dd-MON-yyyy'),'ST_CLERK',2900,NULL,122,50);

INSERT INTO employees
     VALUES (135,'Ki','Gee','KGEE','650.127.1734',TO_DATE ('12-DEC-1999', 'dd-MON-yyyy'),'ST_CLERK',2400,NULL,122,50);

INSERT INTO employees
     VALUES (136,'Hazel','Philtanker','HPHILTAN','650.127.1634',TO_DATE ('06-FEB-2000', 'dd-MON-yyyy'),'ST_CLERK',2200,NULL,122,50);

INSERT INTO employees
     VALUES (137,'Renske','Ladwig','RLADWIG','650.121.1234',TO_DATE ('14-JUL-1995', 'dd-MON-yyyy'),'ST_CLERK',3600,NULL,123,50);

INSERT INTO employees
     VALUES (138,'Stephen','Stiles','SSTILES','650.121.2034',TO_DATE ('26-OCT-1997', 'dd-MON-yyyy'),'ST_CLERK',3200,NULL,123,50);

INSERT INTO employees
     VALUES (139,'John','Seo','JSEO','650.121.2019',TO_DATE ('12-FEB-1998', 'dd-MON-yyyy'),'ST_CLERK',2700,NULL,123,50);

INSERT INTO employees
     VALUES (140,'Joshua','Patel','JPATEL','650.121.1834',TO_DATE ('06-APR-1998', 'dd-MON-yyyy'),'ST_CLERK',2500,NULL,123,50);

INSERT INTO employees
     VALUES (141,'Trenna','Rajs','TRAJS','650.121.8009',TO_DATE ('17-OCT-1995', 'dd-MON-yyyy'),'ST_CLERK',3500,NULL,124,50);

INSERT INTO employees
     VALUES (142,'Curtis','Davies','CDAVIES','650.121.2994',TO_DATE ('29-JAN-1997', 'dd-MON-yyyy'),'ST_CLERK',3100,NULL,124,50);

INSERT INTO employees
     VALUES (143,'Randall','Matos','RMATOS','650.121.2874',TO_DATE ('15-MAR-1998', 'dd-MON-yyyy'),'ST_CLERK',2600,NULL,124,50);

INSERT INTO employees
     VALUES (144,'Peter','Vargas','PVARGAS','650.121.2004',TO_DATE ('09-JUL-1998', 'dd-MON-yyyy'),'ST_CLERK',2500,NULL,124,50);

INSERT INTO employees
     VALUES (145,'John','Russell','JRUSSEL','011.44.1344.429268',TO_DATE ('01-OCT-1996', 'dd-MON-yyyy'),'SA_MAN',14000,.4,100,80);

INSERT INTO employees
     VALUES (146,'Karen','Partners','KPARTNER','011.44.1344.467268',TO_DATE ('05-JAN-1997', 'dd-MON-yyyy'),'SA_MAN',13500,.3,100,80);

INSERT INTO employees
     VALUES (147,'Alberto','Errazuriz','AERRAZUR','011.44.1344.429278',TO_DATE ('10-MAR-1997', 'dd-MON-yyyy'),'SA_MAN',12000,.3,100,80);

INSERT INTO employees
     VALUES (148,'Gerald','Cambrault','GCAMBRAU','011.44.1344.619268',TO_DATE ('15-OCT-1999', 'dd-MON-yyyy'),'SA_MAN',11000,.3,100,80);

INSERT INTO employees
     VALUES (149,'Eleni','Zlotkey','EZLOTKEY','011.44.1344.429018',TO_DATE ('29-JAN-2000', 'dd-MON-yyyy'),'SA_MAN',10500,.2,100,80);

INSERT INTO employees
     VALUES (150,'Peter','Tucker','PTUCKER','011.44.1344.129268',TO_DATE ('30-JAN-1997', 'dd-MON-yyyy'),'SA_REP',10000,.3,145,80);

INSERT INTO employees
     VALUES (151,'David','Bernstein','DBERNSTE','011.44.1344.345268',TO_DATE ('24-MAR-1997', 'dd-MON-yyyy'),'SA_REP',9500,.25,145,80);

INSERT INTO employees
     VALUES (152,'Peter','Hall','PHALL','011.44.1344.478968',TO_DATE ('20-AUG-1997', 'dd-MON-yyyy'),'SA_REP',9000,.25,145,80);

INSERT INTO employees
     VALUES (153,'Christopher','Olsen','COLSEN','011.44.1344.498718',TO_DATE ('30-MAR-1998', 'dd-MON-yyyy'),'SA_REP',8000,.2,145,80);

INSERT INTO employees
     VALUES (154,'Nanette','Cambrault','NCAMBRAU','011.44.1344.987668',TO_DATE ('09-DEC-1998', 'dd-MON-yyyy'),'SA_REP',7500,.2,145,80);

INSERT INTO employees
     VALUES (155,'Oliver','Tuvault','OTUVAULT','011.44.1344.486508',TO_DATE ('23-NOV-1999', 'dd-MON-yyyy'),'SA_REP',7000,.15,145,80);

INSERT INTO employees
     VALUES (156,'Janette','King','JKING','011.44.1345.429268',TO_DATE ('30-JAN-1996', 'dd-MON-yyyy'),'SA_REP',10000,.35,146,80);

INSERT INTO employees
     VALUES (157,'Patrick','Sully','PSULLY','011.44.1345.929268',TO_DATE ('04-MAR-1996', 'dd-MON-yyyy'),'SA_REP',9500,.35,146,80);

INSERT INTO employees
     VALUES (158,'Allan','McEwen','AMCEWEN','011.44.1345.829268',TO_DATE ('01-AUG-1996', 'dd-MON-yyyy'),'SA_REP',9000,.35,146,80);

INSERT INTO employees
     VALUES (159,'Lindsey','Smith','LSMITH','011.44.1345.729268',TO_DATE ('10-MAR-1997', 'dd-MON-yyyy'),'SA_REP',8000,.3,146,80);

INSERT INTO employees
     VALUES (160,'Louise','Doran','LDORAN','011.44.1345.629268',TO_DATE ('15-DEC-1997', 'dd-MON-yyyy'),'SA_REP',7500,.3,146,80);

INSERT INTO employees
     VALUES (161,'Sarath','Sewall','SSEWALL','011.44.1345.529268',TO_DATE ('03-NOV-1998', 'dd-MON-yyyy'),'SA_REP',7000,.25,146,80);

INSERT INTO employees
     VALUES (162,'Clara','Vishney','CVISHNEY','011.44.1346.129268',TO_DATE ('11-NOV-1997', 'dd-MON-yyyy'),'SA_REP',10500,.25,147,80);

INSERT INTO employees
     VALUES (163,'Danielle','Greene','DGREENE','011.44.1346.229268',TO_DATE ('19-MAR-1999', 'dd-MON-yyyy'),'SA_REP',9500,.15,147,80);

INSERT INTO employees
     VALUES (164,'Mattea','Marvins','MMARVINS','011.44.1346.329268',TO_DATE ('24-JAN-2000', 'dd-MON-yyyy'),'SA_REP',7200,.10,147,80);

INSERT INTO employees
     VALUES (165,'David','Lee','DLEE','011.44.1346.529268',TO_DATE ('23-FEB-2000', 'dd-MON-yyyy'),'SA_REP',6800,.1,147,80);

INSERT INTO employees
     VALUES (166,'Sundar','Ande','SANDE','011.44.1346.629268',TO_DATE ('24-MAR-2000', 'dd-MON-yyyy'),'SA_REP',6400,.10,147,80);

INSERT INTO employees
     VALUES (167,'Amit','Banda','ABANDA','011.44.1346.729268',TO_DATE ('21-APR-2000', 'dd-MON-yyyy'),'SA_REP',6200,.10,147,80);

INSERT INTO employees
     VALUES (168,'Lisa','Ozer','LOZER','011.44.1343.929268',TO_DATE ('11-MAR-1997', 'dd-MON-yyyy'),'SA_REP',11500,.25,148,80);

INSERT INTO employees
     VALUES (169,'Harrison','Bloom','HBLOOM','011.44.1343.829268',TO_DATE ('23-MAR-1998', 'dd-MON-yyyy'),'SA_REP',10000,.20,148,80);

INSERT INTO employees
     VALUES (170,'Tayler','Fox','TFOX','011.44.1343.729268',TO_DATE ('24-JAN-1998', 'dd-MON-yyyy'),'SA_REP',9600,.20,148,80);

INSERT INTO employees
     VALUES (171,'William','Smith','WSMITH','011.44.1343.629268',TO_DATE ('23-FEB-1999', 'dd-MON-yyyy'),'SA_REP',7400,.15,148,80);

INSERT INTO employees
     VALUES (172,'Elizabeth','Bates','EBATES','011.44.1343.529268',TO_DATE ('24-MAR-1999', 'dd-MON-yyyy'),'SA_REP',7300,.15,148,80);

INSERT INTO employees
     VALUES (173,'Sundita','Kumar','SKUMAR','011.44.1343.329268',TO_DATE ('21-APR-2000', 'dd-MON-yyyy'),'SA_REP',6100,.10,148,80);

INSERT INTO employees
     VALUES (174,'Ellen','Abel','EABEL','011.44.1644.429267',TO_DATE ('11-MAY-1996', 'dd-MON-yyyy'),'SA_REP',11000,.30,149,80);

INSERT INTO employees
     VALUES (175,'Alyssa','Hutton','AHUTTON','011.44.1644.429266',TO_DATE ('19-MAR-1997', 'dd-MON-yyyy'),'SA_REP',8800,.25,149,80);

INSERT INTO employees
     VALUES (176,'Jonathon','Taylor','JTAYLOR','011.44.1644.429265',TO_DATE ('24-MAR-1998', 'dd-MON-yyyy'),'SA_REP',8600,.20,149,80);

INSERT INTO employees
     VALUES (177,'Jack','Livingston','JLIVINGS','011.44.1644.429264',TO_DATE ('23-APR-1998', 'dd-MON-yyyy'),'SA_REP',8400,.20,149,80);

INSERT INTO employees
     VALUES (178,'Kimberely','Grant','KGRANT','011.44.1644.429263',TO_DATE ('24-MAY-1999', 'dd-MON-yyyy'),'SA_REP',7000,.15,149,NULL);

INSERT INTO employees
     VALUES (179,'Charles','Johnson','CJOHNSON','011.44.1644.429262',TO_DATE ('04-JAN-2000', 'dd-MON-yyyy'),'SA_REP',6200,.10,149,80);

INSERT INTO employees
     VALUES (180,'Winston','Taylor','WTAYLOR','650.507.9876',TO_DATE ('24-JAN-1998', 'dd-MON-yyyy'),'SH_CLERK',3200,NULL,120,50);

INSERT INTO employees
     VALUES (181,'Jean','Fleaur','JFLEAUR','650.507.9877',TO_DATE ('23-FEB-1998', 'dd-MON-yyyy'),'SH_CLERK',3100,NULL,120,50);

INSERT INTO employees
     VALUES (182,'Martha','Sullivan','MSULLIVA','650.507.9878',TO_DATE ('21-JUN-1999', 'dd-MON-yyyy'),'SH_CLERK',2500,NULL,120,50);

INSERT INTO employees
     VALUES (183,'Girard','Geoni','GGEONI','650.507.9879',TO_DATE ('03-FEB-2000', 'dd-MON-yyyy'),'SH_CLERK',2800,NULL,120,50);

INSERT INTO employees
     VALUES (184,'Nandita','Sarchand','NSARCHAN','650.509.1876',TO_DATE ('27-JAN-1996', 'dd-MON-yyyy'),'SH_CLERK',4200,NULL,121,50);

INSERT INTO employees
     VALUES (185,'Alexis','Bull','ABULL','650.509.2876',TO_DATE ('20-FEB-1997', 'dd-MON-yyyy'),'SH_CLERK',4100,NULL,121,50);

INSERT INTO employees
     VALUES (186,'Julia','Dellinger','JDELLING','650.509.3876',TO_DATE ('24-JUN-1998', 'dd-MON-yyyy'),'SH_CLERK',3400,NULL,121,50);

INSERT INTO employees
     VALUES (187,'Anthony','Cabrio','ACABRIO','650.509.4876',TO_DATE ('07-FEB-1999', 'dd-MON-yyyy'),'SH_CLERK',3000,NULL,121,50);

INSERT INTO employees
     VALUES (188,'Kelly','Chung','KCHUNG','650.505.1876',TO_DATE ('14-JUN-1997', 'dd-MON-yyyy'),'SH_CLERK',3800,NULL,122,50);

INSERT INTO employees
     VALUES (189,'Jennifer','Dilly','JDILLY','650.505.2876',TO_DATE ('13-AUG-1997', 'dd-MON-yyyy'),'SH_CLERK',3600,NULL,122,50);

INSERT INTO employees
     VALUES (190,'Timothy','Gates','TGATES','650.505.3876',TO_DATE ('11-JUL-1998', 'dd-MON-yyyy'),'SH_CLERK',2900,NULL,122,50);

INSERT INTO employees
     VALUES (191,'Randall','Perkins','RPERKINS','650.505.4876',TO_DATE ('19-DEC-1999', 'dd-MON-yyyy'),'SH_CLERK',2500,NULL,122,50);

INSERT INTO employees
     VALUES (192,'Sarah','Bell','SBELL','650.501.1876',TO_DATE ('04-FEB-1996', 'dd-MON-yyyy'),'SH_CLERK',4000,NULL,123,50);

INSERT INTO employees
     VALUES (193,'Britney','Everett','BEVERETT','650.501.2876',TO_DATE ('03-MAR-1997', 'dd-MON-yyyy'),'SH_CLERK',3900,NULL,123,50);

INSERT INTO employees
     VALUES (194,'Samuel','McCain','SMCCAIN','650.501.3876',TO_DATE ('01-JUL-1998', 'dd-MON-yyyy'),'SH_CLERK',3200,NULL,123,50);

INSERT INTO employees
     VALUES (195,'Vance','Jones','VJONES','650.501.4876',TO_DATE ('17-MAR-1999', 'dd-MON-yyyy'),'SH_CLERK',2800,NULL,123,50);

INSERT INTO employees
     VALUES (196,'Alana','Walsh','AWALSH','650.507.9811',TO_DATE ('24-APR-1998', 'dd-MON-yyyy'),'SH_CLERK',3100,NULL,124,50);

INSERT INTO employees
     VALUES (197,'Kevin','Feeney','KFEENEY','650.507.9822',TO_DATE ('23-MAY-1998', 'dd-MON-yyyy'),'SH_CLERK',3000,NULL,124,50);

INSERT INTO employees
     VALUES (198,'Donald','OConnell','DOCONNEL','650.507.9833',TO_DATE ('21-JUN-1999', 'dd-MON-yyyy'),'SH_CLERK',2600,NULL,124,50);

INSERT INTO employees
     VALUES (199,'Douglas','Grant','DGRANT','650.507.9844',TO_DATE ('13-JAN-2000', 'dd-MON-yyyy'),'SH_CLERK',2600,NULL,124,50);

INSERT INTO employees
     VALUES (200,'Jennifer','Whalen','JWHALEN','515.123.4444',TO_DATE ('17-SEP-1987', 'dd-MON-yyyy'),'AD_ASST',4400,NULL,101,10);

INSERT INTO employees
     VALUES (201,'Michael','Hartstein','MHARTSTE','515.123.5555',TO_DATE ('17-FEB-1996', 'dd-MON-yyyy'),'MK_MAN',13000,NULL,100,20);

INSERT INTO employees
     VALUES (202,'Pat','Fay','PFAY','603.123.6666',TO_DATE ('17-AUG-1997', 'dd-MON-yyyy'),'MK_REP',6000,NULL,201,20);

INSERT INTO employees
     VALUES (203,'Susan','Mavris','SMAVRIS','515.123.7777',TO_DATE ('07-JUN-1994', 'dd-MON-yyyy'),'HR_REP',6500,NULL,101,40);

INSERT INTO employees
     VALUES (204,'Hermann','Baer','HBAER','515.123.8888',TO_DATE ('07-JUN-1994', 'dd-MON-yyyy'),'PR_REP',10000,NULL,101,70);

INSERT INTO employees
     VALUES (205,'Shelley','Higgins','SHIGGINS','515.123.8080',TO_DATE ('07-JUN-1994', 'dd-MON-yyyy'),'AC_MGR',12000,NULL,101,110);

INSERT INTO employees
     VALUES (206,'William','Gietz','WGIETZ','515.123.8181',TO_DATE ('07-JUN-1994', 'dd-MON-yyyy'),'AC_ACCOUNT',8300,NULL,205,110);

COMMIT;

Gerek yaptığımız rutin data testlerinde, gerekse veri analiz ederken COUNT, SUM, RANK komutlarını sık bir şekilde kullanırız. Bu komutların çalışma süresi verimizin büyüklüğüne göre bazen bir hayli zaman alabilmekte. Bunun temel nedeni işlemlerin çalışma maliyetlerinin yüksek olması ve çoğunlukla verinin tamamına erişme ihtiyaçlarının olmasıdır. Oracle,  bu operasyonların veri boyutuna bağımlı olarak işlem süresinin uzaması durumuna APPROXIMATE QUERY PROCESSING  hızlı çalışan alternatif bir yol üretmiş durumda. (Approximate Query Processing hayatımıza Oracle 12c ile beraber girmişti. Bu özellik geldiğinde bununla ilgili bir yazı paylaşmıştım. Linki takip ederek okuyabilirsiniz. Oracle, 18c sürümü ile bu kısıma yeni fonksiyonlar kazandırdı.) Ancak bu komut setinin %100 doğrulukla bir sonuç üretmediğini unutmamız gerekmekte . Bu alt yapı verinin boyutuna göre göz ardı edebilecek sapmalar ile sonucu hızlı bir şekilde bulabilmekte.

Şimdi APPROX_COUNT(), APPROX_SUM() ve APPROX_RANK() fonksiyonlarının ne yaptıklarını ve nasıl çalıştıklarını inceleyelim.

APPROX_COUNT:  Bu fonksiyon sorgu sonucunda oluşacak toplam satır sayısını yaklaşık ve hızlı bir şekilde getirmeye çalışır.  Bu fonksiyonu kullanmak istiyorsak mutlaka having  söz deyimini de kullanmak zorundayız. Aksi takdirde sorgu hata alır.  Buna ek olarak APPROX_COUNT söz deyimi ile beraber herhangi bir aggregated fonksiyonu sorgu içinde kullanamamaktayız. Şimdi basit olarak nasıl çalıştığına bakalım.

Aşağıdaki sorgu her departmanda, en yaygın çalışılan 5 işi döndürür.

SELECT  DEPARTMENT_ID,
        JOB_ID, 
        APPROX_COUNT(*)
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID, JOB_ID
HAVING APPROX_RANK(PARTITION BY DEPARTMENT_ID ORDER BY APPROX_COUNT(*) DESC) <= 5;

APPROX_COUNT ile MAX_ERROR söz deyimini kullanarak gerçek olan sayı ile APPROX_COUNT sonunda bulunan yaklaşık değer arasındaki farkı da görebiliriz.

SELECT  DEPARTMENT_ID,
        JOB_ID, 
        APPROX_COUNT(*) appr_count,
        APPROX_COUNT(*,'MAX_ERROR') appr_error
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID, JOB_ID
HAVING APPROX_RANK(PARTITION BY DEPARTMENT_ID ORDER BY APPROX_COUNT(*) DESC) <= 5;

APPROX_SUM:  Bu fonksiyon sorgu sonucunda oluşacak toplam değeri yaklaşık ve hızlı bir şekilde getirmeye çalışır.  Bu fonksiyonu kullanmak istiyorsak mutlaka having  söz deyimini de kullanmak zorundayız. Aksi takdirde sorgu hata alır.  Buna ek olarak APPROX_SUM söz deyimi ile beraber herhangi bir aggregated fonksiyonu sorgu içinde kullanamamaktayız. Şimdi basit olarak nasıl çalıştığına bakalım.

Aşağıdaki sorgu her departman içerisinde, çalışanlarının maaş toplamı en yüksek işi döndürür.

SELECT  DEPARTMENT_ID,
        JOB_ID, 
        APPROX_SUM(SALARY) appr_sum
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID, JOB_ID
HAVING APPROX_RANK(PARTITION BY DEPARTMENT_ID ORDER BY APPROX_SUM(SALARY) DESC) <= 1;

APPROX_SUM ile MAX_ERROR söz deyimini kullanarak gerçek olan toplam ile APPROX_SUM sonunda bulunan yaklaşık toplam arasındaki farkı da görebiliriz.

APPROX_RANK:  Bu fonksiyon sorgu sonucunda oluşacak yaklaşık sıralamayı döndürür.  Bu fonksiyonu kullanmak istiyorsak mutlaka having  söz deyimini de kullanmak zorundayız. Aksi takdirde sorgu hata alır.  Buna ek olarak APPROX_RANK söz deyimi ile beraber herhangi bir aggregated fonksiyonu sorgu içinde kullanamamaktayız.   APPROX_RANK ile beraber PARTITION BY  ve ORDER BY deyimlerini de kullanabilmekteyiz.  Ancak ORDER BY deyimini kullanırsak bu deyim APPROX_RANK veya APPROX_SUM deyimini içinde mutlaka barındırmalı. Şimdi basit olarak nasıl çalıştığına bakalım.

Aşağıdaki sorgu her departman içerisinde, çalışanlarının maaş toplamını iş bazında hesaplayıp azalan bir sıralama yapar ve sıralama sonucunda ilk 2 kayıtı getirir.

SELECT department_id, 
       job_id,
       APPROX_RANK(PARTITION BY department_id ORDER BY APPROX_SUM(salary) DESC) appr_rnk
FROM employees
GROUP BY department_id, job_id
HAVING APPROX_RANK(PARTITION BY department_id ORDER BY APPROX_SUM (salary) DESC) <= 2;

 

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

Oracle 18c Kullanmaya Başlayalım

Herkese Selam,

Oracle18cOracle kısa bir süre önce yeni DB sürümü olan 18c’yi geçtiğimiz Şubat ayında duyurdu. Oracle 18c yine Cloud base çalışan ve otonom olduğu iddiası ileilgileri üzerine çeken ve bunların yanında yeni bir çok özelliğe sahip olan bir veritabanı yazılımı olmuş gibi görünüyor.

Oracle 18c ile ilgili bilgi sahibi olmak için linki takip edebilirsiniz.

Oracle, 18c sürümünü hızlıca deneyebilmek adına ise çok güzel bir iş daha yapmış ve LiveSQL platformuna 18c’yi hemen entegre etmiş.  LiveSQL  platformu üzerinden 18c veritabanını hızlıca deneyimleyebilmek mümkün.

livesql

 

 

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

Reinforcement Learning ile Optimal Yol Tespiti

Herkese Selam,

Bu yazıda Reinformcement Learning yöntemlerinden biri olan Q-Learning ile örnek bir harita üzerinden en optimum yolu bulan bir agent tasarımı yapacağım. Umarım farkındalık anlamında faydalı bir yazı olur.


Reinforcement Learning (RL),  bir ödülün en üst düzeye çıkarılması için, belirli bir durumda yapılması gereken optimum eylemleri bulma problemleri ile ilgilenen bir makine öğrenmesi tekniğidir.

Esinlendiği nokta davranış piskolojisi olan bu öğrenme tekniği genellikle şu şekilde anlatılır. Herhangi bir ortamda (environment) bulunan bir agent bu ortam içerisinde belirli hareketler yapar ve bu hareketler sonucunda ödüller kazanır (rewards).  Ana amaç toplamda kazanılacak ödülü maksimize etmek ve uzun erimde en fazla ödülü kazandıracak hareket serisini (optimal policy) öğrenmektir.

Reinforcement Learning’in en sık kullanıldığı uygulamaların başında oyunlar gelmektedir. Örneğin 90’lı yıllarda Tavla oyununda bir insanı yenen makine RL ile öğrenimini gerçekleştirmişti. Yine yakın zamanda Dünyanın en iyi GO oyuncusunu yenen makinede öğrenimini RL ile gerçekleştirmişti (Google DeepMind’s Alpha GO).  Bu uygulamalara ek olarak Robotik de, Kontrol’de,  Otonom Araçlarda ve buna benzer bir çok endüstriyel alanlarda da RL tekniğine sık bir şekilde başvurulmaktadır.

Reinforcement Learning derinliği olan detaylı bir konu olduğundan dolayı bu yazı içerisinde daha fazla bu tekniğin detayını anlatmayacağım ancak merak edenler aşağıdaki video’dan veya internet üzerinden aramalar yaparak örnek uygulamaları ve bu tekniğin teorisini öğrenmeye başlayabilirler.

Şimdi bu yazıya konu olacak örnek bir uygulama geliştirme işine geçebiliriz.

Q-Learning For Optimal Hiking

Elimizde şekildeki gibi bir harita var ve bu haritada başlangıç noktasından başlayarak bitiş noktasına en fazla toplam ödülü elde ederek nasıl ulaşabileceğim sorusunun cevabını arıyorum. Ancak bu haritada bir hücreden diğer hücreye geçerken kazanılan ödüller farklı durumlara göre değişkenlik gösteriyor. Haritadan da görüleceğe üzere düzlük ve tepe şeklinde hücreler mevcut bu hücreler arasındaki geçişlerin ödülleri ise aşağıdaki şekilde bize verilmekte.

Düzlük bir hücreden, düzlük bir hücreye geçişte(P-P): -1

Düzlük bir hücreden, tepe bir hücreye geçişte(P-H):-3

Tepe bir hücreden, düz bir hücreye geçişte(H-P): -1

Tepe bir hücreden, Tepe bir hücreye geçişte(H-H): -2

Herhangi bir hücreden, hedef hücreye geçişte: 10

Görüldüğü üzere, elimizde haritanın nasıl olduğu (environment) ve durumlar arasında geçiş yaparken ne kadarlık bir ödül kazandığımız bilgisi bulunuyor. Biz bu verilenleri kullanarak en optimum yolculuğu Q-Learning yöntemi ile öğrenmeye çalışacağız. Q-Learning’in temel mantığı, agent’ın ortam üzerinde yaşadığı deneyimleri kullanarak maksimum fayda ile yolculuğu nasıl bitirebileceğini bulmaktır. Bunun için agent’ın defalarca ortam üzerinde farklı hareketler yaparak ortamı en iyi şekilde öğrenmesi amaçlanmaktadır.

Şimdi yukarıdaki gibi verilen bir haritada kazanacağı ödülü maksimize ederek sonuca gidecek ve optimal yolu bulacak bir Reinforcement Learning kodu yazalım ve sonuçları gözlemleyelim.

Kodu MATLAB ile implemente edeceğiz.

İlk etapta çözmek istediğimiz haritayı ve gerekli tanımlamaları yapıyoruz.

%****************************************************
%Defining Maze Setup
goalmark = 4;
startmark = 2;
rewards = [-1 -2 -3 -1]; 


        %****************************************************
        %You can change maze whatever you want
        %We need 1 start and 1 stop state.
        maze =[  1 0 0 1 1
                 0 2 0 1 0
                 0 0 0 0 0
                 0 0 1 1 0
                 1 0 1 1 0
                 1 1 1 1 4]; 
        %****************************************************

actUp=3;
actDown=4;
actLeft=1;
actRight=2;
ACTIONS = [actLeft, actRight, actUp, actDown];

mazeSize = size(maze);
mazeRow = mazeSize(1);
mazeColumn = mazeSize(2);
%****************************************************

Şimdi ise durumlar arası kazanılacak ödül matrisini oluşturuyoruz.

%****************************************************
%Construct Reward Matrix
rewardMat =  zeros(mazeRow*mazeColumn,length(ACTIONS));
transitMat = zeros(mazeRow*mazeColumn,length(ACTIONS));
stateIterator=0;
rew = 0;
rewforGoal =10;
for i=1:mazeRow
    for j=1:mazeColumn
        stateIterator = (i-1)*mazeColumn+j;     % Defining Current State
        
        %****************************************************
        %Up
        if(i-1>=1)
            if(maze(i-1,j)==0 && maze(i,j)==0)  % plain plain
                rew = -1;
            end
            if(maze(i-1,j)==0 && maze(i,j)==1)  % hill plain
                rew = -1;
            end
            if(maze(i-1,j)==1 && maze(i,j)==0)  % plain hill
                rew = -3;
            end
            if(maze(i-1,j)==1 && maze(i,j)==1)  % hill-hill
                rew = -2;
            end
                        
            if maze(i-1,j)==goalmark
                rewardMat(stateIterator,actUp)= rewforGoal; 
            else
                rewardMat(stateIterator,actUp)= rew;
            end
            
            transitMat(stateIterator,actUp) = stateIterator-(abs(mazeColumn-j)+abs(1-j)+1);
        end
        
        %****************************************************
        %Down
        if(i+1<=mazeRow) if(maze(i+1,j)==0 && maze(i,j)==0) % plain plain rew = -1; end if(maze(i+1,j)==0 && maze(i,j)==1) % hill plain rew = -1; end if(maze(i+1,j)==1 && maze(i,j)==0) % plain hill rew = -3; end if(maze(i+1,j)==1 && maze(i,j)==1) % hill-hill rew = -2; end if maze(i+1,j)==goalmark rewardMat(stateIterator,actDown)= rewforGoal; %10 else rewardMat(stateIterator,actDown)= rew; end transitMat(stateIterator,actDown) = stateIterator+(abs(mazeColumn-j)+abs(1-j)+1); end %**************************************************** %Left if(j-1>0)
            if(maze(i,j-1)==0 && maze(i,j)==0) % plain plain
                rew = -1;
            end
            if(maze(i,j-1)==0 && maze(i,j)==1) % hill plain
                rew = -1;
            end
            if(maze(i,j-1)==1 && maze(i,j)==0) % plain hill
                rew = -3;
            end
            if(maze(i,j-1)==1 && maze(i,j)==1) % hill-hill
                rew = -2;
            end
            
            if maze(i,j-1)==goalmark
                rewardMat(stateIterator,actLeft)= rewforGoal;  %10
            else
                rewardMat(stateIterator,actLeft)= rew;
            end
                        
            transitMat(stateIterator,actLeft) = stateIterator-1;
        end
        
        %****************************************************
        %Right
        if(j+1<=mazeColumn)
            if(maze(i,j+1)==0 && maze(i,j)==0) % plain plain
                rew = -1;
            end
            if(maze(i,j+1)==0 && maze(i,j)==1) % hill plain
                rew = -1;
            end
            if(maze(i,j+1)==1 && maze(i,j)==0) % plain hill
                rew = -3;
            end
            if(maze(i,j+1)==1 && maze(i,j)==1) % hill-hill
                rew = -2;
            end
            
            
            if maze(i,j+1)==goalmark
                rewardMat(stateIterator,actRight)= rewforGoal;  %10
            else
                rewardMat(stateIterator,actRight)= rew;
            end
            
            transitMat(stateIterator,actRight) = stateIterator+1;
        end
        %****************************************************
    end
end

Sıra kod içerisinde kullanacağımız diğer parametreleri tanımlama kısmına geldi. Bu tanımları yapıyoruz.

%**************************************
%Finding Goal and Start states positions
[sx,sy] = find(maze==startmark);
startState = (sx-1)*mazeColumn+sy;

[gx,gy] = find(maze==goalmark);
goalState = (gx-1)*mazeColumn+gy;

%**************************************
%Initializing Parameteters
Q = transitMat*0; 
Q(goalState,1)= 10; 
gamma = 1;
alpha = 0.5;
randomProb = 0.25;
tx = sx;
ty = sy;
V = zeros(mazeColumn*mazeRow,1);
episode=30000;
stepSize=20;
rewforGoal =10;
%**************************************

Sırada öğrenmeyi gerçekleştirecek kısmı kodlamaya geldi (Q-Learning).

%**************************************
%Start Q Learning
for it=1:episode
    tx = sx;
    ty = sy;
    next=0;
    for step=1:stepSize
        next = 0;
        
        %*************************************
        %Defining Current Position and fing possible actions
        curr =  (tx-1)*mazeColumn+ty;
        actionOptions = Q(curr,:);
        %*************************************
        
        %*************************************
        % Finding Next Action with using random probability
        while next==0
            %choosing random action
            if rand < randomProb
                randAction = randperm(length(actionOptions));
                index = randAction(1);
            else
                [value, index] = max(actionOptions);
            end
            next = transitMat(curr, index);
        end
        %*************************************
        
        %*************************************
        % Get reward for current position
        rew = rewardMat(curr,index);
        %*************************************
        
        
        %*************************************
        % Q Learning Equation
        if(curr~=goalState)
            Q(curr,index) = Q(curr,index) + alpha*( (rew+gamma*max(Q(next,:))) - (Q(curr,index)));
        end
        %*************************************
        
        %*************************************
        % Finding Next Step Position
        sect = fix((next/mazeColumn));
        
        if sect == 0
            sect =1;
        end
        
        rest = mod(next,mazeColumn);
        
        if next==mazeColumn*mazeRow
            tx = sect;
            ty = mazeColumn;
        else
            if ty == 0
                tx = sect;
                ty = mazeColumn;
            else
                tx = sect+1;
                ty = rest;
            end                        
        end
        %*************************************
        
    end
end
%*****************************************

Şimdi ise yazdığımız algoritmayı görselleştirelim.

%****************PLOT*********************


%***********************************************
 % get the figure and axes handles
 hFig = gcf;
 hAx  = gca;
 % set the figure to full screen
 set(hFig,'units','normalized','outerposition',[0 0 1 1]);
%***********************************************
 
 
%***********************************************
%Plot V Values using Q Matrix
subplot(1,3,1);
V = max(Q,[],2);
V = reshape(V,mazeRow,mazeColumn);
%V(goalState) = 10;
imagesc(V); 
title('V Values');
hold on;
for i=1:mazeRow
    for j=1:mazeColumn
        cell = (i-1)*mazeColumn+j;
        content = sprintf('%2.2f',V(cell));
        labels = text(j-0.20,i, content); 
        set(labels);
    end
end
%***********************************************


%***********************************************
%Plot Q Values
subplot(1,3,2);
imagesc(maze);
title('Q Values');
hold on;
for i=1:mazeRow
    for j=1:mazeColumn
        cell = (i-1)*mazeColumn+j;
        
        label1 = text(j-0.15,i-0.21, sprintf('%2.2f',Q(cell,actUp))); 
        set(label1,'FontSize',8);

        label2 = text(j-0.15,i+0.22, sprintf('%2.2f',Q(cell,actDown))); 
        set(label2,'FontSize',8);
        
        label3 = text(j-0.40,i, sprintf('%2.2f',Q(cell,actLeft))); 
        set(label3,'FontSize',8);
        
        label4 = text(j+0.16,i, sprintf('%2.2f',Q(cell,actRight))); 
        set(label4,'FontSize',8);        
    end
end
%***********************************************


%***********************************************
%Plot Optimal Path
subplot(1,3,3);
imagesc(maze);
title('Optimal Path');
hold on;
curr = startState;
tx = sx;
ty = sy;
QPr = Q;
QPr(QPr==0)=-1000;
while curr~=goalState
    curr =  (tx-1)*mazeColumn+ty;
    
    if curr==startState
        labelN = text(ty-0.40,tx-0.4, sprintf('START'));
        set(labelN,'FontSize',15);
    elseif curr==goalState
        labelN = text(ty-0.35,tx, sprintf('GOAL'));
        set(labelN,'FontSize',15);
        continue;
    end
        
    actionOptions = QPr(curr,:);    
    [value, index] = max(actionOptions);        
    
    if index == actLeft
        labelN = text(ty-0.2,tx, sprintf('L'));
        set(labelN,'FontSize',25);
        ty = ty-1;
    end
    
    if index == actRight
        labelN = text(ty-0.2,tx, sprintf('R'));
        set(labelN,'FontSize',25);
        ty = ty+1;
    end
    
    if index == actUp
        labelN = text(ty-0.2,tx, sprintf('U'));
        set(labelN,'FontSize',25);
        tx = tx -1;
    end
    
    if index == actDown
        labelN = text(ty-0.2,tx, sprintf('D'));
        set(labelN,'FontSize',25);
        tx = tx +1;
    end
end
%***********************************************

Şimdi yazdığımız kodu deneyip test edelim.

İlk olarak aşağıdaki gibi bir harita veriyorum.
maze =[ 1 0 2 1 1
0 0 0 1 0
0 0 0 0 0
0 0 1 1 0
1 4 1 1 0
1 1 1 1 1];

0: Düzlük
1: Tepe
2: Başlangıç Noktası
4: Bitiş Noktası

Parametreler: Gamma:0.7- Alpha: 0.5 – Episode: 30000

Sonuç:

Çıktı olarak 3 farklı matrisimiz var. Bunlardan birincisi bulunan V değerlerini  İkincisi bulunan Q değerleri, üçüncüsü ise optimal path’in ne olduğunu gösteriyor.

 

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

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.

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