Data Analysis/Machine Learning

[ISLP] Logistic Regression Lap

Jiyeon's Desk 2025. 3. 20. 16:47

 

목적 : 주식 시장 데이터를 사용해서 다음날 주가가 오를지 내릴지 예측하는 로지스틱 회귀 모델을 학습

 

데이터는 다음과 같이 생겼다. 받은 데이터 셋에서는 Direction이 이미 있지만, 로지스틱 회귀 모델을 사용하여 예측한 Direction의 값의 정확성을 예측하기 위해 사용될 예정이다.

 

First Step:

allvars = Smarket.columns.drop(['Today', 'Direction', 'Year'])
design =MS(allvars)
X = design.fit_transform(Smarket)
y = Smarket.Direction == 'Up'
glm = sm.GLM(y,X, family=sm.families.Binomial())
results = glm.fit()
summarize(results)
 
probs = results.predict()
labels = np.array(['Down']*1250)
labels[probs>0.5] = "Up"
confusion_table(labels, Smarket.Direction)
np.mean(labels == Smarket.Direction)

 

주식시장 에측에 사용될 변수만 남기고, MS를 통해 주어진 변수들을 사용하여 모델의 입력 데이터(설계 행렬, Design matrix)를 만든다. 즉, 모델이 학습할 데이터(X)를 만들었다. y를 up 값을 받으면 true, down을 받으면 false를 받는다(y는 0 또는 1 을 가지는 벡터가 됨) 로지스틱 회귀 모델을 사용하여 모델을 학습시킨다(fit). 즉, 최대우도추정 MLE를 사용하여 회귀 계수를 학습한다.

 

그 후, 학습된 모델을 사용하여 각 데이터 샘플에 대해서 주가가 상승할 확률을 계산한다. 계산한 값이 0.5보다 크면 up, 작으면 down이 되고 원래 데이터의 direction컬럼과 비교하는 작업을 수행한다.

52% 잘 예측한다.

 

Second Step:

first step에서는 같은 데이터 셋으로 학습도 하고, 테스트도 진행하여 과적합 현상이 일어난다. 과적합을 방지하기 위해서 데이터를 2005년이전을 트레이닝 데이터 세트, 그 후를 테스트 데이터 셋으로 설정한다. 결과를 해석할 때 모델이 예측한 값과 실제 dirction값을 비교하기 위해서 dirction컬럼도 train, test로 나눈다.

train = (Smarket.Year < 2005)
Smaket_trian = Smarket.loc[train]
Smaket_test = Smarket.loc[~train]
 
X_train, X_test = X.loc[train], X.loc[~train]
y_train, y_test = y.loc[train], y.loc[~train]

glm_train = sm.GLM(y_train, X_train, family=sm.families.Binomial())
results = glm_train.fit()
probs = results.predict(exog=X_test)
 
D = Smarket.Direction
L_train, L_test = D.loc[train], D.loc[~train]
 
labels = np.array(['Down']*252)
labels[probs>0.5] = 'Up'
confusion_table(labels, L_test)

48% 잘 예측한다고 나온다.

 

Third Step:

'오늘'에서 먼 lag3, lag4, lag5를 제외해서 훈련,예측을 진행해보겠다. feature을 줄이는 이유는 과적합을 방지하고 일반화 성능을 높이기 위해서이다.

model =MS(['Lag1','Lag2']).fit(Smarket)
X = model.fit_transform(Smarket)
X_train, X_test = X.loc[train], X.loc[~train]
y = Smarket.Direction == 'Up'
glm_train= sm.GLM(y_train,X_train, family=sm.families.Binomial())
results = glm_train.fit()

probs = results.predict(exog = X_test)
labels =np.array(['Down']*252)
labels[probs>0.5] ='Up'
confusion_table(labels, L_test)

55% 잘예측 ^~^

 

logistic regression.ipynb
0.07MB