Basit Lineer Regresyon

Basit lineer regresyon, 2 nicel veri arasındaki ilişkiyi özetleyen istatiksel bir metoddur. X ekseninde gösterilen 1.değişken tahmin edici, bağımsız değişkendir. Y ekseninde gösterilen 2.değişken ise tahmin edilen çıktı ise bağımlı değişkendir.

Basit lineer regresyon ile bulunan bu ilişki, istatistiksel bir ilişkidir. Bu bağlamda istatistiksel ve deterministik ilişkiden bahsedelim.

Deterministik ilişki, 2 değişken arasındaki ilişkiyi kesin olarak tanımlayan bi denklem mevcuttur. Örneğin;

Picture1Fahrenheit ve Celcius arasındaki ilişkisi kesin olarak gösteren bir denklem vardır ve grafikte görüldüğü gibi her Celcius’a karşılık gelen değer kesin denklem sonucu çıkan kesin değerdir.

Fahr = 95Cels+32

İstatistiksel ilişki ise değişkenler arasındaki kesin olmayan ilişkiyi tanımlar. Örneğin, boy uzadıkça doğru orantılı olarak kilonun da artması beklenir ama bu her zaman doğru değildir. Çünkü bu sonucu etkileyen birden fazla durum vardır biz sadece 1 tane durumu alarak sonuç üretmeye çalışıyoruz. Bütün durumlarla çalışmasında bile kesin sonuç üretilmez.

Regresyon konusu boyunca ev fiyat tahminlemesi örneği üzerinden ilerleyeceğiz. Elimizde evlere ait evin fiyatı, alanı, banyo sayısı, bahçe alanı vs gibi özellikler mevcut, bu özelliklere veri setimize dahil olan evin fiyat tahminlemesini yapacağız. Konumuz Basit Lineer Regresyon olduğu için 2 değişkenimiz olacak, evin fiyatı ($) ve alanı(sq.ft). Evin alanı (bağımsız değişken) x ekseninde, evin fiyatı (bağımlı değişken) y ekseninde yer alacaktır.

Veri setimizde ki evler, evi = (xi,yi)  olarak tanımlanır. Regresyonla oluşan model, evin tahminlenen fiyatına (f(x) fonkisyonu) gerçek fiyattan tahminlenen fiyatın çıkarılması ile bulunan değerin (hata) eklenmesi ile bulunan;

Regresyon model:

yi = f(xi) +  εi

Hatanın 0 olması istenilen durumdur, hatanın pozitif yada negatif olması verinin eğrinin üstünde yada altnda kalmasına göre değişir.

Screen Shot 2016-02-11 at 09.25.39

Veri üzerinde Regresyon nasıl çalışır?

Örneğimizde yola çıkarak şema üzerinden ilerleyelim. Eğitim verisi, yazının başında bahsettiğim gibi evlere ait belirli değerlerdir. Özellik çıkarımında modelde oluştururken kullanacağımız x ,evin alanı. Regresyonla oluşan Model’in (f) sonucu tahmin edilen fiyat y kalite metriği olan evin gerçek fiyatı y ile karşılaştırılarak hata (error) bulunur. Hataya göre model güncellenir.

Screen Shot 2016-02-11 at 09.27.50

Basit regresyon sonucunda oluşan lineer doğru  f(x) = w0 + w1 x , oluşan model ise yi = w0 + w1 xi + εi  dir. w0 ve w1  regresyon katsayıları olan intercept ve slope dur. Veriye uygun olan model nasıl bulunur, yada modelin uygun olma kriteri nedir ? Bunun için uygun doğrunun bulunması gereklidir.

Uygun doğru nedir?

Uygun doğru, veri en yakın şekilde tahminleyen dolayısıyla hatanın az olduğu doğrudur. Bu kavramı öğrencilere ait boy ve kilo bilgilerinden oluşturulmuş örnek üzerinde irdeleyelim.

Picture2

Örnekte 10 tane öğrenciye ait olan veriye 2 tane doğru uydurulmuştur, beraberce hangi doğrunun daha uygun olduğunu bulalım.

Doğru için kullandığımız denklem yi = w0 + w1 xi + εi  idi. Şimdi doğru denklemlerinde öğrenciye ait boy bilgisini h yerine koyup, kilo yani tahminlenen w bilgisini elde edeceğiz. Elimizde bu öğrencilere ait gerçek kilo bilgileride yer aldığı için işlemleri yapıp 2 doğrudan hangisinde daha az hata varsa o doğruyu seçeceğiz. 1.öğrencinin boyu 63 inch, kilosu ise 127 pounds, doğruda bilgileri yerine koyduğumuzda;

w = -266.53 + 6.1376h
= -266.53 + 6.1376(63)
= 120.1 pounds

εi = 127- 120.1
= 6.9 pounds

Her bir doğru için her öğrenci bilgileri ile hata bulunur, hataların karesi alınarak toplanır. 1.doğrunun hata karelerinin toplamı ve 2. doğrunun hata karelerinin toplamı bulunur. İşlem sonucunda ;

w = -331.2 + 7.1 h                     ε1 = 766.5
w = -266.53 + 6.1376 h            ε2 = 597.4

Hesaplamalara göre 2.doğrunun hatası daha küçük olduğu için uygun olan doğru 2.doğrudur. Hataların neden direkt toplanması yerine karelerinin alındığını düşünüyor olabilirsiniz. Bunun nedeni negatif ve pozitif hata oranlarının toplanırken birbirlerini götürmesini engellemektir.

Yukarıda her bir doğru için yaptığımız hata hesabı RSS olarak tanımlanır,

Screen Shot 2016-02-11 at 09.32.23Intercept (doğrunun y ekseninde kestiği nokta) ve slope (eğim) üzerinden yazarsak aynı denklemi,

Screen Shot 2016-02-11 at 09.32.56Sonuç olarak uygun doğru bulunurken doğrulara ait RSS değeri bulunur ve minimum RSS’e ait doğru, en iyi doğrudur.

Model’in ve Doğru’nun incelenmesi

Model, bilinmeyen parametrelerden oluşturulan genel bir denklem iken, doğru ise tahmin edilen intercept ve slope ile yazılan spesifik bir denklemdir.

Screen Shot 2016-02-11 at 09.35.41w0 > 0 ise yani slope (eğim) pozitif ise grafik te pozitiftir,  x arttığında y nin de artacağı manasına gelir.

w0 < 0 ise yani slope (eğim) negatif ise grafikte negatiftir, x arttığında y nin de azalacağı manasına gelir.

Öğrencilerin boy ve kilo bilgilerinden oluşturulan doğruda xi = 0 ise

yi = -266.53 + 6.1376 xi

yi = -266.53

Bu değer boyu 0 inç olan bir öğrencinin kilosunun -266.53 çıktığı anlamına gelir ve manasız bir sonuç olur. Bunun nedeni x’in aralığıdır. (the scope of the model). Ayrıca xi = 0 modelinde iyi bir model olmadığını söyler bize, verinin gürültülü bir veri olduğu sonucuna bizi ulaştırır.

Intercept w^1 ise x ekseninde 1 birimlik değişimin y ekseninde ki karşılığı manasına gelir. Örneğin 66 inç ve 67 inç lik 2 kişinin kiloları tahmin edildiğinde 144.38 – 138.24 = 6.14 pounds bulunur, bu da 1 inç in 6.14 pounds değişimi ifade ettiğini anlatır. Fakat bu model oluşturulurken kullanılan birimler ile tahmin değerleri aynı ise bu yaklaşım doğrudur.

Least Square Optimizasyonu

Veriye en uygun doğruyu bulmak için w0 ve w1 değerlerinin minimum tahmin ederek dolayısıyla RSS i de minimum sağlamış oluruz. Pekala w0 ve w1 değerlerinin minimum değerlerini nasıl buluruz?

Screen Shot 2016-02-11 at 09.39.44

Öncelikle genel olarak fonksiyonlarda minimum ve maksimum nokta nasıl bulunur bakalım. Eğer fonksiyon iç bükey (concave) ise maksimum nokta bulmak için fonksiyonun türevi 0 eşitlenirken, dış bükey (conxex) ise minimum nokta bulmak için fonksiyonun türevi 0 eşitlenir.

Screen Shot 2016-02-11 at 09.40.27

Hill climbing: İç bükey fonksiyonlarda maksimum noktayı bulmak için kullanılan iterative bir algoritmadır. Eğrinin herhangi bir yerinden başlayarak ilerlediğimiz noktayı sağa yada sola doğru kaydırır. Sağa yada sola doğru kayacağımızı fonksiyonun türevinden anlarız. Eğer türev pozitif ise sağa doğru w yi artırarak ilerleriz, negatif ise sola doğru w yi azaltrak ilerleriz. Her attığımız adımla fonksiyonun türevi küçülmeye başlar bu da optimum noktaya yaklaştığımız anlamına gelir. Türev yeteri kadar küçüldüğünde max noktaya ulaşırız ve w u artırmayı bırakırız.

Screen Shot 2016-02-11 at 09.41.34t iterasyonundaki değerler kullanılarak n adım boyu ile t+1 deki değer bulunur.

Hill descent : dış bükey fonksiyonlarda minimum nokta noktayı bulmak için kullanılan iterative bir algoritmadır. Hill climbing algoritması gibi, eğrinin bir yerinden başlayarak sağa yada sola doğru ilerlenir. Sağa yada sola doğru ilerleyeceğimizi fonksiyonun türevi üzerinden anlarız. Türev negatif ise sağa ilerleyip w yi artırıyoruz, pozitif ise sola doğru w yi azaltarak ilerliyoruz.

Screen Shot 2016-02-11 at 09.42.40

Adım boyu seçimi önemli bir konudur 2 algoritma içinde.

  • Sabit adım boyu ile ilerlendiğinde minimum yada maksimum noktaya ulaşmak zaman alabilir.
  • Adım boyunun azaltıralarak ilerlenilmesi ise daha çok tercih edilen bir yöntemdir.

Screen Shot 2016-02-11 at 09.43.24

Adım boyumuz da belli fakat türevin 0 a eşit olduğu optimum noktayı bulamadık, ne zaman durmalıyız. Bunun için bir eşik değeri () belirlenir. Fonksiyonun türevi eşik değerinden küçük olduğunda ilerlemeyi durduruz ve o noktayı optimum nokta olarak kabul ederiz.

Screen Shot 2016-02-11 at 09.43.54

Gradients hesaplanması

Basit lineer regresyonda çalıştığımız fonksiyonlar 2 bilinmeyenli denklemlerdi (w0 ve w1). Çoklu değişkenler yüksek boyutta olduğundan türev yerine gradient hesaplaması yapılır. Gradient, her bir değişkenin kısmı türevinin yer aldığı vectordür. İterative olarak ilerlenilerek optimum nokta bulunur ve nokta bulunurken durulması gereken iterasyon yine bir eşik değeri ile sınırlayarak belirlenir.

Screen Shot 2016-02-11 at 09.44.36p tane değişkenli bir fonksiyondan p+1 lik bir vectör oluşur. Vectörün her bir elemanı değişkenlerin kısmı türevidir. Sonuç olarak w0 ve w1 değişkenli fonksiyonun gradient’i bulunur.

Screen Shot 2016-02-11 at 09.45.41

Gradient descent  ise optimum noktayı bulmak için her adımda azalar ilerlemektir. Yine duracağımız nokta eşik değeri ile belirlenir.

Screen Shot 2016-02-11 at 09.45.46

Least Square Doğrunun Bulunması

Veriye çizilen bir çok eğriden en uygun olanını seçmek için minimum RSS bulacağız,  bunun için RSS ‘in gradientini hesaplamamız gerekmektedir. Örnekte convex bir fonksiyon üzerinden işlemler gerçekleştirilmektedir. Bulacağımız minimum değeri eşsiz (unique) tir ve gradient descent algortiması bu değere yakınsar.

Screen Shot 2016-02-11 at 09.48.41Screen Shot 2016-02-11 at 09.48.45

Screen Shot 2016-02-11 at 09.47.10Screen Shot 2016-02-11 at 09.47.14
Screen Shot 2016-02-11 at 09.47.18

Closed Form Çözümü

Bulunan Gradient’in 0 a eşitlenerek çözülmesi.

Screen Shot 2016-02-11 at 09.49.56Screen Shot 2016-02-11 at 09.50.00

Gradient Descent Çözümü

Tek değişkenli denklemlerde ki hill descent algoritmasının çoklu değişkenli versiyonudur. Yandaki şekil gradient kuş bakışı görünümüdür ve her bir halka aynı fonkiyona aittir. Bir önceki adımdaki değerleri kullanarak bir sonraki değer elde edilir. RSS ‘in gradient hesabında tahmin yerine

Screen Shot 2016-02-11 at 09.51.08

2 Yöntemin Karşılaştırılması

Çoğunlukla tercih edilen yöntem Gradient Descent’tir fakat adım boyu, eşik değeri gibi durumları belirlemek zordur. Closed form da bu tarz belirlemeler olmadığı için daha kolaydır ama değişkenler arttıkça Gradient Descent’ti kullanmak daha verimli olur.

Örnekler:

Kaynaklar:

 

Apache Sentry ile Yetkilendirme

Merhaba arkadaşlar,

Bu yazıda Büyük Veri Güvenlik çözümlerinden Apache Sentry’den bahsetmek istiyorum. Apache Sentry kullanarak hadoop ekosisteminde rol bazlı yetkilendirme ile pekçok Büyük Veri aracı arasında güvenli iletişim sağlanabilir. Şimdi Sentry’nin hive, impala ve hdfs arasındaki çalışma şekillerine bakalım.
Yazını devamında Sentry metadatasına inceleyip, hive üzerinde yetkilendirme uyarlamaları yapıyor olacağız.

1

Hive aracı ile SQL komutları benzeri erişim yapıldığında HDFS’e gittiğimizde Sentry aracı güvenlik denetimlerini yapmakta ve izni olmayan sorguları engellemektedir. Resimde bu aşamayı görebilirsiniz.

2

Impala erişimlerinde ise Impala catalog processi yetkileri hafızasına aldığı için sorgu anında sentry metadatasını sorgulamak yerine,  kendi üzerinde yetki kontrolünü hızlıca yapabilmektedir.

3

HDFS yetkilendirmesinde Sentry’yi tecrübe etmedim ancak bildiğimiz diğer bir çözüm olan ACL ile yetkilendirme metodunun yerini alabilecek kapasitede değil. Hive tablolarının olduğu dosya ve dizinlere erişimde Sentry devreye girer ve erişim kontrolünü yapar.

4

Sentry Veritabanı Modeli:

Sentry veritabanında tablo yapıları incelediğimizde basit bir mimari görmekteyiz.

mysql> use sentry;
Database changed
mysql> show tables;
+------------------------------+
| Tables_in_sentry             |
+------------------------------+
| SENTRY_DB_PRIVILEGE          |
| SENTRY_GROUP                 |
| SENTRY_ROLE                  |
| SENTRY_ROLE_DB_PRIVILEGE_MAP |
| SENTRY_ROLE_GROUP_MAP        |
| SENTRY_VERSION               |
| SEQUENCE_TABLE               |
+------------------------------+

Bu tablolarda önemli olanları özetlersek:

SENTRY_ROLE                  -> Tanımlı roller 
SENTRY_GROUP                 -> Yetkilendirilen işletim sistemi grupları 
SENTRY_ROLE_GROUP_MAP        -> Rol x Grup bilgisi
SENTRY_DB_PRIVELEGE          -> Yetkiler
SENTRY_ROLE_DB_PRIVILEGE_MAP -> Rol x Yetki

Sentry rol bazlı bir yetkilendirme aracı olduğu için kullanıcı bazında yetkilendirme yapılamamakta ve rolleri işletim sistemi bazında gruplarla eşleştirerek, kullanıcılar yetkilendirilmiş olur.
Örnek olarak yetkiler tablosuna baktığımızda:

mysql> SELECT * FROM SENTRY_DB_PRIVILEGE  ;
+-----------------+-----------------+-------------+----------+---------------------+-------------------------------------------------------------------------------+--------+---------------+-------------------+
| DB_PRIVILEGE_ID | PRIVILEGE_SCOPE | SERVER_NAME | DB_NAME  | TABLE_NAME          | URI                                                                           | ACTION | CREATE_TIME   | WITH_GRANT_OPTION |
+-----------------+-----------------+-------------+----------+---------------------+-------------------------------------------------------------------------------+--------+---------------+-------------------+
|               1 | SERVER          | server1     | __NULL__ | __NULL__            | __NULL__                                                                      | *      | 1435230391611 | N                 |
|               6 | URI             | server1     | __NULL__ | __NULL__            | file:///opt/cloudera/parcels/CDH/lib/hive/lib/hive-contrib-1.1.0-cdh5.4.0.jar | *      | 1435758914457 | N                 |
|               7 | URI             | server1     | __NULL__ | __NULL__            | hdfs:///opt/cloudera/parcels/CDH/lib/hive/lib/hive-contrib-1.1.0-cdh5.4.0.jar | *      | 1435759061151 | N                 |
|              11 | TABLE           | server1     | default  | default             | __NULL__                                                                      | select | 1439543565668 | N                 |
|              12 | TABLE           | server1     | default  | defaul              | __NULL__                                                                      | select | 1439543578705 | N                 |
|              14 | DATABASE        | server1     | default  | __NULL__            | __NULL__                                                                      | select | 1439546951486 | N                 |
|              15 | TABLE           | server1     | default  | default             | __NULL__                                                                      | select | 1439547062374 | Y                 |
|              
+-----------------+-----------------+-------------+----------+---------------------+-------------------------------------------------------------------------------+--------+---------------+-------------------+

Gördüğümüz gibi Sentry ile bir jar dosyasına veya tablo / veritabanı için yetkilendirme yapabilmekteyiz.

Tüm gruplara verilen yetkileri raporlamak için aşağıdaki sorguyu kullanabilirsiniz.

mysql > SELECT rolelist.role_name as "ROLE NAME",
               grouplist.group_name AS "GROUP NAME",
               priv.action"ACTION",
               priv.privilege_scope "PRIV SCOPE",
               priv.db_name "DB_NAME",
               priv.table_name "TABLE_NAME",
               priv.uri "URI"
        FROM SENTRY_DB_PRIVILEGE  priv, 
             SENTRY_ROLE_DB_PRIVILEGE_MAP role_priv_map, 
             SENTRY_ROLE_GROUP_MAP role_group_map,
             SENTRY_ROLE  rolelist,SENTRY_GROUP grouplist
        WHERE role_group_map.role_id=rolelist.role_id
              and role_group_map.group_id=grouplist.group_id
              and role_priv_map.role_id=role_group_map.role_id
              and role_priv_map.db_privilege_id=priv.db_privilege_id
              order by 1 ,2 


+------------------------+-------------------------------------+--------+------------+----------+------------+-------------------------------------------------------------------------------+
| ROLE NAME              | GROUP NAME                          | ACTION | PRIV SCOPE | DB_NAME  | TABLE_NAME | URI                                                                           |
+------------------------+-------------------------------------+--------+------------+----------+------------+-------------------------------------------------------------------------------+
| admin_role             | grup1                      | *      | URI        | __NULL__ | __NULL__   | file:///opt/oracle/bigdatasql/bdcell-12.1/jlib/json-serde-1.3.1.jar           |
| admin_role             | grup2                | *      | URI        | __NULL__ | __NULL__   | file:///opt/oracle/bigdatasql/bdcell-12.1/jlib/json-serde-1.3.1.jar           |
...
| role 2              | oracle                              | *      | URI        | __NULL__ | __NULL__   | hdfs:///opt/cloudera/parcels/CDH/lib/hive/lib/hive-contrib-1.1.0-cdh5.4.0.jar |
| role 3     | grup3                      | *      | DATABASE   | db1   | __NULL__   | __NULL__                                                                      |
+------------------------+-------------------------------------+--------+------------+----------+------------+-------------------------------------------------------------------------------+

Şimdi Hive üzerinde Sentry komutlarına bakarsak:

hive> show roles;
+-----------------------------+--+
|            role             |
+-----------------------------+--+
| role1         |
| role2         |
...
...
| admin_role                  |
| deneme                      |
...
+-----------------------------+--+

Bir roldeki yetkilerin listelenmesi:

hive> show grant role admin_role;
+----------------------------------------------------------------------+--------+------------+---------+-----------------+-----------------+------------+---------------+-------------------+----------+--+
|                               database                               | table  | partition  | column  | principal_name  | principal_type  | privilege  | grant_option  |    grant_time     | grantor  |
+----------------------------------------------------------------------+--------+------------+---------+-----------------+-----------------+------------+---------------+-------------------+----------+--+
| *                                                                    |        |            |         | admin_role      | ROLE            | *          | false         | 1435230391611000  | --       |
| hdfs:///app/hive_serde/json-serde-1.3.1.jar                          |        |            |         | admin_role      | ROLE            | *          | false         | 1440163479303000  | --       |
| file:///tmp/hive-json-serde/json-serde-aws.jar                       |        |            |         | admin_role      | ROLE            | *          | false         | 1440061254959000  | --       |
| file:///tmp/hive-json-serde/json-serde-1.3.1.jar                     |        |            |         | admin_role      | ROLE            | *          | false         | 1440061245472000  | --       |
| file:///opt/oracle/bigdatasql/bdcell-12.1/jlib/json-serde-1.3.1.jar  |        |            |         | admin_role      | ROLE            | *          | false         | 1440163459313000  | --       |
| hdfs:///tmp/hive-json-serde/json-serde-1.3.1.jar                     |        |            |         | admin_role      | ROLE            | *          | false         | 1440061264598000  | --       |
| hdfs:///tmp/hive-json-serde/json-serde-aws.jar                       |        |            |         | admin_role      | ROLE            | *          | false         | 1440061271254000  | --       |
| file:///opt/oracle/bigdatasql/bdcell-12.1/jlib/json-serde-aws.jar    |        |            |         | admin_role      | ROLE            | *          | false         | 1440163475556000  | --       |
| hdfs:///app/hive_serde/json-serde-aws.jar                            |        |            |         | admin_role      | ROLE            | *          | false         | 1440163482669000  | --       |
+----------------------------------------------------------------------+--------+------------+---------+-----------------+-----------------+------------+---------------+-------------------+----------+--+

Bir işletim sistemi grubuna verilen yetkilerin listelenmesi:

hive> SHOW ROLE GRANT GROUP `OSgroup1`;
+------------------------+---------------+-------------+----------+--+
|          role          | grant_option  | grant_time  | grantor  |
+------------------------+---------------+-------------+----------+--+
| admin_role             | false         | NULL        | --       |
| role 1                 | false         | NULL        | --       |
+------------------------+---------------+-------------+----------+--+

Örnek bir Sentry yetkilenmesini şu şekilde yapabilirsiniz:

Tanımlı bir veritabanı üzerindeki yetkileri bir gruba devretmek:

hive> create role roleX;
No rows affected (0.072 seconds)
hive > Grant all on database dbX to role roleX;
No rows affected (0.062 seconds)
hive>Grant role roleX to group `OSgroupX`;
No rows affected (0.024 seconds)

Dikkat etmeniz gereken bir nokta, Sentry tanımlamalarını yapan kullanıcının Sentry konfigürasyonlarında yetkili işletim sistemi gruplarına dahil olması gerekiyor. Yoksa aşağıdaki hatayı alabilirsiniz.

hive> SHOW ROLES;
ERROR : Error processing Sentry command: Access denied to erkanul. Server Stacktrace: org.apache.sentry.provider.db.SentryAccessDeniedException: Access denied to erkanul
        at org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessor.list_sentry_roles_by_group(SentryPolicyStoreProcessor.java:450)
        at org.apache.sentry.provider.db.service.thrift.SentryPolicyService$Processor$list_sentry_roles_by_group.getResult(SentryPolicyService.java:953)
        at org.apache.sentry.provider.db.service.thrift.SentryPolicyService$Processor$list_sentry_roles_by_group.getResult(SentryPolicyService.java:938)
        at sentry.org.apache.thrift.ProcessFunction.process(ProcessFunction.java:39)
        at sentry.org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:39)
        at org.apache.sentry.provider.db.service.thrift.SentryProcessorWrapper.process(SentryProcessorWrapper.java:48)
        at sentry.org.apache.thrift.TMultiplexedProcessor.process(TMultiplexedProcessor.java:123)
        at sentry.org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:285)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

Error: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.SentryGrantRevokeTask. SentryAccessDeniedException: Access denied to erkanul (state=08S01,code=1)

Evet arkadaşlar , yazımız burda sonlanıyor. Apache Sentry ile Büyük Veri dünyasında güvenlik tarafında önemli bir noktayı tamamlayabilirsiniz. Umarım faydalı bir çalışma olmuştur.
İyi çalışmalar.

Kaynak:
https://cwiki.apache.org/confluence/display/SENTRY/Sentry+Tutorial

Hive İç İçe Sorgu Kullanımı

Merhaba arkadaşlar,

Bildiğiniz gibi HIVE aracı ile SQL kurallarına benzer bir dil ile sorgulamalar yapabiliyoruz. Ancak bu noktada ticari veritabanlarının sağlamış olduğu kadar fonksiyonel geliştirme yapamadığımız bir durumda söz konusu.

Öncelikle, HIVE’ın veritabanı veya geliştirici kişiler için SQL kolaylığında sorgulama imkanı sağlamasına rağmen, Hadoop ekosisteminin büyük dosya yapıları üzerinde analiz yapma mantığı etrafında geliştiğini unutmamamız gerekiyor.

İşte, bu noktada bazı limitler ile karşılaşıyoruz, çünkü açık kaynak bir dağıtım olan HIVE, sorgularımızı file işlemleri seviyesine getirirken yaptığı dönüşümlerde, sorgu mantığını anlama işleminde, ticari veritabanları kadar etkin bir işleyişe sahip değil.

Bu yazımda bu konuya örneklemek için içiçe sorgular içeren bir işlemde aldığım hatadan ve yaptığım çalışmadan bahsedeceğim.

Aşağıdaki gibi klasik veritabanlarımızda çalışabilecek bir sorgumuzu ele alalım:

SELECT T1.SESSION_ID, T1.KEY, T1.VALUE
  FROM SCHEMA1.T1
 WHERE     session_id IN
              (SELECT SESSION_ID
                 FROM SCHEMA1.T4
                WHERE session_id IN
                         (SELECT t3.SESSION_ID
                            FROM SCHEMA1.T2 t2,
                                 SCHEMA1.T3 t3
                           WHERE     t2.VALUE IN (.........)
                                 AND t3.VALUE = '..............'
                                 AND t2.SESSION_ID = t3.SESSION_ID))
 AND T1.VALUE BETWEEN '2015-May-01 00:00:00' AND '2015-Dec-30 00:00:00’

Bu sorgumuz içiçe select cümleciklerinden oluşmakta, HIVE üzerinde çalıştırdığımda aşağıdaki hatayı almaktayım. Örnekteki HIVE sürümü 1.1.0 .

FAILED: SemanticException Line 1:190 Unsupported SubQuery Expression 'session_id' in definition of SubQuery sq_1 [
..........................
] used as sq_1 at Line 1:120: Nested SubQuery expressions are not supported

Gördüğümüz gibi kızdı, içiçe sorgularda değişkenlerin kullanımı ile ilgili bir problemden bahsediyor.

Açık kaynak araçların dökümantasyonları da gerçekten özenle hazırlanıyor. Bu hatayı arattığımda HIVE’ın dökümantasyonunda içiçe sorgular kısmında aşağıdaki bilgileri gördüm. Benim de bazılarını tecrübe ettiğim bilgiler şu şekilde. İsterseniz kendinizde test edebilirsiniz.

  • Alt sorgulara İSİM verilmesi gerekiyor.
  • Alt sorgular FROM kısmında yer almalı.
  • İçiçe sorgularda Kolon isimleri tablo isimleri ile beraber verilmeli.
  • Alt sorgu, değişkenin sağ tarafında yer almalı
  • IN , NOT IN , EXISTS ve NOT EXISTS kullanılabilir
  • IN ve NOT IN kullanımında tek bir kolon dönülmeli
  • EXISTS ve NOT EXISTS kullanımında alt sorgular en az bir kolon üzerinden eşlenmeli
  • Sorgunun üst seviyesine refereans olan kolonlar ancak WHERE kısmında kullanılabilir

Bu bilgiler ışığında sorgumuzu tekrar yazarsak ve gereksiz selectleri azaltırsak aşağıdaki gibi bir sorgu ortaya çıkıyor:

SELECT t1.SESSION_ID, t1.KEY, t1.VALUE
  FROM SCHEMA1.T1 as t1, SCHEMA1.T4 as t4
 WHERE     t1.session_id = t4.session_id
       AND t4.session_id IN
              (SELECT t3.SESSION_ID
                 FROM SCHEMA1.T2 as t2, SCHEMA1.T3 as t3
                WHERE     t2.VALUE IN
                             (..................)
                      AND t3.VALUE = '........................'
                      AND t2.SESSION_ID = t3.SESSION_ID)
      AND t1.VALUE BETWEEN '2015-May-01 00:00:00' AND '2015-Dec-30 00:00:00';

Burda gördüğünüz gibi tablo ve sorgulara İSİM verdim yani etiketledim ve alt sorgulardaki kolon isimleri açıkca tablolara bağlandı. Gereksiz select cümleleri çıkartıldı.

Sorguyu bu halde çalıştırdığımda aşağıdaki gibi başarılı bir şekilde sonlanmaktadır.

2015-12-08 01:03:28     End of local task; Time Taken: 4.188 sec.
Execution completed successfully
MapredLocal task succeeded
Launching Job 4 out of 4
...
2015-12-08 13:03:52,249 Stage-6 map = 94%,  reduce = 0%, Cumulative CPU 45.93 sec
2015-12-08 13:03:53,265 Stage-6 map = 100%,  reduce = 0%, Cumulative CPU 49.32 sec
MapReduce Total cumulative CPU time: 49 seconds 320 msec
Ended Job = job_1448973637348_0844
MapReduce Jobs Launched:
Stage-Stage-1: Map: 2098  Reduce: 1099   Cumulative CPU: 1452028.98 sec   HDFS Read: 3916425613388 HDFS Write: 105504 SUCCESS
Stage-Stage-4: Map: 1982  Reduce: 1099   Cumulative CPU: 120765.75 sec   HDFS Read: 259305477973 HDFS Write: 7688479 SUCCESS
Stage-Stage-6: Map: 16   Cumulative CPU: 49.32 sec   HDFS Read: 482421 HDFS Write: 0 SUCCESS
Total MapReduce CPU Time Spent: 18 days 4 hours 54 minutes 4 seconds 50 msec
OK
Time taken: 6884.603 seconds

Bu örnekte kullandığım tabloların büyüklükleri bu şekilde.

T1 -> Satır# 902.942.362.399 , on disk   3.5 T
T2 -> Satır#  28.861.733.076 , on disk 129.8 G
T3->  Satır#  29.576.675.998 , on disk 111.6 G
T4- > Satır#  29.577.122.203 , on disk  66.2 G

Evet arkadaşlar, çalışma burda sonlanıyor. Umarım farkındalık anlamında faydalı bir yazı olmuştur. Sorularınız olursa iletişim kurmanızdan memnuniyet duyarım.

İyi çalışmalar.

Kaynak:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SubQueries#LanguageManualSubQueries-SubqueriesintheWHEREClause
https://issues.apache.org/jira/browse/HIVE-784

Kmeans ve Kmedoids Kümeleme

Bu yazımda sizlere Veri Madenciliği’nin Kümeleme (Clustering) alt başlığının iki üyesi olan K-means ve K-medoids’ten bahsetmeye çalışacağım.

Öğrenme Çeşitleri

Gözetimli öğrenme, sonuçları bilinen veri seti ile modelin oluşturulması ve oluşan modele sonuçları bilinmeyen veri seti verildiğinde, sonuçların tahmin edilmesidir. Örneğin, çalışmada hasta kişiler tahmin edilecekse hasta olan ve olmayan kişilerin bilgisi ile model oluşturulur. Daha sonra modele x kişisinin bilgileri verildiğin x kişisinin hasta olup olmadığı tahmin edilir.

Gözetimsiz öğrenme, sonuçları hakkında bilgi sahibi olunmayan veri setinin tahminidir. Örneğin, elimizde hasta olan ve hasta olmayan kişilere ait bilgileri var fakat kimin hasta olduğunu bilmiyoruz. Bu sefer elimizde olan bilgilere göre kişileri iki gruba ayırıyoruz.

Kümeleme

Kümeleme yöntemi, veriyi gruplara veya kümelere ayıran gözetimsiz öğrenme çeşididir. Veri, grup içindeki elemanların kendi içindeki benzerliği ve grupların birbirine benzememesi kıstası ile birbirinden ayrılır. Kümeleme de esas nokta sınıflar arasındaki benzerliğin minimum, sınıfın kendi içindeki benzerliği maksimum olmasını sağlamaktır. Bu benzerlik uzaydaki veri elemanlarının uzaklık fonksiyonlarına göre birbirlerine olan yakınlığı bazında hesaplanır. Kümeleme bu özelliği ile otomatik sınıflandırma olarak da adlandırılır.

Kümeleme, iş zekası, görüntü örüntü tanıma, web arama, biyoloji ve güvenlik alanlarında yaygın olarak kullanılır. Örneğin, görüntü tanımada el yazısı karakterlerini bulmak için veri kümelere ayrılır.

Kümeleme, bazı uygulamalarda veriyi benzerliğe göre gruplara ayırmasından dolayı aynı zamanda veri segmentasyonu(data segmentation) olarak adlandırılır. Ayrıca ayrılan gruplara benzemeyen veri elemanları ortaya çıktığı için uç değer bulma(outlier detection) uygulamalarında da kullanılır.

Veri madenciliğinde kümelemenin sağlıklı yapılabilmesi için, verinin ölçeklenebilir olmalıdır. Ayrıca kümeleme, veri tipinden bağımsız olarak çalışabilmeli, gürültülü veri ile uğraşabilmeli, girdi sayısının değişkenliğine karşı hassasiyetinin olmaması ve çok elemanlı/boyutlu veri ile çalışabilmelidir.

Kümeleme yöntemleri, bölümleme, hiyerarşik, yoğunluk tabanlı ve ızgara tabanlı olmak üzere dört şekilde uygulanır. Bölümleme metodu, K-means ve K-medoids yöntemlerinden oluşmaktadır.

K-means

Küme merkezi(centroid) tabanlı bir tekniktir. Bölümleme, D elemanı k kümeye ayırır. Oluşan kümelere C dersek,  C 1 den C k’ya k küme adet oluşur ve her küme D nin altkümesi C i ⊂ D  iken kümeler arasında (1 ≤ i, j ≤ k) benzerlik C i ∩ C j = ∅ yoktur.

Algoritma, n elemanı k tane kümeye ayırma işlemi ile başlar.  K centroid belirlendikten sonra elemanların k centroid lere olan uzaklıkları hesaplanır ve k centroid en yakın noktalar bir kümeyi oluşturur. Küme elemanlarının ortalaması alınır ve centroid ler tekrar belirlenir. Eğer  centroid değişmişse noktaların merkeze olan uzaklıklarına göre hangi centroide ait oldukları bulunur ve bu işlem küme merkezleri (centroid) stabil hale gelene kadar devam eder.

Avatajları:

  • Küme sayısı az ise büyük veri setlerinde hiyerarşik kümeleye göre daha hızlıdır.
  • Eğer veri seti özellikle küresel ise hiyerarşik kümelemeye göre daha sıkı kümeler oluşturur.

Dezavantajları:

  • Üretilen kümeler arasında kıyas yapmak zordur.
  • Sabitlenmiş küme sayısı, küme sayısının tahminini zorlaştırır.
  • Küresel olmayan veri setlerinde iyi çalışmaz.
  • Farklı başlangıç bölümlemeleri ile farklı sonuç kümeleri elde edilir.
  • Gürültülü veriye duyarlıdır.

K-medoids

Nesne temelli bir tekniktir. K belirlendikten sonra k tane centroid belirlenir. Elemanların centroide uzaklığına göre hangi centroide ait oldukları bulunur. Centroid ler stabil duruma gelene kadar noktaların centroidlere olan uzaklıkları hesaplanır ve yeni cetroidler belirlenir.

İki algoritma arasındaki temel fark merkezin (centroid) belirlenmesidir. Kmeans’te noktaların ortalaması alınırken, K-medoids’te noktaların centroide olan uzaklıkları hesaplanır.

Avantajları:

  • Daha iyi ve kararlı kümeleme sonuçları verir.
  • Verilerin işleniş sırası ve ilk atamada ki merkez seçiminin kümeleme üzerinde etkisi yoktur.
  • Merkezi elemanların kümeyi temsil etmesinden dolayı gürültülü veriye karşı duyarlı değildir.

Dejavantajları:

  • Uygun küme sayısının belirlenmesi için birden fazla deneme yapmak gerekir.

K-means ve K-medoids Kıyaslaması

K-means

  • Küme, küme merkezi ile temsil edilir.
  • Gürültülü veriye karşı duyarlıdır.
  • Büyük veride daha güvenilirdir.

K-medoids

  • Küme, kümede ki herhangi bir eleman ile temsil edilir.
  • Gürültülü veriden etkilenmez.
  • Küçük veride daha güvenilirdir.

Cluster sayısını belirlenmesi için çeşitli yöntemler

  • Deneysel yöntem: Veri setindeki nokta sayısı n ise cluster sayısı √n/2
  • Elbow Yöntemi: Cluster sayısı başlangıç olarak 1 alınır ve varyans hesaplanır. Varyans değeri sabitlenene kadar cluster sayısı artırılmaya devam edilir.
  • Silhouette Coefficient: Bu değer ile kümelerin birbirinden ne kadar farklı olduğunu bulmuş oluruz. +1 ile -1 arasında oluşan değer +1’e ne kadar yakın olursa cluster sayısının o kadar iyi olduğunu teyit ederiz. Kümelerin kendi içlerindeki ve kümelerin kendi aralarındaki ortalama uzaklık arasında oluşturulan denklem ile bu değer bulunur.

Spark ile K-means örneği: (scala dili ile)

import org.apache.spark.{SparkContext, SparkConf}
import org.apache.spark.mllib.clustering.{KMeansModel, KMeans}
import org.apache.spark.mllib.linalg.Vectors

object Kmeans {
  def main(args: Array[String]) {
    if (args.length < 4) {
      println("usage: input output numClusters maxIterations")
      System.exit(0)
    }

    val conf = new SparkConf
    conf.setAppName("Spark KMeans Example").setMaster("local")
    val context = new SparkContext(conf)

    val input = args(0)
    val output = args(1)
    val K = args(2).toInt
    val maxIteration = args(3).toInt
    val runs = calculateRuns(args)
    
    val data = context.textFile(input).map {
      line => Vectors.dense(line.split(',').map(_.toDouble))
    }.cache()

    val clusters: KMeansModel = KMeans.train(data, K, maxIteration, runs)
    println("cluster centers: " + clusters.clusterCenters.mkString(","))

    val vectorsAndClusterIdx = data.map{ point =>
      val prediction = clusters.predict(point)
      (point.toString, prediction)
    }

    vectorsAndClusterIdx.saveAsTextFile(output)

    context.stop()
  }

  def calculateRuns(args: Array[String]): Int = {
    if (args.length > 4) args(4).toInt
    else 1
  }
}

Girdi:

818.21,809.83
8.37,850.78
680.43,698.76
913.88,173.43
579.87,135.51
204.13,800.01
700.44,758.47
657.36,745.11
290.3,109.27
246.64,885.54

Çıktı:

([818.21,809.83],1)
([8.37,850.78],2)
([680.43,698.76],1)
([913.88,173.43],0)
([579.87,135.51],0)
([204.13,800.01],2)
([700.44,758.47],1)
([657.36,745.11],1)
([290.3,109.27],0)
([246.64,885.54],2)

Kaynaklar
Data Mining Concepts and Techniques Third Edition
Jiawei Han
Micheline Kamber
Jian Pei

Veri analizinde yeni alışkanlıklar

Veri işlemede kullanılan alet ve yöntemler baş döndürücü bir hızla gelişip değişiyor. Bunun sonucu olarak, eski adet ve alışkanlıklar ile devam ettirmeye çalıştığımız iş süreçlerinde çıkan sıkıntılar ve çıkmazlar sıradanlaştı. Bu yazıda, özellikle veri analizi konusunda çıkan sıkıntıları aşmak için alet kutumuza girmesi gerekli olan göreceli yeni üç aletten; data notebooks ve polyglot dillerden ve bu dünyanın getirdiği ek zorlukları aşmak için alet kutumuzda olması gereken docker container lardan bahsedeceğiz.

Çok dillilik (Polyglot)

Son zamanlarda büyük veri işleme ile ilgili isminden sıkça bahsettiğimiz birçok alet (tool), kendi dilleri ile birlikte geldi. Bunlara alana özel diller (domain specific languages – DSL) deniyor ve yazılım dilleri arasında geçiş yapılmayan tutucu eski günleri geride bıraktığımızı haber veriyorlar. Ayrıca, birçok yerde; R dili mi, Python mu tartışmaları yaşanırken, gerçek şu ki, bu iki dilin de aynı projede hatta aynı kişiler tarafından kullanılabildiği bir dönemi yaşadığımızı kabul etmemiz ve alışkanlıklarımızı buna göre değiştirmemizde fayda var. Polyglot olmanın normal olduğu bir dünyada yaşıyoruz artık.

Notebooks

Özellikle veri bilimi açısından bakıldığında, normal bir bilim insanının yaptığı gözlemleme, analiz ve sonuç çıkarma süreçlerinin, veriyi bilimsel olarak incelerken de geçerli olacağını düşünmek çok doğal olacaktır. Bu süreçte, gözlem ve analiz sonuçlarının veri ve bazı şekil ve grafiklerle zenginleştirilmiş halde olduğunu da eski örneklerinden (1) görmüşüzdür.

Alışkanlıkların değişmesi

Veri işleme, veriden sonuç çıkarma konusunda çalışan veri analisti, veri madencisi gibi ünvanlar ile çalışanlar için, bir dile bağlı olarak çalıştıkları dönemdeki alışkanlıklar ile devam etmeleri artık mümkün değil. Yeni veri bilimcileri için ise zaten doğal özelliklerden birisi.

Birbirinden bağımsız ve farklı birikimlerdeki akademik ve ticari dünyadan çok değerli insanlar teknolojinin getirdiği olanaklar sayesinde coğrafi yerden bağımsız olarak birlikte çalışıp üretebiliyorlar. Bunun sonucunda daha öncesinde hiç olmadığı kadar üretken bir yapı ortaya çıktı. Aynı problemi çözmeye odaklanmış çok sayıda grup bir araya gelip çeşitli çözümler üretiyorlar. Bu problemlerin hiç şüphesiz ki en çok ilgi çekenlerinden birisi, büyük verinin işlenmesi ve analiz edilmesidir.

Karmaşa

Değişik gruplar ve farklı birikimler, çözüme farklı yazılım dilleri ve aletleri olarak yansıyor. Bunun sonucunda pek çok alana özel dil geliştiriliyor. Bu dillerin belirli problemlerde kullanılması gerçekte daha iyi çözümler konusunda olanaklar sağlarken, çözüm ortamlarının karmaşasını da arttırıyor.

Daha önce veriyi belli dillerle işlemek alışkanlığına sahip birçok eski BT çalışanını ürküten bir durum bu. Öyle ya, RDBMS olan klasik bir ortamda çalışıyorsanız SQL biliyorsunuz, prosedürel algoritmalar için PL/SQL, T-SQL gibi dilleri öğrendiğinizde veri işlemenin birçok konusuna hakim oluyorsunuz. ETL aletlerini de kullanma beceriniz varsa, iş zekası katmanında kullanılan küp dilleri haricinde uçtan uca bir geliştirici, analist olabilirsiniz. Eğer veri madenciliğinin amiral gemisi SAS olan bir ortamda çalışıyorsanız, SQL yanında SAS programlama ve biraz da SAS Macro programlamayı bildiğinizde veriyi her türlü işleyebilirsiniz.

Bu az seslilikten çok sesliliğe geçişte, artık herkesin bildiği NoSQL veri tabanlarının neredeyse her birinin farklı bir DSL i olması eski dünya ve yenidünya sakinlerini birbirlerinden derin çizgilerle ayırıyor.

Uyum

Operasyondan sorumlu olanlar iyi bilirler, uyumluluk production sistemlerinde en büyük problemlerden birisidir. Bu nedenle bırakın farklı bir dilde çözüm üretmeyi, farklı bir versiyonda çözüm üretilmesi bile homurdanmalara yol açabilir. Bunun haklı sebepleri de var tabii ki, geliştirme ortamında çalışan bir kodun production da patladığı konusunda yaşanılan çoğu anlatılmamış kötü tecrübeler vardır.

Peki bu yeni dünyada, bir sürü belki de ismini bile duymadığımız dillerin kullanımı, operasyonel süreçleri nasıl etkiler? İşte bir sorun da buradan çıkıyor. Eski alışkanlıklar ile devam edildiğinde yenidünya çözümleri production tarafında iyiye gidişi desteklemez.

Dilemma

Peki bu paradoks gibi görünen durum nedir? Çok dillilik desteklenecek, ama aynı zamanda operasyonel işlemler de daha rahat yürüyecek. Bu noktada yenidünyanın yeni çözümü devreye giriyor. Şu anda iki farklı temsilcisi olan bu çözümün biz container tarafından bahsedeceğiz.

Containers

Uygulamaların production a kurulmadığını, geliştiricinin ortamının kontrollü olarak aynen kendi içlerinde paketlenerek çalıştırıldığını düşünelim. Teknik tabiri ile dilden bihaber (language agnostik) bir ortamdan bahsediyoruz. Her uygulama en uygun tool ve dil ne ise onunla geliştiriliyor.

Somutlaştırma

Buraya kadar genel hatları ile anlattığım süreci biraz somutlaştırmak için bir örnek üzerinde gideceğim. Veri bilimi konusunda da, kendimce çalışmalar yapan bir kişi olarak bir veri setinin alınması ve işlenmesi konusunda dilden bağımsız bir ortamda çalışma yapmak amacı ile ortaya çıkmış olan polyglot notebook lardan bazılarını inceleyip, bilinçli bir tercih yapmaya karar verdim. Mevcut seçenekler; Spark-notebook, Jupyter, Beaker-notebook, Zeppelin vb. Bunların her birini indirip makinamda kurulu olan sanal Ubuntu OS üzerinde kurup çalıştırmayı denedim. Yaklaşık iki gün boyunca indirme, kurma, ayarlamalar vb işlerle geçti. Yukarıda bahsettiğim, uyum problemi burada da çıktı. Örnek vermek gerekirse, scala 2.11 kurulu idi, ama kurduğum yazılım scala 2.10 istiyordu, Maven upgrade gerekti. Bir yerden sonra onu kur, bunu ayarla, sonuçta sadece spark-notebook u çalıştırabildim. Onda da istediğim şeyleri yapmada sıkıntı çıkınca, esas uğraşacağım işlere zaman ayıramadığımı fark ettim. Hedeften sapmıştım.

Evreka !

Bu süreçte eski dünyanın alışkanlıklarını terk etmek gerektiğine hükmettiğim yazımı ve katıldığım “Dockerize Yourself! Infinite Scalable Systems With Docker” da devveri.com yazarlarından Hüseyin Babal ın güzel uygulama+sunumunu hatırladım. Zaten Docker ile Mongo DB kullanımı ile ilgili bir yazısı da vardı sitemizde.

Değişim

Sonuçta, notebooklar ile ilgili çalışmayı docker container lar kullanarak yapmaya karar verdim. Docker ile ilgili dokümanları okumam ve ilgili yazılımları indirdikten sonra ortamı hazırlamam bir gün sürmedi. Akşamında beaker-notebook u kurup çalıştırmam birkaç dakikamı aldı. Bu işin güzel tarafı artık benzer kurulumları yapmak için baştaki eforu sarfetmem gerekmeyecek. Tabii uygulamaların network ayarlarının yapılması, uygulamalar arası veri alışverişi, port paylaşımları gibi teknik konularda uzmanlaşmak biraz daha vakit alacak ama ben yine de değişim isteyip, benim gibi nereden başlayacağını bilemeyenler için bir örnek sunmak istedim.

Örnek

Öncelikle Docker ın genel yapısından kısaca bahsedeyim. Docker container ile bir uygulamanın çalışması için gerekli olan dosya sistemi dahil her şeyi, bir pakette toplamayı sağlayan bir yapı sunuyor. Bu yapı iki türlü oluşturulabiliyor, daha önce oluşturulmuş paketlenmiş çalıştırılmaya hazır image dosyaları halinde veya installer ile. Image dosyaları ile daha önce var olan bir image de değişiklik yaparak saklayabiliyoruz. Installer ile özel bir script dili ile nelerin kurulacağını söylüyoruz. Bunun avantajı paylaşımı çok kolay oluyor ve şeffaf oluyor.

Bu oluşturulan image lar diğer insanlarla paylaşılmak istendiğinde bir repository ihtiyacı doğuyor. Bunu Docker şirketi sağlıyor. Bu repository den ücretsiz ve ücretli olmak üzere çeşitli yararlanma olanakları var.

Kurulum

Ben Windows olan bir makinaya kurulum yaptım. Kurulum detayları ile ilgili bilgilere buradan bakabilirsiniz. Docker Toolbox ile kurulum çok kolaylaştırılmış. Kurulum tamamlandıktan sonra ilk yapılan iş Docker Toolbox Terminal i tıklayıp açmak. Docker bir Linux uygulaması olduğu için Windows içinde Linux komutları yazmayı sağlayan bir emulator uygulaması. Linux ortamı olduğunu $ işareti ile anlıyorsunuz. Bu işaretin yanına tıklayıp Docker komutlarını yazabilir hale geliyoruz.

Her şeyin yolunda gittiğini anlamanız için

docker run hello-world

yazarak ilk uygulamanızı çalıştırabilirsiniz. Bu komut hello-world image ını local de arıyor, ilk seferinde bulamadığı için Docker Hub Repository ye gidip çekiyor. Dolayısı ile bu işlemin süresi, image ın büyüklüğü ile doğru orantılı oluyor. Sonrasında localde olduğu için hızla çalışıyor.

Bu hızlı girişten sonra gelelim esas amacımıza. Var olan Notebook lar içinden deneyip bakarak bir seçim yapmak istiyorduk. Bunu hızlı bir şekilde yapabilmek için bu notebookları kurulum ve ayarlamalar ile vakit kaybetmemek için Docker container ları kullanalım istiyoruz.

Burada biz bir tanesi için yapacağız, diğerlerini isteyenler kendileri yapabilirler. Ben daha önce görmediklerimden olduğu için aday olarak Beaker Notebook u seçtim. Genel olarak eski IPython notebook dan faydalanılmış nispeten yeni bir notebook ürünü. Başlama sayfasına (getting started) geldiğinizde sayfada uygulamayı kurmak için çeşitli alternatifler sunulmuş. Bu alternatiflerden Docker container ı seçtiğimizde docker hub daki açık repository e ilgili sayfaya ulaşıyoruz. Burada sayfanın sağında bulunan Docker pull commands kutusunun altında bulunan

docker pull beakernotebook/beaker

kopyalayıp, Docker Toolbox Terminal indeki $ işaretli komut satırına kopyalıyoruz. Enter a bastığımızda lokalimizde beakernotebook/beaker isimli image olmadığı için repository e bağlanıp çekmeye başlıyor. Tabii bu büyük bir imaj (4GB) olduğu için bekleme zamanı uzun oluyor.

Sonuçta her şey yolunda gittiğinde image lokalinize gelmiş olacak. Kontrol etmek için

Docker <command>

Komut ailesinden

docker image

komutunu kullanabiliriz.

Docker makinası
Docker makinası

Kısaca açıklayacak olursak, docker sanal bir makinanın özelliklerinden container bağımsız olanları ayrı bir şekilde çalıştırdığı için, birden fazla container için bir makine çalıştırarak sistem kaynaklarını ekonomik kullanmış oluyoruz. Aynı anda birden fazla makine çalıştırmak da mümkün. Bu aynı zamanda uygulamaların izalasyonunu sağlıyor. Artık containerdan istediğimiz sayıda çalıştırabiliriz.

Bu kısa açıklamalardan sonra beaker-notebook a dönersek;

$ docker run -p 8800:8800 -t beakernotebook/beaker

Komutu ile notebookumuzu çalıştırıyoruz. Çalıştırırken container ın kullandığı port ile localhost umuzun port ları arasında bir mapping yapmamız gerekiyor doğal olarak.

Connecting to https://29e59df53085:8800/

Submit this password: aKOMNCaRnIHUfnr

 

İlk çalıştırmada https üzerinden nasıl bağlanacağımız ve bağlantı sırasında sorulan şifreye verilecek rasgele atanmış şifremizi bir yere not ediyoruz. https adresi olarak yukarıdaki şekilde verdiğimiz URL i kullanmamız uygun olacak.

https://192.168.99.100:8800/

beaker notebook
beaker notebook

Bu ekran geldiği an Notebooks dünyasına girmiş oluyoruz. İlk cümleye dikkat edersek

“Click below to get started coding in Python, R, JavaScript, Julia, Scala, Java, Groovy, and Ruby.”

Bu dünya polyglot bir dünya.

Polyglot notebooks
Polyglot notebooks

Bu üçleme; Docker, uygun bir data notebook ve polyglot diller yazının başında belirttiğimiz dünyanın üç temel unsuru.

Demokratik, çoğulcu bir dünya

Bu dünyada geliştiriciler, problem çözücüler probleme en uygun dili seçip, istedikleri versiyonu kullanma özgürlüğü kazanıyor. Python dünyasının versiyon 2 ve 3 arasındaki uyumsuzluklar bu dünyada problem olmaktan çıkıyor. En güzeli de genişleyebilirlik özelliği containerlar sayesinde çoklamanın kolay olması ile problem olmaktan çıkıyor.

Sonuç

Yazının başında belittiğimiz üç alet; data notebooks ve polyglot diller ve bu dünyanın getirdiği ek zorlukları aşmak için docker container lar kullanarak verimizi analiz edebileceğimiz bir ortamı kolayca kurduk. Belirli bir örneği başka bir yazıya bırakarak daha fazla uzamadan bu yazıyı sonlandıralım.

Daha İyi Bir Veri Bilimcisi Olmanız İçin 5 İnanılmaz Yol

Bu yazı datasciencecentral.com adresindeki bir blog yazısının çevirisidir

titleÇoğu veri bilimcisi, ellerinin mümkün olduğunda çabuk bir şekilde veri ile kirlenmesini isterler ama hemen modellemeye başlamadan önce projenin detaylarına girmek önemlidir. Aklında iş fikri olan bir veri bilimcisi bu işte yoluna çıkacak güç faktörleri, sorunları başarıya ulaşmak için hesaplamalıdır. Farklı aşamalarda çeşitli bilgilere, yöntemlere ihtiyacımız olur ama ilk olarak “understanding the business” cümlesinin ilk aşamasını geçmiş olmak ve başarılı bir veri bilimcisi haline gelebilmek için detaylara hızlı ve derin bir şekilde dalmak gerekiyor.

1 – Bir Kaynak Envanterini Yönetmek

01
Bir veri bilimcisi olarak, bir veri bilimi projesinin ulaşılabilir kaynaklarının girdi ve çıktılarını bilmek önemlidir. Bu sadece analizini çalıştırmak için ne kadar bilgisayar gücüne ihtiyacının olduğunu anlamak ile ilgili değildir. Profesyonel bir veri bilimcisinin iş uzmanları, veri uzmanları, teknik destek ve diğer veri bilimcileri gibi şeyleri göz önünde bulundurması gerekiyor. Ayrıca sabit ekstreler, canlı veriye erişim, warehouse veri ve kullanıma hazır veri gibi önemli değişkenlerimiz var. Ancak, donanım ve yazılım gibi bilişim kaynaklarının da unutulmaması gerekiyor. Ciddi bir şekilde düşünmeden bir proje alan herhangi bir veri bilimcisi, mayın tarlasına yürüyor demektir ve birşeylerin ne zaman patlayacağını asla bilemez.

2 – Gereksinimleri, Varsayımları ve Kısıtlamaları Anlamak

02
Çoğu veri bilimcisi iş hedefi olarak ne seçtiyse, tahmin sonuçları noktasında ortalamadan daha yüksek olmak isterler ama başarılı veri bilimcileri bilir ki; doğru tahmin bundan daha fazlasıdır.
Örneğin tüm varsayımları dikkate alan bir veri bilimcisi projede hem iş perspektifini hemde analitik perspektifi anlamış demektir. Bu varsayımlar pek çok formda olabilir -Ancak birisi çirkin yüzünü gösterdiğinde bu genellikle veri ile ilgili olur. Bazen işe bağlı olarak, varsayımlar doğrulanabilir değildir.- ve bunlar en risklileri olabilir. Bu riskli varsayımlara mümkünse listenin en üstünde yer ve öncelik verilmelidir çünkü bunlar keşfetmeyi hedeflediğin sonucun doğrulunu etkileyebilir.

Veri bilimcileri bazı tuzaklar için dikkatli olmalıdır. Verinin biraz yada bütün olarak kaynakların erişilebilirliğini, hatta teknoloji kısıtlamalarını düşünmemiz gerekir. Bu kısıtlamalar geldiğinde olayın dışında düşünmemiz, büyük resmi görebilmemiz gerekir. Örneğin, veri boyutu modelleme için uygun mu? Bu açıkça ortadadır fakat birçok veri bilimcisi bu kritik göz önünde bulundurma kısmını kaçırıyor.

3 – Riskleri ve Olasılıkları Belirlemek

03

Daha önce hiç sırf dış gecikmeler yüzünden herşeyin parça parça olarak sona erdiği bir projeye başladınız mı? Böylesine şeyler için ön hazırlıkları planlamak akıllıca bir hareket olurdu. Çoğu veri bilimcisi burayı kısa kesiyor ve işleri sağlam temeller üzerine oturtmuyor. Böyle hazırlıklar, ihtiyacınız olduğunda gerçekten işe yarayabilir. Bu gibi durumlarda bir ya da iki yedek plan son derece yardımcı olabilir. Bilinmeyen riskler projenizde, sizi başarı rayından çıkarır. Tecrübe der ki; Her zaman başarısız olmanıza sebep olacak birşey vardır. Yani başlangıçta alternatifleri planlamak gerekir.

4 – Dökümanı Anlamak

04
‘Ne demek istiyorsun?’ sorusu iş ortamında disiplinler arası bir takımla çalışıyorsanız gerçekten cevap verilmesi gereken önemli bir sorudur. Konu kendi alanımıza gelince ortamdaki diğer insanlarla aynı dili konuşmadığımız açıktır. Herşeyden önce uygun iş terminolojisinin bir çalışma sözlüğünü hazırlamak sizi ve diğerlerini aynı rotada tutacaktır. Bir diğer iyi uygulama ise tanımlamalar ve resimlendirilmiş örnekler ile bir veri bilimi terminolojisi oluşturmaktır, ama bu direkt olarak elinizdeki işin problemleri ile ilgili olmalıdır. Tabiki bunun 700 sayfalık bir döküman olması gerekmez, en doğrusu tüm taraflar için ikna edici ve yararlı şeyler kullanmaktır. Unutmayın diğerlerinin bir veri bilimcisi olarak senden istediği; sadece en üst seviyede çalışanlar diğerlerinin derinlemesine istatistik ve kod bilmesini ister.

5 – Maliyet ve Faydayı Hesaplamak

05
Bu kısım veri bilimi projenizdeki değeri gösterebilmek için iyi bir yöntemdir. Hatırlayın, işi destekleyen bir profesyonel olarak ‘Bu veri bilimi projesini değerli kılan şey midir?’ sorusunu sormak ve cevaplamak önemlidir. Projenin birleşmiş maliyetlerin potansiyel faydalara karşı basit bir karşılaştırması ve bunun başarılı bir şekilde yapılması sizin ve işiniz için büyük bir yol katedecek olamanız demektir. Daha projenin başında bunu bilmek size ve organizasyona iş bitiminde açıkça fayda sağlayacaktır. Bana göre bu soruları sormamak ve cevap vermemek, başarılı bir Veri Bilimcisi olma yolunda kariyerinizi limitleyen bir harekettir. Bu işi kendiniz üstlenmek için sağduyuyu kullanın ve işinizde meslektaşlarınızın veya yöneticilerin bunu yapmanızı istemesini beklemeyin.

Özet

Veri bilimi iş bağlamında olgunlaştıkça bir Veri Bilimcisi durum değerlendirmesinde, bir envanter almakta, risk ve riskin gelişme ihtimalini öğrenmekte ve başarılı bir veri bilimi projesine sahip olmanın maliyet avantajlarını anlamakta daha uyanık olmalı ve farkındalığını arttırmalıdır. Her veri bilimcisi bu adımları uygulamaz, ama tekrar, her veri bilimcisi son derece başarılı değildir. İş’te sağlam bir veri bilimi metodolojisi çöldeki bir damla su gibidir. Size en çok ihtiyacı olduğu zamanda susamış organizasyonunuzu bırakmayın.

Kaynak; http://www.datasciencecentral.com/profiles/blogs/5-unbelievable-ways-you-can-be-a-better-data-scientist-in

R ile Korelasyon, Regresyon ve Zaman Serisi Analizleri

KORELASYON

Korelasyon rassal iki değişken arasındaki doğrusal ilişkinin gücünü ve yönünü ifade eder.

Bu konuda R ile bir çalışma yapalım. R’a yerleşik olarak gelen mtcars veri setini kullanarak korelasyon matrisi oluşturup bir takım uygulamalar gerçekleştirelim:

mtcars, 1973-1974 model 32 aracın yakıt tüketimi, dizayn ve performans ölçülerini içeren bir data setidir. Detay için ?mtcars yazabilirsiniz.

summary(mtcars)
head(mtcars)
# mpg: Mil/Galon
# cyl: Silindir sayısı
# disp Silindir Hacmi
# hp: Toplam Beygir Gücü
# drat: Arka Aks Oranı
# wt: Ağırlık (lb/1000)
# qsec 1/4 mil zamanı
# vs: V/S
# am: Vites Türü (0 = otomatik, 1 = Manuel)
# gear: İleri vites sayısı
# carb: Karbürator sayısı

Korelasyon matrisi nedir?

Korelasyon matrisi çoklu değişkenler arasındaki korelasyon katsayılarının tablosudur. Bu tabloda bir değişkenin diğer her değişken ile arasındaki korelasyon görülebilir.

Korelasyon matrisi oluşturalım:

korelasyon_matris <- cor(mtcars)

1.korelasyon_matris

Elde etmiş olduğumuz korelasyon katsayılarını corrplot paketi ile görselleştirerek daha yalın bir şekilde görelim:

# install.packages("corrplot")
library(corrplot)
corrplot(korelasyon_matris, method = "circle")

2.korelogram

Bu grafik ile tüm değişkenlerin birbirine bağlılık derecesini daha net bir şekilde gördük. Grafik üzerindeki koyu mavi noktalar güçlü pozitif korelasyonları, koyu kırmızı noktalar ise güçlü negatif korelasyonları göstermektedir. Diğer daireler de renklerine ve büyüklüklerine göre korelasyonun gücünü ve yönünü belirtmektedir.

Şimdi korelasyon katsayılarını ifade eden bu daireleri gruplayalım ve zayıf korelasyonları çıkaralım. Yardım için ??corplot yazıp ilgili dökümanı inceleyebilirsiniz.

cor.mtest <- function(mat, conf.level = 0.95) {
mat <- as.matrix(mat)
n <- ncol(mat)
p.mat <- lowCI.mat <- uppCI.mat <- matrix(NA, n, n)
diag(p.mat) <- 0
diag(lowCI.mat) <- diag(uppCI.mat) <- 1
for (i in 1:(n - 1)) {
for (j in (i + 1):n) {
tmp <- cor.test(mat[, i], mat[, j], conf.level = conf.level)
p.mat[i, j] <- p.mat[j, i] <- tmp$p.value
lowCI.mat[i, j] <- lowCI.mat[j, i] <- tmp$conf.int[1]
uppCI.mat[i, j] <- uppCI.mat[j, i] <- tmp$conf.int[2]
}
}
return(list(p.mat, lowCI.mat, uppCI.mat))
}

res <- cor.mtest(mtcars, 0.95)
corrplot(korelasyon_matris, method = "circle", order = "hclust", p.mat = res[[1]], sig.level = 0.05, addrect = 2, tl.col="black", tl.srt=45)

3.korelasyon_matris_grafik

Şu halde, güçlü pozitif korelasyonlar bir köşegen üzerinde, negatif korelasyonlar da diğer köşegen üzerinde toplandı. Zayıf korelasyonları ifade eden dairelerin üzeri çizildi.

Sahte Korelasyonlar

Bu gibi bir çalışmalarda pek çok sahte korelasyon çıkabilir. Sahte korelasyon, neredeyse birbiri ile hiçbir nedensellik bulunamayacak iki değişken arasında güçlü bir korelasyon çıkması durumudur.

Örneğin:

Bir ülkedeki çikolata tüketimi ile o ülkedeki insanların kazandığı toplam nobel ödülü sayısı arasında pozitif bir korelasyon var.
Internet Explorer kullanım oranı ile suç oranı arasında pozitif bir korelasyon var.
ABD’nin Maine eyaletindeki boşanma oranı ile kişi başına düşen margarin tüketimi arasında güçlü bir pozitif bir korelasyon var. (0,99)

Bunun için şu ayrıntıyı her zaman akılda tutmakta fayda var: Korelasyon nedensellik değildir.

REGRESYON

Regresyon da iki ya da daha çok değişken arasındaki ilişkiyi ölçmek için kullanılan bir analizdir. Biri bağımlı biri bağımsız olan iki değişkenin fonksiyonel ifadesidir.

Aynı şekilde R ile bir takım çalışmalar yapalım:

Yine mtcars data setini kullanalım:

# sınıfı numerik olan cyl sütununu factor sınıfına dönüştürelim.
mtcars$cyl

Şimdi bir grafiği oluşturalım:

#install.packages(“ggplot2”)
library(ggplot2)
ggplot(mtcars, aes(x=wt, y=mpg)) +
geom_point(size=4, color="blue", shape=20)

4.serpilme_grafiğiBu ilişkiyi ifade eden regresyon doğrularını ekleyelim:

# Regresyon doğrusu eklemek
ggplot(mtcars, aes(x=wt, y=mpg)) +
geom_point()+
geom_smooth(method=lm)

# Güven aralığı kaldırıldığında
ggplot(mtcars, aes(x=wt, y=mpg)) +
geom_point()+
geom_smooth(method=lm, se=FALSE)

# Loess metodu
ggplot(mtcars, aes(x=wt, y=mpg)) +
geom_point()+
geom_smooth()

5.regresyon_grafikler

ZAMAN SERİLERİ VE TEKNİK ANALİZ

Zaman serileri bir zaman aralığı içinde ölçülen veri serisidir. Zaman seri analizleri için R oldukça faydalı bir araçtır.

Hisse senetleri ve benzeri piyasalarda analiz yapmak için çok kullanışlı bir paket olan quantmod’u inceleyelim:

Apple Inc. şirketinin 1 Ocak 2015 tarihinden bu yazının yazıldığı güne kadarki günlük fiyat değişimini görelim (01.01.2015 – 10.10.2015) :

#install.packages("quantmod")
library(quantmod)
getSymbols("AAPL") # Apple Inc. Hissesi, Yahoo Finance
apple_hisse <- AAPL["2015-01-01::2015-10-10"] # 1 Ocak 2015 tarihinden bu yazının yazıldığı güne kadar
chartSeries(apple_hisse, type="candlesticks") #Apple Inc. Hisse Senedi Grafiği

6.apple_inc_hisse_senedi

R ile Apple Inc. şirketinin hisse senedini pek çok modern platformdaki gibi inceleme imkanımız var. Şimdi bu hisse senedinin trendini gözlemlemek için bir Basit Hareketli Ortalama ekleyelim. Bu hareketli ortalama ile fiyat hareketlerini yumuşatarak trend hakkında bir fikir sahibi olabiliriz. (Aşağıdaki grafik üzerindeki kırmızı eğri).

addSMA(20) #20 günlük bir basit hareketli ortalama

7.apple_inc_hisse_senedi_ve_sma

Ve son olarak trendin gücü hakkında fikir sahibi olabileceğimiz Relative Strength Index osilatorünü ekleyelim:

addRSI(14) # Relative Strength Index

8.apple_inc_hisse_senedi_ve_rsi

Teknik Analiz konusu altında incelenen pek çok indikatör ve yöntem quandmod paketi içinde gelmektedir. R, bu ve benzeri analizler için pek çok platformda bulabileceğiniz analiz yöntemlerinden çok daha büyük imkanlar sunabilmektedir.

Finans ve araştırma konularında R ile ilgili kaynaklar için: http://www.opiyasa.com/kategori/istatistik-arastirma/

Data Driven Kavramı ve II. Faz

2015 yılı itibariyle “Data Driven” kavramı dünyamızı kökten etkilemeye ve değiştirmeye devam ediyor. Şirketler artık hizmeti müşterinin ayağına götürmenin yeterli olmadığı, müşterilerini tanımaları, ihtiyaçlarını anlamalarının hiç olmadığı kadar kendi varlık sebepleri olacağı bir döneme girmiş durumdalar. Bunları yapabilmenin yoluda exponansiyel olarak artan veri yığınları ve kaynaklarından, bunları işleyip iş süreçlerine aktarabilmekten yani bigdata analitics dediğimiz kavramdan geçiyor.

Dünyanın en büyük 500 şirketi sıralaması olan Fortune 500 listesie baktığımızda büyük değişimi görebiliyoruz. 1955’den bu yana %90 oranında listenin değişmesi ve en büyük değişiminde artarak son 20 yılda yaşanması artık ayakta kalmanın başlı başına bir başarı olduğunu ortaya koyuyor.

Tüm bu değişimin merkezinde yer alan “data driven şirketler” kavramı ise büyük veri analitik yeteneği kazanmış, algoritmaların sonuçlarını kendi iş süreçlerine entegre etmiş şirket kavramını ifade ediyor. Bu konuda kullanılan teknolojilere baktığımızda ise bu sitede de yazılarını okuduğumuz hadoop, spark, nosql, elasticsearch, R, Python gibi open-source teknolojiler yanında bu alandaki dev yazılım firmalarının sunduğu lisanslı çözümler de yer alıyor.

Büyük yazılım firmaları arasında ise Veri Analitiği konusunda halen liderliğini sürdüren SAS firması ön plana çıkıyor. 1970’lere uzanan analitik ürün geliştirme geçmişiyle SAS, analitik bakışı kendi üzerinde de uyguluyor görünüyor çünkü bu yeni çağa ayak uydurmaya çalışıyor. SAS gemisi bir yandan halen çok ihtişamlı görünüyor ancak bir yandan geminin üzerinde yol aldığı deniz artık eskisi kadar pürüzsüz ve sakin değil, bir yandan da etrafda daha ucuza yolcu taşıyan onlarca irili ufaklı gemicik belirdi. Zaman mağrurların, egoların, bana bir şey olmazların aleyhine işliyor, sen çevreye ayak uyduramazsan çevre seni yok ediyor.

Bu şartlarda SAS son yıllarda stratejisinde bazı değişimlere gitmeye başladı, zaten çok güçlü olduğu analitik alanındaki çözümlerinin, Hadoop, R gibi yeni teknolojilerle birlikte ve entegre çalışmasını sağlayan yöntemler ve entegrasyonlar sundu. In-memory çalışan, gizli patternlerin görsel keşfedilmesini sağlayan Visual Analitics ve Visual Statistics ürünlerini çıkarttı. Base SAS yada Data Step olarak isimlendirilen ve tamamen veri işleme üzerine kurgulanmış, SQL’e göre büyük avantajları olan programlama dilinin artık yeterli olmadığını anlayarak, Base SAS’ın yeni gelişmiş hali olarak Data Step 2 (DS2) yi çıkarttı. Büyük veri üzerinde analitik imkanlar sunan SAS High-Performance Analitik Server’a da yatırım yapmaya devam ediyor.

Bir diğer önemli oyuncu SPSS ise 2009 yılında IBM’in satın almasından sonra yeni gelişen dünyaya SAS’a göre daha yavaş bir reaksiyon vermiş durumda. SPSS kolay kullanımı, görsellikte ön plana çıkması, komple bir veri madenciliği paketi olarak sunulması ile ön plana çıkmıştı. Şu anda görünen SAS, R ve diğer analitik firmalara göre akademik çevrede halen bir ağırlığı olmasına rağmen SPSS’in eski popularitesi azalmış durumda.

Eski versionlarını ücretsiz veren RapidMiner, İsviçre Zurich’de üniversite kökenli bir grup tarafından geliştirilen Open source versiyonu da olan KNIME, Kaliforniya merkezli 700 den fazla musterisi olan Alterix de artık devreye girmiş durumda.

2013 sonunda SAP’ın KXEN’i, 2014 yılı mart ayında DELL’in Statsoft(Statistica)’yı satın alması, Microsoft’un ticari olarak R’ı müsterilerine sunan Revolution Analytics’i Nisan 2015’de yani sadece bir kaç ay önce bünyesine katması büyük veri analitiğinde daha yarışın yeni başladığını gösteriyor.

Bunu destekleyici tarzda Veri analizi ve analitiği konusunda yapılan bazı araştırma sonuçları ve grafikleri şimdi sizinle paylaşmak istiyorum.

Grafik 1. İlk grafikte Amerika’da 1000’den fazla kaynakta yayınlanan iş ilanlarını baz alarak araştırma sonuçları yayınlayan Indeed.com ‘un 2014/02 tarihli bir çalışması var. Grafikte halen Java, C, C++, Python gibi programlama dillerinin halen analitik yeteneklerle birlikte arandığını ortaya koyuyor. SAS’ın halen ikinci olması dikkat çekici.

1

Grafik2. Bir de analitik alanda yarışan R ile SPSS ve R ile SAS arasında karşılaştırmalı olarak geçmişten bugüne verilen iş ilanları trendlerine baktığımızda daha ilginç verilerle karşılaşıyoruz. İlk olarak SPSS ile R karşılaştırması aşağıda. Turuncu renk R, Mavi SPSS’i gösteriyor. R çoktan SPSS’i geçmiş durumda.

2

Grafik3. Aynı grafiğin SAS ile R karşılaştırması ise aşağıda. Turuncu renk R, Mavi SAS’i gösteriyor. SAS düşüş, R ise artış trendiyle devam ediyor.

3Grafik4. Son dönemlerin popüler teknolojileri, R ve Python üzerinden aynı grafiğe baktığımızda ise görüntü aşağıda. İvme yukarı yönlü devam ediyor.

4Grafik5. Bir diğer ilginç popülarite karşılaştırmasıda, Stackoverflow üzerinden geliyor. Haftalık olarak R ve SAS’la ilgili yapılan posting’lerin karşılaştırması aşağıda. 2009’dan sonra her şey değişmeye başlıyor.

5

Grafik6. Bu da Linkedin ve Quora.com verisi üzerinden alınmış bir grafik. 2013 sonu itibariyle konu bazlı açılan tartışma gruplarındaki üye sayıları dikkate alınmış durumda. Hepimizin üye olduğu Linkedin açısından ilginç bir grafik.

6

Bu grafiklere Programlama dillerinin popularitesini araştıran Tiobe Index ve Transparent Language Popularity Index sıralamalrınıda dahil edebiliriz. Bunların linkleride aşağıda ve R’ın özellikle SAS’a karşı yükselişi burada da görülüyor.

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

http://lang-index.sourceforge.net/

Yazının sonuna geldik sanıyorum, baştaki cümleyi tekrar ediyorum, data driven kavramı her şeyi değiştiriyor ve değiştirmeye devam edecek, tüm bu grafikler, karşılaştırmalar, indeksler, trendler, araştırmalar bunu gösteriyor. Eskinin yıkılmaz, dokunulmaz denilen kaleleri dört bir yandan çevrilmiş ve bu haliyle kaldıkları sürece varlıkları sorgulanır durumda. Açık olmadıkları zaman yok olacaklarını anlamış durumdalar.

SAS gibi veri analitiğinde dev bir firmanın 30-40 yıl sonra verdiği reaksiyonlar, dev firmaların veri analitiği firmalarını bir bir satın almaları, verinin exponansiyel artışı, Hadoop-Spark, internet of things kavramları hepsi birden Data scientistlerin damga vuracağı bilgi çağında ikinci fazın başladığını gösteriyor.

Kaynaklar

http://www.dell.com/learn/us/en/vn/secure/2014-03-17-dell-acquires-statsoft-data-analytics-software

http://support.sas.com/documentation/cdl/en/ds2ref/68052/HTML/default/viewer.htm#ds2refwhatsnew94.htm

http://lang-index.sourceforge.net/

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

http://r4stats.com/articles/popularity/

http://www.cio.com/article/2906456/data-analytics/microsoft-closes-acquisition-of-r-software-and-services-provider.html

Apache Kafka

kafka-logo-wide

Günümüzde dev veri dediğimiz şey, artık her an(real-time) oluşabilen bir veri haline geldi. Her an her yerden gelen anlık veri bile devasa boyutlara ulaştı. Bunları hızlı , sorunsuz ve ölçeklenebilir bir şekilde nasıl tutarız ve bu veriye real time a yakın bir sürede nasıl tekrar ulaşabiliriz sorusu gündemi işgal etmeye başladı. Apache Kafka’da aslında bu soruya cevap olacak nitelikte bir çözüm olarak Linkedin bünyesinde geliştirildi ve daha sonra açık kaynak kodlu olarak herkesin hizmetine sunuldu.

Apache Kafka temelde log kaydına benzer bir yapıda kayıtları tutan ve bu kayıtları diğer sistemlere mesajlaşma kuyruğu(messaging queue – MQ ) şeklinde sunan bir yapıdır. Yüksek performansı ve düşük gecikme zamanı(latency) ile gerçek zamanlı veri akışı sağlar.

Temel Kavramlar1

Şimdi Kafka’ya özgü kavramlara gelelim.

  • Kafka mesajları “topic”lerde tutar.
  • Topic”lere mesaj gönderenler “producer”lardır.
  • Topic”leri okuyanlar ise “consumer”lardır.
  • Kafka’nın çalıştığı her bir sunucu ise “broker”dır.
  • Broker”ların hepsi birlikte bir “cluster” oluşturur.

Sunucular ve istemciler arası haberleşme tamamen dil bağımsız bir TCP protokolü üzerinde olur. Bu sayede bilinen çoğu popüler dilde istemci kütüphaneleri mevcuttur.

Topic Nedir?

2

Şimdi birazda Kafka’da topic denince aslında ne kasdediliyor, bu konuyu açalım. Kafka’ya gelen mesajların tutulduğu yer bir topic ve her zaman bir ismi var. Temelde her topic bölümlendirilmiş (partitioned) bir ya da birden fazla log dosyasından oluşuyor. Her bir bölüm(partition) mevcut topicin bir kısmına sahip oluyor. Her bölüm kendi içinde bir sıra ihtiva ediyor. Bu sıraya “offset” deniyor ve her bölümde şekildende görüleceği üzere bağımsız bir offset sırası oluyor.

Topice gelen her yeni mesaj bölüm sonuna ekleniyor ve offset numarası birer birer artıyor. Bir kere bir bölüme yazılan bir mesajın offset ve partition bilgisi değişmiyor. Bütün mesajlar yapılan ayara (config) göre belirtilen süre boyunca offset bilgi değişimeden tutuluyor. Yani digger mesajlaşma sistemleri gibi okunan mesajlar artık okunamaz hale gelmiyor. (Aslında onunda bir yöntemi var, ileride anlatacağım ) Bölümlendirme sayesinde yatayda gayet rahat bir şekilde ölçeklenebilir topicler oluşturabiliyorsunuz.

Dağıtık Topic Mimarisi

Bölümlendirme sayesinde her bölüme okuma yazma işlem performansı broker sayısı ile artar hale geliyor. Çünkü Kafka’ya bağlanan her istemci, ayrı bölüme mesaj yazabiliyor ya da ayrı bölümden okuyabiliyor. Gerçek anlamda paralel okuma ve yazma işlemleri bu sayede mümkün oluyor.

Her bölüm istendiği takdirde (ayrıca tavsiye edilen) clusterdaki diğer brokerlara yedekleme amaçlı kopyalanabiliyor (replication). Her bölümün sadece bir brokerda lideri (leader) oluyor ve okuma yazma işlemleri lider bölüme yapılıyor. Diğerleri ise köle (slave) bölümler oluyorlar ve dışardan asla yazma ya da okuma işlemi yapılamıyor. Herhangi bir brokerda bir bölüm işlevsiz hale geldiğinde, o bölümün diğer kopyalardan biri o bölüm için lider olup, hizmet verir hale geliyor. Aynı topicte her bölüm için farklı makinalar lider olduğu içinde gayet dengeli bir dağılım oluyor.

Producer Kullanımı

Producer hangi mesajın ilgili topicte hangi bölüme gideceğine karar verebiliyor. Bunu ya round-robin şeklinde ya da mantıksal bölümlendirme (semantic partitioning) ile yapıyor. Bir topice mesaj gönderirken eğer bir anahtar(message key) verirseniz ve ilgili topicin mantıksal bölümlendirme fonksiyonu varsa, mesaj ona gore bir partitiona yazılır. Örneğin, gönderidğin mesajlarda anahtar olarak şehir plaka kodu gönderirseniz, aynı şehirden gelen mesajlar aynı bölümde toplanır. Kafka bu konuda garanti verir.

Consumer Kullanımı

3Kafka’da “consumer group” diye bir kavram vardır. Aslında her consumer bir “consumer group”a aittir. Bu consumer gruba eğer tek consumer group bağlı ise o zaman mesajları okuma şekli kuyruk (queue) davranışı sergiler. O consumer group için gelen mesajlar bütün bölümlerden tek tek okunur. Birden fazla consumerın bir consumer gruba bağlı olması durumda ise o zaman publish/subscribe denilen yapıda bir topic olur (Kafka’daki topic ile karıştırmayın J) Yani gelen mesajları birden fazla consumer group içindeki birden fazla proses birden fazla bölümden okur.

Her iki durum içinde aynı consumer group içindeki consumer sayısı bölüm sayısına eşit olursa, gerçekten hızlı bir şekilde paralel mesaj okumalar gerçekleşir. Consumer sayısını bölüm sayısından fazla verseniz bile Kafka en fazla bir consumer group içinde bölüm sayısı kadar consumerın okuma yapmasına izin verir.

Kafka her bölüm için yazma sırasında okuma sırası garantisi verir. Böylece bölüm bazlı sıralama korunmuş olur.

Komut Satırından Kullanım

İlk olarak Kafka’yı http://kafka.apache.org/downloads.html adresinden indiriyoruz. Ben bundan sonra, yazıyı yazdığım sırada en güncel sürüm 0.8.2.1 olan ile devam edeceğim.

$ tar -xzf kafka_2.10-0.8.2.1.tgz 
$ cd kafka_2.10-0.8.2.1

Kafka’nın dağıtık çalışması Zookeeper sayesinde oluyor. İlk olarak kendi içinde gelen Zookeeper’ı ayağa kaldırıyoruz.

$ bin/zookeeper-server-start.sh config/zookeeper.properties 
[2015-08-03 21:45:56,155] INFO Reading configuration from: config/zookeeper.properties (org.apache.zookeeper.server.quorum.QuorumPeerConfig)...

Zookeeper başarılı bir şekilde ayağa kalktıktan sonra, Kafka’yı ayağa kaldıralım

$ bin/kafka-server-start.sh config/server.properties 
[2015-08-03 21:47:04,021] INFO Verifying properties (kafka.utils.VerifiableProperties)
[2015-08-03 21:47:04,049] INFO Property broker.id is overridden to 0 (kafka.utils.VerifiableProperties)...

Kafka’da her bir “topic” birden fazla parça(partition) şeklinde tutulabilir. Ayrıca fail-over senaryoları için de yedekleri (replication) tutulabilir. Şimdi bir “topic” oluşturalım.

$ bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
Created topic "test".

Oluşturduğumuz “topic”i kontrol edelim

$ bin/kafka-topics.sh --list --zookeeper localhost:2181 
test

Artık yeni oluşturduğumuz bu “topic”e mesaj gönderebiliriz

$ bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test  
[2015-08-03 21:50:37,377] WARN Property topic is not valid (kafka.utils.VerifiableProperties)
First message
Second message
Third message

Son olarakta oluşturduğumuz bu “topic”e gelen mesajları okuyalım

$ bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning 
First message
Second message
Third message

Gördüğünüz gibi çok kolay bir şekilde deneme amaçlı bir topic oluşturup, bu topic e okuma yazma işlemleri yaptık. Kafka’nın asıl gücü dağıtık çalışmasında, şimdi birden fazla sunucu ayağa kaldırıp, önceden yaptığımız işlemleri bir daha yapalım.Mevcutta zaten ayakta olan bir Kafka sunucusu vardı, buna 2 tane daha sunucu ekleyelim.

İlk olarak mevcut ayar dosyasının 2 kopyasını alalım

$ cp config/server.properties config/server-1.properties  
$ cp config/server.properties config/server-2.properties

Bu dosyalarda aşağıdaki değişiklikleri yapalım

config/server-1.properties:

broker.id=1     
port=9093     
log.dir=/tmp/kafka-logs-1

config/server-2.properties:

broker.id=2     
port=9094     
log.dir=/tmp/kafka-logs-2

Diğer 2 sunucuyu da ayağa kaldıralım.

$ bin/kafka-server-start.sh config/server-1.properties & 
$ bin/kafka-server-start.sh config/server-2.properties & 

Yeni bir “topic” oluşturalım

$ bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic 

Oluşturduğumuz yeni “topic” sunuculara nasıl dağılmış acaba ?

$ bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic 
Topic:my-replicated-topic	PartitionCount:1	ReplicationFactor:3	Configs: 	Topic: my-replicated-topic	Partition: 0	Leader: 1	Replicas: 1,2,0	Isr: 1,2,0 

En başta oluşturduğumuz “topic” nasılmış ?

$ bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test Topic:test	PartitionCount:1	ReplicationFactor:1	Configs: 	Topic: test	Partition: 0	Leader: 0	Replicas: 0	Isr: 0 

Nerelerde Kullanılabilir?

• Mesajlaşma Kuyruğu
• Websitesi Aktivite Takibi
• Sistem Metrikleri Toplanması
• Log Toplanması (Log Aggregation)
• Stream işleme (processing)
• Event Sourcing
• Commit Log (MySQL binary log gibi)

Kimler Kullanıyor?

Linkedin, Yahoo, Twitter, Netflix, Spotify, Pinterest, Airbnb, PayPal, vb… Detaylarına bu adresten ulaşabilirsiniz : https://cwiki.apache.org/confluence/display/KAFKA/Powered+By

Son olarak gayet güzel bir dokümantasyonu var : http://kafka.apache.org/documentation.html

Elasticsearch İle Metin İşleme

elasticsearch

Bu yazıda, popüler doküman veri tabanlarından Elasticsearch (ES) ile metin işleme ve sorgulama konusunda bazı önemli noktaları sizlerle paylaşmak istiyorum. Java da yazılmış olan açık kaynak kodlu metin arama motoru olan Apache Lucene kullanılarak geliştirilen Elasticsearch, rakibi Apache Solr ile ciddi bir rekabet içinde.

Bu yazı Türkçe kaynaklarda fazlaca değinilmediğini düşündüğüm, Elasticsearch ile metin verisinin işlenmesinin detaylarına bir giriş niteliğinde olacak. Özellikle bu alanda yabancı çözümlerin Türkçe metinlere uygun çözümler içerip içermediği konusunda kafa yormuş ve daha önceden metin işleme konusu ile ilgili geliştirme yapmış bir kişi olarak, Elasticsearch ü bu açıdan oldukça iyi bulduğumu söyleyebilirim.

Metin işlemenin temel adımları

Metnin hangi dilde olduğundan bağımsız olarak, metin işlemede temel adımlar parantez içinde ES dokümanlarında verilen isimleri ile birlikte şu şekildedir.

  1. Dilin ve mümkünse alanın belirlenmesi, Türkçe metin, spor, edebiyat, askeriye, sosyal medya alanı gibi. Bu kullanılacak referans bir corpus (derlem) kullanılarak yapılacak sonraki adımlardaki işlemler için gereklidir.
  2. Metnin kelimelere ayrıştırılması, (tokenization).
  3. Fazlalık olan işaretlemelerin ve gereksiz kelimelerin temizlenmesi (stopwords),
  4. Kalan kelimelerin standartlaştırılması ve kökünün bulunması, (normalization, stemming)
  5. Kelimelerin benzer olanlarının tespit edilmesi, (synonyms)
  6. Hatalı kelimelerin düzeltilmesi (typoes and mispellings)
  7. Uygun şekilde saklanması (indexing)

Bu işlemler hangi dilde olursa olsun bütün metin işlemelerde geçerlidir ve hazır bir kütüphane kullanılarak metin işlemesi yapıldığında farkında olarak ya da olmadan bu adımlar gerçekleştirilmektedir. Bu açıdan bakıldığında Elasticsearch ün gayet açık ve anlaşılır bir işleme mantığı olduğunu ve kullanıcıya yapacağı metin işlemede ciddi kolaylıklar sunarak bu karmaşık işlemi başlangıç (default) değerler ile yapabilmesini sağladığı görülüyor.

Tabii burada ilk kullanıcı için ciddi avantaj olan bu durum, ileri seviyede kullanım için bu default değerlerin nasıl değiştirileceğinin öğrenilmesi gerektiği anlamına gelmektedir. Şimdi bu adımların Elasticsearch ile nasıl gerçekleştirildiğine yakından bakalım.

Dilin ve mümkünse alanın belirlenmesi

Öncelikli olarak dil ve mümkünse bir alan (domain) belirlenmelidir. Bunun nedeni metin işlenirken kullanılacak korpus un seçilmesinin buna bağlı olmasıdır. Korpus, bir dilde yazılmış eserlerde çıkabilecek her kelimenin sistematik olarak tutulduğu bir katalogdur. Bu kataloğa bakarak bir kelimenin o dilde olmadığı, yanlış yazıldığı, cümle başında veya sonunda olamayacağı tespiti yapılabilir. Dilimiz için somut bir örnek için Türkçe korpus a bakılabilir.

Dokümanın yazıldığı dilin tespitinde iki ayrı yöntem kullanılmaktadır ve Elasticsearch de bu iki yöntemi kullanıcıya sunmaktadır. Birincisi bir standart dil belirlenip konfigürasyon buna göre yapılır ve eğer bunun dışında bir dil olacaksa bir parametre ile bildirilir. Özellikle çok dilli metinlerle uğraşanlar için otomatik metin dili belirlemek bir zorunluluk haline geldiğinden, Elasticsearch ün bu tür durumlarda önerdiği açık kaynak kodlu proje chromium-compact-language-detector değişik dilleri desteklemektedir. Bunun dışında, kullanıcı ekrandan bir metin giriyorsa uygulama içinden HTTP accept-language başlık parametresi dili belirlemek için kullanılabilir. Detayları olan bir konudur. Alanın belirlenmesi metni işlerken korpusun daraltılması açısından bazı faydalar sağlamaktadır, zorunlu değildir. Özellikle sorgu performansında iyileşme sağlar.

ElasticSearch e verinin aktarımı

Metni Elasticsearch e koymak, Elasticsearch ün terminolojisinde indekslemek anlamına gelmektedir. Bunun nedeni metni kaydederken yukarıdaki ikinci adımdan yedinci adıma kadarki süreçte kelimeleri ayrıştırma, fazlalıkları atma gibi işlemler ile her bir kelimeye bir indeks karşılık getirilmesidir. Oluşturulan bu indekse inverted index denmektedir.

Basit bir şekilde şöyle açıklayabiliriz. Tabloda ilk sütuna kelimeleri yazıyoruz, her bir doküman için bir sütun ekliyoruz ve her bir kelimenin karşısına o dokümanda olup olmadığı bilgisini bir bit ile 1/0 ile belirtiyoruz.

elesticssearch indeksleme yöntemi - inverted index
elesticssearch indeksleme yöntemi – inverted index

 

Bütün bu işlemler sorgulama sırasında hızlı cevap vermek ve sorguya uygun doküman listesini kullanıcıya dönmek içindir. Bu nedenle bu noktada Elasticsearch de normalde kullanılan bilgi erişim yöntemine kısaca değinmekte fayda görüyorum. Sorgulamalarda sorguda geçen kelimeler bir bilgi erişimi metodu olan Boolean Model kullanılarak inverted index yardımı ile ilişkili dokümanları getirir. Bu model ‘ve’, ‘veya’ ve ‘değil’ gibi mantıksal operatörleri kullanmaya izin vererek basit bir şekilde indeks tablosundaki hangi dokümanların sorguya uyduğunu hızlı bir şekilde bulur.

Sorgu : (Kelime1 ve kelime3) veya kelime 5

Cevap : doc1, doc2

Doc3 ün dönmemesinin sebebi kelime1 in doc3 de bulunmamasıdır. Kelime5 doc1 de bulunmasa bile veya ile bağlandığı için cevap içinde bulunuyor.

Bu aşamada özellikle sonuçların sayısının çok olduğu durumlarda sonuçların kullanıcıya sunulacağı sıranın ne olacağı önem kazanmaktadır. Örneğin çoğumuz arama motorundan sorduğumuz soruya dönen cevaplardan ilk on veya yirmi cevaba bakarız. Bunun için Elasticsearch, Lucene ın altyapısını da kullanarak, çok karmaşık hesaplamalar yaparak _score parametresindeki [0, 1] aralığındaki değerleri üretir. İlişiklik (relevance) değerleri olarak nitelendireceğimiz bu değerlerin nasıl hesaplandığını bilmek, istenen sorgu kalitesinin nasıl arttırılacağının da cevabıdır. Şimdi bu değerin nasıl hesaplandığına bakalım.

İlişiklilik (relevance) değeri

Yapılan bir sorgu ile var olan dokümanlardan hangilerinin kullanıcıya döndürülmesi gerektiğine karar vermek hatta sıralamak için doküman veri tabanlarında kullanılan algoritmalar, bu iş için kullanılan ilişkisel veri tabanlarından benzer etkin sonuçların alınamamasının temel sebeplerinden belki de en önemlisidir. Şimdi perdenin arkasına kısa bir bakış yapalım. Her kelime için hesaplanan aşağıdaki üç değer bu konuda öne çıkmaktadır.

a)     Terim frekansı (tf)

Sorgudaki kelimelerden biri dokümanda altı kere geçiyorsa bir kere geçen dokümana göre altı kere geçen doküman daha ilişkili kabul edilir. T terim veya kelime, d doküman veya alan olmak üzere;

tf(t in d) = √frekans

b)     Ters doküman frekansı (idf)

Ters doküman frekansı (inverse document frequency – idf) kelimelerin koleksiyondaki dokümanlar içinde geçme sıklığını ifade eden bir değerdir.

Kelime ne kadar çok dokümanda geçiyorsa o kadar ayırt edici özelliği zayıftır kabulüne dayanır. Bu nedenle idf değeri ne kadar küçük ise kelimenin o kadar ağırlığı arttırılır. Ne kadar büyükse o kadar düşürülür. idf in tam değeri şu formül ile hesaplanır.

idf(t) = 1 + log ( numDocs / (docFreq + 1))

c)     Alan uzunluğu kuralı (norm)

Dokümanın veya alanın uzunluğu ne kadar fazla ise kelimenin o dokümanda bulunmasının önemi o kadar azalır. Bu açıdan, başlıkta geçen bir kelime konuda geçen bir kelimeden daha önemlidir.

norm(d) = 1 / √numTerms

Bu değerlerin hesaplanması, doküman Elasticsearch e ilk kaydedilirken indeksleme aşamasında yapılır. Bir kelime için hesaplanan bu üç değer kullanılarak bir skor üretilmesi ve hatta birçok sorguda olduğu gibi birden fazla terim içeren sorgular için de bu işlemin yapılması için Elasticsearch de şu yöntem uygulanmaktadır. Bulunan bu değerler ile oluşturulan vektörler kullanılarak, ilişiklik problemi vektör uzaylarında vektörlerin birbiri arasındaki açıyı bulma problemine dönüştürülmektedir. Bu şekilde sorgudan üretilen vektör ile her bir dokümanın vektörü çok boyutlu uzayda vektör hesaplamaları yapılarak skorlar bulunmaktadır. Bu hesaplamalar Lucene ın Pratik Skorlama fonksiyonuna girdi olmaktadır. Detay için bu linke bakabilirsiniz.

 

Sorgu performansının arttırılması

Yukarıdaki bilgiler bazıları için fazla detay gibi gelecektir ama bilmemiz gereken _score parametresinin hesaplanmasında nelerin etkin olduğu ve bunları sorgu sonuçlarının kalitesini arttırmak için nasıl kullanabileceğimizdir. Bu bilgilere dayanarak Elasticsearch de sorgu performansının arttırılması için ilk akla gelenlerden bazıları şunlardır.

  1. Eş anlamlı kelimelerin tanıtılması önemlidir. Bu şekilde terim frekansı arttırılabilir.
  2. Kelimelerin normalize edilmesi önemlidir. Dokümanların çoğunda geçmesi beklenen zamirler bu, şu, soru ekleri ‘mı’, ‘mü’, ‘mıdır’ gibi sorguda faydalı olmayacağı düşünülen kelimelerin indekslemeye sokulmaması genellikle önerilir.
  3. Alan uzunluğunun, dokümanlarda sıkça geçen ‘ve’, ‘veya’ gibi indekslemede gereksiz kelimelerin atılması ile azaltılması iyidir.

Uygulama

Esasen bu noktaya kadar anlattıklarımız metin işlemesi yapan herhangi bir çözümün yaptıkları olarak görülebilir. Bu noktada Elasticsearch ile nasıl yapıldığı konusunda somut örnekler vermek istiyoruz.

Ortam

İşlemler için kullandığımız ortamı kısaca anlatırsak, tek node üzerinde dağıtıklık özelliğine girmeden default ayarları kullanarak Ubuntu üzerinde yaptığımız bir Elasticsearch 1.7.1 kurulumu üzerinden anlatıyoruz. Elasticsearch ile etkileşimleri REST API ile gerçekleştiriyoruz. Alternatiflerimiz

  1. Bir web browser ile
  2. komut satırından curl komutu ile
  3. Marvel/Sense ile plug-in yüklenirse bir browser yardımı ile web sayfasından. Marvel/Sense i anlatan türkçe bir kaynak
  4. Herhangi bir browser ın restclient addon u, örnek; firefox restclient

 

Basit sorgular için doğrudan bir browser ile sorgulamalarımızı yapabiliriz ama kompleks sorgular için kendi sorgulama dili olan Query DSL (Domain Spesific Language) kullanılıyor. Bu dil JSON formatına bağlı kalınarak hazırlanmış yazım kuralları içeriyor. Çok karmaşık sorgular yapmaya izin veriyor.

Analyzer

Yukarıda detaylı bahsettiğimiz kelimelerin işlenmesi sürecinde Elasticsearch analyzer denen bir paket kullanır. Dilin ve yapılacak işlemin durumuna göre alternatifler mevcut olmakla birlikte default olarak standard anayzer kullanılır ve index default olarak analyzed olarak alınınır. Bunun anlamı ilgili alan yukarıdaki işlemlere tabi tutuldu ve indeksleme buna göre yapıldı demektir. Bazı durumlarda not analyzed yapılması gerekebilir. Özellikle işlenmemesi aynen alınması gereken alanlar için bu yöntem önerilir.

Öncelikle default analyzer ın ihtiyacımızı karşılayıp karşılamadığını anlamak, alternatif anlayzer seçimini yapmamızı kolaylaştıracak alet olarak Analyze API sini kullanabiliriz.

Deafult analyzer

Örnek metin ‘Bu gözümün nuru türkçenin hali ne olacak’ olsun.

curl -XGET ‘localhost:9200/_analyze?analyzer=standard‘ -d ‘Bu gözümün nuru türkçenin hali ne olacak’

Elasticsearch string bir alan tespit ettiğinde onu full text string olarak ele alır ve default olarak standard analyzer ı kullanır. Bu komut çalıştırıldığında kelimelere ayrıştırılma işlemi yapılır, metinde kelimenin nerede başlayıp nerede bittiği bilgisi ile birlikte tespit edilir ve indeksleme buna göre yapılır.

Standart analyzer ile kelimelere ayrıştırma işleminin sonuçları
Standart analyzer ile kelimelere ayrıştırma işleminin sonuçları

Burada <türkçenin> kelimesi yerine <türkçe>, <gözümün> kelimesi yerine <göz> kelimelerinin indekslenmesini isteyebiliriz. Hatta <bu> kelimesinin ayırt edici bir özelliği olmadığından tamamen kaldırılmasını isteyebiliriz. Burada ayırt edici özellik olarak metinlerin çoğunda ve yüksek frekansta geçen kelimelerin dokümanları indekslemede kullanılmamasının genellikle daha iyi sonuç ürettiğini söylemek istiyoruz.

Bu durumda farklı bir analyzer kullanmak isteyebiliriz. Bunun için built-in olanları kullanabilir veya kendimiz custom bir analyzer tanımlayabiliriz. Biz var olan turkish anayzer ı kullanalım.

Turkish analyzer

Türkçe için özel olarak geliştirilmiş built-in bir analyzer kullanalım.

curl -XGET ‘localhost:9200/_analyze?analyzer=turkish‘ -d ‘Bu gözümün nuru türkçenin hali ne olacak’

Turkish analyzer ile kelimelere ayrıştırma işleminin sonuçları
Turkish analyzer ile kelimelere ayrıştırma işleminin sonuçları

Artık <bu> ve <ne> kelimeleri indekslenmedi. <türkçenin> yerine <türkçe>, <gözümün> yerine <göz> kelimeleri indekslendi. Bu şekilde sorgu performansı da artmış oldu.

Analyzer seçiminin sorgu performansına etkisi

Bu aşamada örnek için kullandığımız metni Elasticsearch ile indeksleyip yani kaydedip sonrasında analyzer seçiminin sorgularımızın sonuçlarına nasıl yansıdığına bakalım.

Elasticsearch de yapılan sorguların hepsi, başlarında satır numaraları var.
Elasticsearch de yapılan sorguların hepsi, başlarında satır numaraları var.

36. satırdaki sorgu ile

GET /turkcedoc/denemeler/_search?q=metin1:türkçe

sorgulama yaptığımızda sorgu sonucu boş geliyor. Bu indekslenen kelimenin birebir aranmasından kaynaklanıyor. Çünkü <Türkçenin> kelimesi indekslenmişti. Bu tip durumlarda fuzzy matching kullanılabilir. Bu durumda 38. satırdaki sorgu ile cevabı alıyoruz.

GET /turkcedoc/denemeler/_search?q=metin1:türkçenin

Standart analyzer ile indekslenmiş metin1 alanının sorgu sonucu
Standart analyzer ile indekslenmiş metin1 alanının sorgu sonucu

Gelen sonuçta _score değerine bakarsak uygunluğun 0.11506981 ile değerlendiğini görüyoruz.

40.satırdaki sorguyu yapalım

GET /turkcedoc/denemeler/_search?q=metin2:türkçenin

Turkish analyzer ile indekslenmiş metin2 alanının sorgu sonucu
Turkish analyzer ile indekslenmiş metin2 alanının sorgu sonucu

Bu kez sonucun _score değerinde artış olduğunu görüyoruz. 0.13424811 Bu küçük gibi görünen artış binlerce dokümanın olduğu bir ortamda diğerlerinin önüne geçmek için yeterlidir. Hatta bu kez

GET /turkcedoc/denemeler/_search?q=metin2:türkçe

sorgusuna da cevap alıyoruz.

Yazıyı daha fazla uzatmamak için analyzer ın bize sunduğu olanaklardan birçoğuna burada yer veremiyorum. Sonuç olarak gerçekten sorgu sonuçlarını ilgilendiren indeksleme işlemlerinin arka planının anlaşılmasının ve analyzerı buna göre geliştirip değiştirmenin getirdiği faydaları anlatabildiğimi umuyorum. Belki başka bir yazıda diğer özellikleri de ele alabiliriz.

Hadoop Workshop Etkinliği

sparkİstanbul Spark Tanışmaları Grubu (İSTG) tarafından Spark ın tanıtımı ve kullanımı konulu 25 Temmuz 2015 Cumartesi günü İstanbul’da yapılan çalışma etkinliği sonrası, planlanan diğer bir diğer etkinlik olan Hadoop ile Merhaba Dünya konulu workshop, 8 Ağustos 2015 Cumartesi günü Maslak taki İTÜ Teknokent’te gerçekleştirildi. Arı 3 Çekirdek Seminer Salonu’nda gerçekleştirilen etkinliğe değişik şirket ve sektörden 25 kişi katıldı. İTÜ Çekirdek Yönetimi’nin önceki etkinlikte olduğu gibi, seminer salonlarını Workshop için kullanıma sunmaları etkinliğin güzel bir ortamda gerçekleşmesine önemli katkı sağladı.

Etkinliği düzenleyen İSTG grubunun kurucularından olan Şafak Serdar Kapçı’nın, Hadoop’u tanıtan kısa sunumundan sonra yaklaşık üç saat süren uygulama kısmına geçildi. Bu kısım, Hadoop kurulumu için daha önceden Şafak Bey tarafından hazırlanan CentOS İşletim Sistemli sanal makinanın, her bir katılımcı tarafından kendi makinasında ayağa kaldırılması, geliştirme için gerekli olan Java ve IDE ortamı olan Eclipse in yüklenmesi ve Hadoop un son sürümü Hadoop.2.7.1 kurulumu ve gerekli konfigürasyonların yapılması ile tamamlandı. Bu adımda Hadoop un üç farklı çalışma şeklinden,

  1. Basit (Standalone mode)
  2. Sanki dağıtık (Pseudodistributed mode)
  3. Tam dağıtık (Fully distributed mode)

içinden, ikincisi olan sanki dağıtık mode a göre konfigürasyonlar yapıldı. Bu modda, hadoop un temel bileşenleri tek makinada sanki bir cluster varmışçasına çalıştırıldığı için, tek bir makine üzerinde olsa da gerçeğe mümkün olduğunca yakın bir Hadoop kurulumu yapılmış oldu.

Sonrasında Java projeleri olarak hazırlanmış örnek projelerin github üzerinden alınması ve Eclipse ortamında çalıştırılması şeklinde katılımcıların her birinin kendi makinası üzerinde kurduğu Hadoop ile uygulama denemeleri yaptığı aşamaya geçildi.

Detaylar

Uygulama örneklerinde kullanılmak üzere seçilen veri setleri şunlar oldu.

TCMB.txt veri seti : TC Merkez Bankası GBP ve USD döviz kurları 1950 den günümüze efektif alış ve satış kurları verileri.

NCDC.txt veri seti : National Climatic Data Center (NCDC) ın 1901 den bu yana dünyanın birçok bölgelerinde günlük olarak kayıt edilmiş sıcaklık değerleri verileri.

CDR.txt veri seti : Arama verilerinin bulunduğu örnek veri seti.

 

Şafak Bey in hazırladığı projeler şu şekilde kurgulanmıştı.

  1. TCMB => TCMB.txt veri setinden yıl ve İngiliz Sterlini Alış (gbpA) değerlerini Map eden bir Mapper class ı, her yıl için gün bazında map edilen bu değerlerden her yıl için maksimum değerleri üreten bir reducer class ı. Sonuçta <key, value> şeklinde yıl ve o yılki maksimum gbpA değerleri üretilmektedir.
  2. NCDC => NCDC.txt veri setinden yıl ve sıcaklık değerlerini Map eden bir Mapper class ı, her yıl için gün bazında map edilen bu değerlerden her yıl için maksimum sıcaklık değerlerini üreten bir reducer class ı. Sonuçta <key, value> şeklinde yıl ve o yılki maksimum sıcaklık değerleri üretilmektedir.
  3. CallData => CDR.txt veri setinden konuşma süresi değerlerini Map eden bir Mapper class ı, map edilen bu değerlerden ortalama konuşma süresini üreten bir reducer class ı. Sonuçta <key, value> şeklinde duration ve ortalama konuşma değeri üretilmektedir.

 

Bu adımların detaylarına github daki HadoopWorkShop dan ulaşabilirsiniz.

 

Şafak Serdar Kapçı, Hadoop’u tanıtan kısa bir sunum yaptı.
Şafak Serdar Kapçı, Hadoop’u tanıtan kısa bir sunum yaptı.

 

Çalışma boyunca Şafak Bey katılımcılar ile tek tek ilgilendi.
Çalışma boyunca Şafak Bey katılımcılar ile tek tek ilgilendi.

 

Uygulamalar için Eclipse olarak bilinen ve Java dünyasında yaygın olarak kullanılan Etkileşimli Geliştirme Ortamı – IDE (Integrated Development Environment) tercih edildi. Şafak Bey’in hazırladığı kodlar kullanılarak pratikte bir Hadoop uygulamasının veri işlemede nasıl kullanıldığı uygulamalı olarak gösterildi.

IDE olarak Eclipse ortamı kullanıldı.
IDE olarak Eclipse ortamı kullanıldı.

 

Kaynak Yöneticisi WEB kullanıcı ekranı
Kaynak Yöneticisi WEB kullanıcı ekranı

 

NameNode Web kullanıcı ekranı
NameNode Web kullanıcı ekranı

 

Bitiriş

Workshop boyunca Şafak Bey in sorulara tek tek cevap veriyor olması, dağıtık veri işleme gibi zor bir konunun Hadoop ile nasıl yapılabildiğinin anlaşılması açısından katılımcılar için iyi bir fırsat sunmuş oldu. Bu başarılı etkinlikte emeği geçenleri kutluyoruz.

Spark ile Tanışma Etkinliği

sparkİstanbul Spark Tanışmaları Grubu (İSTG) tarafından Spark ın tanıtımı ve kullanımı konulu çalışma toplantısı, 25 Temmuz 2015 Cumartesi günü İstanbul Maslak taki, İTÜ Teknokent’te gerçekleştirildi. Arı 3 Çekirdek Seminer Salonu’nda gerçekleştirilen etkinliğe değişik şirket ve sektörden 23 kişi katıldı. İTÜ Çekirdek Yönetimi’nin seminer salonlarını Workshop için kullanıma sunmaları etkinliğin güzel bir ortamda gerçekleşmesine önemli katkı sağladı.

Etkinliği düzenleyen İSTG grubunun kurucusu olan Şafak Serdar Kapçı’nın, Spark’ı tanıtan kısa sunumundan sonra yaklaşık üç saat süren uygulama kısmına geçildi. Bu kısım, Spark kurulumu için sanal makinanın hazırlanması, gerekli bazı ön yüklemelerin yapılması ve sonunda da Spark’ın kurulumu ile tamamlandı. Sonrasında iki ayrı örnek veri seti üzerinde uygulamalı olarak Spark ın yetenekleri gösterildi. Bu adımların detaylarına github daki SparkWorkShop dan ulaşabilirsiniz.

Şafak Serdar Kapçı’nın, Spark’ı tanıtan kısa sunumu
Şafak Serdar Kapçı’nın, Spark’ı tanıtan kısa sunumu
Çalışmalar boyunca Şafak Bey in tek tek katılımcılar ile ilgilenmesi ve sorularını cevaplaması
Çalışmalar boyunca Şafak Bey in tek tek katılımcılar ile ilgilenmesi ve sorularını cevaplaması

Uygulamalar için REPL olarak bilinen ve popüler etkileşimli hesaplama ortamı olarak yakın zamanda Jupyter Projesi ismi ile Python a bağlı olmayan bir kimliğe bürünen IPython Notebook ortamında Şafak Bey in hazırladığı kodların üzerinden geçildi. Spark için hazırlanmış Python API paketi olan PySpark kullanılarak temel verinin SparkContext e yüklenmesi ve bu veri üzerinde transformasyon ve aksiyon kategorisindeki işlemlerin nasıl yapılacağı ile ilgili örnek verilerek devam edildi.

spark03
Spark için hazırlanmış Python API paketi olan PySpark kullanımı

Arkasından SparkSQL e bir giriş olarak, PySpark paketinin bir alt paketi olan pyspark.sql kullanılarak da benzer işlemlerin aynı veri setleri üzerinde nasıl yapıldığı konusunda bazı örneklerle oturum tamamlandı.

SparkSQL e bir giriş olarak, PySpark paketinin bir alt paketi olan pyspark.sql ın kullanımı
SparkSQL e bir giriş olarak, PySpark paketinin bir alt paketi olan pyspark.sql ın kullanımı

Çalışmalar boyunca Şafak Bey in tek tek katılımcılar ile ilgilenmesi ve sorularını cevaplaması ile genel olarak katılımcıların bir çoğunun Spark a giriş ve ısınma açısından hızlı bir başlangıç yaptıkları söylenebilir. Bu etkinlikte emeği geçen burada bahsedemediğimiz kişileri yorumlar kısmına eklerseniz seviniriz. Hadoop konusunda bir bloğa da sahip olan Şafak Bey i bu başarılı organizasyon nedeni ile tebrik ediyoruz.

MongoDB Replica Set Kullanımı

MongoDB, şüphesiz son 5 yılın en iyi NoSQL veritabanı çözümlerinden bir tanesi. Foursquare gibi büyük firmalar tarafında kullanıldığı öğrenilince, insanlar kendi sistemlerinde ciddi veri saklama çözümleri için bir heyecanla MongoDB kullanmaya çalışıyor. Evet MongoDB bir çok alanda veri saklama işinde çok yararlı olabilir, ama inanın yanlış kullanıldığı takdirde sizin bir numaralı kabusunuz da olabilir…. MongoDB Replica Set kullanımı ile ilgili internette çok fazla döküman var ama tam olarak çalıştırabileceğiniz şekilde Replica Set kurulumunu anlatan bir kaynak yok. Bu yazıda sizlere adım adım nasıl kurulacağını anlatacağım.

Yüksek hit alan sistemlerde veri saklama işini yaparken verilerin en az bir kopyasının olması(redundancy) ve yüksek erişilebilir(high availability) olması olmazsa olmazlardandır. Biz bunu MongoDB de Replica Set ile yapacağız.

Replica Set Nedir?

Aynı veri setini barındıran ve yöneten bir grup mongod servisleridir. Replica Set in öncelikli amacı datanın redundant ve high available olmasını sağlamaktır. Verilerin kopyası birden fazla sunucuda tutulduğu için, herhangi bir sunucuda donanımsal sıkıntı yaşadığınız zaman, ayni veri baska sunucudan okunabilir. Daha sonra sıkıntı giderildiğinde başka sunucudan aynı veri sorun yaşanan sunucuya otomatik olarak senkronize edilir. Ya da başka bir senaryo düşünürsek, aynı veri birden fazla sunucuda var demiştik. Okuma işlemi yaparken hep aynı sunucudan okumak yerine okuma yükü verinin kopyasının olduğu sunuculara dağıtılır. Dolayısıyla veri okuma ya da yazma hızı artırılmış olur.

Replica Set Yöntemleri

MongoDB Replica Set oluşturmak için gerekli üye sayısı tek sayı olmalıdır. Mesela aşağıdaki 3 üyeli bir Replica Set. Gördüğünüz üzere bir tane Primary üye iki tane Secondary üye var. Diyelim ki sizin bir uygulamanız var ve bu uygulama MongoDB ye bağlanıp belirli işlemler yapıyor. Siz herhangi bir yazma işlemi yaptığınızda Primary üye bu isteği alıp kendi log sistemi olan oplog a yazar. Buraya ayzmasının sebei, daha sonra Secondary üyeler tarafından okunup Secondary üyelerin kendi veritabanlarina yazması için gerekli olmasıdır.

01
Replica Set 1 (http://www.mongodb.org)

Şimdi de başa bir yönteme göz atalım. Bu senaryomuzda ise kalıcı bir Primary üye olmayacak, yeri geldiğinde Secondary üyeler Primary olabilecek. Peki neden böyle bir duruma ihtiyaç duyulsun? Diyelim ki Primary üyenin bulunduğu makine kapandı, bu durumda yazma isteklerini karşılayacak bir üye de olmayacak. Yani sistemde data kaybı olacaktır. Ama siz mimarinizi değiştirip, Primary kapandığında ya da Primary üye 10 saniyeden fazla bir süre diğer üyelerle iletişim kuramadığında, geri kalan üyeler kendi aralarında karar verip Primary üye seçerlerse sistem normal işleyişine devam edebilecektir. Bu mimariyi iki şekilde yapabilir siniz:

02
Replica Set 2 (http://www.mongodb.org)

Burada yeni bir üye tipi var: Arbiter. Bu üye hiçbir şekilde veri işlemi yapmaz sadece Primary üye seçimi yapılırken seçmen sayısının tek sayının katı olması için vardır. Yani sadece seçim işleminde rol oynar. Daha önce de demiştik, Replica Set üye sayısı tek sayı olmalıdır. Peki neden 2 tane Secondary ve tek Primary yok? Aslında onu da yapabilirsiniz ama eğer 2 tane Secondary kullanmaya gerek yok ise, Arbiter kullanmak sizin veritabanı maliyetinizi düşürecektir.

03
Üye seçimi (http://www.mongodb.org)

Bu şekilde de Primary üye bir şekilde kapanırsa eğer, geri kalanlar kendi aralarında Primary seçeceklerdir.

Son olarak, Replica Set’ten veri okuma işlemi genelde Primary üye üzerinden yapılır ama siz okuma stratejinizi değiştirip sadece Secondary üyeden okuma işlemi yap diyebilirsiniz. Bu konuyla ilgili detaylı bilgiyi buradan bulabilirsiniz.

Kurulum İçin Gereksinimler

Kurulum sırasında birden fazla sunucuya (ya da sanal makine de olabilir) ihtiyacımız olacak. Aslında aynı makine üzerinde birden fazla mongod servisini ayrı portlarda da çalıştırabiliriz, ama gerçek yaşamdaki kullanıma yakın olsun diye farklı sunucularda kurarak anlatmayı tercih ediyorum. Ama birden fazla suncuyu nerde bulacağız diyebilirsiniz. Hiç sorun değil, lokal makinenize docker kurup birden fazla linux container ayağa kaldırıp bunlara kurulum yapacağız. Docker kurulumu ile ilgili detaylara burada değinmeyeceğiim, isteyen şuradan nasıl kurulduğuna bakabilir. Kurulum esnasında kullandığım docker komutlarından kısaca bahsediyor olacağım.

Replica Set kurulumundan önce size tek bir mongod servisinin nasıl kurulduğunu göstereceğim. Bu Replica Set kurulumu yaparken işinize yarayacak.

MongoDB kurulumu

Docker kurduktuna sonra ubuntu kullanacağız ama öncelikle indirmemiz gerekiyor. docker pull ubuntu komutunu çalıştırarak indirme işlemi tamamlayın. Daha sonra docker images komutunu çalıştırınca listede ubuntu imajını görmeniz lazım. Şimdi ubuntu imajını kullanarak bir tane container ayağa kaldırıp içine MongoDB kurulumu yapabiliriz ama en az 3 tane container olacak ve herbirine tek tek MongoDB kurmak pek mantıklı olmayabilir. O yüzden gelin bunu otomasyona bağlayalım. Yani öyle birşey yapacağız ki,

  1. ubuntuyu kullansın
  2. MongoDB paketini indirsin ve belirli klasöre kopyalasın
  3. daha önceden hazırladığımız mongo.conf dosyasını container içine kopyalasın

Bu adımları bir Dockerfile içine yazıp bu direktifler doğrultusunda kendi imajımızı yaratabiliriz. Şimdi Dockerfile adında bir dosya yaratın ve içine aşağıdaki içeriği koyun.

FROM ubuntu:latest
RUN apt-get update -y && apt-get install -y wget unzip build-essential
RUN cd /opt \
        && wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.4.tgz \
        && tar -xvzf mongodb-linux-x86_64-3.0.4.tgz \
        && mv mongodb-linux-x86_64-3.0.4 mongodb
RUN mkdir -p /data/mongo
RUN mkdir -p /var/log/mongodb

ADD mongodb.conf /opt/mongodb/mongodb.conf
RUN chmod 644 /opt/mongodb/mongodb.conf
RUN chmod 644 /data/mongo

Basitçe, yaratacağımız imajın özelliklerini direktif halinde belirttik, şimdi bunu derleyip imaj oluşturalım. Derlemek için ise aşağıdaki komutu kullanabilirsiniz.

docker build -t mongodb:1.0 .

Bu komut sayesinde, bulunduğunuz dizindeki Dockerfile kullanılarak mongodb adında ve 1.0 versiyonunda bir imaj oluşturduk. Artık bu imajı kullanarak istediğimiz kadar container yaratabiliriz. Sanki bilgisayarınızdaki işletim sistemi ve dosyaların imajını almışsınız ve her an istediğiniz makineye kuruluabilir şeklinde düşünebilirsiniz. Container çalıştırmak için aşağıdaki komutu kullanabilirsiniz.

docker run -d --name mongodb-1 -v /dockerdata:/dockerdata mongodb:1.0 tail -f /dev/null

Bu komut ile container arka planda(-d) çalışır durumda. Adını –name opsiyonuyla verdik ve çalıştırılırken kullanılacak imaj mongodb:1.0 . -v seçeneği volume anlamına geliyor ve bu da lokaldeki bir klasörü container içindeki klasör ile eşleştirmek için kullanılıyor. Mesela ileriki bölümlerde bir anahtar üreteceğiz ve bu anahtar lokaldeki /dockerdata/ klasöründe olacak ve container içinden /dockerdata/mongokey.pem aslında lokal klasörden ulaşılmış olacak. En sondaki fonksiyon zorunlu değil ama eğer docker container içinde hiçbirşey çalışmayacak şeilde ayağa kalkarsa açar açmaz kapanacaktır. O yüzden /dev/null dosyasını tail komutuyla okudum ve bu sayede container ayakta durmuş olacaktır. Container çalışıyor ama bu container e nasıl bağlanacağız? Bağlanmadan önce docker ps diyerek o anki çalışan docker container listesine bakabiliriz. Burada container biligilerini göreceksiniz. Container’a bağlanmak için NAME alanını kullanacağız. Biz container’ı ayağa kaldırırken adını mongodb-1 vermiştik. Bağlanmak için aşağıdaki komutu kullanalım.

docker exec -i -t mongodb-1 bash

Bu komuttan sonra container a bağlanıp komut satırına düşmüş olacaksınız. Artık elinizde icinde MongoDB kurulu olan Ubuntu işletim sistemi var. MongoDB’yi başlatmak icin aşağıdaki komutu kullanabilirsiniz:

/opt/mongodb/bin/mongod --config /opt/mongodb/mongodb.conf

MongoDB’yi başlatmanın birçok yöntemi var. İsterseniz parametreleri direkt olarak komut satırından verebilirsiniz, dilerseniz bir config dosyasına koyup –config opsiyonuyla config dosyasını geçebilirsiniz. Şimdi gelelim config dosyasının içerğindeki ifadelerin ne anlama geldiğine;

dbpath: MongoDB’nin verileri yazacağı klasörün path’i

logpath: MongoDB calışırken logları yazacağı log dosyası

fork: MongoDB’nin daemon modda çalışabilmesi için gereken parametredir. Normalde MongoDB arkaplanda çalışmaz, fork: true derseniz arkaplanda çalıştırmanıza imkan sağlar.

pidfilepath: MongoDB’yi çalıştırdığınızda process id’sini yazacağı dosyadır. Aslında process id’sini ps -ef | awk ‘/mongodb/{print $2}’ | head -1 komutuyla da alabilirsiniz.

logappend: Aslında bu opsiyon analitik için çok önemli. Bu seçenek true olarak ayarlanırsa, mongod restart edildiğinde var olan logların üzerine yazmaz ve kaldığı yerden devam eder. Ama bu seçenek yoksa, restart işleminde eski loglar uçar (Eğer rotate etmediyseniz tabi) ve yeni bir log dosyası yaratıp ona yazmaya devam eder.

smallfiles: Bu seçenek true olursa, MongoDB nin oluşturduğu default veri dosya boyutları küçük olur. Bu konu performans açısından önemli ve burada çok da detaya inmek istemiyorum. Detaylı bilgi için şuraya bakabilirsiniz.

Artık MongoDB çalışır durumda, ama tahmin edeceğiniz gibi hiç bir güvenlik seviyesi yok. İsteyen bağlanıp veri yazabilir. O yüzden yönetim için hesap ekeleyelim. MongoDB servisi çalışırken aşağıdaki komutu çalıştırırsanız:

/opt/mongodb/bin/mongo

MongoDB ye bağlanacaksınız. Replica Set işlemleri, aslında bir yönetici hesabının yapması gereken işlemlerdir. O yüzden sisteme root kullanıcısı ekleyelim. İlk önce admin veritabanına use admin diyerek geçelim ve aşağıdaki komut yardımıyla root kullanıcısı ekleyelim.

db.createUser(
  {
    user: "root",
    pwd: "123456",
    roles: [ { role: "root", db: "admin" } ]
  }
)

Daha sonra şu komut yardımıyla kullanıcıya giriş yaptırabilirsiniz:

db.auth("root", "123456")

Artık kullanıcımız var, MongoDB’yi güvenlikli haliyle restart edebiliriz. Ama önce config dosyasına auth=true eklemeniz lazım. Ekledikten sonra MongoDB’yi restart edelim. Tekrardan admin database ine aşağıdaki komut ile bağlanalım.

/opt/mongodb/bin/mongo localhost:27017/admin

Bağlandıktan sonra db.getUsers() derseniz, yetkili olmadığınızı söyleyen bir mesaj belirecektir. Giriş yapalım:

db.auth("root", "123456"); 

Artık istediğimiz işlemi yapabiliriz.

Buraya kadar yaptığımız güvenlik tabakası olan bir MongoDB servisi kurmaktı. Şimdi replica set nasıl ayarlanır ona bakacağız.

Mantık çerçevesinden olaya baktığımız zaman, Replica Set üyelerinin birbirleriyle haberleşmesi şifreli olması lazım. Yani herhangi bir üye gelişi güzel Replica Set’e bağlanamamalı. Bunun için bir anahtar üreteceğiz ve bütün üyeler bu anahtarı kullanacak. Anahtarı aşağıdaki komut ile üretebiliriz.

openssl rand -base64 741 > mongokey.pem chmod 600 mongokey.pem 

mongokey.pem dosyası, Replica Set üyeleri tarafından okunabilecek bir yerde olması lazım. Bu dosyayı herbir üyenin bulunduğu container’a kopyalayabilirsiniz, ya da dockerdata ortak klasöründen okuyabilirsiniz. Bu anahtarı belirtmek için de config dosyasına bir kayıt daha koymamız lazım.

keyFile=/dockerdata/mongokey.pem

mongokey.pem dosyasını /dockerdata/ klasörüne kopyalayıp MongoDB üyelerini yeniden başlatabiliriz. Tabi yeni configi 3 üyenin config dosyasına ekelmeyi unutmayalım. Diğer üyeler aslında henüz ortada değil onları da aşağıdaki komutlarla başlatalım.

docker run -d --name mongodb-2 -v /dockerdata:/dockerdata mongodb:1.0 tail -f /dev/null
docker run -d --name mongodb-3 -v /dockerdata:/dockerdata mongodb:1.0 tail -f /dev/null

Artık 3 üyemiz var ve docker ps dediğinizde aşağıdaki gibi bir çıktı göreceksiniz.

04

Şimdi ilk container’a bağlanıp Replica Set ayarlarını yapalım.

docker exec -i -t mongodb-1 bash

ile bağlandıktan sonra

/opt/mongodb/bin/mongo localhost:27017/admin -u root -p ‘123456’

ile admin veritabanına bağlanalım ve Replica Set ayarlamaya hazırız.

Replica Set i akliftestirmek icin MongoDB konsolundayken aşağıdaki komutu kullanalım.

rs.initiate()

Bu komut aktifleştirmeyi yapıp kendisini de ilk üye olarak ekler. rs.conf() komutunu çalıştırırsanız aşağıdaki gibi bir çıktı görürsünüz.

05

Buradaki JSON objesinde members altında üyelerin bilgileri yer alır. İlk üyenin host değeri rasgele bir sayı olarak ayarlanmış. Aslında bizim mimaride üyelerin birbirleriyle bu adlarla ulaşması ilk aşamada host tanımlaması yapmadan imkansızdır. O yüzden buradaki host değerini IP ile değiştireceğiz. Peki IP yi nerden bulacağız? Burada docker inspect komutu imdadımıza yetişiyor. docker inspect <container_id> komutunu çalıştırınca ilgili container’a ait bir sürü bilgi gösterilecektir. NetworkSettings.IPAddress de ilgili container’ın IP adresi yer alır. <container_id> yi de docker ps diyerek ilgili container’ın id sini bulabilirsiniz. Aşağıdaki ekrana göre ilk mongo containerin id si 0f110ae7a9f3 tür.

06

docker inspect 0f110ae7a9f3 komutunu çalıştırdığımda IP adresini 172.17.0.29 olduğunu gördüm. Diğer container IP lerine bakmanıza gerek yok çünkü Docker ard arda açılan container ların IP lerini ardışık olarak atar. Yani diğer üyelerin IP adresleri bende 172.17.0.30 ve 172.17.0.32 dir. Şimdi gelelim ilk üyenin host değerini IP ile değiştirmeye. Basit olarak var olan Replica Set konfigürasyonunu bir değişkene atıp host değerini güncelleyeceğiz. Sonra da rs.reconfig() ile eski konfigürasyon ile değiştireceğiz.

cfg=rs.conf()
cfg.members[0].host=”172.17.0.29:27017”
rs.reconfig(cfg)

Diğer üyeleri de eklemek için aşağıdaki komutları kullanabilirsiniz.

rs.add(“172.17.0.30:27017”)
rs.add(“172.17.0.31:27017”)

Tekrar rs.conf() komutuyla diğer üyelerin de eklendiğini görebilirsiniz. rs.conf() dediğinizde her bir üyeye ait bilgileri göreceksiniz. Burda benim bahsetmek istediğim özellik priority. Priority, master seçilirken öncelikli olarak kullanılan alandır. Mesela ilk container 1.0 diğerleri 0 priority değerine sahip olursa, ilk container her zaman seçilen master olacaktır. Örnek aşağıdadır:

cfg=rs.conf()
cfg.members[0].priority = 1
cfg.members[1].priority = 0
cfg.members[2].priority = 0
rs.reconfig(cfg)

Priority hakkında daha fazla bilgiye buradan ulaşabilirsiniz

Son olarak anlatmak istediğim konu Replica Set’in durumuyla ilgili bilgi veren rs.status() komutu. Bu komutu çalıştırdığınızda aşağıdaki gibi bir çıktı alacaksınız.

07

Burada PRIMARY üyenin ne zaman seçildiğini electionTime ile, SECONDARY üyelerin nereye senkronize olduklarını syncingTo ile, SECONDARY üyenin PRIMARY üyeye ne zaman kontrol mesajı gönderdiğini lastHeartbeat, ne zaman yanıt aldığını lastHeartbeatRecv alanından anlayabilirsiniz.

Bu makalede temel olarak MongoDB Replica Set nasıl kurulduğundan bahsetmeye çalıştım. Buradaki anlatım en temel düzeyde olmasına rağmen epeyce uzun oldu. Bir sonraki makalede sizlere Replica Set mimarisinde günlük hayatta nasıl sorunlarla karşılaşılıyor ve bunların çözümleri nelerdir onlardan bahsedeceğim.

NoSQL’in Kısa Tarihi

1 NoSQL’in kısa tarihi

1.1 Eski Güzel Günlerin Bitişi

Eskilerin geçmişi “ah o eski güzel günler” diye andığını ve yeniler için ise “o eski güzel günlerin” henüz gelmediğini bilerek yaşadığımızda, her yeni oluşumun kendine has güzellikleri ile geldiğini de bilmeliyiz. Bilgi teknolojileri dünyasının eski güzel günlerinde, eldeki problemin çözümü için gerekli olanlar az sayıda seçenek arasından seçilirdi. Genel maksatlı bir programlama dili, bir veri tabanı çözümü, bir donanım seçilir ve gerisi şelale tipi proje planının uygulanmasından ibaret olurdu.

Özellikle 2000 li yılların başından itibaren yaşanan gelişmeler ile “eski güzel günleri” bir daha gelmemek üzere geride bıraktık. Hayatın ve bilginin hızlı akışı ile eski alışkanlıklar bir bir değişiyor. Bu oturmuş bir düzende kaçınılmaz olarak “eskiler” ve “yeniler” arasında bir mücadele yaşanmasına da yol açıyor. Eskiler derken, her şeyi kastediyoruz, insanlar, teknolojiler, yöntemler, alışkanlıklar.

Tek bir yazıya sığmayacak kadar geniş olan bu konuda, bu yazımızda amacımız birçok kaynaktan zaten gelişmeleri takip eden siz okurlara farklı bir açıdan genel değişiminin ne olduğunu göstermek olacaktır. Bu yazı fikri, internetten izlediğim bir Renk değiştirme kart numarası videosunu seyrederken uyandı. Bu videoda numarayı yapan kişi, destenin içinden karşısındaki kişinin seçtiği rastgele bir kartın arka rengini el çabukluğu ile değiştiriyor. Numara bittikten sonra ise bu numarayı nasıl yaptığını daha geniş açıdan çekim yapmış bir kameranın yardımı ile görüyoruz. O da ne? Meğerse değişen sadece kartın rengi değilmiş, ekranda görülen her şeyin rengi değişmiş oysaki. Bu video bize dikkatimizi verdiğimiz şeyden büyük bir resim olduğunu ve bu resmi anlamanın gerçek değişimi anlamak olduğunu gösteriyor. Bu nedenle önce büyük resimde nelerin olduğuna bakarak başlayacağız.

Değişim Öncesi

1.2.1 Büyük Resim

2009 yılına kadar, verilerin saklanması ve erişilmesi probleminin çözümü için geliştirilmiş başka veritabanı sistemleri var olsa da, İlişkisel Veri Tabanı Yönetim Sistemleri (RDBMS) bilgi teknolojileri dünyasında ezici bir üstünlük kurmuştu. Bu nedenle ‘veri tabanı’ dendiğinde ilişkisel kelimesi kullanmaya gerek duyulmazdı.

1960 lı yıllara geri gittiğimizde, verilerin saklanması ve bu saklanan verilere hızlı ulaşım problemi için birkaç çözüm önerilmişti. Bunlardan hepimizin bildiği ilişkisel veri tabanları, kümelerin üzerinde tanımlanan ilişkilere dayanmaktadır. Bu yapı üzerine kurgulanan Yapısal Sorgu Dili (SQL), esasen iki kümenin kesişimi, birleşimi, farkı, kartezyen çarpımı gibi kavramların komutlara dönüştürülmüş halidir. Hal böyle olunca, saklanan verinin belli bir yapıda olması, bu yapının da tablolara dayanması çok şaşırtıcı gelmiyor. Esasen bunun arka planında, iş dünyasında dijitalleşme olmadan çok önceleri yaygınlaşan tablo formatlı muhasebe tabloları ve bunun devamı olan ve günümüzde de yaygın olarak kullanılan MS Excel gibi SpreadSheet uygulamalar vardır.

Bu temel yapının üzerine, veriye erişimin hızlanması için indekslemeler, güvenlik için erişim yetkileri, yerden tasarruf için sıkıştırma algoritmaları, zaman içinde çıkan bu problemlerin dışındaki önemli bazı problemlerin çözümü için Atomiklik, Tutarlılık, İzolasyon, Sağlamlık (ACID) kelimeleri ile özetlenen özellikler geldi.

İlk Alternatifler

İlişkisel veri tabanlarına alternatif arayışlarının geçmişi 1970 lerin sonlarına gider. Alternatifler derken üç ayrı grubun var olduğunu baştan söylemekte fayda var.

1.2.2.1 Birinci grup

1.2.2.1.1 NoSQL veri tabanları

Veri modelinin ilişkisel olduğu fakat sorgu dilinin SQL olmadığı gruptur. Bu grubun iyi bir örneği olan Ingres veritabanı 1970 ile 1985 arasında gelişti ve 1980 lerin başında ORACLE ile rekabet ediyordu. Sorgu dili SQL değil Quel di. Her ne kadar rekabete dayanamadıysa da, küllerinden Sybase, MS SQL Server gibi veri tabanları doğdu. Hatta Postgres projesi ile (Post Ingres) PostgreSQL e evrilmiştir.

NoSQL kelimesini ilk olarak kullanan, 1998 yılında geliştirdiği açık kaynak kodlu ilişkisel veri tabanına sorgulama dili olarak SQL kullanmadığı için NoSQL DB ismini veren Carlo Strozzi dir. Kendisi bu nedenle, şu anda ilişkisel olmayan veri modeline dayanan veri tabanları için yaygın olarak kullanılan NoSQL kelimesi yerine NoREL (No Relational) kelimesinin daha uygun olacağını belirtmiştir. Yani ilk kullanıldığında NoSQL gerçekten ‘SQL i olmayan’ anlamında kullanılmıştır.

Strozzi

1.2.2.2 İkinci grup

İlişkisel veri modeline dayanan ama kayıtların satır bazında değil sütün bazında tutulduğu veritabanlarıdır.

1.2.2.2.1 Kolon bazlı ilişkisel veri tabanları

1996 yılında Sybase IQ, ilk kolon bazlı analitik platform oldu.

1.2.2.3 Üçüncü grup

Veri modelinin de farklı olduğu veri tabanlarıdır.

1.2.2.3.1 Nesne ilişkili veri tabanları

Nesne tabanlı yazılım dillerinin yaygınlaşmaya başlaması ile birlikte nesne ilişkili veri tabanları (object relational databases) öne çıksa da yaygınlaşması mümkün olmamıştır. En büyük avantajları veritabanı ile uygulamanın geliştirildiği programlama dilinin aynı veri modelini kullanıyor olmaları idi.

1980 sonrasında nesne tabanlı veri tabanları konusunda ciddi çalışmalar ticari ürünlere dönüştü. GemStone (Smalltalk), Objectivity/DB gibi nesne veri tabanları örnek verilebilir. 1981 de ‘UNIX üzerindeki bilgi’ Informix (INFORMation on unIX) adı verilen nesne ilişkili bulit-in desteği olan Informix DB kullanılmaya başlandı.

1.2.2.3.2 Anahtar-değer (Key-Value) veri tabanları

Verilerin bir anahtar değere ve buna karşılık gelen herhangi bir tipteki veriyle birlikte tutulmasıdır. Örnek olarak telefon rehberindeki telefon numaraları ve karşı gelen ad soyad bilgilerini verebiliriz. Tabii anahtar değerin tekil olması zorunluluğu vardır. Bunun bildiğim en erken örneği 1970 li yılların başında MUMPS (Massachusetts General Hospital Utility Multi-Programming System) ın şemasız M veri tabanıdır.

1.2.2.3.3 Graf veri tabanları

Graf teorisine dayanan ve verinin düğümler ve bu düğümleri birbirine bağlayan bağlantı çizgileri ile ifade edildiği bir veri tabanı yapısıdır. Bu bağlantılar doğrudan gösterge (pointer) denen bellek adresi ile verildiği için indeksleme ihtiyacı olmadan hızlı erişim olanağı verir. Graf teorisinin temel uğraşları olan iki düğüm arasındaki en kısa yolun bulunması, alt grupların belirlenmesi gibi sorulara graf veritabanları ile hızlı şekilde cevap bulunabilir. Uzun yıllar ilişkisel veritabanlarının gölgesinde kalmış olsalar da son zamanlarda yeniden popülerlik kazanmaya başlamıştır.

1.2.2.3.4 Alana özel veri tabanları

Bu kategoride, belli bir iş alanına özel ihtiyaçları karşılamak için özel olarak dizayn edilmiş veritabanlarını toplayabiliriz. Bunlara örnek, 1980 li yılların başından itibaren Electronic design automation (EDA or ECAD) entegre devre veya baskılı devre kartları gibi elektronik sistem tasarımı yapan şirketlerin kullandıkları yazılımları desteklemek için geliştirilmiş EDA database elektronik dizayn veritabanı. 1986 yılında kurulan Amerikan Synopsys şirketi bu alanda önde gelen firmadır.

1.3 Değişimin başlaması

Anlatılan bu büyük resmin değişiminde, Web in 90 lı yıllarda gelişip yaygınlaşmasının katkısını en ön sırada görebiliriz.

1.3.1 CAP Teoremi

Bu bakımdan CAP teoremi olarak anılan ve

“Dağıtık bir sistem inşa ederken, olmasını isteyeceğiniz üç özellikten; tutarlılık (consistency), cevap verebilme (availability) ve ağdaki parçalanmalara tolerans (tolerance of network partitions) dan sadece ikisine sahip olabilirsiniz.”

şeklinde özetlenebilen teoremin ilk olarak Eric Brewer tarafından 1998 yılında ortaya atılması şaşırtıcı değildir. Temel bileşenler;

CAP Teoremi dağıtık sistemler konusunda çalışan araştırmacıların ve uygulayıcıların zaman zaman eleştirdikleri, üzerinde tartışmaların yapıldığı bir konudur. Bu bakımdan, Eric Brewer’in 12 yıl sonra konu hakkında yayınladığı yazısı meraklısının ilgisini çekebilir. Konu hakkındaki örnek bir tartışma için Daniel Abadi’nin yazısına ve gelen yorumlara bakabilirsiniz. Esasen bu üç özellikten; Tutarlılık ve Cevap verebilme, ağda parçalanma olduğu zaman birbirleri ile rekabet eden iki özelliktir. Bu teoreme pratik bir uygulama örneğini Brewer şu şekilde veriyor. ATM lerde para çekme, para yatırma ve bakiye sorgulama sistemini ele alalım.

Tutarlılık her zaman istenen bir özellik midir? Yani C A yı yener mi? Teorik olarak evet, fakat pratikte hayır. Yüksek hizmete açık olma (availability) yüksek gelir ve müşteri memnuniyeti anlamına gelmektedir. Ana kural bakiyenin sıfır veya üstünde olmasıdır. Bunu ihlal edecek operasyon para çekme olacağı için buna özel önem verilmelidir. Diğerleri her zaman çalıştırılabilir. ATM dizaynı yapanlar ağda kopma olduğu zamanlarda para çekmeye engel olmalıdırlar. Bu ise çok kısıtlayıcı bir etki olarak hizmete açık olmayı (availability) düşürür. Bunun yerine tek başına çalışma modunda belirlenen bir miktar kadar para çekilebilmesine izin vermek çözüm olabilir.

1.3.2 Hadoop un doğuşu

Web in hızlı bir gelişim sürecine girdiği 2000 li yılların başlarından itibaren oyunun kuralları yavaş yavaş değişmeye başladı. Bu yavaş değişim 2009 yılında ki büyük patlamaya kadar daha çok webde doğan Google, Yahoo!, Amazon gibi şirketlerin, kendi problemlerine çözüm çabaları olarak bilindi ve sınırlı bir alanda etkili oldu. Birçok bilgi teknolojileri çalışanı dahi gelişmelerden habersizdi. Değişimin fitilini ateşleyen Google un yaptığı çalışmaları makale olarak yayınlaması, bilgi birikimini kısmen de olsa dünya ile paylaşması oldu. 2003 yılında The Google File System, 2004 yılında MapReduce, 2006 yılında Bigtable makaleleri yazılım dünyasında heyecan uyandırdı. Açık kaynak kodlu, dağıtık, kümeleme yapısı üzerinde veri işleme yapabilen mimari üzerine kurulmuş bir çözüm için şartlar hazırlanmıştı.

2002 yılında açık kaynak kodlu bir Web arama motoru yapmak için kolları sıvamış olan Mike Cafarella ve Doug Cutting topladıkları text veriyi işleme konusunda uygun bir çözüm üretmeye çalışırken Google un makalelerini okudular. Nutch ismi verilen ve amacı web i tarayıp topladığı veriyi indeksleyerek etkin bir arama motoru yapmak olan ana projede ihtiyaç olan, dağıtık bir veri işleme altyapısı olarak, Cutting in Hadoop ismini verdiği benzer bir yazılımı geliştirmeye başladılar. Bu noktada Yahoo!, Cutting i işe alarak oyuna dahil oldu. Altı ay içinde Yahoo! nun kullandığı teknolojilerden birisi oldu, iki sene sonra ise vazgeçilmezi haline geldi.

Hadoop ile güçlendirilen veri analizi, reklam alanında kişilerin ilgileri ve reklamın hedef kitleye ulaşması konusunda yapılan analizlerde kullanıldı. Yapılan analizlerden birisi kişilerin browser homepage ini değiştirmesine neden olan hikayeyi ortaya çıkarmaktı. Yahoo on milyonlarca dolar harcadığı tahmin edilen Hadoop u açık kaynak olarak tutmaya devam etti. Bu değişimin ateşinin çok uzaklardan görülebilmesini sağladı. 2008 yılında Microsoft, kendi arama sistemini geliştirmek için doğal dil işleme yöntemlerini kullanarak arama sorgusu problemini çözme konusunda çalışan ve Hadoop a destek veren start-up firmalarından Powerset‘i satın alarak oyuna girdi. Satın alma sonrasında bu desteğin devam etmesi konusunda yeşil ışık yakarak Hadoop un geliştirilmesine destek verenlere katıldı. Facebook elindeki milyarlarca fotoğrafı işlemek için Hadoop teknolojisini kullanmaya başladı.

Dough Cutting ve Hadoop :)
Dough Cutting ve Hadoop :)

1.3.3 Değişimin katalizörleri

1.3.3.1 Çevik yöntemler

Bu yöntemler şemasız çalışmayı destekleyen yöntemlerdir. BT projelerinin iş ihtiyaçlarından kaynaklı hızlı değişim ve gelişim taleplerine cevap verebilmesi nedeni ile çevik (agile) yöntem ve benzerlerinin popülerliği artmıştır.

1.3.3.2 Polyglot programlama

Gittikçe artan bir şekilde, genel uygulama dilini belirlemek ve o dilde uzman geliştiricileri projeye dahil etmek kendi başına yeterli olmadığı, çıkan alt problemleri çözmek için farklı programlama dillerini kullanmanın olağanlaştığı bir döneme girildi. Tek bir programlama dilinin yetmediği bir dönemin başladığını ilk haber verenlerden birisi olan Neal Ford, 5 Aralık 2006’da bloğunda Polyglot Programming‘i tanımlarken şöyle demişti:

“tek bir genel maksatlı dil ile uygulama yazma devri kapanmıştır, alana özel dilleri eklemeye başlayacağız.”

Bu iddia temel olarak bir lisanı öğrenen insanların diğer lisanları öğrenirken temel kavramları zaten bildikleri için çok hızlı bir şekilde öğrenebileceklerine dair yapılan araştırmalara dayanmaktadır. İnsanların konuştukları dillerde olduğu gibi, programlama dillerinde de geçerli bir çıkarım olduğu düşüncesi temelinde şekillenmektedir.

1.3.3.3 Polyglot dayanıklılık

Scott Leberknight, 15 ekim 2008 de yazdığı yazıda programlama dillerindeki polyglot kavramını veritabanı dünyasına uyarlıyor. Dayanıklılık (persistance) kelimesi, zor koşullar altında ayakta durma, kendine verilen görevleri yerine getirme için kullanılmaktadır. Polyglot Persistance, veri tabanlarından beklenen persistance özelliğinin tek bir veri modeline dayalı olarak istenen şekilde sağlanmasının, mevcut problemlere istenen performans özelliklerini kazandırmak için yeterli olmadığı fikrini savunuyor. Farklı veri modellerine dayanan birden fazla veri tabanlı çözümlerin yaygınlaşacağını iddia ediyor. Bunun anlamı aşağı yukarı benzer yapıya sahip, benzer performans özellikleri olan alternatifler içinden bir Veri Tabanı Yönetim Sistemi (DBMS) seçme devrinin kapanmasıdır. Eski güzel günlerin baskın ilişkisel veri modeli artık hiç düşünülmeden seçilen bir veri modeli olmaktan çıkmaya başlamıştır.

1.3.3.4 Entegrasyon

24 Kasım 2008’de yazdığı bir yazıda Martin Fowler; 1980 li yıllardaki nesne ilişkili veri tabanlarının yaygınlaşmamasının en önemli sebebinin, ilişkisel veri tabanlarının bir entegrasyon aracı olarak ve SQL in bir protokolmüş gibi değişik uygulamaların birbiri ile olan veri alış verişinde kullanılıyor olmasından kaynaklandığını söylemektedir. Alternatif yolların özellikle Webservice lerin çıkması ile, çoğunlukla XML formatlı text dokümanlar kullanılarak uygulamaların birbirleri ile sql olmadan konuşmaları sağlanarak, farklı veri tabanları kullanmanın önündeki en önemli engelin aşıldığını öne sürmektedir. Her uygulamanın kendi veri modeline en uygun olana karar vermede hiç olmadığı kadar özgür olduğunun değişimin en önemli sebebi olduğunu dile getirmiştir. 16 Kasım 2011 tarihli yazısında da konuyu daha geniş kitlelere duyurmuştur.

1.4 NOSQL 2009

Last.fm isimli, kişilere dinledikleri müziğe göre önerilerde bulunan (music discovery & recommendation system) bir firmanın Londra’daki ofisinde çalışan Johan Oskarrson, yukarıda özetini verdiğimiz gelişmeler sonrası popüler olan Hadoop konusunda son gelişmelerin konuşulup tartışılacağı Hadoop Submit e katılmak için Haziran 2009’da San Francisco ya gitmeye karar veriyor. Konu ile ilgili birçok kişinin orada olacağı düşüncesi ile katılımın ücretsiz olduğu açık kaynak kodlu, dağıtık, ilişkisel olmayan veri tabanları konulu bir etkinlik NOSQL meetup düzenlemek istiyor ve bloğunda bunu şöyle duyuruyor:

‘To make the most of the flight money I’m putting together a free meetup about “open source, distributed, non relational databases” or NOSQL for short.’

Oskarrson, kısa NOSQL kelimesini büyük ihtimalle tweeter da kullanmak ve akılda kalıcı olması nedeni ile üzerinde çok düşünmeden seçmişti. İlgi çok yoğundu, mevcut 100 kişilik katılımcı kapasitesi beş saatte doldurulunca, yoğun talep üzerine ek 50 kişilik kontenjan da açılmıştı.

O toplantıda kapalı kaynak kodlu Google un BigTable ı, Amazon un Dynamo su ve Yahoo! PNUTS’ından ilham alınarak yapılan, açık kaynak kodlu NRDBMS ler (NonRelational Database Management Systems) konuşuldu. Bu toplantı ilk olarak NoSQL kelimesinin ilişkisel olmayan (non relational) olarak kullanılmaya başlanması olarak alınabilir. Toplantıdaki içeriklere ulaşmak için tıklayın.

NoSQL veritabanlari

1.4.1.1 İsim arayışları

NoSQL isminin mevcut harekete, uygun olmadığı yolundaki eleştiriler alternatif önerileri ile birlikte geldi. Adam Keys tarafından Ağustos 2009’da Post-relational kelimesi önerildi. nosql-database.org‘un arşivlerine başlıklarda geçen NoSQL ve NOSQL kelimelerinin kullanımı olarak baktığımızda, NOSQLin 2 Kasım 2009 da Debasish Ghosh nun ‘NOSQL Movement’ yazısında ‘Call it NoSQL (~SQL) or NOSQL (Not Only SQL), the movement has a mission.’ ile geçtiğini görüyoruz. Yine aynı arşivde en son 15 Aralık 2009 da NOSQL i Nati Shalom un bloğundan alınan yazının başlığında ‘The Common Principles Behind the NOSQL Alternatives’ ve yazıda aşağıdaki resim görülüyor.

Not only sql

Sonrasında Not Only SQL açıklaması kullanılmaya devam ediliyor fakat NoSQL şeklinde yazılma kabul görüyor. Bu sitenin ana sayfasında da belirtildiği üzere:

‘The original intention has been modern web-scale databases. The movement began early 2009 and is growing rapidly. Often more characteristics apply such as: schema-free, easy replication support, simple API, eventually consistent / BASE (not ACID), a huge amount of data and more. So the misleading term “nosql” (the community now translates it mostly with “not only sql“) should be seen as an alias to something like the definition above.’

Sonuç olarak yanlış anlaşmalara yol açsa da NoSQL in bir alias olarak kullanılması genel kabul görüyor.

Ekim 2009 da Atlanta da NoSQL Doğu konferansında kullanım olağanlaştı.
Ekim 2009 da Atlanta da NoSQL Doğu konferansında kullanım olağanlaştı.

1.5 Günümüz

Açık kaynak kodlu, dağıtık, kümeleme yapısı üzerinde veri işleme yapabilen mimari üzerine kurulmuş çözümlerin sayısının arttığı, RDBMS ve NoSQL sistemlerin birbirlerine benzemeye başladığı bir dönemi yaşıyoruz. NoSQL ve Hadoop çözümlerinde SQL e benzeyen dillerin daha çok kullanılıyor olması, NoSQL veri tabanlarında kaçınılan join operasyonunun kolay ve etkin bir şekilde yapılabilmesini sağlayan ürünlerin ön plana çıktığı, SSD diskler gibi disk teknolojilerindeki gelişimlerin veritabanlarının mimarisine etki ettiği bir zaman dilimindeyiz. RDBMS lerde olan birbirine çok benzeme, en azından yakın zamanlarda NoSQL veritabanları için geçerli olmayacak gibi görünüyor. Bir projede farklı veritabanları kullanmanın sıradan olduğu bir döneme giriyoruz. Stream verinin işlenmesinin yaygınlaşması sonucu dağıtık işleme yapma özelliğinin batch ile birlikte stream özelliği kazandığını da görüyoruz. Bu ise diske yazmadan RAM yani bellekde verilerin işlenmesine dayanan in-memory veritabanlarının daha çok kullanıldığı bir uygulama mimarisine götürüyor bizleri. Veritabanına özel saklama motoru (Storage engine) kullanmak yerine probleme uygun saklama motoru kullanmaya izin veren veri tabanlarının öne çıktığını görüyoruz. Hatta yıllardır kullanılan saklama motorları yenileri ile değiştirilmeye veya alternatif olarak sunulmaya başlandı. Örnek olarak CouchDB nin yeni saklama motoru ForestDB Ekim 2014’de duyurulmuştu. MongoDB ninki okuma yoğun çözümler için MMAP, yazma yoğun çözümler için yeni storage engine WiredTiger, veya 3rd party diğer motorlar kullanılabilmektedir.

1.6 Sonuç

Yeni BT dünyasında, iş kullanıcılarının verilere erişim ve analiz konusundaki aylar alan ve ciddi maliyetler getiren isteklerinin karşılanması için NoSQL seçenekler yeni alternatifler sunuyor. Bu alternatiflerin değerlendirilmesi için eski alışkanlıkların değiştirilmesi gerekiyor. Yeni tip yazılımcı, veri analisti, veri bilimci kısaca veriden değer üretenleri daha çok konuda bilgi sahibi olmaları gerekecek dinamik bir gelecek bekliyor. Bu yazının bu anlamda faydalı olacağını umuyorum.

R Programlama Dili

R_logo.svgBu yazımızda, veriyi anlamlandırmak için kullanılan analitik yöntemler için geliştirilmiş istatistiksel paket ve programlama dilleri içinde son yıllarda öne çıkan bir seçenek olan ve iki milyon kullanıcısı olduğu söylenen R programlama dili nin sağladığı avantajlara kısaca bakacağız. Özellikle büyük veri işlemede de etkin bir şekilde kullanımının örnekleri açıklandıkça bu dilin daha da popüler olacağı şüphesiz. Son olarak, R dili üzerine büyük veri ambarları ve Hadoop kapsamında kurumsal çözümler üreten Revolution Analytics firmasının Nisan 2015 başında Microsoft firması tarafından satın alınması bu trendin devam edeceğinin en büyük kanıtı.

Dünyada popüler ve yaygın olarak kullanılan programlama dilleri için bazı peryotlarda çeşitli indeksler ve sıralamalar yayınlanıyor. Bunların içinde benim takip ettiğim indeks, on yıldır aylık olarak yayınlanan TIOBE index. Nisan 2015 sıralamasında R dili 19 uncu sırada ve analitik dünyasının devi SAS firmasının SAS programlama dilinin 2 basamak üstünde. Bu denli yoğun rekabetin olduğu bir alanda nasıl oluyor da açık kaynak kodlu ücretsiz bir yazılım böyle bir başarı kazanabiliyor? Yıllarca SAS programlama dilini kullanmış bir veri madencisi olarak bu konudaki değerlendirmelerimi, ayrı bir yazıya bırakarak R programlama dilinin temel özelliklerine değinerek yazımıza başlayalım.

İstatistiksel çıkarım yapmak için kullanılan teknik ve algoritmaların hazır olarak kullanımı için geliştirilen kütüphaneleri de içeren, buna makine öğrenmesi algoritmalarının da eklendiği R dilinin fonksiyon tabanlı ve nesne bazlı bir dil olması ve rakiplerine görece daha yeni bir dil olması en büyük artılarından. Temel matematiksel işlemlerin yapılması dışında, karmaşık matris işlemlerinin bir satırlık kod ile yapılıyor olması, açık döngü yapıları yerine alternatif olan gizli döngülere izin veren etkin yapısı, dile yeni başlayanlar için sıkıntı yaratsa da ilerleyenler için büyük imkanlar sunuyor.

Ayrıca, açık kaynak kodlu ve ücretsiz ulaşılabilmesi, çok geniş kitleler tarafından kullanılan ve birçok veri işleme ve veri madenciliği yazılımının çözümüne dahil ettiği ortak çözüm dili olma yolunda emin adımlarla ilerlemesini sağlamaktadır.

R programlama dilinin nesne tabanlı bir dil olduğunu söylemiştik. Bu nedenle kullanılan her şey bir nesnedir.

01

Komutların genel yapısı,

çıktı <- komut(<girdi(ler)>)

şeklindedir. Her sonuç bir nesne olarak tutulur ve başka bir fonksiyona parametre olarak gönderilebilir. Örneğin c ile gösterdiğimiz sayıların ortalamasını almak için

Ortalama <- mean( c )

demek yeterlidir. Matematiksel işlemler ve istatistiksel hesaplamaları kolayca yapmak üzerine kurgulanmış bir dil olarak, matris ve vektör hesaplamaları çok kolaylaştırılmıştır. Matris oluşturma, matris çarpımı ve transpozunu alma işlemleri oldukça kolaydır.

02

Eldeki verinin işlenmesi ve analizi için de gayet uygun bir dildir ve veri bilimcilerinin Python dili ile birlikte kullandıkları zaman, veri işlemede her problemin üstesinden gelebilecek bir ikili olurlar.

Grafiksel analiz ve işlemler R programlamanın güçlü yanlarından birisidir. Temel faydaları;

  • Yaptıklarımız manuel işlemler olmadığı için kolay tekrar edilebilir geliştirilebilir, aktarılabilir, otomatikleştirilebilir.
  • Bir analizi birçok değer için tekrar etmek çok kolaylaşır.
  • Veriyi işleme kolaylaşır.
  • Programlama ile benzer problemlere hızlı çözüm mümkün olur.

Bu amaçla gelişmiş bir komut seti sunulmaktadır. Bunlardan bazılarını kısaca görerek devam edelim. R dilinin kütüphanelerle zenginleştirilmiş yapısı içinde base R olarak isimlendireceğimiz ana paketin içinde bulunan plot komutu ile aşağıdaki grafikleri kolayca elde edebiliriz.

03

04

Başka bir örnek, ortalaması 0, standart sapması 1 olan bir normal dağılımı 500 deneme için şu şekilde bulup, grafiğini çizebiliriz.

05

Bu çok basit grafik örnekleri verdikten sonra, istatistiksel hesaplamaların nasıl yapıldığı konusuna da girerek, bu tür bir işte geçirilen adımları da içerecek şekilde daha somut bir örnek ile devam edelim.

İhtiyacımız olan veriyi Dünya Bankası web adresinden Ülkelerin Nüfus Sayısı Değişim Oranları Verisi olarak alıyoruz. Kaynağından CSV formatında aldığımız verinin, R dilinde bir nesne olarak yüklenmesini çok kolay bir şekilde yapıyoruz. Bunun için benim de kullandığım ve gayet memnun olduğum IDE RStudio yu kullanırsanız, menüler ile de bu işlemi gerçekleştirebilirsiniz.

06

Veriye kısaca bakacak olursak, ülkelerin 1960 yılından itibaren yapılan nüfus sayımları sonuçlarına göre, senelik nüfus sayısı değişim oranlarını yüzde olarak bize veriyor. Şimdi R dilini kullanarak bu verileri kısaca analiz edelim. Öncelikle gereksiz olan kolonlardan kurtulalım.

07

Veriyi incelediğimizde bir zaman serisi verisi olduğunu görüyoruz. Zaman serileri, düzenli veya düzensiz aralıklarla değişkenin ölçülen değeri ile ölçüm zamanının sıralama ilişkisinin dikkate alınarak veri olarak saklanması ile oluşan matematiksel yapılardır. Elimizdeki veride ölçülen değişken nüfus değişim oranı, zaman dilimi yıldır. Zaman serileri; enerji, havacılık, parakende, telekom, finans, askeriye, bilimsel deney vb birçok alanda karşımıza çıkan ve Şeylerin İnterneti (Internet of Things – IOT) olarak isimlendirilen yeni büyük verinin temelidir. Veri üreten ve bu veriyi internet yolu ile aktaran akıllı cihazların yaygınlaşması ile yakın zamanda iş dünyasının karar alma mekanizmalarının kökten değişeceği görülmektedir. Öyle ki son birkaç yıldır zaman serileri için geliştirilen TSDB gibi özel veritabanlarına şahit oluyoruz.

Nüfus değişimi verilerimize dönecek olursak, 1960 yılı bütün ülkelerin verilerinden yola çıkarak, şöyle bir grafiğe çok kolay erişebiliyoruz.

08

Bu grafikten 1960 yılında ortalama nüfus artış hızının ikiyi biraz geçtiğini, ekstrem değerleri yuvarlak işaretlerle görüyoruz ve maksimumda %10 a yakın bir artışın olduğu ülke olduğu negatif olan yani nüfusu azalan bir ülke de olduğunu görüyoruz. Bu çizimlerin nasıl yorumlanacağı ile ilgili detay merak edenler tıklayın.

Üç ülke için 1960-2013 yıllarındaki bütün verileri değerlendirerek bakacak olursak;

09

10

Summary komutu ile aldığımız temel istatistiklere bakarak hemen görebiliyoruz ki nüfus artış ortalaması tüm dünya için 1960 dan bu yana düşüş trendinde.

11

Bunu grafik olarak da görebiliyoruz. Bütün dünyada 1960-2013 arasındaki nüfus değişim oranlarının yıl bazındaki temel istatistiklerini tek grafikte görmek mümkündür.

12

13
Dünyanın nüfus değişim oranlarındaki değişimin 1980 yılı mallonrasında, azalma trendinde olduğunu görüyoruz.

İncelediğimiz verinin zaman serisi olduğunu tespit etmiştik. Bu veriyi hazır fonksiyonları kullanarak kolayca işleyebilmek için R dilindeki ts sınıfını kullanabiliriz. Bunun için yılları gösteren kolonların satır olarak bulunması gerekiyor. Bu noktada veriyi uygun hale getirmek için bir ön işlem gereksinimi doğuyor. Bu bize R dilinin bu konudaki yeteneklerini göstermek için fırsat sunuyor. Bu amaçla R nin temel veri tiplerinden data.frame i, transpoze eden fonksiyonu kullanabiliriz ama bunu yaparken ilk kolondaki ülke isimlerini ayırmak, işlemin püf noktasıdır.

14

Bu şekilde veriyi aşağıdaki formata getirmiş olduk.

15

R dilinin tanımlı sınıflarından ts class ına geçirebiliriz. Verimizde zaman boyutunda her yıl bir gözlem/ölçüm olduğu için, başlangıcı ve frekansı verirken bunu dikkate alıyoruz.

16

Bu şekilde birden fazla ülke için 1960-2013 arasındaki çoklu bir zaman serisini elde etmiş oluyoruz.

17

Zaman serilerinin bir alt bölümünü almak istersek şu şekilde yapabiliriz.

18

Burada 1985-2013 aralığındaki zaman dilimi Türkiye verisi için basit bir lineer model (lm) yapabiliriz.

20

19

Temel grafik paketi ile çizimler görsel olarak zayıftır. Fakat yeteneklidir.

21 22

Bu noktada temel R içinde olmayıp ek paket olarak geliştirilmiş olan görsel yönden güçlü grafikler veren ve ek özellikler katan ggplot2 kütüphanesi’nden de bahsetmekte fayda var. Örnek olarak yukarıdaki grafik ggplot2 ile şu şekilde görselleştirilebilir.

23 24

Burada ggplot2 nin geliştirilmesi gereken bir noktadan bahsetmekte fayda var, zaman serilerini desteklemiyor. Bu nedenle veriyi dönüştürmek zorunda kalıyoruz. Bunun için aşağıdaki tablo üzerinde bazı değişiklikler yapmak gerekiyor. Her gözlem zamanı bir kolon ile gösterildiği formattan, her gözlemin yatayda olduğu bir formata geçmek gerekiyor. Bu işleme teknik olarak de-pivoting denmektedir. Bu işlem ile her bir satırda; ülke kodu, yıl ve gözlem değeri ayrı ayrı yer alacaktır. Elimizdeki veri şu şekilde,

25

De-pivoting işleminin R dilinde melt komutu ile ne kadar kolay yapılabildiğini görelim. Bunun için reshape paketine ihtiyaç duyuyoruz.

26 27

Bu formattaki veriden ilgilendiğimiz ülkelerle ilgili veriyi filtreleyip ggplot2 nin gelişmiş grafikleri ile görelim.

28 29

Sonuç

Büyük veriyi işlerken veriyi depolamak kadar önemli olan depolanan veriden sonuç çıkarma işlemi için etkili ve üründen bağımsız bir analitik dile ihtiyaç bulunmakta. Bu dil için en çok öne çıkan R dilinin analitik karar alma süreçlerinde ve veri analizinde gittikçe daha çok kullanılacağını görüyoruz. Bu nedenle bu konularda çalışan veya çalışmak isteyen veri bilimcisi ve analistlerin R dilini iyi bir şekilde öğrenmelerinde büyük fayda vardır.