Sklearn ile Machine Learning Modellerinin Saklanması, Yüklenmesi ve Kullanılması

Herkese Selam,

Oluşturduğumuz makine öğrenmesi tabanlı modellerin saklanması ve daha sonra yüklenip kullanılma ihtiyacı sıkça karşılaştığımız durumlardan biri. Bu yazıda sklearn ile oluşturduğumuz modelleri nasıl saklayacağımızı ve daha sonra nasıl yükleyip kullanacağımızdan bahsedeceğim. Umarım farkındalık anlamında faydalı bir yazı olur.

Öncelikle örnek bir model oluşturalım. Bu örnekte oluşturacağımız model basit bir text classification yapan bir model olacak. Bu modelli oluştururken kullanacağım veri seti ile ilgili bilgiler aşağıdaki gibidir.

Veri Seti : Sentiment Labelled Sentences Data Set

Kaynak : UCI Machine Learning Libarary

İçerik : Bu veri seti 3 farklı internet sitesi (Amazon, Yelp, Imdb) üzerinden toplanmış kullanıcı yorumları ile oluşturulmuştur. Bu yorumlar restoran, film ve ürün değerlendirmelerinden oluşmaktadır. Veri setindeki her bir kayıt iki farklı duygu ile etiketlenmiştir. Bunlar 1: Olumlu/Pozitif 2:Olumsuz/Negatif

Şimdi modeli oluşturma adımına geçelim.
(Bu modelin detaylı anlatımı için linki takip edebilirsiniz. https://emrahmete.wordpress.com/2018/11/25/dogal-dil-isleme-nlp-ile-sentiment-duygu-analizi-tespiti/
)

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

#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_

#Split test and training data set
X_train, X_test, y_train, y_test = train_test_split(data['Sentence'].values.astype('U'),data['Class'].values.astype('int32'), test_size=0.10, random_state=0)
classes  = data['Class'].unique()

#Creating Model
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)

Evet modelimizi oluşturduk. Şimdi ise yazımıza konu olan bu modeli saklamak/kaydetmek kısmına geldik. Modelin saklanma işlemini pickle kütüphanesi ile yapacağız.

# Model and Vocabulary Save
pickle.dump(classifier,open("sentiment_classifier.pkl","wb"))
pickle.dump(vocab,open("vocab_sentiment_classifier.pkl","wb"))

Evet modelimizi kayıt ettik. Şimdi kayıt ettiğimiz modeli tekrar geri yükleyip örnek bir metnin sentimentini bulalım.

# Reload Model and Vocabulary
vec = open("sentiment_classifier.pkl", 'rb')
loaded_model = pickle.load(vec)

vcb = open("vocab_sentiment_classifier.pkl", 'rb')
loaded_vocab = pickle.load(vcb)

Load işlemi başarı ile tamamlandı. Şimdi load ettiğimiz modeli kullanarak bir örnek yapalım.

# Single Value Prediction
examples = 'this is the greatest film that I have ever seen'

#lower string
examples = examples.lower()

#remove email adress
examples = re.sub(r'[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+', '', examples)

#remove IP address
examples = re.sub(r'((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}', '', examples)

#remove punctaitions and special chracters
examples = re.sub(r'[^\w\s]', '', examples)

#remove numbers
examples = re.sub(r'\d', '', examples)

#remove stop words
examples = ttp.clean_turkish_stop_words(examples)

examples = [examples]

from sklearn.feature_extraction.text import TfidfTransformer
count_vect = TfidfVectorizer(analyzer='word',ngram_range=(1,2), max_features=50000,max_df=0.5,use_idf=True, norm='l2',vocabulary=loaded_vocab)
tfidf_transformer = TfidfTransformer()
x_count = count_vect.fit_transform(examples)
predicted = loaded_model.predict(x_count)

result_category = predicted[0]

if result_category == 1:
    print('Positive')
else:
    print('Negative')

Input : ‘this is the greatest film that I have ever seen’
Result : Positive

Evet test ettiğimiz gibi pozitif bir duygu ile yazdığımız metini sistem’de positive olarak buldu.
Böylelikle daha önceden kayıt ettiğimiz bir modeli, yükleyip başarılı bir şekilde kullanmış olduk.

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

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

Herkese Selam,

Bu yazıda doğal dil işleme tekniklerini kullanarak basit bir sentiment analizi uygulaması geliştireceğim. Umarım farkındalık anlamında faydalı bir yazı olur.

Son yıllarda yapay zeka konusundaki gelişmeleri takiben doğal dil işleme tabanlı geliştirilen yapay zeka uygulamalarının önemi ve sayısı gün geçtikçe artmakta.  Bu konuda geliştirilen uygulamalar bir çok işte insan gücünü ortadan kaldırarak daha hızlı ve daha doğru çalışan alt yapılar kullanmamıza olanak sağlayacaktır. Doğal dil işleme ile geliştirilen yaygın örnek uygulamalar ise şu alanlarda karşımıza çıkmakta.

  • Metinleri Sınıflandırma (Spam Detector, Haber Konularının Tespiti)
  • Sentiment Analizi (Duygu analizi)
  • Yazar Tespiti / Yazar Tanıma
  • Makine Çevirisi (Google Translate, Amazon Translate..)
  • Chatbot

Sentiment analizi doğal dil işleme teknikleri ile geliştirilen ve karşımıza en sık çıkan problemlerden bir tanesi. Sentiment analizi ile yazılan bir metnin hangi duygu durumu ile yazıldığına karar verebiliyoruz.

Sosyal medya kullanımın yaygınlaşması ile birlikte insanların sosyal medya üzerinden paylaştıkları görüşlerinin analiz edilme ihtiyacı gün geçtikçe artmakta. Sosyal medya üzerinden akan verinin hacmi düşünüldüğünde bu işi insan gücü ile yapılabilmesi oldukça güç bir iştir. Bu nedenle insanların yazdıkları olumlu veya olumsuz yorumları hızlı bir şekilde algılayıp aksiyon alabilen uygulamalara ihtiyaç her geçen gün artmakta. Bu yazıda bu konuya basit bir giriş yapabileceğimiz bir benchmark uygulaması geliştireceğiz.

Öncelikle sentiment analizi yapacağımız veri setini ile ilgili bilgi verelim.

Veri Seti : Sentiment Labelled Sentences Data Set 

Kaynak : UCI Machine Learning Libarary

İçerik : Bu veri seti 3 farklı internet sitesi (Amazon, Yelp, Imdb) üzerinden toplanmış kullanıcı yorumları ile oluşturulmuştur. Bu yorumlar restoran, film ve ürün değerlendirmelerinden oluşmaktadır. Veri setindeki her bir kayıt iki farklı duygu ile etiketlenmiştir. Bunlar  1: Olumlu/Pozitif   2:Olumsuz/Negatif

Yukarıda detaylarını vermiş olduğumuz veri setini kullanarak örnek bir sentiment analizi modeli oluşturacağız.

Bu modeli kullanma için kuracağımız makine öğrenmesi modelini python programlama dili ile sklearn ve nltk kütüphanesini kullanarak yapacağız.

Şimdi kodumuzu yazma kısmına geçebiliriz.

Öncelikle Kullanacağımız kütüphaneleri import edelim.

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

Şimdi verimizi yükleyelim ve görüntüleyelim.

#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

data

Evet veriyi yükledik ve görüntüledik. Şimdi ise veri ile ilgili istatistiklere bakalım.

#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()

Görüldüğü üzere veri seti oldukça dengeli. Pozitif ve negatif sınıfa ait neredeyse eşit sayıda örnek bulunmakta.

Şimdi veri setini model içerisinde kullanmadan önce, metini temizlemek için bir kaç işlem yapalım.

#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_

Verinin ön temizliğini yaparak model içerisinde kullanmaya hazır hale getirdik. Şimdi modelimizi oluşturmadan önce verimizi test (%10) ve eğitim (%90) olacak şekilde bölme işlemini yapalım.

X_train, X_test, y_train, y_test = train_test_split(data['Sentence'].values.astype('U'),data['Class'].values.astype('int32'), test_size=0.10, random_state=0)
classes  = data['Class'].unique()

Artık eğitim verimizi kullanarak modelimizi oluşturabiliriz. Modeli oluştururken vectorizer olarak TF-IDF, sınıflandırıcı olarak ise Stochastic Gradient Descend algoritması kullanacağım. Bu metodları ve metod içerisindeki parametreleri grid search kullanarak bulduk (Bu yazıda grid search’ten bahsetmeyeceğim).

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)

Modelimiz oluştu şimdi test datası ile modelimizi test edip accuracy, precision, recall ve f1 sonuçlarına bakalım.

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))
Model Accuracy:0.83
             precision    recall  f1-score   support

          0       0.83      0.84      0.84       139
          1       0.84      0.82      0.83       136

avg / total       0.83      0.83      0.83       275

Görüldüğü üzere oluşturduğumuz modelin başarısı %83 çıktı. Şimdi modelimizin tahminlerinin ne kadar doğru olduğunu daha net görebileceğimiz confusion matrix’e bakalım.

#source: https://www.kaggle.com/grfiv4/plot-a-confusion-matrix
import itertools
def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        #print("Normalized confusion matrix")
    else:
        print()

    plt.imshow(cm, interpolation='nearest', cmap=cmap, aspect='auto')
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.figure(figsize=(150,100))
# Compute confusion matrix
cnf_matrix = confusion_matrix(y_test, predictions,classes)
np.set_printoptions(precision=2)

class_names = range(1,classes.size+1)

# Plot non-normalized confusion matrix
plt.figure()
plot_confusion_matrix(cnf_matrix, classes=class_names,title='Confusion matrix, without normalization')

classInfo = pd.DataFrame(data=[])
for i in range(0,classes.size):
    classInfo = classInfo.append([[classes[i],i+1]],ignore_index=True)

classInfo.columns=['Category','Index']
classInfo

Evet bu çalışma ile baştan uca bir doğal dil işleme projesi geliştirdik. Yazının en başında da söylemiş olduğum gibi, kurduğumuz model bir başlangıç modeli olarak alınarak daha iyi modellerin önü açılabilir. Bu yazımızın amacı doğal dil işlemeye giriş sayılabilecek bir uygulama geliştirmekte. Umarım farkındalık anlamında faydalı bir yazı olmuştur.

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

Oracle Data Mining ile Regreson Uygulaması

Herkese Selam,

Bu yazıda Oracle Data Mining ile basit bir regresyon (Regression) analizi yapacağım. Umarım farkındalık anlamında faydalı bir yazı olur.

Veri Bilimi ve Makine Öğrenmesi gibi konular günümüzde hakkında çokça söz ettiren başlıkların başında gelmekte. Öğrenmesi ve uygulaması uzmanlık gerektiren bu başlıklar için adreslenen problemleri ve yöntemleri günümüzde bir çok ürün veya yazılım ile gerçekleyebilmekteyiz. Oracle’da bu başlıklar altındaki problemlerin çözümüne ilişkin yöntem ve algoritmaları DBMS_DATA_MINING paketi ile desteklemekte.

DBMS_DATA_MINING paketi ile Custering, Classification, Regression, Anomaly Detection, Feature Extraction ve Assosication gibi modeller kurup, verimizi bu modellerden geçirip yorumlayabiliyoruz. Bu modellerden elde ettiğimiz sonuçları ise business kurgularımızda input olarak kullanabilmekteyiz.

DBMS_DATA_MINING paketi Oracle veritabanı üzerinde default kurulu olarak gelmiyor. Bu nedenle bu destekten faydalanabilmek için öncelikle bu paketi kurmak gerekiyor. Aşağıdaki linki takip ederek veritabanınıza Oracle Data Mining’ı kurabilirsiniz.

https://docs.oracle.com/cd/E11882_01/datamine.112/e16807/install_odm.htm#DMADM117

Oracle Data Mining paketi kurulumu ile beraber gelen 3 yeni dictionary tablomuz bulunmakta.

SELECT * FROM  ALL_MINING_MODELS;

SELECT * FROM ALL_MINING_MODEL_SETTINGS;

SELECT * FROM ALL_MINING_MODEL_ATTRIBUTES;

ALL_MINING_MODELS tablosunda Oracle’ın bu alt yapı ile bize sunmuş olduğu tüm modeller listesi ve modeller hakkında bilgiler bulunuyor.

ALL_MINING_MODEL_SETTINGS ve ALL_MINING_MODEL_ATTRIBUTES tablolarında ise bu modeller ile ilgili parametreler ve spesifik detaylar bulunmakta.

Şimdi bu alt yapının nasıl kullanıldığını görmek için bir örnek yapalım.

Örneği yapabilmek için bir veri setine ihtiyaç duyuyorum. Örneği, kaggle üzerinde bulunan veri setlerinden Boston Housing üzerinde yapacağım.

Öncelikle Boston Housing veri setini tanıyalım.

Column Name Description Data Type
crim per capita crime rate by town. Number
zn proportion of residential land zoned for lots over 25,000 sq.ft. Number
indus proportion of non-retail business acres per town. Number
chas Charles River dummy variable (= 1 if tract bounds river; 0 otherwise). Number
nox nitrogen oxides concentration (parts per 10 million). Number
rm average number of rooms per dwelling. Number
age proportion of owner-occupied units built prior to 1940. Number
dis weighted mean of distances to five Boston employment centres. Number
rad index of accessibility to radial highways. Number
tax full-value property-tax rate per \$10,000. Number
ptratio pupil-teacher ratio by town. Number
black 1000(Bk – 0.63)^2 where Bk is the proportion of blacks by town. Number
lstat lower status of the population (percent). Number
medv median value of owner-occupied homes in \$1000s. Number

Evet veri setimiz ile ile ilgili detaylara baktıktan sonra indirdiğimiz veri setini Oracle veritabanımıza yükleyelim.

Öncelikle indirdiğimiz veri setini (training.csv) yükleyeceğimiz Oracle tablosunu yaratalım.

CREATE TABLE BOSTON_HOUSING
(
   ID        NUMBER,
   CRIM      NUMBER,
   ZN        NUMBER,
   INDUS     NUMBER,
   CHAS      NUMBER,
   NOX       NUMBER,
   RM        NUMBER,
   AGE       NUMBER,
   DIS       NUMBER,
   RAD       NUMBER,
   TAX       NUMBER,
   PTRATIO   NUMBER,
   BLACK     NUMBER,
   LSTAT     NUMBER,
   MEDV      NUMBER
);

Tablomuzu yarattık, şimdi .csv olarak indirdiğimiz veri setimizi içeriye yükleyeceğiz, bunu yapmak için birden çok yöntemimiz bulunuyor. Bunlardan bazıları;

  • Oracle External Table yardımı ile yüklemek.
  • Oracle SQL Loader kullanarak yüklemek.
  • Kullandığımız editörlerden faydalanarak yüklemek.

Ben veri setini kullandığım editör yardımı ile yükleyeceğim. Editör olarak Toad kullanmaktayım. Toad ile aşağıdaki yolu takip ederek yükleme işlemini gerçekleştirebilirsiniz.

Database –> Import –> Import Table Data 

Toad ürünü ücretli olduğu için bu editörü kullanıyor olabilirsiniz. Ancak diğer editörlerin de bu özelliği mevcut, diğer editörlerle de bu işlemi kolaylıkla yapabilirsiniz. Örneğin ücretsiz olan Oracle SQL Developer ile veri yüklemesini aşağıdaki gibi yapabilirsiniz.

SELECT * FROM BOSTON_HOUSING;

Evet veri seti yükleme işlemini tamamladık.

Veriyi gözlemlediğimizde evlerin çeşitli özelliklerine göre detayları görmekteyiz. Her bir satırda ilgili evin spesifik özelliklerine ait bilgiler bulunuyor. Regresyon analizine girecek temel parametrelerimiz bu tablodaki gibi. Bu tabloda regresyon analizi sonucu tahminleyeceğimiz değer ise en sondaki MEDV kolonu. MEDV kolonu bu analizde kullanacağımız target değişkeni.

Regresyon analizine başlamadan önce konunun daha iyi anlaşılması için kullanılan algoritma hakkında biraz bilgi vereceğim.

DBMS_DATA_MINING paketi birliktelik analizini Generalized Linear Model algoritması ile gerçeklemekte.  Bu algoritmayı kullanmak içinse bizim bazı parametreleri tanımlamamız gerekiyor. Bu parametreler aşağıdaki gibidir;

Şimdi algoritma ayarlarını okuyacağımız tabloyu yaratalım.

 

CREATE TABLE SETTINGS_GLM
AS
SELECT *
     FROM TABLE (DBMS_DATA_MINING.GET_DEFAULT_SETTINGS)
    WHERE SETTING_NAME LIKE '%GLM%';

BEGIN
   INSERT INTO SETTINGS_GLM
        VALUES (DBMS_DATA_MINING.ALGO_NAME, 'ALGO_GENERALIZED_LINEAR_MODEL');

   INSERT INTO SETTINGS_GLM
        VALUES (DBMS_DATA_MINING.PREP_AUTO, 'ON');

   INSERT INTO SETTINGS_GLM
        VALUES (
                  DBMS_DATA_MINING.GLMS_RIDGE_REGRESSION,
                  'GLMS_RIDGE_REG_DISABLE');

   INSERT INTO SETTINGS_GLM
        VALUES (
                  DBMS_DATA_MINING.ODMS_MISSING_VALUE_TREATMENT,
                  'ODMS_MISSING_VALUE_MEAN_MODE');

   COMMIT;
END;

Evet algoritma parametrelerimizi okuyacağımız tabloyu oluşturduk. Şimdi modelimizi oluşturma adımına geçebiliriz.

CREATE OR REPLACE VIEW VW_BOSTON_HOUSING AS SELECT * FROM BOSTON_HOUSING;

BEGIN 
   DBMS_DATA_MINING.CREATE_MODEL(
      model_name            => 'MD_GLM_MODEL',
      mining_function       =>  DBMS_DATA_MINING.REGRESSION,
      data_table_name       => 'VW_BOSTON_HOUSING',
      case_id_column_name   => 'ID',
      target_column_name    =>  'MEDV',
      settings_table_name   => 'SETTINGS_GLM');
END;

Modelimiz oluştu, şimdi modelimiz ile ilgili oluşan detaylara dictionary’den bakalım.

SELECT MODEL_NAME,
       ALGORITHM,
       COMMENTS,
       CREATION_DATE,
       MINING_FUNCTION,
       MODEL_SIZE
  FROM ALL_MINING_MODELS
 WHERE MODEL_NAME = 'MD_GLM_MODEL';

SELECT SETTING_NAME, SETTING_VALUE
FROM ALL_MINING_MODEL_SETTINGS
WHERE MODEL_NAME = 'MD_GLM_MODEL';

Evet yarattığımız Regresyon modeline ait Anova tablosuna aşağıdaki gibi erişlebilir.

 

SELECT * FROM TABLE (DBMS_DATA_MINING.GET_MODEL_DETAILS_GLM ('MD_GLM_MODEL'));

Evet şimdi modelimizle nasıl test yapabileceğimize bakalım. Öncelikle bunun için kaggle’dan indirdiğimiz test.csv dosyasını yüklemek için gerekli olan tablomuzu yaratıyoruz ve datayı içerisinde import ediyoruz.

CREATE TABLE BOSTON_HOUSING_TEST
(
   ID        NUMBER,
   CRIM      NUMBER,
   ZN        NUMBER,
   INDUS     NUMBER,
   CHAS      NUMBER,
   NOX       NUMBER,
   RM        NUMBER,
   AGE       NUMBER,
   DIS       NUMBER,
   RAD       NUMBER,
   TAX       NUMBER,
   PTRATIO   NUMBER,
   BLACK     NUMBER,
   LSTAT     NUMBER,
   MEDV      NUMBER
);

Database –> Import –> Import Table Data (test.csv)

SELECT * FROM BOSTON_HOUSING_TEST;

Şimdi yüklediğimiz test verisi ile oluşturduğumuz modeli çalıştırıp sonuçlara bakalım.

SELECT T.*,
 PREDICTION (MD_GLM_MODEL USING *) MODEL_PREDICT_RESPONSE
FROM BOSTON_HOUSING_TEST T;

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

Veritabanı İçerisindeki JSON Değerlerin Karşılaştırılması

Herkese Selam,

Bu yazıda Oracle 18c ile beraber gelen bazı yeni SQL fonksyonlarından bahsedeceğim umarım farkındalık anlamında faydalı bir yazı olur.

Bilindiği üzere Oracle 18c geçtiğimiz Şubat ayında duyuruldu ve kullanıcılara Cloud ortamlarda kullanımlarına açıldı. Bu gelişmeyi takiben Oracle, LiveSQL platformu üzerinden de son kullanıcıların denemeleri üzerine yeni sürümü kullanıma açtı.

Bu yazıya konu olan fonksiyon denemelerini LiveSQL platformu üzerinden gerçekleştireceğim.

Yazımıza konu olan yeni SQL fonksyonları veritabanına kaydettiğimiz json içeriklerin içerik kontrollerini yapıp jsonların uyuşup uyuşmadığını anlayabilmektedir. Mevcut alt yapı ile jsonların içerik kontrollerini yapabilmek için karmaşık sql sorguları geliştirmemiz gerekirken yeni geliştirilen fonskyonlar ile bu kontrol oldukça hızlı ve kolay yapılabilmektedir.

Şimdi bir kaç farklı senaryo deneyerek neler yapabildiğimize bir bakalım.  Öncelikle işe örnek bir tablo ve veri oluşturarak başlayalım.

CREATE TABLE comp_json_values
(
   json_val_1   VARCHAR2 (2000),
   json_val_2   VARCHAR2 (2000),
   use_case_desc VARCHAR2(2000)
);

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"key":"k1","value":"v1"}',
               'Exactly Same');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"key":"k1" ,  "value":"v1"   }',
               'Exactly Same but having whitespaces');    

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"key":"k2","value":"v2"}',
               'Format:Same - Order:Same - Values:Different');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"key":"k2","value":"v2","value2":"v3"}',
               'Format:Different - Order:Different - Values:Different');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"value":"v1","key":"k1"}',
               'Format:Same - Order:Different - Values:Same');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"value":"v21","key":"k21"}',
               'Format:Same - Order:Different - Values:Different');

INSERT INTO comp_json_values
     VALUES (
               '{"key":"k1","value":"v1"}',
               '{"value2":"v2","key2":"k2"}',
               'Format:Different - Order:Different - Values:Different');

COMMIT;

select * from comp_json_values;

Şimdi yeni alt yapının sunmuş olduğu fonksiyonlar ile json veriyi kontrol edelim. Hangi senaryoda ne gibi sonuçlar alıyoruz.

SELECT json_val_1,
       json_val_2,
       use_case_desc,
       CASE
          WHEN json_equal (json_val_1, json_val_2) THEN 'Match'
          ELSE 'Mismatch'
       END
          json_comp
FROM comp_json_values;

Bu alt yapıyı CASE..WHEN ile kullanabildiğimiz gibi WHERE cümlesinde de kullanabiliyoruz.

SELECT json_val_1, json_val_2, use_case_desc
  FROM comp_json_values
 WHERE json_equal (json_val_1, json_val_2);

select json_val_1, 
       json_val_2, 
       use_case_desc
from comp_json_values
where not json_equal(json_val_1,json_val_2);

Yeni alt yapı ile gelen  yeni fonksiyonlar aynı zamanda PL/SQL içerisinde de basit bir şekilde kullanılabilmektedir.

 

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

Approximate Query Processing

Herkese Selam,

Bu yazıda Oracle 18c ile beraber gelen bazı yeni SQL fonksyonlarından bahsedeceğim umarım farkındalık anlamında faydalı bir yazı olur.

Bilindiği üzere Oracle 18c geçtiğimiz Şubat ayında duyuruldu ve kullanıcılara Cloud ortamlarda kullanımlarına açıldı. Bu gelişmeyi takiben Oracle, LiveSQL platformu üzerinden de son kullanıcıların denemeleri üzerine yeni sürümü kullanıma açtı.

Bu yazıya konu olan fonksiyon denemelerini LiveSQL platformu üzerinden gerçekleştireceğim.

İlk olarak üzerinde çalışacağımız tabloyu yaratalım ve içerisine veri girelim.

CREATE TABLE employees
(
   employee_id      NUMBER (6),
   first_name       VARCHAR2 (20),
   last_name        VARCHAR2 (25) CONSTRAINT emp_last_name_nn NOT NULL,
   email            VARCHAR2 (25) CONSTRAINT emp_email_nn NOT NULL,
   phone_number     VARCHAR2 (20),
   hire_date        DATE CONSTRAINT emp_hire_date_nn NOT NULL,
   job_id           VARCHAR2 (10) CONSTRAINT emp_job_nn NOT NULL,
   salary           NUMBER (8, 2),
   commission_pct   NUMBER (2, 2),
   manager_id       NUMBER (6),
   department_id    NUMBER (4),
   CONSTRAINT emp_salary_min CHECK (salary > 0),
   CONSTRAINT emp_email_uk UNIQUE (email)
);

INSERT INTO employees
     VALUES (100,'Steven','King','SKING','515.123.4567',TO_DATE ('17-HAZ-1987', 'dd-MON-yyyy'),'AD_PRES',24000,NULL,NULL,90);

INSERT INTO employees
     VALUES (101,'Neena','Kochhar','NKOCHHAR','515.123.4568',TO_DATE ('21-SEP-1989', 'dd-MON-yyyy'),'AD_VP',17000,NULL,100,90);

INSERT INTO employees
     VALUES (102,'Lex','De Haan','LDEHAAN','515.123.4569',TO_DATE ('13-JAN-1993', 'dd-MON-yyyy'),'AD_VP',17000,NULL,100,90);

INSERT INTO employees
     VALUES (103,'Alexander','Hunold','AHUNOLD','590.423.4567',TO_DATE ('03-JAN-1990', 'dd-MON-yyyy'),'IT_PROG',9000,NULL,102,60);

INSERT INTO employees
     VALUES (104,'Bruce','Ernst','BERNST','590.423.4568',TO_DATE ('21-MAY-1991', 'dd-MON-yyyy'),'IT_PROG',6000,NULL,103,60);

INSERT INTO employees
     VALUES (105,'David','Austin','DAUSTIN','590.423.4569',TO_DATE ('25-JUN-1997', 'dd-MON-yyyy'),'IT_PROG',4800,NULL,103,60);

INSERT INTO employees
     VALUES (106,'Valli','Pataballa','VPATABAL','590.423.4560',TO_DATE ('05-FEB-1998', 'dd-MON-yyyy'),'IT_PROG',4800,NULL,103,60);

INSERT INTO employees
     VALUES (107,'Diana','Lorentz','DLORENTZ','590.423.5567',TO_DATE ('07-FEB-1999', 'dd-MON-yyyy'),'IT_PROG',4200,NULL,103,60);

INSERT INTO employees
     VALUES (108,'Nancy','Greenberg','NGREENBE','515.124.4569',TO_DATE ('17-AUG-1994', 'dd-MON-yyyy'),'FI_MGR',12000,NULL,101,100);

INSERT INTO employees
     VALUES (109,'Daniel','Faviet','DFAVIET','515.124.4169',TO_DATE ('16-AUG-1994', 'dd-MON-yyyy'),'FI_ACCOUNT',9000,NULL,108,100);

INSERT INTO employees
     VALUES (110,'John','Chen','JCHEN','515.124.4269',TO_DATE ('28-SEP-1997', 'dd-MON-yyyy'),'FI_ACCOUNT',8200,NULL,108,100);

INSERT INTO employees
     VALUES (111,'Ismael','Sciarra','ISCIARRA','515.124.4369',TO_DATE ('30-SEP-1997', 'dd-MON-yyyy'),'FI_ACCOUNT',7700,NULL,108,100);

INSERT INTO employees
     VALUES (112,'Jose Manuel','Urman','JMURMAN','515.124.4469',TO_DATE ('07-MAR-1998', 'dd-MON-yyyy'),'FI_ACCOUNT',7800,NULL,108,100);

INSERT INTO employees
     VALUES (113,'Luis','Popp','LPOPP','515.124.4567',TO_DATE ('07-DEC-1999', 'dd-MON-yyyy'),'FI_ACCOUNT',6900,NULL,108,100);

INSERT INTO employees
     VALUES (114,'Den','Raphaely','DRAPHEAL','515.127.4561',TO_DATE ('07-DEC-1994', 'dd-MON-yyyy'),'PU_MAN',11000,NULL,100,30);

INSERT INTO employees
     VALUES (115,'Alexander','Khoo','AKHOO','515.127.4562',TO_DATE ('18-MAY-1995', 'dd-MON-yyyy'),'PU_CLERK',3100,NULL,114,30);

INSERT INTO employees
     VALUES (116,'Shelli','Baida','SBAIDA','515.127.4563',TO_DATE ('24-DEC-1997', 'dd-MON-yyyy'),'PU_CLERK',2900,NULL,114,30);

INSERT INTO employees
     VALUES (117,'Sigal','Tobias','STOBIAS','515.127.4564',TO_DATE ('24-JUL-1997', 'dd-MON-yyyy'),'PU_CLERK',2800,NULL,114,30);

INSERT INTO employees
     VALUES (118,'Guy','Himuro','GHIMURO','515.127.4565',TO_DATE ('15-NOV-1998', 'dd-MON-yyyy'),'PU_CLERK',2600,NULL,114,30);

INSERT INTO employees
     VALUES (119,'Karen','Colmenares','KCOLMENA','515.127.4566',TO_DATE ('10-AUG-1999', 'dd-MON-yyyy'),'PU_CLERK',2500,NULL,114,30);

INSERT INTO employees
     VALUES (120,'Matthew','Weiss','MWEISS','650.123.1234',TO_DATE ('18-JUL-1996', 'dd-MON-yyyy'),'ST_MAN',8000,NULL,100,50);

INSERT INTO employees
     VALUES (121,'Adam','Fripp','AFRIPP','650.123.2234',TO_DATE ('10-APR-1997', 'dd-MON-yyyy'),'ST_MAN',8200,NULL,100,50);

INSERT INTO employees
     VALUES (122,'Payam','Kaufling','PKAUFLIN','650.123.3234',TO_DATE ('01-MAY-1995', 'dd-MON-yyyy'),'ST_MAN',7900,NULL,100,50);

INSERT INTO employees
     VALUES (123,'Shanta','Vollman','SVOLLMAN','650.123.4234',TO_DATE ('10-OCT-1997', 'dd-MON-yyyy'),'ST_MAN',6500,NULL,100,50);

INSERT INTO employees
     VALUES (124,'Kevin','Mourgos','KMOURGOS','650.123.5234',TO_DATE ('16-NOV-1999', 'dd-MON-yyyy'),'ST_MAN',5800,NULL,100,50);

INSERT INTO employees
     VALUES (125,'Julia','Nayer','JNAYER','650.124.1214',TO_DATE ('16-JUL-1997', 'dd-MON-yyyy'),'ST_CLERK',3200,NULL,120,50);

INSERT INTO employees
     VALUES (126,'Irene','Mikkilineni','IMIKKILI','650.124.1224',TO_DATE ('28-SEP-1998', 'dd-MON-yyyy'),'ST_CLERK',2700,NULL,120,50);

INSERT INTO employees
     VALUES (127,'James','Landry','JLANDRY','650.124.1334',TO_DATE ('14-JAN-1999', 'dd-MON-yyyy'),'ST_CLERK',2400,NULL,120,50);

INSERT INTO employees
     VALUES (128,'Steven','Markle','SMARKLE','650.124.1434',TO_DATE ('08-MAR-2000', 'dd-MON-yyyy'),'ST_CLERK',2200,NULL,120,50);

INSERT INTO employees
     VALUES (129,'Laura','Bissot','LBISSOT','650.124.5234',TO_DATE ('20-AUG-1997', 'dd-MON-yyyy'),'ST_CLERK',3300,NULL,121,50);

INSERT INTO employees
     VALUES (130,'Mozhe','Atkinson','MATKINSO','650.124.6234',TO_DATE ('30-OCT-1997', 'dd-MON-yyyy'),'ST_CLERK',2800,NULL,121,50);

INSERT INTO employees
     VALUES (131,'James','Marlow','JAMRLOW','650.124.7234',TO_DATE ('16-FEB-1997', 'dd-MON-yyyy'),'ST_CLERK',2500,NULL,121,50);

INSERT INTO employees
     VALUES (132,'TJ','Olson','TJOLSON','650.124.8234',TO_DATE ('10-APR-1999', 'dd-MON-yyyy'),'ST_CLERK',2100,NULL,121,50);

INSERT INTO employees
     VALUES (133,'Jason','Mallin','JMALLIN','650.127.1934',TO_DATE ('14-JUN-1996', 'dd-MON-yyyy'),'ST_CLERK',3300,NULL,122,50);

INSERT INTO employees
     VALUES (134,'Michael','Rogers','MROGERS','650.127.1834',TO_DATE ('26-AUG-1998', 'dd-MON-yyyy'),'ST_CLERK',2900,NULL,122,50);

INSERT INTO employees
     VALUES (135,'Ki','Gee','KGEE','650.127.1734',TO_DATE ('12-DEC-1999', 'dd-MON-yyyy'),'ST_CLERK',2400,NULL,122,50);

INSERT INTO employees
     VALUES (136,'Hazel','Philtanker','HPHILTAN','650.127.1634',TO_DATE ('06-FEB-2000', 'dd-MON-yyyy'),'ST_CLERK',2200,NULL,122,50);

INSERT INTO employees
     VALUES (137,'Renske','Ladwig','RLADWIG','650.121.1234',TO_DATE ('14-JUL-1995', 'dd-MON-yyyy'),'ST_CLERK',3600,NULL,123,50);

INSERT INTO employees
     VALUES (138,'Stephen','Stiles','SSTILES','650.121.2034',TO_DATE ('26-OCT-1997', 'dd-MON-yyyy'),'ST_CLERK',3200,NULL,123,50);

INSERT INTO employees
     VALUES (139,'John','Seo','JSEO','650.121.2019',TO_DATE ('12-FEB-1998', 'dd-MON-yyyy'),'ST_CLERK',2700,NULL,123,50);

INSERT INTO employees
     VALUES (140,'Joshua','Patel','JPATEL','650.121.1834',TO_DATE ('06-APR-1998', 'dd-MON-yyyy'),'ST_CLERK',2500,NULL,123,50);

INSERT INTO employees
     VALUES (141,'Trenna','Rajs','TRAJS','650.121.8009',TO_DATE ('17-OCT-1995', 'dd-MON-yyyy'),'ST_CLERK',3500,NULL,124,50);

INSERT INTO employees
     VALUES (142,'Curtis','Davies','CDAVIES','650.121.2994',TO_DATE ('29-JAN-1997', 'dd-MON-yyyy'),'ST_CLERK',3100,NULL,124,50);

INSERT INTO employees
     VALUES (143,'Randall','Matos','RMATOS','650.121.2874',TO_DATE ('15-MAR-1998', 'dd-MON-yyyy'),'ST_CLERK',2600,NULL,124,50);

INSERT INTO employees
     VALUES (144,'Peter','Vargas','PVARGAS','650.121.2004',TO_DATE ('09-JUL-1998', 'dd-MON-yyyy'),'ST_CLERK',2500,NULL,124,50);

INSERT INTO employees
     VALUES (145,'John','Russell','JRUSSEL','011.44.1344.429268',TO_DATE ('01-OCT-1996', 'dd-MON-yyyy'),'SA_MAN',14000,.4,100,80);

INSERT INTO employees
     VALUES (146,'Karen','Partners','KPARTNER','011.44.1344.467268',TO_DATE ('05-JAN-1997', 'dd-MON-yyyy'),'SA_MAN',13500,.3,100,80);

INSERT INTO employees
     VALUES (147,'Alberto','Errazuriz','AERRAZUR','011.44.1344.429278',TO_DATE ('10-MAR-1997', 'dd-MON-yyyy'),'SA_MAN',12000,.3,100,80);

INSERT INTO employees
     VALUES (148,'Gerald','Cambrault','GCAMBRAU','011.44.1344.619268',TO_DATE ('15-OCT-1999', 'dd-MON-yyyy'),'SA_MAN',11000,.3,100,80);

INSERT INTO employees
     VALUES (149,'Eleni','Zlotkey','EZLOTKEY','011.44.1344.429018',TO_DATE ('29-JAN-2000', 'dd-MON-yyyy'),'SA_MAN',10500,.2,100,80);

INSERT INTO employees
     VALUES (150,'Peter','Tucker','PTUCKER','011.44.1344.129268',TO_DATE ('30-JAN-1997', 'dd-MON-yyyy'),'SA_REP',10000,.3,145,80);

INSERT INTO employees
     VALUES (151,'David','Bernstein','DBERNSTE','011.44.1344.345268',TO_DATE ('24-MAR-1997', 'dd-MON-yyyy'),'SA_REP',9500,.25,145,80);

INSERT INTO employees
     VALUES (152,'Peter','Hall','PHALL','011.44.1344.478968',TO_DATE ('20-AUG-1997', 'dd-MON-yyyy'),'SA_REP',9000,.25,145,80);

INSERT INTO employees
     VALUES (153,'Christopher','Olsen','COLSEN','011.44.1344.498718',TO_DATE ('30-MAR-1998', 'dd-MON-yyyy'),'SA_REP',8000,.2,145,80);

INSERT INTO employees
     VALUES (154,'Nanette','Cambrault','NCAMBRAU','011.44.1344.987668',TO_DATE ('09-DEC-1998', 'dd-MON-yyyy'),'SA_REP',7500,.2,145,80);

INSERT INTO employees
     VALUES (155,'Oliver','Tuvault','OTUVAULT','011.44.1344.486508',TO_DATE ('23-NOV-1999', 'dd-MON-yyyy'),'SA_REP',7000,.15,145,80);

INSERT INTO employees
     VALUES (156,'Janette','King','JKING','011.44.1345.429268',TO_DATE ('30-JAN-1996', 'dd-MON-yyyy'),'SA_REP',10000,.35,146,80);

INSERT INTO employees
     VALUES (157,'Patrick','Sully','PSULLY','011.44.1345.929268',TO_DATE ('04-MAR-1996', 'dd-MON-yyyy'),'SA_REP',9500,.35,146,80);

INSERT INTO employees
     VALUES (158,'Allan','McEwen','AMCEWEN','011.44.1345.829268',TO_DATE ('01-AUG-1996', 'dd-MON-yyyy'),'SA_REP',9000,.35,146,80);

INSERT INTO employees
     VALUES (159,'Lindsey','Smith','LSMITH','011.44.1345.729268',TO_DATE ('10-MAR-1997', 'dd-MON-yyyy'),'SA_REP',8000,.3,146,80);

INSERT INTO employees
     VALUES (160,'Louise','Doran','LDORAN','011.44.1345.629268',TO_DATE ('15-DEC-1997', 'dd-MON-yyyy'),'SA_REP',7500,.3,146,80);

INSERT INTO employees
     VALUES (161,'Sarath','Sewall','SSEWALL','011.44.1345.529268',TO_DATE ('03-NOV-1998', 'dd-MON-yyyy'),'SA_REP',7000,.25,146,80);

INSERT INTO employees
     VALUES (162,'Clara','Vishney','CVISHNEY','011.44.1346.129268',TO_DATE ('11-NOV-1997', 'dd-MON-yyyy'),'SA_REP',10500,.25,147,80);

INSERT INTO employees
     VALUES (163,'Danielle','Greene','DGREENE','011.44.1346.229268',TO_DATE ('19-MAR-1999', 'dd-MON-yyyy'),'SA_REP',9500,.15,147,80);

INSERT INTO employees
     VALUES (164,'Mattea','Marvins','MMARVINS','011.44.1346.329268',TO_DATE ('24-JAN-2000', 'dd-MON-yyyy'),'SA_REP',7200,.10,147,80);

INSERT INTO employees
     VALUES (165,'David','Lee','DLEE','011.44.1346.529268',TO_DATE ('23-FEB-2000', 'dd-MON-yyyy'),'SA_REP',6800,.1,147,80);

INSERT INTO employees
     VALUES (166,'Sundar','Ande','SANDE','011.44.1346.629268',TO_DATE ('24-MAR-2000', 'dd-MON-yyyy'),'SA_REP',6400,.10,147,80);

INSERT INTO employees
     VALUES (167,'Amit','Banda','ABANDA','011.44.1346.729268',TO_DATE ('21-APR-2000', 'dd-MON-yyyy'),'SA_REP',6200,.10,147,80);

INSERT INTO employees
     VALUES (168,'Lisa','Ozer','LOZER','011.44.1343.929268',TO_DATE ('11-MAR-1997', 'dd-MON-yyyy'),'SA_REP',11500,.25,148,80);

INSERT INTO employees
     VALUES (169,'Harrison','Bloom','HBLOOM','011.44.1343.829268',TO_DATE ('23-MAR-1998', 'dd-MON-yyyy'),'SA_REP',10000,.20,148,80);

INSERT INTO employees
     VALUES (170,'Tayler','Fox','TFOX','011.44.1343.729268',TO_DATE ('24-JAN-1998', 'dd-MON-yyyy'),'SA_REP',9600,.20,148,80);

INSERT INTO employees
     VALUES (171,'William','Smith','WSMITH','011.44.1343.629268',TO_DATE ('23-FEB-1999', 'dd-MON-yyyy'),'SA_REP',7400,.15,148,80);

INSERT INTO employees
     VALUES (172,'Elizabeth','Bates','EBATES','011.44.1343.529268',TO_DATE ('24-MAR-1999', 'dd-MON-yyyy'),'SA_REP',7300,.15,148,80);

INSERT INTO employees
     VALUES (173,'Sundita','Kumar','SKUMAR','011.44.1343.329268',TO_DATE ('21-APR-2000', 'dd-MON-yyyy'),'SA_REP',6100,.10,148,80);

INSERT INTO employees
     VALUES (174,'Ellen','Abel','EABEL','011.44.1644.429267',TO_DATE ('11-MAY-1996', 'dd-MON-yyyy'),'SA_REP',11000,.30,149,80);

INSERT INTO employees
     VALUES (175,'Alyssa','Hutton','AHUTTON','011.44.1644.429266',TO_DATE ('19-MAR-1997', 'dd-MON-yyyy'),'SA_REP',8800,.25,149,80);

INSERT INTO employees
     VALUES (176,'Jonathon','Taylor','JTAYLOR','011.44.1644.429265',TO_DATE ('24-MAR-1998', 'dd-MON-yyyy'),'SA_REP',8600,.20,149,80);

INSERT INTO employees
     VALUES (177,'Jack','Livingston','JLIVINGS','011.44.1644.429264',TO_DATE ('23-APR-1998', 'dd-MON-yyyy'),'SA_REP',8400,.20,149,80);

INSERT INTO employees
     VALUES (178,'Kimberely','Grant','KGRANT','011.44.1644.429263',TO_DATE ('24-MAY-1999', 'dd-MON-yyyy'),'SA_REP',7000,.15,149,NULL);

INSERT INTO employees
     VALUES (179,'Charles','Johnson','CJOHNSON','011.44.1644.429262',TO_DATE ('04-JAN-2000', 'dd-MON-yyyy'),'SA_REP',6200,.10,149,80);

INSERT INTO employees
     VALUES (180,'Winston','Taylor','WTAYLOR','650.507.9876',TO_DATE ('24-JAN-1998', 'dd-MON-yyyy'),'SH_CLERK',3200,NULL,120,50);

INSERT INTO employees
     VALUES (181,'Jean','Fleaur','JFLEAUR','650.507.9877',TO_DATE ('23-FEB-1998', 'dd-MON-yyyy'),'SH_CLERK',3100,NULL,120,50);

INSERT INTO employees
     VALUES (182,'Martha','Sullivan','MSULLIVA','650.507.9878',TO_DATE ('21-JUN-1999', 'dd-MON-yyyy'),'SH_CLERK',2500,NULL,120,50);

INSERT INTO employees
     VALUES (183,'Girard','Geoni','GGEONI','650.507.9879',TO_DATE ('03-FEB-2000', 'dd-MON-yyyy'),'SH_CLERK',2800,NULL,120,50);

INSERT INTO employees
     VALUES (184,'Nandita','Sarchand','NSARCHAN','650.509.1876',TO_DATE ('27-JAN-1996', 'dd-MON-yyyy'),'SH_CLERK',4200,NULL,121,50);

INSERT INTO employees
     VALUES (185,'Alexis','Bull','ABULL','650.509.2876',TO_DATE ('20-FEB-1997', 'dd-MON-yyyy'),'SH_CLERK',4100,NULL,121,50);

INSERT INTO employees
     VALUES (186,'Julia','Dellinger','JDELLING','650.509.3876',TO_DATE ('24-JUN-1998', 'dd-MON-yyyy'),'SH_CLERK',3400,NULL,121,50);

INSERT INTO employees
     VALUES (187,'Anthony','Cabrio','ACABRIO','650.509.4876',TO_DATE ('07-FEB-1999', 'dd-MON-yyyy'),'SH_CLERK',3000,NULL,121,50);

INSERT INTO employees
     VALUES (188,'Kelly','Chung','KCHUNG','650.505.1876',TO_DATE ('14-JUN-1997', 'dd-MON-yyyy'),'SH_CLERK',3800,NULL,122,50);

INSERT INTO employees
     VALUES (189,'Jennifer','Dilly','JDILLY','650.505.2876',TO_DATE ('13-AUG-1997', 'dd-MON-yyyy'),'SH_CLERK',3600,NULL,122,50);

INSERT INTO employees
     VALUES (190,'Timothy','Gates','TGATES','650.505.3876',TO_DATE ('11-JUL-1998', 'dd-MON-yyyy'),'SH_CLERK',2900,NULL,122,50);

INSERT INTO employees
     VALUES (191,'Randall','Perkins','RPERKINS','650.505.4876',TO_DATE ('19-DEC-1999', 'dd-MON-yyyy'),'SH_CLERK',2500,NULL,122,50);

INSERT INTO employees
     VALUES (192,'Sarah','Bell','SBELL','650.501.1876',TO_DATE ('04-FEB-1996', 'dd-MON-yyyy'),'SH_CLERK',4000,NULL,123,50);

INSERT INTO employees
     VALUES (193,'Britney','Everett','BEVERETT','650.501.2876',TO_DATE ('03-MAR-1997', 'dd-MON-yyyy'),'SH_CLERK',3900,NULL,123,50);

INSERT INTO employees
     VALUES (194,'Samuel','McCain','SMCCAIN','650.501.3876',TO_DATE ('01-JUL-1998', 'dd-MON-yyyy'),'SH_CLERK',3200,NULL,123,50);

INSERT INTO employees
     VALUES (195,'Vance','Jones','VJONES','650.501.4876',TO_DATE ('17-MAR-1999', 'dd-MON-yyyy'),'SH_CLERK',2800,NULL,123,50);

INSERT INTO employees
     VALUES (196,'Alana','Walsh','AWALSH','650.507.9811',TO_DATE ('24-APR-1998', 'dd-MON-yyyy'),'SH_CLERK',3100,NULL,124,50);

INSERT INTO employees
     VALUES (197,'Kevin','Feeney','KFEENEY','650.507.9822',TO_DATE ('23-MAY-1998', 'dd-MON-yyyy'),'SH_CLERK',3000,NULL,124,50);

INSERT INTO employees
     VALUES (198,'Donald','OConnell','DOCONNEL','650.507.9833',TO_DATE ('21-JUN-1999', 'dd-MON-yyyy'),'SH_CLERK',2600,NULL,124,50);

INSERT INTO employees
     VALUES (199,'Douglas','Grant','DGRANT','650.507.9844',TO_DATE ('13-JAN-2000', 'dd-MON-yyyy'),'SH_CLERK',2600,NULL,124,50);

INSERT INTO employees
     VALUES (200,'Jennifer','Whalen','JWHALEN','515.123.4444',TO_DATE ('17-SEP-1987', 'dd-MON-yyyy'),'AD_ASST',4400,NULL,101,10);

INSERT INTO employees
     VALUES (201,'Michael','Hartstein','MHARTSTE','515.123.5555',TO_DATE ('17-FEB-1996', 'dd-MON-yyyy'),'MK_MAN',13000,NULL,100,20);

INSERT INTO employees
     VALUES (202,'Pat','Fay','PFAY','603.123.6666',TO_DATE ('17-AUG-1997', 'dd-MON-yyyy'),'MK_REP',6000,NULL,201,20);

INSERT INTO employees
     VALUES (203,'Susan','Mavris','SMAVRIS','515.123.7777',TO_DATE ('07-JUN-1994', 'dd-MON-yyyy'),'HR_REP',6500,NULL,101,40);

INSERT INTO employees
     VALUES (204,'Hermann','Baer','HBAER','515.123.8888',TO_DATE ('07-JUN-1994', 'dd-MON-yyyy'),'PR_REP',10000,NULL,101,70);

INSERT INTO employees
     VALUES (205,'Shelley','Higgins','SHIGGINS','515.123.8080',TO_DATE ('07-JUN-1994', 'dd-MON-yyyy'),'AC_MGR',12000,NULL,101,110);

INSERT INTO employees
     VALUES (206,'William','Gietz','WGIETZ','515.123.8181',TO_DATE ('07-JUN-1994', 'dd-MON-yyyy'),'AC_ACCOUNT',8300,NULL,205,110);

COMMIT;

Gerek yaptığımız rutin data testlerinde, gerekse veri analiz ederken COUNT, SUM, RANK komutlarını sık bir şekilde kullanırız. Bu komutların çalışma süresi verimizin büyüklüğüne göre bazen bir hayli zaman alabilmekte. Bunun temel nedeni işlemlerin çalışma maliyetlerinin yüksek olması ve çoğunlukla verinin tamamına erişme ihtiyaçlarının olmasıdır. Oracle,  bu operasyonların veri boyutuna bağımlı olarak işlem süresinin uzaması durumuna APPROXIMATE QUERY PROCESSING  hızlı çalışan alternatif bir yol üretmiş durumda. (Approximate Query Processing hayatımıza Oracle 12c ile beraber girmişti. Bu özellik geldiğinde bununla ilgili bir yazı paylaşmıştım. Linki takip ederek okuyabilirsiniz. Oracle, 18c sürümü ile bu kısıma yeni fonksiyonlar kazandırdı.) Ancak bu komut setinin %100 doğrulukla bir sonuç üretmediğini unutmamız gerekmekte . Bu alt yapı verinin boyutuna göre göz ardı edebilecek sapmalar ile sonucu hızlı bir şekilde bulabilmekte.

Şimdi APPROX_COUNT(), APPROX_SUM() ve APPROX_RANK() fonksiyonlarının ne yaptıklarını ve nasıl çalıştıklarını inceleyelim.

APPROX_COUNT:  Bu fonksiyon sorgu sonucunda oluşacak toplam satır sayısını yaklaşık ve hızlı bir şekilde getirmeye çalışır.  Bu fonksiyonu kullanmak istiyorsak mutlaka having  söz deyimini de kullanmak zorundayız. Aksi takdirde sorgu hata alır.  Buna ek olarak APPROX_COUNT söz deyimi ile beraber herhangi bir aggregated fonksiyonu sorgu içinde kullanamamaktayız. Şimdi basit olarak nasıl çalıştığına bakalım.

Aşağıdaki sorgu her departmanda, en yaygın çalışılan 5 işi döndürür.

SELECT  DEPARTMENT_ID,
        JOB_ID, 
        APPROX_COUNT(*)
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID, JOB_ID
HAVING APPROX_RANK(PARTITION BY DEPARTMENT_ID ORDER BY APPROX_COUNT(*) DESC) <= 5;

APPROX_COUNT ile MAX_ERROR söz deyimini kullanarak gerçek olan sayı ile APPROX_COUNT sonunda bulunan yaklaşık değer arasındaki farkı da görebiliriz.

SELECT  DEPARTMENT_ID,
        JOB_ID, 
        APPROX_COUNT(*) appr_count,
        APPROX_COUNT(*,'MAX_ERROR') appr_error
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID, JOB_ID
HAVING APPROX_RANK(PARTITION BY DEPARTMENT_ID ORDER BY APPROX_COUNT(*) DESC) <= 5;

APPROX_SUM:  Bu fonksiyon sorgu sonucunda oluşacak toplam değeri yaklaşık ve hızlı bir şekilde getirmeye çalışır.  Bu fonksiyonu kullanmak istiyorsak mutlaka having  söz deyimini de kullanmak zorundayız. Aksi takdirde sorgu hata alır.  Buna ek olarak APPROX_SUM söz deyimi ile beraber herhangi bir aggregated fonksiyonu sorgu içinde kullanamamaktayız. Şimdi basit olarak nasıl çalıştığına bakalım.

Aşağıdaki sorgu her departman içerisinde, çalışanlarının maaş toplamı en yüksek işi döndürür.

SELECT  DEPARTMENT_ID,
        JOB_ID, 
        APPROX_SUM(SALARY) appr_sum
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID, JOB_ID
HAVING APPROX_RANK(PARTITION BY DEPARTMENT_ID ORDER BY APPROX_SUM(SALARY) DESC) <= 1;

APPROX_SUM ile MAX_ERROR söz deyimini kullanarak gerçek olan toplam ile APPROX_SUM sonunda bulunan yaklaşık toplam arasındaki farkı da görebiliriz.

APPROX_RANK:  Bu fonksiyon sorgu sonucunda oluşacak yaklaşık sıralamayı döndürür.  Bu fonksiyonu kullanmak istiyorsak mutlaka having  söz deyimini de kullanmak zorundayız. Aksi takdirde sorgu hata alır.  Buna ek olarak APPROX_RANK söz deyimi ile beraber herhangi bir aggregated fonksiyonu sorgu içinde kullanamamaktayız.   APPROX_RANK ile beraber PARTITION BY  ve ORDER BY deyimlerini de kullanabilmekteyiz.  Ancak ORDER BY deyimini kullanırsak bu deyim APPROX_RANK veya APPROX_SUM deyimini içinde mutlaka barındırmalı. Şimdi basit olarak nasıl çalıştığına bakalım.

Aşağıdaki sorgu her departman içerisinde, çalışanlarının maaş toplamını iş bazında hesaplayıp azalan bir sıralama yapar ve sıralama sonucunda ilk 2 kayıtı getirir.

SELECT department_id, 
       job_id,
       APPROX_RANK(PARTITION BY department_id ORDER BY APPROX_SUM(salary) DESC) appr_rnk
FROM employees
GROUP BY department_id, job_id
HAVING APPROX_RANK(PARTITION BY department_id ORDER BY APPROX_SUM (salary) DESC) <= 2;

 

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

Oracle 18c Kullanmaya Başlayalım

Herkese Selam,

Oracle18cOracle kısa bir süre önce yeni DB sürümü olan 18c’yi geçtiğimiz Şubat ayında duyurdu. Oracle 18c yine Cloud base çalışan ve otonom olduğu iddiası ileilgileri üzerine çeken ve bunların yanında yeni bir çok özelliğe sahip olan bir veritabanı yazılımı olmuş gibi görünüyor.

Oracle 18c ile ilgili bilgi sahibi olmak için linki takip edebilirsiniz.

Oracle, 18c sürümünü hızlıca deneyebilmek adına ise çok güzel bir iş daha yapmış ve LiveSQL platformuna 18c’yi hemen entegre etmiş.  LiveSQL  platformu üzerinden 18c veritabanını hızlıca deneyimleyebilmek mümkün.

livesql

 

 

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

Reinforcement Learning ile Optimal Yol Tespiti

Herkese Selam,

Bu yazıda Reinformcement Learning yöntemlerinden biri olan Q-Learning ile örnek bir harita üzerinden en optimum yolu bulan bir agent tasarımı yapacağım. Umarım farkındalık anlamında faydalı bir yazı olur.


Reinforcement Learning (RL),  bir ödülün en üst düzeye çıkarılması için, belirli bir durumda yapılması gereken optimum eylemleri bulma problemleri ile ilgilenen bir makine öğrenmesi tekniğidir.

Esinlendiği nokta davranış piskolojisi olan bu öğrenme tekniği genellikle şu şekilde anlatılır. Herhangi bir ortamda (environment) bulunan bir agent bu ortam içerisinde belirli hareketler yapar ve bu hareketler sonucunda ödüller kazanır (rewards).  Ana amaç toplamda kazanılacak ödülü maksimize etmek ve uzun erimde en fazla ödülü kazandıracak hareket serisini (optimal policy) öğrenmektir.

Reinforcement Learning’in en sık kullanıldığı uygulamaların başında oyunlar gelmektedir. Örneğin 90’lı yıllarda Tavla oyununda bir insanı yenen makine RL ile öğrenimini gerçekleştirmişti. Yine yakın zamanda Dünyanın en iyi GO oyuncusunu yenen makinede öğrenimini RL ile gerçekleştirmişti (Google DeepMind’s Alpha GO).  Bu uygulamalara ek olarak Robotik de, Kontrol’de,  Otonom Araçlarda ve buna benzer bir çok endüstriyel alanlarda da RL tekniğine sık bir şekilde başvurulmaktadır.

Reinforcement Learning derinliği olan detaylı bir konu olduğundan dolayı bu yazı içerisinde daha fazla bu tekniğin detayını anlatmayacağım ancak merak edenler aşağıdaki video’dan veya internet üzerinden aramalar yaparak örnek uygulamaları ve bu tekniğin teorisini öğrenmeye başlayabilirler.

Şimdi bu yazıya konu olacak örnek bir uygulama geliştirme işine geçebiliriz.

Q-Learning For Optimal Hiking

Elimizde şekildeki gibi bir harita var ve bu haritada başlangıç noktasından başlayarak bitiş noktasına en fazla toplam ödülü elde ederek nasıl ulaşabileceğim sorusunun cevabını arıyorum. Ancak bu haritada bir hücreden diğer hücreye geçerken kazanılan ödüller farklı durumlara göre değişkenlik gösteriyor. Haritadan da görüleceğe üzere düzlük ve tepe şeklinde hücreler mevcut bu hücreler arasındaki geçişlerin ödülleri ise aşağıdaki şekilde bize verilmekte.

Düzlük bir hücreden, düzlük bir hücreye geçişte(P-P): -1

Düzlük bir hücreden, tepe bir hücreye geçişte(P-H):-3

Tepe bir hücreden, düz bir hücreye geçişte(H-P): -1

Tepe bir hücreden, Tepe bir hücreye geçişte(H-H): -2

Herhangi bir hücreden, hedef hücreye geçişte: 10

Görüldüğü üzere, elimizde haritanın nasıl olduğu (environment) ve durumlar arasında geçiş yaparken ne kadarlık bir ödül kazandığımız bilgisi bulunuyor. Biz bu verilenleri kullanarak en optimum yolculuğu Q-Learning yöntemi ile öğrenmeye çalışacağız. Q-Learning’in temel mantığı, agent’ın ortam üzerinde yaşadığı deneyimleri kullanarak maksimum fayda ile yolculuğu nasıl bitirebileceğini bulmaktır. Bunun için agent’ın defalarca ortam üzerinde farklı hareketler yaparak ortamı en iyi şekilde öğrenmesi amaçlanmaktadır.

Şimdi yukarıdaki gibi verilen bir haritada kazanacağı ödülü maksimize ederek sonuca gidecek ve optimal yolu bulacak bir Reinforcement Learning kodu yazalım ve sonuçları gözlemleyelim.

Kodu MATLAB ile implemente edeceğiz.

İlk etapta çözmek istediğimiz haritayı ve gerekli tanımlamaları yapıyoruz.

%****************************************************
%Defining Maze Setup
goalmark = 4;
startmark = 2;
rewards = [-1 -2 -3 -1]; 


        %****************************************************
        %You can change maze whatever you want
        %We need 1 start and 1 stop state.
        maze =[  1 0 0 1 1
                 0 2 0 1 0
                 0 0 0 0 0
                 0 0 1 1 0
                 1 0 1 1 0
                 1 1 1 1 4]; 
        %****************************************************

actUp=3;
actDown=4;
actLeft=1;
actRight=2;
ACTIONS = [actLeft, actRight, actUp, actDown];

mazeSize = size(maze);
mazeRow = mazeSize(1);
mazeColumn = mazeSize(2);
%****************************************************

Şimdi ise durumlar arası kazanılacak ödül matrisini oluşturuyoruz.

%****************************************************
%Construct Reward Matrix
rewardMat =  zeros(mazeRow*mazeColumn,length(ACTIONS));
transitMat = zeros(mazeRow*mazeColumn,length(ACTIONS));
stateIterator=0;
rew = 0;
rewforGoal =10;
for i=1:mazeRow
    for j=1:mazeColumn
        stateIterator = (i-1)*mazeColumn+j;     % Defining Current State
        
        %****************************************************
        %Up
        if(i-1>=1)
            if(maze(i-1,j)==0 && maze(i,j)==0)  % plain plain
                rew = -1;
            end
            if(maze(i-1,j)==0 && maze(i,j)==1)  % hill plain
                rew = -1;
            end
            if(maze(i-1,j)==1 && maze(i,j)==0)  % plain hill
                rew = -3;
            end
            if(maze(i-1,j)==1 && maze(i,j)==1)  % hill-hill
                rew = -2;
            end
                        
            if maze(i-1,j)==goalmark
                rewardMat(stateIterator,actUp)= rewforGoal; 
            else
                rewardMat(stateIterator,actUp)= rew;
            end
            
            transitMat(stateIterator,actUp) = stateIterator-(abs(mazeColumn-j)+abs(1-j)+1);
        end
        
        %****************************************************
        %Down
        if(i+1<=mazeRow) if(maze(i+1,j)==0 && maze(i,j)==0) % plain plain rew = -1; end if(maze(i+1,j)==0 && maze(i,j)==1) % hill plain rew = -1; end if(maze(i+1,j)==1 && maze(i,j)==0) % plain hill rew = -3; end if(maze(i+1,j)==1 && maze(i,j)==1) % hill-hill rew = -2; end if maze(i+1,j)==goalmark rewardMat(stateIterator,actDown)= rewforGoal; %10 else rewardMat(stateIterator,actDown)= rew; end transitMat(stateIterator,actDown) = stateIterator+(abs(mazeColumn-j)+abs(1-j)+1); end %**************************************************** %Left if(j-1>0)
            if(maze(i,j-1)==0 && maze(i,j)==0) % plain plain
                rew = -1;
            end
            if(maze(i,j-1)==0 && maze(i,j)==1) % hill plain
                rew = -1;
            end
            if(maze(i,j-1)==1 && maze(i,j)==0) % plain hill
                rew = -3;
            end
            if(maze(i,j-1)==1 && maze(i,j)==1) % hill-hill
                rew = -2;
            end
            
            if maze(i,j-1)==goalmark
                rewardMat(stateIterator,actLeft)= rewforGoal;  %10
            else
                rewardMat(stateIterator,actLeft)= rew;
            end
                        
            transitMat(stateIterator,actLeft) = stateIterator-1;
        end
        
        %****************************************************
        %Right
        if(j+1<=mazeColumn)
            if(maze(i,j+1)==0 && maze(i,j)==0) % plain plain
                rew = -1;
            end
            if(maze(i,j+1)==0 && maze(i,j)==1) % hill plain
                rew = -1;
            end
            if(maze(i,j+1)==1 && maze(i,j)==0) % plain hill
                rew = -3;
            end
            if(maze(i,j+1)==1 && maze(i,j)==1) % hill-hill
                rew = -2;
            end
            
            
            if maze(i,j+1)==goalmark
                rewardMat(stateIterator,actRight)= rewforGoal;  %10
            else
                rewardMat(stateIterator,actRight)= rew;
            end
            
            transitMat(stateIterator,actRight) = stateIterator+1;
        end
        %****************************************************
    end
end

Sıra kod içerisinde kullanacağımız diğer parametreleri tanımlama kısmına geldi. Bu tanımları yapıyoruz.

%**************************************
%Finding Goal and Start states positions
[sx,sy] = find(maze==startmark);
startState = (sx-1)*mazeColumn+sy;

[gx,gy] = find(maze==goalmark);
goalState = (gx-1)*mazeColumn+gy;

%**************************************
%Initializing Parameteters
Q = transitMat*0; 
Q(goalState,1)= 10; 
gamma = 1;
alpha = 0.5;
randomProb = 0.25;
tx = sx;
ty = sy;
V = zeros(mazeColumn*mazeRow,1);
episode=30000;
stepSize=20;
rewforGoal =10;
%**************************************

Sırada öğrenmeyi gerçekleştirecek kısmı kodlamaya geldi (Q-Learning).

%**************************************
%Start Q Learning
for it=1:episode
    tx = sx;
    ty = sy;
    next=0;
    for step=1:stepSize
        next = 0;
        
        %*************************************
        %Defining Current Position and fing possible actions
        curr =  (tx-1)*mazeColumn+ty;
        actionOptions = Q(curr,:);
        %*************************************
        
        %*************************************
        % Finding Next Action with using random probability
        while next==0
            %choosing random action
            if rand < randomProb
                randAction = randperm(length(actionOptions));
                index = randAction(1);
            else
                [value, index] = max(actionOptions);
            end
            next = transitMat(curr, index);
        end
        %*************************************
        
        %*************************************
        % Get reward for current position
        rew = rewardMat(curr,index);
        %*************************************
        
        
        %*************************************
        % Q Learning Equation
        if(curr~=goalState)
            Q(curr,index) = Q(curr,index) + alpha*( (rew+gamma*max(Q(next,:))) - (Q(curr,index)));
        end
        %*************************************
        
        %*************************************
        % Finding Next Step Position
        sect = fix((next/mazeColumn));
        
        if sect == 0
            sect =1;
        end
        
        rest = mod(next,mazeColumn);
        
        if next==mazeColumn*mazeRow
            tx = sect;
            ty = mazeColumn;
        else
            if ty == 0
                tx = sect;
                ty = mazeColumn;
            else
                tx = sect+1;
                ty = rest;
            end                        
        end
        %*************************************
        
    end
end
%*****************************************

Şimdi ise yazdığımız algoritmayı görselleştirelim.

%****************PLOT*********************


%***********************************************
 % get the figure and axes handles
 hFig = gcf;
 hAx  = gca;
 % set the figure to full screen
 set(hFig,'units','normalized','outerposition',[0 0 1 1]);
%***********************************************
 
 
%***********************************************
%Plot V Values using Q Matrix
subplot(1,3,1);
V = max(Q,[],2);
V = reshape(V,mazeRow,mazeColumn);
%V(goalState) = 10;
imagesc(V); 
title('V Values');
hold on;
for i=1:mazeRow
    for j=1:mazeColumn
        cell = (i-1)*mazeColumn+j;
        content = sprintf('%2.2f',V(cell));
        labels = text(j-0.20,i, content); 
        set(labels);
    end
end
%***********************************************


%***********************************************
%Plot Q Values
subplot(1,3,2);
imagesc(maze);
title('Q Values');
hold on;
for i=1:mazeRow
    for j=1:mazeColumn
        cell = (i-1)*mazeColumn+j;
        
        label1 = text(j-0.15,i-0.21, sprintf('%2.2f',Q(cell,actUp))); 
        set(label1,'FontSize',8);

        label2 = text(j-0.15,i+0.22, sprintf('%2.2f',Q(cell,actDown))); 
        set(label2,'FontSize',8);
        
        label3 = text(j-0.40,i, sprintf('%2.2f',Q(cell,actLeft))); 
        set(label3,'FontSize',8);
        
        label4 = text(j+0.16,i, sprintf('%2.2f',Q(cell,actRight))); 
        set(label4,'FontSize',8);        
    end
end
%***********************************************


%***********************************************
%Plot Optimal Path
subplot(1,3,3);
imagesc(maze);
title('Optimal Path');
hold on;
curr = startState;
tx = sx;
ty = sy;
QPr = Q;
QPr(QPr==0)=-1000;
while curr~=goalState
    curr =  (tx-1)*mazeColumn+ty;
    
    if curr==startState
        labelN = text(ty-0.40,tx-0.4, sprintf('START'));
        set(labelN,'FontSize',15);
    elseif curr==goalState
        labelN = text(ty-0.35,tx, sprintf('GOAL'));
        set(labelN,'FontSize',15);
        continue;
    end
        
    actionOptions = QPr(curr,:);    
    [value, index] = max(actionOptions);        
    
    if index == actLeft
        labelN = text(ty-0.2,tx, sprintf('L'));
        set(labelN,'FontSize',25);
        ty = ty-1;
    end
    
    if index == actRight
        labelN = text(ty-0.2,tx, sprintf('R'));
        set(labelN,'FontSize',25);
        ty = ty+1;
    end
    
    if index == actUp
        labelN = text(ty-0.2,tx, sprintf('U'));
        set(labelN,'FontSize',25);
        tx = tx -1;
    end
    
    if index == actDown
        labelN = text(ty-0.2,tx, sprintf('D'));
        set(labelN,'FontSize',25);
        tx = tx +1;
    end
end
%***********************************************

Şimdi yazdığımız kodu deneyip test edelim.

İlk olarak aşağıdaki gibi bir harita veriyorum.
maze =[ 1 0 2 1 1
0 0 0 1 0
0 0 0 0 0
0 0 1 1 0
1 4 1 1 0
1 1 1 1 1];

0: Düzlük
1: Tepe
2: Başlangıç Noktası
4: Bitiş Noktası

Parametreler: Gamma:0.7- Alpha: 0.5 – Episode: 30000

Sonuç:

Çıktı olarak 3 farklı matrisimiz var. Bunlardan birincisi bulunan V değerlerini  İkincisi bulunan Q değerleri, üçüncüsü ise optimal path’in ne olduğunu gösteriyor.

 

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