Petrol fiyatları genelde tahmin edilemez. Fakat petrol fiyat hareketlerinin tabii ki mevsimselliği var. Mesela Çin'in yeni yılı, Batı dünyasındaki resmi tatiller, ABD sürüş sezonu, rafinerilerin bakım sezonları... Veriye baktığımızda bunları görebilecek miyiz? Bu yazıda Python'a yeni başlayanlar için ABD Enerji Bilgi Dairesi EIA'dan Brent petrol fiyatının günlük verisini indirerek üzerinde işlemleri göstermeye çalışıyorum. Python öğrenmek R'a göre biraz daha zor. Kütüphaneler, kurallar... Ama Python, son 5 yıldaki BASIC dili gibi oldu. Yani biraz öğrenince, internette arama ile her derde deva bir reçete bulunabiliyor. Öğrenmek ise zaman alıyor. Unutmayalım, öğrenmek eğlenceli olsa herkes ders çalışırdı..... Bu yazıda:
Ben Python ve R için Jupyter tavsiye ediyorum. Bu dosyada zaten Jupyter Notebook ile yazıldı. Bir defa kurunca kullanımı kolay rahat. Windows/linux/mac için Anaconda indirmeniz yeterli. Bir komuttan sonra kırmızı renkli uyarı mesajı gelir ise onu internette aratın. Kütüphaneyi bulamadıysa, yeni terminal açıp pip install kütüphane_ismi yapmanız yeterli Veriyi internetten indiriyoruz, ben bu dosyayı yazarken 8043 küsur nokta vardı. Veri dosyası güncellendikçe veri sayısı artar. EIA'in verileri webde Excel formatında buradan indirilebilir https://www.eia.gov/dnav/pet/hist_xls/RBRTEd.xls . 1987'den beri her gün petrol kapanış fiyatlarını içeriyor Kütüphaneler¶Başlamadan önce, ben Python'da her uyarının ekrana gelmesini sevmiyorum. O yüzden uyarıları aşağıdaki komutla bastırıyorum In [1]:
# Supress warnings
import warnings
warnings.filterwarnings('ignore')
Analiz için gerekli kütüphanelerden numpy(sayısal analiz) ve matplotlib(çizim) kütüphanelerini tek satır bir komutla %pylab inline ile dahil edebiliyoruz. In [2]:
# %pylab inline komutu ile numpy, matplotlib dahil edilir
%pylab inline
# veri düzenlemeleri için de Pandas'ı pd olarak alalım
import pandas as pd
Veriye ilk bakış¶Tüm örnek boyunca tek bir veri kullanacağımdan, ana veriyi indirerek prices adlı bir değişkene yükleyeceğim. Bunun üzerinde değişiklikleri yaparsam, değişen halini başka değişkenlere yükleyeceğim. Internet bağlantısı var ise, dosyayı read_excel komutu ile indirebiliriz. Eğer kütüphaneyi bulamazsa Terminal açarak xlrd yani Excel dosyası okuma kütüphanesini kurabilirsiniz. Bilgisayarınıza otomatik kurar. Bunun için
In [3]:
Brent_data="https://www.eia.gov/dnav/pet/hist_xls/RBRTEd.xls"
read_excel internetten dosyayı alarak Pandas'ın meşhur veri çerçevelerine çevirir. Fakat bir Excel dosyasının başında boş satırlar, sütünlar olabilir. Ayrıca veri birden çok alt sayfada da olabilir. Bu yüzden çalışma sayfası "Data 1"'de 2 satır atlayarak veri çekmeye başlıyoruz In [4]:
prices=pd.read_excel("https://www.eia.gov/dnav/pet/hist_xls/RBRTEd.xls",sheet_name="Data 1", skiprows=2)
Verimizin kaç satır/sütun olduğunu .shape alt özelliği görebiliriz. In [5]:
prices.shape
Out[5]:
Verimizin 8048 satır ve 2 sütunu var. Python da (satır,sütun) şeklinde veri tanımları vardır. Şimdi verimizin baş ve son tarafına bakalım Sırasıyla head ve tail komutları ile verinin başını ve sonunu görebiliriz. İstersek baştaki ya da sondaki kaç satırı görmek istediğimizi de parantez içinde ekleyebiliriz. In [6]:
#ilk 4 satır
prices.head(4)
Out[6]:
In [7]:
# son 3 satır
prices.tail(3)
Out[7]:
And let's see the column titles with list command In [8]:
list(prices)
Out[8]:
Çizim¶%pylab inline komutu kullandığımızdan plot yazarak doğrudan veriyi görebiliriz. UYARI: %pylab inline komutunu baştaki gibi çalıştırmadıysanız, ne plot'u bulabilir ne de çizim yapar. Veri setimizdeki alt verileri görmek için prices[' yazdıktan sonra TAB'a basmamız yeterli, Jupyter de otomatik tamamlama özelliği var . Ben mesela Europe yazıp TAB'a basınca alt veri geliyor In [9]:
plot(prices['Europe Brent Spot Price FOB (Dollars per Barrel)'])
Out[9]:
Histogram¶Histogram veri setimizin nasıl dağıldığını gösterir ve sadece hist komutu ile çağrılır. Verimizin normal mi dağıldığı, şişman kuyruklar (yani uç olaylar) histogram ile görülebilir. Şimdi petrol fiyatlarının dağılımını görelim In [10]:
hist(prices['Europe Brent Spot Price FOB (Dollars per Barrel)'])
Out[10]:
Grafikten sonra gelen yazılar can sıkıcı ise .; kullanarak bunları engelleyebilirsiniz. hist komutunda bins parametresi ile de çözünürlüğü arttırabilirsiniz. Yukarıda veri setini 10 kategori(bin) de değerlendirirken, şimdi 100 kategori de grafiği isteyelim In [11]:
hist(prices['Europe Brent Spot Price FOB (Dollars per Barrel)'], bins=100);
Farkı gördünüz değil mi? bins=100 ile çok daha yüksek çözünürlüklü bir veri dağılımı görüntüsüne sahip olduk. Gerçekte petrol fiyatları hep 20\$ etrafındaymış gibi bir görüntü var. Tüm veri seti için bu doğru olabilir. Fakat petrol fiyatlarında önemli olan yüzde değişimlerdir. Asıl bakmamız gereken % değişimlerin dağılımıdır. Bunun için python'da Pandas kütüphanesinde yüzde değişim komutu var. .pct__change(). Veri setini seçip sonra .pct__change() yazınca otomatik olarak % değişimleri hesaplıyor In [12]:
hist(prices['Europe Brent Spot Price FOB (Dollars per Barrel)'].pct_change(), bins=100 );
Petrol fiyatları görüldüğü gibi çok dağınık bir dağılım sergilemiyor. Hatta diyebiliriz ki hiç değişmemeye yakın. Fakat daha yakın bakmamız lazım. Bir söz vardır, yarın için en iyi petrol fiyat tahmini bugün ki fiyatı söylemektir. Bakalım ne kadar doğru Yakın Plan¶hist komutu otomatik olarak sınırları kendi belirliyor. Yukarıdaki grafiğe bakınca %30(-0.3)lere kadar negatif, %20 (0.2)lere kadar pozitif değişkenler görüldüğü söylenebilir. Göz ucuyla bakınca, veri setinin önemli kısmı %5 ile %-5 arasında dağılıyor gibi gözükmektedir. % değişimleri pct_change() ile hesaplattıktan sonra, bu hesaplanan verileri pc değişkenine atayalım, sonra geri kalan işlemleri pc ile yaparız. In [13]:
pc=prices['Europe Brent Spot Price FOB (Dollars per Barrel)'].pct_change()
hist(pc, bins=100);
Veriyi filtrelemek¶Yukarıdaki grafik daha detay bakış için kaba. Özellikle %1 ve %-1 arasındaki veriyi görmek isteyebilirim. Bu iki şekilde olur.
Önce filtreleme ile başlayalım. Normalde tüm verilerimiz pc'de. Yani yüzde değişim. Eğer
Şimdi ilk adımla başlayalım... Yer kazanmak adına daima head(5) komutu ile verisetinin sadece başına bakıyorum. Adım 1. %1 yani 0.01'den yüksek değerleri hücrelerin yerini saptayalım In [14]:
(pc>0.01 ).head(5)
Out[14]:
Şimdi bu doğru/yanlış verilerini veri setine girerek 0.01 den büyük hücre değerlerini ve en başta satır değerlerini elde edelim. In [15]:
pc[pc>0.01].head(5)
Out[15]:
Aynı zamanda birden çok koşulu mantıksal operatörler (& ve diğerleri ile) birleştirebiliriz. Mesela %1'den düşük ve %-1'den küçük değerlere(negatif değerlerde büyüklük-küçüklük ters) sahip hücreleri belirlemek için: (pc<0.01) & (pc>-0.01) In [16]:
pc[(pc<0.01) & (pc>-0.01)].head(3)
Out[16]:
Şimdi %1 ve %-1 arasındaki hücrelerin dağılımını çizdirelim In [17]:
hist(pc[(pc<0.01) & (pc>-0.01)], bins=100);
Çok garip görünüyor, bir de %5 ve %-5 arasındaki verilere bakalım In [18]:
hist(pc[(pc<0.05) & (pc>-0.05)], bins=100);
Tüm bunun daha kolay bir yöntemi var, tüm veri setini alıp, hist komutuna range= (-0.05, 0.05) parametresi girerek histogramın %5 ve %-5 arasındaki grafiğini görebiliriz In [19]:
hist(pc, bins=100, range=(-0.05,0.05));
Dağılımın uç değerlerini görmek¶Şimdi de, tüm seride, %1 ve %-1 arasındaki verilerin miktarını görmek isteyebiliriz. Bunun için ise .count komutunu kullanabiliriz. In [20]:
# Orjinal verinin yapısı
pc.shape
Out[20]:
shape genelde 2li bir veri döndürür. İçindeki veriyi almak için [0] veya [1] ile satır-sütun verisini çekebiliriz. Unutmayın Python'da (satır, sütun) In [21]:
pc.shape[0]
Out[21]:
Verimizde bu yazının yazıldığı tarihte 8048 satır vardı. Daha sonra çalıştırıldığında bu satır sayısı artacaktır. Çünkü yeni petrol kapanış fiyatları eklenmeye devam ediyor, Excel dosyası EIA tarafından güncelleniyor. In [22]:
pc.count()
Out[22]:
Uyarı shape ile sorduğumuzda 8048 satır vardı, count ile sorduğumuzda 8047 satır olduğu söylendi. Sorun şu, count() NA veri noktalarını yani olmayan verileri saymaz. Olasılıkları hesaplarken iki yöntemi de göstermeye çalışacağım %1 ile %-1 arasındaki verilerin oranı = (%1 ve %-1 arasındaki veri sayısı) / (toplam veri sayısı) Başlayalım In [23]:
# For 1%
pc[(0.01>pc) & (-0.01<pc)].shape[0]/pc.shape[0]
Out[23]:
Peki %5 ile %-5 arasındaki veri sayısı In [24]:
pc[(0.05>pc) & (-0.05<pc)].shape[0]
Out[24]:
Eğer %5 ila %-5 arasında değişimlerin sayısı 7770 ise, %5 ila %-5 arasındaki değişimlerin tüm değişimlere oranı 7770/8048 olacaktır In [25]:
7770/8048
Out[25]:
Şimdi bunları sıra ile hesaplayarak notlara yazdırabiliriz In [26]:
print("1% ile -1% arasındaki günlük petrol fiyat değişimlerinin oranı ", (100*pc[(0.01>pc) & (-0.01<pc)].shape[0]/pc.shape[0]))
print("5% ile -5% arasındaki günlük petrol fiyat değişimlerinin oranı " ,(100*pc[(0.05>pc) & (-0.05<pc)].shape[0]/pc.shape[0]))
print("5%'ün üzerindeki günlük petrol fiyat değişimlerinin oranı " , (100*(pc[(0.05<pc)].shape[0])/pc.shape[0]))
print("-5%ten daha küçük günlük petrol fiyat değişimlerinin oranı" , (100*pc[(-0.05>pc)].shape[0]/pc.shape[0]))
Gördüğünüz gibi bir sürü sayılar sayılar. Print komutu ile formatlama da yaparak daha güzel sayı dizilimleri elde edebiliriz. Fakat bazı dikkat edilmesi gereken noktalar var. Eğer formatlama sistemi kullanıyorsanız, tırnak içindeki gerçek % işaretleri %% (iki) şeklinde yazılmalı, aksi halde hata verir. Buraları da formatlayacağını zanneder. Sırayla yapılacaklar:
In [27]:
print("1%% ile -1%% arasındaki günlük petrol fiyat değişimlerinin oranı %.2f%%" % (100*pc[(0.01>pc) & (-0.01<pc)].shape[0]/pc.shape[0]))
print("5%% ile -5%% arasındaki günlük petrol fiyat değişimlerinin oranı %.2f%%" % (100*pc[(0.05>pc) & (-0.05<pc)].shape[0]/pc.shape[0]))
print("5%%'ün üzerindeki günlük petrol fiyat değişimlerinin oranı %.2f%%" % (100*(pc[(0.05<pc)].shape[0])/pc.shape[0]))
print("-5%%ten daha küçük günlük petrol fiyat değişimlerinin oranı %.2f%%" % (100*pc[(-0.05>pc)].shape[0]/pc.shape[0]))
Uç değerler - Minimum, Maksimum değerler ve yerleri¶Şimdi uç değerleri inceleyelim. Öncelikle en uç değerlerin olduğu, dağılım eğrisinin şişman uçlarını görmeye çalışalım. Öncelikle en büyük fiyat düşüşlerine bakalım. Yani %-5 ile %-31 arasındaki değerleri görelim. Bunun için hist komutuna range= parametresi girmek yeterli In [28]:
hist(pc, bins=100, range=(-0.31,-0.05));
Ama en düşük değer tam olarak kaç? Bunun için min komutunu kullanıyoruz In [29]:
pc.min()
Out[29]:
Bir gündeki en büyük fiyat düşüşü -30%. Peki bu hangi gün oldu? Önce kaçıncı satırda minimum değerin gerçekleştiğini görelim, komutumuz idxmax() In [30]:
pc.idxmin()
Out[30]:
Orjinal verimiz prices dı, yüzde değişimler pc Belirli bir satırdaki değere ulaşmak için kullanacağımız komut iloc . Örneğin veri.iloc[satır, sütun] gibi.Ben aslında tam 936'yı değil etrafındaki satırları da görmek isterim. Bunun için iki yolumuz var:
In [31]:
prices.iloc[[935,936,937]]
Out[31]:
In [32]:
prices.iloc[range(935,938)]
Out[32]:
Peki neden pc den istemedik? Görelim, şimdi pc ile o satırlara bakalım. In [33]:
pc.iloc[[935,936,937]]
Out[33]:
Gördüğünüz gibi hiç tarih verisi yok. Çünkü orjinal veriden bir değişim hesaplayıp başka bir değişkene aktık, bu sebeple orjinal verinin endeksi (tarihler) yeni değişkene gelmedi Şimdi de maksimum değerin yerini bulalım. .idxmax() komutu ile maksimum değerin satırını bulabiliriz. In [34]:
# maksimum değer
pc.idxmax()
Out[34]:
In [35]:
prices.iloc[range(5498,5501)]
Out[35]:
Sonuç olarak.
Verisetini geliştirmek : Hafta, Ay, %değişim ile daha büyük bir veri seti¶Internetten indirdiğimi veri setinde sadece Brent fiyatları var. prices veri setimize aşağıdaki başlıkları da eklemek isteyebilirz
İlk adım olarak Hafta verisini ekleyelim. Bu o tarihin yılın hangi haftasına denk geldiğini verecek. Yeni bir sütun oluşturmak çok kolay. Sadece yeni sütun ismi ile yeni bir değişken tanımlayıp, hesapladığımız değerleri oraya atıyoruz. Bu durumda "Hafta" başlığı ile yeni sütun açmak yeterli olacaktır. İndirdiğimiz veri setinin indeksi - yani ana göstergesi Date olduğundan doğrudan bu tarihten datetime kütüphanesi dt ile dönüşüm yapacağız. In [36]:
# Hafta isimli yeni bir sütun oluştur ve veriseti endeksinde tarihin hafta değerini al
prices["Hafta"]=prices["Date"].dt.week
Veri setimizin son 3 satırını görelim In [37]:
prices.tail(3)
Out[37]:
Eğer problem yaşamadıysak ay, yıl ve haftanın günü(HG) değişkenlerini de ekleyebilir. Değişken isimlerinde Türkçe karakterler sorun olduğundan ben ingilizce alfabe ile değişkenleri tanımlamayı tercih ettim. In [38]:
prices["Ay"]=prices["Date"].dt.month
prices["Yil"]=prices["Date"].dt.year
prices["HG"]=prices["Date"].dt.dayofweek
Veri setimizi genişlettik. Haftanın günü (HG) verisi Pazartesi için 0, Cuma için 4 değerini verir. Petrol piyasaları haftasonu açık olmadığından sadece haftaiçi değişkenleri var. In [39]:
#let's see last 4 lines
prices.tail(4)
Out[39]:
Şimdi analizimize devam edebiliriz Python Pandas ile pivot tablolama¶Gruplama¶Toplulaştırılmış veri oluşturmak için en kolay yol gruplandırmadır. Mesela veriyi haftalara göre gruplandırabilirz. pandas kütüphanesinde, doğrudan veri setinden çağırabileceğimiz groupby komutu ile gruplama yapabiliriz. Daha sonra gruplanan verinin ortalamasını .mean() ile veya sayısını .count() ile alabiliriz. prices yazıp . koyup TAB a basmanız yeterli, alt komutlar çıkacaktır. In [40]:
plot(prices.groupby("Hafta")['Europe Brent Spot Price FOB (Dollars per Barrel)'].mean())
Out[40]:
Maalesef bazı yıllarda 53 hafta olabiliyor, bu yüzden ilk 52 haftayı almak için head(52) komutunu kullanabiliriz. In [41]:
plot(prices.groupby("Hafta")['Europe Brent Spot Price FOB (Dollars per Barrel)'].mean().head(52))
Out[41]:
Grafiğe bir başlık ve eksen isimleri gerekiyor. %pylab inline 'ı en başta yazdığımız ve çalıştırdığımız için şimdi çizim alt komutlarını doğrudan title, xlabel veya ylabel olarak çağırabiliriz. In [42]:
plot(prices.groupby("Hafta")['Europe Brent Spot Price FOB (Dollars per Barrel)'].mean().head(52))
title("52 hafta ortalamalı petrol fiyatları (1987-2019)")
xlabel("Hafta")
ylabel("$/varil");
Şimdi bir sonraki aşamayı deneyelim. Sadece tek 1 yıl verisini çekmeye çalışalım. Mesela 2018 İki adımlı bir yolumuz olacak. 1) pc'de yaptığımız gibi önce yil verisinin 2018'e ait olduğu satırları alalım. prices[prices.Yil==2018] 2) ilk 4 satırına bakalım .head(4) In [43]:
pf=prices[prices.Yil==2018]
pf.head(4)
Out[43]:
Şimdi de filtrelediğimiz sonuçları gruplayarak, sonra da ortalamalarını alacağız. In [44]:
pf.head(4)
Out[44]:
In [45]:
# Just look at the averages for the first 4 week
pf.groupby("Hafta")['Europe Brent Spot Price FOB (Dollars per Barrel)'].mean().head(4)
Out[45]:
Şimdi herşeyi birleştirelim ve grafiğini çıkaralım In [46]:
plot(pf.groupby("Hafta")['Europe Brent Spot Price FOB (Dollars per Barrel)'].mean())
Out[46]:
Veya herşeyi tek satırda da yazabiliriz. Yani 2018'deki haftaların ortalama fiyatı... In [47]:
plot(prices[prices.Yil==2018].groupby("Hafta")['Europe Brent Spot Price FOB (Dollars per Barrel)'].mean())
Out[47]:
Şimdi son 5 yıl ve 10 yılın grafiklerini de görebiliriz
komutlarını kullanabiliriz. In [48]:
plot(prices[prices.Yil>=2014].groupby("Hafta")['Europe Brent Spot Price FOB (Dollars per Barrel)'].mean().head(52))
Out[48]:
Bunu daha okunabilir şekilde de yapabiliriz. Örneğin 1) 2014'ten büyük yılları ayrı bir değişkene atarız mesela p2014_2019 2) Ardından tüm işlemleri p2014_2019 için yaparız. In [49]:
p2014_2019=prices[prices.Yil>=2014]
In [50]:
plot(p2014_2019.groupby("Hafta")['Europe Brent Spot Price FOB (Dollars per Barrel)'].mean().head(52))
# title for the plot and ";" for supressing text output
title("Haftalık Petrol Fiyatları(2014-2019)");
Pivot Tablolar¶Uyarı _Ben aynı işlemleri hem groupby hem de pivottable ile yaptım. Ama sonuçlar küçük de olsa ayrışıyordu. NA(olmayan veri) işlevinden olabilir diye fonksiyon opsiyonlarını denedim, ama sonuç elde edemedim Pivot tablolara veri analizinde önemli araçlardandır. Bilmeyenler için elimizdeki günlük veriden, haftaları satıra, yılları sütuna al, Brent rakamlarını da ortalamalardan oluştur diye tek satır ile dönüşüm yapabileceğiz. Orjinal veri setinden verileri aşağıdaki adımlar ile şekillendireceğiz
Petrol fiyatını uzun uzun "Europe Brent Spot Price FOB (Dollars per Barrel)" yazmıyorum, Jupyter de Euro yazıp tab a basınca kendinden geliyor In [51]:
pt=prices.pivot_table( values='Europe Brent Spot Price FOB (Dollars per Barrel)', index=['Hafta'],
columns=['Yil'], aggfunc=np.mean)
Pivot tablomuzu oluşturarak yüklediğimi pt değişkenine bakalım(pt pivot tablo kısaltması) In [52]:
pt.head(4)
Out[52]:
Şimdi Filtreleme Yapalım¶Bakınca 1987'de amma çok NaN -olmayan veri- var gözüküyor. Çünkü veri seti 1987 Mayıs'tan başlıyor. Diğerlerinde sorun gözükmüyor. Şimdi 2014 ile 2019 arasındaki yılları seçerek ilk 52 haftalarını çizebiliriz
In [53]:
plot(pt.loc[:,range(2014,2020)].mean(axis=1).head(52))
title ("Haftalık fiyat ortalamaları (2014-2019)");
İnanmazsanız range komutunun neleri içerdiğine bakabilirsiniz In [54]:
# range command does not include the last element
print(*range(2014,2020))
Eğer sorun yoksa pct_change() ile haftadan haftaya %değişimleri de hesaplayalım In [55]:
ptpc=pt.pct_change()
Daima verisetini yada bir kısmını kontrol edin (mesela ilk 4 satırı head(4) ile görelim) In [56]:
ptpc.head(4)
Out[56]:
İlk satır hep NaN, yani hesaplanamadı, Çünkü ilk satır yani hafta 1'in üstünde bir değer yok. Şimdi bir de grafikleyelim, haftalık ortalama % değişimleri. In [57]:
plot(ptpc.mean(axis=1))
title("Haftalık petrol fiyat değişimleri(1987-2019)")
xlabel("Haftalar")
ylabel("Haftadan Haftaya % değişim");
5 ve 10 yıllık ortalama haftalık fiyatlar¶% değişimler yerine, dikkatimizi tekrar orjinal veriler pt 'ye çevirelim. Son 5 ve 10 yıldaki fiyat ortalamalarını çıkarmaya çalışalım
In [58]:
# First 5 years 2014,2015,2016,2017,2018
plot(pt.loc[:,range(2014,2019)].mean(axis=1).head(52))
Out[58]:
Şimdi 10 yılı görelim In [59]:
# 10 years of average weekly prices
plot(pt.loc[:,range(2009,2019)].mean(axis=1).head(52));
10 yıllık ortalamada, 10ncu hafta civarı büyük bir artış gördük. Fakat benim tavsiyem son 5 yıla bakmak çünkü ABD şeyl üretimi son 5 yılda ana etkisini oluşturdu. Ben 5 yılı yapayım, siz 10 yılı deneyebilirsiniz. Bu sefer veriyi alıp, yüzde değişimlere bakalım pct_change ile In [60]:
pt_haftalik=pt.loc[:,range(2014,2019)].mean(axis=1).head(52)
plot(pt_haftalik.pct_change());
5 yılda bir şeye dikkat ettiniz mi? Yılın başında bir sürü artış, son çeyrekte ise bir sürü düşüş (0'ın altında değişim var) Şimdi bu değişimlere de yakından bakalım. Kodumuz güzel gözüksün diye yüzde değişimleri ayrı bir değişkene atalım In [61]:
pt_haftalik_pc=pt_haftalik.pct_change()
Bu sefer mutlak değer 2%'nin üzerindeki değişimleri görmeye çalışalım.
In [62]:
pt_haftalik_pc[abs(pt_haftalik_pc)>0.029]
Out[62]:
Haftaları Tarihlere Çevirme¶%2'nin(+-%2) üzerinde değişimlerin olduğu hafta rakamlarını biliyoruz, fakat bunlar bu sene(2019)'da hangi tarihlere denk geliyor. Beni işi birazda daraltmak adına 2.9% (tamamen rastsal), değişimlerin üzerindeki değişim haftalarını alıyorum. Önce bu verilerin olduğu hafta rakamlarını (.index.values) ile alıyor strptime komutu ile de tarihe çeviriyorum. Tarih çevrimlerinden nefret ediyorum.... In [63]:
for hafta in pt_haftalik_pc[abs(pt_haftalik_pc)>0.029].index.values:
print(time.asctime(time.strptime('{} {} 1'.format(2019, hafta), '%Y %W %w')))
Son 5 yılda, en güçlü
Aylık veri¶Aylık analiz için bir farklı adımımız daha var. Bunun için bir önceki senenin Aralık aylarını Ocak ayının önüne koyacağız. Bu şekilde Ocak aylarındaki değişimleri de hesaplama şansımız olacak. Bunun için son satır (12. ay = Aralık) alıp, bir sütun sağa kaydırıp (1987 ARalık 1988 Ocak'tan önce gelecek şekilde) en üst satıra taşıyoruz. Adımlarımız ise şöyle:
In [64]:
# Prices monthly data to pm variable
pa=prices.pivot_table( values='Europe Brent Spot Price FOB (Dollars per Barrel)', index=['Ay'],
columns=['Yil'], aggfunc=np.mean)
Yeni verimizin ilk 4 satırına bakalım In [65]:
pa.head(4)
Out[65]:
Şimdi dikkat
In [66]:
pa.loc[0]=pa.loc[12,:].shift(1)
pa.head(3)
Out[66]:
Bizim sıfırıncı sütun nerede? bir de son 3 satıra bakalım In [67]:
pa.tail(3)
Out[67]:
Evet 0.satır ekledik ama en sonda kaldı, onu başa almak için endeksi tekrar sırala diyerek, verimizin üzerine yazacağız. Bunun için sort_index() komutu yeterli olacak In [68]:
pa=pa.sort_index()
pa.head(3)
Out[68]:
Şimdi yüzde değişimleri hesaplayalım In [69]:
# aylık fiyattan aylık değişim
pad=pa.pct_change()
pad.head(3)
Out[69]:
0.satır hep NaN. Çünkü üstünde satır olmadığından yüzde değişim hesaplanamadı. Bu yüzden silelim Satırı silmek için drop komutunu kullanarak, verinizin üzerine yazmanız lazım In [70]:
pad=pad.drop(pad.index[0])
In [71]:
pad.head()
Out[71]:
Şimdi son 10 yıldaki değişimlerin ortalamalarını hesaplayabiliriz.
In [72]:
pad.loc[:,range(2009,2020)].mean(axis=1)
Out[72]:
Son 10 yılda, Şubat-Nisan fiyat artışlarının pozitif olma ihtimali yüksek olduğu aylar. Kasım-Aralık ise düşüş yönünde eğilimlerin yüksek olduğu aylar Şimdi 1987-2019 dönemine, yani tüm veri setine bakalım. In [73]:
pad.mean(axis=1)
Out[73]:
İki sonucu birleştirirsek
Artış veya Düşüş yönündeki ayların toplama oranı¶Daha detayda olasılıkları da hesaplayabiliriz. Yani tüm yıllar boyunca aynı aylar için kaç yıl pozitif veya negatif olmuş, toplama oranı ne? gibi...
In [74]:
pad["Artis"]=pad[(pad.iloc[:,:]>0)].count(axis=1)/(2020-1987+1)
Aynısını negatif, yani düşüşler için yapalım In [75]:
pad["Dusus"]=pad[(pad.iloc[:,:]<0)].count(axis=1)/(2020-1987+1)
Hem artış hem de düşüş olasılıklarını birlikte görelim In [76]:
pad[["Artis","Dusus"]]
Out[76]:
Yukarıdaki sonuçlara göre en yüksek fiyat artışı görme ihtimali Nisan'da (ay=4), ve ihtimali(=artış) 70%(=0.705). Fiyat düşüş ihtimali ise 26%(=0.26) Aylık Grafiklere Devam¶2009-2019 ve 1987-2019 arası aylık ortalama fiyatların grafiği ile devam edelim In [77]:
plot(pa.loc[:,range(2009,2020)].mean(axis=1))
title('2009-2019 Ortalama aylık fiyatlar')
xlabel("Aylar")
ylabel("$/varil");
In [78]:
plot(pa.loc[:,range(1987,2020)].mean(axis=1))
title('1987-2019 Ortalama aylık fiyatlar')
xlabel("Aylar (0 = önceki Aralık)")
ylabel("$/varil");
Haftanın günü etkisi¶Acaba petrol fiyatlarında haftanın günü hareketin yönünü etkiliyor mu? Bazen "Cuma günleri açığa satma" gibi sözleri traderlardan duyabiliyoruz. Bakalım doğru mu? Bu sefer verimizi haftanın günü yani HG değişkenine göre yeniden yapılandıracağız. Fakat önce % değişimleri hesaplamamız gerekecek In [79]:
prices.head(3)
Out[79]:
Günlük yüzde değişimleri hesaplayalım pct_change ile In [80]:
prices["Yuzde"]=prices["Europe Brent Spot Price FOB (Dollars per Barrel)"].pct_change()
prices.head(3)
Out[80]:
Şimdi pivot_table ile günleri sütunlara, yıllar da endeks olacak şekilde verimizi şekillendirelim. (0= Pazartesi, 4=Cuma) In [81]:
pgun=prices.pivot_table( values='Yuzde', index=['Yil'],columns=['HG'], aggfunc=np.mean)
# This time check the last 5 lines
pgun.tail (5)
Out[81]:
pgun* yani haftanın günlerinden derlenen veride kaç satır ve sütun var? In [82]:
pgun.shape
Out[82]:
Bu fiyat değişimlerinin ne kadarı pozitif, ne kadarı negatifmiş. Önce pozitifler In [83]:
pgun[pgun>0].count()
Out[83]:
Şimdi de negatiflere bakalım (pday küçüktür sıfır) In [84]:
pgun[pgun<0].count()
Out[84]:
Olasılık hesabı da gayet basit, pozitifleri/negatifleri toplam satır sayısına böl In [85]:
pgun[pgun>0].count()/pgun.shape[0]
Out[85]:
Haftanın 3.günü(0=Pazartesi), Perşembe gününün pozitif kapanma ihtimali çok çok yüksek: %72 In [86]:
pgun[pgun<0].count()/pgun.shape[0]
Out[86]:
Negatif, yanin düşüş ihtimali ise Pazartesi veya Salı daha yüksek görünüyor. Sonuç¶Bu çalışma kitabında, basit filtreleme, gruplandırma, pivot tablo ve çizim fonksiyonlarını örneklemeye çalıştım. Evet belki, petrol fiyatları tahmin edilemez, ama insan davranışlarına bağlı belirli eğilimler olabilir. Python ile bunları aramak, bulmak daha kolaylaşmışa benziyor Baris Sanli, 11 Şubat 2019, barissanli2@gmail.com , www.barissanli.com¶ |