Thursday, December 27, 2012

Siparisler Uzerinde Veri Madenciligi - kNN

Daha once regresyon ile atillik tahmini yapmistik (lineer, ve GLM ile). Bu yazida En Yakin k-Komsu (k-Nearest Neighbor -kNN-) teknigini kullanacagiz.

kNN metodu veriden model cikartmaz, verinin kendisini model olarak kullanir. Bu sebeple ornek bazli metotlardan (instance based methods) bilinir. Temeli basit; model kurmadan etiketleri bilinen veriyi bir kenarda tutariz sonra etiketsiz yeni veri noktasi gelince bu veriye donup bakariz, eldeki veriye "en yakin" k-tane ornegi buluruz ve bu k ornek icinde en fazla hangi etiket var ise, yeni etiketin bu olacagina karar verilir. "En yakinlik" sozu bir kordinat sistemi / uzaklik kavramini cagristirir, ve evet kNN numerik degerlerle bir kordinate sisteminde islem yapar, bu acidan k-means'e (ve pek cok diger yapay ogrenim metotuna) benzedigi soylenebilir. Regresyon ornegindeki gibi gibi kategorik degerler var ise bunlar sayisal hale cevirilmelidir.

kNN'in detaylarina ileride girecegiz, simdilik dellstore2 uzerindeki ornegi gorelim.

from sklearn import neighbors
from patsy import dmatrix
import numpy as np
from pandas import *

__day__ = 130

cols = """
0 + month + day + day_of_week + rank + categoryname + income + season
+ cat_freq + creditcardtype
"""

orders = read_csv("dell-train.csv",sep=",")
train = dmatrix(cols,orders)
last_value = orders[['last_visit']].as_matrix()[:,0] > __day__

print len(last_value[last_value==True])
print len(last_value[last_value==False])

knn = neighbors.KNeighborsClassifier(n_neighbors=10)
knn.fit(train,last_value)

orders = read_csv("dell-validate.csv",sep=",")
validate = dmatrix(cols,orders)
last_value = orders[['last_visit']].as_matrix()[:,0] > __day__

pred = knn.predict(validate)

success = sum(pred[last_value==True] == 1) + \
          sum(pred[last_value==False] == 0)
print success / float(len(pred)) * 100


Burada kNN'e bir 0/1 tahmini yaptirdik, bu etiketleri atillik sayisindan urettik, 130 gunden buyuk atillik degeri 1, kucukleri 0 olsun dedik. Etiket sayisinda bir sinirlama yok (SVM'in aksine), bu ornekte 2 tane kullandik, daha fazla da olabilirdi. Bu arada kNN regresyon amacli da kullanilabilir, k yakin komsu bir etiket oyu verecegine, belli agirliklarla bir ortalama sayi da uretebilir.

Kullandigimiz kNN paketi scikits-learn Python kutuphanesi. Kategorik degerleri sayisallastirmak icin Pasty kullanildi. 

Ustteki kodun basari orani yuzde 86'dir. Gercek dunya verisinde yuzde 85 degerini gorduk (atillik esik degeri ne olursa olsun basari orani ayni -biz 53 gun kullandik-). Metot kuvvetli.

Saturday, December 22, 2012

Mahout, Jython ve Yapay Ogrenim

Bir diger unlu yapay ogrenim kutuphanesi Mahout. Kurmak icin su sayfanin basindaki hareketler takip edilebilir

$ apt-get install maven2

$ cd /opt

$ svn co http://svn.apache.org/repos/asf/mahout/trunk

$ mv trunk mahout_trunk

$ ln -s mahout_trunk/ mahout

$ cd mahout

$ mvn install


Burada Maven denen ve Java dunyasinda pek sevilmeyen bir program kullaniliyor. Maven, Ant yerine / ustune ona bir paket sistemi kazandiran bir sistem, mvn install sirasinda bir suru paketin Internet'ten indirildigini goreceksiniz. Yani Maven paket baglantilarini takip ederek (guya) bizi bir suru dertten kurtariyor, gereken her seyi indiriyor, fakat goreceginiz gibi mvn install asamasi saatler surebilir. Neyse, Mahout kullanabilmek icin bu aci ilaci icmek gerekecek (!), ve bundan sonra Maven bir daha da kullanilmayacak.

Kurulus bitinca $HOME dizini altinda bir .m2 dizini olusturulur. Maven tum gerekli jar dosyalarini buraya koymustur. Biz bu jar dosyalarini Jython'a disaridan kullandirtacagiz. Bunun icin ufak bir bash script numarasi yeterli. Dizin .m2 seviyesinden baslayarak ozyineli (recursive) olarak asagi ineriz, ve onumuze cikan her jar dosyasini alip iki nokta ustuste ile ayirarak CLASSPATH'e ekleriz. Bu noktadan sonra Jython gerekli tum jar'lara sahip olacaktir.

CLASSPATH=`find $HOME/.m2/ -name *.jar`
export CLASSPATH=`echo $CLASSPATH | sed 's/jar\s/jar\:/g'`
jython test.py


Ornek bir Jython Mahout programini altta bulduk

https://gist.github.com/2878249

Yanliz biz bu programda bazi degisiklikler yaptik, ustteki kod icinde CLASSPATH Python programi "icinde" olusturuluyor, bu pek temiz degil, biz bu isleri bash script ortaminda yaptik, boylece Python kodu sadece Mahout ile ilgili isler yapabiliyor. Bizim versiyon test.py altta

from datetime import datetime
from org.apache.mahout.common import RandomUtils
from org.apache.mahout.cf.taste.common import TasteException
from org.apache.mahout.cf.taste.eval import *
from org.apache.mahout.cf.taste.impl.eval import *
from org.apache.mahout.cf.taste.impl.model.file import *
from org.apache.mahout.cf.taste.impl.neighborhood import *
from org.apache.mahout.cf.taste.impl.recommender import GenericUserBasedRecommender
from org.apache.mahout.cf.taste.impl.recommender.slopeone import SlopeOneRecommender
from org.apache.mahout.cf.taste.impl.similarity import *
from org.apache.mahout.cf.taste.model import *
from org.apache.mahout.cf.taste.neighborhood import *
from org.apache.mahout.cf.taste.recommender import *
from org.apache.mahout.cf.taste.similarity import *
from java.io import *
from java.util import *

class GenericRecommenderBuilder(RecommenderBuilder):
    def __init__(self):
        pass
    def buildRecommender(self, model):
        similarity = PearsonCorrelationSimilarity(model)
        neighborhood = NearestNUserNeighborhood(2, similarity, model)
        return GenericUserBasedRecommender(model, neighborhood, similarity)

class SlopeOneRecommenderBuilder(RecommenderBuilder):
    def __init__(self):
        pass
    def buildRecommender(self, model):
        similarity = PearsonCorrelationSimilarity(model)
        neighborhood = NearestNUserNeighborhood(2, similarity, model)
        return SlopeOneRecommender(model)

def main():
    RandomUtils.useTestSeed()
    model = FileDataModel(File("intro.csv"))
    builder = GenericRecommenderBuilder()

    print 'Starting run at %s' % datetime.now()
    for builder in [GenericRecommenderBuilder(), SlopeOneRecommenderBuilder()]:
        print 'Starting evaluations of recommender created using %s at %s...' % (builder, datetime.now())
        for evaluator in [AverageAbsoluteDifferenceRecommenderEvaluator(), RMSRecommenderEvaluator()]:
            print 'Evaluating recommender using %s at %s...' % (evaluator, datetime.now())
            score = evaluator.evaluate(builder, None, model, 0.7, 1.0)
            print 'Score evaluated by %s=%.2f' % (evaluator, score)
    print 'Ending run at %s' % datetime.now()

if __name__ == '__main__':
    main()


Bu kod intro.csv adli bir dosyaya ihtiyac duyar. Bu ornek veri

1,101,5.0
1,102,3.0
1,103,2.5
2,101,2.0
2,102,2.5
2,103,5.0
2,104,2.0
3,101,2.5
3,104,4.0
3,105,4.5
3,107,5.0
4,101,5.0
4,103,3.0
4,104,4.5
4,106,4.0
5,101,4.0
5,102,3.0
5,103,2.0
5,104,4.0
5,105,3.5
5,106,4.0


Weka, Jython ve Yapay Ogrenim

Yapay ogrenim (machine learning) paketlerinden / yazilimlarindan unlu birisi Weka. Paket icinde karar agaclari, SVM gibi bilinen ML algoritmalari var; Weka Java ile yazilmistir fakat Jython uzerinden Python ile erisim mumkundur.

Kurmak icin site

http://www.cs.waikato.ac.nz/ml/weka/

Zip acilir ve kurulum bu kadar. Su baglantida Jython ornegi var

http://weka.wikispaces.com/Using+WEKA+from+Jython

Jython kullanmak icin Ubuntu uzerinde apt-get install jython. Sonra bir script yazin, mesela iris.sh,

export CLASSPATH=$CLASSPATH:[WEKA_DIZIN]/weka-3-6-8/weka.jar
jython iris1.py


Kodunuz iris1.py icinde olacak, ve suna benzeyecek (ustteki siteden alindi)

import sys
import weka.classifiers.trees.J48 as J48
import java.io.FileReader as FileReader
import weka.core.Instances as Instances
import weka.core.converters.CSVLoader as CSVLoader
import weka.classifiers.trees.J48 as J48

file = FileReader("[WEKA_DIZINI]/weka-3-6-8/data/iris.arff")
data = Instances(file)
data.setClassIndex(data.numAttributes() - 1)

j48 = J48()
j48.buildClassifier(data)

print j48


Bu kodu iris.sh ile isletin. Soyle bir sonuc gelecek

petalwidth <= 0.6: Iris-setosa (50.0)
petalwidth > 0.6
|   petalwidth <= 1.7
|   |   petallength <= 4.9: Iris-versicolor (48.0/1.0)
|   |   petallength > 4.9
|   |   |   petalwidth <= 1.5: Iris-virginica (3.0)
|   |   |   petalwidth > 1.5: Iris-versicolor (3.0/1.0)
|   petalwidth > 1.7: Iris-virginica (46.0/1.0)

Number of Leaves  :     5

Size of the tree :     9


Iris veri seti ML'de iyi bilinen veri setlerinden, ve ustteki kod ile J48 algoritmasi ile bu veri uzerinde bir karar agaci olusturduk.

Fakat pratikte bir problem var, is dunyasinda cogunlukla veriyi ARFF formatinda bulmayiz, cogunlukla CSV formati karsimiza cikiyor. Dert degil, Weka'nin CSV okuyucusu da var, simdi Iris verisini CSV'den okuyan ornek gorelim.

import sys
import weka.classifiers.trees.J48 as J48
import java.io.FileReader as FileReader
import java.io.File as File
import weka.core.Instances as Instances
import weka.core.converters.CSVLoader as CSVLoader
import weka.classifiers.trees.J48 as J48

file = File("/bir/dizin/iris.csv")
loader = CSVLoader()
loader.setSource(file)
data = loader.getDataSet()
data.setClassIndex(data.numAttributes() - 1)

j48 = J48()
j48.buildClassifier(data)

print j48


Ustteki kod benzer bir cikti verecek.

Veri dosyasi iris.csv'i Internet'ten bulabilirsiniz, bir ornegi surada mesela

Sunday, December 16, 2012

Kategorik Veri, 1-in-n, Faktorler, R ve Patsy

R dilini kullanarak kategorik veri iceren kolonlarin 1-in-n seklinde yana dogru "genisletilerek" 1/0 iceren hale cevirilebildiginden bahsetmistik. Fakat R bu degismis hali disa yansitmaz, lm(), nnet() gibi komutlar ic isleyisleri sirasinda bu degisimi kullanirlar, lm() sonuc raporunde bu yeni kolonlari gorebilirsiniz mesela, ama veri disari cikmaz.

Eger bu veriyi mesela matris formatinda istiyorsaniz, su komut dizisini kullanabilirsiniz (dellstore2 ornegindeki season ve categoryname kolonlari icin)

orders <- read.csv ("data.csv",header=TRUE,sep="|")
orders <- cbind(orders, model.matrix( ~ 0 + season + categoryname, orders))
orders <- orders[, setdiff(names(orders), c("season", "categoryname"))]
write.csv (orders,"out.csv")


Sondan ikinci satir lazim cunku genisletilmis kolonlar eklense bile orijinal kolon hala orders icinde tutuluyor. Bu kolona artik ihtiyac yok ve cikartilmasinda bir zarar olmayacak.

Eger ayni islemi Python ile yapmak istersek Patsy adli paket yardimci olabilir. En son versiyon

http://pypi.python.org/pypi/patsy/

Ayrica Pandas kurmak ta gerekiyor, bunun icin "sudo pip install pandas" yeterli.

Kullanmak icin mesela

from patsy import dmatrix
from pandas import *
orders = read_csv("dell.csv",sep=",")
matrix = dmatrix("0 + month + netamount + gender + season + cat_freq + creditcardtype",orders)

print matrix.design_info
print matrix[0,:]


Ust son iki satirda matrisin ic yapisini (yeni kolon isimlerini gormek icin) ekrana bastirdik, ayrica matrisin ilk satirini ornek olarak gosterttik. Sonuc

DesignInfo(['gender[F]', 'gender[M]', 'season[T.SPRING]', 'season[T.SUMMER]', 'season[T.WINTER]', 'creditcardtype[T.c2]', 'creditcardtype[T.c3]', 'creditcardtype[T.c4]', 'creditcardtype[T.c5]', 'month', 'netamount', 'cat_freq'],  ....

[  0.     1.     0.     0.     0.     0.     0.     0.     0.    11.     5.08
   1.  ]


gibi bir cikti goreceksiniz, yani faktor kolonlari 1-in-n formatina cevirilerek 1/0 degeri tasiyacak sekilde "yana dogru" genisletilmistir. Yeni kolon isimleri mesela season[T.SPRING] gibi, yaz mevsimi icin apayri bir kolon vardir,ve ona tekabul eden 0/1 degeri olacaktir.

Bu yeni matrisle istediginiz yapay ogrenim rutinini cagirabilirsiniz. Matris Numpy formatiyla uyumludur. 

Kaynak

Saturday, December 15, 2012

Git Commit ve Unite Halinde Degisimler

Diyelim ki bir Git deposundaki kodlarinizda calisiyorsunuz, degisiklik yaptiniz. Bu kodlari nasil depoya geri koymak gerekir?Once dizin icinde git status yapin. 

# On branch master
# Changes not staged for commit:
#   (use "git add/rm ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#    modified:   README
#    modified:   build.py
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#    mining/dosya.py

#
no changes added to commit (use "git add" and/or "git commit -a")

Takip edilmeyen dosyalar (untracked files) altinda. Bu dosyalar Git'e verilmemis, o yuzden git commit ile iceri alinmiyorlar. Eger bazi dosyalarin hakikaten Git disinda kalmasini ister, ve ustteki mesajla bile bunun bildirilmesini istemezsek, .gitignore icinde bunu yapabiliriz. Takip edilmeyen dosyalari git add ile ekleyebiliriz.

Degistirilmis (modified:) ile gosterilen dosyalar Git'in izledigi ve uzerinde degisim yapilmis dosyalardir. Bunlarin icinden istediklerimizi git add ile secerek commit icin hazirlayabiliriz. Mesela README dosyasinda bunu yapmis olsak, tekrar git status deyince

# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#    modified:   README

#    ...

gozukecek.

Onemli bir nokta: git commit oncesi git add ile eklenen her dosya belli bir "toplu degisim" icin ve bu degisimi temsil eder sekilde yapiliyor olmali. Ornek: yeni bir ozellik ekledik, ve bu ozellik icin A,B,C dosyalarina dokunduk (sonra baska sebeple D,E,F'ye dokunduk). Bu ozellik icin commit oncesi sadece A,B,C'yi git add ile eklemeliyiz (ekleme derken, ekleme icin 'isaretlemeliyiz' daha dogrusu). Niye? Cunku git commit derli toplu bir grup degisimi iceri almali, ve daha da onemlisi bu degisimi depoya git commit -m 'mesaj' ile verdigimiz mesaj da sadece o tek (unite) degisimi tarif ediyor olmali. Aslinda sadece ve sadece bu mesaj sebebiyle birbiriyle alakali degisimlerin tek unite halinde yapilmasina bir nevi mecburuz denebilir (kod okunabilirligi, takip edilebilirligi, bakilabilirligi acisindan).

Eger bir commit oncesi yapilan her degisikliklerin tamami tek bir uniteye aitse, o zaman basit bir sekilde git add -u ile tum bu degisiklikleri otomatik olarak ekleyebiliriz.

htop

Unix eski "top" komutu sistemdeki surecleri, ne kadar mikroislemci zamani kullanildigi gibi raporlari ekranda sabitleyip gosteren (akisli degil, mesela tail -f gibi -text bazli ortamda bu is icin curses gerekiyor dogal olarak-) bir programdi. Fakat biraz renksizdi, ve cok ozellige sahip degildi.

Yeni komut htop, tum cekirdeklerin (cores) yukunu sol ust kisimda canli olarak aktarir, htop ayrica hiyerarsik gosterime izin verir ve renklidir. Ubuntu'da kurmak icin sudo apt-get install htop




Sunday, November 25, 2012

Hinton Geri Geldi

Yapay Sinir Aglari alaninda unlu Geoffrey Hinton, Derin Ogrenme (Deep Learning -DL-) adli bir teknikle geri geldi. YSA (ve Hinton), 90'li yillarda SVM ve benzer tekniklerin parlamasi ile biraz arka planda kalmisti. Ama o sirada, ve son yenilik oncesi, Hinton Kisitli Boltzman Makinalari (Restricted Boltzman Machines -RBM) alaninda ilerlemeler yapmis; ve en son DL tekniginde ust uste konulan RBM'ler arasinda bir hiyerarsi olusturarak ses ve goruntu tanimada ciddi ilerlemeler kaydetmeyi basardi. Bu bulus etrafinda bayagi gurultu kopuyor bu gunlerde, acaba evrensel ogrenme algoritmasi  bu mu? gibi dusunceler.. DL, tamamen paralel sekilde kullanilmaya acik, Hinton'a gore ne kadar fazla donanim, ne kadar fazla paralellik eklenirse DL o kadar daha iyi isleyecektir.

Hinton ve arkadaslari gecende girdikleri bir Kaggle yarismasinda az bir veri uzerinde (ki eski YSA'lar genelde cok veriye ihtiyac duyarlardi), fazla "veri hazirlama"dan son anda girip birinciligi kazandilar. Bir diger makalede, yine ayni grup, daha onceki bir yarisma Netflix verisi uzerinde toplam filtrelemede (collaborative filtering) o yarismayi kazanmis olan ve dikkatle ayarlanmis SVD bazli algoritmayi hic ayarlanmamis RBM ile az da olsa gectiklerini yazdilar..

Diger yonde bir gorus surada.

Derini  Ogrenim'i Hinton burada anlatiyor

Siparisler Uzerinde Veri Madenciligi, Regresyon

Regresyon, veri zenginlestirme, yapay ogrenim tekniklerinden bahsettik. Bu yazida bu tekniklerden bazilarini ornek uzerinde isleyecegiz.

Ornek olarak dellstore2 adli tabandaki siparisleri kullanarak bir musterinin ne kadar bize "ugramayacagini", yani atil kalacagini tahmin etmek istiyoruz. Bunun icin siparis ve baglantili tablodaki verileri genisletilmis bir tabloya alarak, bu tablo uzerinde yapay ogrenim tekniklerini uygulayabiliriz. Regresyon hedef degiskeni musterinin ne kadar atil kaldigi, diger degiskenler ise siparis ve baglantili diger kolonlar. Once veriyi olusturalim, SQL soyle olabilir

select
rank() over (partition by o.customerid order by ol.orderlineid) as rank,
count(*) over (partition by o.customerid) as per_customer_count,
sum(o.totalamount) over (partition by o.customerid) as total_total_amount,
o.orderid,
o.customerid,
o.totalamount,
o.netamount,
c.zip,
'c' || c.creditcardtype as creditcardtype,
c.gender,
c.age,
c.income,
o.orderdate,
cat.categoryname,
extract(year from o.orderdate) as year,
extract(month from o.orderdate) as month,
extract(day from o.orderdate) as day,
extract(dow from o.orderdate)+1 as day_of_week,
case when extract(month from o.orderdate) in (3,4,5) then 'SPRING'
     when extract(month from o.orderdate) in (6,7,8) then 'SUMMER'
     when extract(month from o.orderdate) in (9,10,11) then 'AUTUMN'
     when extract(month from o.orderdate) in (12,1,2) then 'WINTER'
     end as season,
count(*) over (partition by o.customerid,cat.categoryname) as cat_freq,
first_last.min,
first_last.max,
extract('epoch' from ('2005-01-01'::timestamp - first_last.max)) / 60 / 60 / 24 as last_visit
from orders o
join customers c on o.customerid = c.customerid
join orderlines ol on ol.orderid = o.orderid
join products p on ol.prod_id = p.prod_id
join categories cat on p.category = cat.category
left outer join
(
 select o.orderid as oid,
 min(o.orderdate) over (partition by o.customerid) as min,
 max(o.orderdate) over (partition by o.customerid) as max
 from orders o
) as first_last on first_last.oid = o.orderid
order by customerid,orderlineid


Burada aklimiza ne geliyorsa onu siparise baglayarak tek satir olarak sunmaya calistik, bir suru ek kolon yarattik, mesela mevsim, haftanin gunu gibi. Bazi aciklamalar:

first_last adindaki alt sorgu, her musterinin "ilk ve en son siparis tarihini" almak icin kullanildi. Sonra bu tarih, customerid uzerinden dis sorgudaki siparise baglanacak, ve now() - __bu son tarih__ hesabi uzerinden atillik ortaya cikartilacak (not, bu ornekte simdi icin 2005-01-01 kullandik, gercek dunya verisi uzerinde now() olurdu.

per_customer_count musterinin tum siparislerini sayarak o musteriye ait her siparise bu toplami yazar.

rank() ile musterinin siparisleri siraya dizilir, ve 1,2,3,.. gibi bir sira sayisi bu siparislere verilir. Bu sira sayisi onemli olabilir, 1. sipariste olan olaylar, 2. siparisteki olanlardan ayirilabilir bu sekilde, mesela..

_freq ile biten kolonlar en ilginci: Ama ondan sonra kategorik (metinsel) veriyi regresyonda nasil kullanacagiz onu dusunelim:

Musterinin siparis ettigi film genre'sini (Aksiyon, Korku, Dram gibi -ki bunlar metinsel kategoriler-) biliyoruz. Peki bu verileri, bir sekilde, numerik hale cevirip kullanabilir miyiz? Ilk akla gelen cozum, her genre'ya rasgele bir sayi atamak. Fakat regresyon bu sayilarla ne yapacak? Regresyon icin 2'nin 1'den buyuk olmasinin bir anlami var, fakat tiplere rasgele sayi atadigimizda bu tur irdeleme sacma.

Cozum genre kolonunundaki mumkun her degeri bir ek kolon haline getirmek ve siparis hangi genre icinde tekabul eden kolon altina '1' degeri vermek, yoksa '0' degeri kullanmak. Yani kolon degerlerini "yana dogru acarak" ek kolonlar haline getirmek (iyi bir numaradir). Bu kodlama sekline literaturde 1-in-n, ya da 1-hot kodlamasi (encoding) ismi veriliyor. Bu durumda bu ek kolonun 1/0 degeri tasimasi anlamli, deger ya vardir, ya yoktur, ve regresyon, bu degerlerle is yapabilir.

Simdi _freq isine gelelim: kategorik veri uzerinde bir takla daha atmak mumkun. Mesela musterinin siparisleri soyle gidiyor: Aksiyon, Aksiyon, Dram, Aksiyon. En cok aksiyon seyrediliyor, ama bir ara drama geciliyor sonra geri donuluyor. Bu degisimi nasil yakalariz? Soyle - her genre icin alim frekansini hesaplariz, ve onu Postgres analitik fonksiyonu ile tum tekabul eden satirlara yayariz. Yani Aksiyon, Aksiyon, Dram, Aksiyon yerine 3,3,1,3 kullanilir. Kabaca bu soyle dis dunyaya gozukur: musteri en cok aldigi genre'yi ardi ardina iki kez almis, sonra cok az aldigi bir genre'ya gecmis, sonra geri donmus. Burada bir onemli bir bilgi olabilir - bu degisimin oldugu siparisteki diger bilgilerle birleserek belki regresyon bize yeni bir takim seyler sunabilir belki de. Bu teknikte de sayilarin buyuklukleri anlamli, en cok, en az gibi irdelemeler var ve bunlar veriyle uyumlu, en cok denen sey 3, en az denen 1, vs.

Bu teknik pek cok diger kategorik veri icin kullanilabilir, mesela musterinin o siparis icin kullandigi isletim sistemi, baglanti cihazi, kullandigi adres, kullandigi isim, vs.

Verinin satir sayisi hakkinda bir not:

orders (siparis) ile orderlines'i (siparis kalemleri / alt siparis) birlestirdigimiz icin eldeki veri sayisi orderlines ile ayni hale geldi, bu sebeple orders uzerindeki veriler alt siparis uzerinde tekrar etti. Bu birlesimi yapmak gerekti cunku ornek icin genre kategorisi alt siparise bagli bir bilgiydi. Bu veride tekrara sebep olsa da bu ornek icin fazla onemli degil.

Artik regresyon kullanabiliriz. R dilini kullanacagiz, bu dil kategorik verileri 1-in-n kodlamasina otomatik olarak ceviriyor. Egitim ve test setleri lazim, tum script soyle:

psql dellstore2 -h localhost -p 5432 -U postgres -c "COPY (`cat data.sql`) TO stdout with delimiter ',' CSV HEADER "  > dell.csv

head -1 dell.csv > dell2.csv
sed -n 2,30000p $HOME/dell.csv >> dell2.csv

head -1 dell.csv > dell-validate.csv
sed -n 30000,60000p dell.csv >> dell-validate.csv


Veri uretildikten sonra onu iki parcaya ayiriyoruz, dell2.csv egitim seti, dell-validate.csv test seti. head -1 kullaniminin sebebi ilk satirdaki kolon isimlerini almak. sed ile belli satir no'lari arasindaki satirlari cekip cikariyoruz. Eger rasgele satirlar cekip cikartmak istesek,

cat dell.csv | perl -n -e 'print if (rand() < .008)' >> dell-sample.csv

kullanabilirdik. Simdi R koduna gelelim:

Kod

Cikti soyle:

                          Estimate Std. Error  t value Pr(>|t|)   
(Intercept)              3.695e+02  1.910e+00  193.428  < 2e-16 ***
month                   -2.315e+01  9.398e-02 -246.384  < 2e-16 ***
netamount                5.027e+02  9.166e+01    5.484 4.17e-08 ***
genderM                  1.195e+00  4.835e-01    2.471  0.01348 * 
day                     -7.253e-01  2.733e-02  -26.538  < 2e-16 ***
day_of_week             -7.094e-02  1.207e-01   -0.588  0.55668   
totalamount             -4.644e+02  8.467e+01   -5.484 4.17e-08 ***
rank                     3.222e-01  7.645e-02    4.214 2.51e-05 ***
categorynameAnimation    2.181e-01  1.355e+00    0.161  0.87213   
categorynameChildren    -7.310e-01  1.364e+00   -0.536  0.59188   
categorynameClassics    -2.954e-01  1.353e+00   -0.218  0.82721   
categorynameComedy      -3.352e-01  1.365e+00   -0.246  0.80602   
categorynameDocumentary -1.131e+00  1.357e+00   -0.833  0.40477   
categorynameDrama        7.911e-01  1.389e+00    0.570  0.56888   
categorynameFamily      -1.221e+00  1.363e+00   -0.896  0.37007   
categorynameForeign     -8.789e-01  1.354e+00   -0.649  0.51636   
categorynameGames       -7.045e-01  1.368e+00   -0.515  0.60652   
categorynameHorror      -2.934e+00  1.386e+00   -2.117  0.03428 * 
categorynameMusic        8.873e-01  1.367e+00    0.649  0.51623   
categorynameNew          3.155e-01  1.377e+00    0.229  0.81872   
categorynameSci-Fi      -6.511e-01  1.376e+00   -0.473  0.63616   
categorynameSports      -1.550e+00  1.372e+00   -1.130  0.25856   
categorynameTravel      -1.273e+00  1.368e+00   -0.931  0.35187   
per_customer_count      -5.879e+00  1.023e-01  -57.456  < 2e-16 ***
total_total_amount       3.218e-04  3.876e-04    0.830  0.40640   
income                   1.244e-05  8.590e-06    1.448  0.14769   
seasonSPRING            -4.909e-02  8.853e-01   -0.055  0.95578   
seasonSUMMER             3.973e+00  7.396e-01    5.371 7.84e-08 ***
seasonWINTER            -1.032e+01  8.319e-01  -12.404  < 2e-16 ***
cat_freq                 2.047e-01  3.374e-01    0.607  0.54411   
creditcardtypec2        -2.199e+00  7.668e-01   -2.868  0.00414 **
creditcardtypec3        -1.874e+00  7.665e-01   -2.445  0.01449 * 
creditcardtypec4        -8.769e-01  7.713e-01   -1.137  0.25560   
creditcardtypec5        -9.416e-01  7.715e-01   -1.221  0.22228 
  

Bu sonucu nasil irdeleriz? Bildigimiz gibi regresyon cevap degiskenlerini (response variables) ilk basta bilinmeyen katsayilar ile carpip bu carpimlarin toplanarak hedefin hesaplandigini varsayan bir tekniktir. Eldeki veri kullanilarak bu carpma / toplama = hedef formuluna en cok "uyan" katsayilar hesaplanir. Ustteki cikti bize bu katsayilari vermektedir, mesela totalamount icin -4.644e+02 katsayisi verilmis, bu eksi yonde buyuk bir sayi, yani siparisin toplam fiyatindaki bir birimlik degisim, atillik uzerinde eksi yonde buyuk bir degisim getirir. Std Error kolonuna bakiyoruz, 8.467e+01 sayisi var. Bu bilgi soyle kullanilir, eger katsayi degerinin sifirdan uzakligi Std. Error'un iki katindan fazla ise katsayi istatistiki olarak anlamli  / degerli (significant) demektir ve kullanilabilir [2].

Ayrica, daha once bahsettigimiz gibi kategorik kolonlar, mesela mevsim (season), tasidigi degerlerle birlestirilerek yeni kolonlar haline geldi, mesela yaz icin seasonSUMMER var, kis icin seasonWINTER. Bu yapay kolonlar ustteki raporda tek basina gercek bir kolon olan mesela gun (day) ya da rank ile ayni seviyede verilmis.

Ciktinin sonlarinda su satir gorulur:

Residual standard error: 47.32

Bu deger regresyonun RMSE hatasidir [1], yani hedefin hesabina kabaca 47 gun yaklasilabilmistir. Yani 20 gun atillik tahmini yapildigi zaman, belki gercek hesap aslinda 67. Daha az da olabilir, fazla da (ya da tam hedef tutturulabilir).

Not: RMSE bu tur problemlerde uygun olmayabilir. Netflix verisi icin regresyon hedefi 1-5 arasi degismeyen bir sayiydi, orada daha uygun; atillik rakami ust siniri olmayan bir hedef degiskeni. Diger bir hata hesabi, hatalarin tam degerlerinin (absolute value) ortalamasini dondurur. Bu sekilde hesaplaninca sonuc 36 cikacaktir.

Peki bu atillik hesabi yeterli midir? Burada sirketteki karar vericileri dusunur, eger bu hata payi iyi, yeterli bulunmazsa alternatiflere bakilir. Veri madenciligi acisindan farkli teknikler kullanilabilir. Mesela yapay sinir aglari (neural net). Bu arada, ustteki rakamlarin uretilmis veriden geldigini unutmayalim, yontemin basarisini irdelemek icin gercek dunya verisine bakmak daha iyi olacaktir.

YSA

R ile kurmak icin install.packages("nnet") 

Kod

YSA girdileri bir ara katman uzerinden ciktiya baglar, egitilmesi backprop denen iteratif bir algoritma iledir. YSA ve nnet kullanirken bilinmesi iyi olacak bazi puf noktalari: Her iterasyon / dongu (epoch) YSA'nin hatasini azaltmali. Her dongude bu sayi ekrana basilir, eger hic azalma olmadan dongu pat diye biterse (YSA tamam oldu dese de), aslinda hicbir sey yapilmamistir. Bu durumda decay parametresi ile oynamaya baslamak gerekir. Bu parametrenin ne olacagi hedef olarak hesaplanan seyin buyuklugune oranla dusunulebilir, eger hedef 100'lu, 200'lu bir sayi ise, decay, yani her dongude uygulanan azalmanin (bu konunun detaylari icin bir YSA kitabina danisabilirsiniz), 1 ve 2 civarinda olmasi mantikli olabilir. Eger 0.5, 0.6 gibi bir hedef var ise, decay belki 0.01 olmalidir, vs. Bu sayi deneme yanilmayla bulunabilir. Fakat onemli olan dongunun en az birkac kez "donmesi" ve hata sayisinda azalma gorebilmemiz.

Ustteki YSA isletimi ortala hata olarak 53 sayisini dondurdu.

GLM

Regresyon yapmanin bir yolu daha, genel lineer modeller (generalized linear models - GLM). Bu modellerde regresyondaki katsayilar ve onlarin carptigi ogeler toplanarak bir "baglanti fonksiyonuna (link function)" gecilir, ve hedef degiskeni carpimlarin toplami degil bu suzulmus yeni degerdir. R dilinde GLM kullanmak icin mesela

model <- family="gaussian(link=" formula="..." glm="glm" log="log" nbsp="nbsp" span="span">


Burada link fonksiyonu Gaussian uzerinden log, yani hedef degiskeninin log'u alinmis hali islenecek. Konunun detaylari icin R dokumanlarina bakilabilir.

Dikkat: onemli bir konu su, bazen normal regresyon lm'e log'u alinmis hedef degiskenlerin verildigini gorebilirsiniz, bu durum ustteki durumdan farklidir, glm log icin disaridan bir log islemine gerek yok, hedef degiskenini oldugu gibi verirsiniz, ve iceride o islem yapilir. Link fonksiyonlarinin varligi GLM cozum matematigini etkilemektedir - bir link fonksiyonunun olacagi bilindigi icin cozum icin buna gore taktikler izlenir; lm durumunda degiskenler bazi filtrelerden geciriliyor olsa bile metotun kendisinin bu degisimlerden haberi olmayacagi icin farkli sonuclar ortaya cikabilir.

GLM durumunda link log olunca, predict ile verilen degerler de log'lu geri gelecektir, onlari normal sayiya dondurmek icin exp (log'un tersi) uygulamak gerekir.

Kod

Ustteki kodun ortalama hatasi 19 gun.

----

[1] Hata hesabini R lm() egitim verisi uzerinde yapti, ve bu hesap RMSE hesabidir, yani hatalarin karesinin toplaminin karekokunun veri sayisina bolunmesiyle elde edilir. RMSE hesabi cogunlukla egitim sonrasi egitilmis model kullanilarak test verisi uzerinde uygulanir.

[2] Tabii burada biraz daha ek detay var; mesela kisilerin arabalarinin beygir gucunu kazandiklari maasa baglayan bir regresyon, beygir gucu katsayisi icin beygir basina $10  ve std. hata $2 vermisse bu istatistiki olarak onemli, ama pratikte onemsizdir. Benzer sekilde eger beygir katsayisi icin $10,000 ve std. hata $10,000 bulmussak, bu istatistiki olarak onemsiz, ama pratikte onemlidir. Yani R lm() sonuclarini rapor ettikten sonra bu ek irdelemeleri de akilda tutmak gerekir.

Thursday, October 18, 2012

Zaman Kolonlari Arasindaki Farki Gun Olarak Gostermek

Postgresql tabaninda timestamp tipindeki iki tarih (kolonu) arasindaki farki hemen eksi (-) isareti kullanarak hesaplamak mumkundur. Bu yapildigi zaman sonuc gayet detayli bir sekilde 'su kadar yil, su kadar gun, .. ' gibi bir tanimi iceren bir sonuctur.  Yani en basit ornek soyle:

select tarih1::timestamp - tarih2::timestamp from ..

Eger zamanlar arasindaki farki tek bir sayiya indirgemek istiyorsak, o zaman farki epoch (saniye) tipine, ve oradan dakika, saat, vs gibi bolum yaparak istedigimiz sayiya cevirmemiz gerekli. Mesela gun istiyorsak,

select cast(extract('epoch' from tarih1::timestamp - tarih2::timestamp) as numeric) / 60 / 60 / 24 
from ..

Thursday, October 4, 2012

Bir Vektorun Kismi Toplamini Almak

Diyelim ki bir Numpy vektorunun tum elemanlarini degil, ucer ucer bloklar halinde toplamak istiyoruz. Kullanilacak komut add.reduceat komutu.

import numpy as np

a = np.array([1,2,3,4,5,6])
print np.add.reduceat(a,[0,3])


[ 6 15]

sonucunu verir. Yani sifirinci ve ucuncu indis arasindaki bir toplam, ucuncu ve vektor sonuna kadar olan bolum baska bir toplam haline geldi. Geri dondurulen sonuc her zaman verilen indis matrisi ile esit olacaktir.

Wednesday, September 26, 2012

Postgresql ile Yuzdelik (Percentile) Hesabi

Eger bir olcutun dagilimi tek tepeli ve simetrik degilse, ortalama (mean) ve standart sapma (std deviation) bize uc noktalar (outliers) ve hakiki ortalama degerler hakkinda iyi sonuclar vermeyebilir. Bu durumlarda yuzdelikler (percentile) hesabi daha iyidir, ki medyan kavrami burada devreye girer, medyan 50. yuzdeliktir.

Postgresql ile bu hesabi yapmak icin, mesela dellstore2 verisinde

select totalamount, ntile(20) over (order by totalamount) as cume from orders

kullanilabilir. Bu ilk basamak, PG analitik ntile .. over komutunu kullandi. Bu komut tum satirlari totalamount'a gore siralayarak onlari 20 yuzdelikten birine atayacak.

Eger mesela 95. yuzdeligin en buyuk degerini istersek (ki mesela bu degeri bir uc nokta olarak kabul etmeyi secebiliriz, ve bu degerden buyuk her degeri gurultu, asiri buyuk deger, vs. gibi kabul edebiliriz), o zaman

select max(totalamount) AS max_var from
(
  select totalamount, ntile(20) over (order by totalamount) as cume from orders
) as tmp where cume = 19


kullanilabilir. Ustteki sorgu 410.41 dondurur. Eger "ortalamadan iki standart sapma uzagi" hesabini yaparsak (ki bu hesabinda uc nokta hesabi oldugu kabul edilir), o zaman

select avg(totalamount)+2*stddev(totalamount) from orders

ve

464.19

degeri gelecek. Goruldugu gibi arada buyuk fark var.



Monday, September 17, 2012

SVD ile Kumeleme

Wednesday, September 5, 2012

Postgis ve Mesafe Hesabi

Enlem ve boylam iceren iki kordinate arasindaki mesafeyi Postgis'e nasil hesaplattiririz? Diyelim ki enlem (latitude) ve boylam (longitude) numerik bazli iki ayri kolonda duruyor. Bu durumda bu iki kolonu alip onu PG'in anlayabilecegi bir kordinat formatina cevirmek lazim, sonra st_distance ile mesafe hesabi yapmak.

select ...,
st_distance(GeomFromEWKT('SRID=4326;POINT(' || lat1 || ' ' || lng1 || ')'),
            GeomFromEWKT('SRID=4326;POINT(' || lat2 || ' ' || lng2 || ')'))

from tablo ...

Sonuc kilometre olarak gelecek. Konu hakkinda bazi hizli bilgiler: kordinatlardan en azindan kuzey yarimkure icin 40'li, 50'li olan sayi enlem (latitude) icindir. Ingilizce olan kelimeyi hatirlamanin bir yolu "lower your latitude to change your attitude (guneye gittikce havanin sicaklasmasindan hareketle)". Neyse -  eger bir kordinati map.google.com uzerinde hemen kontrol etmek isterseniz, oraya boylam, enlem sirasinda girmek gerekiyor. 


Monday, September 3, 2012

Basit Web Sunucusu - SimpleHTTPServer

Eger hizli bir sekilde, acil ihtiyaclar icin bir Web sunucusu baslatmak isterseniz, SimpleHTTPServer bu is icin bicilmis kaftan. Sadece su satirlar ile herhangi bir dizindeki dosyalar servis edilebilir. Mesela..

import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

HandlerClass = SimpleHTTPRequestHandler
ServerClass  = BaseHTTPServer.HTTPServer
Protocol     = "HTTP/1.0"

if sys.argv[1:]:
    port = int(sys.argv[1])
else:
    port = 8080
server_address = ('[IP ADRESI]', port)

HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass)

sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
httpd.serve_forever()
 

Bu kadar. Olagan port degeri 8080, ama istenilen baska bir port numarasi arguman olarak gecilebilir. Eger bu script'i baslattigimiz dizinde mesela bir index.html var ise, aynen normal Web sunucularinin yaptigi gibi o dizin ziyaret edilir edilmez otomatik olarak servis edilecektir.

Bir puf nokta: ustteki script, komut satirindan baslatildiktan sonra, bunu yapan Unix kullanicisinin sistem disina cikmasi (logout) olayina hassas, o yuzden python ibaresinin basina nohup komutunun eklenmesi lazim.

Biz yukaridaki script'i bir ana siteyi bakima aldigimizda (ki site kendine has apayri baska bir Web altyapisi kullaniyor) hizli bir sekilde "simdi mesguluz sonra gelin" mesajini gostermek icin kullaniyoruz. Ana sitenin ayni IP ve port numarasi uzerinden hemen bir SimpleHTTPServer baslatiyoruz, ve ana siteye gelen kullanicilar bu basit sunucunun servis ettigi mesaji goruyorlar.

Thursday, August 23, 2012

Zaman Serisi Tahmini (Forecasting), R, VAR, rpy2

Zaman serisi modellemesinde VAR modelleri bugunlerde en populer olanlari. VAR, vector autoregression kelimelerinden geliyor, yani tek bir zaman serisi degil, birkac tanesine birden, ayni anda modellemeye ugrasiyoruz.

Autregression, zaman serisinin kendi kendisiyle regresyona sokulmasidir; bilindigi gibi regresyon y = f(x) modellemesinde gurultulu elde edilen y ile, x degerleri arasindaki baglantinin bulunmasina yardim eder (eger f(x) lineer ise iyi sonuclar da bulur). Tek boyutlu zaman serisi modellemesi icin soyle bir numara kullanilir, serinin kopyasi alinir, bir geri kaydirilir, x bu kaydilirilmis seri, y esas seri olur, bu ikili regresyona sokulur. Boylece zaman serisinin kendisini ve regresyon mekanizmasi kullanilarak zaman serisi tahmini yapilabilir.

VAR ise bunu cok boyutlu yapar. Her seriyi hem kendisi, hem de diger tum serilerin p kadar gecmis degeri goz onune alinir. Oldukca guclu bir metottur.

Bu alanda unlu isimlerden Sims'i bilmek gerekir, 1980 yilinda yazdigi ve kendi alanini elestirdigi bir makalede makroekonomide yapisal modeller yerine, ciplak veriye bakmak gerektigini, ve bunu yapmak icin her zaman serilerine tek baslarina degil tum diger serilere de baglantilarini goz onune alarak incelemek gerektigini soyler. VAR matematigi buradan cikmistir. Granger ismi de vardir, VAR modellemesi sonrasi serilerin "birbirine ne kadar etki ettigini" hesaplayan "Granger istatistigi" mesela ona aittir.

Isin matematigine sonra daha detayli girebiliriz, simdilik kodlama acisindan ornekleri verelim. Bu alanda R kodculari cok aktif, o yuzden bir R paketi vars kullanacagiz, ve onu Python uzerinden cagiracagiz.

Diyelim ki bir predict-1.csv icinde bir ulkenin GDP ve tuketim verileri (cons) var, 1959-2009 arasi icin (bu oldukca standart bir veri seti). Once R kurulur

sudo apt-get install r-base-dev r-base python-rpy2

Sonra R'ye girilir

> install.packages("vars")

Simdi su R kodu kullanilabilir

library("vars")

file = "predict-1.csv"
a <- read.csv(file, header = TRUE, sep = ",", na.strings="")

impute.med <- function(x) {
    z <- median(x, na.rm = TRUE)
    x[is.na(x)] <- z
    return(x)
}

a2 <- sapply(a, function(x){
    if(is.numeric(x) & any(is.na(x))){
            impute.med(x)
        } else {
            x
        }
    }
)

out <- VAR(a2, p = 2, type = "const")
out.prd <- predict(out, n.ahead = 30, ci = 0.95)


Bunu Python'dan cagirmak icin rpy2 kullaniriz,

import os, sys
import numpy as np
import rpy2.robjects
from datetime import date, timedelta

f = file("predict.R")
code = ''.join(f.readlines())
result = rpy2.robjects.r(code)
res = [['gdp','cons']]
for i in range(30):
    res.append([str(result[0][0][i]),str(result[0][1][i]) ] )

res = np.array(res)
np.savetxt('predict-2.csv',res,delimiter=",",fmt='%s')


Python isledikten sonra sonuc predict-2.csv icinde olacak. Sonuclar 2009 sonrasi 30 sene sonrasi icin gdp ve tuketim rakamlarini tahmin edecek.

Eger pur Python kullanmak isteseydik, scikits statsmodels adinda bir paketi de kullanabilirdik. Bu durumda hic R kodlamasi olmayacak, kurmak icin

https://github.com/statsmodels/statsmodels

Bu kod

import os
import numpy as np
import statsmodels.api as sm
from statsmodels.tsa.api import VAR
 
def pad(data):
    bad_indexes = np.isnan(data)
    good_indexes = np.logical_not(bad_indexes)
    good_data = data[good_indexes]
    interpolated = np.interp(bad_indexes.nonzero()[0], good_indexes.nonzero()[0], good_data)
    data[bad_indexes] = interpolated
    return data

data = np.genfromtxt("predict-1.csv", skip_header=1, delimiter=',')
data = np.apply_along_axis(pad, 0, data)
model = VAR(data)
res = model.fit(2)

f = res.forecast(data[-2:], 30)
np.savetxt('predict-3.csv',f,delimiter=",",fmt='%s')


Ustteki kod sonuclar predict-3.csv icine yazar.

VAR ile zaman serisi tahminlerinde onemli bazi konular incelenen verinin (zaman serisinin) duragan (stationary), ve beraber entegre (co-integrated) olup olmadigidir -- bu durumlarda bazi ek numaralar kullanmak gerekebilir, mesela duragan bir veri seti yoksa serinin farklarini kullanmak gibi..

Ana veri

gdp,cons
2710.349,1707.4
2778.801,1733.7
2775.488,1751.8
2785.204,1753.7
2847.699,1770.5
2834.390,1792.9
2839.022,1785.8
2802.616,1788.2
2819.264,1787.7
2872.005,1814.3
2918.419,1823.1
2977.830,1859.6
3031.241,1879.4
3064.709,1902.5
3093.047,1917.9
3100.563,1945.1
3141.087,1958.2
3180.447,1976.9
3240.332,2003.8
3264.967,2020.6
3338.246,2060.5
3376.587,2096.7
3422.469,2135.2
3431.957,2141.2
3516.251,2188.8
3563.960,2213.0
3636.285,2251.0
3724.014,2314.3
3815.423,2348.5
3828.124,2354.5
3853.301,2381.5
3884.520,2391.4
3918.740,2405.3
3919.556,2438.1
3950.826,2450.6
3980.970,2465.7
4063.013,2524.6
4131.998,2563.3
4160.267,2611.5
4178.293,2623.5
4244.100,2652.9
4256.460,2669.8
4283.378,2682.7
4263.261,2704.1
4256.573,2720.7
4264.289,2733.2
4302.259,2757.1
4256.637,2749.6
4374.016,2802.2
4398.829,2827.9
4433.943,2850.4
4446.264,2897.8
4525.769,2936.5
4633.101,2992.6
4677.503,3038.8
4754.546,3110.1
4876.166,3167.0
4932.571,3165.4
4906.252,3176.7
4953.050,3167.4
4909.617,3139.7
4922.188,3150.6
4873.520,3163.6
4854.340,3117.3
4795.295,3143.4
4831.942,3195.8
4913.328,3241.4
4977.511,3275.7
5090.663,3341.2
5128.947,3371.8
5154.072,3407.5
5191.499,3451.8
5251.762,3491.3
5356.131,3510.6
5451.921,3544.1
5450.793,3597.5
5469.405,3618.5
5684.569,3695.9
5740.300,3711.4
5816.222,3741.3
5825.949,3760.2
5831.418,3758.0
5873.335,3794.9
5889.495,3805.0
5908.467,3798.4
5787.373,3712.2
5776.617,3752.0
5883.460,3802.0
6005.717,3822.8
5957.795,3822.8
6030.184,3838.3
5955.062,3809.3
5857.333,3833.9
5889.074,3847.7
5866.370,3877.2
5871.001,3947.9
5944.020,3986.6
6077.619,4065.7
6197.468,4137.6
6325.574,4203.2
6448.264,4239.2
6559.594,4299.9
6623.343,4333.0
6677.264,4390.1
6740.275,4464.6
6797.344,4505.2
6903.523,4590.8
6955.918,4600.9
7022.757,4639.3
7050.969,4688.7
7118.950,4770.7
7153.359,4799.4
7193.019,4792.1
7269.510,4856.3
7332.558,4910.4
7458.022,4922.2
7496.600,5004.4
7592.881,5040.8
7632.082,5080.6
7733.991,5140.4
7806.603,5159.3
7865.016,5182.4
7927.393,5236.1
7944.697,5261.7
8027.693,5303.3
8059.598,5320.8
8059.476,5341.0
7988.864,5299.5
7950.164,5284.4
8003.822,5324.7
8037.538,5345.0
8069.046,5342.6
8157.616,5434.5
8244.294,5466.7
8329.361,5527.1
8417.016,5594.6
8432.485,5617.2
8486.435,5671.1
8531.108,5732.7
8643.769,5783.7
8727.919,5848.1
8847.303,5891.5
8904.289,5938.7
9003.180,5997.3
9025.267,6004.3
9044.668,6053.5
9120.684,6107.6
9184.275,6150.6
9247.188,6206.9
9407.052,6277.1
9488.879,6314.6
9592.458,6366.1
9666.235,6430.2
9809.551,6456.2
9932.672,6566.0
10008.874,6641.1
10103.425,6707.2
10194.277,6822.6
10328.787,6913.1
10507.575,7019.1
10601.179,7088.3
10684.049,7199.9
10819.914,7286.4
11014.254,7389.2
11043.044,7501.3
11258.454,7571.8
11267.867,7645.9
11334.544,7713.5
11297.171,7744.3
11371.251,7773.5
11340.075,7807.7
11380.128,7930.0
11477.868,7957.3
11538.770,7997.8
11596.430,8052.0
11598.824,8080.6
11645.819,8122.3
11738.706,8197.8
11935.461,8312.1
12042.817,8358.0
12127.623,8437.6
12213.818,8483.2
12303.533,8555.8
12410.282,8654.2
12534.113,8719.0
12587.535,8802.9
12683.153,8865.6
12748.699,8888.5
12915.938,8986.6
12962.462,9035.0
12965.916,9090.7
13060.679,9181.6
13099.901,9265.1
13203.977,9291.5
13321.109,9335.6
13391.249,9363.6
13366.865,9349.6
13415.266,9351.0
13324.600,9267.7
13141.920,9195.3
12925.410,9209.2
12901.504,9189.0
12990.341,9256.0




Wednesday, August 22, 2012

Kolon Degerleri Arasinda Harfleme (Spelling) Hata Farki Var mi?

Diyelim ki bir adres kolonundaki (cadde, numara, apartman) degerleri girilirken hata yapilip yapilmadigini kontrol etmek istiyorsunuz. Acaba tabanda birbirine benzeyen ve arasinda sadece harfleme hatasi kadar fark olan iki adres var mi? Kontrol etmek icin onceki yazida gordugumuz levenshtein uzakligini kullanabiliriz. Isin guzel tarafi bu fonksiyonu direk Postgresql icinden kullanabiliriz.

Aktive etmek icin, tabana baglanin ve

# CREATE EXTENSION fuzzystrmatch;

Test etmek icin

# select levenshtein('elma','alma');

Sonuc

 levenshtein
-------------
           1
(1 row)

Yani elma ve alma arasindaki fark 1 'degisimdir'. Levenshtein uzakligi her turlu degisime bakar, harf eklemek, silmek gibi operasyonlar hep uzakligi arttirir.

Sorguya donelim. Once ilgilendigimiz kolonu ve onun tablosunu kendisiyle birlestiririz (join), yani tum adresleri tum diger adreslerle yanyana getirmeye ugrasiyoruz, bunu yapmanin en kolay yolu da SQL'deki join operasyonudur. Bilindigi gibi iliskisel teoride join bir kartezyen birlesimidir, iki tablo birlestirilince her satir, her diger satirla yanyana gelmis olur, yani tum mumkun kombinasyonlari elde ederiz. Yeni ANSI SQL icinde bunu ozellikle belirtmek gerekiyor, bunun icin cross join adli komut var.

select adres, sub1.adres
from tablo
cross join (
 select adres from tablo
 ...
) as sub1
where levenshtein(adres, sub1.adres) between 1 and 3
...


Bu komutla arasinda 1 ila 3 fark olan adresleri bulmus olacagiz. 0 uzakligi kullanmadik, bu iki adresin ayni olmasi demek olurdu. Onlarla ilgilenmiyoruz. 3'ten fazla uzaklik ise herhalde o adresin hakikaten degisik bir fiziki adres oldugu anlamina gelirdi. 

Matriste Bos Degerleri Yakin Degerle Doldurmak (Interpolation)

Eger icinde nan yani "tanimsiz" ve "bos" degerler olan bir vektorumuz var ise, bu tanimsiz degerlerin yerine, yine ayni vektorde, ve o bos degerin iki yanindaki degere yakin olan bir degerle doldurmak isteyebiliriz.

Mesela vektor

1, nan, nan, 2, 2, nan, 0

olsun, ve nan diyen yerlerde 1 ve 2 arasi, sonraki nan yerine 2 ve 0 arasi degerler olmali.

data = np.array([1, nan, nan, 2, 2, nan, 0])
print data

bad_indexes = np.isnan(data)
good_indexes = np.logical_not(bad_indexes)
good_data = data[good_indexes]
interpolated = np.interp(bad_indexes.nonzero()[0], good_indexes.nonzero()[0], good_data)

data[bad_indexes] = interpolated

print data


Sonuc

[ 1.          1.33333333  1.66666667  2.     2.     1.        0.    ]

Peki islemi bir matris uzerinde, ve her kolon icin ayri ayri yapmak istersek?

def pad(data):
    bad_indexes = np.isnan(data)
    good_indexes = np.logical_not(bad_indexes)
    good_data = data[good_indexes]
    interpolated = np.interp(bad_indexes.nonzero()[0], good_indexes.nonzero()[0], good_data)
    data[bad_indexes] = interpolated
    return data

A = np.array([[1, 20, 300],
              [nan, nan, nan],
              [3, 40, 500]])

A = np.apply_along_axis(pad, 0, A)


Sonuc

[[   1.   20.  300.]
 [   2.   30.  400.]
 [   3.   40.  500.]]


Kaynak

Tuesday, August 14, 2012

OpenCV 2.4.1 Hareket Vektorleri, Kenarlar

OpenCV 2.4.1'de guzel gelismeler var; demo kodlari daha temiz. Mesela samples/python2/opt_flow.py kodu alttaki goruntuyu verir, ikinci resim edge.py orneginden. Bu kodlar, cagrilar ve onlarin geri dondurdugu veriler biraraya konarak ilginc uygulamalar gerceklestirilebilir. Mesela ilk cikti biz kafayi yana kaydirinca o hareketin vektorlerini hesapladi. Ikinci resim her karede hizli bir sekilde kenar hesaplamasi yapiyor. Bunlar biraraya konarak algilayici birlestirimi (sensor fusion) ile ekranda hareketin tetikledigi / onu baz alan obje tanimlamasi, takibi gerceklestirilebilir. Hareket vektorleri ekranda sadece belli bir bolgede var, yine ayni bolgeler icin ikinci algilayicidan kenar bilgileri geliyor...




Monday, August 13, 2012

Gaussian Dagilimi, Contour Plot

3 boyutlu Gaussian dagilimi yukaridan cevrit (contour) olarak cizebilen kod parcasi.

# Multivariate gaussian, contours
#
import scipy.stats
import numpy as np
import matplotlib.pyplot as plt

def norm_pdf(b,mean,cov):
   k = b.shape[0]
   part1 = np.exp(-0.5*k*np.log(2*np.pi))
   part2 = np.power(np.linalg.det(cov),-0.5)
   dev = b-mean
   part3 = np.exp(-0.5*np.dot(np.dot(dev.transpose(),np.linalg.inv(cov)),dev))
   dmvnorm = part1*part2*part3
   return dmvnorm

x = np.arange(55., 80., 1)
y = np.arange(80., 280., 1)
X, Y = np.meshgrid(x, y)

Z = np.zeros(X.shape)
nx, ny = X.shape
mu = np.array([  65.89350086,  193.21741426])
sigma = np.matrix([[    7.84711283,    25.03111826],
                    [   25.03111826,  1339.70289046]])
for i in xrange(nx):
    for j in xrange(ny):
        Z[i,j] = norm_pdf(np.array([X[i,j], Y[i,j]]),mu,sigma)
       
levels = np.linspace(Z.min(), Z.max(), 10)
plt.contour(X, Y, Z, colors='b', levels=levels)
plt.show()



Friday, August 10, 2012

OpenCV 2.4

Ubuntu 12.04 LTS icin en son OpenCV kurulusu.

http://www.samontab.com/web/2012/06/installing-opencv-2-4-1-ubuntu-12-04-lts/

Basit "resim cekmek" icin (t tusuna basilinca ekran goruntusu diske jpg olarak yazilir),

import cv

class Capture:
   
    def save(self, pic):
        cv.SaveImage('deneme' + str(self.i) + '.jpg', pic)
   
    def __init__(self):
        self.i = 1
        self.capture = cv.CaptureFromCAM(0)
        cv.NamedWindow( "CamShiftDemo", 1 )

        print( "Keys:\n"
            "    ESC - quit the program\n"
            "    t - take picture\n"
            "To initialize tracking, drag across the object with the mouse\n" )


    def run(self):
        while True:
            frame = cv.QueryFrame( self.capture )
            cv.ShowImage( "CamShiftDemo", frame )

            c = cv.WaitKey(7)
            if c == 27:
                break
            elif c == ord("t"):
                frame = cv.QueryFrame( self.capture )
                self.save(frame)
                self.i += 1

if __name__=="__main__":
    demo = Capture()
    demo.run()


Video kaydetmek icin

import cv
import cv2

class Capture:
   
    def __init__(self):
        self.capture = cv.CaptureFromCAM(0)
        cv.NamedWindow( "CamShiftDemo", 1 )

        print( "Keys:\n"
            "    ESC - quit the program\n"
            "    t - take picture\n"
            "To initialize tracking, drag across the object with the mouse\n" )

    def run(self):
        fps =  30
        frame = cv.QueryFrame( self.capture )
        frame_size = cv.GetSize (frame)
        writer=cv.CreateVideoWriter('movie.avi',cv2.cv.CV_FOURCC('F', 'M', 'P', '4'),fps,frame_size)
        while True:
            frame = cv.QueryFrame( self.capture )
            cv.ShowImage( "CamShiftDemo", frame )
            c = cv.WaitKey(7)
            cv.WriteFrame(writer,frame)
            if c == 27:
                break
           
        cv.ReleaseVideoWriter (writer)
 
if __name__=="__main__":
    demo = Capture()
    demo.run()

Thursday, August 9, 2012

Klavye Tusunu Mouse Tiklamasi Haline Getirmek

Diyelim ki bazi makinalarda olan "Windows" dugmesine (ya da herhangi bir dugmeye) baska bir is yaptirmak istiyoruz, mesela bu tusa basinca sol mouse tiklamasi olmasini istiyoruz. xmodmap bu tur degisimleri cok rahat yapar.

Once tusun kodu lazim; xev programini baslatin, ve tusa basin, konsolda kodu gozukecek. Diyelim ki kod 133, o zaman soyle bir script yazilir (diger kodlari da ogrendikten sonra)

xmodmap -e "keycode 133 = Pointer_Button1"
xmodmap -e "keycode 108 = Pointer_Button1"
xmodmap -e "keycode 135 = Pointer_Button3"
xkbset m


Bu script'i kaydedelim, ve Applications | System Tools | Preferences | Startup Applications'a giderek bilgisayar her basladiginda isletilmesini istedigimizi belirtelim, sh /dizin/ismi/script.sh gibi mesela, bunu ekleyelim. Artik bilgisayar her basladiginda windows tusu mouse tiklamasi yapabilecek.

Ek bir puruz, sistem uykudan (suspend) uyandiktan sonra ortaya cikiyor - ustteki ayarlar kayboluyor. Bu ayarlarin uyanma sonrasi islemesi icin, mesela  /etc/pm/sleep.d/99_remap adinda bir dosyayi sudo ile yaratin, uzerinde chmod +x yapin, ve icine

#!/bin/sh
case "$1" in
        thaw|resume)
                DISPLAY=:0.0 ; export DISPLAY
                su - [KULLANICI] -c /dizin/ismi/script.sh
                ;;
esac


komutlarini yazin, [KULLANICI] sizin Unix kullanici isminiz olacak. Ayrica script.sh dosyasini u+x ile chmod'lamayi unutmayin.

Kaynak

Tabanlar Arasi Buyuk Veri Transferi, pg_dump

Bir projemiz icin birkac tabanin icindeki (ayni semaya sahip) tablolarin icerigini nihai, bir baska taban icinde birbirine ekleyerek yeni, birlesmis tablolar olarak yaratmamiz gerekti. Bunun icin basta dblink kullandik fakat hafiza kullanimiyla alakali bazi hatalar ortaya cikti.

Biz de dblink yerine pg_dump kullanmaya karar verdik.

Diyelim ki taban1,taban2,taban3 icinde her tabanda ayni semaya sahip tablo1,tablo2 var. Script soyle:

TABLES="-t tablo1 -t tablo2"

pg_dump $TABLES -f /tmp/xfer.db -c taban1
psql -f /tmp/xfer.db sonuc
pg_dump $TABLES -f /tmp/xfer.db -a taban2
psql -f /tmp/xfer.db sonuc
pg_dump $TABLES -f /tmp/xfer.db -a taban3
psql -f /tmp/xfer.db sonuc

Dikkat edelim, ilk pg_dump -c ile veri aliyor, mevcut tablolari silecek komutlari da urettiriyoruz boylece. Daha sonraki pg_dump komutlari sadece veriyi aliyor, -a ile. Yani ilk basta tablolari, semasi ile yaratip ilk veriyi ekliyoruz, sonra sadece veri ekliyoruz. Boylece birlestirme islemini otomatik olarak gerceklestirmis oluyoruz. Surekli ayni veri dosyasini kullandik, xfer.db adinda, yer israfi olmamasi icin.

pg_dump kullaniminin bir avantaji daha var. Uretilen xfer.db icine bakarsaniz, set komutlari ve analyze ibarelerini goreceksiniz. Postgresql analyze komutu bir tabanin "ic istatistiklerini" guncellemeye yarar, boylece sorgulayici daha guncel veriye sahip olur. Ozellikle buyuk veri transferlerinden sonra bunun yapilmasi tavsiye edilir. Eh pg_dump bunu kendiliginden yapiyor iste.

Sunday, August 5, 2012

Ubuntu 12.04 LTS ve Acer Aspire S3

Acer Aspire S3 laptop uzerinde Ubuntu 12.04 LTS kullanmaya basladik.

Bu laptop 250 GB boyutunda solid state disk'e sahip. Solid state teknolojisi ucucu bellek (RAM) teknolojisini sabit diskler icin kullanan bir teknolojidir, eskiden pahaliydi, son zamanlarda dizustu bilgisayarlarda gorulmeye basladi. Bazi yorumlara gore solid state disk erisimi normal disklere oranla 10 kat daha hizlidir. SS manyetik disk olmadigi icin oynayan bir okuyucu kafaya ihtiyaci yok, hata payi daha az. Manyetik diskler olmadigi icin daha hafif. Mekanik islem olmadigi icin ayrica daha az isiniyor. Her bakimdan tercih edilebilecek bir teknoloji.

Solid state disk'e sahip bir dizustu bilgisayarlarin etiketinde satildiklari dukkanlarda "SSD" ibaresi kullanilir genelde. Acer Aspire'in parakende fiyati 1000 EUR'luk alet Internet erisim paketi eklenince daha ucuza 500 EUR'a dusuyor (Berlin Saturn fiyati).

Ubuntu kurulusuna donelim: Kurmak icin USB flash disk / stick kullandik, artik cogu laptop CD okuyucu dahil etmiyor. Aslinda boylesi daha iyi, CD okuyucu kurulus haricinde baska bir ise yaramiyordu zaten, fakat USB disk pek cok baska is icin de kullanilabilir.

Bilgisayari alinca Windows ile gelecek, tabii onu bir USB boot edilebilir Ubuntu diski yaratmak haricinde baska bir sey icin kullanmayacagiz, hemen silinecek [2] (baska bir Ubuntu uzerinden USB'ye iso yakmak icin suraya bakilabilir). Once gerekli iso dosyasini indirin (Aspire'in 64 bit kullanan bir makina oldugunu unutmayalim, 32 bit versiyonu degil 64'u indirin). Simdi hem USB'den direk kullanilabilir bir Ubuntu 12 yaratacak hem de istenildigi zaman Ubuntu'nun sabit diskinize yazilmasini saglayacak. Not: USB'den Ubuntu yuklemek icin BIOS'unuzda araclarin "yuklenis sirasini" degistirmeyi unutmayin. Cogunlukla ilk sirada sabit disk olur, siz bunu degistirerek USB'yi en tepeye gonderin. Windows ile USB yaratmak icin

http://www.pendrivelinux.com/universal-usb-installer-easy-as-1-2-3/

Ozellikler

Acer Aspire uzerinde Ubuntu 12, touchpad uzerinde tek dokunus (tap) sol fare dugmesi, iki parmak ile dokunus sag fare dugmesi tiklamasi anlamina geliyor.

Programlar

Ubuntu hala Unity denen absurt bir GUI yapisinda israr ediyor. O yuzden sisteme girer girmez

apt-get install gnome-shell

Logout edip tekrar girmeden once kullanici isminin girildigi kutunun ustundeki tekerlek resmine tiklanir, ve Gnome Classic (No Effects) secilir. Bu bizi klasik Gnome masaustune goturur ve rahat nefes alinir.

Eger ust sag kosedeki mail ikonunu yoketmek istiyorsak

sudo apt-get remove indicator-messages

Eger gnome panelden ikon silmek istiyorsak, Alt Super + sag mouse tiklamasi yapilir ve "Remove from Panel" secilir. Ya da $HOME/.config/gnome-panel altinda ikona tekabul eden dosya silinir.

Emacs uzerinde Alt-Space cok kullaniyoruz, fakat bu kombinasyon Ubuntu tarafindan "kapilmis". Bu kombinasyonu Ubuntu seviyesinde iptal etmek icin System Tools | System Settings | Keyboard ve Shortcuts | Windows bolumunde "Activate the window menu" icin Alt+Space secilmis, bu satira gidip cift tiklama yapin ve Silme (backspace) dugmesine basin.

Dil seciminde bazi hatalar var. Her ne kadar ne zaman sorulsa English US secsek te, birden bire en ust sol kosedeki Applications diyen yer ve Firefox ikonu (her nedense bunlar) bir Uzakdogu diline geciyor. Bu hatayi duzeltmek icin /etc/default/locale sudo gedit ile acilir ve

LANG="en_US.UTF-8"
LANGUAGE="en_US:en"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"

yazilir. Tekrar sisteme girildiginde problem duzelmis olacaktir.

Eger alt-tab ile pencereler arasi gecis yapilamadigini farkederseniz, 

sudo apt-get install compiz compizconfig-settings-manager

Sonra Applications | System Settings | Preferences | Combiz Settings Manager

oradan Window Management ve Application Switcher secilir.

Pek cok kez Ubuntu kurduktan sonra bazi paketlerin surekli kurdugumuzu farkettik, gelistirme, analitik, veri isleme icin gerekli bu paketler sunlar (sudo apt-get ile)

build-essential emacs python-dev python-setuptools  python-numpy python-scipy python-matplotlib ipython-notebook texlive emacs-goodies-el preview-latex dvipng openjdk-7-jdk  libavformat-dev ffmpeg postgresql-contrib octave octave-image recoll libatlas-base-dev liblapack-dev gfortran python-sympy r-base-dev r-base python-rpy2 imagemagick gimp python-qt4 pdftk pdfjam gsl-bin xkbset python-pip nautilus-open-terminal nautilus-open-terminal python-markdown python-jinja2 wvdial mplayer vlc xkbset git cmake chromium-browser calibre

texlive-latex-extra [very large]

ubuntu-restricted-extras

sudo pip install pyzmq tornado

Skype icin

sudo apt-get install libasound2 libqt4-dbus libqt4-network libqt4-xml libqtcore4 libqtgui4 libqtwebkit4 libstdc++6 libxss1 libxv1 libssl1.0.0

Ses Efektleri

Eger konsol icine mesela gidilemeyecek durumda bile backspace yapilinca cikan bip, tan, tun seslerini kapatmak istiyorsak System Tools | System Settings, oradan Sound ve Sound Effects. Bir ses kontrol ayari var, onun yaninda Mute secilirse artik uyarici sesleri cikmaz.

Ubuntu baslayinca calan davul sesinden kurtulmak istiyorsaniz

sudo rm /usr/share/sounds/ubuntu/stereo/system-ready.ogg

Clickpad

Acer Aspire S3 bir clickpad ile geliyor. Clickpad hem dokunus (tap) hem de asagi yukari inebilen mekanik dugme gibi islev gorebilen bir mekanizma. Bu clickpad'i kullanmanin farkli yollari var, paketten cikan hali ile hem dugme olarak hem de tek, iki dokunuslar mouse tiklamasi yapabiliyor. Klavyeyi kullanirken yanlislikla dokunusun tiklama yapmasi rahatsizlik yaratiyorsa (mouse isareti baska bir pencereye kaymis mesela, ve yazi yazarken yanlislikla tiklama odagi istemeden o pencereye kaydiriyor), ve "klavye kullanirken clickpad'in iptal edilmesi" secenegi ise yaramiyorsa, o zaman tum clickpad'i bir mouse gibi isler hale getirebilirsiniz. Once System Tools | System Settings | Mouse and Touchpad yapin ve "Enable mouseclicks with touchpad" secenegini iptal edin. Simdi, alttaki cagrilari her bilgisayar acildiginda cagrilacak bir yere yazin, mesela rc.local ya da .bashrc gibi

synclient ClickPad=1
synclient RightButtonAreaLeft=1500
synclient RightButtonAreaRight=2846
synclient RightButtonAreaTop=101
synclient RightButtonAreaBottom=1771


Ustteki komutlar clickpad'i bolgelere ayirarak o bolgelerde olan dokunuslari sag mouse tiklamasi gibi algilanmasini sagliyor. Ustteki bolge sag tiklama icin tanimli. Ayrica dokusun tiklama olmasini iptal ettik, boylece clickpad mouse gibi isler hale geldi.

Balon tavsiyelerini yoketmek icin

sudo mv /usr/share/dbus-1/services/org.freedesktop.Notifications.service /usr/share/dbus-1/services/org.freedesktop.Notifications.service.disabled

Klavye Tusunu Mouse Tiklamasi Haline Getirmek

OpenCV

Google arama sonuclarindaki URL'lere Google kendi eklerini yapiyor, bu sebeple kopyala, yapistir ile bu sonucu baska bir yere tasidiginizda karmakarisik bir URL ortaya cikiyor. Google eklerini yoketmek icin Firefox uzerinde Google / Yandex search link fix adli eklentiyi kurun. Bu eklenti arama sonuclarinizdaki URL'leri temizleyecektir.

Almanya'da USB Modem ile T-Mobile Internet Baglantisi

GPU

Eger GPU ile ilgili bir hata ortaya cikiyorsa,

sudo gksu gedit /etc/default/apport

ile ustteki dosya edit edilir, ve "enabled" diyen yer '1' degerinden '0' degerine getirilir ve dosya kaydedilir.

Ust sag kosede olan Bluetooth ikonu Bluetooth iptal edilmis olsa bile orada gozukmeye devam ediyor, ve kalabalik yaratiyor. Bu ikonu tamamen yoketmek icin

gksu nautilus /etc/xdg/autostart

ile dizini aciniz, ve bu dizindeki bluetooth-applet.desktop ve bluetooth-applet-unity.desktop dosyalarini siliniz. Makina tekrar baslatilinca ikon silinmis olacaktir.

Chrome Uzerinde Flash

Flash, mesela youtube gibi sitelerde, islemiyor ise, suradaki tavsiye takip edilir,

http://askubuntu.com/questions/449103/chromium-34-and-later-cannot-detect-flash-plugin

Komut satirindan

sudo apt-add-repository ppa:skunk/pepper-flash
sudo apt-get update
sudo apt-get install pepflashplugin-installer

Simdi

sudo gedit /etc/chromium-browser/default

ile dosyayi acin ve sonuna

. /usr/lib/pepflashplugin-installer/pepflashplayer.sh

ekleyin. Chrome'u tekrar baslatin (birkac kez f5 ile refresh yapmak gerekebilir), flash isleyecektir.

Ubuntu 13

sudo apt-get install gnome-session-fallback

Caps control yapmak icin

setxkbmap -option ctrl:nocaps

Bu yaziya eklemeler olacak.

Kaynaklar

[1] http://askubuntu.com/questions/153016/apport-gpu-error-intel-py-crash 

[2]  Eger Windows'u silmiyorsaniz, o zaman bolum (partition) araci size bir ekranda diski tekrar bolmeniz ve yeni Unix disk bolume yaratmaniz icin yardim eder. Fakat bir problem bu ekran hangi tarafin Win hangi tarafin Unix oldugunu acikca soylemiyor. Soldaki kisim Windows.