Oracle Veritabanında SQL ile Deep Learning Modeli Geliştirmek : Predicting Boston House Prices

Herkese Selam,
Bu yazıda Oracle 18c’nin ileri analitik opsiyonlarına getirdiği yeni algoritmalardan biri olan Neural Networkleri kullanarak bir deep learning modeli kurup 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. Oracle bu alt yapı ile kullanıcılarına SQL kullanarak Makine Öğrenmesi uygulamaları geliştirmelerine olanak sağlamakta.

DBMS_DATA_MINING paketi ile Custering, Classification, Regression, Anomaly Detection, Feature Extraction ve Assosication Rules 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 aşağıdaki 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

Ben bu uygulamayı Oracle Cloud içinde servis olarak sunulan Autonomous Data Warehouse (DB) içerisinde yapacağımdan dolayı herhangi bir ek kurulum yapma ihtiyacım bulunmuyor. Autonomous Data Warehouse içerisinde bu algoritmaları kullanabilir durumdayım. Oracle Open World 2019’da Always Free olarak yer alan servislerden biri olan Autonomous Data Warehouse servisini ücretsiz olarak edinip herhangi bir kuruluma ihtiyaç duymadan dakikalar içerisinde Cloud üzerinde ayağa kaldırıp kullanabilirsiniz. Detaylı bilgi için linki takip edebilirsiniz.

Deep Learning bilindiği üzerine son yılların en çok konuşulan yapay öğrenme tekniklerinden. Öğrenme kapasitesi ve yapabildiklerinin sınırlarını çok yakından takip ediyoruz ve bir taraftanda kurgulamak istediğimiz iş senaryolarımızda da bu kapasiteden, güçten faydalanmak istiyoruz. Oracle, 18c ile beraber, veritabanı içerisinde datayı farklı bir ortama taşımaya gerek kalmaksızın, neural network modelleri kurabilmemize olanak sağlayan alt yapıyı kullanıma açtı. Şimdi bu alt yapıyı nasıl kullanacağımıza ve detaylarına bir örnek ile bakalım.

Uygulamayı yapabilmek için bir veri setine ve bir probleme ihtiyaç duyuyorum. Problem olarak Boston Housing Prices’ı seçiyorum. Bu problemi çözmek için bir regresyon modeli kurgulayacağım. Veri setini, kaggle dan temin ediyorum. (Boston Housing)

Ö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 Oracle SQL Developer kullanmaktayım. 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 tahminleyeceğimiz target değişkeni.

Veritabanı içerisinde Deep Learning modeli kurabilmek için DBMS_DATA_MINING paketi  içerisindeki Neural Network algoritmasını kullanmak durumundayız.  Bu algoritmayı kullanmak içinse bizim bazı parametreleri anlayıp daha sonra kullanmak için tanımlamamız gerekiyor. Bu parametreler aşağıdaki gibidir;

Setting Name Setting Value Description
NNET_HIDDEN_LAYERS Non-negative integer Defines the topology by number of hidden layers.

The default value is 1.

NNET_NODES_PER_LAYER A list of positive integers Defines the topology by number of nodes per layer. Different layers can have different number of nodes.

The value should be non-negative integers and comma separated. For example, ’10, 20, 5′. The setting values must be consistent with NNET_HIDDEN_LAYERS. The default number of nodes per layer is the number of attributes or 50 (if the number of attributes > 50).

NNET_ACTIVATIONS A list of the following strings:

  • NNET_ACTIVATIONS_LOG_SIG
  • NNET_ACTIVATIONS_LINEAR
  • NNET_ACTIVATIONS_TANH
  • NNET_ACTIVATIONS_ARCTAN
  • NNET_ACTIVATIONS_BIPOLAR_SIG
Defines the activation function for the hidden layers. For example, ”’NNET_ACTIVATIONS_BIPOLAR_SIG”, ”NNET_ACTIVATIONS_TANH”’.

Different layers can have different activation functions.

The default value is ”NNET_ACTIVATIONS_LOG_SIG”.

The number of activation functions must be consistent with NNET_HIDDEN_LAYERS and NNET_NODES_PER_LAYER.

Note:

All quotes are single and two single quotes are used to escape a single quote in SQL statements.

NNET_WEIGHT_LOWER_BOUND A real number

The setting specifies the lower bound of the region where weights are randomly initialized. NNET_WEIGHT_LOWER_BOUND and NNET_WEIGHT_UPPER_BOUND must be set together. Setting one and not setting the other raises an error. NNET_WEIGHT_LOWER_BOUND must not be greater than NNET_WEIGHT_UPPER_BOUND. The default value is –sqrt(6/(l_nodes+r_nodes)). The value of l_nodes for:

  • input layer dense attributes is (1+number of dense attributes)
  • input layer sparse attributes is number of sparse attributes
  • each hidden layer is (1+number of nodes in that hidden layer)

The value of r_nodes is the number of nodes in the layer that the weight is connecting to.

NNET_WEIGHT_UPPER_BOUND A real number This setting specifies the upper bound of the region where weights are initialized. It should be set in pairs with NNET_WEIGHT_LOWER_BOUND and its value must not be smaller than the value of NNET_WEIGHT_LOWER_BOUND. If not specified, the values of NNET_WEIGHT_LOWER_BOUND and NNET_WEIGHT_UPPER_BOUND are system determined.

The default value is sqrt(6/(l_nodes+r_nodes)). See NNET_WEIGHT_LOWER_BOUND.

NNET_ITERATIONS Positive integer This setting specifies the maximum number of iterations in the Neural Network algorithm.

The default value is 200.

NNET_TOLERANCE TO_CHAR(0< numeric_expr <1) Defines the convergence tolerance setting of the Neural Network algorithm.

The default value is 0.000001.

NNET_REGULARIZER NNET_REGULARIZER_NONE

NNET_REGULARIZER_L2

NNET_REGULARIZER_HELDASIDE

Regularization setting for Neural Network algorithm. If the total number of training rows is greater than 50000, the default is NNET_REGULARIZER_HELDASIDE. If the total number of training rows is less than or equal to 50000, the default is NNET_REGULARIZER_NONE.
NNET_HELDASIDE_RATIO 0 <= numeric_expr <=1 Define the held ratio for the held-aside method.

The default value is 0.25.

NNET_HELDASIDE_MAX_FAIL The value must be a positive integer. With NNET_REGULARIZER_HELDASIDE, the training process is stopped early if the network performance on the validation data fails to improve or remains the same for NNET_HELDASIDE_MAX_FAIL epochs in a row.

The default value is 6.

NNET_REG_LAMBDA TO_CHAR(numeric_expr >=0) Defines the L2 regularization parameter lambda. This can not be set together with NNET_REGULARIZER_HELDASIDE.

The default value is 1.

Evet görüldüğü üzere modeli üretebilmek için kullanabileceğimiz bir çok parametre var. Bu parametreleri kurmak istediğimiz network topolojisine göre farklı ayarlar ile kullanabilmekteyiz.

İlk olarak yapmamız gereken; bu parametreleri kullanmak istediğimiz şekilde setleyecek insert cümlelerini oluşturup yaratacağımız bir tabloya kayıt etmek. Bu tabloya sadece değiştirmek istediğimiz parametreleri insert etmemiz yeterli. Kalan parametreleri Oracle default değerleri ile kullanacak. Bu tabloyu daha sonra, modelimizi yaratırken kullanacağımız fonksiyona algoritma ayarlarını okuyabilmesi için parametre olarak vereceğiz.

CREATE TABLE neural_network_settings (
    setting_name    VARCHAR2(1000),
    setting_value   VARCHAR2(1000)
);

BEGIN
    INSERT INTO neural_network_settings (
        setting_name,
        setting_value
    ) VALUES (
        dbms_data_mining.prep_auto,
        dbms_data_mining.prep_auto_on
    );

    INSERT INTO neural_network_settings (
        setting_name,
        setting_value
    ) VALUES (
        dbms_data_mining.algo_name,
        dbms_data_mining.algo_neural_network
    );

    INSERT INTO neural_network_settings (
        setting_name,
        setting_value
    ) VALUES (
        dbms_data_mining.nnet_activations,
        '''NNET_ACTIVATIONS_LOG_SIG'',''NNET_ACTIVATIONS_LOG_SIG'',''NNET_ACTIVATIONS_LOG_SIG'''
    );

    INSERT INTO neural_network_settings (
        setting_name,
        setting_value
    ) VALUES (
        dbms_data_mining.nnet_nodes_per_layer,
        '512,250,100'
    );

    COMMIT;
END;

select * from neural_network_settings;

Görüldüğü üzere default ayarlar ile kullanmak istemediğimiz parametreleri istediğimiz değerlerler ile ayar tablomuza insert ettik.

Kabaca insert ettiğimiz iki parametreyi açıklayacak olursak;

  • İki numaralı satırda algoritma seçimini yaptık.
  • Dört numaralı satırda neural network ün kaç layerdan oluşacağını ve hangi layerda kaç hidden unit olacağını belirledik. Bu örneğimizde 3 katmanlı bir network kuruyoruz ve ilk katmanında 512, ikinci katmanında 250 ve son katmanında 100 hidden unit bulunuyor bu modelimizde.
  • Üç numaralı satırda ise her katmanda kullanmak istediğimiz aktivasyon fonksiyonunu belirledik. Bu örnekte her katmadan SIGMOID kullanıcağımızı deklare etmiş olduk.

Evet training datamızı yükledik. Algoritma ayarlarını belirledik. Şimdi ise sıra modelimizi yaratmaya (training) geldi.

BEGIN
   DBMS_DATA_MINING.CREATE_MODEL(
      model_name          => 'DEEP_LEARNING_MODEL',
      mining_function     => dbms_data_mining.REGRESSION,
      data_table_name     => 'BOSTON_HOUSING',
      case_id_column_name => 'ID',
      target_column_name  => 'MEDV',
      settings_table_name => 'neural_network_settings');
END;

Evet modelimizi yaratacağımız fonksiyonu gerekli parametreler ile çağırdık. Bu parametrelere bakarsak.

  • model name: Modelimize vereceğimiz unique bir model ismi.
  • mining function: Çözeceğimiz problemin tipini bildirdiğimiz parametre. Bu problemde bir regression yaptığımızdan dolayı bu parametreyi regression olarak seçtik. Burası problemimizin tipine göre CLASSIFICATION veya CLUSTERING vb’de seçebilirdik.
  • data_table_name: Training de kullanılacak datanın hangi tabloda olduğunu söylediğimiz parametre.
  • case_id_column_name: Training de kullandığımız datayı biribirinden ayıran anahtarı verdiğimiz parametre. Eğer composite bir key var ise modeli oluşturmadan önce yeni bir attribute oluşturarak bu kolonu sağlamalıyız. Bizim tablomuzda ID kolonu unique olduğu için doğrudan bu kolonu verebildik.
  • target_column_name: Modelimizin target olarak hangi kolonu kullanması gerektiğini söylediğimiz yer. Modelimizin target değişkeni. Yani modelin tahminleyeceği değer.
  • settings_table_name: Model oluşturulurken, neural network ün kullanmasını istediğimiz parametrelerin yazılı olduğu ayar tablosu.

Evet modelimizi train ettik. Modelimizle ilgili tüm parametrik detaylara aşağıdaki sorguyu yazarak ulaşabiliyoruz bu adımda.

select * from all_mining_model_settings where model_name='DEEP_LEARNING_MODEL';

Evet tabloda hem bizim dışardan verdiğimiz parametreleri hemde default değerleri ile atamaların yapıldığı model parametrelerini görüyoruz.

Şimdi oluşturduğumuz bu Deep Learning modeli ile ilgili detay bilgilerin olduğu tablolara bakalım.

Her katmanda üretilen weight değerlerine ulaşmak için;

select * from DM$VADEEP_LEARNING_MODEL;

Model ile genel bilgilere ulaşmak için;

select * from DM$VGDEEP_LEARNING_MODEL;

Değişkenlerin normalizasyon değerlerine ulaşmak için;

select * from DM$VNDEEP_LEARNING_MODEL;

Evet şimdi modelimiz üzerinden yeni tahminler nasıl yapabileceğimize bir bakalım. Bunu iki şekilde yapabiliriz.

İlk olarak bir tablodaki toplu değerlerin tamamı için modelimizi çalıştırabiliriz. Bunun için kaggle’dan indirdiğimiz veri dosyaları içindeki test.csv dosyasını kullanacağız. Bu dosyayı yükleyeceğimiz tabloyu yaratalım ve datayı içeriye yükleyelim.

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

-- Veriyi yukarida anlatmis oldugumuz yontem ile yukleyip tabloyu sorgulayabiliriz.

SELECT * FROM BOSTON_HOUSING_TEST;

Şimdi bu datayı modelimize input verip tahminleri üretelim.

SELECT T.*,
 PREDICTION (DEEP_LEARNING_MODEL USING *) NN_RES
FROM BOSTON_HOUSING_TEST T;

Evet toplu olarak bir çok kayıt için prediction yapmış olduk. Şimdi tek bir kayıt ile nasıl tahmin yapabileceğimize bakalım.

SELECT prediction(DEEP_LEARNING_MODEL USING 0.02 as crim,
                                            12.5 as zn,
                                            8.01 as indus,
                                            0    as chas,
                                            0.48 as nox,
                                            6.25 as rm,
                                            15.4 as age,
                                            4.92 as dis,
                                            4.00 as rad,
                                            242  as tax,
                                            15.3 as pratio,
                                            399  as balck,
                                            4.09 as lstat) pred
FROM dual;

Görüldüğü üzere çok basit bir şekilde, gelen değerleri modelimize verip tahmin sonucunu saniyenin altındaki sürelerde almayı başardık.

Kaynaklar

https://docs.oracle.com/en/database/oracle/oracle-database/18/arpls/DBMS_DATA_MINING.html#GUID-7793F608-2719-45EA-87F9-6F246BA800D4

https://docs.oracle.com/en/database/oracle/oracle-database/18/dmcon/neural-network.html#GUID-7FD5CE00-473D-4E72-9568-70494EDFABD4

https://docs.oracle.com/cd/E76298_01/UDMRF/data_mining_udm.htm

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

Uzak Sunucudaki (Oracle Cloud) Jupyter Notebook Ortamına Lokalden Erişim

Herkese Selam,

Çalıştığımız projelerin büyüklüğü ve uğraştığımız veri setlerinin hacmi arttıkça lokal makinelerimizde çalışmakta zorlanmaya başlamaktayız. Çalıştığımız bilgisayarın donanımsal kısıtları nedeni ile projelerimizi sağlıklı bir şekilde geliştirememekteyiz. Bu gibi durumlarda imdadımıza kendi lokal bilgisayarlarımızdan daha güçlü olan remote sunucular koşmakta. Remote sunucular, çalıştığımız şirket içerisinde bulunan bilgisayarlar olacağı gibi satın aldığımız veya kullanma şansımızın bulunduğu cloud ortamlarda olabilir. Bu yazıda, cloud ortamda bulunan bir makineye Anaconda ve jupyter kurup, lokal makinemden bu ortamda ayağa kaldırmış olduğum jupyter notebook’a erişimi anlatacağım. Umarım farkındalık anlamında faydalı bir yazı olur.

İlk iş olarak kullanacağım uzak sunucuyu OCI (Oracle Cloud Infrustructure) üzerinde kuracağım. Oracle Cloud üzerinde bir demo hesap açıp sizde böyle bir makine edinebilirsiniz (https://cloud.oracle.com/en_US/tryit). Şimdi bu sunucuyu çok hızlı bir şekilde nasıl ayağa kaldıracağımıza bakalım.

İlk olarak bir Compute instance’ı oluşturacağız. Sol üst menüden resimdeki path’i izleyerek instances sayfasına ulaşabiliriz.

Yeni gelen pencerede Create Instance butonuna basıp ayağa kaldıracağımız makinenin spesifikasyonlarını belirleyelim.

Ben bir ubuntu’lu bir makine başlatmayı tercih ediyorum. Burada menünden farklı imajlarda tercih edilebilir.

Aynı sayfa içerisinde makinenin donanımsal özelliklerinide seçebiliyoruz. Ben 2 CPU ve 30 GB’lık bir memory opsiyonu tercih ediyorum. Bu spesifikasyonlar isteğe göre arttırılabilir veya azaltılabilir.

Yine aynı ekran üzerinde bu makineye güvenli bir şekilde erişebilmemiz için bir ssh key’e ihtiyacımız var. Bu key dosyasını oluşturmak için lokal makinemizde aşağıdaki linux komutunu çalıştırıp id_rsa ve id_rsa.pub dosyalarını oluşturabiliriz. Bu dosyalar oluştuktan sonra aşağıdaki ekranda key istenen yere id_rsa.pub dosyasını yükleyerek bu makineye hangi şifre ile bağlanacağımızı söyleyebiliriz.

ssh-keygen -t rsa 

Bu işlemide tamamladıktan sonra sayfa sonundaki Create butonuna basarak çok kısa bir sürede seçtiğimiz spesifikasyonlara uygun bir makinenin ayağa kalktığını ekran üzerinden göreceğiz. Makine ayağa kalktıktan sonra public IP’sini ve bir çok özelliğini yine ekran üzerinden gözlemleyebileceğiz.

Evet makine görüldüğü üzere ayağa kalktı. Burada kullanacağımız en önemli bilgi lokalden ssh yapabilmemiz ve external bağlantılar kurabilmememizi sağlayacak public IP bilgisi. Şimdi bu bilgiyi kullanarak makineye bağlanıp, bu makine içerisine Anaconda ve Jupyter Notebook kurulumu yapalım.

Makineye bağlanırken ürettiğimiz key dosyalarından id_rsa dosyasını kullanacağız. Ssh bağlantısı kurmak için lokal makinemizden aşağıdaki linux komutunu çalıştırıyoruz.

ssh -i id_rsa ubuntu@PUBLIC_IP_ADDRESS

Bağlantıyı tamamlamak için id_rsa dosyasını oluştururken verdiğimiz şifreyi giriyoruz.
Doğrulama işlemi tamamlandıktan sonra Oracle Cloud üzerindeki sunucuya başarılı bir şekilde ulaşıyoruz.

Makineye bağlandığımıza göre şimdi Anaconda ve Jupyter notebook indirip kuralım.

wget https://repo.anaconda.com/archive/Anaconda3-2019.07-Linux-x86_64.sh
sh Anaconda3-2019.07-Linux-x86_64.sh
sudo snap install jupyter

Anaconda ve jupyter kurduktan sonra şimdi makinenin 30303 portundan bir jupyter notebook ayağa kaldıralım.
Ancak jupyter’i başlatmadan önce Cloud’daki makinenin 30303 numaralı portunu Oracle Cloud arayüzünden açmamız gerekiyor. Üst menüden Networking –> Virtual Cloud Network –> Security Lists path’i izlenerek 30303 portu dışardan erişime açılır.

Evet makinenin ilgili portunu erişme açtıktan sonra şimdi Cloud üzerinde başlattığımız makinenin 30303 portundan bir jupyter notebook başlatalım.

jupyter notebook --no-browser --port 30303

Notebook başarılı cloud’daki makinede bir şekilde başladı. Şimdi lokal makinemizden, cloud’daki makinenin 30303 portundan servis edilen jupyter notebook’a bağlanabilmek için lokal makinemizden ilgili yönlendirme işlemini yapalım. Bu komut ile uzak sunucudaki uygulamayı lokalimizdeki bir porta yönlendirerek, lokalimizdeki port üzerinden bu uygulamaya erişmiş olacağız.

Şimdi lokal makinemizden ilgili yönlendirmeyi yapıp, lokal makinemizdeki bir browser üzerinden jupyter notebook’a bağalanalım.

ssh -N -f -L localhost:10001:localhost:30303 ubuntu@PUBLIC_IP_ADDRESS

Lokal makinemde uygulamayı 10001 portuna yönlendirdim. Şimdi browser’a http://localhost:10001 yazıp çalıştıralım.

Evet giriş sayfasına başarılı bir şekilde ulaştık. Bize uygulamanın içine girebilmek için bir token sormakta. Bu tokenı sistem bize jupyter notebook’u başlattığımızda dönmekte.

jupyter notebook --no-browser --port 30303

Yukarıdaki komutu çalıştırdığımız ekran görüntüsünde bu token’ı görebilirsiniz. Bu tokenı girdikten sonra artık istediğimiz şekilde notebook başlatıp ana makinemiz üzerinden uzaktaki sunucuya bağlanıp kod geliştirebiliriz.

Kaynaklar:

https://jupyter.readthedocs.io/en/latest/

https://docs.anaconda.com/

https://docs.oracle.com/en/cloud/

Posted in Uncategorized | Leave a comment

Spark ve Hive ile Basit bir ETL Uygulaması

Herkese Selam,

Bu yazıda HDFS (Hadoop File System) üzerinde Spark ile örnek bir veri setini okuyup  basit bir analitik operasyon yapıp daha sonra Hive’da yaratacağım bir tabloya yazacağım.

Günümüzde üretilen veri miktarının çok yüksek ölçekte olması ve toplanan verinin analiz edilme ihtiyacının her geçen gün artması sonucunda büyük veri teknolojileri hayatımıza hızla girdi. Artık neredeyse bir çok firmanın büyük veri ortamları bulunmakta ve bu ortamlarda büyük veri teknolojilerini kullanarak analizler yapmaktalar.

Endüstride çok bilinen ve kullanımı en yaygın olaran büyük veri ortamları Hadoop’tur. Hadoop ekosisteminde, verinin saklanmasından verinin işlenmesine, verinin  görselleştirilmesinden sorgulanmasına kadar bir çok çözüm bulunmaktadır.  Hadoop ekosisteminde bulunan her bir çözüm ve kütüphane ayrı uzmanlıklar gerektiren derinlikte teknolojilerdir. Bu ekosistemin barındırdığı farklı teknolojileri ve kullanım alanlarını aşağıdaki resimden inceleyebilirsiniz.

Şimdi örnek uygulamanın yapımına geçelim. Yapacağımız örnekte veriyi önce linux file sistemimizden, Hadoop ekosisteminin veri saklama ünitesi olan HDFS’e göndereceğiz (Bu adıma Extraction diyebiliriz.). Daha sonra buraya yazdığımız veriyi Spark ile önce okuyacağız ve daha sonra basit bir transformasyon (Transformation) uygulayıp Hive’a yazacağız (Load). Hive, hadoop ekosisteminde var olan ve bu ortamda saklanan verileri sorgulayabilmemizi sağlayan bir alt yapı. Biz bu alt yapı ile büyük veri ortamımızdaki verileri SQL dili kullanarak kolayca sorgulayabiliyoruz.

Öncelikle örnek çalışacağımız veri setini tanıyalım. Çalışacağımız veri seti Kaggle üzerindenki “Sample Sales Data” veri seti. Aşağıdaki tabloda kolon adlarını ve tiplerini görebilirsiniz.

Column Name Data Type
ORDERNUMBER Number
QUANTITYORDERED Number
PRICEEACH Number
ORDERLINENUMBER Number
SALES Number
ORDERDATE Date
STATUS String
QTR_ID Number
MONTH_ID Number
YEAR_ID Number
PRODUCTLINE String
MSRP Number
PRODUCTCODE String
CUSTOMERNAME String
PHONE Number
ADDRESSLINE1 String
ADDRESSLINE2 String
CITY String
STATE String
POSTALCODE Number
COUNTRY String
TERRITORY String
CONTACTLASTNAME String
CONTACTFIRSTNAME String
DEALSIZE String

Bu veriseti, örnek satış işlemleri transactionlarını içermektedir. Biz bu örnek satış datasından bazı transformationlar yapıp örnek bir rapor datası oluşturup bunu bir Hive tablosuna insert edeceğiz.

İlk olarak Kaggle’dan download ettiğimiz örnek veriyi HDFS’e kopyalayalım. Bunun için hdfs’te öncelikle bir dizin oluşturalım.

hadoop fs -mkdir samplesales

Evet, hdfs’te dizini yarattık şimdi ise lokal dizinimiz de duran örnek veriyi hdfs’e kopyalayalım.

hadoop fs -copyFromLocal sales_sample_data.csv samplesales

hadoop fs -ls samplesales/

Veriyi hdfs’e yazdık şimdi ise Pyspark arayüzümüzü başlatıp veriyi spark ile işlemeye başlayalım.

/user/spark-2.1.0-bin-hadoop2.7/bin/pyspark --master yarn-client --num-executors 4 --driver-memory 2g --executor-memory 4g

Spark başarılı bir şekilde başladı. Bu aşamada kullanacağımız kütüphaneleri import edelim.

from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext
from pyspark.sql import Row
from pyspark.sql import HiveContext
from pyspark.sql.functions import *

hive_context = HiveContext(sc)
sqlContext = SQLContext(sc)

Şimdi ise örnek versetimizi tutacağımız satır formatını oluşturalım.

RecSales = RecSales = Row('ordernumber','quantityordered','priceeach','orderlinenumber','sales','orderdate','status','qtr_id','month_id','year_id','productline','msrp','productcode','customername','phone','addressline1','addressline2','city','state','postalcode','country','territory','contactlastname','contactfirstname','dealsize')

Sıra hdfs’e aldığımız verimizi okumaya ve bir dataframe içerisine yazmaya geldi. Veri içerisinde kolonlar “,” ayracı ile ayrildığı için bunu ayracı veriyi yüklerken belirtiyoruz. Veriyi data frame içine aldıktan sonra bir isim verip temp table olarak işaretliyoruz. Bu isimi daha sonra hive_context veya sqlContext içerisinde SQL yazarken kullanabileceğiz.

dataSales = sc.textFile("/user/samplesales/")
header = dataSales.first()
dataSales= dataSales.filter(lambda line: line != header)
recSales = dataSales.map(lambda l: l.split(","))
dataSales = recSales.map(lambda l: RecSales(l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],l[8],l[9],l[10],l[11],l[12],l[13],l[14],l[15],l[16],l[17],l[18],l[19],l[20],l[21],l[22],l[23],l[24]))
dfRecSales = hive_context.createDataFrame(dataSales)
dfRecSales.registerTempTable("sales")

Veriyi başarılı bir şekilde hdfs’ten okuduk ve bir data frame objesi içerisine yazdık. Şimdi Spark SQL ile yüklediğimiz veriye basit bir kaç sorgu atalım.

hive_context.sql("select count(*) from sales").collect()

hive_context.sql("select * from sales").head()

hive_context.sql("select ordernumber,priceeach  from sales").head(2)

Evet şimdi satışları territory (bölge) alanına göre gruplayalım ve sonuçları bir Hive tablosuna yazalım.

dfterriroty = hive_context.sql("select territory,sum(priceeach) total from sales group by territory")
dfterriroty.registerTempTable("sumterr")
dfterriroty.show()

Elde ettiğimiz sonucu bir hive tablosu yaratıp içerisine yazalım.

hive_context.sql("CREATE TABLE IF NOT EXISTS territory_sum (territory String, total INT)")

hive_context.sql("insert into territory_sum select * from sumterr")

Son olarak Hive’a yazılan datayı kontrol edelim.

hive_context.sql("select * from territory_sum").show()

hive_context.sql("select count(*) from territory_sum").show()

hive_context.sql("select count(*) from sumterr").show()

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

Oracle Cloud Based Machine Learning Alt Yapısı

Herkese Selam,

Oracle Cloud üzerinde analitik çalışmalar yapabilmemiz adına bazı güzel özellikler geliştirmiş durumda. Cloud üzerinde Oracle Advanced Analytics package’i ile gelen bir çok özelliği cloud üzerinde kullanabilmemiz sağlanmış durumda.  Oracle Cloud üzerinden ulaşılabilen bu alt yapıda Cloud veritabanımız üzerinde sorgular çalıştırabilmemiz yanında ML notebook’lar yaratıp analitik çalışmalarımızı gerçekleştirebiliyoruz. Kullanıcıların adaptasyonunu hızlandırmak için ise bir çok örnek çalışma içeriye koyulmuş durumda.  

Bu alt yapının sunmuş olduğu en güzel özellik şüphesiz ki zepplin based bir ML notebook alt yapısının bizlere sunulmuş olması. Bu notebook mekanizması ile web based bir şekilde analizlerimizi yapmamız mümkün. Veriyi görselleştirmede ve analiz etmede oldukça güçlü bir alt yapı sunulduğunu söylemek mümkün.

Oracle Advanced Analytics’in bize sunmuş olduğu onlarca algoritma mevcut. Veritabanızmıda bulunan veriyi veritabanı dışarısına çıkartmadan bize sunulan notebook alt yapısı ile istediğimiz ML modelini datamız üzerinde kullanıp makine öğrenmesi uygulamaları geliştirebilmekteyiz.

Regression, Classification, Anomaly Detection, Clustering, Market Basket Analysis ve Attribute Importance gibi bir çok ML modelini bu alt yapı ile kullanabilmekteyiz.

Daha detaylı bilgi sahibi olabilmek için trial bir Oracle Cloud hesabı açıp bu özellikleri deneyebiliyoruz. Oracle 1 aylık 250 Euro krediye sahip bir hesabı kullanımımıza açıyor.

Ücretisiz bir Oracle Cloud hesabı açmak için linki takip edebilirsiniz. [Oracle Cloud]

Ayrıca Oracle Cloud ML servisini kullanabilmek için güzel bir dokumantasyon hazırlanmış durumda. Bu dokumantasyonu kullanarak Oracle Cloud ML servisini ayağı kaldırıp kullanmaya başlayabiliriz.

https://oracle.github.io/learning-library/workshops/adwc4dev/?version=Self-Guided&page=L300.md

Ayrıca aşağıdaki video izlenerek alt yapının nasıl kullanılacağı ile ilgili fikir edinilebilir. Ek kaynak olarak şu sunuma da bakılabilir.

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

Hibrit Partitioned Tablolar

Herkese Selam,

Partitioning Oracle 8 sürümünden bu yana hayatımızda olan ve benim kişisel olarak Oracle veritabanının en beğendiğim özellikleri arasında. Oracle’da partition alt yapısı büyük hacimli veriler tuttuğumuz tablolarda veriye erişim konusunda sorgu performanslarımızı arttıran, özellikle veri ambarı ortamlarında vazgeçemediğimiz özelliklerin en başında geliyor. Tablolarımızı doğru fiziksel partition tasarımları yaparak büyük hacimli veriyi rahatlıkla sorgulayabilmekteyiz.

Oracle’ın her major veya minor sürüm güncellemelerinde partitioning alt yapısı ile ilgili bir çok yenilik ve güncelleme oldu.  Bu güncellemeler 19c sürümü ile de devam etti. Oracle 19c ile beraber partitioning tarafında yeni bir özellik daha geldi. Bu özelliğin adı hibrit partitioned tablolar.

Partitioning bilindiği üzere büyük tabloları, küçük parçalara bölerek daha kolay ulaşılabilir ve yönetilebilir hale getiriyordu. Bunun yanı sıra bir çok farklı tipte (List-Hash-Range) partitionlar oluşturmamıza sistem olanak sağlıyordu. Ancak kurumsal dünyadaki verinin büyüklüğündeki devasa büyümeler, yasal regülasyonlar ve karmaşıklığın artması bu tarafta yapılacak geliştirmelerin zorunluluğunu arttırdı. Özellikle verinin sürekli online olma ihtiyacı önemli zorluklardan bir tanesi olarak karşımıza çıkmakta.

Yeni gelen hibrit partitioned tablolar ile artık DBA’ler büyük hacimli tablolarda eskisi gibi partitionlama işlemlerini yapabilecekleri gibi veritabanı içerisinde hangi partitionların hızlı bir şekilde sorgulamaya ve güncellemeye açık olacağını seçebilmekteler. Aynı zamanda partitionlara read only erişim vermek gibi bir opsiyonda yine yapılabilmekteler. Bunun yanı sıra yeni gelen bu özellik ile beraber cold ve eski verileri tutan partitionlar farklı external storage’larda saklanabiliyor. Örneğin iki yıldan daha eski datayı tutan partitionları standart file sistem de dosya şeklinde saklayabileceğim gibi hdfs gibi storage cost’u düşük ortamlarda da tutabiliyorum.

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

Oracle 19c Kullanmaya Başlayalım

Herkese Selam,

Oracle kısa bir süre önce yeni DB sürümü olan 19c’yi duyurdu. Oracle 19c yine Cloud base çalışan ve otonom olduğu iddiası ile ilgileri ü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 19c ile ilgili bilgi sahibi olmak için linki takip edebilirsiniz.

Oracle, 19c 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.

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

Spark ile Oracle ve Cassandra Üzerinde Veritabanı İşlemleri

Herkese Selam,

Bu yazıda Spark ile Cassandra veritabanına veri yazma ve veri okuma işlemi gerçekleştireceğim. Umarım farkındalık anlamında faydalı bir yazı olur.

 

Günümüzde veri kaynaklarının ve veri miktarlarının hızla artması, geleneksel yöntemler ile toplanan verinin işlenmesini zorlaştırmıştır. Toplanan veri miktarının artması aynı zamanda verinin işlenme ihtiyacını her geçen gün arttırmıştır. Bu ihtiyaç ve zorlukları takiben büyük verinin hızlı analiz edilmesi ve depolanması ile ilgili çeşitli çözümler üretilmiştir. Spark verinin işlenmesi tarafında günümüzde kullanılan en yaygın ve performanslı bir çözüm iken Cassandra‘da büyük verinin depolanması ve sorgulanması konusunda endüstride yaygın kullanılan veritabanlarından biridir. Bu makalede bu iki güncel teknolojiyi bir arada kullanmayı deneyeceğiz.

Öncelikle bu örneği yaparken kullandığım yazılımlar hakkında bilgi vermek istiyorum.

İşletim Sistemi: SUSE

Spark: Spark 2.1.0

Oracle Database : Oracle 11g R2

Cassandra: Cassandra 3.4

Hadoop: Hadoop 2.7

İlk olarak Spark ile Oracle veritabanına bağlanıp örnek bir veri çekelim ve bunu hdfs’e yazalım.  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

Şimdi Oracle’dan okuyacağımız tabloyu 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);

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()

empDF.show()

empDF.select('EMPNO','ENAME','JOB','MGR','SAL','COMM','DEPTNO').write.format('com.databricks.spark.csv').save('/employees/')

Evet veriyi Oracle’dan Spark ile okuyup hdfs’e yazdık. Şimdi bu veriyi Cassandra veritabanında saklayacağımız tabloyu cassandra’da yaratalım.

CREATE TABLE emp(
empno int,
ename text,	
job text,
mgr text,
sal text,
comm text,
deptno text,
primary key(empno)	
);

Şimdi yeni bir pyspark başlatalım ve hdfs’e yazdığımız veriyi okuyup cassandra veritabanına yazalım. Ancak bunu yapmadan önce cassandra veritabanı ile bağlantı kurabilmek için bazı .jar dosyalarına ihtiyacımız bulunuyor. Bu .jar dosyalarını indirdikten sonra pyspark’ı bu jar dosyalarını kullanarak başlatıyoruz.

* spark-cassandra-connector-2.4.0-s_2.11.jar
* jsr166e-1.1.0.jar
* pyspark-cassandra-0.8.0.jar

/spark-2.1.0-bin-hadoop2.7/bin/pyspark \
  --jars /jar_s/spark-cassandra-connector-2.4.0-s_2.11.jar,/jar_s/jsr166e-1.1.0.jar\
  --py-files /jar_s/pyspark-cassandra-0.8.0.jar \
  --conf spark.cassandra.connection.host= CASSANDRA_IP_ADDRESS
from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext
from pyspark.sql import Row
from pyspark.sql import HiveContext
from pyspark.sql.functions import *


hive_context = HiveContext(sc)
sqlContext = SQLContext(sc)

RecEmp = Row('empno','ename','job','mgr','sal','comm','deptno')


dataEmp = sc.textFile("/employees/")
recEmp = dataEmp.map(lambda l: l.split(","))
dataEmp = recEmp.map(lambda l: RecEmp(float(l[0]),l[1],l[2],(l[3]),(l[4]),(l[5]),(l[6])))
dfEmp = hive_context.createDataFrame(dataEmp)
dfEmp.registerTempTable("emp")


spark = SparkSession.builder \
  .appName('SparkCassandraApp') \
  .config('spark.cassandra.connection.host', 'CASSANDRA_IP_ADDRESS') \
  .config('spark.cassandra.connection.port', 'CASSANDRA_PORT') \
  .config('spark.cassandra.auth.username','CASSANDRA_USER') \
  .config('spark.cassandra.auth.password','CASSANDRA_PASS') \
  .master('local[2]') \
  .getOrCreate()

Hdfs’e daha önce yazdığımız veriyi okudum ve cassandra bağlantılarını kurdum. Şimdi hdfs’den okuduğumuz veriyi cassandra veri tabanına yazalım.

dfEmp.write\
    .format("org.apache.spark.sql.cassandra")\
    .mode('append')\
    .options(table="emp", keyspace="test")\
    .save()

Evet data cassandra’ya başarılı bir şekilde yazıldı. Şimdi cassandra üzerinden veriyi kontrol edelim.

select * from emp;

Verinin başarılı bir şekilde yazıldığını gördük. Şimdi cassandraya yazdığımız veriyi Spark ile okuyup. Pyspark ile console üzerinde gösterelim.

ds = sqlContext \
  .read \
  .format('org.apache.spark.sql.cassandra') \
  .options(table='emp', keyspace='test') \
  .load()

ds.show()

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