Dự đoán giá có phiếu bằng python

Stock Market Predictions with LSTM in Python Khám phá các mạng Long Short-Term Memory [LSTM] trong Python và cách bạn có thể sử dụng chúng để đưa ra các dự đoán thị trường chứng khoán! Trong hướng dẫn này, bạn sẽ thấy cách bạn có thể sử dụng một model Time-series được gọi là Long Short-Term Memory. Các model LSTM rất mạnh mẽ, đặc biệt là để giữ lại một Long Short-Term Memory, theo thiết kế, như bạn sẽ thấy sau này. Bạn sẽ giải quyết các chủ đề sau trong hướng dẫn này: Hiểu lý do tại sao bạn cần để có thể dự đoán biến động giá cổ phiếu; Tải xuống dữ liệu - Bạn sẽ sử dụng dữ liệu thị trường chứng khoán được thu thập từ tài chính của Yahoo; Chia tách dữ liệu kiểm tra - train và cũng thực hiện một số chuẩn hóa dữ liệu; Đi qua và áp dụng một vài kỹ thuật trung bình có thể được sử dụng cho các dự đoán trước một bước; Khuyến khích và thảo luận ngắn gọn về model LSTM vì nó cho phép dự đoán trước một bước; Dự đoán và hình dung thị trường chứng khoán trong tương lai với dữ liệu hiện tại Nếu bạn không quen thuộc với việc deep learning hoặc mạng thần kinh, bạn nên xem qua Khóa deep learning của chúng tôi trong khóa học Python. Nó bao gồm những điều cơ bản, cũng như làm thế nào để xây dựng một mạng thần kinh của riêng bạn trong Keras. Đây là một gói khác với TensorFlow, sẽ được sử dụng trong hướng dẫn này, nhưng ý tưởng là như nhau. Tại sao bạn cần model Time-series? Bạn muốn model hóa giá cổ phiếu một cách chính xác, do đó, với tư cách là người mua cổ phiếu, bạn có thể quyết định khi mua cổ phiếu và khi nào bán chúng để kiếm lời. Đây là nơi model hóa Timeseries xuất hiện. Bạn cần các model machine learning tốt có thể xem lịch sử của một chuỗi dữ liệu và dự đoán chính xác những yếu tố tương lai của chuỗi sẽ như thế nào. Cảnh báo: Giá thị trường chứng khoán rất khó lường và dễ bay hơi. Điều này có nghĩa là không có mẫu nhất quán trong dữ liệu cho phép bạn lập model giá cổ phiếu theo thời gian gần như hoàn hảo. Đừng lấy nó từ tôi, lấy nó từ nhà kinh tế học Burton Malkiel của Đại học Princeton, người tranh luận trong cuốn sách năm 1973, "Đường đi bộ ngẫu nhiên xuống phố", rằng nếu thị trường thực sự hiệu quả và giá cổ phiếu phản ánh mọi yếu tố ngay lập tức ngay sau đó khi chúng được công bố, một con khỉ bị bịt mắt ném phi tiêu vào một danh sách cổ phiếu báo chí nên làm cũng như bất kỳ chuyên gia đầu tư nào. Tuy nhiên, chúng ta không phải đi tất cả các cách tin rằng đây chỉ là một quá trình ngẫu nhiên hoặc ngẫu nhiên và rằng không có hy vọng cho việc machine learning. Hãy xem liệu bạn có thể ít nhất là model hóa dữ liệu, để các dự đoán bạn thực hiện tương quan với hành vi thực tế của dữ liệu. Nói cách khác, bạn không cần các giá trị cổ phiếu chính xác của tương lai, nhưng các biến động giá cổ phiếu [có nghĩa là, nếu nó sẽ tăng trong mùa thu trong tương lai gần]. # Make sure that you have all these libaries available to run the code successfully from pandas_datareader import data import matplotlib.pyplot as plt import pandas as pd import datetime as dt import urllib.request, json import os import numpy as np import tensorflow as tf # This code has been tested with TensorFlow 1.6 from sklearn.preprocessing import MinMaxScaler Tải xuống dữ liệu Bạn sẽ sử dụng dữ liệu từ các nguồn sau: Alpha Vantage. Trước khi bạn bắt đầu, tuy nhiên, trước tiên bạn sẽ cần một khóa API, mà bạn có thể có được miễn phí tại đây. Sau đó, bạn có thể gán khóa đó cho biến api_key. Sử dụng dữ liệu từ trang này. Bạn sẽ cần phải sao chép thư mục Cổ phiếu trong tệp zip vào thư mục nhà dự án của bạn. Giá cổ phiếu có nhiều hương vị khác nhau. Họ đang, Mở: Mở giá cổ phiếu trong ngày Đóng: Đóng giá cổ phiếu trong ngày Cao: Giá cổ phiếu cao nhất của dữ liệu Thấp: Giá cổ phiếu thấp nhất trong ngày Lấy dữ liệu từ Alphavantage Trước tiên, bạn sẽ tải dữ liệu từ Alpha Vantage. Vì bạn sẽ sử dụng giá thị trường chứng khoán American Airlines để đưa ra dự đoán của mình, bạn đặt mã cổ phiếu thành "AAL". Ngoài ra, bạn cũng định nghĩa url_string, tệp này sẽ trả về tệp JSON có tất cả dữ liệu thị trường chứng khoán cho American Airlines trong vòng 20 năm qua và tệp_to_save, đây sẽ là tệp mà bạn lưu dữ liệu. Bạn sẽ sử dụng biến ticker mà bạn đã xác định trước để giúp đặt tên cho tệp này. Tiếp theo, bạn sẽ chỉ định một điều kiện: nếu bạn chưa lưu dữ liệu, bạn sẽ tiếp tục và lấy dữ liệu từ URL mà bạn đã đặt trong url_string; Bạn sẽ lưu trữ ngày, thấp, cao, khối lượng, đóng, mở các giá trị cho một chú gấu trúc DataFrame df và bạn sẽ lưu nó vào file_to_save. Tuy nhiên, nếu dữ liệu đã có sẵn, bạn sẽ chỉ tải dữ liệu từ CSV. Lấy dữ liệu từ Kaggle Dữ liệu tìm thấy trên Kaggle là tập hợp các tệp csv và bạn không phải thực hiện bất kỳ quá trình tiền xử lý nào, vì vậy bạn có thể trực tiếp tải dữ liệu vào một Khung dữ liệu Pandas. data_source = 'kaggle' # alphavantage or kaggle if data_source == 'alphavantage': # ====================== Loading Data from Alpha Vantage ================================== api_key = '' # American Airlines stock market prices ticker = "AAL" # JSON file with all the stock market data for AAL from the last 20 years url_string = "//www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=%s&outputsize=full&ap ikey=%s"%[ticker,api_key] # Save data to this file file_to_save = 'stock_market_data-%s.csv'%ticker # If you haven't already saved data, # Go ahead and grab the data from the url # And store date, low, high, volume, close, open values to a Pandas DataFrame if not os.path.exists[file_to_save]: with urllib.request.urlopen[url_string] as url: data = json.loads[url.read[].decode[]] # extract stock market data data = data['Time Series [Daily]'] df = pd.DataFrame[columns=['Date','Low','High','Close','Open']] for k,v in data.items[]: date = dt.datetime.strptime[k, '%Y-%m-%d'] data_row = [date.date[],float[v['3. low']],float[v['2. high']], float[v['4. close']],float[v['1. open']]] df.loc[-1,:] = data_row df.index = df.index + 1 print['Data saved to : %s'%file_to_save] df.to_csv[file_to_save] # If the data is already there, just load it from the CSV else: print['File already exists. Loading data from CSV'] df = pd.read_csv[file_to_save] else: # ====================== Loading Data from Kaggle ================================== # You will be using HP's data. Feel free to experiment with other data. # But while doing so, be careful to have a large enough dataset and also pay attention to the data normalization df = pd.read_csv[os.path.join['Stocks','hpq.us.txt'],delimiter=',',usecols=['Date','Open','High','Low','Close']] print['Loaded data from the Kaggle repository'] Khám phá dữ liệu Tại đây bạn sẽ in dữ liệu bạn đã thu thập vào DataFrame. Bạn cũng nên đảm bảo rằng dữ liệu được sắp xếp theo ngày, bởi vì thứ tự của dữ liệu là rất quan trọng trong model Time-series # Sort DataFrame by date df = df.sort_values['Date'] # Double check the result df.head[] Hiển thị dữ liệu Bây giờ hãy xem loại dữ liệu bạn có. Bạn muốn dữ liệu với các mẫu khác nhau xảy ra theo thời gian plt.figure[figsize = [18,9]] plt.plot[range[df.shape[0]],[df['Low']+df['High']]/2.0] plt.xticks[range[0,df.shape[0],500],df['Date'].loc[::500],rotation=45] plt.xlabel['Date',fontsize=18] plt.ylabel['Mid Price',fontsize=18] plt.show[] Biểu đồ này đã nói rất nhiều điều. Lý do cụ thể tôi chọn công ty này so với những công ty khác là biểu đồ này đang bùng nổ với các hành vi khác nhau của giá cổ phiếu theo thời gian. Điều này sẽ làm cho việc học tập trở nên mạnh mẽ hơn cũng như cung cấp cho bạn một sự thay đổi để kiểm tra mức độ dự đoán tốt cho nhiều tình huống khác nhau. Một điều cần lưu ý là các giá trị gần năm 2017 cao hơn nhiều và biến động nhiều hơn các giá trị gần với những năm 1970. Do đó, bạn cần đảm bảo rằng dữ liệu hoạt động trong các phạm vi giá trị tương tự trong suốt khung thời gian. Bạn sẽ chăm sóc điều này trong giai đoạn chuẩn hóa dữ liệu. Chia dữ liệu thành một tập huấn luyện và một tập kiểm tra Bạn sẽ sử dụng giá giữa được tính bằng cách lấy mức trung bình của giá cao nhất và thấp nhất được ghi lại trong một ngày. # First calculate the mid prices from the highest and lowest high_prices = df.loc[:,'High'].as_matrix[] low_prices = df.loc[:,'Low'].as_matrix[] mid_prices = [high_prices+low_prices]/2.0 Bây giờ bạn có thể chia dữ liệu huấn luyện và dữ liệu kiểm tra. Dữ liệu đào tạo sẽ là 11.000 điểm dữ liệu đầu tiên của Time-series và phần còn lại sẽ là dữ liệu thử nghiệm. train_data = mid_prices[:11000] test_data = mid_prices[11000:] Bình thường hóa dữ liệu Bây giờ bạn cần xác định một scaler để chuẩn hóa dữ liệu. MinMaxScalar quy mô tất cả các dữ liệu nằm trong vùng 0 và 1. Bạn cũng có thể định hình lại dữ liệu huấn luyện và kiểm tra ở dạng [data_size, num_features]. # Scale the data to be between 0 and 1 # When scaling remember! You normalize both test and train data with respect to training data # Because you are not supposed to have access to test data scaler = MinMaxScaler[] train_data = train_data.reshape[-1,1] test_data = test_data.reshape[-1,1] Do quan sát bạn đã thực hiện trước đó, có nghĩa là, các khoảng thời gian khác nhau của dữ liệu có phạm vi giá trị khác nhau, bạn chuẩn hóa dữ liệu bằng cách tách chuỗi đầy đủ thành cửa sổ. Nếu bạn không làm điều này, dữ liệu trước đó sẽ gần bằng 0 và sẽ không thêm nhiều giá trị cho quá trình học tập. Ở đây bạn chọn kích thước cửa sổ là 2500. Mẹo: khi chọn kích thước cửa sổ, hãy đảm bảo rằng nó không quá nhỏ, bởi vì khi bạn thực hiện bình thường hóa cửa sổ, nó có thể giới thiệu một khoảng ngắt ở cuối mỗi cửa sổ, vì mỗi cửa sổ được chuẩn hóa độc lập. Trong ví dụ này, 4 điểm dữ liệu sẽ bị ảnh hưởng bởi điều này. Nhưng nếu bạn có 11.000 điểm dữ liệu, 4 điểm sẽ không gây ra bất kỳ vấn đề nào # Train the Scaler with training data and smooth data smoothing_window_size = 2500 for di in range[0,10000,smoothing_window_size]: scaler.fit[train_data[di:di+smoothing_window_size,:]] train_data[di:di+smoothing_window_size,:] = scaler.transform[train_data[di:di+smoothing_window_size,:]] # You normalize the last bit of remaining data scaler.fit[train_data[di+smoothing_window_size:,:]] train_data[di+smoothing_window_size:,:] = scaler.transform[train_data[di+smoothing_window_size:,:]] Định hình lại dữ liệu trở lại hình dạng của [data_size] # Reshape both train and test data train_data = train_data.reshape[-1] # Normalize test data test_data = scaler.transform[test_data].reshape[-1] Bây giờ bạn có thể làm mịn dữ liệu bằng cách sử dụng trung bình di động theo hàm mũ. Điều này giúp bạn thoát khỏi sự rách rưới vốn có của dữ liệu trong giá cổ phiếu và tạo ra một đường cong mượt mà hơn. Lưu ý rằng bạn chỉ nên làm mịn dữ liệu đào tạo. # Now perform exponential moving average smoothing # So the data will have a smoother curve than the original ragged data EMA = 0.0 gamma = 0.1 for ti in range[11000]: EMA = gamma*train_data[ti] + [1-gamma]*EMA train_data[ti] = EMA # Used for visualization and test purposes all_mid_data = np.concatenate[[train_data,test_data],axis=0] Một bước dự đoán trước qua trung bình Cơ chế trung bình cho phép bạn dự đoán [thường đi trước một bước] bằng cách trình bày giá cổ phiếu trong tương lai là mức trung bình của giá cổ phiếu được quan sát trước đây. Làm điều này trong nhiều bước thời gian có thể tạo ra kết quả khá xấu. Bạn sẽ xem xét hai kỹ thuật trung bình dưới đây; trung bình di động trung bình và theo hàm mũ. Bạn sẽ đánh giá cả về chất lượng [kiểm tra trực quan] và định lượng [Mean Squared Error] các kết quả được tạo ra bởi hai thuật toán. Lỗi trung bình bình phương [MSE] có thể được tính bằng cách lấy sai số bình phương giữa giá trị thực tại một bước phía trước và giá trị được dự đoán và tính trung bình nó trên tất cả các dự đoán. Chuẩn trung bình Bạn có thể hiểu được khó khăn của vấn đề này bằng cách đầu tiên cố gắng model hóa vấn đề này như một phép tính trung bình. Trước tiên, bạn sẽ cố gắng dự đoán giá thị trường chứng khoán trong tương lai [ví dụ, xt + 1] là giá trung bình của giá thị trường chứng khoán trước đây trong một cửa sổ kích thước cố định [ví dụ: xt-N, ..., xt] 100 ngày trước đó]. Sau đó bạn sẽ thử phương pháp "trung bình di chuyển theo hàm mũ" hơn một chút và xem nó hoạt động tốt như thế nào. Sau đó, bạn sẽ chuyển sang "chén thánh" của dự đoán Time-series; Các model bộ nhớ ngắn hạn dài. Trước tiên, bạn sẽ thấy cách tính trung bình bình thường hoạt động. Đó là bạn nói, Nói cách khác, bạn nói dự đoán tại t + 1 là giá trị trung bình của tất cả giá cổ phiếu bạn quan sát được trong một cửa sổ từ t đến t − N. window_size = 100 N = train_data.size std_avg_predictions = [] std_avg_x = [] mse_errors = [] for pred_idx in range[window_size,N]: if pred_idx >= N: date = dt.datetime.strptime[k, '%Y-%m-%d'].date[] + dt.timedelta[days=1] else: date = df.loc[pred_idx,'Date'] std_avg_predictions.append[np.mean[train_data[pred_idxwindow_size:pred_idx]]] mse_errors.append[[std_avg_predictions[-1]-train_data[pred_idx]]**2] std_avg_x.append[date] print['MSE error for standard averaging: %.5f'%[0.5*np.mean[mse_errors]]] Hãy xem các kết quả trung bình bên dưới. Nó theo sau hành vi thực tế của cổ phiếu khá chặt chẽ. Tiếp theo, bạn sẽ xem xét phương pháp dự đoán một bước chính xác hơn. plt.figure[figsize = [18,9]] plt.plot[range[df.shape[0]],all_mid_data,color='b',label='True'] plt.plot[range[window_size,N],std_avg_predictions,color='orange',label='Pr ediction'] #plt.xticks[range[0,df.shape[0],50],df['Date'].loc[::50],rotation=45] plt.xlabel['Date'] plt.ylabel['Mid Price'] plt.legend[fontsize=18] plt.show[] Vậy các đồ thị trên [và MSE] nói gì? Dường như nó không phải là quá xấu của một model cho những dự đoán rất ngắn [một ngày trước]. Cho rằng giá cổ phiếu không thay đổi từ 0 đến 100 qua đêm, hành vi này là hợp lý. Tiếp theo, bạn sẽ xem xét kỹ thuật trung bình fancier được gọi là trung bình di động theo hàm mũ. Trung bình di chuyển theo hàm mũ Bạn có thể đã thấy một số bài viết trên internet bằng cách sử dụng các model rất phức tạp và dự đoán gần như hành vi chính xác của thị trường chứng khoán. Nhưng hãy cẩn thận! Đây chỉ là ảo tưởng quang học chứ không phải do học một cái gì đó hữu ích. Bạn sẽ thấy bên dưới cách bạn có thể sao chép hành vi đó bằng một phương pháp trung bình đơn giản. Trong phương pháp di chuyển trung bình theo hàm mũ, bạn tính xt + 1 là, xt + 1 = EMAt = γ × EMAt-1 + [1-γ] xt trong đó EMA0 = 0 và EMA là giá trị trung bình di động theo hàm mũ mà bạn duy trì theo thời gian. Phương trình trên cơ bản tính toán trung bình di động theo hàm mũ từ bước t + 1 và sử dụng nó như dự đoán trước một bước. γ quyết định mức đóng góp của dự đoán gần đây nhất là EMA. Ví dụ, một γ = 0,1 chỉ nhận được 10% giá trị hiện tại vào EMA. Bởi vì bạn chỉ lấy một phần rất nhỏ trong số gần đây nhất, nó cho phép bảo tồn nhiều giá trị cũ hơn bạn thấy rất sớm ở mức trung bình. Xem vẻ đẹp này trông như thế nào khi được sử dụng để dự đoán trước một bước bên dưới. window_size = 100 N = train_data.size run_avg_predictions = [] run_avg_x = [] mse_errors = [] running_mean = 0.0 run_avg_predictions.append[running_mean] decay = 0.5 for pred_idx in range[1,N]: running_mean = running_mean*decay + [1.0-decay]*train_data[pred_idx-1] run_avg_predictions.append[running_mean] mse_errors.append[[run_avg_predictions[-1]-train_data[pred_idx]]**2] run_avg_x.append[date] print['MSE error for EMA averaging: %.5f'%[0.5*np.mean[mse_errors]]] plt.figure[figsize = [18,9]] plt.plot[range[df.shape[0]],all_mid_data,color='b',label='True'] plt.plot[range[0,N],run_avg_predictions,color='orange', label='Prediction'] #plt.xticks[range[0,df.shape[0],50],df['Date'].loc[::50],rotation=45] plt.xlabel['Date'] plt.ylabel['Mid Price'] plt.legend[fontsize=18] plt.show[] Nếu Trung bình di chuyển theo hàm mũ là tốt, tại sao bạn cần model tốt hơn? Bạn thấy rằng nó phù hợp với một dòng hoàn hảo theo sau sự phân bố thực sự [và được chứng minh bởi MSE rất thấp]. Thực tế, bạn không thể làm gì nhiều chỉ với giá trị thị trường chứng khoán của ngày hôm sau. Cá nhân những gì tôi muốn không phải là giá thị trường chứng khoán chính xác cho ngày hôm sau, nhưng giá thị trường chứng khoán sẽ tăng hoặc giảm trong 30 ngày tới. Hãy thử làm điều này, và bạn sẽ vạch trần sự bất lực của phương pháp EMA. Bây giờ bạn sẽ cố gắng đưa ra các dự đoán trong các cửa sổ [giả sử bạn dự đoán cửa sổ 2 ngày tới, thay vì chỉ vào ngày hôm sau]. Sau đó, bạn sẽ nhận ra sai EMA có thể đi. Đây là một ví dụ: Dự đoán nhiều hơn một bước trong tương lai Để làm cho mọi thứ cụ thể, hãy giả sử các giá trị, giả sử xt = 0,4, EMA = 0,5 và γ = 0,5 Giả sử bạn nhận được đầu ra với phương trình sau Xt + 1 = EMAt = γ × EMAt-1 + [1 - γ] Xt Vì vậy, bạn có xt + 1 = 0,5 × 0,5 + [1−0,5] × 0,4 = 0,45 Vì vậy xt + 1 = EMAt = 0,45 Vì vậy, dự đoán tiếp theo xt + 2 trở thành, Xt + 2 = γ × EMAt + [1-γ] Xt + 1 Đó là xt + 2 = γ × EMAt + [1 − γ] EMAt = EMAt Hoặc trong ví dụ này, Xt + 2 = Xt + 1 = 0,45 Vì vậy, bất kể bạn dự đoán bao nhiêu bước trong tương lai, bạn sẽ tiếp tục nhận được câu trả lời tương tự cho tất cả các bước dự đoán trong tương lai. Một giải pháp mà bạn có sẽ đưa ra thông tin hữu ích là xem xét các thuật toán dựa trên động lượng. Họ đưa ra các dự đoán dựa trên việc các giá trị gần đây trong quá khứ có tăng hay giảm [không phải là các giá trị chính xác] hay không. Ví dụ, họ sẽ nói giá ngày hôm sau có thể sẽ thấp hơn, nếu giá đã giảm trong những ngày qua, điều đó nghe có vẻ hợp lý. Tuy nhiên, bạn sẽ sử dụng một model phức tạp hơn: một model LSTM. Những model này đã đưa ra lĩnh vực dự đoán Time-series theo bão, bởi vì chúng rất tốt trong việc lập model dữ liệu Time-series. Bạn sẽ thấy nếu thực sự có các mẫu ẩn trong dữ liệu mà bạn có thể khai thác. Giới thiệu về LSTMs: Đưa ra dự đoán về phong trào cổ phiếu xa trong tương lai Các model bộ nhớ ngắn hạn dài là các model Time-series cực kỳ mạnh mẽ. Họ có thể dự đoán một số bước tùy ý trong tương lai. Một mô-đun LSTM [hoặc ô] có 5 thành phần thiết yếu cho phép nó model cả dữ liệu dài hạn và ngắn hạn. Trạng thái ô [ct] - Biểu thị bộ nhớ trong của ô lưu trữ cả bộ nhớ ngắn hạn và ký ức dài hạn Trạng thái ẩn [ht] - Đây là thông tin trạng thái đầu ra được tính toán w.r.t. đầu vào hiện tại, trạng thái ẩn trước đó và ô nhập hiện tại mà cuối cùng bạn sử dụng để dự đoán giá thị trường chứng khoán trong tương lai. Ngoài ra, trạng thái ẩn có thể quyết định chỉ phát lại ngắn hoặc dài hạn hoặc cả hai loại bộ nhớ được lưu trữ trong trạng thái ô để thực hiện dự đoán tiếp theo. Cổng vào [nó] - Quyết định lượng thông tin từ luồng đầu vào hiện tại đến trạng thái ô Quên cổng [ft] - Quyết định lượng thông tin từ đầu vào hiện tại và trạng thái ô trước đó chuyển sang trạng thái ô hiện tại Cổng ra [ot] - Quyết định lượng thông tin từ trạng thái ô hiện tại chảy vào trạng thái ẩn, để nếu LSTM cần chỉ có thể chọn những ký ức dài hạn hoặc những ký ức ngắn hạn và những ký ức dài hạn Một ô được hình dưới đây. Và các phương trình để tính toán từng thực thể như sau. $ it = \ sigma [W {ix} xt + W {ih} h_ {t-1} + b_i] $ $ \ tilde {c} t = \ sigma [W {cx} xt + W {ch} h_ {t-1} + b_c] $ $ ft = \ sigma [W {fx} xt + W {fh} h_ {t-1} + b_f] $ $ c_t = ft c {t-1} + i_t \ dấu ngã {c} _t $ $ ot = \ sigma [W {ox} xt + W {oh} h_ {t-1} + b_o] $ ht = ottanh [ct] Để hiểu rõ hơn về LSTM, bạn có thể tham khảo bài viết này. TensorFlow cung cấp một API phụ tốt [được gọi là API RNN] để triển khai các model Time-series. Bạn sẽ sử dụng nó cho việc triển khai của bạn. Trình tạo dữ liệu Trước tiên, bạn sẽ triển khai trình tạo dữ liệu để đào tạo model của mình. Trình tạo dữ liệu này sẽ có một phương thức được gọi là .unroll_batches [...] sẽ xuất ra một tập hợp các lô num_unrollings của dữ liệu đầu vào thu được tuần tự, trong đó một lô dữ liệu có kích thước [batch_size, 1]. Sau đó, mỗi lô dữ liệu đầu vào sẽ có một lô dữ liệu đầu ra tương ứng. Ví dụ: nếu num_unrollings = 3 và batch_size = 4 một tập hợp các lô chưa được kiểm tra, nó có thể trông giống như, dữ liệu đầu vào: [x0, x10, x20, x30], [x1, x11, x21, x31], [x2, x12, x22, x32] dữ liệu đầu ra: [x1, x11, x21, x31], [x2, x12, x22, x32], [x3, x13, x23, x33] Cập nhật dữ liệu Ngoài ra, để làm cho model của bạn trở nên mạnh mẽ, bạn sẽ không tạo kết quả cho $ xtalwaysx {t + 1} .Ratheryouwillrandomlysampleanoutputfromthesetx {t + 1}, x {t + 2}, \ ldots, x_ {t + N} trong đóN $ là một cửa sổ nhỏ kích thước. Ở đây bạn đang thực hiện giả định sau: $ x {t + 1}, x {t + 2}, \ ldots, x_ {t + N} $ sẽ không cách nhau xa nhau Cá nhân tôi nghĩ rằng đây là một giả định hợp lý cho dự đoán chuyển động cổ phiếu. Bên dưới, bạn minh họa cách một loạt dữ liệu được tạo trực quan class DataGeneratorSeq[object]: def __init__[self,prices,batch_size,num_unroll]: self._prices = prices self._prices_length = len[self._prices] - num_unroll self._batch_size = batch_size self._num_unroll = num_unroll self._segments = self._prices_length //self._batch_size self._cursor = [offset * self._segments for offset in range[self._batch_size]] def next_batch[self]: batch_data = np.zeros[[self._batch_size],dtype=np.float32] batch_labels = np.zeros[[self._batch_size],dtype=np.float32] for b in range[self._batch_size]: if self._cursor[b]+1>=self._prices_length: #self._cursor[b] = b * self._segments self._cursor[b] = np.random.randint[0,[b+1]*self._segments] batch_data[b] = self._prices[self._cursor[b]] batch_labels[b]= self._prices[self._cursor[b]+np.random.randint[0,5]] self._cursor[b] = [self._cursor[b]+1]%self._prices_length return batch_data,batch_labels def unroll_batches[self]: unroll_data,unroll_labels = [],[] init_data, init_label = None,None for ui in range[self._num_unroll]: data, labels = self.next_batch[] unroll_data.append[data] unroll_labels.append[labels] return unroll_data, unroll_labels def reset_indices[self]: for b in range[self._batch_size]: self._cursor[b] = np.random.randint[0,min[[b+1]*self._segments,self._prices_length-1]] dg = DataGeneratorSeq[train_data,5,5] u_data, u_labels = dg.unroll_batches[] for ui,[dat,lbl] in enumerate[zip[u_data,u_labels]]: print['\n\nUnrolled index %d'%ui] dat_ind = dat lbl_ind = lbl print['\tInputs: ',dat ] print['\n\tOutput:',lbl] Xác định Hyperparameters Trong phần này, bạn sẽ định nghĩa một số hyperparameters. D là chiều của đầu vào. Thật đơn giản, khi bạn lấy giá cổ phiếu trước đó làm đầu vào và dự đoán giá tiếp theo, giá trị này phải là 1. Sau đó, bạn có num_unrollings, đây là một tham số liên quan đến backpropagation qua thời gian [BPTT] được sử dụng để tối ưu hóa model LSTM. Điều này biểu thị số bước thời gian liên tục mà bạn xem xét cho một bước tối ưu hóa duy nhất. Bạn có thể nghĩ về điều này, thay vì tối ưu hóa model bằng cách xem xét một bước thời gian, bạn tối ưu hóa mạng bằng cách xem các bước thời gian num_unrollings. Càng lớn càng tốt. Sau đó, bạn có batch_size. Kích thước lô là số lượng mẫu dữ liệu bạn xem xét trong một bước thời gian. Tiếp theo, bạn xác định num_nodes đại diện cho số lượng tế bào thần kinh ẩn trong mỗi ô. Bạn có thể thấy rằng có ba lớp LSTM trong ví dụ này. D = 1 # Dimensionality of the data. Since your data is 1-D this would be 1 num_unrollings = 50 # Number of time steps you look into the future. batch_size = 500 # Number of samples in a batch num_nodes = [200,200,150] # Number of hidden nodes in each layer of the deep LSTM stack we're using n_layers = len[num_nodes] # number of layers dropout = 0.2 # dropout amount tf.reset_default_graph[] # This is important in case you run this multiple times Xác định đầu vào và đầu ra Tiếp theo bạn xác định trình giữ chỗ cho các đầu vào và nhãn đào tạo. Điều này rất đơn giản vì bạn có danh sách các trình giữ chỗ đầu vào, trong đó mỗi trình giữ chỗ chứa một lô dữ liệu duy nhất. Và danh sách có phần giữ chỗ num_unrollings, sẽ được sử dụng cùng một lúc cho một bước tối ưu hóa duy nhất. # Input data. train_inputs, train_outputs = [],[] # You unroll the input over time defining placeholders for each time step for ui in range[num_unrollings]: train_inputs.append[tf.placeholder[tf.float32, shape=[batch_size,D],name='train_inputs_%d'%ui]] train_outputs.append[tf.placeholder[tf.float32, shape=[batch_size,1], name = 'train_outputs_%d'%ui]] Định nghĩa các tham số của lớp LSTM và Regression Bạn sẽ có ba lớp LSTM và một lớp hồi qui tuyến tính, được biểu thị bằng w và b, lấy đầu ra của ô Long Short-Term Memory cuối cùng và đưa ra dự đoán cho bước thời gian tiếp theo. Bạn có thể sử dụng MultiRNNCell trong TensorFlow để đóng gói ba đối tượng LSTMCell mà bạn đã tạo ra. Ngoài ra, bạn có thể có dropout thực hiện các tế bào LSTM, khi chúng cải thiện hiệu suất và giảm bớt việc lấp đầy. lstm_cells = [ tf.contrib.rnn.LSTMCell[num_units=num_nodes[li], state_is_tuple=True, initializer= tf.contrib.layers.xavier_initializer[] ] for li in range[n_layers]] drop_lstm_cells = [tf.contrib.rnn.DropoutWrapper[ lstm, input_keep_prob=1.0,output_keep_prob=1.0-dropout, state_keep_prob=1.0-dropout ] for lstm in lstm_cells] drop_multi_cell = tf.contrib.rnn.MultiRNNCell[drop_lstm_cells] multi_cell = tf.contrib.rnn.MultiRNNCell[lstm_cells] w = tf.get_variable['w',shape=[num_nodes[-1], 1], initializer=tf.contrib.layers.xavier_initializer[]] b = tf.get_variable['b',initializer=tf.random_uniform[[1],-0.1,0.1]] Tính toán đầu ra LSTM và cho nó vào lớp hồi qui để nhận dự đoán cuối cùng Trong phần này, trước tiên bạn tạo các biến TensorFlow [c và h] sẽ giữ trạng thái ô và trạng thái ẩn của ô Long Short-Term Memory Dài. Sau đó, bạn chuyển đổi danh sách train_inputs thành hình dạng [num_unrollings, batch_size, D], điều này là cần thiết để tính toán kết quả đầu ra bằng hàm tf.nn.dynamic_rnn. Sau đó, bạn tính toán kết quả đầu ra LSTM bằng hàm tf.nn.dynamic_rnn và chia kết quả đầu ra trở lại danh sách các hằng số num_unrolling. sự mất mát giữa các dự đoán và giá cổ phiếu thực sự. # Create cell state and hidden state variables to maintain the state of the LSTM c, h = [],[] initial_state = [] for li in range[n_layers]: c.append[tf.Variable[tf.zeros[[batch_size, num_nodes[li]]], trainable=False]] h.append[tf.Variable[tf.zeros[[batch_size, num_nodes[li]]], trainable=False]] initial_state.append[tf.contrib.rnn.LSTMStateTuple[c[li], h[li]]] # Do several tensor transofmations, because the function dynamic_rnn requires the output to be of # a specific format. Read more at: //www.tensorflow.org/api_docs/python/tf/nn/dynamic_rnn all_inputs = tf.concat[[tf.expand_dims[t,0] for t in train_inputs],axis=0] # all_outputs is [seq_length, batch_size, num_nodes] all_lstm_outputs, state = tf.nn.dynamic_rnn[ drop_multi_cell, all_inputs, initial_state=tuple[initial_state], time_major = True, dtype=tf.float32] all_lstm_outputs = tf.reshape[all_lstm_outputs, [batch_size*num_unrollings,num_nodes[-1]]] all_outputs = tf.nn.xw_plus_b[all_lstm_outputs,w,b] split_outputs = tf.split[all_outputs,num_unrollings,axis=0] Mất tính toán và tối ưu hóa Bây giờ, bạn sẽ tính toán sự mất mát. Tuy nhiên, bạn nên lưu ý rằng có một đặc điểm duy nhất khi tính toán sự mất mát. Đối với mỗi đợt dự đoán và đầu ra thực, bạn tính toán Lỗi trung bình bình phương. Và bạn tính tổng [không phải trung bình] tất cả những khoản tiền bình phương này lại với nhau. Cuối cùng, bạn xác định trình tối ưu hóa bạn sẽ sử dụng để tối ưu hóa mạng thần kinh. Trong trường hợp này, bạn có thể sử dụng Adam, một trình tối ưu hóa rất gần đây và hoạt động tốt. # When calculating the loss you need to be careful about the exact form, because you calculate # loss of all the unrolled steps at the same time # Therefore, take the mean error or each batch and get the sum of that over all the unrolled steps print['Defining training Loss'] loss = 0.0 with tf.control_dependencies[[tf.assign[c[li], state[li][0]] for li in range[n_layers]]+ [tf.assign[h[li], state[li][1]] for li in range[n_layers]]]: for ui in range[num_unrollings]: loss += tf.reduce_mean[0.5*[split_outputs[ui]-train_outputs[ui]]**2] print['Learning rate decay operations'] global_step = tf.Variable[0, trainable=False] inc_gstep = tf.assign[global_step,global_step + 1] tf_learning_rate = tf.placeholder[shape=None,dtype=tf.float32] tf_min_learning_rate = tf.placeholder[shape=None,dtype=tf.float32] learning_rate = tf.maximum[ tf.train.exponential_decay[tf_learning_rate, global_step, decay_steps=1, decay_rate=0.5, staircase=True], tf_min_learning_rate] # Optimizer. print['TF Optimization operations'] optimizer = tf.train.AdamOptimizer[learning_rate] gradients, v = zip[*optimizer.compute_gradients[loss]] gradients, _ = tf.clip_by_global_norm[gradients, 5.0] optimizer = optimizer.apply_gradients[ zip[gradients, v]] print['\tAll done'] Dự đoán tính toán liên quan Ở đây bạn xác định các hoạt động liên quan đến dự đoán TensorFlow. Đầu tiên, hãy định nghĩa một trình giữ chỗ cho ăn trong đầu vào [sample_inputs], sau đó tương tự như giai đoạn đào tạo, bạn xác định các biến trạng thái để dự đoán [sample_c và sample_h]. Cuối cùng, bạn tính toán dự đoán với hàm tf.nn.dynamic_rnn và sau đó gửi đầu ra qua lớp hồi quy [w và b]. Bạn cũng nên xác định hoạt động reset_sample_state, cài đặt lại trạng thái ô và trạng thái ẩn. Bạn nên thực hiện thao tác này ngay từ đầu, mỗi khi bạn thực hiện một chuỗi các dự đoán. print['Defining prediction related TF functions'] sample_inputs = tf.placeholder[tf.float32, shape=[1,D]] # Maintaining LSTM state for prediction stage sample_c, sample_h, initial_sample_state = [],[],[] for li in range[n_layers]: sample_c.append[tf.Variable[tf.zeros[[1, num_nodes[li]]], trainable=False]] sample_h.append[tf.Variable[tf.zeros[[1, num_nodes[li]]], trainable=False]] initial_sample_state.append[tf.contrib.rnn.LSTMStateTuple[sample_c[li],sample_h[li]]] reset_sample_states = tf.group[*[tf.assign[sample_c[li],tf.zeros[[1, num_nodes[li]]]] for li in range[n_layers]], *[tf.assign[sample_h[li],tf.zeros[[1, num_nodes[li]]]] for li in range[n_layers]]] sample_outputs, sample_state = tf.nn.dynamic_rnn[multi_cell, tf.expand_dims[sample_inputs,0], initial_state=tuple[initial_sample_state], time_major = True, dtype=tf.float32] with tf.control_dependencies[[tf.assign[sample_c[li],sample_state[li][0]] for li in range[n_layers]]+ [tf.assign[sample_h[li],sample_state[li][1]] for li in range[n_layers]]]: sample_prediction = tf.nn.xw_plus_b[tf.reshape[sample_outputs,[1,-1]], w, b] print['\tAll done'] Chạy LSTM Ở đây bạn sẽ đào tạo và dự đoán các biến động giá cổ phiếu trong một vài kỷ nguyên và xem liệu các dự đoán có tốt hơn hay xấu hơn theo thời gian hay không. Bạn làm theo các thủ tục sau đây. Xác định một tập kiểm tra các điểm bắt đầu [test_points_seq] trên Time-series để đánh giá model trên Đối với mỗi kỷ nguyên Đối với toàn bộ chuỗi thời lượng của dữ liệu đào tạo Mở một tập hợp các lô num_unrollings Đào tạo mạng thần kinh với các lô chưa được kiểm soát Tính toán tổn thất đào tạo trung bình Đối với mỗi điểm xuất phát trong tập kiểm tra Cập nhật trạng thái LSTM bằng cách lặp qua các điểm dữ liệu num_unrollings trước đó được tìm thấy trước điểm kiểm tra Đặt dự đoán cho các bước n_predict_once liên tục, sử dụng dự đoán trước đó làm đầu vào hiện tại Tính toán khoản lỗ MSE giữa các điểm n_predict_once được dự đoán và giá cổ phiếu thực tại các thời điểm đó epochs = 30 valid_summary = 1 # Interval you make test predictions n_predict_once = 50 # Number of steps you continously predict for train_seq_length = train_data.size # Full length of the training data train_mse_ot = [] # Accumulate Train losses test_mse_ot = [] # Accumulate Test loss predictions_over_time = [] # Accumulate predictions session = tf.InteractiveSession[] tf.global_variables_initializer[].run[] # Used for decaying learning rate loss_nondecrease_count = 0 loss_nondecrease_threshold = 2 # If the test error hasn't increased in this many steps, decrease learning rate print['Initialized'] average_loss = 0 # Define data generator data_gen = DataGeneratorSeq[train_data,batch_size,num_unrollings] x_axis_seq = [] # Points you start your test predictions from test_points_seq = np.arange[11000,12000,50].tolist[] for ep in range[epochs]: # ========================= Training ===================================== for step in range[train_seq_length//batch_size]: u_data, u_labels = data_gen.unroll_batches[] feed_dict = {} for ui,[dat,lbl] in enumerate[zip[u_data,u_labels]]: feed_dict[train_inputs[ui]] = dat.reshape[-1,1] feed_dict[train_outputs[ui]] = lbl.reshape[-1,1] feed_dict.update[{tf_learning_rate: 0.0001, tf_min_learning_rate:0.000001}] _, l = session.run[[optimizer, loss], feed_dict=feed_dict] average_loss += l # ============================ Validation ============================== if [ep+1] % valid_summary == 0: average_loss = average_loss/[valid_summary*[train_seq_length//batch_size]] # The average loss if [ep+1]%valid_summary==0: print['Average loss at step %d: %f' % [ep+1, average_loss]] train_mse_ot.append[average_loss] average_loss = 0 # reset loss predictions_seq = [] mse_test_loss_seq = [] # ===================== Updating State and Making Predicitons ======================== for w_i in test_points_seq: mse_test_loss = 0.0 our_predictions = [] if [ep+1]-valid_summary==0: # Only calculate x_axis values in the first validation epoch x_axis=[] # Feed in the recent past behavior of stock prices # to make predictions from that point onwards for tr_i in range[w_i-num_unrollings+1,w_i-1]: current_price = all_mid_data[tr_i] feed_dict[sample_inputs] = np.array[current_price].reshape[1,1] _ = session.run[sample_prediction,feed_dict=feed_dict] feed_dict = {} current_price = all_mid_data[w_i-1] feed_dict[sample_inputs] = np.array[current_price].reshape[1,1] # Make predictions for this many steps # Each prediction uses previous prediciton as it's current input for pred_i in range[n_predict_once]: pred = session.run[sample_prediction,feed_dict=feed_dict] our_predictions.append[np.asscalar[pred]] feed_dict[sample_inputs] = np.asarray[pred].reshape[-1,1] if [ep+1]-valid_summary==0: # Only calculate x_axis values in the first validation epoch x_axis.append[w_i+pred_i] mse_test_loss += 0.5*[pred-all_mid_data[w_i+pred_i]]**2 session.run[reset_sample_states] predictions_seq.append[np.array[our_predictions]] mse_test_loss /= n_predict_once mse_test_loss_seq.append[mse_test_loss] if [ep+1]-valid_summary==0: x_axis_seq.append[x_axis] current_test_mse = np.mean[mse_test_loss_seq] # Learning rate decay logic if len[test_mse_ot]>0 and current_test_mse > min[test_mse_ot]: loss_nondecrease_count += 1 else: loss_nondecrease_count = 0 if loss_nondecrease_count > loss_nondecrease_threshold : session.run[inc_gstep] loss_nondecrease_count = 0 print['\tDecreasing learning rate by 0.5'] test_mse_ot.append[current_test_mse] print['\tTest MSE: %.5f'%np.mean[mse_test_loss_seq]] predictions_over_time.append[predictions_seq] print['\tFinished Predictions'] Hình dung các dự đoán Bạn có thể thấy sự mất mát của MSE đang giảm xuống như thế nào với số lượng đào tạo. Đây là dấu hiệu tốt cho thấy model đang học cái gì đó hữu ích. Để định lượng phát hiện của bạn, bạn có thể so sánh tổn thất MSE của mạng với tổn thất MSE mà bạn thu được khi thực hiện tiêu chuẩn trung bình [0,004]. Bạn có thể thấy rằng LSTM đang làm tốt hơn so với mức trung bình tiêu chuẩn. Và bạn biết rằng tiêu chuẩn trung bình [mặc dù không hoàn hảo] theo sau các phong trào giá cổ phiếu thực sự hợp lý. best_prediction_epoch = 28 # replace this with the epoch that you got the best results when running the plotting code plt.figure[figsize = [18,18]] plt.subplot[2,1,1] plt.plot[range[df.shape[0]],all_mid_data,color='b'] # Plotting how the predictions change over time # Plot older predictions with low alpha and newer predictions with high alpha start_alpha = 0.25 alpha = np.arange[start_alpha,1.1,[1.0-start_alpha]/len[predictions_over_time[::3]]] for p_i,p in enumerate[predictions_over_time[::3]]: for xval,yval in zip[x_axis_seq,p]: plt.plot[xval,yval,color='r',alpha=alpha[p_i]] plt.title['Evolution of Test Predictions Over Time',fontsize=18] plt.xlabel['Date',fontsize=18] plt.ylabel['Mid Price',fontsize=18] plt.xlim[11000,12500] plt.subplot[2,1,2] # Predicting the best test prediction you got plt.plot[range[df.shape[0]],all_mid_data,color='b'] for xval,yval in zip[x_axis_seq,predictions_over_time[best_prediction_epoch]]: plt.plot[xval,yval,color='r'] plt.title['Best Test Predictions Over Time',fontsize=18] plt.xlabel['Date',fontsize=18] plt.ylabel['Mid Price',fontsize=18] plt.xlim[11000,12500] plt.show[] Mặc dù không hoàn hảo, LSTM dường như có thể dự đoán hành vi giá cổ phiếu một cách chính xác phần lớn thời gian. Lưu ý rằng bạn đang dự đoán gần đúng trong khoảng 0 và 1.0 [nghĩa là, không phải giá cổ phiếu thực]. Điều này là ổn, bởi vì bạn đang dự đoán chuyển động giá cổ phiếu, không phải là giá của chính họ. Chú thích cuối Tôi hy vọng rằng bạn thấy hướng dẫn này hữu ích. Tôi nên đề cập rằng đây là một kinh nghiệm bổ ích cho tôi. Trong hướng dẫn này, tôi đã học được cách khó khăn để thiết bị một model có thể dự đoán chính xác các biến động giá cổ phiếu. Bạn bắt đầu với một động lực cho lý do tại sao bạn cần phải model hóa giá cổ phiếu. Tiếp theo là một lời giải thích và mã để tải xuống dữ liệu. Sau đó, bạn đã xem xét hai kỹ thuật trung bình cho phép bạn dự đoán một bước trong tương lai. Bạn tiếp theo thấy rằng những phương pháp này là vô ích khi bạn cần phải dự đoán nhiều hơn một bước trong tương lai. Sau đó bạn đã thảo luận cách bạn có thể sử dụng LSTM để đưa ra những dự đoán nhiều bước trong tương lai. Cuối cùng, bạn đã hình dung kết quả và thấy rằng model của bạn [mặc dù không hoàn hảo] là khá tốt khi dự đoán chính xác biến động giá cổ phiếu. Nếu bạn muốn tìm hiểu thêm về học tập sâu, hãy chắc chắn để có một cái nhìn tại Deep Learning của chúng tôi trong khóa học Python. Nó bao gồm những điều cơ bản, cũng như làm thế nào để xây dựng một mạng thần kinh của riêng bạn trong Keras. Đây là một gói khác với TensorFlow, sẽ được sử dụng trong hướng dẫn này, nhưng ý tưởng là như nhau. Ở đây, tôi đang nói một số hướng dẫn của hướng dẫn này. Giá cổ phiếu / dự báo chuyển động là một nhiệm vụ cực kỳ khó khăn. Cá nhân tôi không nghĩ rằng bất kỳ các model dự đoán cổ phiếu ra khỏi đó không nên được thực hiện cho các cấp và mù quáng dựa vào chúng. Tuy nhiên, các model có thể dự đoán sự biến động giá cổ phiếu một cách chính xác phần lớn thời gian, nhưng không phải lúc nào cũng vậy. Đừng để bị lừa bởi các bài báo trên đó cho thấy đường cong dự đoán mà chồng chéo hoàn toàn giá cổ phiếu thực sự. Điều này có thể được nhân rộng với một kỹ thuật trung bình đơn giản và trong thực tế nó vô dụng. Một điều hợp lý hơn để làm là dự đoán biến động giá cổ phiếu. Các hyperparameters của model cực kỳ nhạy cảm với kết quả bạn thu được. Vì vậy, một điều rất tốt cần làm là chạy một số kỹ thuật tối ưu hóa siêu tham số [ví dụ, tìm kiếm lưới / tìm kiếm ngẫu nhiên] trên các siêu tham số. Dưới đây tôi liệt kê một số các hyperparameters quan trọng nhất Tốc độ học của trình tối ưu hóa Số lượng lớp và số lượng đơn vị ẩn trong mỗi lớp Trình tối ưu hóa. Tôi tìm thấy Adam để thực hiện tốt nhất Loại model. Bạn có thể thử GRU / Standard LSTM / LSTM với Peepholes và đánh giá hiệu suất khác biệt Trong hướng dẫn này, bạn đã làm điều gì đó bị lỗi [do kích thước dữ liệu nhỏ]! Đó là bạn đã sử dụng mất kiểm tra để phân rã tốc độ học tập. Điều này gián tiếp rò rỉ thông tin về kiểm tra thiết lập vào các thủ tục đào tạo. Một cách tốt hơn để xử lý này là có một bộ xác nhận riêng biệt [ngoài bộ kiểm tra] và tỷ lệ học tập phân rã liên quan đến hiệu suất của bộ xác nhận hợp lệ.

Nếu bạn muốn liên lạc với tôi, bạn có thể gửi cho tôi một email tại [email protected] hoặc kết nối với tôi qua LinkedIn.

Tài liệu tham khảo Tôi đã giới thiệu đến kho lưu trữ này để hiểu về cách sử dụng LSTM cho dự đoán cổ phiếu. Nhưng chi tiết có thể khác xa so với việc thực hiện được tìm thấy trong tham chiếu

Video liên quan

Chủ Đề