رگرسیون لجستیک با استفاده از tensorflow

فهرست مطالب
در درس سی و چهارم از نیچ کورس آموزش رایگان یادگیری ماشین با پایتون می خواهیم در مورد رگرسیون لجستیک با استفاده از tensorflow صحبت کنیم.
رگرسیون لجستیک (Logistic Regression) یک الگوریتم طبقهبندی است که در یادگیری ماشین کاربرد زیادی دارد. این روش به ما امکان میدهد تا با یادگیری ارتباطات موجود در مجموعه دادههای دارای برچسب، دادهها را به دستههای مشخصی تقسیم کنیم. این الگوریتم ابتدا یک رابطه خطی از دادهها را یاد میگیرد و سپس با افزودن تابع غیرخطی سیگموئید، تغییری در آن ایجاد میکند.
در رگرسیون لجستیک، فرضیه ما سیگموئید یک خط راست است، به این صورت:
که در آن:
است. در این فرمول، بردار w وزنها و عدد b بایاس مدل را نشان میدهند.
حالا بیایید نگاهی به نمودار تابع سیگموئید بیندازیم.
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(z):
return 1 / (1 + np.exp( - z))
plt.plot(np.arange(-5, 5, 0.1), sigmoid(np.arange(-5, 5, 0.1)))
plt.title('Visualization of the Sigmoid Function')
plt.show() توجه کنید که محدوده تابع سیگموئید بین (0, 1) است، به این معنی که مقادیر حاصل از آن بین 0 و 1 قرار دارند. این ویژگی تابع سیگموئید باعث میشود که این تابع به عنوان یک تابع فعالسازی، بسیار مناسب برای دستهبندی دوتایی باشد. همچنین برای z = 0، مقدار Sigmoid(z) برابر با 0.5 است که نقطه میانی محدوده تابع سیگموئید میباشد.
همانند رگرسیون خطی، ما نیاز داریم تا بهترین مقادیر برای w و b را پیدا کنیم که در آن تابع هزینه J کمینه باشد. در این مورد، از تابع هزینه “Sigmoid Cross Entropy” استفاده خواهیم کرد که به صورت زیر بیان میشود:
سپس این تابع هزینه با استفاده از روش گرادیان کاهشی بهینهسازی خواهد شد.
اجرا:
ابتدا با وارد کردن کتابخانههای لازم شروع میکنیم. برای محاسبات از کتابخانههای Numpy و Tensorflow، برای تحلیل دادههای اولیه از Pandas و برای نمودارکشی از Matplotlib استفاده خواهیم کرد. همچنین از ماژول پیشپردازش Scikit-Learn برای کدگذاری (One Hot Encoding) دادهها استفاده خواهیم کرد.
# importing modules import numpy as np import pandas as pd import tensorflow as tf import matplotlib.pyplot as plt from sklearn.preprocessing import OneHotEncoder
سپس، دیتاست را وارد خواهیم کرد. از یک زیرمجموعه از دیتاست معروف Iris استفاده خواهیم کرد.
data = pd.read_csv('dataset.csv', header = None)
print("Data Shape:", data.shape)
print(data.head()) خروجی:
Data Shape: (100, 4) 0 1 2 3 0 0 5.1 3.5 1 1 1 4.9 3.0 1 2 2 4.7 3.2 1 3 3 4.6 3.1 1 4 4 5.0 3.6 1
حالا بیایید ماتریس ویژگیها و برچسبهای مرتبط را دریافت کنیم و آنها را تصویر کنیم.
# Feature Matrix
x_orig = data.iloc[:, 1:-1].values
# Data labels
y_orig = data.iloc[:, -1:].values
print("Shape of Feature Matrix:", x_orig.shape)
print("Shape Label Vector:", y_orig.shape) خروجی:
Shape of Feature Matrix: (100, 2) Shape Label Vector: (100, 1)
بصریسازی دیتا
# Positive Data Points
x_pos = np.array([x_orig[i] for i in range(len(x_orig))
if y_orig[i] == 1])
# Negative Data Points
x_neg = np.array([x_orig[i] for i in range(len(x_orig))
if y_orig[i] == 0])
# Plotting the Positive Data Points
plt.scatter(x_pos[:, 0], x_pos[:, 1], color = 'blue', label = 'Positive')
# Plotting the Negative Data Points
plt.scatter(x_neg[:, 0], x_neg[:, 1], color = 'red', label = 'Negative')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Plot of given data')
plt.legend()
plt.show() اکنون ما دادهها را با استفاده از روش One Hot Encoding تبدیل خواهیم کرد تا با الگوریتم هماهنگ شود. کدگذاری واتهات ویژگیهای دستهای را به فرمتی تبدیل میکند که بهتر با الگوریتمهای دستهبندی و رگرسیون کار میکند. همچنین، ما نرخ یادگیری و تعداد دورهها (Epochs) را تنظیم خواهیم کرد.
# Creating the One Hot Encoder
oneHot = OneHotEncoder()
# Encoding x_orig
oneHot.fit(x_orig)
x = oneHot.transform(x_orig).toarray()
# Encoding y_orig
oneHot.fit(y_orig)
y = oneHot.transform(y_orig).toarray()
alpha, epochs = 0.0035, 500
m, n = x.shape
print('m =', m)
print('n =', n)
print('Learning Rate =', alpha)
print('Number of Epochs =', epochs) خروجی:
m = 100 n = 7 Learning Rate = 0.0035 Number of Epochs = 500
حالا شروع میکنیم به ساختن مدل با تعریف پلیسهولدرهای (placeholders) X و Y. این کار به ما این امکان را میدهد که نمونههای آموزشی x و y را در طول فرایند آموزش به سیستم وارد کنیم. همچنین، ما به ساخت متغیرهای قابل یادگیری W و b میپردازیم که قابل بهینهسازی توسط روش گرادیان کاهشی هستند.
# There are n columns in the feature matrix # after One Hot Encoding. X = tf.placeholder(tf.float32, [None, n]) # Since this is a binary classification problem, # Y can take only 2 values. Y = tf.placeholder(tf.float32, [None, 2]) # Trainable Variable Weights W = tf.Variable(tf.zeros([n, 2])) # Trainable Variable Bias b = tf.Variable(tf.zeros([2]))
در مرحله بعد، فرضیه، تابع هزینه، بهینهساز و اولیهسازی متغیرهای global را تعریف میکنیم.
# Hypothesis Y_hat = tf.nn.sigmoid(tf.add(tf.matmul(X, W), b)) # Sigmoid Cross Entropy Cost Function cost = tf.nn.sigmoid_cross_entropy_with_logits( logits = Y_hat, labels = Y) # Gradient Descent Optimizer optimizer = tf.train.GradientDescentOptimizer( learning_rate = alpha).minimize(cost) # Global Variables Initializer init = tf.global_variables_initializer()
فرایند آموزش را درون یک TensorFlow Sessionشروع کنید.
# Starting the Tensorflow Session
with tf.Session() as sess:
# Initializing the Variables
sess.run(init)
# Lists for storing the changing Cost and Accuracy in every Epoch
cost_history, accuracy_history = [], []
# Iterating through all the epochs
for epoch in range(epochs):
cost_per_epoch = 0
# Running the Optimizer
sess.run(optimizer, feed_dict = {X : x, Y : y})
# Calculating cost on current Epoch
c = sess.run(cost, feed_dict = {X : x, Y : y})
# Calculating accuracy on current Epoch
correct_prediction = tf.equal(tf.argmax(Y_hat, 1),
tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,
tf.float32))
# Storing Cost and Accuracy to the history
cost_history.append(sum(sum(c)))
accuracy_history.append(accuracy.eval({X : x, Y : y}) * 100)
# Displaying result on current Epoch
if epoch % 100 == 0 and epoch != 0:
print("Epoch " + str(epoch) + " Cost: "
+ str(cost_history[-1]))
Weight = sess.run(W) # Optimized Weight
Bias = sess.run(b) # Optimized Bias
# Final Accuracy
correct_prediction = tf.equal(tf.argmax(Y_hat, 1),
tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,
tf.float32))
print("\nAccuracy:", accuracy_history[-1], "%") خروجی:
Epoch 100 Cost: 125.700202942 Epoch 200 Cost: 120.647117615 Epoch 300 Cost: 118.151592255 Epoch 400 Cost: 116.549999237 Accuracy: 91.0000026226 %
بیایید تغییرات هزینه را در طول دورهها (Epochs) پلات کنیم.
plt.plot(list(range(epochs)), cost_history)
plt.xlabel('Epochs')
plt.ylabel('Cost')
plt.title('Decrease in Cost with Epochs')
plt.show() تغییرات دقت را در طول دورهها (Epochs) به صورت نموداری نشان دهید.
plt.plot(list(range(epochs)), accuracy_history)
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.title('Increase in Accuracy with Epochs')
plt.show() اکنون ما مرز تصمیمگیری برای کلاسیفایر آموزش دیده خود را رسم خواهیم کرد. مرز تصمیمگیری یک سطح فراگیر است که فضای برداری زیرین را به دو بخش تقسیم میکند، یک بخش برای هر کلاس.
# Calculating the Decision Boundary
decision_boundary_x = np.array([np.min(x_orig[:, 0]),
np.max(x_orig[:, 0])])
decision_boundary_y = (- 1.0 / Weight[0]) *
(decision_boundary_x * Weight + Bias)
decision_boundary_y = [sum(decision_boundary_y[:, 0]),
sum(decision_boundary_y[:, 1])]
# Positive Data Points
x_pos = np.array([x_orig[i] for i in range(len(x_orig))
if y_orig[i] == 1])
# Negative Data Points
x_neg = np.array([x_orig[i] for i in range(len(x_orig))
if y_orig[i] == 0])
# Plotting the Positive Data Points
plt.scatter(x_pos[:, 0], x_pos[:, 1],
color = 'blue', label = 'Positive')
# Plotting the Negative Data Points
plt.scatter(x_neg[:, 0], x_neg[:, 1],
color = 'red', label = 'Negative')
# Plotting the Decision Boundary
plt.plot(decision_boundary_x, decision_boundary_y)
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Plot of Decision Boundary')
plt.legend()
plt.show()















