Machine Learning Uygulamalarının Docker Üzerinden Servis Edilmesi

Herkese Selam,

Makine Öğrenimi ile ilgili projeler yaygınlaşmaya başladıkça bu projelerin canlı ortamlara nasıl aktarılacağı ile ilgili pratikler hakkında her geçen gün yenilikler olmakta. Bu bağlamda bu yazı ile bir makine öğrenimi modelini container alt yapılarını kullanarak en hızlı ve etkili bir şekilde canlı ortama nasıl aktarılabileceği ile ilgili bir örnek yapacağım. Umarım farkındalık anlamında faydalı bir çalışma olur.

Örneğimize başlamadan önce sözel olarak bu aktarım alt yapısını hakkında bir miktar bilgi vermek istiyorum.

Günümüzde modern yazılım geliştirme mimarilerini incelediğimizde yazılım geliştirme yaşam döngüsünün her adımında yeni pratiklerin ve frameworklerin geliştiğini görmekteyiz.  Uygulamanın geliştirilmesinden, uygulamanın test edilmesine ve devreye alınmasına kadar her adımda farklı yaklaşımların denendiğini görüyoruz. Modern yazılım geliştirme mimarilerini incelerken karşılaştığımız en temel bileşenlerinden birinin şüphesiz container teknolojileri olduğunu görmekteyiz. Kısaca, container teknolojilerinin bize sunmuş olduğu avantajlardan bahsetmek gerekirse;

  • Geliştirdiğimiz uygulamaları çok kolay ve hızlı bir şekilde çalıştırılmasını sağlar.
  • Uygulamanın ihtiyaç duyduğu tüm ek kütüphane bağımlıklarını uygulamamız ile bütünleşik bir şekilde tutarak kolay, hızlı ve etkili bir şekilde uygulamamızı devreye almamıza olanak sağlar ve uygulamamızın dağıtımını kolaylaştırır.
  • Container olarak devreye alınan uygulamaların yönetimi ve bakımıda oldukça kolay yapılabilmektedir.

Container teknolojileri derinlemesine incelenmesi gereken bir konu olduğu için ben bu yazıda bu konu hakkında daha fazla detaya girmeyeceğim. Daha detaylı bilgi edinmek için Docker dokümantasyonunu inceleyebilir bu konu hakkında yazılmış yüzlerce blog yazılarından faydalanabilir.

Container teknolojilerini konuştuğumuz bir dünyada Docker şüphesiz ki lokomotif olan bir teknoloji. Endüstride defacto bir standart haline gelen docker, container tabanlı yazılım geliştirme yapan hemen hemen herkesin kullandığı bir araç. Bugün bende bu örneği Docker platformu üzerinde yaratacağım bir container aracılığı ile çalıştırmayı deneyeceğim.

Bu örneğimizin yapılabilmesi için öncelikle çalıştığımız ortamda Docker ‘ın kurulu olması gerekmekte. Aşağıdaki lini izleyerek Docker’ı çalışma ortamınızda hazır edebilirsiniz.

Şimdi yapacağımız örneğe gelelim. Bu örnekte yeni bir uygulama geliştirmeyeceğim. Bir önceki “Web Sayfası olarak Machine Learning Modellerinin Kullanıma Açılması” başlıklı yazımda yapmış olduğum çalışmanın bire bir aynısını yapacağım. Ancak sonuç kısmını lokalimden ayağa kaldırmayacağım, geliştirdiğim web uygulamasını bir Docker Container’ına çevirip o şekilde Docker üzerinde çalıştıracağım. Bu nedenle örneği tam olarak anlayabilme adına linkini paylaştığım yazımda nasıl bir uygulama geliştirildiğine bir göz atmanızı öneririm. Bu yazıya konu olan çalışma, o yazıda geliştirilen çalışmanın devamı niteliğinde olacaktır.

Görseller ile uygulamanın ne olduğunu hatırlayacak olursak;

Evet şimdi bu uygulamayı Docker container’ına dönüştürecek imajımı oluşturmak için dockerfile’ı yazalım. Oluşturacağım imajın iskeletini dockerhub’daki official python imajlarından kullanacağım. Seçtiğim iskelet imaj alpine olacak boyutunun küçük olması sebebi ile. Ancak şunu unutmamak gerekiyor benim bu imajı kullanarak oluşturduğum kendi imajlarımın build süreleri azımsanmayacak kadar uzun bunuda dip not olarak söylemek istiyorum.

Dockerfile.yaml

FROM python:3.9.0b3-alpine3.12
WORKDIR /app
ENV FLASK_APP webform.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk --update add gcc build-base freetype-dev libpng-dev openblas-dev
RUN apk --no-cache add --virtual .builddeps g++ musl-dev
RUN apk del .builddeps
RUN pip install scikit-learn==0.19.1
RUN pip install --no-cache-dir flask sklearn matplotlib pandas numpy 
COPY . .
CMD ["flask", "run"]

 

Uygulamamızın çalışacağı docker imajını oluşturacak Dockerfile’ı yazdık. Kabaca burada alpine python imajı üzerinden uygulama ayarlarımızı yaptık. Bu imaj içindeki işletim sisteminin eksik kütüphanelerini kurduk (RUN komutları). Bu aşamadan sonra python içerisinde uygulamamızın kullanacağı kütüphanelerin kurulmasını sağlayacak girdileri verdik. Daha sonra ise uygulama kodlarımızın tamamını oluşacak imaj içine kopyalanmasını sağladık (COPY) ve tüm işlemler bittikten sonra kodumuzu çalıştıracak komutu yazdık (CMD) ve işlemleri sonlandırdık.

Şimdi yazdığımız Dockerfile’dan imajımızı üretecek kodumuzu terminal ekranından çalıştıralım.

docker build -f Dockerfile.yaml -t sentiment-model .

İmajın build edilmesi uzun sürebilir. Build işlemi bittikten sonra aşağıdaki komut ile imajın Docker registry’ye gelip gelmediğini kontrol edebilirsiniz.

docker image ls

Evet gördüğümüz üzere docker imajımız oluşmuş verdiğimiz tag name ile.

Şimdi bu imajı bir container içine koyup çalıştıralım ve test edelim.

docker run -d -it --rm -p 3000:5000 --name sentiment-model sentiment-model:latest

Container’da ayağa kalkacak uygulamaya makinemden ulaşmak için, container’ın 5000 portunda çalışan uygulamayı ana makinemdeki 3000 numaralı porta yönlendirdim. Dolayısıyla 3000 numaralı port üzerinden uygulamaya erişeceğim ana makinemden.

Evet container ayağa kalktı. Şimdi ana makinemizdeki browserdan container da çalışan uygulamamıza erişmeye çalışalım.

Evet container üzerinden çalıştırdığımız uygulamayı lokalimizdeki browserdan ulaşıp testimizi yapabildik.

Uygulamayı bir docker imajına çevirmemizin en büyük faydası oluşturduğumuz bu imajı her ortama çok kolay bir şekilde taşıyıp o ortamda çalıştırabilmemiz olacak. Ürettiğimiz bu imajı dockerhub’a yüklediğimiz takdirde böyle bir uygulamaya ihtiyaç duyacak herkes çok rahat bir şekilde dockerhub üzerinden bu uygulamayı çekip kullanabilecek. Bunun yanı sıra bu imajı neredeyse tüm cloud vendorların docker registry’lerine gönderip dakikalar mertebisinde bulutta da çalıştırabilme imkanımız olacak. Dolayısıyla yazdığımız uygulamaları docker imajlarına çevirmemizin faydası çok ama çok fazla oluyor. Geliştirdiğimiz uygulamaları bu perspektiften bakarak geliştirmemiz kolayca sökülüp takılabilen modüler yazılımlar üretmemize olanak sağlayacaktır.

Posted in Root | Leave a comment

Web Sayfası olarak Machine Learning Modellerinin Kullanıma Açılması

Herkese Selam,

Machine Learning modellerinin kullanıma açılması ile ilgili opsiyonları bir süredir paylaşıyorum. Bu opsiyonlardan birini bir önceki yazımda paylaşmıştım. Link‘e tıklayarak bu yazıya gidebilirsiniz. Bu yazıda ise farklı bir kullanıma açma senaryosu ile ilgili bir örnek yapmayı planlıyorum. Umarım farkındalık anlamında faydalı bir yazı olur.

Girişi, yukarıda linkini paylaşmış olduğum bir önceki yazımdan alıntı yaparak başlamak istiyorum.

“Hepimizin bildiği üzere Makine Öğrenimi ve uygulamaları günümüzün en trend konularının başında geliyor. Bireysel kullanıcılardan kurumsal büyük organizasyonlara kadar bir çok oyuncu makine öğrenimi uygulamaları geliştirmeye çalışıyor. Bu konu ile ilgili mesai harcayan herkesin bildiği üzere bu projelerin gelişimi standart yazılım geliştirme akışından bir miktar farklı. Çözmek istediğimiz probleme ait modeli önce prototipliyoruz daha sonra belirli bir süre test edip parametrelerini en iyileyerek modelimizi nihai halini almasını sağlıyoruz. Modelimiz oldu dediği noktada da bu modeli kullanıma açma kısımına geçiyor. Tam bu noktada mevcut skill setimizin yanında bir miktar yazılım geliştirme ve veri mühendisliği bilmemiz gerekiyor çünkü standart yazılım geliştirme yöntemleri ile bundan sonraki kısımları halletmemiz gerekiyor. Yazımıza konu olan kısımda tamda bu noktada başlıyor.” 

Bu yazıya konu olacak modelimiz bir önceki yazımda kullanmış olduğum modelin bire bir aynısı dolayısıyla bu yazıdaki örneği daha iyi kavrayabilme adına bir önceki yazıdakinin aynısı. Yani daha önce bu blogta paylaşmış olduğum “Doğal Dil İşleme (NLP) ile Sentiment (Duygu) Analizi Tespiti” yazısında paylaşmış olduğum model üzerinden çalışmayı yapacağım ve yine önemle vurgulamak isterimki bu yazının yazılma amacı state of the art bir sentiment analyzer yapmak değil.

“Öncelikle senaryomdan bir miktar bahsedeyim. Bir sentiment analizi modeli geliştirmek istiyorum. Bu modeli imdb, yelp ve amazon’dan toplanmış bir veri seti ile eğitip basit bir sentiment tahmin modeli geliştireceğim. Daha sonra bu modeli bitirdikten sonra bir web sayfası tasarlayıp bu web sayfası üzerinden modeli son kullanıcıların kullanımına açacağım.

Bu yazıya konu olan modeli daha önce paylaşmış olduğum yazımdan daha detaylı anlayabilirsiniz. Ben sadece modeli elde ettiğim kod kısmını bütünlük bozulmasın diye copy paste edeceğim.

import pandas as pd
import numpy as np
import pickle
import sys
import os
import io
import re
from sys import path
import numpy as np
import pickle
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
import matplotlib.pyplot as plt
from string import punctuation, digits
from IPython.core.display import display, HTML
from nltk.corpus import stopwords
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.tokenize import RegexpTokenizer
#Amazon Data
input_file = "../data/amazon_cells_labelled.txt"
amazon = pd.read_csv(input_file,delimiter='\t',header=None)
amazon.columns = ['Sentence','Class']

#Yelp Data
input_file = "../data/yelp_labelled.txt"
yelp = pd.read_csv(input_file,delimiter='\t',header=None)
yelp.columns = ['Sentence','Class']

#Imdb Data
input_file = "../data/imdb_labelled.txt"
imdb = pd.read_csv(input_file,delimiter='\t',header=None)
imdb.columns = ['Sentence','Class']


#combine all data sets
data = pd.DataFrame()
data = pd.concat([amazon, yelp, imdb])
data['index'] = data.index
#Total Count of Each Category
pd.set_option('display.width', 4000)
pd.set_option('display.max_rows', 1000)
distOfDetails = data.groupby(by='Class', as_index=False).agg({'index': pd.Series.nunique}).sort_values(by='index', ascending=False)
distOfDetails.columns =['Class', 'COUNT']
print(distOfDetails)

#Distribution of All Categories
plt.pie(distOfDetails['COUNT'],autopct='%1.0f%%',shadow=True, startangle=360)
plt.show()
#Text Preprocessing
columns = ['index','Class', 'Sentence']
df_ = pd.DataFrame(columns=columns)

#lower string
data['Sentence'] = data['Sentence'].str.lower()

#remove email adress
data['Sentence'] = data['Sentence'].replace('[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+', '', regex=True)

#remove IP address
data['Sentence'] = data['Sentence'].replace('((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}', '', regex=True)

#remove punctaitions and special chracters
data['Sentence'] = data['Sentence'].str.replace('[^\w\s]','')

#remove numbers
data['Sentence'] = data['Sentence'].replace('\d', '', regex=True)

#remove stop words
for index, row in data.iterrows():
    word_tokens = word_tokenize(row['Sentence'])
    filtered_sentence = [w for w in word_tokens if not w in stopwords.words('english')]
    df_ = df_.append({"index": row['index'], "Class":  row['Class'],"Sentence": " ".join(filtered_sentence[0:])}, ignore_index=True)

data = df_
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
from sklearn.neural_network import MLPClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import SGDClassifier


#grid search result
vectorizer = TfidfVectorizer(analyzer='word',ngram_range=(1,2), max_features=50000,max_df=0.5,use_idf=True, norm='l2') 
counts = vectorizer.fit_transform(X_train)
vocab = vectorizer.vocabulary_
classifier = SGDClassifier(alpha=1e-05,max_iter=50,penalty='elasticnet')
targets = y_train
classifier = classifier.fit(counts, targets)
example_counts = vectorizer.transform(X_test)
predictions = classifier.predict(example_counts)
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import classification_report

#Model Evaluation
acc = accuracy_score(y_test, predictions, normalize=True)
hit = precision_score(y_test, predictions, average=None,labels=classes)
capture = recall_score(y_test, predictions, average=None,labels=classes)

print('Model Accuracy:%.2f'%acc)
print(classification_report(y_test, predictions))

Evet modelimizi oluşturduk. Bundan sonra ihtiyacımız olan şey oluşturduğumuz modeli ve modelin vocabulary çıktısını pickle ile kayıt etmek. Daha sonra geliştireceğimiz web sayfasında bu outputları kullanacağız.

### model_save ###
pickle.dump(classifier,open("model_sentiment.pkl","wb"))
pickle.dump(vocab,open("vocab_sentiment.pkl","wb"))

Modelimiz ile ilgili çıktılarımız diske kayıt edildi. Şimdi bu modele input olarak gönderilecek text’in sentimentini bulup geriye dönecek web sayfasının geliştirmesine başlayabiliriz.

Geliştirmeyi python ile yapacağımdan dolayı python’ın flask kütüphanesini kullanacağım. Flask python ile web tabanlı uygulamalar geliştirmenizi sağlayan bir kütüphane. Bende bu kütüphaneyi kullanarak bir web servis geliştireceğim. Öncelikle geliştirme ortamımıza flask kurulumu yapalım.

pip install -U Flask

veya anaconda kullanıcıları için 

conda install -c anaconda flask

Flask kurulumumuzda tamamlandığına göre şimdi web sayfamızın geliştirmesini yapabiliriz.

Geliştirmeye başlamadan önce kendi localimde kurmuş olduğum dizin yapısını göstermek istiyorum. Böyle bir çalışma için sizinde benzer bir dizin yapısı kurmanızın işe yarayacağını düşünmekteyim. Zaten bu bir web uygulaması olacağı için ana kodu yazdığımız webform.py çalıştığı esnada render edeceği .html dosyasını /templates dizini altında arayacak. Dolayısıyla html sayfanızı geliştirdikten sonra templates dizini altına atmanız gerekecek. Aşağıda başarılı şekilde çalışacak dizin yapısını görebilirsiniz.

Dizin yapımda da göreceğiniz üzere geliştirdiğim ve outputlarını aldığım model çıktılarımı models folder’ının altına taşıdım. Templates dizini altına webform.html dosyamı yaratıp koydum. Aynı şekilde ana dizin altına da webform.py isimli kod dosyamı oluşturup kayıt ettim.

Bu uygulama web sayfası üzerinden kullanıcıya ulaştırılacağı için çok basit bir tasarım la kullanıcının text girişi yapıp sonucu göreceği basit bir html form tasarlıyorum. Bu web sayfası, web teknolojilerinin sunmuş olduğu tüm güncel alt yapılar ile donatılabilir ben sadece olabildiğince basit bir tasarım ile nasıl yapıldığını göstermek istiyorum.

“Not: Form inputunu bir tweet olarak kurguladım. Bunun hiç bir önemi yok :)”

webform.html

<form method="POST">
	<br><b>Enter Tweet here...</b></br>
	<textarea rows="4" cols="50" name="tweet">
	</textarea>
	<br></br>
    <input type="submit">
    <br></br>
    <h1><b> Result: </b> {{ value }} </h1>
</form>

Şimdi yarattığımız formun nasıl bir şey olduğuna bakalım.

Evet görüldüğü üzere tasarımımız çok basit. Şimdi bu formu kullacak ve modelimizi çalıştırıp yukarıdaki sayfadan gönderilen text’in sentimeni bulup geri form’a cevabı döndüren python kodunuz yazalım.

webform.py

Burada dikkat edilmesi gereken üç şey var. Birincisi yazdığımı html kodunun nasıl çağırıldığı. İkincisi model outputlarımızı load edip kullanıma hazır hale getirmek.
Üçüncüsü ise dışarıdan parametre olarak gelecek text’i bir değişken içerisine almak ve dördüncüsü bulunan sonucun web sayfasına geri döndürülmesi. Bu satırları vurgulamak açısından bold yapıyorum.

from flask import Flask, request, render_template, url_for
import pickle
import time
import os
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
import io
import re
from sys import path
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
import matplotlib.pyplot as plt
from string import punctuation, digits
from flask import Flask, request, render_template, url_for

start_time = time.time()

app = Flask(__name__)
app.config["DEBUG"] = True

@app.route('/')
def my_form():
    return render_template('webform.html')

@app.route('/', methods=['POST','GET'])
def home():
	vec = open("models/model_sentiment.pkl", 'rb')
	loaded_model = pickle.load(vec)

	vcb = open("models/vocab_sentiment.pkl", 'rb')
	loaded_vocab = pickle.load(vcb)

	txt = request.form['tweet']
    
	examples = txt

	examples = examples.lower()
	examples = examples.replace('\n',' ')
	examples = re.sub(r'[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+', ' ', examples)
	examples = re.sub(r'@[A-Za-z0-9]+', ' ', examples)
	examples = re.sub(r'((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}', ' ', examples)
	examples = re.sub(r'[^\w\s]', ' ', examples)
	examples = re.sub(r'\d', ' ', examples)
	examples = re.sub(' +',' ',examples) 
	examples = [examples]
	
        from sklearn.feature_extraction.text import TfidfTransformer
	from sklearn.feature_extraction.text import TfidfVectorizer
	count_vect = TfidfVectorizer(analyzer='word',ngram_range=(1,2), max_features=50000,max_df=0.6,use_idf=True, norm='l2',vocabulary=loaded_vocab)
	x_count = count_vect.fit_transform(examples)
	predicted = loaded_model.predict(x_count)
	result=''
	if predicted[0] == 0:
	    result= 'Negative'
	elif predicted[0] == 1:
	    result= 'Positive'
	return render_template('webform.html',value=result)

Evet geliştirmeleri tamamladık. Şimdi yazdığımız webform.py kodunu çalıştıralım.

env FLASK_APP=webform.py flask run


Evet servisimiz ayağa kalktı ve endpoint adresi ekranda bize gösterildi. Şimdi servisi test edelim. Test için ekranda görünen endpointi browsera yazmamız yeterli olacak ve istediğimiz bir input ile testimizi yapacağız.

Evet görüldüğü üzere web sayfamızı yazdığımız python kodu üzerinden ayağa kaldırdık ve machine learning modelini son kullanıcının rahatlıkla kullanabileceği bir hale getirmiş olduk.

Posted in Root, Uncategorized | Tagged , , , , , , , , , , | 1 Comment

Machine Learning Modellerinin Flask ile Web Service olarak Kullanıma Açılması

Herkese Selam,

Bu yazıda, daha önceden geliştirmiş olduğum bir machine learning modelini flask kullanarak bir web servise dönüştürüp kullanıma açacağım. Umarım farkındalık anlamında faydalı bir çalışma olur.

Hepimizin bildiği üzere Makine Öğrenimi ve uygulamaları günümüzün en trend konularının başında geliyor. Bireysel kullanıcılardan kurumsal büyük organizasyonlara kadar bir çok oyuncu makine öğrenimi uygulamaları geliştirmeye çalışıyor. Bu konu ile ilgili mesai harcayan herkesin bildiği üzere bu projelerin gelişimi standart yazılım geliştirme akışından bir miktar farklı. Çözmek istediğimiz probleme ait modeli önce prototipliyoruz daha sonra belirli bir süre test edip parametrelerini en iyileyerek modelimizi nihai halini almasını sağlıyoruz. Modelimiz oldu dediği noktada da bu modeli kullanıma açma kısımına geçiyor. Tam bu noktada mevcut skill setimizin yanında bir miktar yazılım geliştirme ve veri mühendisliği bilmemiz gerekiyor çünkü standart yazılım geliştirme yöntemleri ile bundan sonraki kısımları halletmemiz gerekiyor. Yazımıza konu olan kısımda tamda bu noktada başlıyor.

Öncelikle senaryomdan bir miktar bahsedeyim. Bir sentiment analizi modeli geliştirmek istiyorum. Bu modeli imdb, yelp ve amazon’dan toplanmış bir veri seti ile eğitip basit bir sentiment tahmin modeli geliştireceğim. Amacım kesinlikle state of the art sentiment analyzer yapmak değil sadece bu kurgunun bir parçası olacak bir model elde etmek. Daha sonra bu modeli bitirdikten sonra  web servise dönüştürme kısmının geliştirmesini yaparak kullanıma açma kısmını halledeceğiz.

Bu yazıya konu olan modeli daha önce paylaşmış olduğum yazımdan daha detaylı anlayabilirsiniz. Ben sadece kod kısmını copy paste edeceğim.

Doğal Dil İşleme (NLP) ile Sentiment (Duygu) Analizi Tespiti

 

Modelimizi oluşturduğumuz kod bloğumuz. (Modeli Jupyter Notebook üzerinde geliştirdim.)

import pandas as pd
import numpy as np
import pickle
import sys
import os
import io
import re
from sys import path
import numpy as np
import pickle
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
import matplotlib.pyplot as plt
from string import punctuation, digits
from IPython.core.display import display, HTML
from nltk.corpus import stopwords
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.tokenize import RegexpTokenizer
#Amazon Data
input_file = "../data/amazon_cells_labelled.txt"
amazon = pd.read_csv(input_file,delimiter='\t',header=None)
amazon.columns = ['Sentence','Class']

#Yelp Data
input_file = "../data/yelp_labelled.txt"
yelp = pd.read_csv(input_file,delimiter='\t',header=None)
yelp.columns = ['Sentence','Class']

#Imdb Data
input_file = "../data/imdb_labelled.txt"
imdb = pd.read_csv(input_file,delimiter='\t',header=None)
imdb.columns = ['Sentence','Class']


#combine all data sets
data = pd.DataFrame()
data = pd.concat([amazon, yelp, imdb])
data['index'] = data.index
#Total Count of Each Category
pd.set_option('display.width', 4000)
pd.set_option('display.max_rows', 1000)
distOfDetails = data.groupby(by='Class', as_index=False).agg({'index': pd.Series.nunique}).sort_values(by='index', ascending=False)
distOfDetails.columns =['Class', 'COUNT']
print(distOfDetails)

#Distribution of All Categories
plt.pie(distOfDetails['COUNT'],autopct='%1.0f%%',shadow=True, startangle=360)
plt.show()
#Text Preprocessing
columns = ['index','Class', 'Sentence']
df_ = pd.DataFrame(columns=columns)

#lower string
data['Sentence'] = data['Sentence'].str.lower()

#remove email adress
data['Sentence'] = data['Sentence'].replace('[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+', '', regex=True)

#remove IP address
data['Sentence'] = data['Sentence'].replace('((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}', '', regex=True)

#remove punctaitions and special chracters
data['Sentence'] = data['Sentence'].str.replace('[^\w\s]','')

#remove numbers
data['Sentence'] = data['Sentence'].replace('\d', '', regex=True)

#remove stop words
for index, row in data.iterrows():
    word_tokens = word_tokenize(row['Sentence'])
    filtered_sentence = [w for w in word_tokens if not w in stopwords.words('english')]
    df_ = df_.append({"index": row['index'], "Class":  row['Class'],"Sentence": " ".join(filtered_sentence[0:])}, ignore_index=True)

data = df_
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
from sklearn.neural_network import MLPClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import SGDClassifier


#grid search result
vectorizer = TfidfVectorizer(analyzer='word',ngram_range=(1,2), max_features=50000,max_df=0.5,use_idf=True, norm='l2') 
counts = vectorizer.fit_transform(X_train)
vocab = vectorizer.vocabulary_
classifier = SGDClassifier(alpha=1e-05,max_iter=50,penalty='elasticnet')
targets = y_train
classifier = classifier.fit(counts, targets)
example_counts = vectorizer.transform(X_test)
predictions = classifier.predict(example_counts)
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import classification_report

#Model Evaluation
acc = accuracy_score(y_test, predictions, normalize=True)
hit = precision_score(y_test, predictions, average=None,labels=classes)
capture = recall_score(y_test, predictions, average=None,labels=classes)

print('Model Accuracy:%.2f'%acc)
print(classification_report(y_test, predictions))

Evet modelimizi oluşturduk. Bundan sonra ihtiyacımız olan şey oluşturduğumuz modeli ve modelin vocabulary çıktısını pickle ile kayıt etmek. Daha sonra geliştireceğimiz webservis’te bu outputları kullanacağız.

### model_save ###
pickle.dump(classifier,open("model_sentiment.pkl","wb"))
pickle.dump(vocab,open("vocab_sentiment.pkl","wb"))

Modelimiz ile ilgili çıktılarımız diske kayıt edildi. Şimdi bu modele input olarak gönderilecek text’in sentimentini bulup geriye dönecek web servisi geliştirmesine başlayabiliriz.

Geliştirmeyi python ile yapacağımdan dolayı python’ın flask kütüphanesini kullanacağım. Flask python ile web tabanlı uygulamalar geliştirmenizi sağlayan bir kütüphane. Bende bu kütüphaneyi kullanarak bir web servis geliştireceğim. Öncelikle geliştirme ortamımıza flask kurulumu yapalım.

pip install -U Flask

veya anaconda kullanıcıları için 

conda install -c anaconda flask

Flask kurulumumuzda tamamlandığına göre şimdi web servis kodumuzu yazabiliriz.

webservice.py

from flask import Flask, request, render_template, url_for
import pickle
import time
import os
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
import io
import re
from sys import path
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
import matplotlib.pyplot as plt
from string import punctuation, digits

Gerekli kütüphaneleri import ettikten sonra şimdi servisin ana gövdesini yazalım.
Burada dikkat edilmesi gereken iki şey var. Birincisi model outputlarımızı load edip kullanıma hazır hale getirmek.
İkincisi ise dışarıdan parametre olarak gelecek text’i bir değişken içerisine almak. Bu satırları anlaşılması açısından bold yapıyorum.

start_time = time.time()

app = Flask(__name__)
app.config["DEBUG"] = True

@app.route('/sentiment', methods=['POST'])
def home():
	vec = open("models/model_sentiment.pkl", 'rb')
	loaded_model = pickle.load(vec)

	vcb = open("models/vocab_sentiment.pkl", 'rb')
	loaded_vocab = pickle.load(vcb)

	txt = request.args['text']
    
	examples = txt
        # Parametre olarak gelen text'e preprocessing yapıyoruz.
	examples = examples.lower()
	examples = examples.replace('\n',' ')
	examples = re.sub(r'[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+', ' ', examples)
	examples = re.sub(r'@[A-Za-z0-9]+', ' ', examples)
	examples = re.sub(r'((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}', ' ', examples)
	examples = re.sub(r'[^\w\s]', ' ', examples)
	examples = re.sub(r'\d', ' ', examples)
	examples = re.sub(' +',' ',examples) 
	examples = [examples]
	
        # Preprocessing bitti şimdi elimizdeki inputu daha önceden load ettiğimiz modelimize verelim 
        # ve prediction sonucu return edelim

        from sklearn.feature_extraction.text import TfidfTransformer
	from sklearn.feature_extraction.text import TfidfVectorizer
	count_vect = TfidfVectorizer(analyzer='word',ngram_range=(1,2), max_features=50000,max_df=0.6,use_idf=True, norm='l2',vocabulary=loaded_vocab)
	x_count = count_vect.fit_transform(examples)
	predicted = loaded_model.predict(x_count)
	if predicted[0] == 0:
	    return 'Negative'
	elif predicted[0] == 1:
	    return 'Positive'

Evet servisimizin geliştirmesini tamamladık. Şimdi yazdığımız servis kodunu çalıştıralım ve web servisi ayağa kaldıralım.

env FLASK_APP=webform.py flask run

Evet servisimiz ayağa kalktı ve endpoint adresi ekranda bize gösterildi. Şimdi servisi test edelim. Ben webservis testini postman ile yapacağım ama bu zorunlu değil soapui gibi araçlarlada test edilebilir. Şimdi postman’i açıp ekranda gördüğüm endpoint’i bir input text girerek request edeceğim ve servisin response’una bakacağız.

Evet yukarıdaki görselde de göreceğiniz üzere postman üzerinden servisin ayakta olduğu endpointe (http://127.0.0.1:5000/sentiment) “this is great” input text’ini gönderdim ve sonuç olarak servis bize bu text sentimentinin “Positive” olduğunu söyledi.

Görüldüğü üzere Flask ile çok rahat bir şekilde geliştirmiş olduğum machine learning modelini deploy edip kullanıma açtım. Artık bu servisi kullanacak her kullanıcı ile bu endpoint’i paylaşarak servisi kullanmalarını sağlayabiliriz.

Posted in Uncategorized | Tagged , , , , , , , , , | 1 Comment

Doğal Dil İşleme Problemlerinin Çözüm Yaklaşımları ve Gelişimi

Herkese Merhaba,

Doğal Dil İşlemle problemlerini çözme yöntemlerinin evrimi üzerine bir kaç not bırakmak adına bu içeriği oluşturuyorum. Bu yazı, bu metodlardaki gelişimi çok üstün körü anlatmaktadır dolayısıyla sadece sonraki okumalarınız için fikir vermesi açısından bir kaç dakikada tüketilebilecek bir içerik olmasını hayal ederek yazıyorum. Dolayısıyla detaylı yöntem incelemesi ve karşılaştırması yapmayacağım eğer bu konuda bir talep gelirse yöntem bazlı daha detaylı anlatımlarıda yine yapmaya çalışabilirim.

Geçmişten günümüze NLP tasklarında (Name Entity Recognition, Part of Speech Tagging, Sentiment Analysis, Document Classification, Question Answering, Reasoning, Machine Translation …) farklı yaklaşım temellerinin üzerine oturan bir çok metod denendi. Bu metodların bazıları daha basit bir mantıkla çalışırken, bazıları ise oldukça karmaşık ve açıklanması çok daha zor sofistike modeller ile çalışıyor. NLP tasklarını çözmeye çalışan metodlara tarihsel olarak bakacak olursak;

1- Bag of Words (BoW) and Word Vectors (Traditional): Kelimelerin metinlerde geçme frekanslarını temel alan ve kelimeleri vektör olarak temsil etme mantığına dayanan bu metod her seviyeden NLP derslerinde anlatılan en fundemental yaklaşım. Anlaşılması oldukça kolay ve kendi içinde farklı detayda yaklaşımları barındıran bir yöntemler kümesi diyebiliriz. Ancak bu yaklaşım kelime anlamlarını ve cümle içindeki pozisyonlarını/sıralarını bypass ettiği için zor taskların çözümünde çok başarılı olduğunu söyleyemeyiz. Zaten yeni metodların keşfide bu eksiklikleri çözümü ile gelişti hep. Mühendislikte her konuda olduğu gibi.

2- Word Embeddings:  Word Embedding’lere başlamadan bir miktar Derin Öğrenmeden (Deep Learning / Derin Yapay Sinir Ağları) bahsetmek gerekir çünkü Yapay Zeka dünyasında başka bir faza geçilmesine olanak sağlayan bir gelişme. Derin Öğrenme algoritmalarının öğrenme kapasitesi ile beraber Yapay Zekanın bir çok alanında inanılmaz ilerlemeler kayıt edildi. Edilmeyede devam ediliyor. Nihayetinde NLP’de bu gelişmeden nasibini aldı tabiki. Word Embedding’lerin gelişiminde Derin Öğrenmenin katkısı çok ama çok fazla oldu. Word Embedding, NLP problemlerinin çözümünde yeni bir dönemin başlamasına sebep olan çok güçlü bir yöntem. Temel olarak kelimelerin anlamlarına odaklanan ve sözlükteki her kelimenin, N-boyutlu uzayda birbirleri ile matematiksel operatörler kullanarak (toplanabilen, çıkartılabilen) işlemler yapılabilir hale dönüşmesini sağlayan bir teknik. Kelimelerin (vektörlerin) uzaydaki yakınlıkları, anlamsal olarakta yakın olduklarınıda söylemekte. Yani bize semantic yakınlık hakkında da bilgi veriyor word embeddingler. Word Embeddinglerin oluşturma süreçleri var  bu süreç kabaca şöyle çalışıyor. Siz elinizde ne kadar külliyat varsa (bu wikipedia daki tüm içerik olabilir mesela) modele veriyorsunuz, modelde kendi algoritmaları ile (Skip Gram veya CBOW) bu verdiğiniz külliyatdan her bir kelime için bir vektör temsili buluyor (örneğin ingilizce’de her kelime için 300 özellikli bir temsil söz konusu. Her kelime için 300 boyutlu bir vektör var word2Vev’de). Word Embeddinglerin kullanımı oldukça basit çünkü önceden eğitilmiş/ öğrenilmiş birden çok word embedding hali hazırda literatürde mevcut. Bu nedenle bir külliyat ile yeniden bu vektörleri öğrenme maliyetine girmiyoruz çoğunlukla (çok maliyetli bir işlem). Milyarlarca döküman ile eğitilmiş embeddingleri kullanıyoruz genellikle. Literatürde en çok bilinen başlıca Word Embedding’ler Google’ın Word2Vec’i, GLoVe, ve FastText (Facebook). Bu hazır önceden eğitilmiş kelime temsillerini alıp tasklarımızda hazır kullanabilmekteyiz. Bu konu çok derin olduğu için daha fazla uzatmıyorum ve son olarak şunu eklemek istiyorum. Bu kavramı konuşurken Tomas Mikolov’dan bahsetmemek olmaz çünkü Word Embedding kavramının gelişimine inanılmaz bir katkı sundu. Kendisi Google çalışanı ve Word2Vec’in mucidi. O meşhur makalesinin linkinide buraya bırakıyorum.  https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf

3- Deep Learning, Attention Mekanizmaları, Word Embedding ve bu yöntemlerin kombinasyonları: Bu yöntemlerin combine edilip kullanılması 2010’lı yılların başlarından günümüze kadar uzanmakta. Hala trend konular içerisinde yerini koruyor. Derin Öğrenmenin yüksek öğrenme kapasitesi ile kelimelerin semantic temsilleri bir araya gelince bir çok zor task’da SOTA (State of the Art)’lara ulaşıldı. Machine Translation, Question Answering ve Reasoning gibi çok ama çok zor tasklarda büyük başarılar elde edildi. Hatta Google Translate’in başarısının arkasında yine bu kombinasyonlar yatıyor. Google kendi ürünlerini geliştirirken yeni yeni yöntemler keşif ediyor çoğunlukla. Dolayısıyla lokomotif ürünleri yeni alt yapılarla çalışmaya başlıyor bir süre sonra ve bir taraftan da bu yenilikleri community ile paylaşıp herkesin faydalanmasına olanak sağlıyorlar. Google Translate ve Google Search Engine servisleri kendilerinin geliştirdiği ve tüm dünyaya armağan ettikleri yeni yaklaşım olan BERT’i (Bi-directional Encoded Representations from Transformers) de kullanıyor artık. Özellikle search engine’in context bağımlı arama yapabiliyor olması doğru sonuçları kullanıcılara ulaştırma anlamında çok ama çok önemli.

4- Transformers: Word Embedding’ler kusursuz alt yapılar değiller tabiki. Hala güncel olarak kullanılsada belli başlı problemleri var (Context Indepedent, Long Term Dependencies, Computation Complexity vs..). Bunlardan en bariz olanı kelime temsillerinin tek olması ve context’den bağımsız olması. Bunu şöyle anlatabilirim. Örneğin race kelimesinin ingilizcede 2 anlamı var. Bunlardan biri Irk diğeri ise yarış. Bunlar anlamsal olarak çok farklı kavramlar. Ancak elimizdeki embedding’de race ile ilgili tek vektör var. Bu vektör anlam olarak ırk mı demek?  yoksa yarış mı demek?. Bu sorunun cevabı aslında embedding i eğittiğimiz külliyat ile doğrudan alakalı olsada temsil ettiği anlam tek. Bu nedenle eş anlamlı sözcüklerin sadece 1 anlamının word embedding ile temsil edildiğini kabaca söyleyebiliriz. Eğer bizim embedding’imizdeki race = yarış olarak öğrenildi ise ırkçılığın anlatıldığı bir paragrafın sınıflandırması probleminde büyük ihtimalle modelimiz hata yapacaktır. Bu noktada yine araştırmacılar devreye girip nasıl çözebileceklerini düşünüp Transformers fikrini ortaya atmışlar. Transformers’lar temel olarak kelime anlamlarını tamamen gelen contexten öğrenmeye çalışarak eş anlamlı kelimelerde yaşanacak problemleri bertaraf etmeye çalışmakta. Şu an NLP dünyasında SOTA yaklaşım Transformers’lar ve bu furyanın öncülerinden biri yine Google ve önerdikleri framework’ün adı BERT  (Bi-directional Encoded Representations from Transformers). (Transformers’larında Derin Öğrenme temelli çalıştıklarını unutmamak lazım.). BERT’in anlatıldığı meşhur makalenin linkini bırakıyorum. https://arxiv.org/pdf/1810.04805.pdf (2018).

Transformers’ların yaşanan bir çok problemi çözdüğü görülünce farklı Transformers alt yapıları geliştirilmeye devam edildi zaman içerisinde. Bunlardan BERT kadar meşhur olanı ve başarılı olanı Open AI’ın GPT ve GPT-2’si. Paper linkleri : https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf – https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf . BERT ve GPT dışında XLM (Facebook), RoBERTa(Facebook), Transformer-XL (Carnigie Mellon University) ve ALBERT (Google + Toyota) bilinen diğer Transformers’lar. Bunların dışında da yine farklı transformers modelleri mevcut.

Transformers’ların da kullanımı oldukça kolay. Bir üst paragrafta örneklerini sıraladığım Transformers lar önceden eğitilmiş ve kullanıcıların kullanımına açılmış durumda. Ancak bunların çoğu ingilizce’de eğitilmiş alt yapılar yavaş yavaşta farklı dillerdeki versiyonlarıda eğitilmekte. HuggingFace oluşumu aslında birazda bu işi üstlenmiş durumda. HuggingFace, yukarıda örneklerini sıralamış olduğum Transformerların implementasyonlarını yaptıkları python kütüphaneleri geliştirerek son kullanıcıların bu modelleri rahatlıkla kullanabilmelerini sağlamalarının yanında farklı diller için bu modelleri eğiten insanların modellerini paylaştıkları bir mekanizmada sunuyor. Yaptıkları inanılmaz güzel bir iş ve twitter’dan takip etmenizi öneriyorum. (@HuggingFace —> https://twitter.com/huggingface )

Bu noktada BERT’in Türkçe versiyonundan bahsetmemek olma çünkü üzerinde durulması gereken katma değeri oldukça yüksek.  “Türkçe eğitimi yapılmış BERT modeli” BERTurk (https://github.com/stefan-it/turkish-bert). Bu konunun gelişimini çok yakından takip etmiştim çünkü Yüksek Lisans’ta  Deep Natural Language Processing dersini aldığım hocam Reyyan Yeniterzi işin içindeydi. Yayınlanan sayfada ekibin Prof. Dr. Kemal Oflazer (Carnige Mellon University), Reyyan Yeniterzi (Sabancı Üniversitesi) ve Stefan Schweter olduğunu görmekteyiz. Bu çalışma eğer yapılmasaydı Türkçe için BERT alt yapısını kullanmak ilk etapta mümkün olmayabilirdi. Bu bağlamda bu Türkçe NLP çalışmalarına katkısının oldukça yüksek olduğunu söylemek çokta yanlış olmaz. BERTurk’un oluşturulması için Stefan Schweter, içinde 4 tane RTX-2080 GPU olan bir makinanın 5 gün boyunca çalışarak bitirebildiğini yazmıştı.

Turkish BERT’in duyurulma tweeti güzel bir anıydı 🙂 https://twitter.com/_stefan_munich/status/1229183985630240769

 

 

 

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

Oracle Big Data Service, Oracle Cloud Infrastructure Üzerinde Kullanıma Açıldı

Herkese Selam,
Oracle bugün Big Data Servisi kullanıma açtı. Bu servis hızlı bir şekilde istediğiniz büyüklükte, güvenli ve ölçeklenebilen büyük veri platformu yaratabilmemize olanak sağlayan esnek bir bulut hizmeti.

Oracle Big Data Service, Cloudera tabanlı çalışan otomatikleştirilmiş bir servis. Bu alt yapı ile ileri analitik yeteneklerine sahip Hadoop data lake ortamları oldukça uygun maliyetler ile provizyonlanabilmekte. Big Data ve Data Lake platformlarının kurumsal ölçekte büyük alt yapı maliyetlerine sebebiyet veren ihtiyaçlar (CAPEX) olduğunu düşündüğümüzde ilk yatırım maliyetleri anlamında oldukça büyük bir fırsat vermekte ihtiyaç sahiplerine.

Bu servis çok basit bir şekilde porvizyonlanabilmekte. Kabaca nasıl provizyonlandığına ve hangi opsiyonları içerisinde barındırdığına bir bakalım.

Big Data Servis’e OCI arayüzünden erişilebilmekte.

Açılan ekrandan Create Cluster diyerek yaratacağımız Big Data Cluster’ının spesifikasyonlarını belirleyeceğimiz alt yapıya ulaşabiliyoruz.

Öncelikli olarak yaratacağımız cluster’a bir isim veriyoruz ve bir admin şifresi belirliyoruz. Bu aşamadan sonra cluster üzerinde çalışacak yazılımın(Cloudera Hadoop) cluster versiyonunu belirliyoruz. Big Data Service, Cloudera Hadoop Distrobution kullanmakta bu adımda hangi distro’yu kullanacağımıza karar veriyoruz. Ben CDH 6.2.0 olan daha güncel sürümü seçiyorum.

CDH 6.2.0 sürümü ile aşağıdaki komponentler otomatik olarak gelmekte.

Cluster yazılım sürümünü de belirledikten sonra bu aşamada cluster ile ilgili  bazı seçimler yapmaya devam ediyoruz. Bunlar;

MASTER/UTILITY NODE AYARLARI

CHOOSE INSTANCE TYPE: Burada master node’un instance tipini seçiyoruz.  Hem Virtual Machine hem de Bare Metal olarak cluster’ımızı ayağa kaldırabiliyoruz. Ben Virtual Machine olarak kaldırmayı tercih ediyorum.

CHOOSE MASTER/UTILITY NODE SHAPE: Burada Master node’un hangi donanım spesifikasyona sahip olacağını belirlediğimiz parametre. Burada oldukça fazla seçeneğimiz mevcut. 4 CPU 60 GB RAM’e sahip opsiyondan 24 CPU 320 GB RAM spesifikasyona sahip bir donanım seçeneğine kadar farklı opsiyonlarımız mevcut. Hatta daha güçlü IO performansına sahip olan (Dense IO) seçeneklerde mevcut.

BLOCK STORAGE SIZE PER MASTER/UTILITY NODE (IN GB): Master Node’ların her biri için ne kadarlık bir storage kapasitesi istediğimizi yazıyoruz. Bu kapasite 150 GB ile 32 TB’a kadar değişmekte. Kapasite arttırımını 50GB büyüklüğünde yapabiliyoruz.

Aynı konfügrasyonu Worker Node’lar için yapacağız. Ayrıca Worker Node’ların donanım spesifaksyonları için daha fazla opsiyon bulunuyor.

WORKER NODE AYARLARI

Bu ayarları yaptıktan sonra pencerenin altındaki Create Cluster düğmesine basarak servisin yaratılma işlemini başlatabiliriz.

Görüldüğü üzere Big Data Service’ini ayağa kaldırmak oldukça basit. Edinme kolaylığının yanı sıra Big Data Servisi ile bir çok ileri analitik çözümde kullanımımıza açılmış durumda. Bunlardan şüphesizki en önemlilerden biri Cloud SQL özelliği. Cloud SQL özelliği, tüm big data kaynaklarımızı Oracle SQL ile sorgulayabilmemize olanak sağlıyor. Bu kaynaklar HDFS, Hive, Object Stores, Kafka ve NoSQL veritabanları olabiliyor.

Cloud SQL’in yanı sıra Machine Learning workload’larını da Spark ve Hadoop içerisinde ölçeklendirilebilir bir formatta çalıştırabiliyoruz.

Oracle Big Data Service, ML alt yapıları ile makine öğrenmesi uygulamaları geliştirebilme, büyük hacimli veri saklama ve onları analiz edebilme, güvenilir bir alt yapı ile ölçeklenebilir uygulama geliştirebilme gibi bir çok ihtiyacımızı düşük maliyetler ile karşılayabilecek nitelikte. Büyük veri ortamlarının yönetilme maliyetlerini de düşündüğümüzde Big Data Platformunu bulut üzerinden bir servis olarak edinmek oldukça mantıklı bir opsiyon olarak gözükmekte.

 

Daha detaylı bilgi edinmek için linki takip edebilirsiniz.

Oracle Big Data Service

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

Twitter Verisinin Oracle Cloud Streaming Servisi Üzerinden Autonomous Data Warehouse’a Yazılması ve Sorgulanması

Herkese Selam,

Bu yazıda Oracle Cloud Streaming Servisi üzerindeki bir kuyrukta (stream/topic) duran veriyi geliştireceğimiz bir python consumer’ı ile okuyup Oracle Cloud üzerinde provizyonladığımız bir Autonomous Datawarehouse veritabanına yazacağız. Daha sonra veritabanına yazdığımız verinin  veritabanı üzerinden sorgulamasını yapacağız. Umarım farkındalık anlamında faydalı bir yazı olur.

Öncelikle senaryomuz şu şekilde. Stream edeceğimiz veri kaynağı twitter. Dolayısıyla ilk etapta twitter’dan okuyacağımız veriyi Oracle Streaming Servisi üzerindeki bir kuyruğa yazacağız. Buraya kadar olan kısımı bu yazı içerisinde tekrardan geliştirmeyeceğim. Bu kısımın nasıl yapıldığını detaylı bir şekilde anlattığım Oracle Cloud Streaming Servisi (OSS) ve Oracle Data Science Cloud Servisi ile Entegrasyonu isimli yazıma bakarak yapabilirsiniz. Şu anda yapacağımız örnek, referansını verdiğim örneğin devamı niteliğinde olacağından dolayı ilk olarak onun yapılması gerekecektir.

Referansını verdiğim makaleye konu olan örnek esasında büyük resimin Producer parçası idi. Şu geliştireceğimiz parça ile de büyük resimin Consumer parçasını yapmaktayız. Geliştireceğimiz consumer çok basit bir şekilde OSS’de duran bir streami okuyup Oracle Autonomous Datawarehouse’a yazacak.

Geliştirmeye Oracle Data Science Cloud servis üzerinden devam edeceğim için bu servisin Autonomous Datawarehouse’a bağlanabilmesi gerekmekte. Bu bağlantının nasıl yapılacağını Oracle Cloud Data Science Servis Üzerinden Oracle Autonomous Datawarehouse’a Bağlanmak başlıklı yazımı okuyarak basitçe yapabilirsiniz. Bu bağlantı sağlandıktan sonra şimdi Consumer kodumuzu geliştirmeye başlayabiliriz.

Öncelikle consumer’ımız OSS’den okuyacağı veriyi Autonomous Datawarehouse(ADW)’da bir tabloya yazacak. Dolayısıyla bizim bu veriyi ADW’de saklayacak bir tablo yaratmaya ihtiyacımız var. Bu tablo kabaca tek kolon bir tablo olacak ve OSS’e gönderdiğim tweetleri saklayacak. Bu noktada belirtmemiz gereken bir ayrıntıda şu. Twitter bize tweetleri json formatında döndürmekte. Producer kısmını geliştirirken twitter’dan gelen cevabı hiç bir değişikliğe uğratmadan OSS içindeki kuyruğumuza json olarak yazmıştık.  Şimdi ise bu kuyruktaki json veriyi ADW içinde yaratacağımız tabloda json olarak tutacağız. O halde ADW tarafında json formatında tweetleri yazacağımız tabloyu yaratalım.

CREATE TABLE demostreamtweet
  (tweet clob);

Evet ADW’de verileri tutacağımız tabloyu yarattık. Şimdi Oracle Data Science Cloud servis tarafına geçip bu tabloya veriyi yazacak consumer kısmını gerçekleyelim.

İlk önce ADW bağlantımızı kuruyoruz ve gerekli kütüphaneleri import ediyoruz.

import sqlalchemy as db
import pandas as pd
import numpy as np
import os
import warnings as w
from __future__ import absolute_import, print_function
from tweepy import OAuthHandler, Stream, StreamListener
from kafka import KafkaConsumer, KafkaProducer
import json

w.filterwarnings("ignore",category=Warning)

os.environ['TNS_ADMIN']='instantclient_19_5/network/admin/'
engine = db.create_engine('oracle://ADMIN:Welcome1@dbml19c_high')

Evet şimdi Oracle Streaming Servisine yazdığımız datayı gerçek zamanlı okuyacak consumer objemizi yaratalım. Bu objede kullandığımız parametrelerin tamamının nasıl elde edildiğini Oracle Cloud Streaming Servisi (OSS) ve Oracle Data Science Cloud Servisi ile Entegrasyonu isimli makalede detaylıca anlatmıştım. O yazıyı inceleyerek bu bilgileri nasıl elde edeceğinizi öğrenebilirsiniz. Ayrıca consumer objesinin beklemiş olduğu parametrelerden biri hangi stream’i/topic dinleyeceğimiz bilgisi. Bu stream’de referansını verdiğim makalede veriyi yazmış olduğumuz yer olan demostream isimli topic olacak. (Burada geliştirdiğimiz örnek referansını verdiğim makalenin devamı niteliğindedir)

consumer = KafkaConsumer('demostream', bootstrap_servers = 'streaming.<your_region>.oci.oraclecloud.com:9092', 
                         security_protocol = 'SASL_SSL', sasl_mechanism = 'PLAIN',
                         consumer_timeout_ms = 10000, auto_offset_reset = 'earliest',
                         group_id='consumer-0000',
                         sasl_plain_username = '<your_tenancyname>/<username>/<streampool_ocid>', 
                         sasl_plain_password = '<your_auth_token>')

Evet consumer objemizde yaratıldı. Şimdi demostream topic’ine yazdığımız mesajları tek tek okuyup Autonomous Datawarehouse’da yarattığımız tabloya gönderelim.

metadata = MetaData()

twitter_stream = Table('demostreamtweet', metadata,
    Column('tweet', String, primary_key=False),
)

for message in consumer:
    upsert = twitter_stream.insert().from_select([twitter_stream.c.tweet],select([literal(message.value)]))
    engine.execute(upsert) 

Evet kodumuzu çalıştırdığımızda OSS içinde demostream içinde yazılan verilerimizin gerçek zamanlı bir şekilde okunup ADW’de yaratmış olduğumuz demostreamtweet isimli tabloya yazıldığını gözlemleyebiliriz. Şimdi ADW tarafına gidip tablomuzu select edelim.

select * from demostreamtweet;

Evet Streaming Servisten okuduğumuz veriler gerçek zamanlı olarak ADW’ye yazılıyor. Şimdi ADW içinde bu json veriyi parse etmeye çalışalım.

Bilindiği üzere Oracle veritabanı converged ve polyglot bir yapıda. Bu yapıda olması bir çok veri tipini destekleyebilmesi anlamına geliyor. Bu veri tipleri arasında json’da var tabiki. Çok basit SQL cümleleri ile sakladığımız json verileri parse edip anlamı hale getirebilmekteyiz. Bunun ile ilgili küçük bir sorgu paylaşarak yazıyı sonlandırıyorum. Umarım farkındalık anlamında faydalı bir çalışma olmuştur.

SELECT 
   JSON_VALUE(m.tweet, '$.id') id, 
   TO_CHAR(to_timestamp(upper(REGEXP_SUBSTR (JSON_VALUE(m.tweet, '$.created_at'), '[^ ]+' , 1 , 3 )
  || REGEXP_SUBSTR ( JSON_VALUE(m.tweet, '$.created_at') , '[^ ]+' , 1 , 2 )
  || REGEXP_SUBSTR ( JSON_VALUE(m.tweet, '$.created_at') , '[^ ]+' , 1 , 6 )
  || ' '
  || REGEXP_SUBSTR (JSON_VALUE(m.tweet, '$.created_at'), '[^ ]+' , 1 , 4 )),'DDMONYY HH24:MI:SS') + INTERVAL '03:00' HOUR TO MINUTE,'DD-MON-YY HH24:MI:SS') created_at ,
JSON_VALUE(m.tweet, '$.user.followers_count') followers_count,
  JSON_VALUE(m.tweet, '$.user.friends_count') friends_count,
  JSON_VALUE(m.tweet, '$.user.favourites_count') favourites_count
FROM demostreamtweet m;

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

Oracle Cloud Streaming Servisi (OSS) ve Oracle Data Science Cloud Servisi ile Entegrasyonu

Herkese Selam,

Bu yazıda Oracle Data Science Cloud Servisi üzerinden geliştireceğim bir uygulama ile Oracle Cloud Streaming Servis üzerinde yaratacağım bir kuyruğa data yazacağım. Umarım farkındalık anlamında faydalı bir yazı olur.

Geçtiğimiz günlerde Oracle Data Science Cloud Servis ile ilgili bazı paylaşımlarda bulunmuştum. Bu paylaşımlar ile ilgili yazılarıma aşağıdaki linkler aracılığı ile ulaşıp daha detaylı bilgiler edinebilirsiniz.

Oracle Data Science Cloud Servis

 

Oracle Data Science Cloud Servisini Hızlı ve Kolay Yapılandırma

 

Oracle Data Science Cloud Service üzerinde Git Yapılandırmak

 

Oracle Cloud Data Science Servis Üzerinden Oracle Autonomous Datawarehouse’a Bağlanmak

 

Otomatik Machine Learning (AutoML) Alt Yapısı – Oracle Data Science Cloud Service

 

Bugünde örnek uygulama geliştirmeden önce bir miktar Oracle Cloud Streaming Service (OSS)’i hakkında bir miktar bilgi vermek istiyorum.

OSS Oracle’ın Cloud üzerinde sunmuş olduğu bir streaming servisi. Bu servis tamamı ile managed bir servis olarak kullanıcılara açılıyor. Yani siz hiç bir şekilde alt yapı ile ilgili herhangi bir ihtiyaca karışmıyorsunuz. Sadece Cloud arayüzü üzerinden çok basit bir şekilde ayağa kaldırıp kullanmaya başlayabiliyorsunuz. Bu servis tamamı ile ölçeklenebilir ve dağıtık bir mimari çalışıyor ve en düşük veri akış hızlarından en yüksek veri akış hızlarına kadar gerçek zamanlı bir şekilde kullanıcılara hizmet verebiliyor. Bu servis ile yüksek veri akış hızına sahip uygulama loglarını, gerçek zamanlı akan telemetry verilerini, clickstream verilerini, anlık mesajlama verilerini ve buna benzeyen bir çok gerçek zamanlı akan verinizi saklayabilir ve tüketicilerin (consumers) kullanımına açabilirsiniz.

OSS, streaming konusunda de facto bir standart olan Kafka ile uyumludur. Yani Kafka üzerinde geliştirdiğiniz kodları bu platforma sorunsuz bir şekilde taşıyabilirsiniz. Aynı zamanda Kafka için yazılmış API’leride bu servis ile yazılım geliştirirken kullanabiliyorsunuz. Confluent Kafka Python veya Python Kafka API gibi. Ancak Kafka tarafındaki bazı özellikler henüz desteklenmiyor. Dolayısıyla Kafka’nın bu özelliklerini kullanarak geliştirme şimdilik yapamıyoruz. Bu özellikler şu şekilde.

  • Compacted topics
  • Idempotent producers
  • Transactions
  • Kafka Streams
  • Adding partitions to a topic
  • Some administrative APIs

OSS’in birde Streaming SDK‘sı mevcut. Dolayısıyla Cloud yönetim ekranlarından yapabildiğiniz işlemleri kodlarlar aracılığı ile de yapabilme imkanınız bulunuyor.

OSS hakkındaki daha fazla bilgiye OSS dokümantasyonundan erişebilirsiniz.

Şimdi OSS’in nasıl kullanabileceğimizi basit bir şekilde gösterebilmek için örneğimizi yapmaya başlayalım.

Bu örneği geliştirirken OSS’e Oracle Data Science Cloud Servis üzerinden bağlanacağım. Böylelikle iki servisin entegre nasıl çalıştığınıda göstermek istiyorum.

Kabaca yapacağımız örnekte Twitter’dan dinlediğim tweetleri OSS’de yarattığım bir stream içerisine push edeceğim ve daha sonrada Oracle Cloud ekranlarından bu yazdığımız mesajları görüntüleyeceğiz.

Evet şimdi örneğimizi yapmaya başlayabiliriz. İlk olarak yapmamız gereken şey Oracle Cloud hesabımızı açıp ekranlar üzerinden önce bir Stream Pool daha sonra bu Stream Pool içerisine bir Stream yaratacağız. Kafka bilenler için anoloji kurmaları açısından şöyle bir benzetim yapmak mümkün; Stream Pool –> Broker,  Stream –> Topic

Stream Pool ve Stream yaratma işlemlerini aşağıdaki görselleri takip ederek sizde yapabilirsiniz.

 

Evet Stream Pool ve içerisine bir Stream yaratma işlemini başarı ile gerçekleştirdik. Stream yaratma ekranında akacak verinizin hacmine ve hızına göre farklı konfügrasyonlar ile Stream alt yapısını ayağa kaldırabileceğinizi görmüşsünüzdür. Bu kısım ihtiyaca göre şekillendirilebilir.

Şimdi Oracle Data Science Cloud Servisimiz üzerinden ayağa kaldıracağımız bir jupyter notebook ile yarattığımız Stream’e veri basmadan önce jupyter notebook üzerinde yazılacak kodları Data Science Cloud servis üzerinden çalıştırma zorunluluğunuzun olmadığını hatırlatmak isterim. Yani yazılan kodları lokalinizde kurulu olan python ortamlarından da çalıştırabilirsiniz. Ben sadece 2 servis entegrasyonunuda bu örnekte gösterebilmek adına kodları Data Science cloud servis üzerinde çalıştıracağım.

O halde Data Science Cloud Servis’imiz üzerinden öncelikle bir terminal açalım ve OSS’e ve twitter’a bağlanabilmek için ihtiyacımız olacak python kütüphanelerini kuralım.

pip install kafka-python

pip install tweepy

Evet ihtiyacımız olacak paket kurulumları tamamlandıktan sonra şimdi bir notebook açıp kodlarımızı yazmaya başlayabiliriz.

Öncelikle ihtiyacımız olan kütüphaneleri import ederek başlayalım.

from __future__ import absolute_import, print_function
from tweepy import OAuthHandler, Stream, StreamListener
from kafka import KafkaConsumer, KafkaProducer
import json

Evet şimdi Producer objemizi yaratacağız ancak bu objeyi başarılı yaratabilmemiz için bizden beklenen bazı bilgiler var. Bu bilgiler bizim OSS tarafında yarattığımız Stream’e bağlanmamızı sağlayacak bilgiler. Şimdi bu bilgilerin neler olduğuna ve nasıl elde edileceğine bakalım.

bootstrap_servers: Streaming servisinizin endpoint bilgisi. Bunun formatı şu şekilde -> ‘streaming.<region_shortcode>.oci.oraclecloud.com:9092′  burada değişmesi gereken tek yer region bilgisi. Stream servisinizin ayağa kalktığı region’ın kısa kodu. Bu bilgiye aşağıdaki ekran görüntülerinden bakarak ulaşabilirsiniz. Örneğin ekranın sağ üstünde Germany Central (Frankfurt) yazıyorsa region kısa kodunuz eu-frankfurt-1 oluyor.

security_protocol: Bu parametre ‘SASL_SSL’ olarak ayarlanmalıdır.

sasl_mechanism: Bu parametre ‘PLAIN’ olarak ayarlanmalıdır.

sasl_plain_username: Bağlantı kurmanızı sağlayacak en önemli parametrelerden biri bu parametre. Bu parametrenin formatı ise şu şekilde.

<tenancy_name>/<username>/<stream_pool_ocid> şeklinde. Bu 3 bilgiye aşağıdaki şekilde ulaşabilirsiniz.

      • Tenancy Name: OCI arayüzünden soldaki menüden Administration -> Tenancy Details yolunu takip ederek ulaşacağınız menüden edinebilirsiniz. Bu bilgi OCID değil. OCID ile karıştırmamak gerekiyor. Sadece tenancy’nizin adını yazacaksınız.
      • username: Cloud accountunuzun kullanıcı adı. Cloud ekranınızdan Identity -> Users -> User Details ekranından görebilirsinizi.
      • stream pool ocid: Cloud ekranından aşağıdaki yolu izleyerek alabilirsiniz bu bilgiyi.

sasl_plain_password: Servise bağlanabilmek için kendi user’ınız altından token üretip o tokenı kopyalayıp kullanmanız gerekiyor. Aşağıdaki ekranlar aracılığı ile bu token’ı üretip kullanabilirsiniz.

Evet ihtiyaç duyduğumuz tüm bilgileri Cloud ekranlarımız üzerinden edindik. O halde şimdi Kafka Producer’ımızı yaratabiliriz.

producer = KafkaProducer(bootstrap_servers = 'streaming.your_region.oci.oraclecloud.com:9092',
security_protocol = 'SASL_SSL', sasl_mechanism = 'PLAIN',
sasl_plain_username = 'tenancy_name/username/streampoolOCID',
sasl_plain_password = 'YOUR_AUTH_TOKEN')

Evet kafka producer’ımızı OSS’e bağladık. Şimdi sıra twitter’a bağlanıp bir tag dinlemeye sıra geldi. Twitter’dan veri stream edebilmek için bir Twitter Developer account’una sahip olmanız gerekiyor. Bu hesabı edinmek için linki takip edebilirsiniz. Twitter Developer hesabı edindikten sonra twitter size bu servisi dinleyebilmek için bazı bilgiler veriyor. Bu bilgiler aşağıdaki gibidir. İlgili değişkenleri hesabınıza atanmış değerler ile doldurmanız gerekiyor twitter’ı dinleyebilmek için.

consumerKey=””
consumerSecret=””
accessToken=””
accessTokenSecret=””

Şimdi bu değerleri set edip OSS’de yarattığımız demostream içine dinleyeceğimiz tweetleri yazacak metodu kodlayalım.

consumerKey=""
consumerSecret=""
accessToken=""
accessTokenSecret=""

class StdOutListener(StreamListener):
    def on_data(self, data):
        producer.send("demostream", data.encode('utf-8'))
        return True

    def on_error(self, status):
        print(status)

Evet artık veriyi yazacak metodlarımız ve twitter bağlantımızda hazır. Şimdi streaming işini başlatacak kodu yazalım ve çalıştıralım. Ben twitter üzerinde Turkey içerikli twittleri dinlemek istiyorum. İlgili parametremi bu değerle set ediyorum.

tracktag='Turkey'
        
listener = StdOutListener()
auth = OAuthHandler(consumerKey, consumerSecret)
auth.set_access_token(accessToken, accessTokenSecret)

twitter_stream = Stream(auth, listener)
twitter_stream.filter(track=[tracktag])

Evet twitter’da Turkey geçen tweetleri dinleyip OSS içindeki demostream içerisine verileri göndermeye başladık. Şimdi bu verilerin OSS tarafına ulaşıp ulaşmadığına cloud ekranlarımız üzerinden bakalım.

Evet görüldüğü üzere twitter üzerinden dinlediğimiz Turkey içerikli tweetleri başarılı bir şekilde demostream içerisine yazabildik.

Yaptığımız uygulamadan da anlayacağınız üzere OSS servisinin yapılandırılması ve bağlantı kurulması oldukça kolay.  Bu örnek ile bir adım öteye geçerek Cloud üzerindeki iki serviside birbirleri ile entegre bir şekilde kullanmaya çalıştık. Umarım farkındalık anlamında faydalı bir yazı olmuştur.

Posted in Oracle, Root, Uncategorized | Tagged , , , , , , , , | 1 Comment

Oracle Data Science Cloud Service üzerinde Git Yapılandırmak

Herkese Selam,

Bu yazıda Oracle Data Science Cloud Servis ile uzaktaki Git repomuz arasında bir bağlantı kurup Data Science Cloud servis üzerinden uzaktaki repository’mize code checkinleyeceğiz. Umarım farkındalık anlamında faydalı bir yazı olur.

Geçtiğimiz günlerde Oracle Data Science Cloud Servis ile ilgili bazı paylaşımlarda bulunmuştum. Bu paylaşımlar ile ilgili yazılarıma aşağıdaki linkler aracılığı ile ulaşıp daha detaylı bilgiler edinebilirsiniz.

 

Oracle Data Science Cloud Servis

 

Oracle Data Science Cloud Servisini Hızlı ve Kolay Yapılandırma

 

Oracle Cloud Data Science Servis Üzerinden Oracle Autonomous Datawarehouse’a Bağlanmak

 

Otomatik Machine Learning (AutoML) Alt Yapısı – Oracle Data Science Cloud Service

 

Oracle Data Science Cloud servis içerisinde bir çok kütüphanenin önden kurulu geldiğini önceki yazılarımda değinmiştim. Eksik olan kurulumlarıda yapabileceğiniz bir terminal ekranınında var olduğuna yine değinmiştik. Git, Oracle Data Science Cloud servis içerisinde kurulu gelen yazılımlardan biri. Terminal ekranını açıp aşağıdaki komut ile bu kurulumu kontrol edebilirsiniz.

conda list

Evet görüldüğü üzere servisimiz içinde Git kullanmaya hazır. Şimdi uzaktaki repositorymizi nasıl bağlayacağımıza bakalım. Ben bunun için kendi Github hesabımı kullanacağım (https://github.com/emrahmete/codebase.git).

Şimdi /blockstorage dizinine geçip uzaktaki repomu clone’layacağım folder’ı yaratmak istiyorum. Bu noktada şu bilgiyi hatırlatmak istiyorum. Oracle Data Science Cloud Servis içerisinde notebook’unuzun çalışmasını durdurduğunuzda (ekranlar üzerinden deactivation işlemi) kaybolmasını istemediğiniz çalışmaları mutlaka /blockstorage dizini içerisine taşımalısınız. Aksi takdirde servisi tekrar ayağa kaldırdığınızda bu çalışmaların silindiği durumu ile karşılaşabilirsiniz. Bu nedenle çalışmalarınızı blockstorage dizini altında yapmanızı öneriyorum.

Şimdi repoyu tutacağımız dizini yaratalım ve ardından repository konfügrasyonlarımızı yapalım.

cd block_storage/

mkdir GitRepo

cd GitRepo

git init

git config --global user.email "emrahmete@gmail.com"

git config --global user.name "emrahmete"

git clone https://github.com/emrahmete/codebase

Evet uzaktaki git repomuzu clone’ladık. /blockstorage dizini içerisinde yarattığımız GitRepo dizininin içerisine baktığımızda tüm repomuzun kopyalandığını göreceğiz.

cd /home/datascience/block_storage/GitRepo

ls -al

Evet codebase klasörümüzün geldiğini gördük. Bu klasör içerisinde kodlarıda istediğimizde listeleyip içini açıp değiştirip uzaktaki repomuza gönderebiliriz. Şimdi repository kopyamı oluşturduğum GitRepo dizini içinde yeni dosya oluşturup bunu uzakta bağlantısını kurduğumuz repository’ye checkinleyelim.

Yeni yaratacağım dosyamı repositoryim içindeki /home/datascience/block_storage/GitRepo/codebase/oracle/oml dizini altına koyacağım. Daha sonra buradan uzak sunucuya göndereceğim. O halde işlemlerimizi yapmaya başlayalım.

cd /home/datascience/block_storage/GitRepo/codebase/oracle/oml

echo 'Cloud Repo Test' > cloudtest.dat

ls -al

more cloudtest.dat

git add .

git commit -m "DS Cloud Service Commit Test"

Evet öncelikle içine basit bir text yazarak cloudtest.dat dosyamızı oluşturduk ve lokalimizdeki Git Repomuza bu dosyayı commitledik. Şimdi uzaktaki Git repomuza push etme işlemimiz kaldı. Bunu yapabilmek için uzaktaki Git Repomuzun güvenlik bilgilerini ekran üzerinden girmemiz gerekecek ve bilgiler doğrulandığında kodumuz uzaktaki sunucuya gidecek.

git push

Evet lokalimizde yeni yarattığımız dosyayı uzaktaki repository’ye göndermeyi başardık. Şimdi GitHub arayüzünden dosyanın gidip gitmediğini kontrol edebiliriz.

Evet görüldüğü üzere Oracle Data Science Cloud Servis üzerinden uzaktaki Git repositorymize çok basit bir şekilde kod göndermeyi başardık.

Posted in Oracle, Uncategorized | Tagged , , , , , , , , , | 2 Comments

Oracle Data Science Cloud Servisini Hızlı ve Kolay Yapılandırma

Herkese Selam,

Geçtiğimiz günlerde Oracle Data Science Cloud Servis ile ilgili bazı paylaşımlarda bulunmuştum. Bu paylaşımlar ile ilgili yazılarıma aşağıdaki linkler aracılığı ile ulaşıp daha detaylı bilgiler edinebilirsiniz.

Oracle Data Science Cloud Servis

 

Oracle Cloud Data Science Servis Üzerinden Oracle Autonomous Datawarehouse’a Bağlanmak

 

Otomatik Machine Learning (AutoML) Alt Yapısı – Oracle Data Science Cloud Service

 

Oracle Data Science Cloud Servisininin bazı özelliklerini (model kayıt etmek, OCI ile ilgili temel verileri okuyabilmesi, ADW veya Object Storage bağlantıları yapabilmek) kullanabilmek için bu servisi ilk açtığınızda yapılandırmanız gerekmekte. Bu yapılandırma ile ilgili bir tarif servis içinde gelen getting-started.ipynb notebook’u içerisinde tarif edilmiş durumda. Bu tarif içerisinde bazı adımların otomatikleştirilebileceğini düşünerek bir .sh hazırladım. Bu yazı vasıtası ile de bu .sh ı hızlıca nasıl kullanılacağını anlatacağım.

Öncelikle bu yapılandırmayı yapabilmemiz için ihtiyacımız olan bazı bilgiler var. Bu bilgiler.

  • Profile: Bu bilgiyi [DEFAULT] olarak set edebiliriz.
  • User OCID: OCI arayüzünden soldaki menüden Identity -> Users -> User Details yolunu takip ederek ulaşacağınız menüden edinebilirsiniz.
  • Keyfile Path: Bu file sh’ın çalıştıracağı komutlar aracılığı ile otomatik yaratılacağı için bu path’i olduğu gibi bırakabilirsiniz.
  • Tenancy OCID: OCI arayüzünden soldaki menüden Administration -> Tenancy Details yolunu takip ederek ulaşacağınız menüden edinebilirsiniz.
  • Region:  Servisinizi hangi data center’da ayağa kaldırdıysanız o region’ının kısa kod bilgisi. Örneğin ekranın sağ üstünde Germany Central (Frankfurt) yazıyorsa region kısa kodunuz eu-frankfurt-1 oluyor.

Evet bu bilgileri edinip note ettikten sonra aşağıdaki .sh’ta yerlerine yazıyoruz.

export profile=$'[DEFAULT]'
export user=$'user=<your_user_ocid>'
export keyfile=$'key_file=/home/datascience/.oci/oci_api_key.pem'
export tenancy=$'tenancy=<your_tenancy_ocid>'
export region=$'region=<your_region_shortcode>'

cd /home/datascience/
mkdir .oci
cd .oci
openssl genrsa -out ~/.oci/oci_api_key.pem 2048
chmod go-rwx ~/.oci/oci_api_key.pem
openssl rsa -pubout -in ~/.oci/oci_api_key.pem -out ~/.oci/oci_api_key_public.pem

export fingerprint=$'fingerprint='$(openssl rsa -pubout -outform DER -in ~/.oci/oci_api_key.pem | openssl md5 -c)

newline=$'\n'

find="(stdin)= "
rplc=''
fngr=${fingerprint//$find/$rplc}

configStr="${profile}${newline}${user}${newline}${fngr}${newline}${keyfile}${newline}${tenancy}${newline}${region}"
echo "${configStr}"


FILE=$"config"

if [ -f "$FILE" ];
then
   rm $FILE
fi

echo "${configStr}" >> config

cat oci_api_key_public.pem

Evet bu .sh ı lokalinizde düzenledikten sonra Oracle Data Science Cloud Servisi üzerinden bir terminal açalım ve block_storage dizinine geçip isimi (isimin ne olduğu önemli değil) oci_setup.sh adında boş bir dosya oluşturup (vi açıldıktan sonra içerisine veri yazmak için i düğmesine 1 kez basmamız gerekecek) içine lokalimizde editlediğimiz .sh ın içeriğini yapıştıralım ve kayıt edip çıkalım (vi’dan kayıt edip çıkmak için sırası ile ESC:wq! düğmelerine basılır).

cd block_storage/
vi oci_setup.sh

Evet oci_setup.sh’ımız hazır geriye 2 işlemimiz kaldı. Bu işlemlerden ilki bu .sh’ı çalıştırmak. Terminal ekranına aşağıdaki kodu yazarak .sh ı çalıştırabiliriz.

sh oci_setup.sh 

.sh çıktı olarak 2 değer döndürüyor. Bunlardan kullanacağımız olanı yukarıdaki ekran görüntüsündeki kırmızı alan içerisinde kalan bilgi. Bu bilginin tamamını kopyalıyoruz ve OCI’da Identity -> Users -> User Details pathini izleyerek kullanıcı bilgileri ekranını açıyoruz. Bu kopyaladığımız bilgiyi bu ekranda gördüğümüz Add Public Key düğmesine basarak açılan ekrana yapıştırıyoruz ve ADD düğmesine basıp kayıt ediyoruz.

Evet artık tüm işlerimiz tamam. Artık OCI Data Science servisimiz konfügre edilmiş durumda. Son olarak OCI Data Science Servis üzerinden aşağıdaki komut ile yaptığımız ayarların başarılı çalışıp çalışmadığını test edebilirsiniz.

oci iam availability-domain list
Posted in Oracle, Root, Uncategorized | Tagged , , , , , | 3 Comments

Makine Öğrenmesi Modellerinin Container Teknolojileri Aracılığı ile Kullanıma Açılması- FnProject (Functions-As-a-Service)

Herkese Selam,

Makine Öğrenimi günümüzün en trend konularından biri. Hemen hemen her kurum ve IT sektörü ile ilgili profesyoneller / öğrenciler bu alanda çalışamalar yapmaktalar ve her geçen gün bilgi seviyelerini arttırmaktadırlar.

Makine Öğrenimi ile ilgili projeler yaygınlaşmaya başladıkça bu projelerin canlı ortamlara nasıl aktarılacağı ile ilgili pratikler hakkında her geçen gün yenilikler olmakta. Bu bağlamda bu yazı ile bir makine öğrenimi modelini en hızlı ve etkili bir şekilde canlı ortama nasıl aktarılabileceği ile ilgili bir örnek yapacağım. Umarım farkındalık anlamında faydalı bir çalışma olur.

Örneğimize başlamadan önce sözel olarak bu aktarım alt yapısını hakkında bir miktar bilgi vermek istiyorum.

Günümüzde modern yazılım geliştirme mimarilerini incelediğimizde yazılım geliştirme yaşam döngüsünün her adımında yeni pratiklerin ve frameworklerin geliştiğini görmekteyiz.  Uygulamanın geliştirilmesinden, uygulamanın test edilmesine ve devreye alınmasına kadar her adımda farklı yaklaşımların denendiğini görüyoruz. Modern yazılım geliştirme mimarilerini incelerken karşılaştığımız en temel bileşenlerinden birinin şüphesiz container teknolojileri olduğunu görmekteyiz. Kısaca, container teknolojilerinin bize sunmuş olduğu avantajlardan bahsetmek gerekirse;

  • Geliştirdiğimiz uygulamaları çok kolay ve hızlı bir şekilde çalıştırılmasını sağlar.
  • Uygulamanın ihtiyaç duyduğu tüm ek kütüphane bağımlıklarını uygulamamız ile bütünleşik bir şekilde tutarak kolay, hızlı ve etkili bir şekilde uygulamamızı devreye almamıza olanak sağlar ve uygulamamızın dağıtımını kolaylaştırır.
  • Container olarak devreye alınan uygulamaların yönetimi ve bakımıda oldukça kolay yapılabilmektedir.

Container teknolojileri derinlemesine incelenmesi gereken bir konu olduğu için ben bu yazıda bu konu hakkında daha fazla detaya girmeyeceğim. Daha detaylı bilgi edinmek için Docker dökümantasyonunu inceleyebilir bu konu hakkında yazılmış yüzlerce blog yazıları okunabilir.

Container teknolojilerini konuştuğumuz bir dünyada Docker şüphesizki lokomotif olan bir teknoloji. Endüstride defacto bir standart haline gelen docker, container tabanlı yazılım geliştirme yapan hemen hemen herkesin kullandığı bir araç. Bugün bende bu örneği Docker platformu üzerinde çalışan ve open source bir teknoloji olan Fnproject kullanarak gerçekleştireceğim.

Fnproject, açık kaynak ve container-native bir platform. Fnproject, geliştirdiğimiz yazılımları, ister bulut üzerinde, ister on-prem sunucularda bir fonksiyon gibi çalıştırabilmemizi sağlayacak containerlara dönüştürmekte. Bu platform python, java, ruby, node.js ve C# programlama dillerinin tamamını desteklemekte.

Bu örneğimizin yapılabilmesi için öncelikle çalıştığımız ortamda Docker ve Fnproject‘in kurulu olması gerekmektedir. Aşağıdaki linkleri izleyerek gerekli alt yapıları kendi çalışma ortamınızda hazır edebilirsiniz.

Evet gerekli alt yapıyı hazırladıktan sonra şimdi ilk işimiz olan bir makine öğrenimi modeli kurgulayalım ve modelimizni çıktısını diskte saklayalım.

Burada basit bir regresyon modeli kurgulayacağım Sklearn içindeki Boston Housing hazır veri setini kullanarak. Amacım burada state of the art bir Machine Learning modeli kurgulamak değil sadece basit bir model oluşturup bu modeli diske kayıt etmek.

from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split, cross_val_score
import pickle

X, y = load_boston(return_X_y=True)
X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size = 0.1, random_state=5)

regres = LinearRegression()
regres.fit(X_train, Y_train)

pred = regres.predict(X_test)
rmse = (np.sqrt(mean_squared_error(Y_test, pred)))
r2 = round(regres.score(X_test, Y_test),2)

filename = 'boston_model.pkl'
pickle.dump(regres, open(filename, 'wb'))

Evet geliştirdiğim model diske kayıt oldu. Şimdi bu modeli, container’a çevirecek çalışmayı yapacağımız dizine taşıyalım.

mkdir faas

cd faas

mkdir boston

cd boston 

mv /Users/emete/boston_model.pkl .

Öncelikle ürettiğim tahmin modelini bir fonksiyona çevireceğim. Daha sonra Fnproject bu fonksiyonu otomatik olarak her ortama deploy edilebilecek bir container’a dönüştürecek. Ancak bunun için hazırlamam gereken ve Fnproject‘in benden beklediği bazı dosyalar var kabaca bunlar; (Ben python projesi geliştirdiğim için kod dosyalarım .py uzantılı. Farklı diller için uzantılar değişecektir) (Bu dosyalar ile ilgili formatların nasıl olacağına ve daha detay bilgilere linkten erişebilirsiniz.)

  • func.py –> Burası tahmini üreteceğimiz python fonksiyonu.. Modelin tahmin üretmesini isteyeceğimiz her talep için bu fonksiyon çağırılacak.
  • func.yaml –> Bu dosya fonksiyonumuzun nasıl bir ortam üzerinde çalışması gerektiğini söylediğimiz bir konfügrasyon dosyası.  Bu dosya içerisinde memory miktarını, fonksiyonun versiyon bilgilerini, kodun hangi dil ile çalıştırılıcağını ve entrypoint’in ne olduğuna karar veriyoruz.
  • requirements.txt –> Bu dosyada yazdığımız fonksiyonun/uygulamanın kütüphane bağımlılıklarını yazıyoruz. Böylelikle fonksiyon container’a dönüşürken bu bağımlılıklarında container içerisine alınması sağlanıyor.

İlk olarak func.py fonksiyonunu yazacağız. Bu fonksiyon, kayıt ettiğimiz boston_model.pkl modelini load edecek ve fonksiyona gelen parametreleri kullanarak modelin yeni tahmin yapmasını sağlayıp geriye tahmin sonucunu döndürecek. Bu fonksiyonu model dosyamızı içine koyduğumuz dizine kayıt ediyoruz.

import io
import json
import cloudpickle as pickle
from fdk import response

def load_model(model_name):
        return pickle.load(open(model_name, 'rb'))

def pred(model, data):
    return {'prediction':model.predict(data).tolist()}

model_name = 'boston_model.pkl'
model = load_model(model_name)

def handler(ctx, data: io.BytesIO=None):
    try:
        input = json.loads(data.getvalue())['input']
        prediction = pred(model, input)
    except (Exception, ValueError) as ex:
        print(str(ex))

    return response.Response(
        ctx, response_data=json.dumps(prediction),
        headers={"Content-Type": "application/json"}
    )

Evet görüldüğü üzere 3 tane metodumuz bulunuyor ancak ana metodumuz handler metodu. Daha sonra func.yaml dosyasını oluştururken bu fonksiyonu entry point olarak vereceğiz. Yani fonksiyon çağırıldığında ilk çalışacak kod bloğu bu metod olacak. Bu metod kendi içerisinde load_model ve predict metodlarını kullanarak yeni tahmini üretip ve geriye tahmin sonucunu döndürüyor.

Şimdi func.yaml dosyamızı oluşturalım. Bu dosyada fonksiyonun çalışacağı ortam parametrelerini, entrypoint bilgisini ve fonksiyonumuzun adını giriyoruz. Bu dosyayı da yine aynı dizin altına kayıt ediyoruz.

schema_version: 20200101
name: pythonfn
version: 0.0.1
runtime: python
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256

Evet bu dosyayı oluşturma işlemi de tamamlandı. Sırada requirements.txt dosyasını oluşturmak kaldı. Bu dosyada da fonksiyonumuzun çalışabilmesi için gerekli olacak kütüphane bağımlılıklarını yazıyoruz. Bu dosyayı da yine aynı dizin altına kayıt ediyoruz.

scikit-learn==0.21.3
cloudpickle==1.2
pandas==0.24.2
numpy==1.17
scipy==1.3
fdk==0.1.12

Fnproject alt yapısının bizden istedikleri bu kadardı. Şimdi Fnproject komutları ile oluşturduğumuz dosyaları kullanarak modelimizi fonksiyon gibi kullanabilmemizi sağlayacak bir imaja dönüştüreceğiz. Daha sonra local makinemize bu imajı bir container olarak deploy ederek fonksiyonu test edeceğiz.

Öncelikle Fnproject’i bir terminal ekranı aracılığı ile başlatmamız gerekiyor.

fn start

Fnproject alt yapısı çalışmaya başladı. Şimdi dosyalarımızı kayıt ettiğimiz dizinde bir fn projesi yaratacağız ve daha sonra lokal makinemizde kurulu olan fn sunucusuna bu projenin deploymentını gerçekleştireceğiz.

fn create app boston

Evet application’ı yarattık. Şimdi bu application’ı container olarak deploy edeceğiz. Bu adımda bizim yarattığımız konfügrasyon dosyaları okunarak gerekli olan kütüphaneler indirilecek ve fonksiyonumuz ile beraber bir docker imajı şeklinde paketlenerek local docker registry’ye kayıt edilecek. Ardından yine otomatik olarak, oluşturulan yeni imaj, bir container içerisinde ayağa kaldırılarak kullanıma açılacak. Bu adımın çalışma süresi requirements.txt dosyasında verdiğimiz kütüphanelerin sayısına ve boyutuna göre değişkenlik gösterebilir.

fn --verbose deploy --app boston  --local

Evet uygulamamızı local’de kurulu olan Fnproject sunucusuna deploy etmeyi başardık. Test işine geçmeden önce arka tarafta Docker’da neler olmuş onlara bakalım. Öncelikle Dockler imajlarımızı kontrol edelim.

docker image ls

Evet görüldüğü üzere yeni docker imajımız registry’ye gelmiş. Şimdi üretilen bu yeni imaj bir container aracılığı ile çalışmaya hazır edilmiş mi ona bakalım.

docker container ls

Görüldüğü üzere fonksiyon bir container olarak ayağa kalkmış durumda şimdi ayakta olan bu fonksiyonu test edelim.

Fonksiyon bilindiği üzere önceden ürettiğimiz makine öğrenmesi modeline dayalı ev fiyatları tahmini yapmakta. Her evin 13 tane float tipinde bir özelliği bulunuyor ve fiyatını tahmin etmek istediğimizin evin bu 13 özelliğini fonksiyona parametre olarak göndermemiz gerekmekte (Modeli eğitirken kullandığımız Boston Housing veri seti ile ilgili detaya linkten ulaşabilirsiniz.) .

İki farklı yöntem ile fonksiyonu test edeceğim bunlardan biri fn komutları yardımı ile olacak.

echo -n '{"input":[[0.23,18.3,2.3,0.45,0.51,6.6,65.2,4.1,1.1,296.56,15.3,396.9,5.30]]}' | 
fn invoke boston pythonfn --content-type application/json

Diğer çağırım yöntemi ise standart CURL ile olacak ancak CURL ile çağırım yapmadan önce ayakta olan container’ın endpointine bakmam gerekiyor. Önce endpointe bakıyorum daha sonra bu end point ile CURL komutu çalıştırıyorum.

fn inspect function boston pythonfn

Evet endpoint bilgisini aldım şimdi CURL komutu ile fonksiyonu test edebiliriz.

curl -X "POST" -H "Content-Type: application/json" -d \
 '{"input":[[0.23,18.3,2.3,0.45,0.51,6.6,65.2,4.1,1.1,296.56,15.3,396.9,5.30]]}' \
 http://localhost:8080/invoke/01E46TAQKPNG8G00GZJ0000001

Evet görüldüğü üzere CURL ile de çağırıp sonuç almayı başardık.

Yazının girişinde de anlattığım gibi. Yarattığımız alt yapının ürettiği imajlar tamamı ile container-native bir alt yapı ve çalışmak için docker dışında hiç bir ihtiyacı bulunmuyor. Dolayısıyla yaratılan imajlar container çalıştırabilen her ortama deploy edilebilir durumda. Bu bir cloud ortam olabilir veya on-prem bir cluster olabilir. Bir sonraki yazıda burada ürettiğim imajı cloud’da bulunan bir docker registry’e gönderip cloud’da bir fonksiyon olarak deploy edip çalıştıracağım.

Görüldüğü üzere, modelimizi çok basit bir şekilde standalone çalışabilecek bir imaja çevirip daha sonra  container olarak deploy ettik ve test etmeyi başardık.

 

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