# 모델을 넣고나서
# 학습한 모델로 .predict를 하던 .pvalues[] 또는 .params를 진행함
예측을 한다 -> .predict() /
설명변수, 의미를 찾는다 -> .pvalues[] /
오즈비, 회귀계수를 찾는다 -> .params[]
---Predict 관련 빈출예시 ---- #예측 #RMSE
# 이탈 확률이 0.3 이상인 고객 수 예측 # 9회 3-2-2
proba = model.predict(X_const)
result = (proba >= 0.3).sum()
# 정해준 값으로 예측
new_data = [[1, 50, 28, 120]] #2차원! 1차원으로 해도상관없긴함 #10회 3-1-2
pred = model.predict(new_data)
print(pred)
# RMSE # 9회 3-1-3
pred = model.predict(X_const)
from sklearn.metrics import root_mean_squared_error
rmse = root_mean_squared_error(y, pred)
---Pvalues 관련 빈출예시--- #유의확률, 유의미한값 #설명변수
# 1. 해당 col의 pvalue 값을 구하여라
result = model.pvalues['col']
print(round(result ,4))
# 2. 의미가 없는 설명변수를 개수는
pvalue1 = model.pvalues.drop('const') # 모델넣을때 상수를 넣었으니 빼야함 #9회 3-1-1
result = (pvalue1 >= 0.05).sum()
# 3. 유의수준 0.05 이하인 변수명 추출 # 10회 3-2-2
names = model.pvalues[model.pvalues <= 0.05].index
# 3-1. 유의미한 변수의 이름을 찾겠다. # 8회 3-1-2
name1 = model.pvalues[model.pvalues < 0.05].index
# 3-2 유의확률이 가장 낮은 변수 이름 확인 # 8회 3-2-1
name = model.pvalues.idxmin()
name = model.pvalues.sort_values().index[0] 동일함
---- Params ---- #회귀계수 #오즈비
# 유의한 회귀계수 확인 # 8회 3-1-2
coef = model.params[model.pvalues < 0.05]
odds = np.exp(coef) # 오즈비 문제
# 유의한 회귀계수의 합계 # 8회 3-1-2
result = model.params[model.pvalues < 0.05].sum()
3. summary() # r2
# 10회 3-2-1
---- 모든 회귀계수의 합-----
# 모든 독립변수를 포함한 회귀모형을 적합하시오. 이때 절편을 제외한 회귀계수의 합을 구하시오.
# heattng_load : 난방 부하 (종속변수)
# X, y 분리
y = df['heating_load']
X = df.drop(['heating_load'], axis=1)
# 상수항 추가
import statsmodels.api as sm
X_const = sm.add_constant(X)
model = sm.OLS(y, X_const).fit()
summary = model.summary()
print(summary)
model.params[1:].sum() 해도되긴함 # (1은 상수항 제거)
# 사진 1번의 const (절편)을 제외한 나머지값을 더하면 됨
-------r2--------
result = model.rsquared 해도되고 # 10회 3-2-2
summary() 로도 나옴! 값은 똑같음! (사진의 3번 참고)
model = sm.OLS(y, X_const).fit()
result = model.rsquared
summary = model.summary()
print(round(result, 3))
print(summary)
4. 임계값, 민감도 + 상관분석
------임계값 및 민감도----
임계값 나오면 np.where 바로 생각하기
np.where(조건, 참일때, 거짓일때)
예시
y_pred = model.predict(x_train)
y_pred2 = np.where(y_pred > 0.5, 1, 0) # 예측값이 0.5보다 높으면 1로, 아니면 0으로
from sklearn.metrics import recall_score
score = recall_score(y_train, y_pred2) # 민감도
print(score)
- 혼동행렬없이 바로 metrics에서 메서드 들고오기
<from sklearn.metrics import recall_score, accuracy_score ... 가능함
# 실제값 = y_train, 예측값 = y_pred
recall_score(실제값, 예측값) # 민감도
recall_score(실제값, 예측값) # 특이도
accuracy_score(실제값, 예측값, pos_label=0) # 정확도
precision_score(실제값, 예측값) # 정밀도
confusion_matrix(y_true, 예측값) # 혼동행렬
root_mean_squared_error(실제값, 예측값) # RMSE
f1_score(실제값, 예측값) # f1 score
# 평가지표사용방법 잊어버렸을 때 시험장 꿀팁!!
from sklearn.metrics import get_scorer_names # 평가지표 사용방법확인 # 대신 이름을 알아야함
print(get_scorer_names()) -> 내가 써야하는 평가지표 찾기 -> help(f1_score)
------ 상관분석 --------
상관분석이다?
df.corr(예측값) 바로 이거 생각하기
model = sm.OLS(y, X_const).fit()
# 학습데이터 예측값 확인
pred = model.predict(X_const)
# 학습데이터의 실제값과 예측값의 피어슨 상관계수 확인 #9회 3-1-2 / # 11회 3-1-2
pred.corr(y) # 피어슨 상관계수
pred.corr(y, method = 'spearman') # 스피어만 상관계수
---------------
chi2_contingency() – 범주형 변수의 독립성 검정 (교차표 기반)
두 범주형 변수 간에 통계적으로 연관이 있는지를 검정
from scipy.stats import chi2_contingency
# 예: 교차표 (관찰도수)
table = [[30, 10], [20, 40]]
chi2, p, dof, expected = chi2_contingency(table)
from scipy.stats import chisquare
# 관찰값과 기대값
obs = [30, 50, 20]
exp = [33.3, 33.3, 33.3] # 예: 균등 분포
chi2, p = chisquare(f_obs=obs, f_exp=exp)
-------실제 기출문제 ------
# 11회 3유형
# 오즈비, 예측, 민감도 /// 일표본 ttest, 상관분석, 회귀계수
# 다음은 보건소,검진 대상자의 당뇨병 유무를 분석하기 위한 데이터셋이다.
# diabetes(당뇨여부)에 대해 로지스틱 회귀분석을 진행하고자 한다.
# 각 소문항에 대해 답을 구하시오
# (단, diabetes 1= 당뇨, 0= 정상임을 나타낸다)
# 당뇨병 유무(diabetes)를 종속변수로 하고, 나머지를 독립변수로
# 하는 로지스틱 회귀모형을 만들고 아래 문제에 대해 답하시오.
# (단, 모든 답은 반올림하여 소수점 둘째자리까지 구하시오)
# 1-1) age 변수의 오즈비를 구하시오
# 1-2) age=50, bmi=28, blood_sugar=120일 때 당뇨병 유무 확률을 구하시오
# 1-3) 임계값이 0.5일 때 민감도를 구하시오.
import pandas as pd
import numpy as np
X = df.drop(["diabetes"], axis = 1)
y = df["diabetes"]
import statsmodels.api as sm
X_const = sm.add_constant(X)
model = sm.Logit(y, X_const).fit()
# print(model.summary())
# 1-1 age 변수의 오즈비를 구하시오
odds = np.exp(model.params["age"])
# 1-2
new_data = [1, 50, 28, 120]
pred = model.predict(new_data)
print(pred)
# 1-3 임계값이 0.5일 때 민감도를 구하시오.
y_pred = model.predict(X_const)
y_pred
y_pred = np.where(y_pred > 0.5, 1,0)
from sklearn.metrics import recall_score
score = recall_score(y, y_pred)
print(score)
# 3유형 2번문제
# 다음은 웹페이지 지표와 홍보비용에 대한 데이터셋이다.
# 아래 소문항에 대해 답하시오.
# (단, 모든 답은 반올림하여 소수점 둘째자리까지 구하시오)
# 2-1) 홍보비용(ad_cost)의 평균이 115,000원이라고 할 수 있는지
# 일표본 t-test 를 진행하여 p-value 값을 구하시오.
# 2-2) 변수들간의 상관분석을 진행하고 가장 큰 상관계수를 구하시오.
# 2-3) ad_cost를 종속변수로 하는 다중회귀모형에서 통계적으로 유의미한 회귀계수의 값을 구하시오.
############# 실기환경 복사 영역 #############
import pandas as pd
import numpy as np
from scipy import stats
import statsmodels.formula.api as smf
np.random.seed(42)
n = 100
visit = np.random.randint (10, 100, n)
duration = np.random.uniform (5, 30, n)
noise = np.random.normal (0, 55000, n)
ad_cost = 2000 + (2075.945 * visit) + (50 * duration) + noise
df = pd. DataFrame({
'visit': visit,
'duration': duration,
'ad_cost': ad_cost
})
############### 실기환경 복사 영역 ############
df.head()
# 1. 일표본 ttest
statistic, pvalue = stats.ttest_1samp(df['ad_cost'],
popmean =115000,
alternative = 'two-sided') # 같은지 다른지 확인하라했으니 양측
# print(round(statistic, 2), round(pvalue, 2))
# 2. 상관분석
result = df.corr()
result
# 3. ad_cost를 종속변수로 하는 다중회귀모형에서
# 통계적으로 유의미한 회귀계수의 값을 구하시오.
# 독립변수와 종속변수 지정
X = df.drop (['ad_cost'], axis=1)
y = df['ad_cost']
# 모델링
import statsmodels.api as sm
X_const = sm.add_constant(X_const)
# 주의: 상수항 추가해줘야 함
model = sm.OLS(y, X_const).fit()
# 주의할 것 : y, x 순으로 입력해야 함
summary = model.summary()
coef = model.params[model.pvalues[model.pvalues < 0.05].index]
print(coef)
print(round(model.params['visit'],2))
10회
# 1 로지스틱 회귀 pvalue, 2오즈비, 3예측 문제 / 회귀계수, r2 , 예측
# 로지스틱 회귀모델을 적용 후 p-value가 0.05보다 작은 변수의 회귀 계수를 구하시오
# 단 절편항(상수항은 제외한다.
# 반올림하여 소수 셋째 자리까지 작성
# attrition : 이직여부 (0= 잔류, 1=이직) 종속변수
# age (나이)
# income
# overtime : 초과근무여부
import pandas as pd
# X,y 분리
y = df['attrition']
X = df.drop(['attrition'], axis = 1)
# 상수항
import statsmodels.api as sm
X_const = sm.add_constant(X)
# 로지스틱회귀
model = sm.Logit(y, X_const).fit(disp=0)
# pvalue
model.summary()
pvalue1 = model.pvalues.drop('const') # 상수항 제거
name = model.pvalues[model.pvalues < 0.05].index # name 인덱스
# 회귀계수
coef1 = model.params['income']
print(round(coef1 ,3))
#3-1-2 나이가 1증가할때 이직할 오즈비를 구하라 (반올림하여 소수3자리
model = sm.Logit(y, X_const).fit()
coef1 = model.params['age']
result = np.exp(coef1)
print(round(result,3))
# 3-1-3 # 새로운 직원 age=40, income=4500, overtime=1 에 대하여,
# 모델을 이용하여 이직 확률을 예측하시오 (반올림하여 소수 3자리까지)
# new_data = pd.DataFrame([[1, 40, 4500, 1]], columns=X_const.columns) 이게정석이긴함
new_data = pd.DataFrame([[1, 40, 4500, 1]])
result=model.predict(new_data)
print(round(result, 3))
# 10회 3-2-1
# 모든 독립변수를 포함한 회귀모형을 적합하시오. 이때 절편을 제외한 회귀계수의 합을 구하시오. (반올림하여 소수 셋째 자리까지 작성)
# heattng_load : 난방 부하 (종속변수)
import pandas as pd
df=pd.read_csv('data/bigdata_1032.csv')
# X, y 분리
y = df['heating_load']
X = df.drop(['heating_load'], axis=1)
# 상수항 추가
import statsmodels.api as sm
X_const = sm.add_constant(X)
model = sm.OLS(y, X_const).fit()
model.summary()
result = 0.0304 +0.2483+0.2217-0.2469
print(round(result,4))
# 10회 3-2-2
#유의한 변수(유의수준 0.05 이하)만을 사용하여 다중회귀분석을 다시 수행하고, R (결정제수) 을 구하시오.
# (반올림하여 소수 셋째 자리까지 작성)
X_new = X[model.params[model.pvalues < 0.05].index.drop('const')] # X[] 감싸야 이름만 가져오는게 아닌 리스트로 가져옴 []
X_new_const = sm.add_constant(X_new)
x_model = sm.OLS(y, X_new_const).fit()
r2_score = x_model.rsquared
result = round(r2_score, 3)
print(result)
# 10회 3-2-3 모형을 이용하여 WaLL=20, roof=150, glazing=20, height=5 일 때, heating_load를 예측하시오
new_data = [[1, 150, 20, 5]] # wall 빼고 값넣기
result= x_model.predict(new_data)
print(round(result[0], 3))
9회
# 1 설명변수(pvalue), 상관계수, RMSE / 2 로지 p value, 오즈비, 예측
# 문제1)
# 한 제조업체에서는 직원들의 생산성을 향상시키기 위해, 주요 생산성 요인을 분석하고자 하였다.
# 이를 위해 총 200명의 직원 데이터를 수집하였으며, 각 직원의 근속 기간, 개인 특성 및 속성과 함께
# 생산성 점수를 기록하였다.
# <data description>
# - id : 데이터의 고유 식별자
# - tenure : 근속 기간
# - f2 ~ f5 : 직원의 개인 특성을 나타내는 변수
# - design : 생산성 점수 (연속형, 예측 대상)
# <데이터 분리조건 >
# - 학습용 데이터 : id가 1 이상 140 이하인 경우
# - 평가용(테스트) 데이터 : id가 141 이상 200 이하인 경우
# =============================================================================
# 1-1) 모든 설명변수(tenure, f2 ~ f5)를 활용하여 design을 예측하는 다중 회귀 분석을 수행하시오.
# 이때 유의하지 않은 설명변수 개수를 구하시오. (패널티는 포함하지 않으며, 모델의 절편항은 포함)
# =============================================================================
# X, y 분리
y = df1['design']
X = df1.drop(['design', 'id'], axis = 1)
# 상수항 추가
import statsmodels.api as sm
X_const = sm.add_constant(X)
# 회귀모형 적합
model = sm.OLS(y, X_const).fit()
# 유의확률 확인 / 유의하지 않은 설명변수 확인
pvalue1 = model.pvalues.drop('const')
result = (pvalue1 >= 0.05).sum()
# 정답 제출
print(result)
# =============================================================================
# 1-2) 훈련 데이터(학습용 데이터)의 예측값과 실제값의 피어슨 상관계수를 구하시오.
# 반올림하여 소수점 넷째자리까지 표현
# =============================================================================
# 훈련/테스트 데이터 분리
train = df1[df1['id'] <= 140]
test = df1[df1['id'] > 140]
# X, y 분리
y = train['design']
X = train.drop(['design', 'id'], axis = 1)
# 상수항 추가
X_const = sm.add_constant(X)
# 회귀모형 적합
model = sm.OLS(y, X_const).fit()
# 학습데이터 예측값 확인
pred = model.predict(X_const)
# 학습데이터의 실제값과 예측값의 피어슨 상관계수 확인
pred.corr(y) # 피어슨 상관계수
pred.corr(y, method = 'spearman') # 스피어만 상관계수
# 정답 제출
result = round(pred.corr(y),4)
print(result)
# =============================================================================
# 1-3) 적합한 모델을 활용하여 테스트 데이터에서의 RMSE를 구하시오.
# 반올림하여 소수점 넷째자리까지 표현
# =============================================================================
# 테스트 데이터 X, y 분리
y = test['design']
X = test.drop(['design', 'id'], axis=1)
# 테스트 데이터 상수항 추가
X_const = sm.add_constant(X)
# 기존 모델사용 -> 예측값 확인
pred = model.predict(X_const)
# RMSE
from sklearn.metrics import root_mean_squared_error
rmse = root_mean_squared_error(y, pred)
# 정답 제출
result = round(rmse, 4)
print(result)
# =============================================================================
# 9회 문제2)
# 통신 회사는 고객 이탈을 줄이기 위해 주요 요인을 분석하고자 하였다. 이를 위해 500명의 고객 데이터를 수집하였다.
# 고객의 서비스 이용 내역과 개인 정보를 기반으로 다음 분석을 수행하시오.
#
# <data description >
# - col1 : 고객의 첫번째 특성
# - col2 : 고객의 두번째 특성
# - Phone_Service : 폰 서비스 가입 여부
# - Tech_Insurance : 기술 보험 가입 여부
# - churn : 이탈 여부(1:이탈, 0:유지)
# =============================================================================
# 2-1) 고객 이탈을 예측하는 로지스틱회귀를 시행한 후 col1 컬럼의 p-value를 구하시오.
# 반올림하여 소수점 넷째자리까지 표현
# =============================================================================
# X, y 분리
X = df1.drop(columns = 'churn')
y = df1['churn']
# 상수항 추가
import statsmodels.api as sm
X_const = sm.add_constant(X)
# 로지스틱 회귀 모형 적합
model = sm.Logit(y, X_const).fit(disp=0)
# pvalue 확인
result = model.pvalues['col1']
# 정답 제출
print(round(result,4))
# =============================================================================
# 2-2) 폰 서비스를 받지 않은 고객 대비 받은 고객의 이탈 확률 오즈비를 구하시오.
# 반올림하여 소수점 셋째자리까지 표현
# =============================================================================
# Phone_Service의 회귀 계수
coef1 = model.params['Phone_Service']
# 오즈비 확인
import numpy as np
result = round(np.exp(coef1), 3)
# 정답 제출
print(result)
# =============================================================================
# 2-3) 이탈할 확률이 0.3 이상인 고객 수를 구하시오.
# =============================================================================
# 이탈 확률
proba = model.predict(X_const)
# 이탈 확률이 0.3 이상인 고객 수
result = (proba >= 0.3).sum()
# 정답 제출
print(result)
8회
# 1 로지스틱 회귀 pvalue, 로지스틱 회귀, 오즈비 2- 설명변수, R 결정계수, 예측
# =============================================================================
# 1-1) 주어진 데이터에서 로지스틱 회귀 분석을 수행하고,
# 유의확률(p-value)이 0.05 이상인 유의하지 않은 독립변수의 개수를 구하시오.
# (종속변수: Churn, 독립변수: Churn을 제외한 모든 변수)
# =============================================================================
# X, y 분리
y = df1['Churn']
X = df1.drop(columns = 'Churn')
# 로지스틱 회귀 수행
import statsmodels.api as sm
X_const = sm.add_constant(X) # 상수항 추가
model = sm.Logit(y, X_const).fit(disp=0)
# pvalue 결과 확인
pvalue1 = model.pvalues.drop('const')
# 0.05 이상인 유의하지 않은 독립변수의 개수
result = (pvalue1 >= 0.05).sum()
# 정답 제출
print(result)
# =============================================================================
# 1-2) 1-1에서 구한 결과를 바탕으로, 유의확률이 0.05 미만인 유의한 변수들만 사용하여
# 로지스틱 회귀 분석을 다시 수행하시오. 이때 유의한 회귀 계수(상수항 포함)의 합계를 구하되,
# 결과는 반올림하여 소수점 셋째 자리까지 구하시오.
# =============================================================================
# 유의한 변수 확인(상수항 포함)
name1 = model.pvalues[model.pvalues < 0.05].index
# 유의한 변수만 모델링
X_const2 = X_const[name1]
model2 = sm.Logit(y, X_const2).fit(disp=0)
# 유의한 회귀계수 확인
model2.params[model2.pvalues < 0.05]
# 유의한 회귀계수의 합계
result = round(model2.params[model2.pvalues < 0.05].sum(),3)
# 정답 제출
print(result)
# =============================================================================
# 1-3) 1-2에서 생성한 회귀식에서 DataUsage 변수가 5만큼 증가할 때의 오즈비(odds ratio)를 구하시오.
# (소수점 셋째 자리까지 반올림하여 제시할 것)
# =============================================================================
# DataUsage 회귀계수 확인
coef1 = model2.params['DataUsage']
# 5만큼 증가할 때 오즈비
import numpy as np
result = round(np.exp(coef1 * 5), 3)
# 정답 제출
print(result)
# =============================================================================
# 문제2) 주어진 데이터를 이용하여 종속변수 PIQ와 독립변수 Brain, Height, Weight 간의 다중선형회귀분석을 수행하시오.
# =============================================================================
import pandas as pd
df1 = pd.read_csv('ex_8_3_2.csv')
# =============================================================================
# 2-1) 가장 유의미한 변수(유의확률이 가장 낮은 변수)의 회귀계수 값을 소수점 셋째 자리까지 반올림하여 구하시오.
# =============================================================================
# X, y 분리
y = df1['PIQ']
X = df1.drop(columns = 'PIQ')
# 상수항 추가
import statsmodels.api as sm
X_const = sm.add_constant(X)
# 회귀분석 학습
model = sm.OLS(y, X_const).fit()
# 유의확률이 가장 낮은 변수 이름 확인
vname = model.pvalues.idxmin()
# 해당 변수의 회귀계수 확인
result = round(model.params[vname], 3)
# 정답 제출
print(result)
# =============================================================================
# 2-2) 위에서 생성한 회귀 모델의 결정계수(R²)를 소수점 둘째 자리까지 반올림하여 구하시오.
# =============================================================================
dir(model)
result = round(model.rsquared, 2)
# 정답 제출
print(result)
# =============================================================================
# 2-3) 다음과 같은 독립변수 값이 주어졌을 때 PIQ를 예측하시오.
# (Brain = 90, Height = 70, Weight = 150)
# 예측값은 반올림하여 정수로 출력하시오.
# =============================================================================
# 데이터 생성
new_data = pd.DataFrame({'const' : [1], 'Brain' : [90], 'Height' : [70], 'Weight' : [150]})
new_data= [1, 90, 70, 150] # 와 같음
# 예측값 확인
result = round(model.predict(new_data).iloc[0])
# 결과 제출
print(result)
7회
1 오즈비, 잔차 이탈도, 오분류표 2- 상관계수, r2, pvalue
# =============================================================================
# 작업형 3유형
# =============================================================================
# 문제1)
# 어느 회사의 고객 데이터를 바탕으로 제품 구매 여부를 예측하고자 한다.
# 해당 데이터는 총 100개의 샘플로 구성되어 있으며, 각 샘플에는 다음과 같은 정보가 포함되어 있다:
# - age (나이)
# - income (소득)
# - family_size (가족 수)
# - buy (제품 구매 여부: 0 또는 1)
# 학습용 데이터를 이용하여 로지스틱 회귀 모델을 구축하고, 아래 질문에 답하시오.
# (모형 예측의 임계값은 0.5로 간주한다.)
import pandas as pd
train = pd.read_csv('ex_7_3_1_train.csv')
test = pd.read_csv('ex_7_3_1_test.csv')
# =============================================================================
# 1-1)
# 로지스틱 회귀 모델에서 소득(income) 변수의 오즈비(odds ratio)를 구하시오.
# 반올림하여 소수점 첫째자리까지 표현
# =============================================================================
# 회귀계수 -> exp 함수값 리턴
# X, y 분리
train_x = train.drop('buy', axis=1)
train_y = train['buy']
test_x = test.drop('buy', axis=1)
test_y = test['buy']
# 방법1) sklearn 모델 적용
from sklearn.linear_model import LogisticRegression
model = LogisticRegression() # 기본적으로 l2 규제를 사용하므로 statsmodels 함수들과 결과가 달라짐
model = LogisticRegression(penalty=None) # penalty를 사용하지 않으면 statsmodels 함수들과 결과가 같아짐
model.fit(train_x, train_y)
coef1 = model.coef_[0,1] # income 변수의 회귀 계수 확인
model.intercept_ # 절편
import numpy as np
result = np.exp(coef1)
print(round(result, 1))
# 방법2) statsmodels 라이브러리의 Logit 함수 적용
import statsmodels.api as sm
train_x_const = sm.add_constant(train_x) # 상수항 추가
model = sm.Logit(train_y, train_x_const).fit() # disp=0 옵션 사용 시 모델 학습 결과가 출력되지 X
coef1 = model.params['income']
import numpy as np
result = np.exp(coef1)
print(round(result, 1))
# 방법3) statsmodels 라이브러리의 GLM 함수 적용
import statsmodels.api as sm
# train_x_const = sm.add_constant(train_x) # 상수항 추가
model = sm.GLM(train_y, train_x_const, family=sm.families.Binomial()).fit()
coef1 = model.params['income']
import numpy as np
result = np.exp(coef1)
print(round(result, 1))
# =============================================================================
# 1-2)
# 학습 데이터(train)를 기준으로 잔차 이탈도(Residual Deviance)를 반올림하여 소수점 넷째 자리까지 구하시오.
# =============================================================================
# 잔차제곱합 : 모델이 얼마나 데이터를 잘 설명했는지를 측정(작을수록 잘 설명했다고 볼 수 있음)
# 잔차 이탈도 : 주로 로지스틱 회귀, 포아송 회귀 처럼 비선형 회귀에서 잔차제곱합을 대신하여 모형을 평가하는 척도
import statsmodels.api as sm
# train_x_const = sm.add_constant(train_x) # 상수항 추가
model = sm.GLM(train_y, train_x_const, family=sm.families.Binomial()).fit()
print(model.summary())
result = model.deviance
print(round(result, 4))
# =============================================================================
# 1-3)
# 테스트 데이터(test)를 이용하여 오분류율(misclassification rate)을 구하시오.
# =============================================================================
statsmodels Logit
import statsmodels.api as sm
# train_x_const = sm.add_constant(train_x) # train data 상수항 추가
test_x_const = sm.add_constant(test_x) # test data 상수항 추가
model = sm.Logit(train_y, train_x_const).fit()
proba = model.predict(test_x_const) # P(Y=1)
pred = np.where(proba >= 0.5,1,0)
(pred != test_y).mean()
# =============================================================================
# 문제2)
# 다음은 한 기업의 시스템 성능 데이터이다. 아래 지시에 따라 데이터를 분석하고 결과를 도출하시오.
# =============================================================================
# =============================================================================
# 2-1)
# 변수 ERP와 가장 높은 상관관계를 가지는 변수를 찾고, 해당 상관계수 값을 소수점
# 셋째 자리까지 반올림하여 구하시오.
# =============================================================================
# 상관계수 확인
df_corr = df.corr() # numeric_only = True 옵션을 사용하면 문자컬럼을 제외하고 숫자컬럼들에 대해서만 상관계수 구함
# ERP와의 상관계수 확인
corr_erp = df_corr['ERP'].drop('ERP')
# 최대 상관계수 확인
result = corr_erp.abs().max()
# 최종 출력
print(round(result, 3))
# =============================================================================
# 2-2)
# 변수 CPU의 값이 100 미만인 데이터만 필터링한 후, ERP를 종속변수로, 나머지 수치형 변수들을
# 독립변수로 하여 선형 회귀 모델을 적합하고, 그 회귀모형의 결정계수(R²) 값을 소수점 셋째
# 자리까지 반올림하여 구하시오.
# =============================================================================
# 조건에 맞는 데이터 선택
df2 = df.loc[df['CPU'] < 100]
# X,y 분리
y = df2['ERP']
X = df2.drop(['ERP'], axis=1)
# 방법1) sklearn
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X,y)
result = model.score(X,y)
print(round(result, 3))
# 방법2) statsmodels
import statsmodels.api as sm
X_const = sm.add_constant(X) # 상수항 추가
model = sm.OLS(y, X_const).fit() # 모델 적합
model.summary()
print(dir(model)) # 모델에 대한 정보 확인할 수 있는 메서드 목록
result = model.rsquared # 결정계수
model.rsquared_adj # 수정결정계수
print(round(result, 3))
# =============================================================================
# 2-3)
# 2-2에서 학습한 회귀모형의 독립변수 중 p-value가 가장 큰 값을 소수점 셋째 자리까지 반올림하여 구하시오.
# =============================================================================
import statsmodels.api as sm
# X_const = sm.add_constant(X) # 상수항 추가
# model = sm.OLS(y, X_const).fit() # 모델 적합
# pvalue 확인
pvalue1 = model.pvalues
# 독립변수 중(const제외) pvalue 최대값 확인
result = pvalue1.drop('const').max()
# 결과 제출
print(round(result, 3))
# 11회 1번문제
# 다음은 연도별(2001~2021) 온실가스 배출 데이터이다.
# 연도별 배출량 1위를 가장 많이 한 국가의 1위 횟수를 구하시오.
count = df.loc[:,'2001':'2021'].idxmax() # 2001, 2021 문자열로 판단
result = count.value_counts().sort_values(ascending=False)
a = result.iloc[0]
print(a)
# 11회 3번문제
3-1번
# 다음은 고객별 거래코드 및 매출액 데이터이다.
# 거래코드가 C로 시작하면 주문취소 코드라고 할 때
# 주문취소 금액(매출액)이 가장 큰 고객의 고객코드를 구하시오.
df["매출액"] = df["Quantity"] * df["Unit_price"]
df2 = df[df["transaction_code"].str.astype(str).str.startswith("C")]
df3 = df2.groupby('customer_id')['매출액'].sum().sort_values(ascending=False)
a= df3.index[0]
3-2번
# 주문취소 금액은 음수로 처리하고, 매출액이 가장 큰 고객의 매출액을 구하시오.
df["매출보정"] = np.where(df['transaction_code'].astype(str).str.startswith('C'), -df["매출액"] , df["매출액"])
result = df.groupby("customer_id")["매출보정"].sum().sort_values(ascending=False)
result.index[0]
# 글자인덱싱 문제
# 10회 문제 3¶
# 제공된 데이터(hamspam.csv)는 문자 메시지 내용과 스팸 여부를 담고 있다.
아래 수행 순서에 따라 데이터를 처리한 뒤, 구한 값을 [제출 형식]에 맞춰 답안 페이지에 입력하시오.
# 제공 데이터
# label : 메시지 구분 (spam: 스팸, ham: 정상)
# text : 메시지
# 각 메시지의 단어 개수를 띄어쓰기(공백) 기준으로 계산하시오.
# 스팸 메시지의 평균 단어 개수와 정상 메시지의 평균 단어 개수를 각각 구하시오.
# 두 평균의 차이의 절댓값을 구하여 입력하시오.
df["단어"] = df["text"].str.split()
df["단어수"] = df["단어"].str.len()
df.head()
# 2. 스팸과 정상 메시지의 평균 단어 수 구하기
m = df.groupby("label")["단어수"].mean()
# 3. 두 평균 차이의 절댓값 구하기
diff = abs(m["spam"] - m["ham"])
print(m.["spam"], m.["ham"])
# Goupby + unstack 관련 문제
# 문제1)
# 1) 총대출액은 신용대출과 담보대출의 합으로 정의한다.
# 2) 각 지역코드 내에서 성별별(1과 2)로 총대출액의 합계를 계산하시오.
# 3) 이후, 성별 간 총대출액의 차이가 가장 큰 지역코드를 구하시오. (단, 차이는 절대값 기준)
# =============================================================================
df1['총대출액'] = df1['신용대출'] + df1['담보대출']
df_mean = df1.groupby(["지역코드", "성별"])["총대출액"].sum()
df2 = df_mean.unstack()
diff = (df2[1] - df2[2]).abs().sort_values(ascending=False)
result = diff.index[0] # diff.idxmax() 랑 같음
# print(result)
초기 > 그룹바이 > 언스택 순서
# 시간관련 문제
# 10회 문제2¶
# 제공된 데이터(cafe_sales.csv)는 2024년 4월부터 2025년 12월까지의 카페 메뉴 판매 이력이다. 소문항을 각각 구한 다음 [제출 형식]에 맞춰 답안 페이지에 입력하시오.
# 제공 데이터
# order_date : 주문 날짜 (예 2024.05.24 13:22)
# category : 음료/디저트 종류 (예 coffee, tea …)
# item : 메뉴명
# price : 판매 금액
# 소문항
# 2-1. 연-월별 총 매출액을 계산하여 큰 순서대로 정렬했을 때, 2번째로 큰 매출액을 입력하시오.
# 2-2. 연-월별 총 매출액이 4번째로 큰 연-월을 찾으시오. 해당 연-월의 데이터에서 카테고리별 매출 합계를 계산하고, 그중 최댓값을 입력하시오.
df['order_date']=pd.to_datetime(df['order_date']) # object 타입이라 datetime 으로 변경
df["year_month"] = df["order_date"].dt.to_period("M") # 2024-10 형태의 년-월 형태로 변경
month_sales = df.groupby("year_month")["price"].sum().sort_values(ascending=False) # 기간별 매출합계
target_month = month_sales.index[3] # 기간별 매출합계가 4번째인 년-월
# # 2. 4번째로 큰 연-월에 해당하는 데이터만 추출
cond = df["year_month"] == target_month
df = df[cond] # 해당 년-월 자료만 표시
cate_sales = df.groupby("category")["price"].sum().sort_values(ascending=False) # 카테고리별 매출로 표시
result = cate_sales.iloc[0]
print(result)
# 통계량 관련문제
# =============================================================================
# 8회 3번 문제
# CO(GT)와 NMHC(GT) 두 컬럼에 대해 Min-Max 스케일링을 수행한 후,
# 스케일링된 CO(GT)의 표준편차를 a (소수점 셋째 자리에서 반올림),
# 스케일링된 NMHC(GT)의 표준편차를 b (소수점 셋째 자리에서 반올림)라 할 때,
# a + b 값을 구하시오.
# =============================================================================
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
# 1. 스케일러 소환
scaler = MinMaxScaler()
# 2. 두 컬럼을 한 번에 스케일링해서 덮어씌우기 (반드시 괄호 두 개 [[ ]] 사용!)
cols = ['CO(GT)', 'NMHC(GT)']
df[cols] = scaler.fit_transform(df[cols])
# 3. 표준편차 구하고 반올림하기 (소수점 셋째 자리에서 반올림 = 둘째 자리까지 남김)
a = round(df['CO(GT)'].std(), 2)
b = round(df['NMHC(GT)'].std(), 2)
# 4. 정답 출력
print(a + b)
# 데이터 확인
print(train.head(3))
print(train.isnull().sum())
# 결측치가 있는경우!!! 결측치 처리방법
# 2. 데이터 전처리 - train, test 둘 다 처리! (→ But, 보통 결측치 없는 데이터로 출제됨)
train['A'] = train['A'].fillna(train['A'].mean()) # 평균 대체
test['A'] = test['A'].fillna(test['A'].mean())
train['A'] = train['A'].fillna(train['A'].mode()[0]) # 최빈값 대체
train['A'] = train['A'].fillna(0) # 0으로 대체
train['A'] = train['A'].fillna(method='bfill') # 뒤 값으로 대체
train = train.dropna() # 전체 결측치 데이터 삭제
train = train.dropna(subset=['A', 'B']) # 특정컬럼의 결측치 데이터 삭제
train = train.dropna(axis=1) # 결측치 있는 컬럼 삭제
print(train["종속변수"].value_counts()) # 불균형데이터인지 확인
# X, y 분리
X = train.drop(["변수"], axis=1)
y = train["변수"]
# 원핫인코딩
X_full = pd.concat([X, test], axis=0)
X_full = pd.get_dummies(X_full)
X_train= X_full[:train.shape[0]]
X_test=X_full[train.shape[0]:]
# 학습용, 검증 데이터 분리
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val = train_test_split(X_train, y, random_state=42)
# 모델 학습
from sklearn.ensemble import RandomForestClassifier # 회귀라면 RandomForestRegressor 로 변경
model = RandomForestClassifier(n_estimators=42, random_state=42)
model.fit(X_tr, y_tr)
model.score(X_val, y_val)
# 전체 학습
model.fit(X_train, y)
pred = model.predict(X_test)
# 결과저장
result = pd.DataFrame({"pred": pred})
result.to_csv("result.csv", index=False)
# 생성확인
result_check = pd.read_csv("result.csv")
print(result_check)
# 1. 데이터 형태 확인방법들 -> 이 단계에서 회귀문제인지 분류 문제인지 판단
print(train.shape)
print(train.head(5))
print(train.describe(include="all"))
print(train.info()) # 범주형 변수 확인
print(test.info())
print(train.isnull().sum()) # 결측치 확인
print(test.isnull().sum())
print(train["종속변수"].value_counts()) # 불균형인지 확인
# 2. 결측치 처리방법
------ 결측치 전처리는 train, test 둘 다 처리 해야함!!
train['A'] = train['A'].fillna(train['A'].mean()) # 평균 대체
test['A'] = test['A'].fillna(test['A'].mean()) 이런식으로!! 밑에는 test는 생략함
train['A'] = train['A'].fillna(train['A'].mode()[0]) # 최빈값 대체
train['A'] = train['A'].fillna(0) # 0으로 대체
train['A'] = train['A'].fillna(method='bfill') # 뒤 값으로 대체
train = train.dropna() # 전체 결측치 데이터 삭제
train = train.dropna(subset=['A', 'B']) # 특정컬럼의 결측치 데이터 삭제
train = train.dropna(axis=1) # 결측치 있는 컬럼 삭제
train.set_index('id')
test.set_index('id') # train 했으면 test도 반드시 해야함
-----시간관련 데이터가 있는경우---- # 8회 2유형
for df in [train, test]:
df["date_time"] = pd.to_datetime(df["date_time"])
#df["hour"] = df["date_time"].dt.hour # 시간 (0~23)
#df["day"] = df["date_time"].dt.dayofweek # 요일 (0~6)
#df["month"] = df["date_time"].dt.month # 월 (1~12)
#df["is_holiday"] = df["date_time"].dt.dayofweek >= 5 # 주말 여부
df.set_index('date_time', inplace=True) # !!!필수!!!
# 3.X,y 세팅
X = train.drop(['최종확인값'], axis=1)
y = train['최종확인값'] # 예측 대상
# 4. 원핫 인코딩 준비작업
# train + test 합치기
X_full = pd.concat([X, test])
X_full = pd.get_dummies(X_full)
X_train = X_full[:train.shape[0]]
X_test = X_full[train.shape[0]:]
# 5. 학습용, 검증 데이터 분리 및 그리드서치 준비
from sklearn.model_selection import train_test_split, GridSearchCV
X_tr, X_val, y_tr, y_val =
train_test_split(X_train, y, random_state=42) # 분류일때 stratify = y 넣기! (비율에 맞춰 자르기)
#회귀
# 1. 튜닝의 뼈대가 될 기본 모델 생성
# 주의: 회귀 모델은 연속된 숫자를 맞추는 것이라 class_weight="balanced" 옵션이 없습니다!
from sklearn.ensemble import RandomForestRegressor # Classifier가 아닌 Regressor!
base_model = RandomForestRegressor(random_state=42)
# from lightgbm import LGBMRegressor
# base_model = LGBMRegressor(random_state=42, verbose=-1) # verbose =-1 로그숨김
# from xgboost import XGBRegressor
# base_model = XGBRegressor(random_state=42)
param_grid = {
'n_estimators': [50, 100, 150], # 나무의 개수
'max_depth': [5, 10, 15] # 나무의 깊이
# 'learning_rate': [0.01, 0.05, 0.1] # 부스팅모델은 추가가능
}
# 3. GridSearchCV 객체 생성
# cv=3 : 3등분하여 교차 검증 (시간 절약을 위해 3 추천)
grid_search = GridSearchCV(
estimator=base_model,
param_grid=param_grid,
scoring='neg_root_mean_squared_error', # RMSE로 평가
# neg_mean_absolute_error, neg_mean_squared_error, r2 등인데 neg 넣는거 잊지말자!
)
print("하이퍼파라미터 탐색")
# 4. 탐색 시작 (쪼개둔 훈련용 데이터 X_tr, y_tr 사용)
grid_search.fit(X_tr, y_tr)
# 5. 튜닝 결과 확인
print("가장 좋은 파라미터:", grid_search.best_params_)
# grid_search.best_score_ # 점수보기
# 가장 똑똑하게 튜닝된 최종 모델을 변수에 담아줍니다.
#best_model = grid_search.best_estimator_
# 파라미터 찾았으면 위에 전부 주석처리하고 찾은 파라미터값 넣기
best_model = RandomForestRegressor(max_depth=10, n_estimators=50, random_state=42)
best_model.fit(X_tr, y_tr)
# =============================================================================
# 검증 (튜닝된 최고 모델 사용)
# =============================================================================
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np
# 그냥 model이 아니라 best_model이 문제를 풀게 합니다.
y_pred = best_model.predict(X_val)
print("검증 데이터 평가 결과")
# 회귀는 정확도가 아니라 '오차(Error)'와 '설명력(R2)'을 봅니다.
mse = mean_squared_error(y_val, y_pred)
rmse = np.sqrt(mse) # = mse ** 0.5 도 가능
r2 = r2_score(y_val, y_pred) # 1에 가까울수록 모델이 예측을 잘한다는 뜻입니다.
print("RMSE (평균 제곱근 오차):", rmse)
print("R2 Score (결정계수):", r2)
# =============================================================================
# 전체 train으로 다시 학습 및 최종 예측
# =============================================================================
# 성능을 영혼까지 끌어모으기 위해, 쪼개기 전의 전체 데이터(X_train, y)로 최종 학습
best_model.fit(X_train, y)
# 진짜 시험지(test) 데이터 예측 (회귀이므로 예측 결과가 연속된 숫자들로 나옵니다)
pred = best_model.predict(X_test)
# 결과 저장
result = pd.DataFrame({
"pred": pred
})
result.to_csv("result.csv", index=False)
# 생성 결과 확인
result_check = pd.read_csv("result.csv")
print(result_check.head())
#분류
# 1. 튜닝의 뼈대가 될 기본 모델 생성
from sklearn.ensemble import RandomForestClassifier
base_model = RandomForestClassifier(random_state=42, class_weight="balanced")
# from lightgbm import LGBMClassifier
# base_model = LGBMClassifier(random_state=42, verbose=-1) # verbose=-1: 로그숨김
# from xgboost import XGBClassifier
# base_model = XGBClassifier(random_state=42)
# 2. 탐색할 파라미터 후보군 설정
# (시험 환경의 1분 시간 초과 방지를 위해 후보를 너무 많이 넣지 않는 것이 좋습니다!)
param_grid = {
'n_estimators': [50, 100, 150], # 나무의 개수
'max_depth': [5, 10, None] # 나무의 깊이 (None은 끝까지 자란다는 뜻)
# 'learning_rate': [0.01, 0.05, 0.1] # 부스팅 모델은 추가가능
}
grid_search = GridSearchCV(
estimator=base_model,
param_grid=param_grid,
scoring='f1_macro', # 평가지표로 매크로 f1
# accuracy, f1 # 문제에 맞게 넣어주기
)
print("하이퍼파라미터 탐색")
# 4. 탐색 시작 (우리가 쪼개둔 훈련용 데이터 X_tr, y_tr 사용)
grid_search.fit(X_tr, y_tr)
# 5. 튜닝 결과 확인
print("가장 좋은 파라미터:", grid_search.best_params_)
# grid_search.best_score_ # 점수보기
# 가장 똑똑하게 튜닝된 최종 모델을 변수에 담아줍니다.
# best_model = grid_search.best_estimator_
# 파라미터 찾았으면 위에 전부 주석처리하고 찾은 파라미터값 넣기
best_model = RandomForestClassifier(max_depth=10, n_estimators=50, random_state=42)
best_model.fit(X_tr, y_tr)
# =============================================================================
# 검증 (튜닝된 최고 모델 사용)
# =============================================================================
from sklearn.metrics import accuracy_score, f1_score, classification_report
# 그냥 model이 아니라 best_model이 문제를 풀게 합니다.
y_pred = best_model.predict(X_val)
print("검증 데이터 평가 결과")
print("accuracy:", accuracy_score(y_val, y_pred))
print("macro f1:", f1_score(y_val, y_pred, average="macro"))
print(classification_report(y_val, y_pred))
# =============================================================================
# 전체 train으로 다시 학습 및 최종 예측
# =============================================================================
# 성능을 영혼까지 끌어모으기 위해, 쪼개기 전의 전체 데이터(X_train, y)로 최종 학습
best_model.fit(X_train, y)
# 진짜 시험지(test) 데이터 예측
pred = best_model.predict(X_test)
# 결과 저장
result = pd.DataFrame({
"pred": pred
})
result.to_csv("result.csv", index=False)
# 생성 결과 확인
result_check = pd.read_csv("result.csv")
print(result_check.head())
# 파라미터 기억안날때
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
help(model)
from sklearn.model_selection import GridSearchCV
help(GridSearchCV)
# 1. 데이터 형태 확인방법들 -> 이 단계에서 회귀문제인지 분류 문제인지 판단
print(train.shape)
print(train.head(5))
print(train.describe(include="all"))
print(train.info()) # 범주형 변수 확인
print(test.info())
print(train.isnull().sum()) # 결측치 확인
print(test.isnull().sum())
print(train["종속변수"].value_counts()) # 불균형인지 확인
# 2. 결측치 처리방법
------ 결측치 전처리는 train, test 둘 다 처리 해야함!!
train['A'] = train['A'].fillna(train['A'].mean()) # 평균 대체
test['A'] = test['A'].fillna(test['A'].mean()) 이런식으로!! 밑에는 test는 생략함
train['A'] = train['A'].fillna(train['A'].mode()[0]) # 최빈값 대체
train['A'] = train['A'].fillna(0) # 0으로 대체
train['A'] = train['A'].fillna(method='bfill') # 뒤 값으로 대체
train = train.dropna() # 전체 결측치 데이터 삭제
train = train.dropna(subset=['A', 'B']) # 특정컬럼의 결측치 데이터 삭제
train = train.dropna(axis=1) # 결측치 있는 컬럼 삭제
-----시간관련 데이터가 있는경우----
for df in [train, test]:
df["date_time"] = pd.to_datetime(df["date_time"])
#df["hour"] = df["date_time"].dt.hour # 시간 (0~23)
#df["day"] = df["date_time"].dt.dayofweek # 요일 (0~6)
#df["month"] = df["date_time"].dt.month # 월 (1~12)
#df["is_holiday"] = df["date_time"].dt.dayofweek >= 5 # 주말 여부
df.set_index('date_time', inplace=True) # !!!필수!!!
# 3.X,y 세팅
X = train.drop(['최종확인값'], axis=1)
y = train['최종확인값'] # 예측 대상
# 4. 원핫 인코딩 준비작업
# train + test 합치기
X_full = pd.concat([X, test])
X_full = pd.get_dummies(X_full)
X_train = X_full[:train.shape[0]]
X_test = X_full[train.shape[0]:]
# ---라벨인코딩의 경우---
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
for col in train.columns :
if train[col].dtype == 'object' :
le.fit(pd.concat([train[col], test[col]]))
train[col] = le.transform(train[col])
test[col] = le.transform(test[col])
# 회귀
# 분류(Classifier)가 아닌 회귀(Regressor) 모델을 사용합니다.
# (데이터 불러오기 및 결측치/원핫인코딩 처리 등 전처리가 끝난 상태라고 가정합니다.)
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val = train_test_split(X_train, y, random_state=42)
# =============================================================================
# 1. 3가지 회귀 모델 성능 비교 (RMSE 기준, 낮을수록 좋음)
# =============================================================================
from sklearn.ensemble import RandomForestRegressor
from xgboost import XGBRegressor
from lightgbm import LGBMRegressor
from sklearn.metrics import mean_squared_error
import numpy as np
models = {
"RandomForest": RandomForestRegressor(random_state=42),
"LightGBM": LGBMRegressor(random_state=42),
"XGBoost": XGBRegressor(random_state=42)
}
best_model_name = ""
# 오차(Error)는 낮을수록 좋으므로, 초기값을 무한대(inf)로 설정합니다.
best_score = float('inf')
print("기본 모델 성능 비교 (RMSE 오차 점수)")
for name, model in models.items():
model.fit(X_tr, y_tr)
pred_val = model.predict(X_val)
# RMSE(Root Mean Squared Error) 계산: mse에 루트(np.sqrt)를 씌움
mse = mean_squared_error(y_val, pred_val)
rmse = np.sqrt(mse)
print(f"{name} 모델 RMSE: {rmse:.4f}")
# 오차가 이전 최저 오차보다 '작다면(낮다면)' 최고 모델 갱신
if rmse < best_score:
best_score = rmse
best_model_name = name
print(f"가장 좋은모델: {best_model_name} (최저 오차: {best_score:.4f})\n")
# =============================================================================
# 2. 선정된 최고 모델에 대해 GridSearchCV (하이퍼파라미터 튜닝)
# =============================================================================
from sklearn.model_selection import GridSearchCV
# 승리한 모델에 맞춰 파라미터 세팅
if best_model_name == "RandomForest":
base_model = RandomForestRegressor(random_state=42)
param_grid = {
'n_estimators': [50, 100, 150],
'max_depth': [6, 8, 10]
}
elif best_model_name == "XGBoost":
base_model = XGBRegressor(random_state=42)
param_grid = {
'n_estimators': [50, 100, 150],
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.1]
}
elif best_model_name == "LightGBM":
base_model = LGBMRegressor(random_state=42)
param_grid = {
'n_estimators': [50, 100, 150],
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.1]
}
grid_search = GridSearchCV(
estimator=base_model,
param_grid=param_grid,
)
print("하이퍼파라미터 탐색 시작")
grid_search.fit(X_tr, y_tr)
print("가장 좋은 파라미터 조합:", grid_search.best_params_)
# 출력할 때 다시 마이너스를 떼고 원래의 양수 오차 값으로 보여줍니다.
print("그때의 최저 오차(RMSE):", -grid_search.best_score_)
# 가장 똘똘한 최종 모델 저장
final_best_model = grid_search.best_estimator_
# =============================================================================
# 3. 전체 훈련 데이터로 최종 학습 및 결과 제출
# =============================================================================
print("전체 데이터 최종 학습 및 예측 ---")
# 쪼개기 전의 전체 훈련 데이터(X_train, y)로 최종 학습
final_best_model.fit(X_train, y)
# 평가용(Test) 데이터 예측 (연속된 숫자가 예측됨)
pred = final_best_model.predict(X_test)
# 제출 형식에 맞게 데이터프레임 만들기 (문제에서 요구하는 컬럼명 확인 필수!)
result = pd.DataFrame({"pred": pred})
# csv 파일 저장 (index=False 잊지 마세요!)
result.to_csv("result.csv", index=False)
print(pd.read_csv("result.csv").head())
# 분류
# 전처리 진행한 상황이라는 전제
# 검증 데이터 분리
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val = train_test_split(
X_train, # 레이블한거
y,
random_state=42,
stratify=y # 분류일때만
)
# =============================================================================
# 1. 3가지 모델 성능 비교 및 최우수 모델 선정
# =============================================================================
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier
from sklearn.metrics import f1_score
# 사용할 3가지 모델을 딕셔너리 형태로 준비합니다.
# - RandomForest와 LightGBM은 class_weight="balanced" 로 데이터 불균형을 잡아줍니다.
# - XGBoost는 다중 분류(0, 1, 2)를 자동으로 인식하며, eval_metric 경고를 없애기 위해 옵션을 추가합니다.
# - LightGBM은 불필요한 출력 메시지를 숨기기 위해 verbose=-1 을 설정합니다.
models = {
"RandomForest": RandomForestClassifier(random_state=42, class_weight="balanced"),
"LightGBM": LGBMClassifier(random_state=42, class_weight="balanced"),
"XGBoost": XGBClassifier(random_state=42)
}
best_model_name = ""
best_score = 0
print("--- [1단계] 기본 모델 성능 비교 (Macro F1 Score) ---")
# 준비한 3가지 모델을 하나씩 꺼내서 학습시키고 점수를 확인합니다.
for name, model in models.items():
# 학습 데이터로 모델 학습
model.fit(X_tr, y_tr)
# 검증 데이터로 예측 수행
pred_val = model.predict(X_val)
# 평가지표인 Macro F1 점수 계산
score = f1_score(y_val, pred_val, average="macro")
print(f"{name} 모델 Macro F1 점수: {score:.4f}")
# 이전 모델보다 점수가 높다면, 최고 점수와 최고 모델 이름을 갱신(업데이트)합니다.
if score > best_score:
best_score = score
best_model_name = name
print(f" 가장좋은모델 모델: {best_model_name} (최고 점수: {best_score:.4f})\n")
# =============================================================================
# 2. 선정된 최고 모델에 대해 GridSearchCV (하이퍼파라미터 튜닝) 수행
# =============================================================================
from sklearn.model_selection import GridSearchCV
# 앞서 1차전에서 승리한 모델이 무엇인지에 따라 탐색할 파라미터(옵션)를 다르게 설정합니다.
if best_model_name == "RandomForest":
base_model = RandomForestClassifier(random_state=42)
param_grid = {
'n_estimators': [50, 100, 150], # 만들 나무의 개수
'max_depth': [6, 8, 10] # 나무의 최대 깊이 (과적합 방지)
}
elif best_model_name == "XGBoost":
base_model = XGBClassifier(random_state=42)
param_grid = {
'n_estimators': [50, 100, 150], # 학습 반복 횟수
'max_depth': [3, 5, 7], # 나무의 깊이 (부스팅 모델은 보통 얕게 설정합니다)
'learning_rate': [0.01, 0.1] # 학습률 (업데이트 속도)
}
elif best_model_name == "LightGBM":
base_model = LGBMClassifier(random_state=42")
param_grid = {
'n_estimators': [50, 100, 150],
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.1]
}
grid_search = GridSearchCV(
estimator=base_model,
param_grid=param_grid,
cv=5,
scoring='f1_macro',
)
print("--- [2단계] 하이퍼파라미터 탐색 시작 ---")
# 쪼개두었던 훈련용 데이터(X_tr, y_tr)를 넣고 모든 조합을 테스트합니다.
grid_search.fit(X_tr, y_tr)
# 탐색 결과 출력
print("\n가장 좋은 파라미터 조합:", grid_search.best_params_)
print("그때의 최고 점수(교차검증 평균 F1 Macro):", grid_search.best_score_)
# 튜닝이 완료된 가장 똑똑한 최종 모델을 변수에 저장합니다.
final_best_model = grid_search.best_estimator_
# 우리가 빼두었던 검증 데이터(X_val)로 최종 모의고사를 봅니다.
final_val_pred = final_best_model.predict(X_val)
print("튜닝 후 검증 데이터(X_val) 최종 Macro F1 점수:", f1_score(y_val, final_val_pred, average="macro"))
# =============================================================================
# 3. 전체 훈련 데이터로 최종 학습 및 결과 제출 (시험 제출용)
# =============================================================================
print("전체 데이터 최종 학습 및 예측")
# 모델이 더 많은 데이터를 보고 배울 수 있도록,
# 쪼개기 전의 전체 훈련 데이터(X_train, y)를 다시 집어넣고 최종 학습시킵니다.
final_best_model.fit(X_train, y)
# 진짜 시험지(test) 데이터의 정답을 예측합니다.
pred = final_best_model.predict(X_test)
# 제출 형식에 맞게 데이터프레임으로 묶어줍니다. (컬럼명 'pred' 확인!)
result = pd.DataFrame({"pred": pred})
# csv 파일로 저장합니다. (index=False는 필수입니다!)
result.to_csv("result.csv", index=False)
# 제대로 만들어졌는지 마지막으로 확인합니다.
print(pd.read_csv("result.csv").head())
파라미터 기억안나면 이렇게 항목들 확인가능
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
help(model)
from sklearn.model_selection import GridSearchCV
help(GridSearchCV)
2026-05-05PRD 2차 + MVP 1차관리사무소 요구사항 추가 정리. 신청 폼·결재 흐름·관리자 페이지 기본 동작.
2026-05-06PRD 3차 + MVP 2차관리실 요구사항 정리. 부서 2뎁스 트리·관리자 마스터 PIN·시리즈 신청·고정 행사·인쇄 진행 트래킹.
2026-05-07시놀로지 NAS 사양 확인 → 프린트 자동화 가능 판정사무실 NAS = Synology DS420+. 도커 컨테이너 가능 → 프린트 큐 에이전트 구동 가능. 사무실 프린터: Sindoh d450.
2026-05-09MVP 3차 — 프린트 자동화신청서 작성 → 사무실 NAS 도커 → Sindoh d450 자동 출력 → 프린트 상태 콜백. 이 단계가 끝나면 의도한 플로우가 온전히 진행됨.
5 핵심 사용자 흐름
5-1. 신청 → 자동 인쇄 → 결재 (목표 플로우)
[신청자] /apply 진입 → 부서·호실·일시·목적 입력
↓ 충돌 검사 (실시간) — 기존 예약 + 고정 행사 + 빈 시간 추천
↓
신청서 1장 발급 (ref_no = "26-0042" + QR 토큰 1개)
├─→ 사무실 NAS 도커 → Sindoh d450 자동 출력 ← MVP3
└─→ 신청자 화면: 출력 진행 모니터링 (출력중 → 완료 / 오류)
↓
[결재자] 종이 양식의 QR 스캔 → /sign/[token]
├─ PIN 4자리 (휴대폰 뒷자리) → 본인 단계 자동 승인
├─ 5분 안에 다른 신청서도 PIN 없이 결재
└─ admin role PIN 또는 0000 → 어떤 단계든 강제 승인
↓
모든 단계 승인 → status='approved' 확정
└─→ 신청자에게 결과 알림 (카카오 알림톡 + SMS, 예정)
5-2. 정기(시리즈) 신청
매주 같은 요일·시간대 반복 (예: 매주 일요일 14:00~16:00 1청년회 모임)
시작일·종료일 + 요일 + 시간 블록 입력 → 회차 자동 생성
결재 1회로 시리즈 전체 확정
5-3. 신청 수정/취소 (신청자)
1단계 결재 시작 전까지만 본인 수정·삭제 가능
본인 인증: 신청 시 입력한 휴대폰 번호 매칭
5-4. 결재 취소 (당회장 권한)
모든 단계 끝난 신청서를 다시 검토하고 싶을 때
당회장 PIN으로 취소 → 모든 approval 초기화 + reservation status='pending'
이런 경우 실행중인 Containers > Files로 접근하여서 home > node > .openclaw > openclaw:json 을 우측 클릭하여 edit file
쭉내리면 gateway 설정이있다
{
"gateway": {
"bind": "0.0.0.0", // <--- 여기가 루프백으로 되어 있다면 무조건 0.0.0.0으로 수정! 또는 "lan" 으로 수정
"port": 18789,
"controlUi": {
"allowInsecureAuth": true // <--- 이 설정이 있어야 브라우저 접속을 허용됨
}
}
}
8 Pairing
마지막으로 openclaw dashboard 입력하거나 설치가 다 끝나면 링크+토큰 번호를 주는데 해당 링크를 누르면 이렇게 뜸
docker exec -it {컨테이너이름} dist/index.js devices list
# Particle CLI
bash <( curl -sL https://particle.io/install-cli )
# 업데이트 진행
particle update-cli
# 버전확인
particle --version
2. 장비 프로그램 모드 전환
# 전원버튼 3초이상 꾹 누르면 노란색으로 LED 바뀜
# usb 확인
particle usb configure
# Tachyon 설치
particle tachyon setup
# 단계 쭈욱 이어가면됨!
# 설치가 다되면 이렇게 뜸
All done! Your Tachyon device is ready to boot to the desktop and will automatically connect to Wi-Fi.
To continue:
- Disconnect the USB-C cable
- Connect a USB-C Hub with an HDMI monitor, keyboard, and mouse.
- Power off the device by holding the power button for 3 seconds and releasing.
- Power on the device by pressing the power button.
When the device boots it will:
- Activate the built-in 5G modem.
- Connect to the Particle Cloud.
- Run all system services, including the desktop if an HDMI monitor is connected.
Learn more about Tachyon at our developer site: https://developer.particle.io/tachyon
View your device on the Particle Console at: https://console.particle.io/tachyon-번호/devices/장비번호
# 다시 부팅하면
전원 led가 보라색으로 뜰거임
2022년에 작성된 글인데 3년동안 똑같이 장사를 하고 있다는건? 도대체 해당기관은 뭐하고 있음?
그래 일단 저 블로그 작성자의 말 또한 온전히 믿을 수 없다. 내가 상품을 받아본 것이 아니기 때문에, 우선 정말 가품을 판매하는지부터, 그리고 왜 저 사이트가 3년 동안 무사히 운영될 수 있었는지 파헤치려고 한다. 분명 나처럼 시도한 사람들의 후기를 보고 싶었는데 딱히 없어서 내가 시도해봄.
우선 상품을 구매하기 전에 가품을 받으면 어떻게 되냐고 물어보았다. 애네들 구조를 보아하니 “나 오픈마켓이라 판매자들이 판매하는 거고 나는 중간에서 중개만 했을 뿐이야!” 라는 식으로 꼬리 자르기를 하려는 구조인 듯함.
이때부터 느낌이 쎄함을 느낌 ㅋㅋㅋ
판매사이트에 정품만 파냐고 문의한 내용의 답변
그래서 직접 판매하는 판매처의 연락처를 알아내서 그 쪽으로 문의를 진행하였더니 더 가관이였다.
"이전에 정품 하나는 비정상적으로 나왔습니다" 그럼 그게 정품이 아닌거잖아? 왜 정품이라는 표현을 쓰는거지?
그래서 상품페이지에 100% 정품이라는 말을 쓰지말랬더니 참고하겠다고 한다 (안바꾸겠다는 소리임)
12/15일 사건담당자는 가품소견서가 없으면 진행할 수 없다고 함. 나는 가품소견서를 받고싶은데 대부분 고가의 상품만 가품확인을 해주어서 업체를 찾지못했다고 말하자, 그냥 취하하라고 한다. 이해는 된다... 형사 입장에서는 얼마나 많은 더 우선순위인 일들이 있을까? 결국 왜 한국에 사기꾼들이 판을 치고 돌아다니는지 시장경제와 공무원들의 업무 이해관계를 보아 바로 이해할 수 있었다.
근로자 수가 10명 미만인 사업에 고용된 근로자 중 월평균보수가 270만원 미만인신규가입 근로자와 그 사업주
2021년부터는 신규가입자에 대해서만 지원
2. 지원수준 및 지원기간
(지원수준) 신규가입 근로자 및 사업주가 부담하는 고용보험과 국민연금 보험료의 80%
* 고용보험의 경우 근로자는 월 최대 16,560원, 그 사업주는 월 최대 21,160원까지 지원하며, 국민연금의 경우 근로자와 그 사업주는 각각 월 최대 82,800원까지 지원
(지원기간) 2018년 1월 1일부터 신규가입자 및 기가입자 지원을 합산하여 36개월까지만 지원
3. 지원 제외대상
지원 대상에 해당하는 근로자가 아래의 어느 하나라도 해당되는 경우에는 지원 제외됩니다.
지원신청일이 속한 보험연도의 전년도 재산의 과세표준액 합계가6억원 이상인 자
지원신청일이 속한 보험연도의 전년도(소득자료 입수 시기에 따라 보험연도의 전년도 또는 전전년도) 종합소득이4,300만원 이상인 자
4. 보험료 지원방법
두루누리 사회보험료 지원을 신청하면 사업주가 월별보험료를 법정기한 내에 납부하였는지를 확인하여 완납한 경우 그 다음 달 보험료에서 해당 월의 보험료 지원금을 뺀 나머지 금액을 고지하는 방법으로 지원하고 있습니다. (다만, 그 다음 달에 부과될 보험료가 없는 경우에는 해당 월의 지원금은 지원하지 않음)
두루누리 사회보험료의 경우 지원신청일이 속한 달의 고용보험료부터 해당 보험연도 말까지 지원하되, 보험연도 말 현재 고용보험료 지원을 받고 있고 그 보험연도 중 보험료 지원기간의 월평균 근로자인 피보험자 수가 10명 미만인 경우에는 다음 보험연도에 별도로 신청하지 않더라도 계속 지원을 받으실 수 있습니다. 다만, 고용보험료의 경우 사업주가 보수총액신고 또는 피보험자격 취득신고를 법정기한 내에 하지 않은 경우에는 그 신고를 이행한 날이 속한 달의 고용보험료부터 지원하고, 지원대상이 되는 근로자인 피보험자가 일용근로자인 경우에는 사업주가 법정기한 내에 제출한 달의 '근로내용 확인신고서'에 기재된 사람에 대한 월별보험료만을 지원합니다.
5. 지원금액 산정 예시
사업주지원금(신규가입자의 경우)
근로자 수 10명 미만인 사업에 고용된 근로자의 월평균보수가 230만원이라면 매월 103,960원을 지원 받을 수 있습니다.(80% 지원)
근로자지원금(신규가입자의 경우)
근로자 수 10명 미만인 사업에 고용된 근로자의 월평균보수가 230만원이라면 매월 99,360원을 지원 받을 수 있습니다.(80% 지원)
참고사항
근로자 수가 ‘10명 미만인 사업’이란?
지원신청일이 속한 보험연도의 전년도에 근로자인 피보험자 수가 월평균 10명 미만이고, 지원신청일이 속한 달의 말일을 기준으로 10명 미만인 사업
지원신청일이 속한 보험연도의 전년도 근로자인 피보험자 수가 월평균 10명 이상이나 지원 신청일이 속한 달의 직전 3개월 동안 (지원신청일이 속한 연도로 한정함) 근로자인 피보험자 수가 연속하여 10명 미만인 사업
지원신청일이 속한 보험연도 중에 보험관계가 성립된 사업으로 지원신청일이 속한 달의 직전 3개월 동안(지원신청일이 속한 연도로 한정하며, 보험관계성립일 이후 3개월이 지나지 아니한 경우에는 그 기간 동안) 근로자인 피보험자 수가 연속하여 10명 미만인 사업
* 근로자 수 산정 시 출산전후휴가, 유산ㆍ사산 휴가, 육아휴직 또는 육아기 근로시간 단축에 해당하는 근로자는 제외하고 산정함
* 법인은 법인등록번호, 개인은 사업자등록번호 단위로 사업 규모를 판단함
* 「부패방지 및 국민권익위원회의 설치와 운영에 관한 법률」 제2조 제1호에 따른 공공기관은 10명 미만인 사업에 해당하여도 지원대상에서 제외함