오늘도 머신러닝에 대해 배웠다. 확실히 머신러닝 파트에 들어오고부터는 이론도 많지만 코드로 접근하는 시간이 많아져서 한결 편한 것 같다. 그러면서 동시에 생각보다 코드는 어려운 부분이 없고 많은 부분이 정해져 있어서 그 이전 과정인 데이터 전처리와 핸들링, 통계 분석 부분의 실력을 쌓는 것이 더 중요한 것 같은 느낌이 들었다.
from sklearn.model_selection import train_test_split
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=1234)
y_train.mean()
# np.float64(9697.907297830374)
y_valid.mean()
# np.float64(9692.633858267716)
from sklearn.linear_model import LinearRegression
fit_intercept : y절편 계산 여부Truecopy_X : 특성 행렬 X의 복사 여부 지정Truetol : X가 희소행렬인 경우 최소제곱문제를 풀기 위한 알고리즘 오차 허용 범위1e-6n_jobs : 연산에 사용할 코어 지정NoneNone = 1positive : 회귀계수를 양수로 강제할지 여부Falsemodel_linear = LinearRegression()
model_linear.fit(X=X_train, y=y_train)
model_linear.get_params()
# {'copy_X': True,
# 'fit_intercept': True,
# 'n_jobs': None,
# 'positive': False,
# 'tol': 1e-06}
score()model_linear.score(X=X_train, y=y_train)
# 0.7453200377582148
model_linear.score(X=X_valid, y=y_valid)
# 0.7350351379962555
model_linear.coef_
# array([-9.93166454e+01, -1.67673109e-02, -2.96617966e+01, -1.05935604e+01,
# 3.84406446e+01, 2.65917973e+00, -2.74794384e+01, 1.74106123e+01,
# 6.13430567e+02, -1.94223202e+03, 1.32880146e+03])
model_linear.intercept_
# np.float64(-3566.4391928929563)
from sklearn.linear_model import Ridge
fit_intercept : y절편 계산 여부Truecopy_X : 특성 행렬 X의 복사 여부 지정Truetol : X가 희소행렬인 경우 최소제곱문제를 풀기 위한 알고리즘 오차 허용 범위1e-6positive : 회귀계수를 양수로 강제할지 여부Falsealpha : 규제 상수( )max_iter : 최대 반복 횟수Nonesolver : 최적화 알고리즘automodel_ridge = Ridge(alpha=1)
model_ridge.fit(X=X_train, y=y_train)
model_ridge.score(X=X_train, y=y_train)
# 0.745024558772102
from sklearn.linear_model import Lasso
fit_intercept : y절편 계산 여부Truecopy_X : 특성 행렬 X의 복사 여부 지정Truetol : X가 희소행렬인 경우 최소제곱문제를 풀기 위한 알고리즘 오차 허용 범위1e-6positive : 회귀계수를 양수로 강제할지 여부Falsealpha : 규제 상수( )max_iter : 최대 반복 횟수Noneprecompute : 그람 행렬 미리 계산Falseselection : 계수 업데이트 순서‘cyclic’warm_start : 이전 결과를 초기값으로 재사용 여부Falsemodel_lasso = Lasso(alpha=1)
model_lasso.fit(X=X_train, y=y_train)
model_lasso.score(X=X_train, y=y_train)
# 0.7451306731162222
model_lasso.score(X=X_valid, y=y_valid)
# 0.7368623585441034
pd.DataFrame(
data={
'Linear': model_linear.coef_,
'Ridge': model_ridge.coef_,
'Lasso': model_lasso.coef_
},
index=X_train.columns
)

y_pred_linear = model_linear.predict(X=X_valid)
y_pred_ridge = model_ridge.predict(X=X_valid)
y_pred_lasso = model_lasso.predict(X=X_valid)
pd.DataFrame(
data={
'Real': y_valid,
'Pred_Linear': y_pred_linear,
'Pred_Ridge': y_pred_ridge,
'Pred_Lasso': y_pred_lasso
}
)

from sklearn.metrics import mean_squared_error
from sklearn.metrics import root_mean_squared_error
from sklearn.metrics import mean_absolute_percentage_error
mean_squared_error(y_true=y_valid, y_pred=y_pred_linear)
# 972596.4199871043
root_mean_squared_error(y_true=y_valid, y_pred=y_pred_ridge)
# 981.7528319556632
mean_absolute_percentage_error(y_true=y_valid, y_pred=y_pred_lasso)
# 0.08251582058445193
hds.stat.regmetrics(y_true=y_valid, y_pred=y_pred_linear)

alphas = np.arange(0.1, 20.1, 0.1)
vl_req = []
for alpha in alphas:
model_ridge.set_params(alpha=alpha).fit(X=X_train, y=y_train)
vl_req.append(model_ridge.score(X=X_valid, y=y_valid))
np.max(vl_req)
# np.float64(0.7397932326581274)
index = np.argmax(vl_req)
# np.int64(106)
alphas[index]
# np.float64(10.700000000000001)
df = pd.get_dummies(data=df, columns=['rank'], dtype=int)
df.head()

yvar = 'admit'
X = df.drop(columns=yvar)
y = df[yvar].copy()
display(X)
display(y)

from sklearn.model_selection import train_test_split
train_test_split 함수의 stratify 속성에 범주형 시리즈를 지정하면 해당 변수의 원소별 상대도수 기준으로 층화추출을 실행X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=1, stratify=df['admit'])
display(y_train.value_counts(normalize=True).sort_index())
# admit
# Fail 0.6894
# Pass 0.3106
# Name: proportion, dtype: float64
display(y_valid.value_counts(normalize=True).sort_index())
# admit
# Fail 0.689349
# Pass 0.310651
# Name: proportion, dtype: float64
from sklearn.linear_model import LogisticRegression
C : 정규화 강도(작을수록 강한 규제)class_weight : 클래스별 가중치(불균형 데이터 처리)Nonedual : 각 행별 영향력 관점으로 최적화Falsefit_intercept : y절편 계산 여부Trueintercept_scaling : 절편 정규화 스케일링l1_ratio : L1, L2, ElasticNet 비율 선택C=np.infl1_ratio=0.0l1_ratio=1.0, solver=’liblinear’penalty : 1.10 버전에서 제거 예정max_iter : 최대 반복 횟수Nonen_jobs : 연산에 사용할 코어 지정NoneNone = 1random_state : 난수 시드Nonesolver : 최적화 알고리즘‘lbfgs’tol : 수렴 판단 기준verbose : 로그 출력 수준warm_start : 이전 결과를 초기값으로 재사용 여부Falsemodel_logit = LogisticRegression(C=np.inf, max_iter=1000, random_state=0)
model_logit.fit(X=X_train, y=y_train)
model_logit.score(X=X_train, y=y_train)
# 0.7323943661971831
model_logit.score(X=X_valid, y=y_valid)
# 0.6863905325443787
model_logit.intercept_
# array([-5.35142011])
model_logit.coef_[0]
# array([ 0.0038324 , 1.07656158, -0.2272636 , -1.1787027 , -1.78295985,
# -2.16249395])
‘lbfgs’‘liblinear’‘newton-cg’‘sag’‘saga’‘lbfgs’ 는 안정적으로 사용‘liblinear’ 큰 데이터는 ‘saga’ 를 선택‘liblinear’ 는 이진 분류만 지원model_ridge = LogisticRegression(l1_ratio=0, max_iter=1000, random_state=0, C=0.1, solver='lbfgs')
model_ridge.fit(X=X_train, y=y_train)
model_ridge.score(X=X_train, y=y_train)
# 0.7249814677538917
model_ridge.score(X=X_valid, y=y_valid)
# 0.6952662721893491
model_lasso = LogisticRegression(l1_ratio=1, max_iter=1000, random_state=0, solver='liblinear', C=0.1)
model_lasso.fit(X=X_train, y=y_train)
model_lasso.score(X=X_train, y=y_train)
# 0.7220163083765753
model_lasso.score(X=X_valid, y=y_valid)
# 0.6804733727810651
pd.DataFrame(
data={
'Logit': model_logit.coef_[0],
'Ridge': model_ridge.coef_[0],
'Lasso': model_lasso.coef_[0],
},
index=X_train.columns
)

y_pred_logit = model_logit.predict(X=X_valid)
y_pred_ridge = model_ridge.predict(X=X_valid)
y_pred_lasso = model_lasso.predict(X=X_valid)
hds.stat.clfmetrics(y_true=y_valid, y_pred=y_pred_logit)

y_prob_logit = model_logit.predict_proba(X=X_valid)
y_prob_ridge = model_ridge.predict_proba(X=X_valid)
y_prob_lasso = model_lasso.predict_proba(X=X_valid)
hds.plot.roc_curve(y_true=y_valid, y_prob=y_prob_logit, color='red')
hds.plot.roc_curve(y_true=y_valid, y_prob=y_prob_ridge, color='green')
hds.plot.roc_curve(y_true=y_valid, y_prob=y_prob_lasso, color='blue')

sns.boxplot(x=y_valid, y=y_prob_logit[:, 1])
plt.axhline(y=0.5, color='0.5', linestyle='--')
plt.axhline(y=0.31, color='red', linestyle='-')
plt.show()

hds.plot.pr_curve(y_true=y_valid, y_prob=y_prob_logit, color='red')
hds.plot.pr_curve(y_true=y_valid, y_prob=y_prob_ridge, color='green')
hds.plot.pr_curve(y_true=y_valid, y_prob=y_prob_lasso, color='blue')

강사님께서 주신 실제 데이터를 사용해서 데이터 전처리부터 통계 분석을 진행하면서 나만의 통계 분석 템플릿을 만들고 있는데 워낙 케이스도 많고 아직 잘 아는 게 아니다 보니 막히는 부분이 많다. 단계별로 조금씩 해결해가면서 템플릿을 완성하면 이후에는 조금 수월하게 작업을 할 수 있지 않을까 싶다.