รู้รึเปล่า? หุ้นตัวไหนน่าเสี่ยง น่าซื้อ… ก็สามารถใช้ Machine learning ทำนายได้นะ😉
By: Kulyarat L.
Tags: Botnoi Classroom, Data Science, Trend Forecast

Step 2 Data Cleansing and Transformation

อันดับแรกมาเช็ค Data type กับ missing value กันก่อน

ทีนี้เราก็จะมา drop คอลลัมน์ที่เราไม่ใช้ทิ้งไป

def Drop_DivSplit(dataframe): dataframe.drop('Dividends', axis=1, inplace=True) dataframe.drop('Stock Splits', axis=1, inplace=True) dataframe.drop('Adj Close', axis=1, inplace=True) return dataframe

ก็จะได้มาแบบนี้ ตอนนี้ก็ไม่มีสามคอลลัมน์ที่เราไม่ใช้แล้ว

2.1 Get Features

# Create get_X_y function to get dependent (y) and independent (X) variables def get_X_y(dataframe): # Extract time series variable X = dataframe.reset_index()[['Date']] X['Year'] = [X.iloc[i, 0].year for i in range(len(X))] X['Month'] = [X.iloc[i, 0].month for i in range(len(X))] X['Day'] = [X.iloc[i, 0].day for i in range(len(X))] X['EnglishDay'] = X.Date.dt.strftime('%a') # Set categorical variable X = X.astype({'Month':'category', 'Day':'category', 'EnglishDay':'category'}).set_index('Date') # Get OHLC X = X.merge(dataframe, left_index=True, right_index=True) y = dataframe[['NextDayClose']].copy() return X,y

จากโค้ดนี้ก็คือเรากำลังจะทำตัว features เป็น time series ดังนั้น เราก็จะทำให้วันที่กลายเป็น คอลลัมน์ขึ้นมาก่อน

ทีนี้เราก็จะทำให้ Month, Day, EnglishDay เป็น category เพื่อที่เราจะสามารถจับ Trend ของข้อมูลได้ ตัวอย่างเช่น ทุกวันศุกร์ บีทีเอสจะมีคนใช้เยอะเป็นพิเศษ

เสร็จแล้วเราก็เอา original dataframe มา merge กับตัวที่มี features

ก็จะออกมาแบบนี้

# Create feature_engineer function to extract new features def feature_engineer(dataframe, feat_eng=False): #Looking for 90 day if feat_eng: # Create a feature from next day Close dataframe[f'NextDayClose'] = dataframe[['Close']].shift(periods=-1, fill_value=0) for i in range(1,91): # Create a feature from previous day HIGH dataframe[f'PreviousDayHigh{i}'] = dataframe[['High']].shift(periods=i,fill_value=0) # Create a feature from previous day LOW dataframe[f'PreviousDayLow{i}'] = dataframe[['Low']].shift(periods=i, fill_value=0) # Create a feature from previous day Open dataframe[f'PreviousDayOpen{i}'] = dataframe[['Open']].shift(periods=i,fill_value=0) # Create a feature from previous day Close dataframe[f'PreviousDayClose{i}'] = dataframe[['Close']].shift(periods=i,fill_value=0)

dataframe = dataframe[dataframe.PreviousDayHigh90!= 0 ] dataframe = dataframe[:-1] return dataframe

เสร็จแล้วเราก็จะสร้าง features จากอย่างอื่นนอกจาก time กันบ้าง โดยจากโค้ดนี้เราก็จะสร้าง features จาก ราคาเปิด-ปิด สูง-ต่ำ ของวันก่อนหน้า วันที่กำลังวิเคราะห์อยู่ (เช่นถ้าวิเคราะห์ข้อมูลวันที่ 20 ก็ใช้ราคาวันที่ 19)

def feature_diff(dataframe): dataframe[f'NextDayClose'] = dataframe[f'NextDayClose']-dataframe['Close'] for i in range(1,91): # Create a feature from previous day HIGH dataframe[f'PreviousDayHigh{i}'] = dataframe[f'PreviousDayHigh{i}']- dataframe['High'] # Create a feature from previous day LOW dataframe[f'PreviousDayLow{i}'] = dataframe[f'PreviousDayLow{i}']- dataframe['Low'] # Create a feature from previous day Open dataframe[f'PreviousDayOpen{i}'] = dataframe[f'PreviousDayOpen{i}']- dataframe['Open'] # Create a feature from previous day Open dataframe[f'PreviousDayClose{i}'] = dataframe[f'PreviousDayClose{i}']- dataframe['Close'] return dataframe

method นี้เป็นการหา diff ราคาของวันที่วิเคราะห์ กับวันก่อนหน้า แล้วไปทำเป็น features เช่นกัน

2.2 Get one-hot encoder

def one_hot_encoder(dataframe): # Select category columns cat_df = dataframe.select_dtypes(include=['category']).columns.to_list()

# Convert to one-hot dataframe one_hot_df = pd.get_dummies(dataframe, columns=cat_df) return one_hot_df

ก็คือเราจะมา encode ข้อมูลในคอลลัมน์ที่เป็น category ให้กลายเป็นตัวเลข 0,1 เพื่อที่จะสามารถเอาไปรันในโมเดลได้

หน้าตาประมาณนี้

2.3. Split train and test dataframe

# Create stock_train_test_split function def stock_train_test_split(dataframe, y, trainsize=0.8): import math train_ratio = trainsize train_size = math.ceil(len(dataframe) * train_ratio) # Get train dataframe X_train = dataframe.iloc[:train_size, :] y_train = y.iloc[:train_size, :] # Get train dataframe # X_test = dataframe.iloc[train_size:, :] X_test = dataframe.copy() y_test = y.iloc[train_size:, :] # Drop label from independent variable col_drop = ['OPEN', 'HIGH', 'LOW', 'CLOSE', 'VOLUME'] X_train = X_train.drop(col_drop, axis=1) X_test = X_test.drop(col_drop, axis=1) return X_train, X_test, y_train, y_test

ในขั้นตอนนี้เราจะเริ่มมา split ข้อมูลเป็น train กับ test เพื่อที่จะเอาไปใช้ในการ fit model และ predict กันต่อไป