'분류 전체보기'에 해당되는 글 11건
- 2022.09.19
- 2021.05.18
-
2019.07.10
8 강화학습 1
- 2019.05.27
- 2019.05.27
- 2019.05.24
- 2019.05.24
- 2019.05.24
- 2019.05.24
- 2017.02.26
https://www.samsungcard.com/LkpmOutLinkfdkDta.do?linkInf=u8Rkb7XAanPY3RumBfTb6uDIwZlaAg%252Bg%252FLv7fRIwatjl1kqA3DVA3SFjt%252FZgOguP
https://www.samsungcard.com/LkpmOutLinkfdkDta.do?linkInf=u8Rkb7XAanPY3RumBfTb6uDIwZlaAg%2Bg%2FLv7fRIwatjl1kqA3DVA3SFjt%2FZgOguP
https://www.samsungcard.com/LkpmOutLinkfdkDta.do?linkInf=u8Rkb7XAanPY3RumBfTb6uDIwZlaAg%2Bg%2FLv7fRIwatjl1kqA3DVA3SFjt%2FZgOguP
https://www.samsungcard.com/personal/services/link/UHPPBE0408M0.jsp?linkInf=u8Rkb7XAanPY3RumBfTb6uDIwZlaAg%2Bg%2FLv7fRIwatjl1kqA3DVA3SFjt%2FZgOguP
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 강화 학습\n",
"\n",
"상태(state)는 주식값에 대한 이전값, 현재 예산, 그리고 주식의 수를 나타내는 것이다.\n",
"\n",
"행동(action)은 사거나, 팔거나, 아니면 그냥 가지고 있는 것을 말한다.\n",
"\n",
"주식 시장 데이터는 Yahoo Finance library에서 가져오며, pip install yahoofinancials 로 설치할 수 있다.\n",
"(참조 : https://github.com/JECSand/yahoofinancials )"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# 주식 library\n",
"from yahoofinancials import YahooFinancials\n",
"\n",
"# 필요 Library\n",
"%matplotlib inline\n",
"from matplotlib import pyplot as plt \n",
"import numpy as np\n",
"import tensorflow as tf\n",
"import random"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"#라이브러리에서 주가 호출\n",
"def get_prices(share_symbol, start_date, end_date, interval='daily'): \n",
" share = YahooFinancials(share_symbol)\n",
" stock_hist = share.get_historical_price_data(start_date, end_date, interval)\n",
" stock_prices = list()\n",
" price_tab = stock_hist[share_symbol]['prices']\n",
" \n",
" for i in range(len(price_tab)):\n",
" stock_prices.append(price_tab[i]['open'])\n",
" stock_prices = np.array(stock_prices)\n",
" return stock_prices.astype(float)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# 주식값 그래프 출력\n",
"def plot_prices(prices):\n",
" plt.title('Opening stock prices')\n",
" plt.xlabel('day')\n",
" plt.ylabel('price ($)')\n",
" plt.plot(prices)\n",
" plt.savefig('prices.png')\n",
" plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"class DecisionPolicy:\n",
" def select_action(self, current_state):\n",
" pass\n",
" \n",
" def update_q(self, state, action, reward, next_state):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# 무작위 행동 선정\n",
"class RandomDecisionPolicy(DecisionPolicy):\n",
" def __init__(self, actions):\n",
" self.actions = actions\n",
" \n",
" def select_action(self, current_state, step):\n",
" action = self.actions[random.randint(0, len(self.actions) - 1)]\n",
" return action"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"class QLearningDecisionPolicy(DecisionPolicy):\n",
" def __init__(self, actions, input_dim):\n",
" # Neural Network 설계시 필요한 Hyperparameter\n",
" self.epsilon = 0.9\n",
" self.gamma = 0.001\n",
" self.actions = actions\n",
" output_dim = len(actions)\n",
" h1_dim = 200\n",
" \n",
" # Neural Network 설계\n",
" self.x = tf.placeholder(tf.float32, [None, input_dim])\n",
" self.y = tf.placeholder(tf.float32, [output_dim])\n",
" W1 = tf.Variable(tf.random_normal([input_dim, h1_dim]))\n",
" b1 = tf.Variable(tf.constant(0.1, shape=[h1_dim]))\n",
" h1 = tf.nn.relu(tf.matmul(self.x, W1) + b1)\n",
" W2 = tf.Variable(tf.random_normal([h1_dim, output_dim]))\n",
" b2 = tf.Variable(tf.constant(0.1, shape=[output_dim]))\n",
" self.q = tf.nn.relu(tf.matmul(h1, W2) + b2)\n",
" loss = tf.square(self.y - self.q)\n",
" self.train_op = tf.train.AdagradOptimizer(0.01).minimize(loss)\n",
" \n",
" self.sess = tf.Session()\n",
" self.sess.run(tf.global_variables_initializer())\n",
" \n",
" def select_action(self, current_state, step):\n",
" threshold = min(self.epsilon, step / 1000.)\n",
" if random.random() < threshold:\n",
" # epsilon 확률 내에서 최고의 행동을 수행함(Exploit)\n",
" action_q_vals = self.sess.run(self.q, feed_dict={self.x: current_state})\n",
" action_idx = np.argmax(action_q_vals) \n",
" action = self.actions[action_idx]\n",
" else:\n",
" # 1 – epsilon 확률 내에서 새로운 행동을 무작위로 탐색함(Explore)\n",
" action = self.actions[random.randint(0, len(self.actions) - 1)]\n",
" return action\n",
" \n",
" def update_q(self, state, action, reward, next_state):\n",
" action_q_vals = self.sess.run(self.q, feed_dict={self.x: state})\n",
" next_action_q_vals = self.sess.run(self.q, feed_dict={self.x: next_state})\n",
" next_action_idx = np.argmax(next_action_q_vals)\n",
" action_q_vals[0, next_action_idx] = reward + self.gamma * next_action_q_vals[0, next_action_idx]\n",
" action_q_vals = np.squeeze(np.asarray(action_q_vals))\n",
" self.sess.run(self.train_op, feed_dict={self.x: state, self.y: action_q_vals})"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def run_simulation(policy, initial_budget, initial_num_stocks, prices, hist):\n",
" budget = initial_budget\n",
" num_stocks = initial_num_stocks\n",
" share_value = 0\n",
" transitions = list()\n",
" for i in range(len(prices) - hist - 1):\n",
" if i % 1000 == 0:\n",
" print('progress {:.2f}%'.format(float(100*i) / (len(prices) - hist - 1)))\n",
" current_state = np.asmatrix(np.hstack((prices[i:i+hist], budget, num_stocks)))\n",
" current_portfolio = budget + num_stocks * share_value\n",
" action = policy.select_action(current_state, i)\n",
" share_value = float(prices[i + hist])\n",
" if action == 'Buy' and budget >= share_value:\n",
" budget -= share_value\n",
" num_stocks += 1\n",
" elif action == 'Sell' and num_stocks > 0:\n",
" budget += share_value\n",
" num_stocks -= 1\n",
" else:\n",
" action = 'Hold'\n",
" new_portfolio = budget + num_stocks * share_value\n",
" reward = new_portfolio - current_portfolio\n",
" next_state = np.asmatrix(np.hstack((prices[i+1:i+hist+1], budget,num_stocks)))\n",
" transitions.append((current_state, action, reward, next_state))\n",
" policy.update_q(current_state, action, reward, next_state)\n",
" portfolio = budget + num_stocks * share_value\n",
" return portfolio"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def run_simulations(policy, budget, num_stocks, prices, hist):\n",
" num_tries = 10\n",
" final_portfolios = list()\n",
" for _ in range(num_tries):\n",
" final_portfolio = run_simulation(policy, budget, num_stocks, prices,hist)\n",
" final_portfolios.append(final_portfolio)\n",
" print('Final portfolio: ${}'.format(final_portfolio))\n",
" plt.title('Final Portfolio Value')\n",
" plt.xlabel('Simulation #')\n",
" plt.ylabel('Net worth')\n",
" plt.hlines(budget, 0, num_tries, linestyles='dashed')\n",
" plt.plot(final_portfolios)\n",
" plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $227077.02664661407\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $227642.20277404785\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $227440.80604076385\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $228530.6992225647\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $227601.0991754532\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $228938.4273405075\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $228326.875831604\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $229112.49336242676\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $229102.22488307953\n",
"progress 0.00%\n",
"progress 16.55%\n",
"progress 33.10%\n",
"progress 49.65%\n",
"progress 66.20%\n",
"progress 82.75%\n",
"progress 99.30%\n",
"Final portfolio: $229053.33343029022\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"if __name__ == '__main__':\n",
" prices = get_prices('MSFT', '1992-07-22', '2016-07-22')\n",
" plot_prices(prices)\n",
" actions = ['Buy', 'Sell', 'Hold']\n",
" hist = 3\n",
" #policy = RandomDecisionPolicy(actions)\n",
" policy = QLearningDecisionPolicy(actions, hist + 2)\n",
" budget = 100000.0\n",
" num_stocks = 0\n",
" run_simulations(policy, budget, num_stocks, prices, hist) "
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
import tensorflow as tf
learning_rate = 0.01
training_epochs = 1000
num_labels = 3
batch_size = 100
X = tf.placeholder(tf.float32, shape=[None, num_features])
Y = tf.placeholder(tf.float32, shape=[None, num_labels])
w=tf.Variable(tf.zeros[num_features, num_labels])
b=tf.Variable(tf.zeros[num_labels])
y_model = tf.nn.softmax(tf.matmul(X, W) + b)
cost = -tf.reduce_sum(Y * tf.log(y_model))
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
correnct_prediction = tf.equal(tf.argmax(y_model, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
with tf.Session() as sess:
tf.grobal_variables_initializer().run()
fpr step in range(training_epochs * train_size // batch_size):
offset = (step * batch_size) % train_size
batch_xs = xs[offset: ( offset + batch_size), :]
batch_labels = labels[offset: (offset + batch_size)]
err, _ = sess.run([cost, train_op], feed_dict={X: batch_xs, Y: batch_labels})
if step % 100 == 0:
print(step, err)
W_val = sess.run(W)
print('w', W_val)
b_val = sess.run(b)
print('b', b_val)
print("accuracy", accuracy.eval(feed_dict={X: test_xs, Y: test_labels}))
import numpy as np
import matplotlib.pyplot as plt
x1_label0 = np.random.normal(1, 1, (100,1))
x2_label0 = np.random.normal(1, 1, (100,1))
x1_label1 = np.random.normal(5, 1, (100,1))
x2_label1 = np.random.normal(4, 1, (100,1))
x1_label2 = np.random.normal(8, 1, (100,1))
x2_label2 = np.random.normal(0, 1, (100,1))
plt.scatter(x1_label1, x2_label0, c='r', marker='o', s=60)
plt.scatter(x1_label1, x2_label1, c='g', marker='x', s=60)
plt.scatter(x1_label2, x2_label2, c='b', marker='_', s=60)
plt.show()
import numpy as np
import tensorflow as tf
import matplotib.pyplot as plt
learning_rate = 0.001
training_epochs = 1000
def sigmoid(x):
return 1. / (1. + np.exp(-x))
x1_label1 = np.random.normal(3, 1, 1000)
x2_label1 = np.random.normal(2, 1, 1000)
x1_label2 = np.random.normal(7, 1, 1000)
x2_label2 = np.random.normal(6, 1, 1000)
x1s = np.append(x1_label1, x1_label2)
x2s = np.append(x2_label1, x2_label2)
ys = np.asarray([0.] * len(x1_label1) + [1.] * len(x1_label2))
X1 = tf.placeholder(tf.float32, shape=(None,), name='x1')
X2 = tf.placeholder(tf.float32, shape=(None,), name='x2')
Y = tf.placeholder(tf.float32, shape=(None,), name='y')
w = tf.Variable([0., 0., 0.], name="w", trainable=True)
y_model = tf.sigmoid(-(w[2] * X2 + w[1] * X1 + w[0]))
cost = tf.reduce_mean(-tf.log(y_model * Y + (1 - y_model) * (1 - Y)))
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
prev_err = 0
for epoch in range(training_epochs):
err, _ = sess.run([cost, train_op], {X1: x1s, X2: x2s, Y: ys})
if epoch % 100 == 0:
print(epoch, err)
if abs(prev_err - err) < 0.0001:
break
prev_err = err
w_val = sess.run(w, {X1: x1s, X2: x2s, Y: ys})
x1_boundary, x2_boundary = [], []
for x1_test in np.linspace(0, 10, 100):
for x2_test in np.linspace(0, 10, 100):
z = sigmoid(-x2_test*w_val[2] - x1_test*w_val[1] - w_val[0])
if abs(z - 0.5) < 0.01:
x1_boundary.append(x1_test)
x2_boundary.append(x2_test)
plt.scatter(x1_boundary, x2_boundary, c='b', marker='o', s=20)
plt.scatter(x1_label1, x2_label1, c='r', marker='x', s=10)
plt.scatter(x1_label2, x2_label2, c='g', marker='1', s=10)
plt.show()
import numpy as np
import tensorflow as tf
import matplotib.pyplot as plt
learning_rate = 0.001
training_epochs = 1000
def sigmoid(x):
return 1. / (1. + np.exp(-x))
x1 = np.random.normal(-4, 2, 1000)
x2 = np.random.normal(4, 2, 1000)
xs = np.append(x1, x2)
ys = np.asarray([0.] * len(x1) + [1.] * len(x2))
plt.scatter(xs, ys)
X = tf.placeholder(tf.float32, shape=(None,), name='x')
Y = tf.placeholder(tf.float32, shape=(None,), name='y')
w=tf.Variable([0., 0.], name="parameter", trainable=True)
y_model = tf.sigmoid(w[1] * X + w[0])
cost = tf.reduce_mean(-Y * tf.log(y_model) - (1 - Y) * tf.log(1 - y_model))
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
prev_err = 0
for epoch in range(training_epochs):
err, _ = sess.run([cost, train_op], {X: xs, Y: ys})
print(epoch, err)
if abs(prev_err - err) < 0.0001:
break
prev_err = err
w_val = sess.run(w, {X: xs, Y: ys})
all_xs = np.linspace(-10, 10, 100)
plt.plot(all_xs, sigmoid((all_xs * w_val[1] + w_val[0])))
plt.show()
{
"cmd": ["C:/ProgramData/Anaconda3/python.exe", "-u", "$file"],
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python"
}
import tensorflow as tf
import numpy as np
import matplotib.pyplot as plt
x_label0 = np.random.normal(5, 1, 10)
x_label1 = np.random.normal(2, 1, 10)
xs = np.append(x_label0, x_label1)
labels = [0.] * len(x_label0) + [1.] * len(x_label1)
plt.scatter(xs, labels)
learning_rate = 0.001
training_epochs = 1000
X = tf.placeholder("float")
Y = tf.placeholder("float")
def model(X, w):
return tf.add(tf.multiply(w[1], tf.pow(X, 1)), tf.multiply(w[0], tf.pow(X, 0)))
w = tf.Variable([0., 0.], name="parameters")
y_model = model(X, w)
cost = tf.reduce_sum(tf.square(Y-y_model))
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
for epoch in range(training_epochs):
sess.run(train_op, feed_dict={X: xs, Y: labels})
current_cost = sess.run(cost, feed_dict={X: xs, Y: labels})
if epoch % 100 ==0:
print(epoch, current_cost)
w_val = sess.run(w)
print('leaned parameters', w_val)
correct_prediction = tf.equal(Y, tf.to_float(tf.greater(y_model, 0.5)))
accuracy = tf.reduce_mean(tf.to_float(correct_prediction))
print('accuracy', sess.run(accuracy, feed_dict={X: xs, Y: labels}))
sess.close()
all_xs = np.linspace(0, 10, 100)
plt.plot(all_xs, all_xs*w_val[1] + w_val[0])
plt.show()