Sunday, December 15, 2013

PDF Icinde Animasyon, Ubuntu Uzerinde Acrobat Reader - acroread

Animasyonlu PDF ornegi

http://mlss.tuebingen.mpg.de/Hennig_2013_Animating_Samples_from_Gaussian_Distributions.pdf

Her nedense acroread Ubuntu 64 ortaminda yok, 32 bitlik olani 64 bit uzerinde kurmak lazim.

wget http://ardownload.adobe.com/pub/adobe/reader/unix/9.x/9.5.1/enu/AdbeRdr9.5.1-1_i386linux_enu.deb

sudo dpkg -i --force-architecture AdbeRdr9.5.1-1_i386linux_enu.deb 

sudo apt-get install -f

sudo apt-get install libxml2:i386 lib32stdc++6

Simdi acroread calisacaktir.

Monday, December 2, 2013

Tex Paketleri Eklemek

TeX'e ek islevsellik kazandiran stil dosyalari (style files) kurmak icin ne yapilir? Bu dosyalar .sty soneki tasirlar. Kurmak icin .ins ile biten bir dosya uzerinde latex isletmek gerekebilir, ve .sty dosyasi uretilir. Ubuntu uzerinde bu dosyalar alinir ve

/usr/local/share/texmf/tex/latex

altinda pakete tekabul eden bir dizin mkdir ile yaratilip oraya kopyalanir. Daha sonra iki ust dizine cikilir, orada ls-R adinda bir dosya var. Orada

./tex/latex:
[yeni paket]


...
./tex/latex/[yeni paket]:

[yeni paket].sty

Ekleri yapilir. Artik \usepackage ile bu paketi kullanabilirsiniz.


Tabii tum bunlari kolaylastiracak bir script soyle,

import os

pkgs = ['paket1','paket2']

fout = open("/tmp/ls-R","w")
fout.write("% ls-R -- filename database for kpathsea; do not change this line.")
fout.write("\n")
fout.write("./tex/latex:\n")
for x in pkgs: fout.write(x+"\n")
   
fout.write("\n")

for x in pkgs:
    fout.write("./tex/latex/%s:\n" % x)
    fout.write("%s.sty\n" % x)
    fout.write("%s.tex\n" % x)

for x in pkgs:
    os.system("mkdir /usr/local/share/texmf/tex/latex/%s" % x )
    os.system("cp %s.sty /usr/local/share/texmf/tex/latex/%s/" % (x,x) )
    os.system("cp %s.tex /usr/local/share/texmf/tex/latex/%s/" % (x,x) )

fout.close()

os.system("cp /tmp/ls-R /usr/local/share/texmf/" )

   
Bu script ayni dizin icinde gerekli sty dosyalarinin oldugunu varsayar. Script sudo olarak isletilmelidir.

Saturday, November 23, 2013

Sayfadan Video Indirme, videolectures.net, rtmpdump

Komut satiri araclari kullanarak mesela videolectures.net gibi bir siteden nasil video indiririz? Once rtmpdump kurmak lazim,

sudo apt-get install rtmpdump

Bu aracin hangi adrese isaret edecegini bilmesi lazim. Fakat o gereken adres web adresi degil, o web sayfasindan sonra arka planda baglanilan baska bir adres. Bu adresi bulmak icin kendi network iletisiminizi "takibe" alabilirsiniz, su komutu isletin,

sudo iptables -t nat -A OUTPUT -p tcp --dport 1935 -j REDIRECT && rtmpsrv

Bu bir servis baslatacak ve bekleyecek. Simdi web sayfasina girin, mesela

http://videolectures.net/cikm08_elkan_llmacrf

Sayfaya girilip video baslayinca arkada isleyen servisin ciktisina bakin. Buradaki cikti video indirmek icin gerekli rtmpdump komutunu listelemis olacaktir.

Servisi Ctrl-C ile durdurun ve rtmpdump isleminizi baslatin.

Eger indirme sirasinda baglanti koparsa, tekrar kalinan yerden baslatmak icin komuta -e secenegi eklenebilir.

Not: Eger rtmpdump, hemen iptables ardindan baslamiyorsa, o zaman makinanizi reboot edip tekrar deneyebilirsiniz.

Not: videolectures.net gibi siteler mesela bir dersi parca parca verebiliyor, bu durumda ana adrese, mesela ikinci parca icin /video/2 ekini yapmak gerekiyor. Mesela

http://videolectures.net/cikm08_elkan_llmacrf/video/2

adresi icin su rtmpdump cikti

rtmpdump \
-r "rtmp://hydro2.videolectures.net:1935/vod" \
-a "vod" \
-f "LNX 11,2,202,327" \
-W "http://media.videolectures.net/rel.1383672220/common/swf/PlayerViidea.swf" \
-p "http://videolectures.net" \
-y "mp4:v00e/a3/unhk5n6cclzlkipr25rxyh5i2manetf7.mp4" \
-o bir_dosya_ismi.flv


Not: rtmpdump bazen bazi bolumleri tekrar tekrar kayit edebiliyor. Mesela 1:00 ve 1:05 arasi, 1:05 ve 1:10 arasinda tekrarlanabiliyor. Cozum: video'yu goruntulemek icin VLC kullanirsaniz bu program otomatik olarak tekrarlanan bolumleri atlamayi biliyor.

Kaynak

Tuesday, November 19, 2013

Veri Bilimi, Ceviklik, Anlik Veri Ambari

Suradaki yazidan devam edelim:

Yeni yaklasima gore veri ambari semasinin onceden yaratilmadigini, Hadoop merkezli teknolojiler ile sonradan, ihtiyaca gore ortaya cikarildigini soyledik. Bunu yapiyoruz cunku yapabiliyoruz, elimizde devasa bir analiz kapasitesi var, ayrica yapisiz, daginik, bol miktarda ve (basta) kirli veri setleri var.

Bu baglamda bazi ticari teknolojilerden bahsettik. Fakat bahsedilen teknolojilerin onemli bir problemi, ticari olmalaridir. Altyapi dunyasinda acikca gorduk ki acik yazilim daha tercih edilen bir yaklasim - programcilar bir projeden digerine, bir isten digerine yanlarinda rahatca tasiyabilecekleri teknolojileri tercih ediyorlar, ayrica acik urunlerin etrafinda daha rahat bir kullanici agi olusabiliyor, bu sorularin daha cabuk cevaplanmasi demek olabilir, daha iyi kullanici belgelendirmesi, hatalarin daha hizli tamiri demek olabilir.. "Satis temsilcisi", "deneme amacli yazilim indirme" gibi islerle ugrasmaya gerek kalmaz (Platfora sirketi mesela bize bu sekilde bir yazilim saglayamadi).

Peki eger acik yazilim urunlerini merkeze koyarsak, yeni veri bilim isi neye benzer? Bir soru daha: Bir veri bilimci (data scientist) gunluk baglamda nasil calisir? Nelere odaklidir? Her gun ustune biraz daha ekledigi is birimi, obegi hangi tur cabanin etrafinda doner?

Bu sorulari cevaplamaya calisan bir kitap: Cevik Veri Bilimi (Agile Data Science). 

 
Kitabin yaklasimina gore kullanilan araclar Hadoop etrafinda doner.

Tum veri HDFS (ya da Amazon S3'e) gonderilir [1]. Oradan Pig ile transform edilip, temizlenip, MongoDB'ye "yayinlama" amacli koyulur [2]. Ayni anda bir "veri Web arayuzu" yazilir, ve arayuz veriyi, gosterebildigi sekilde, yavas yavas sunmaya baslar. Ilk basta bu tek, atomik kayit bazli olabilir (kullanici verisi mesela), daha sonra toparlanarak ozetleme amacli ciktilar sunulur, bol bol, akla gelen her turlu grafik eklenir. Bu gelistirme eforu bir surec haline gelir, veri gonder /  geri cek / temizle / yayinla. Bu sirada sirkette herkes bu arayuzu kullanmaktadir, sirket lideri, programcilar, digerleri, o arayuz etrafinda / sayesinde bir veri anlayisi, veri bakisi olusur, ve yavas yavas kesifler ortaya cikmaya baslar.

Yapay ogrenim (machine learning) firsatlari bu noktada ortaya cikmaya baslayabilir, bunlar kodlaninca onlarin ciktisi da MongoDB'ye koyulur, yani "yayinlanir". MongoDB'de olan rahat bir sekilde hem veri arayuzune, hem de ana programa alinabilir (kullanicilarini analiz ettigimiz program yani), boylece cember tamamlanmis olur. Bu surec devam ettirilir.

Platfora, Datameer, Hunk (Splunk) gibi urunler genel anlayis olarak dogru yoldalar, yani veri ambarini dinamik olarak yaratmak, "siz bize Hadoop kumenizi gosterin, biz ona baglanip size guzel raporlar sunariz" bakisinda bir avantaj var. Sadece bunu bahsedilen urunler uzerinden yapmak, onlari her sirketin kendi amaclari icin kullanabilmek kulfetli hatta yetersiz kalabilir. Bu acidan Cevik Veri Bilimi veri bilimciye kendi araclarini kullanmasini ogutler, ve surekli bir GUI gelistirerek rutin bir sekilde veride gorulen, kesfedilen sonuclari arka arkaya yayinlanmasini tavsiye eder. Kitabin arac demeti Hadoop, Pig, Flask, MongoDB, Amazon Elastic Map/Reduce, dotCloud urunleri / servisleridir.

Rutin bir sekilde veri yayinlamak, elde avucta ne varsa onu hemen gostermek surekli buyuyen, gun gectikce daha cok islev edinen bir uygulamanin insasi, veri bilimci baglaminda "bu adam ne uzerinde calisiyor?" sorusunu da rahatca cevaplar. Ne bulunmussa, uzerinde ne calisilmissa, gittigi yer bellidir. Yapay ogrenim ile bulunanlarin yayini da ayni sekilde tek bir yere gitmesi faydalidir. Alternatif olarak mesela veri bilimci bir odaya kapanip lojistik regresyon, kmeans, vs gibi algoritmalari ardi ardina veri uzerinde kullanarak iki ay sonra bir sey "bulacaktir", fakat bu bulunan sonuc ile ne yapilacaktir? Koridorda yuruyen CEO'ya kenara cekilip "bakin vs vs buldum, simdi bunu kullanalim" mi denilecektir? Pek cok acidan Cevik Veri Bilimi yaklasiminin veri analiz surecine faydalari var.

--

[1] Niye Hadoop? Cunku tiklama verisi tanim itibariyle "buyuktur", bu veri bir kere bir yere gidince, tum diger alakali verinin de onunla beraber ayni yere gitmesi gerekir.

[2] Ham veri "buyuk" ise o veriden analiz sonrasi cikan veriyi tutacak yapi da "buyuk" olmalidir, yani anahtar / deger temelli NoSQL tarzinda bir yapi olmalidir, Hadoop ve NoSQL tabanlarin atbasi seklinde surekli yanyana bahsedilmesinin bir sebebi de bu.

Wednesday, November 13, 2013

Anlik Veri Ambari

Suradaki prezentasyondan notlar:

Eski veri ambari teknolojileri / firmalariyla 1 terabayt depolamak, islemek $10,000'a varabilecek bir masraftir. Ucuz makinalari birlestirerek ortaya cikartilan Hadoop kumeleri ile ayni veriyi birkac yuz dolarlik masrafla isleyebilirsiniz. Bu buyuk bir degisim.

Bunun sonucu olarak yaklasimda bazi degisiklikler oldu: Hadoop durumunda ambar "semasi" onceden tanimlanmaz, bu sebeple veri transferi (ETL) ile ugrasmak gerekmez. Bu kararin onceden verilmesine gerek yoktur. Elde ne veri varsa, duz dosya, zip formatinda dosya, vs. olarak Hadoop'a tikilir.

Daha sonra, gereken analize gore esle / indirge kodlari ile veriler istenildigi sekilde birlestirilir. Bu yapilabilir cunku 300, 400, 1000 makinayi yanyana getirmek kolaydir (bulut servisinde mesela), ve performans artik ucuz satin alinabilen bir seydir. Hadoop durumunda her sorgu aslinda bir "anlik ambar" yaratabilir.

Hatta Platfora, Zoomdata gibi teknolojiler, urunler bu sorgularin gorsel araclar uzerinden yapilmasina izin veriyor. Tiklama, secme gibi aksiyonlar, arka planda esle / indirge uretiyorlar ve gelen cevap gorsel sekilde onunuzdeki raporda gosteriliyor.

Tuesday, November 12, 2013

SASHA: Esle/Indirge Altyapisi

Github'da yeni projemiz:

https://github.com/burakbayramli/sasha

Bu altyapi ile mrjob usulu tanimlanan class job dosyalari ile esle/indirge hesaplamalari yapilabilir. Arka planda mesajlarin iletimi icin zeromq kullaniliyor. Esle/indirge mimarileri (mesela Hadoop) bilindigi gibi indirgeme islemi sirasinda ayni anahtarlari ayni makinaya, kod parcasina gonderir, biz bu dagitim icin mod(hash(anahtar), kume_buyuklugu) gibi bir mantik kullaniyoruz. Matematiksel mod bolum sonrasi kalan. artik degeri verir, hash ise bir string icin sayisal deger cikarir. Ikisini biraraya koyarsak, sayisal degeri kume buyuklugune bolunce artik deger hicbir zaman bolenden (kumedeki servis sayisi) buyuk olamaz, o zaman bu deger yuk dagitimi icin hizli bir sekilde kullanilabilir.

Thursday, October 31, 2013

Meteor


Ustte Meteor adi verilen yeni bir UI altyapisi anlatiliyor, pur Javascript temelli (Ruby, vs gibi ek diller yok), kullanilan yaklasim hakikaten temiz duruyor. Suradaki bir yazi Meteor'un niye Ruby on Rails gibi bir yaklasimdan daha iyi olabilecegini anlatmis.

Friday, October 25, 2013

LAN Icindeki Diger Makinalari Bulmak

Diyelim ki monitoru olmayan (ya da islemeyen) bir makinayi bir cafe'ye getirdiniz, Wifi baglantisini yapti (hatirladi cunku), simdi ikinci bir makinadan bu alete baglanmak lazim (ssh ile). Ama ilk makina hangi IP adresinde acaba?

Cafe gibi yerlerde Wifi hizmeti var ise, Wifi dagitim noktasi arka planda DHCP kullanir, ve 192.168.2.x gibi adresler her yeni kullaniciya dagilitir, bir kisiye 192.168.2.100 verilebilir, digerine 192.168.2.5 vs. Diger makinalari (kendi makinamizi en azindan) "bulmak" icin teker teker ping ile bakabilirdik, ama uzun surer. Script edelim,

import os
for i in range(255):
    cmd = "ping -c 1 192.168.2.%d > /tmp/out" % i   
    os.system(cmd)
    if " 0% packet loss" in open("/tmp/out").read():
        print i, "Found"


Secenek -c 1 kullanildi, sadece bir kere ping edilmesi icin (yoksa 3 kere denenir). Sonucta tek ilgilendigimiz "0% packet loss" gormek, o adreste bir makina varsa bu sonucu verir cunku, diger durumlarda "100% packet loss" ibaresi cevapta oluyor.

ØMQ

Makinalar, sureclerarasi mesaj gonderimi icin ØMQ (ya da ZeroMQ) programi tavsiye edilir. Kullanimi soket kullanimina benzeyecek sekilde yapilmis fakat arka planda mesajlarin hizli gonderilebilmesi ve iletilmesinden emin olunmasi, tampon bellekte mesajlari biriktirmek (gerekiyorsa) gibi bir suru ek kodlama yapilmis. Noktadan noktaya TCP protokolu ile, ayrica UDP ya da multicast ile yayin bazli da calisabiliyor.

Kurmak icin

sudo apt-get install libzmq-dev uuid-dev python-zmq

Not: Eger ustteki yeterli olmazsa (mesela bir assertion error gelirse), kaynaklardan derlemek gerekebilir, libzmq Github'dan kaynak indirilir, ./autogen.sh, ./configure, make ve sudo make install gerekebilir. 

TCP kullanan noktadan-noktaya transfer ornegi

# alici
import sys, time, zmq

context = zmq.Context()
receiver = context.socket(zmq.PULL)
receiver.bind("tcp://*:10000")

arr = []
while True:
    data = receiver.recv()
    if data == "start":
        print time.time()
        continue
    arr.append(data)
    if data == "end":
        print time.time()
        print len(arr)
        continue


# gonderen
import zmq, time

context = zmq.Context()
sender = context.socket(zmq.PUSH)
sender.connect("tcp://localhost:10000")
sender.send("start")
for i in range(100000):
    sender.send("01234567890123456789")
sender.send("end")


Eger gonderici baska bir makinada ise localhost yerine o makina ismi (ya da IP adresi) kullanilir.

Uyelik / gonderim (publish, subscribe) kullanimi ve protokol bazinda yayin kulllanan ornek (ki yayin bazli protokol kullaninca uyelik kullanmak mecburi)

# alici
import zmq

context = zmq.Context()
socket = context.socket(zmq.SUB)

socket.connect('epgm://wlan0;239.192.1.1:5000')
socket.setsockopt(zmq.SUBSCRIBE, "10001")

while True:
    data = socket.recv()
    print data


# gonderici
import zmq, time

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect('epgm://wlan0;239.192.1.1:5000')
while True:
    socket.send("10001 kjashfkjasdf")
    time.sleep(1)


Ornek pgm icin ayni, egpm yerine gpm kullanilir. Yanliz o pgm icin her iki tarafta da sudo kullanmak gerekti. Bu biraz garip bir durum.

Ayrica egpm (ve pgm) nedir? Bunlar ek protokoller, pgm UDP'nin guvenilirligini arttirmak icin yazildi. ZeroMQ openpgm uzerinden bunlari kullanabiliyor. ZeroMQ sayfalarina gore pgm direk multicast, egpm arka planda UDP kullanir.

UDP yayin bazli bir protokoldur, network'un tek bir adresine (mesela 0.0.0.0) mesajlari basarsiniz, bu mesajlari herkes gorur. Bunun fi tarihinde bazi faydalari vardi, cunku 'zaten Ethernet (bir alttaki protokol olmasi baglaminda) zaten mesajlari donanim olarak herkese goturuyor, bunun ustune yayin bazli kullanim niye daha uygun olmasin". Irdeleme boyleydi. Bunu yeni network donanimlarinda test etmek gerekir, zaten pur UDP guvenilir bir protokol degildir (oldugu gibi kullanilmasini tavsiye etmiyoruz). ZeroMQ her iki protokolu de pgm uzerinden disari servis ediyor.

Ornekte ilginc bir kullanim goruyoruz, 239.192.1.1 adresi var mesela. Internet adresleme kurallarina gore 224.0.0.0 ve 239.255.255.255 arasi multicast icin ayrilmistir, bu araliga baglananlar disari, yani daha genis baglamda Internet'e aktarilmazlar (routing). Multicast UDP'den daha populer bugunlerde, UDP'nin pabucu dama atildi bir baglamda. Multicast'te "yayin gruplari" yaratiliyor (ustteki aralikta bir adres) ve o adrese yazilan her mesaj, o adresi okuyan herkes tarafindan alinabiliyor. Sistem bakimi (maintenance) acisindan iyi bir sey, network'e istediginiz kadar makina ekleyin, bu makinalarin sadece tek bir adresi bilmeleri yeterli.

Isleri biraz daha karistiralim, multicast mesaj gonderimi icin UDP perde arkasinda UDP kullanabiliyor (fakat bu illa sart degil). Ayrica bazi pur UDP orneklerinde yayin grubu kullanildigini gorduk.

Ustteki ornekte ayrica filtreleme kullanimi var, sadece 10001 ile baslayan mesajlari almak istedigimizi belirtmisiz.

wlan0 nedir? Network donaniminin ismidir. Bu ismi ifconfig -a ile bulmak mumkun.

Test ederken netstat -g ile o anda network'unuzdeki tum yayin gruplarini gorebilirsiniz.

Not: bazi durumlarda ./configure cagrisini --with-pgm ile yapmak gerekebilir.

Tuesday, October 22, 2013

Buyuk Veri, Akim Analizi

Buyuk Veri dunyasinda durum nedir? Tabii buyuk veri deyince Hadoop'tan bahsetmemek olmaz, once buraya nasil geldigimize bakalim.

Hadoop'un en onde gelen kullanim alanlarindan biri log dosyasi islemek[ti]. Ozellikle populer olan Web siteleri asiri seviyelerde log dosyasi uretiyordu (her kullanici tiklamasi), ama Hadoop oncesinde bu veriyi basit / olcekli  bir sekilde isleyebilecek bir ortam yoktu. Log analizi yapmak isteyenler koca koca Sun, Oracle makinalari alip bunlara veri yuklemeye ugrasiyorlardi, ozel kodlar, ozel paketlerle bu veriler incelenmeye ugrasiliyordu. 2002'de boyle bir projede bizzat calistik, SQL ile "buyuk veri" analizi yapmak hakikaten zor bir isti, bu tur veri ambari raporlamasinda uzman olan bir danismana saatte yuzlerce dolarlar verildigini hatirliyorum.

Google'in Hadoop'un temelini olusturan esle/indirge (map/reduce) mimarisini aciklamasindan, ve Hadoop'un ortaya cikmasindan sonra isler degisti. Insanlar log dosyalarini direk, oldugu gibi dosya halinde alip Hadoop kumesine atabilmeye basladilar (HDFS buyuk dosyalari parca parca makinalara boler, ama disari tek bir dosyaymis gibi gosterir). Analiz gerektiginde paralel sekilde isleyecek esle / indirge sureclerini kodladilar, her yerde bulanabilecek PC makinalarini birlestirip 100, 200 hatta 700 makinalik kumelerde devasa verilerini nisbeten ucuz sekilde islemeye basladilar. Sirketler cogunlukla kendi Hadoop kumelerini de kendileri kurdular.

Bugun Hadoop servisini bulut servisi (cloud service) olarak sunmaya ugrasan pek cok sirket var tabii, ama halen sirketler kendi kumelerini kuruyorlar.

Mimariye gelelim: Esle/indirge mimarisi veri satirlarina teker teker bakan / isleyen, ve veriyi bir akim (stream) gibi goren mimaridir. Bugunlerde veri akimi islemi (stream processing) surekli anlik (realtime) baglamda telafuz ediliyor, fakat aslinda Hadoop ta akim analizi yapiyor, sadece bunu cevrimdisi (offline) olarak yapiyor. Yani onlarca, binlerce veri satirinin hafizada olacagi farzedilmiyor, one gelen o tek satir, o tek veri noktasi uzerinde islem yapiliyor (ve ona tekabul eden, bir veya daha fazla "sonuc satiri" uretiliyor, bu da bir cikis akimi olusturur, baska bir islemciye gonderilebilir, vs). Dolayli olarak bu kulturde hafizada az konum verisi tutmak ana amactir, ya da ne kadar az konum verisi olursa o kadar iyi olacagi dusunulmektedir [1]. Fena bir yaklasim degildir.

Simdi pek cok veri analizinin, hatta yapay ogrenim (machine learning) algoritmasinin bu sekilde kodlanabilecegi birdenbire "kesfedilmistir". Hatta bu tur algoritmalara bugunlerde "utandiracak boyutlarda paralelize edilebilen" adi veriliyor, mesela KMeans kumeleme metotu bunlardan biri. Yani paralelize edilmesi o kadar, o kadar kolay ki, simdiye kadar niye yapmadik turunden bir serzeniste var bu soylemin icinde. Tabii altyapi (framework) mevcudiyeti cok onemliydi.. Hadoop'un bazi isleri kolaylastirmasi, bir suru algoritmanin bu altyapiya gecirilebilecegini farketmesi yonunde insanlari tesvik etti. 

Ve bugune geliyoruz: veri analizini akim islemesi (stream processing) olarak gormeye alisilinca, "niye bu isi habire diske yazipi diskten okuyan sekilde yapalim ki?" dusuncesi basladi, cunku Hadoop isini gormek icin cok fazla gecici dosya uretiyor, bu da performansi dusuruyordu... Iste son zamanlarda etrafa sacilan anlik akim veri analizi (realtime stream processing) urunleri, paketleri bu ihtiyaci tatmin etmeye ugrasiyor. Storm, S4, Samza bu tur urunler.

---

[1] Zaten devasa boyutlarda veriyi baska sekilde (ucuz olarak) islemek mumkun degildir. Terabayt olceginde bir verinin tamamini hafizaya alip, direk veri erisimi yapabilecegimizi farzedemeyiz. Bu tur makinalar insa edilebilir muhakkak, fakat sabit disk RAM'den ucuz oldugu icin buyuk diskli az hafizali makinalar daha ekonomik.

Buyuk Matrisler Uzerinde SVD Ayristirmasi (SVD Factorization for Tall-and-Fat Matrices on Map/Reduce Architectures)

Monday, September 30, 2013

Bir Veri Akış Dili: Pig

Hadoop icin yazilan bazi veri analizleri oldukca cetrefil hale gelebilir. Ilginctir ki SQL bazli veri tabanlari ortaminda tablolar, dosyalar ile ugrasirken, Buyuk Veri / Hadoop devreye girince duz dosyalar (flat file) ortamina geri donduk. Aslinda bu bir bakima iyi oldu, daha daginik, yapisiz (unstructured) veriler ile ugrasiyoruz, ve onlari sonradan analiz etmek icin daha yaratici cozumler bulmamiz gerekiyor. Verinin uzerinde onceden bir sablon koymuyoruz, analiz gerektiginde veriyi o ihtiyaca yonelik olarak okuyoruz. Veri parcali parcali, bir takim duz dosyalar, bir tar.gz dosyasi icindeki birkac, yuzlerce, binlerce bir halde karsimiza cikabiliyor.

Daha once MRJob'tan bahsettik. Bu ortamda bir islemden (job) digerine veri aktarimi kolaydir, her basamakta direk Python icinde kalarak kod yazabilirsiniz, map() icinden yayinladiginiz anahtar degerler mesela, sonraki reduce() basamagina direk Python tipleri olarak aktarilir.

Fakat MRJob'in hala bazi eksikleri var, tum veri akisinizi ayarlamak icin bir arac degil. Diyelim ki elinizde girdi olarak iki dosya var, bu dosyalari birlestireceksiniz (join) sonra sonuc olarak iki dosya ureteceksiniz, bunlarin biri, bir sonraki basamak icin referans olacak, vs. Bu tur isleri idare etmek icin bir veri analiz diline ihtiyac var.

En son surumu Pig 0.12 bu ihtiyaclara cevap veriyor, ayrica, bizim icin en onemli ozelligi Python icin Jython uzerinden degil, artik direk baglanti kurabiliyor olmasi, yani numpy, scipy gibi kutuphaneleri Pig uzerinden kullanmak mumkun olacak. Bu surum hakikaten yeni, duyurusu surada.

Konusma

Apache Pig

Pig musteri tarafinda (client side) isleyen bir programdir. Yani bir Pig script yazdigimizda bu script'i tum Hadoop makinalarina ayri ayri gondermeye gerek yoktur mesela. Pig script'iniz Hadoop kumenize baglanir, ve o kumeye, veri akis kodunuza gore arka planda bazi esle/indirge islemleri islettirir. Pig'i bir nevi derleyici gibi gorebiliriz, Pig kodu yazariz, "derleyince" arka planda EI islemleri uretilir (ve kumeye gonderilir). Demek ki tek bir makinada Pig kurulmus olmasi yeterlidir.

Once baglantidan Pig 0.12 indirin, unzip yapin. Kurulusu hduser altina yapsaniz iyi olur. Sonra su - hduser ile hduser olun ve .bashrc icine PATH sonuna [PIG DIZINI]/bin ekleyin

Kullanmak icin soyle bir veriyi

1950    0    1
1950    22    1
1950    -11    1
1949    111    1
1949    78    1


/tmp/sample.txt icine yazin. Su kodu /tmp/sample.pig icine yazin

records = LOAD '/tmp/sample.txt' AS (year:chararray, temperature:int, quality:int);

filtered_records = FILTER records BY temperature != 9999 AND (quality == 0 OR quality == 1 OR quality == 4 OR quality == 5 OR quality == 9);

grouped_records = GROUP filtered_records BY year;

max_temp = FOREACH grouped_records GENERATE group, MAX(filtered_records.temperature);

DUMP max_temp;


Simdi hduser olun, ve komut satirindan pig -x local /tmp/sample.pig isletin.

(1949,111)
(1950,22)

gibi bir sonuc ekrana basilmali. Ilk Pig script'imiz boyle.

Bir birlestirme yapalim, /tmp/A icine

Joe    2
Hank    4
Ali    0
Eve    3
Hank    2


/tmp/B icine

2    Tie
4    Coat
3    Hat
1    Scarf


Simdi /tmp/join.pig icine

A = LOAD '/tmp/A';
B = LOAD '/tmp/B';

C = JOIN A BY $0, B BY $1;
DUMP C;


Isletelim

pig -x local /tmp/join.pig

Sonuc

(2,Tie,Joe,2)
(2,Tie,Hank,2)
(3,Hat,Eve,3)
(4,Coat,Hank,4)


Kurulus Notlari

Kurulus acisindan en rahati Pig'i hduser altinda kurmak, sonra diger gunluk kullanilan kullanici icindeyken ssh hduser@localhost araciligi ile pig cagrisini hduser'a yaptirmak. Bu sekilde local durumunda ciktilar /home/hduser altina gidecektir. Bu ssh kullanimina bir ornek soyle

$ ssh hduser@localhost "\
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64; \
/home/hduser/pig-0.12.0/bin/pig -x local \
/home/burak/dizin/filanca.pig \


Tabii ustte pig script'in oldugu dizinin hduser tarafindan erisilebiliyor olmasi lazim, bunu chmod +x ile script'in icinde oldugu dizinleri disariya acarak basarabilirsiniz.

Dizinler

Pig ile store ... into 'filanca' komutlari into'dan sonra gelen isim altinda bir dizin yaratir, ve sonuclar tanidik Hadoop formatinda part-r-.. gibi dosyalardir. Fakat ayni script tekrar isletilirse bu dizinin ustune yazilmaya ugrasilir ve Pig hata verir. Dizinin uzerine yazmak problem degilse, script basinda

fs -rmr filanca

ile bu dizin silinebilir, sonra script'in geri kalani o dizini yeniden yaratacaktir.

Bu yaziya ekler olacak.

Sunday, September 29, 2013

Tuesday, September 24, 2013

Yerel Ag Kurmak - Ubuntu

Ubuntu temelli bir yerel ag (network) nasil kurulur? Ubuntu uzerinden bunu yapmak aslinda cok basit (dis Internet baglantisinin paylastirma konularina daha girmiyoruz), dinamik IP adres kullanmadan, tum makinalara bir statik (ve yerel) IP adresi atayarak bu ag kurulabilir. Belki evde bir Hadoop kumesi kurmak istiyorsunuz, vs.

Once tum makinalarda sshd kurulursa iyi olur:

apt-get install openssh-server

Ag kurmak icin su resimdeki hareketler




Adres olarak 192.168.0.1 sayisi kullanildi, bu adres dis baglantilar icin anlamsiz bir sayidir, sadece yerel ic ag icinde gecerlidir. Bu tur disaridan bagimsiz IP adresleri vardir. Eger ikinci, ucuncu makinayi eklerseniz, 0.2, 0.3, vs. gibi bu makinalar adreslenebilir.

Fiziki baglanti icin en azindan switch denen bir donanim gerekli. Bu donanim uzerinde Ethernet kablo baglantilari olur, eger laptop baglanacaksa, ve son zamanlarda artik laptop'lar uzerinde Ethernet girisi olmadigi icin, bir USB / Ethernet donusturucusu lazim.

Neyse, switch baglantisi ve IP atamasi yapildigi anda o bilgisayarin komut satirindan

sudo ifconfig

isletince yeni IP'nin gorulmesi lazim. Diger makinalar baglaninca, onlardan bu makinaya

ssh 192.168.0.1 -l [kullanici]

diye erisebilirsiniz. Eger tum makinalara sifresiz (ama guvenli) baglanmak icin daha once pek cok kez bahsettigimiz ssh-keygen -t rsa, ile anahtar uretmek, sonra id_rsa.pub'in alinip oteki makinaya kopyalanip .ssh/authorized_keys'e eklenmesi, ardindan ustteki ssh (ve scp) komutu sifresiz olarak giris yapma numarasi kullanilabilir.

Kaynak

Tuesday, September 17, 2013

Storm, Python, Gercek Zamanda Veri Islemek



Storm, Hadoop'un toptan (batch) dunyada yaptigini gercek zamanli (real-time) veri akislarinda, hesaplarinda yapmaya ugrasiyor. Yatay olarak olcekleme (scaling) destekleniyor, veri akisinin muhakkak / en az bir kere islenme garantileri var. Islem noktalarinda emit() cagrisi gorulebilir, veri akisi alip veri akisi yaratmak mumkun yani. FieldsGrouping kavrami ile Hadoop'un esle/indirge basamagindaki indirge basamagi benzer kavramlar. Ustteki prezentasyon ilginc, cunku JVM / Java bazli Storm icin arkadas bir Python arayuzu yaratmis. Kod suna benziyor:


MariaDB

Link

En populer veri tabani sistemi olmasina ragmen, Oracle'in MySQL'nin basi dertte. Red Hat ve SuSE gibi en unlu Linux dagitimlari paketlerinden MySQL'i cikartip yerine onun kodundan gelistirilmeye baslanmis (fork) MariaDB'ye geciyor. Wikipedia gibi buyuk Web siteleri de arka plan kodlarini MySQL'den MariaDB'ye geciriyorlar. En son da Google'in MySQL'i atip yerine MariaDB'ye gecmesi yaraya tuz surmek gibi oldu.

---

Bu konu hakkinda daha once yazmistik. Acik kaynak dunyasinda care tukenmez. Fakat problem cikmadan once insanlarin gecis yapmaya baslamalari ilginc. Burada ticari bir sirketin acik kaynak bir yazilima sahip olmasinin diger ticari sirketler icin potansiyel problemi olabilme durumu var. Oracle ileride MySQL'i bir silah gibi kullanabilir; kimse Oracle'a guvenmiyor. O yuzden problem cikmadan once MySQL'i kenara atmak, ozellikle Google gibi bir sirketin isine gelir.

Thursday, September 12, 2013

Python ile SQL Tabandan CSV Uretmek

Alttaki kod SQL ile kursor (cursor) acarak veriyi satir satir alir ve CSV dosyasina yazar. Oracle icin

import csv
import cx_Oracle as odb


oraclepass = [SIFRE]
user = [KULLANICI]
conn = odb.connect("%s/%s@TABAN" % (user,oraclepass) )

cursor = conn.cursor()
query = """
select vs,vs from vs
"""

cursor.execute(query)

csv_writer = csv.writer(open("/tmp/out.csv", "wt"),delimiter=';')
csv_writer.writerow([i[0] for i in cursor.description])
csv_writer.writerows(cursor)
del csv_writer



Tuesday, September 3, 2013

MySQL Kurulus

MySQL Ubuntu kurulusu

sudo apt-get install mysql-server

Baglanmak (kendi makinanizdan)

mysql --host=localhost --user=root --password=[sifre]

Kurulurken root icin sifre vs istenir, fakat bu kullanici disaridan kullanis sirasinda problem cikartir. Makina ici ve disindan kullanilacak bir kullanici yaratmak icin (suradan)

CREATE USER 'monty'@'localhost' IDENTIFIED BY 'some_pass';
GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
    WITH GRANT OPTION;
CREATE USER 'monty'@'%' IDENTIFIED BY 'some_pass';
GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
    WITH GRANT OPTION;


Taban Dizini

Eger veri tabanlarinin tutuldugu dizini degistirmek istiyorsaniz, /etc/mysql/my.cnf ayar dosyasindaki dataDir dizini degismeli. Hatta mevcut tabanlarin verisini kaybetmeden sadece dataDir'deki dizini oldugu gibi yeni yere kopyalayip, yeni dizinden ise devam etmek mumkun. Dikkat, kopyalanan yeni yerdeki erisim haklari mysql kullanicisina olmali. Tabii ondan once sudo service mysql stop ile servisi durdurmayi unutmayin.

MySQLdb, Pandas

Ubuntu uzerinde kurmak icin

sudo pip install pip --upgrade

sudo easy_install -U distribute

sudo apt-get build-dep python-mysqldb

sudo pip install MySQL-python


Ornek kod

import MySQLdb, os, sys

conn= MySQLdb.connect(host='makina',
                      port=3306,user='user', passwd='sifre',
                      db='test')


Bir Pandas dataframe'i alarak veri tabanina yazmak muthis kolay:

pd.io.sql.write_frame(df, "tablo1", conn, flavor='mysql')

Ustteki ifade df icindeki dataframe'i alip veri tiplerini ayarlayip Mysql'de tablo yaratacak ve veriyi tabloya ekleyecektir. Eger tablo mevcut ise ikinci isletim hata verebilir, tablo yokedilip tekrar bastan yaratilsin istersek,

pd.io.sql.write_frame(df, "tablo1", conn, flavor='mysql', if_exists='replace')

Eger dataframe verisi mevcut tabloya "eklensin" istiyorsak,

pd.io.sql.write_frame(df, "tablo1", conn, flavor='mysql', if_exists='append')

Basit bir SQL (DDL usulu, mesela bir DELETE komutu)

sql = "delete from tablo where kolon1 = %d and kolon2 = %d" % (arg1,arg2)
conn.cursor().execute(sql)
conn.commit()



Monday, August 26, 2013

Flask

Hafif, basit Web UI ihtiyaclarini karsilamak icin yazilmis bir paket, Flask. Web programlarini Python ile yazmaniza izin veriyor ve isaret (annotation) kullanarak aksiyonlarin hangi metota esleneceginin tanimlanmasini sagliyor. Kurmak icin

sudo pip install Flask

Ilk ornek

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World'

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=10000)


Host icin 0.0.0.0 kullanilmasinin sebebi ufak web sitenizin disaridan cagirilabilmesi icin.

Guzel bir giris dokumani surada.

AJAX ile bilgi gonderip ekrana basmak, giris.

Tuesday, August 20, 2013

MrJob


Python bazli esle/indirge sureclerini hic Hadoop komut satiriyla ve Streaming ile ugrasmadan isletmenin bir diger yolu mrjob (Amerikalilar bunu "mister job" diye okuyor). Kurmak icin

sudo pip install mrjob

/home/hduser altinda .mrjob.conf adinda bir dosya yaratin ve icine sunu yazin

runners:
  hadoop:
    hadoop_home: [HADOOP DIZINI] 


Mrjob ile esleme / indirgeme komutlari ayri script olarak degil, tek bir class'ta ayri metotlar olarak verilir. Mesela kelime sayma

from mrjob.job import MRJob
import re

WORD_RE = re.compile(r"[\w']+")

class MRWordFreqCount(MRJob):

    def mapper(self, _, line):
        for word in WORD_RE.findall(line):
            yield (word.lower(), 1)

    def reducer(self, word, counts):
        yield (word, sum(counts))

if __name__ == '__main__':
    MRWordFreqCount.run()


Test amacli tek basina isletmek icin (Hadoop olmadan)

python words.py words.csv

Hadoop ile (once dosyayi kopyalayalim)

hadoop dfs -copyFromLocal words.csv  /user/

python /home/hduser/words.py hdfs:///user/words.csv -r hadoop --step-num=1

Ustteki komutun islemesi icin hduser olarak login etmeniz gerekir. Eger baska bir kullanicidan isletmek isterseniz,

ssh localhost -l hduser [ustteki ayni komut]

isleyecektir. Kac tane esle / indirge'nin paralel isleyecegini tanimlayabiliriz, bunun icin (mesela 2)

... --jobconf mapred.map.tasks =2 --jobconf mapred.reduce.tasks=2

kullanilir.

Nasil Isliyor?

Peki motor kapaginin altinda neler oluyor? Mrjob, Hadoop Streaming'i sarmalayarak bize daha rahat kullanimi olan bir arayuz sunar. Streaming, bilindigi gibi HDFS'teki bir dosyayi okuyup script'lerimize satir satir gecmekle sorumludur. Mrjob ise bunun uzerine bir katman daha ekler, ve mesela dosyamizda tab, bosluk (space) iyi bilinen ayraclar kullaniliyorsa daha bastan anahtar ve degeri ayirip map cagrisina bunlari tek obje, obje listeleri olarak gecebilir.

Dahasi da var: map icinden uretilen anahtar ve deger ikilileri cetrefil tipler olabilir (vektor, sozluk gibi) ve bu ciktilar Python'un yerli (native) tipleri olarak indirgeyiciye gonderilebilirler. Direk Hadoop'ta bu is oldukca zor olurdu. Bu iletisim icin

from mrjob.protocol import PickleProtocol
..
class BizimMR(MRJob):
    INTERNAL_PROTOCOL = PickleProtocol

secimi yeterli.

Simdi anlamsal (semantic), islem sirasi gibi konulara gelelim. Hem esle hem indirgeme icin tek bir sinif tanimlanmasi bizi aldatmasin, esleyici metot ile indirgeyici metot arasinda aslinda sinif ic degiskenlerini kullanarak iletisim olamiyor. Yani sinifimizdan bir obje yaratilacak, o obje'nin esleme kismi bitince obje atilacak, indirgeme icin baska bir (ayni siniftan) obje yaratilacak. "Peki o zaman niye ayni sinif kullanilmis?" diye bir soru akla gelebilir, yani, kod idaresi acisindan her seyin tek bir yerde olmasi daha temiz tabii.

Ayrica indirgeme evresinde her ayri anahtar icin ayri bir objenin (ve reducer metotunun) kullanildigini / cagrildigini kabul edebilirsiniz. Yani obje eger "aklinda bir sey tutacaksa" bu degerlerin baska anahtarlara ait olmamasi gerekir. Yuk dagitimi baglaminda ayni obje belki birkac kez ayni anahtar icin kullanilir, ama bunun nasil olacaginin garantisi yoktur, o sebeple tek anahtar tek indirgeyici kabul etmek en iyisi. Zaten indirgeyici metotunun parametre listesini dusunursek, def reducer(self, key, tokens) olarak gosterilmis, yani tek bir anahtar gelmis ve onunla alakali degerler listesi gelmis.

Bu arada mapper her satir icin bir kere cagrilir. Her anahtar icin o anahtara ait reducer bir kere cagrilir.

Bu cagrilardaki mesela tokens tipine dikkat, bir iterator bu, Hadoop'un mantigini biliyoruz, satir satir isleme uzerinde ve hafizada cok az sey tutmak uzerine kurulu. Python'un iteratorleri de bu mantiga cuk diye oturuyor, sadece iteratorun bize o anda gosterdigi seyle ilgileniyoruz. Benzer bir sebeple Python icinden yield kullaniyoruz [link], cunku kendimiz de basamagimiz icinde "bir sonraki basamagin okuyabilecegi" bir iterator yaratiyoruz.

Bazi Cengel (hook) Noktalari ve Numaralar:

Bir makina / surecteki esleyicinin isi tamamen bitince, su metotu cagir gibi bir tanim yapilabiliyor. Bunun icin map_final metotu tekrar tanimlanir.

Bir diger numara: Metot steps ile kendi EI isimlerimiz tanimlayabilir, hatta EI basamaklarina ek basamaklar ekleyebiliriz. Isim degisikligi:

def steps(self):
    return [self.mr(mapper=self.xxx, reducer=self.yyy)]


Ek basamaklar

def steps(self):
    return [self.mr(mapper=self.mapper,reducer=self.reducer),
            self.mr(reducer=self.reduce_final)]


Bu durumda reducer'in urettigi anahtarlar bir sonraki reduce_final'a yine anahtar bazinda gidecek. Ayni indirgeyici mantigi, sadece bir tane daha. Biz bu asamayi bir "nihai toparlama" noktasi olarak kullaniyoruz genelde, o yuzden cogunlukla tum reduce metotlarina ayni anahtari urettiriyoruz, ve tum yollar tek bir reduce_final'e cikiyor.

Eger reduce tanimlamazsaniz Hadoop'taki IdentityReducer tanimlamak ile ayni kapiya cikiyor, yani mapper'in ciktisi indirgenmeden direk sonuca gidiyor.

Eger anahtar degeri icermeyen sadece degerleri bir cikti dosyasina yazmak istiyorsak,

OUTPUT_PROTOCOL = RawValueProtocol

tanimlamak yeterli, bu durumda yield(None, my_list) gibi bir cagrinin sadece my_list kismi yazilir (eger o tanimi yapmasaydik, None ibaresini ciktida gorecektiniz). Biraz formatlama yaparsak, mesela virgullerle ayrili bir cikti

yield (None,",".join(map(str,my_list)))

diyebiliriz. Bu durumda mesela tek makina ortaminda python myjob.py girdi.csv > cikti.csv isletikten sonra virgulle ayrilmis anahtarsiz guzel bir cikti buluruz.

Wednesday, July 31, 2013

Pandas ile Kategorik Veriyi Ikisel Hale Getirmek (One-Hot Encoding)

Yapay ogrenim algoritmalarinin cogu zaman hem kategorik hem numerik degerleri ayni anda bulunduran verilerle is yapmasi gerekebiliyor. Ayrica literature bakilinca gorulur ki cogunlukla bir algoritma ya biri, ya digeri ile calisir, ikisi ile ayni anda calismaz (calisanlar var tabii, mesela karar agaclari -decision tree-). Bu gibi durumlarda iki secenek var, ya numerik veri kategorisellestirilir (ayriksallastirilir), ya da kategorik veri numerik hale getirilir.

Mesela su veri seti

   pop   state  year
0  1.5    Ohio  2000
1  1.7    Ohio  2001
2  3.6    Ohio  2002
3  2.4  Nevada  2001
4  2.9  Nevada  2002


su hale getirilir

   pop  year  state=Ohio  state=Nevada
0  1.5  2000           1             0
1  1.7  2001           1             0
2  3.6  2002           1             0
3  2.4  2001           0             1
4  2.9  2002           0             1


Bu durumda, kategorik bir kolon eyalet icin, eyaletin Ohio olup olmamasi basli basina ayri bir kolon olarak gosteriliyor. Ayni sekilde Nevada. Bu kodlamaya literaturde One-Hot Kodlamasi adi veriliyor. KMeans, lojistik regresyon gibi metotlara girdi vermek icin bu transformasyon kullanilabilir.

import numpy as np
import pandas as pd, os
import scipy.sparse as sps
from sklearn.feature_extraction import DictVectorizer

def one_hot_dataframe(data, cols, replace=False):
    vec = DictVectorizer()
    mkdict = lambda row: dict((col, row[col]) for col in cols)
    vecData = pd.DataFrame(vec.fit_transform(data[cols].apply(mkdict, axis=1)).toarray())
    vecData.columns = vec.get_feature_names()
    vecData.index = data.index
    if replace is True:
        data = data.drop(cols, axis=1)
        data = data.join(vecData)
    return (data, vecData, vec)

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}

df = pd.DataFrame(data)

df2, _, _ = one_hot_dataframe(df, ['state'], replace=True)
print df2


Unutmayalim, kategorik degerler bazen binleri bulabilir (hatta sayfa tiklama tahmini durumunda mesela milyonlar, hatta milyarlar), bu da binlerce yeni kolon demektir.

Fakat 1/0 kodlamasi, yani one-hot isleminden ele gecen yeni blok icinde aslinda oldukca cok sayida sifir degeri vardir (sonucta her satirda binlerce 'sey' icinde sadece bir tanesi 1 oluyor), yani bu blok bir seyrek matris olacaktir. O zaman matrisin tamamini sps.csr_matrix ya da sps.lil_matrix ile gercekten seyrek formata cevirebiliriz, ve mesela Scikit Learn adli yapay ogrenim paketi, sifirdan YO kodlamak istersek Numpy, Scipy islemleri seyrek matrisler ile hesap yapabilme yetenegine sahip. Seyreksellestirince ne elde ediyoruz? Sifirlari depolamadigimiz icin sadece sifir olmayan degerler ile islem yapiyoruz, o olcude kod hizlaniyor, daha az yer tutuyor.

Dikkat etmek gerekir ki yeni kolonlari uretince degerlerin yerleri sabitlenmis olur. Her satir bazinda bazen state=Ohio, state=Nevada, bazen sadece state=Ohio uretiyor olamayiz. Ustteki ornekte her zaman 4 tane kolon elde edilmelidir.

Bastan Seyrek Matris ile Calismak

Buyuk Veri ortaminda, eger kategorik degerler milyonlari buluyorsa, o zaman ustteki gibi normal Numpy matrisinden seyrege gecis yapmak bile kulfetli olabilir. Bu durumlarda daha en bastan seyrek matris uretiyor olmaliyiz. Mevcut tum degerleri onceden bildigimizi farz edersek,

import numpy as np
import pandas as pd, os
import scipy.sparse as sps
import itertools

def one_hot_column(df, cols, vocabs):
    mats = []; df2 = df.drop(cols,axis=1)
    mats.append(sps.lil_matrix(np.array(df2)))
    for i,col in enumerate(cols):
        mat = sps.lil_matrix((len(df), len(vocabs[i])))
        for j,val in enumerate(np.array(df[col])):
            mat[j,vocabs[i][val]] = 1.
        mats.append(mat)

    res = sps.hstack(mats)   
    return res
           
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year': ['2000', '2001', '2002', '2001', '2002'],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}

df = pd.DataFrame(data)
print df

vocabs = []
vals = ['Ohio','Nevada']
vocabs.append(dict(itertools.izip(vals,range(len(vals)))))
vals = ['2000','2001','2002']
vocabs.append(dict(itertools.izip(vals,range(len(vals)))))

print vocabs

print one_hot_column(df, ['state','year'], vocabs).todense()


Sonuc olarak

   pop   state  year
0  1.5    Ohio  2000
1  1.7    Ohio  2001
2  3.6    Ohio  2002
3  2.4  Nevada  2001
4  2.9  Nevada  2002


[{'Ohio': 0, 'Nevada': 1}, {'2002': 2, '2000': 0, '2001': 1}]


[[ 1.5  1.   0.   1.   0.   0. ]
 [ 1.7  1.   0.   0.   1.   0. ]
 [ 3.6  1.   0.   0.   0.   1. ]
 [ 2.4  0.   1.   0.   1.   0. ]
 [ 2.9  0.   1.   0.   0.   1. ]]


one_hot_column cagrisina bir "sozlukler listesi" verdik, sozluk her kolon icin o kolonlardaki mumkun tum degerleri bir sira sayisi ile esliyor. Sozluk listesinin sirasi kolon sirasina uyuyor olmali.

Niye sozluk verdik? Bunun sebebi eger azar azar (incremental) ortamda is yapiyorsak, ki Buyuk Veri (Big Data) ortaminda her zaman azar azar yapay ogrenim yapmaya mecburuz, o zaman bir kategorik kolonun mevcut tum degerlerine azar azar ulasamazdik (verinin basinda isek, en sonundaki bir kategorik degeri nasil gorelim ki?). Fakat onceden bu listeyi baska yollarla elde etmissek, o zaman her one-hot islemine onu parametre olarak geciyoruz.

Sozluk niye one_hot_dataframe cagrisi disinda yaratildi? Bu cagri duz bir liste alip oradaki degerleri sirayla bir sayiyla esleyerek her seferinde bir sozluk yaratabilirdi. Bunu yapmadik, cunku sozluk yaratiminin sadece bir kere, one_hot_dataframe disinda olmasini istiyoruz. Yine Buyuk Veri ortamini dusunenelim, esleme (map) icin mesela bir script yazdik, bu script icinde (basinda) hemen sozlukler yaratilirdi. Daha sonra verinin tamami icin, azar azar surekli one_hot_dataframe cagrisi yapilacaktir. O zaman arka arkaya surekli ayni veriyi (sozlukleri) sifirdan tekrar yaratmamiz gerekirdi. Bu gereksiz performans kaybi demek olacakti. Unutmayalim, Buyuk Veri ortaminda tek bir kategorik kolonun milyonlarca degisik degeri olabilir!

Friday, July 26, 2013

Veriyi Ayriksallastirmak (Discretization)

Pandas ile eldeki veriyi ayriksallastirmak icin herhangi bir sayisal kolon uzerinde qcut kullanilabilir. Bu cagri istatistiksel bolgeler (quartile) uzerinden hesap yapan bir cagridir, belli bir kolon icin numerik degerler belirlenen araliklara bolunur ve eslemesi geri rapor edilir.

import pandas as pd
import numpy as np

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}

df = pd.DataFrame(data)

cats = pd.qcut(df['pop'], 3)
df['pop_cat'] = cats
df['pop_cat'] = "pop_" + df['pop_cat']


Bu cagridan sonra her satirin belli bir araliga eslendigini gorecegiz (cikti altta). Cagri qcuts'dan gelen objeye bakmak ilginc olabilir, icinde bir dizin (array) bir de "seviyeler (levels)" adinda 2. bir dizin var. Ana dizin icinde her nokta icin (veriyle ayni sirada) hangi araligin secildigi gosteriliyor. Siranin veri ile ayni olmasi sayesinde zaten pop_cat adli yeni bir kolona atama yaptigimiz anda Pandas o kolonu ana veriyle hemen esleyebiliyor. Bu iyi bir ozellik bu arada, elde mesela bir Numpy vektoru var ise, ve bu vektor DataFrame'imiz satir sayisi ile esdeger tane veri iceriyorsa, o zaman o vektoru alip cat diye aninda DataFrame'e yeni bir kolonmus gibi verebiliriz (ya da eskisinin uzerine yazabiliriz).

Levels ise o araliklari teker teker listeliyor, ustteki ornek icin 3 tane.

Biz ayrica ufak bir ek yaparak araligin hangi kolona ait oldugu gozuksun diye onu da veri icine ekledik. DataFrame icinde zaten belli oluyor ama duz CSV'ye versek ve mesela fpgrowth gibi bir algoritma onun uzerinde islese sonuclari rapor ederken aralik ve veri baglantisi daha rahat belli olur.


   pop   state  year             pop_cat
0  1.5    Ohio  2000    pop_[1.5, 1.933]
1  1.7    Ohio  2001    pop_[1.5, 1.933]
2  3.6    Ohio  2002    pop_(2.733, 3.6]
3  2.4  Nevada  2001  pop_(1.933, 2.733]
4  2.9  Nevada  2002    pop_(2.733, 3.6]


Istatistiksel bolgeler bu arada verinin frekansina hassastir (ki bu iyi), median ve mode arasindaki fark gibi, quartile islemi mode gibi hesaplanir, mode bilindigi gibi veri noktalarini siraya dizip ortadaki noktayi dondurur. Ortalama gibi toplama bolme yapmaz.

Thursday, July 4, 2013

Dekoratorler, Onbellek Kodlamasi, Fonksiyon Degistirmek

Bir fonksiyona ya da kod parcasina onbellek kullanimi eklemek kolaydir fakat bu tur ekler kodun okunabilirligini de azaltabilirler. Mesela kare almakla yukumlu bir fonksiyonumuz var diyelim (altta ise yaramaz bir degisken dummy ekledik, bazi puf noktalari gosterebilmek icin),

def kare(dummy, a):
    return a*a


Bu fonksiyonu

kare("filan", 3)

diye cagiriyoruz ve sonuc olarak 9 gelmesini bekliyoruz.

Onbellekleme icin, diyelim ki, eger a degeri onceden gorulmusse, kare islemi sonucunun tekrar hesaplanmasini istemiyoruz, onu onbellekten bulup hizli bir sekilde geri dondurmek tercihimiz (tabii carpim islemi de cok hizli isler, ama bu ornek icin yavas olabilecegini hayal edelim).

Bu kod uzerinde onbelleklemeyi eski usulle yapsaydik, kod suna benzerdi:

cache = {}
def kare(dummy, a):
    if not a in cache: cache[a] = a*a
    return cache[a]


Degisken cache bir Python dictionary'dir ve onbellegimiz onun uzerinde  duruyor. Goruldugu gibi kod biraz kalabaliklasti. Onbellek objesi alanen ortada, ayrica if gibi cok ciddi bir ibareyi koda sokusturmak zorunda kaldik :) Genellikle bu ifade onemli bir islem mantigi var ise kullanilir - en azindan kod okunabilirligi acisindan boyle olmasi daha iyidir.

Peki bu isi daha temiz bir sekilde yapamaz miydik?

Python dekorator fonksiyonlari iste tam burada ise yarar. Bir dekorator bir fonsiyonu "sarmalayabilir (wrap)", ve o fonksiyona giren cikan tum degerler uzerinde islem yapabilir, ve onlari istedigi gibi degistirebilir, bu sayede o fonksiyona "caktirmadan" ek ozellikler verebilir. Sozdizim acisindan da temiz dururlar, cunku dekorator fonksiyon uzerinde '@' ile tanimlanan bir seydir, baska bir eke ihtiyac yoktur. O zaman (once dekoratorun kendisi)

def cache(function):
  memo = {}
  def wrapper(*args):
    if args[1] in memo:
      print "cache hit"
      return memo[args[1]]
    else:
      print "cache miss"
      rv = function(*args)
      memo[args[1]] = rv
      return rv
  return wrapper


Ustteki kod ana kodunuzdan ayri bir yerde, bir dosyada durabilir mesela, sadece bir kere yazilir zaten, ve kullanilmasi gerektigi zaman su ibare yeterlidir,

@cache
def kare(dummy, a):
    return a*a


Goruldugu gibi gayet temiz. Onbellek kodu hic etrafta gozukmuyor, bu da kod bakimini daha rahatlastiran bir ozellik. Boylece kare fonksiyonunu normalde olmasi gerektigi gibi yaziyoruz, kod onbellek olsa da olmasa da ayni sekilde yaziliyor, sadece carpim icin gereken islem mantigini iceriyor.

Not: dummy degiskenini dekorator icinde istedigimiz herhangi fonksiyon argumani ile is yapabilecegimizi gostermek icin kullandik, args[1] ile sadece ikinci argumana baktik mesela.

Koda Ekler Enjekte Etmek

Diyelim ki mevcut bir kod parcasi var,


import random

class Foo:
    def f(self,x):
        x = random.random()
        return x

o = Foo()   


Biz bu kodun f() cagrisini "yakalayip" ona ek bir seyler yaptirtmak istiyoruz, ve mevcut koda hic dokunmadan bunu yapmak istiyoruz. Belki f() cagrisi bir baska yazilim paketi icinde, vs. Bu fonsiyonu dekore ederek bunu yapabiliriz, fakat mevcut fonksiyon koduna dokunmak istemedigimiz icin metot ustunde @birdekorator gibi bir kullanim yapamayiz. Bu durumda baska bir secenek sudur,

def decorated_f(fn):
    def new_f(*args, **kwargs):
        res = fn(*args, **kwargs)
        setattr(args[0], "was", res)
        return res
    return new_f

Foo.f = decorated_f(Foo.f)


Simdi

print "o", o.f(0)
print "was", o.was


Yeni ekleri de isletecek, bu ek Foo uzerinde yeni bir oge yaratti, ve bu ogeye o.was diye erisiyoruz.


Monday, July 1, 2013

Oracle, Pandas, HDF5

Daha onceki yazilarda SQL*Plus uzerinden CSV dosyalarina veri aktarimini gorduk. SQLplus'in bazi eksikleri var ne yazik ki, bu program metin bazli terminaller caginda ekranda birseyler gostermek icin yazilmis, hizli, verimli veri aktarimini pek beceremiyor. Disaridan parametre gecmek bile buyuk problem. Bunlarin yerine Oracle Python baglanti kutuphanesi kurulup direk Pandas icinden baglanti yapilabilir.

Diger yandan CSV ciktisi almak yerine daha az yer tutan HDF formati secilebilir.

Simdi bunlarin hepsini yanyana koyalim:

import pandas as pd
import pandas.io.sql as sql
import cx_Oracle as odb

conn = odb.connect("kullanici/sifre@DB")

query = """
select ...

from ...
"""

df = sql.read_frame(query, conn)               
df.to_hdf("dosya.h5" % i,"table")

Direk Python icinden baglandik, sorguyu islettik, Pandas DataFrame'i direk sorgu verisinden yarattik, ve ciktiyi HDF formatinda diske yazdik. Bu formati kullanmak icin PyTables adli bir paket lazim, kurmak icin

sudo apt-get install python-tables

Friday, June 28, 2013

Oracle SQL ile Orneklemek (Sampling)

SELECT ifadesi ile tum satirlar (where ile filtrenenleri tabii) almak yerine, o kume icinden 10000 satirlik bir orneklem (sample) almak icin alttaki ifade kullanilir,

exec dbms_random.initialize(17809465);

select
kolon1,
kolon2,
...
FROM [tablo]
where 1=1
and ...
and rownum<10000
..
order by dbms_random.random
;

Cagri initialize ne ise yarar? Bu fonksiyona ayni tohum (seed) degeri verilirse (rasgele sayi uretme literaturunu bilenlere bu kavram tanidik gelecektir), o deger ile yapilan bir rasgele islem arka arkaya isletilse bile hep ayni "rasgele degerleri" dondurur (ya da ustteki ornekte hep ayni rasgele satirlari geri getirir). Eger tohum verilmeseydi ustteki cagri her seferinde farkli degerleri geri getirecekti.

Bunun faydasi, kodumuzda hata ararken hep ayni veriyle islem yaptigimizdan emin olabilmemiz (hep ayni tohumu kullanarak), boylece veriye donuk farkliliklarla ugrasmaya ihtiyac kalmamasi. Sayi 17809465 yerine herhangi, yeterince buyuk baska bir sayi kullanilabilir.

Eger farkli cagrilarda farkli veri istersek, bir sonraki cagrida tohum degerini degistiririz, ve farkli rasgele sonuclar aliriz.

Wednesday, June 26, 2013

Bash, Surec Idaresi

Komut satirindan surec kontrolu, idaresi gibi isler icin Unix bash'in guzel ozellikleri var. Bash icin bir script'i sh script.sh ile degil bash script.sh olarak isletmek gerekli. Mesela

set -m # Enable Job Control
for (( i = 0; i < $2; i++ ))
do
    cmd="baz komut "
    cmd+=" ";cmd+=$2;cmd+=" ";cmd+=$i
    if [ $1 == "secim1" ]; then
        xterm -hold -e $cmd &
    fi
    if [ $1 == "secim2" ]; then
        $cmd &
    fi
done
wait
echo "hepsi tamam"

...

Ustteki script icinde surec kontrolu (job control) icin -m en basta tanimlanmali.

Diyelim ki bu script'e verilen birinci secenek (yani $1) ile bir string veriyoruz, ve string uzerinde if..else irdelemesi yapilarak script farkli seyler yapabiliyor. Ayrica baz bir komuta ek string'leri dinamik olarak ekleyerek dinamik bir komut olusturabiliyoruz. Isletmek icin mesela

bash test.sh secim1 2

Ikinci secenek ile (yani $2) ile bir sayi veriyoruz diyelim, bu sayi kadar bir dongu baslatabiliriz, ve dongude her indis icin baska "alt komutlari" arka planda isletebiliriz. Birinci secenek her komut icin xterm baslatmak, ya da pur arka planda "sessiz olarak" isletmeyi kontrol ediyor olabilir.

Bash surec kontrolunun guzel tarafi, mesela wait komutu ile bu arka plana atilmis tum surecler bitene kadar ana script'in bekleyebilme ozelligidir. Belki tum alt komutlar bitince bazi ek birlestirme, vs. islemleri yapilacaktir. Onlari yapmanin en uygun yeri burasi, yani hemen wait sonrasi. Bunu test etmek icin su script'e bakalim

set -m # Enable Job Control
echo "1 saniye bekle..."
sleep 1 &
echo "3 saniye bekle..."
sleep 3 &
wait
echo "hepsi tamam"


Bu script isletilence 3 saniye bekleme olacaktir, 1 saniyelik "uyku (sleep)" komutu bitmis olsa bile 3 saniyelik olanin bitmesi beklenecektir. Ve (and), yani & isareti bilindigi gibi Unix'te bir komutu arka plana atmaya / isletmeye yarar (background process).

Friday, June 7, 2013

Not Defteri Icinde R

iPython not defterleri icinde R kodu bile kullanmak mumkun. Bazi puf noktalar / uzak durulmasi gereken seyler: Mesela read.csv metoduna ek parametre (mesela ayrac -seperator-) gecilmesi not defterini rahatsiz edebiliyor, o zaman olagan (default) ayrac hep kullanilabilir, ki bu virgul isareti.

Ornek bir kullanim asagida

In [1]:
%load_ext rmagic

In [31]:
%R -n -d myData myData <- read.csv('dosya.csv')

In [*]:
%%R
library(rpart)
tree <- rpart(y ~ kolon1 + kolon2, method="class", data=myData)

In [ ]:
%%R
library(rpart.plot)
rpart.plot(tree,type=4, extra=1)

Magic (buyu) kullanimi not defterlerinin pek cok ek ozelligi cagirabilmesini sagliyor, su anda sql icin bile bir magic eklemesi var mesela.

iPython ortami hakikaten bilim, veri analizi, vb. kullanimlar icin ideal bir ortam haline geliyor.

Friday, May 24, 2013

MySQL ve CSV

Komut su sekilde

mysql -e 'SELECT * FROM [tablo]' --user=[kullanici] --password=[sifre] --host=[makina] > /bir/dizin/dosya.csv

Secenek -e sonrasi sorgu SQL'in izin verdigi herhangi bir sorgu olabilir, yani ek WHERE sartlari burada tanimlanabilir. Eger tum tablo alinacaksa ustteki format yeterli. Ustteki komut bir shell script icinden isletilebilir. Ubuntu uzerinde sudo apt-get install mysql-client ile en azindan MySQL baglanti programlari kurulmus olmali.

Thursday, April 18, 2013

IP ve Bolge Eslemesi, Python

IP adresini yaklasik olarak bir bolgeye, sehre, hatta enlem boylam kordinatina eslemek icin pygeoip adli Python paketi var. Kurmak icin

sudo easy_install pygeoip

Kodun ek veri dosyalarina ihtiyaci var. Bu dosyalar

http://dev.maxmind.com/geoip/geolite#IP_Geolocation-1

adresinde Downloads bolumunden indirilebilir, GeoIP.dat.gz, GeoIPv6.dat.gz, GeoLiteCity.dat.gz dosyalari mesela. Ornek kod, mesela 212.174.157.30 ip adresi icin (adresi nslookup www.tbmm.gov.tr ile bulduk)

import pygeoip

gi = pygeoip.GeoIP('[DIZIN]/GeoLiteCity.dat')
print gi.record_by_addr('212.174.157.30')


Sonuc

{'city': u'B\xfcy\xfck', 'region_name': u'61', 'area_code': 0, 'time_zone': 'Asia/Istanbul', 'dma_code': 0, 'metro_code': None, 'country_code3': 'TUR', 'latitude': 40.66669999999999, 'postal_code': '', 'longitude': 40.400000000000006, 'country_code': 'TR', 'country_name': 'Turkey', 'continent': 'EU'}

Sonuc Istanbul (sitenin barindirma servisi degisik bir sehirde demek ki). Diger ornekler

https://github.com/appliedsec/pygeoip

Eger mesela Pandas DataFrame objesi uzerindeki bir IP adresini isleyip, hesaplanan enlem / boylam degerlerini ayni satira ayri kolonlar olarak yazmak isteseydiniz,

import pygeoip, os         
import pandas as pd

gi = pygeoip.GeoIP('[DIZIN]/GeoLiteCity.dat')

def ip_loc(x):
    rec = gi.record_by_addr(x)
    lat = rec['latitude']
    lon = rec['longitude']
    return pd.Series([lat, lon], index=['latitude','longitude'])

df = pd.DataFrame({'ip': ['212.174.157.30','212.174.157.30','212.174.157.30']})

df[['latitude','longitude']] = df['ip'].apply(ip_loc)

print df


Buradan gelen sonuc

               ip  latitude  longitude
0  212.174.157.30   40.6667       40.4
1  212.174.157.30   40.6667       40.4
2  212.174.157.30   40.6667       40.4


Monday, April 15, 2013

LateX ile Prezentasyon - Beamer

Daha once baska bir prezentasyon paketinden bahsetmistik. Beamer adli bir paket kullanmasi daha kolay bir program.

Eger suradaki apt-get listesi var ise, beamer kurulmus olacaktir, yok ise

apt-get install latex-beamer

ile kurulabilir. En basit ornek

\documentclass{beamer}

\usetheme{Darmstadt}
\usefonttheme[onlylarge]{structurebold}
\setbeamerfont*{frametitle}{size=\normalsize,series=\bfseries}
\setbeamertemplate{navigation symbols}{}

\title{Introduction to Whatever}
\logo{%
    \includegraphics[width=1cm,height=1cm,keepaspectratio]{logo-dosyasi}
}

\begin{document}
\begin{frame}{Header}

Text text

\end{frame}

\end{document}






Dosya logo-dosyasi bir imaj dosyasidir ve eps eklentisinde olmasi gerekiyor, ImageMagick ile baska bir formattan rahatca eps cevrimi yapilabilir.

Paketin pek cok ozelligi var, suradan dosyalar indirilip, doc altindaki pdf okunabilir, examples altindaki orneklere bakilabilir.

Eger yazicidan basmak istersek, ve iki sayfa tek tarafta olacak sekilde cikti istersek (prezentasyonlar genelde oyle basilir) ama yazici problem cikartiyorsak, yaziciya gondermeden once PDF uzerinde degisim yapilabilir, mesela

pdfjam --landscape --nup 2x1 dosya.pdf --outfile dosya2.pdf

Bu script cagrisi ile 2 sayfa teke indirgenmis olur.


Friday, April 12, 2013

Sqlplus ile CSV Uretmek

Komut satirindan sqlplus ile CSV uretmek icin

set echo off
set verify off
set termout on
set heading off
set pages 50000
set feedback off
set newpage none
set linesize 250
set colsep '|'

spool out.csv;

select 

kolon1 || '|' ||
kolon2 
from tablo where filtre = 'filan';

spool off;
exit;


Bu sql dosyasini mesela test.sql olarak kaydedersek,

sqlplus64 user/pass@db @test.sql

ile isletebiliriz, ve ciktiyi out.csv icinde goruruz. Kolon degerleri | ile ayrilmis olacaktir. Okunan tablo ismi goruldugu gibi tablo, zaten ciktiyi uretecek SQL ozellikle belirtiliyor.

SQLPlus'un CSV uretmek icin pek iyi bir ortam oldugu soylenemez. Zaten bu aracin "sekli olarak veri uretmek" oldugu soyleniyor, tabii 70-80'li yillarin text bazli ortami icin kolonsal sekiller uretmek anlaminda.. Bu sekli egilim sadece veriyi cekip cikartmak isteyenler  icin problem olabiliyor. Mesela linesize parametresine dikkat, bu parametre bir satirda kac karakter olacagini tanimlar, eger veri satirinda o kadar karakter yoksa, o zaman linesize bosluk karakteri ile doldurulur (daha fazla veri gelmisse de fazla olan karakterler kesip atilir! dikkat). Bu bosluk karakteri satirdaki en son kolonu okurken problem cikartabilir, Pandas ile mesela skipinitialspace=True ile bu bosluktan kurtulmak gerekiyor.

Kolonlari yanyana ve | ile ayrilacak sekilde biz yanyana getiriyoruz, cunku baska turlu tum bilgilerin ardi ardina sirilanmasi mumkun olmuyor (colsep ile set edilen ayarin pek bir anlami yok yani).

Ayrica SQLPlus kolon isimlerini otomatik olarak vermiyor. Biz bu isimleri Pandas ile okurken kendimiz veriyoruz.

Monday, April 8, 2013

Ubuntu'dan Oracle'a Baglanmak

Su sayfadaki tarif takip edilebilir

https://help.ubuntu.com/community/Oracle%20Instant%20Client

Su adrese girilir ve baglanan sisteme tekabul eden baglanti tiklanir

http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html

Bizim icin bu Linux x86-64 idi mesela. Buradaki listelenen seyler icinde Basic, SQL*Plus, JDBC Supplement icin gosterilen rpm indirilir. "Lisans Kabulu" icin en ust soldaki radyo dugmesinin secilmis olmasi gerekiyor.

Bu noktada Oracle sitesi "uyelik" sartini arar, email, sifre vs verip uyelik yapilir, konfirmasyon email'ine cevap verildikten sonra ustteki rpm dosyalari indirilecektir.

Sonra

apt-get install alien

kurulur ve

sudo alien -i oracle-instantclient11.2-*

ile indirilen dosyalar kurulur. Eger paylasilan kutuphane (shared library, so) hatalari var ise, .bashrc icine

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/oracle/11.2/client64/lib

yaziniz. Bir kere sudo ldconfig yapmaniz da gerekebilir. Ayrica

sudo apt-get install libaio1

Bundan sonra sqlplus64 isleyecektir. Simdi makina, db isimlerini nasil tanimlayacagimiza gelelim.

sudo mkdir /etc/oracle

ve bu dizinde

sudo gedit /etc/oracle/tnsnames.ora

Bu dosyada db, makina isimleri, ip adresleri yeralir. En son .bashrc icinde

export TNS_ADMIN=/etc/oracle

Artik sqlplus64 user@db gibi bir ifade ile baglanti yapilabilir.

Eger Python icinden baglanmak istersek,

http://tshepang.net/accessing-oracle-db-using-python-in-debian

cxOracle lazim, mesela 64 bit Python 2.7 Oracle 11 icin CentOS 5 x86_64 RPM (Oracle 11g, Python 2.7)  baglantisina tiklanir. Indikten sonra

sudo alien --install cx_Oracle-5.1.2-11g-py27-1.x86_64.rpm
sudo easy_install cx_oracle
sudo ln -s /usr/lib/python2.7/site-packages/cx_Oracle.so /usr/lib/python2.7/lib-dynload
sudo ln -s /usr/lib/oracle/11.2/client/lib/libnnz11.so /usr/lib
sudo ln -s /usr/lib/oracle/11.2/client/lib/libclntsh.so.11.1 /usr/lib


Kod ornegi

import pandas as pd]
import pandas.io.sql as sql
import cx_Oracle as odb
conn = odb.connect("[kullanici]/[sifre]@[taban]")

df = sql.read_frame("select .. from", conn)

ile Oracle verisi bir Dataframe icine alinmis olur.

Sunday, March 31, 2013

Ubuntu, Nautilus, Dosya / Dizin Uzerinde Islem Yapmak

Ubuntu masaustu dizin gezme programi (explorer) Nautilus'u kullanirken, eger  icinde olunan bir dizin, dosya uzerinde islem yapmak istersek, bir gorsel kisayol tanimlayabiliriz. Nautilus yapisina gore $HOME/.gnome2/nautilus-scripts altina atilan her script, mouse'ta sag tiklama yapilinca menude Scripts altinda cikar. Mesela notebook-server adinda bir dosya yaratmissak (dosya chmod 755 ile isler hale getirilmelidir), sag tiklama sonrasi su goruntu cikar,


Script icinde

#!/bin/sh
cd `echo $NAUTILUS_SCRIPT_CURRENT_URI | sed -e 's/file:\/\///g'`

... burada o dizine gore ek islem yap ...

olabilir mesela, sed ile yapilan islem $NAUTILUS_SCRIPT_CURRENT_URI icinden file:/// ibaresini cikartmak icin. Bu degiskene Nautilus tarafindan otomatik olarak "sag tiklamanin yapildigi dizinin degeri" geciliyor, ama URI oldugu icin icinde file:/// ibaresi var. Biz de o degeri cikartiyoruz. Ardindan istenilen ek islem yapilabilir.