hossam 0.4.3__tar.gz → 0.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hossam-0.4.3/hossam.egg-info → hossam-0.4.4}/PKG-INFO +1 -1
- {hossam-0.4.3 → hossam-0.4.4}/hossam/hs_plot.py +16 -13
- {hossam-0.4.3 → hossam-0.4.4}/hossam/hs_prep.py +37 -5
- {hossam-0.4.3 → hossam-0.4.4}/hossam/hs_stats.py +149 -16
- {hossam-0.4.3 → hossam-0.4.4/hossam.egg-info}/PKG-INFO +1 -1
- {hossam-0.4.3 → hossam-0.4.4}/pyproject.toml +1 -1
- {hossam-0.4.3 → hossam-0.4.4}/LICENSE +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/MANIFEST.in +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/README.md +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam/NotoSansKR-Regular.ttf +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam/__init__.py +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam/data_loader.py +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam/hs_classroom.py +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam/hs_gis.py +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam/hs_timeserise.py +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam/hs_util.py +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam/leekh.png +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam.egg-info/SOURCES.txt +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam.egg-info/dependency_links.txt +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam.egg-info/requires.txt +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/hossam.egg-info/top_level.txt +0 -0
- {hossam-0.4.3 → hossam-0.4.4}/setup.cfg +0 -0
|
@@ -35,12 +35,12 @@ if pd.__version__ > "2.0.0":
|
|
|
35
35
|
|
|
36
36
|
config = SimpleNamespace(
|
|
37
37
|
dpi=200,
|
|
38
|
-
width=
|
|
39
|
-
height=
|
|
40
|
-
font_size=
|
|
38
|
+
width=600,
|
|
39
|
+
height=350,
|
|
40
|
+
font_size=7,
|
|
41
41
|
font_weight="normal",
|
|
42
|
-
frame_width=0.
|
|
43
|
-
line_width=1
|
|
42
|
+
frame_width=0.5,
|
|
43
|
+
line_width=1,
|
|
44
44
|
grid_alpha=0.3,
|
|
45
45
|
grid_width=0.5,
|
|
46
46
|
fill_alpha=0.3
|
|
@@ -69,10 +69,13 @@ def get_default_ax(width: int = config.width, height: int = config.height, rows:
|
|
|
69
69
|
figsize = (width * cols / 100, height * rows / 100)
|
|
70
70
|
fig, ax = plt.subplots(rows, cols, figsize=figsize, dpi=dpi)
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
# ax가 배열 (subplots)인지 단일 Axes인지 확인
|
|
73
|
+
is_array = isinstance(ax, (np.ndarray, list))
|
|
74
|
+
|
|
75
|
+
if is_array and (ws != None and hs != None):
|
|
73
76
|
fig.subplots_adjust(wspace=ws, hspace=hs)
|
|
74
77
|
|
|
75
|
-
if title:
|
|
78
|
+
if title and not is_array:
|
|
76
79
|
fig.suptitle(title, fontsize=config.font_size * 1.5, fontweight='bold')
|
|
77
80
|
|
|
78
81
|
if flatten == True:
|
|
@@ -125,11 +128,11 @@ def create_figure(width: int = config.width, height: int = config.height, rows:
|
|
|
125
128
|
# ===================================================================
|
|
126
129
|
# 그래프의 그리드, 레이아웃을 정리하고 필요 시 저장 또는 표시한다
|
|
127
130
|
# ===================================================================
|
|
128
|
-
def finalize_plot(ax: Axes, callback: any = None, outparams: bool = False, save_path: str = None, grid: bool = True, title: str = None) -> None:
|
|
131
|
+
def finalize_plot(ax: Axes | np.ndarray, callback: any = None, outparams: bool = False, save_path: str = None, grid: bool = True, title: str = None) -> None:
|
|
129
132
|
"""공통 후처리를 수행한다: 콜백 실행, 레이아웃 정리, 필요 시 표시/종료.
|
|
130
133
|
|
|
131
134
|
Args:
|
|
132
|
-
ax (Axes|ndarray
|
|
135
|
+
ax (Axes|np.ndarray): 대상 Axes (단일 Axes 또는 subplots 배열).
|
|
133
136
|
callback (Callable|None): 추가 설정을 위한 사용자 콜백.
|
|
134
137
|
outparams (bool): 내부에서 생성한 Figure인 경우 True.
|
|
135
138
|
save_path (str|None): 이미지 저장 경로. None이 아니면 해당 경로로 저장.
|
|
@@ -159,7 +162,7 @@ def finalize_plot(ax: Axes, callback: any = None, outparams: bool = False, save_
|
|
|
159
162
|
|
|
160
163
|
plt.tight_layout()
|
|
161
164
|
|
|
162
|
-
if title:
|
|
165
|
+
if title and not is_array:
|
|
163
166
|
ax.set_title(title, fontsize=config.font_size * 1.3, pad=7, fontweight='bold')
|
|
164
167
|
|
|
165
168
|
if save_path is not None:
|
|
@@ -173,12 +176,12 @@ def finalize_plot(ax: Axes, callback: any = None, outparams: bool = False, save_
|
|
|
173
176
|
# ===================================================================
|
|
174
177
|
# 그래프의 그리드, 레이아웃을 정리하고 필요 시 저장 또는 표시한다
|
|
175
178
|
# ===================================================================
|
|
176
|
-
def show_figure(ax: Axes, callback: any = None, outparams: bool = False, save_path: str = None, grid: bool = True, title: str = None) -> None:
|
|
179
|
+
def show_figure(ax: Axes | np.ndarray, callback: any = None, outparams: bool = False, save_path: str = None, grid: bool = True, title: str = None) -> None:
|
|
177
180
|
"""공통 후처리를 수행한다: 콜백 실행, 레이아웃 정리, 필요 시 표시/종료.
|
|
178
181
|
finalize_plot의 래퍼 함수.
|
|
179
182
|
|
|
180
183
|
Args:
|
|
181
|
-
ax (Axes|ndarray
|
|
184
|
+
ax (Axes|np.ndarray): 대상 Axes (단일 Axes 또는 subplots 배열).
|
|
182
185
|
callback (Callable|None): 추가 설정을 위한 사용자 콜백.
|
|
183
186
|
outparams (bool): 내부에서 생성한 Figure인 경우 True.
|
|
184
187
|
save_path (str|None): 이미지 저장 경로. None이 아니면 해당 경로로 저장.
|
|
@@ -1736,7 +1739,7 @@ def ols_residplot(
|
|
|
1736
1739
|
y = y_pred + resid # 실제값 = 적합값 + 잔차
|
|
1737
1740
|
|
|
1738
1741
|
if ax is None:
|
|
1739
|
-
fig, ax = get_default_ax(width, height, 1, 1, dpi)
|
|
1742
|
+
fig, ax = get_default_ax(width + 150 if mse else width, height, 1, 1, dpi)
|
|
1740
1743
|
outparams = True
|
|
1741
1744
|
|
|
1742
1745
|
# 산점도 직접 그리기 (seaborn.residplot보다 훨씬 빠름)
|
|
@@ -158,16 +158,23 @@ def minmax_scaler(
|
|
|
158
158
|
# ===================================================================
|
|
159
159
|
# 지정된 컬럼들을 범주형 데이터로 설정한다
|
|
160
160
|
# ===================================================================
|
|
161
|
-
def set_category(data: DataFrame, *args: str) -> DataFrame:
|
|
161
|
+
def set_category(data: DataFrame, *args: str, columns: list = None) -> DataFrame:
|
|
162
162
|
"""카테고리 데이터를 설정한다.
|
|
163
163
|
|
|
164
164
|
Args:
|
|
165
165
|
data (DataFrame): 데이터프레임 객체
|
|
166
166
|
*args (str): 컬럼명 목록
|
|
167
|
+
columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
|
|
167
168
|
|
|
168
169
|
Returns:
|
|
169
170
|
DataFrame: 카테고리 설정된 데이터프레임
|
|
170
171
|
"""
|
|
172
|
+
# columns 인자가 있으면 args보다 우선한다.
|
|
173
|
+
if columns is not None:
|
|
174
|
+
if args:
|
|
175
|
+
raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
|
|
176
|
+
args = columns
|
|
177
|
+
|
|
171
178
|
df = data.copy()
|
|
172
179
|
|
|
173
180
|
for k in args:
|
|
@@ -219,7 +226,7 @@ def unmelt(
|
|
|
219
226
|
# ===================================================================
|
|
220
227
|
# 지정된 변수의 이상치 테이블로 반환한다
|
|
221
228
|
# ===================================================================
|
|
222
|
-
def outlier_table(data: DataFrame, *fields: str) -> DataFrame:
|
|
229
|
+
def outlier_table(data: DataFrame, *fields: str, columns: list = None) -> DataFrame:
|
|
223
230
|
"""수치형 컬럼에 대한 사분위수 및 IQR 기반 이상치 경계를 계산한다.
|
|
224
231
|
|
|
225
232
|
전달된 `fields`가 없으면 데이터프레임의 모든 수치형 컬럼을 대상으로 한다.
|
|
@@ -228,6 +235,7 @@ def outlier_table(data: DataFrame, *fields: str) -> DataFrame:
|
|
|
228
235
|
Args:
|
|
229
236
|
data (DataFrame): 분석할 데이터프레임.
|
|
230
237
|
*fields (str): 대상 컬럼명(들). 생략 시 모든 수치형 컬럼 대상.
|
|
238
|
+
columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
|
|
231
239
|
|
|
232
240
|
Returns:
|
|
233
241
|
DataFrame: Q1, Q2(중앙값), Q3, IQR, 하한, 상한을 포함한 통계표.
|
|
@@ -236,6 +244,11 @@ def outlier_table(data: DataFrame, *fields: str) -> DataFrame:
|
|
|
236
244
|
from hossam import *
|
|
237
245
|
hs_prep.outlier_table(df, "value")
|
|
238
246
|
"""
|
|
247
|
+
# columns 인자가 있으면 args보다 우선한다.
|
|
248
|
+
if columns is not None:
|
|
249
|
+
if args:
|
|
250
|
+
raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
|
|
251
|
+
args = columns
|
|
239
252
|
|
|
240
253
|
target_fields = list(fields) if fields else list(data.select_dtypes(include=[np.number]).columns)
|
|
241
254
|
result = []
|
|
@@ -273,7 +286,7 @@ def outlier_table(data: DataFrame, *fields: str) -> DataFrame:
|
|
|
273
286
|
# ===================================================================
|
|
274
287
|
# 이상치를 대체값(NaN, 0) 또는 중앙값으로 교체한다
|
|
275
288
|
# ===================================================================
|
|
276
|
-
def replace_outliner(data: DataFrame, method: str = "nan", *fields: str) -> DataFrame:
|
|
289
|
+
def replace_outliner(data: DataFrame, method: str = "nan", *fields: str, columns: list = None) -> DataFrame:
|
|
277
290
|
"""이상치 경계값을 넘어가는 데이터를 경계값으로 대체한다.
|
|
278
291
|
|
|
279
292
|
Args:
|
|
@@ -285,10 +298,16 @@ def replace_outliner(data: DataFrame, method: str = "nan", *fields: str) -> Data
|
|
|
285
298
|
- most: 최빈값 대체
|
|
286
299
|
- median: 중앙값 대체
|
|
287
300
|
*fields (str): 컬럼명 목록
|
|
301
|
+
columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
|
|
288
302
|
|
|
289
303
|
Returns:
|
|
290
304
|
DataFrame: 이상치가 경계값으로 대체된 데이터 프레임
|
|
291
305
|
"""
|
|
306
|
+
# columns 인자가 있으면 args보다 우선한다.
|
|
307
|
+
if columns is not None:
|
|
308
|
+
if args:
|
|
309
|
+
raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
|
|
310
|
+
args = columns
|
|
292
311
|
|
|
293
312
|
# 원본 데이터 프레임 복사
|
|
294
313
|
df = data.copy()
|
|
@@ -335,16 +354,22 @@ def replace_outliner(data: DataFrame, method: str = "nan", *fields: str) -> Data
|
|
|
335
354
|
# ===================================================================
|
|
336
355
|
# 중빈 이상치를 제거한 연처리된 데이터프레임을 반환한다
|
|
337
356
|
# ===================================================================
|
|
338
|
-
def drop_outliner(data: DataFrame, *fields: str) -> DataFrame:
|
|
357
|
+
def drop_outliner(data: DataFrame, *fields: str, columns: list = None) -> DataFrame:
|
|
339
358
|
"""이상치를 결측치로 변환한 후 모두 삭제한다.
|
|
340
359
|
|
|
341
360
|
Args:
|
|
342
361
|
data (DataFrame): 데이터프레임
|
|
343
362
|
*fields (str): 컬럼명 목록
|
|
363
|
+
columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
|
|
344
364
|
|
|
345
365
|
Returns:
|
|
346
366
|
DataFrame: 이상치가 삭제된 데이터프레임
|
|
347
367
|
"""
|
|
368
|
+
# columns 인자가 있으면 args보다 우선한다.
|
|
369
|
+
if columns is not None:
|
|
370
|
+
if args:
|
|
371
|
+
raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
|
|
372
|
+
args = columns
|
|
348
373
|
|
|
349
374
|
df = replace_outliner(data, "nan", *fields)
|
|
350
375
|
return df.dropna()
|
|
@@ -353,7 +378,7 @@ def drop_outliner(data: DataFrame, *fields: str) -> DataFrame:
|
|
|
353
378
|
# ===================================================================
|
|
354
379
|
# 범주 변수를 더미 변수(One-Hot 인코딩)로 변환한다
|
|
355
380
|
# ===================================================================
|
|
356
|
-
def get_dummies(data: DataFrame, *args: str, drop_first=True, dtype="int") -> DataFrame:
|
|
381
|
+
def get_dummies(data: DataFrame, *args: str, columns: list = None, drop_first: bool = True, dtype: str = "int") -> DataFrame:
|
|
357
382
|
"""명목형 변수를 더미 변수로 변환한다.
|
|
358
383
|
|
|
359
384
|
컬럼명을 지정하면 그 컬럼들만 더미 변수로 변환하고,
|
|
@@ -362,6 +387,7 @@ def get_dummies(data: DataFrame, *args: str, drop_first=True, dtype="int") -> Da
|
|
|
362
387
|
Args:
|
|
363
388
|
data (DataFrame): 데이터프레임
|
|
364
389
|
*args (str): 변환할 컬럼명 목록. 지정하지 않으면 숫자형이 아닌 모든 컬럼 자동 선택.
|
|
390
|
+
columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
|
|
365
391
|
drop_first (bool, optional): 첫 번째 더미 변수 제거 여부. 기본값 True.
|
|
366
392
|
dtype (str, optional): 더미 변수 데이터 타입. 기본값 "int".
|
|
367
393
|
|
|
@@ -379,6 +405,12 @@ def get_dummies(data: DataFrame, *args: str, drop_first=True, dtype="int") -> Da
|
|
|
379
405
|
result = hs_prep.get_dummies(df, 'col1', drop_first=False, dtype='bool')
|
|
380
406
|
```
|
|
381
407
|
"""
|
|
408
|
+
# columns 인자가 있으면 args보다 우선한다.
|
|
409
|
+
if columns is not None:
|
|
410
|
+
if args:
|
|
411
|
+
raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
|
|
412
|
+
args = columns
|
|
413
|
+
|
|
382
414
|
if not args:
|
|
383
415
|
# args가 없으면 숫자 타입이 아닌 모든 컬럼 자동 선택
|
|
384
416
|
cols_to_convert = []
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
4
|
+
from typing import overload, Tuple, Literal, Union
|
|
3
5
|
|
|
4
6
|
# -------------------------------------------------------------
|
|
5
7
|
import numpy as np
|
|
@@ -28,6 +30,7 @@ from scipy.stats import (
|
|
|
28
30
|
wilcoxon,
|
|
29
31
|
pearsonr,
|
|
30
32
|
spearmanr,
|
|
33
|
+
chi2
|
|
31
34
|
)
|
|
32
35
|
|
|
33
36
|
import statsmodels.api as sm
|
|
@@ -36,10 +39,71 @@ from statsmodels.stats.outliers_influence import variance_inflation_factor
|
|
|
36
39
|
from statsmodels.stats.multitest import multipletests
|
|
37
40
|
from statsmodels.stats.stattools import durbin_watson
|
|
38
41
|
from statsmodels.regression.linear_model import RegressionResultsWrapper
|
|
42
|
+
from statsmodels.discrete.discrete_model import BinaryResultsWrapper
|
|
39
43
|
from statsmodels.discrete.discrete_model import BinaryResults
|
|
40
44
|
|
|
41
45
|
from pingouin import anova, pairwise_tukey, welch_anova, pairwise_gameshowell
|
|
42
46
|
|
|
47
|
+
from .hs_plot import ols_residplot, ols_qqplot
|
|
48
|
+
|
|
49
|
+
# ===================================================================
|
|
50
|
+
# MCAR(결측치 무작위성) 검정
|
|
51
|
+
# ===================================================================
|
|
52
|
+
def mcar_test(data: DataFrame, columns: list | str | None = None) -> DataFrame:
|
|
53
|
+
if isinstance(columns, str):
|
|
54
|
+
columns = [c.strip() for c in columns.split(",")]
|
|
55
|
+
|
|
56
|
+
cols = data.columns if columns is None else columns
|
|
57
|
+
df = data[cols]
|
|
58
|
+
|
|
59
|
+
# 결측치가 있는 컬럼만 사용
|
|
60
|
+
cols_with_na = [c for c in df.columns if df[c].isna().any()]
|
|
61
|
+
if len(cols_with_na) < 2:
|
|
62
|
+
raise ValueError("MCAR 검정은 결측치가 있는 변수가 최소 2개 이상 필요합니다.")
|
|
63
|
+
|
|
64
|
+
X = df[cols_with_na].to_numpy()
|
|
65
|
+
n, p = X.shape
|
|
66
|
+
|
|
67
|
+
# complete cases로 평균·공분산 추정
|
|
68
|
+
complete = ~np.isnan(X).any(axis=1)
|
|
69
|
+
if complete.sum() < p + 1:
|
|
70
|
+
raise ValueError("완전관측치(complete cases)가 부족하여 MCAR 검정을 수행할 수 없습니다.")
|
|
71
|
+
|
|
72
|
+
mu = X[complete].mean(axis=0)
|
|
73
|
+
S = np.cov(X[complete], rowvar=False)
|
|
74
|
+
S_inv = np.linalg.pinv(S)
|
|
75
|
+
|
|
76
|
+
chi_sq = 0.0
|
|
77
|
+
dfree = 0
|
|
78
|
+
|
|
79
|
+
for i in range(n):
|
|
80
|
+
obs = ~np.isnan(X[i])
|
|
81
|
+
if obs.sum() == p:
|
|
82
|
+
continue # complete case는 제외
|
|
83
|
+
diff = X[i, obs] - mu[obs]
|
|
84
|
+
S_obs = S[np.ix_(obs, obs)]
|
|
85
|
+
S_obs_inv = np.linalg.pinv(S_obs)
|
|
86
|
+
|
|
87
|
+
chi_sq += diff @ S_obs_inv @ diff
|
|
88
|
+
dfree += obs.sum()
|
|
89
|
+
|
|
90
|
+
dfree -= p # Little's adjustment
|
|
91
|
+
|
|
92
|
+
p_value = 1 - chi2.cdf(chi_sq, dfree)
|
|
93
|
+
is_mcar = p_value > 0.05
|
|
94
|
+
|
|
95
|
+
return DataFrame([{
|
|
96
|
+
"statistic": chi_sq,
|
|
97
|
+
"dof": dfree,
|
|
98
|
+
"p-value": p_value,
|
|
99
|
+
"is_mcar": is_mcar,
|
|
100
|
+
"interpretation": (
|
|
101
|
+
"결측치는 완전 무작위(MCAR)로 판단됨 → 결측치 삭제 가능"
|
|
102
|
+
if is_mcar else
|
|
103
|
+
"결측치는 완전 무작위(MCAR)가 아님 → 삭제 시 편향 가능"
|
|
104
|
+
)
|
|
105
|
+
}])
|
|
106
|
+
|
|
43
107
|
# ===================================================================
|
|
44
108
|
# 결측치 분석 (Missing Values Analysis)
|
|
45
109
|
# ===================================================================
|
|
@@ -219,6 +283,8 @@ def describe(data: DataFrame, *fields: str, columns: list | None = None):
|
|
|
219
283
|
행은 다음과 같은 통계량을 포함:
|
|
220
284
|
|
|
221
285
|
- count (float): 비결측치의 수
|
|
286
|
+
- na_count (int): 결측치의 수
|
|
287
|
+
- na_rate (float): 결측치 비율(%)
|
|
222
288
|
- mean (float): 평균값
|
|
223
289
|
- std (float): 표준편차
|
|
224
290
|
- min (float): 최소값
|
|
@@ -267,9 +333,13 @@ def describe(data: DataFrame, *fields: str, columns: list | None = None):
|
|
|
267
333
|
|
|
268
334
|
# 기술통계량 구하기
|
|
269
335
|
desc = data[list(fields)].describe().T
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
336
|
+
|
|
337
|
+
# 각 컬럼별 결측치 수(na_count) 추가
|
|
338
|
+
na_counts = data[list(fields)].isnull().sum()
|
|
339
|
+
desc.insert(1, 'na_count', na_counts)
|
|
340
|
+
|
|
341
|
+
# 결측치 비율(na_rate) 추가
|
|
342
|
+
desc.insert(2, 'na_rate', (na_counts / len(data)) * 100)
|
|
273
343
|
|
|
274
344
|
# 추가 통계량 계산
|
|
275
345
|
additional_stats = []
|
|
@@ -1192,7 +1262,10 @@ def trend(x: any, y: any, degree: int = 1, value_count: int = 100) -> Tuple[np.n
|
|
|
1192
1262
|
# ===================================================================
|
|
1193
1263
|
# 선형회귀 요약 리포트
|
|
1194
1264
|
# ===================================================================
|
|
1195
|
-
def ols_report(fit, data, full=False, alpha=0.05)
|
|
1265
|
+
def ols_report(fit, data, full=False, alpha=0.05) -> Union[
|
|
1266
|
+
Tuple[DataFrame, DataFrame],
|
|
1267
|
+
Tuple[DataFrame, DataFrame, str, str, list[str], str]
|
|
1268
|
+
]:
|
|
1196
1269
|
"""선형회귀 적합 결과를 요약 리포트로 변환한다.
|
|
1197
1270
|
|
|
1198
1271
|
Args:
|
|
@@ -1211,6 +1284,7 @@ def ols_report(fit, data, full=False, alpha=0.05):
|
|
|
1211
1284
|
- 회귀식 문자열 (`equation_text`, str): 상수항과 계수를 포함한 회귀식 표현.
|
|
1212
1285
|
|
|
1213
1286
|
full=False일 때:
|
|
1287
|
+
- 성능 지표 표 (`pdf`, DataFrame): R, R², Adj. R², F, p-value, Durbin-Watson.
|
|
1214
1288
|
- 회귀계수 표 (`rdf`, DataFrame)
|
|
1215
1289
|
|
|
1216
1290
|
Examples:
|
|
@@ -1378,7 +1452,19 @@ def ols_report(fit, data, full=False, alpha=0.05):
|
|
|
1378
1452
|
# ===================================================================
|
|
1379
1453
|
# 선형회귀
|
|
1380
1454
|
# ===================================================================
|
|
1381
|
-
def ols(df: DataFrame, yname: str, report=False)
|
|
1455
|
+
def ols(df: DataFrame, yname: str, report: bool | str | int = False) -> Union[
|
|
1456
|
+
RegressionResultsWrapper,
|
|
1457
|
+
Tuple[RegressionResultsWrapper, DataFrame, DataFrame],
|
|
1458
|
+
Tuple[
|
|
1459
|
+
RegressionResultsWrapper,
|
|
1460
|
+
DataFrame,
|
|
1461
|
+
DataFrame,
|
|
1462
|
+
str,
|
|
1463
|
+
str,
|
|
1464
|
+
list[str],
|
|
1465
|
+
str
|
|
1466
|
+
]
|
|
1467
|
+
]:
|
|
1382
1468
|
"""선형회귀분석을 수행하고 적합 결과를 반환한다.
|
|
1383
1469
|
|
|
1384
1470
|
OLS(Ordinary Least Squares) 선형회귀분석을 실시한다.
|
|
@@ -1387,7 +1473,7 @@ def ols(df: DataFrame, yname: str, report=False):
|
|
|
1387
1473
|
Args:
|
|
1388
1474
|
df (DataFrame): 종속변수와 독립변수를 모두 포함한 데이터프레임.
|
|
1389
1475
|
yname (str): 종속변수 컬럼명.
|
|
1390
|
-
report: 리포트 모드 설정. 다음 값 중 하나:
|
|
1476
|
+
report (bool | str | int): 리포트 모드 설정. 다음 값 중 하나:
|
|
1391
1477
|
- False (기본값): 리포트 미사용. fit 객체만 반환.
|
|
1392
1478
|
- 1 또는 'summary': 요약 리포트 반환 (full=False).
|
|
1393
1479
|
- 2 또는 'full': 풀 리포트 반환 (full=True).
|
|
@@ -1426,10 +1512,10 @@ def ols(df: DataFrame, yname: str, report=False):
|
|
|
1426
1512
|
fit = hs_stats.ols(df, 'target')
|
|
1427
1513
|
|
|
1428
1514
|
# 요약 리포트 반환
|
|
1429
|
-
fit, pdf, rdf = hs_stats.ols(df, 'target', report=
|
|
1515
|
+
fit, pdf, rdf = hs_stats.ols(df, 'target', report='summary')
|
|
1430
1516
|
|
|
1431
1517
|
# 풀 리포트 반환
|
|
1432
|
-
fit, pdf, rdf, result_report, model_report, var_reports, eq = hs_stats.ols(df, 'target', report=
|
|
1518
|
+
fit, pdf, rdf, result_report, model_report, var_reports, eq = hs_stats.ols(df, 'target', report='full')
|
|
1433
1519
|
```
|
|
1434
1520
|
"""
|
|
1435
1521
|
x = df.drop(yname, axis=1)
|
|
@@ -1459,15 +1545,31 @@ def ols(df: DataFrame, yname: str, report=False):
|
|
|
1459
1545
|
# ===================================================================
|
|
1460
1546
|
# 로지스틱 회귀 요약 리포트
|
|
1461
1547
|
# ===================================================================
|
|
1462
|
-
def logit_report(
|
|
1548
|
+
def logit_report(
|
|
1549
|
+
fit: BinaryResultsWrapper,
|
|
1550
|
+
data: DataFrame,
|
|
1551
|
+
threshold: float = 0.5,
|
|
1552
|
+
full: Union[bool, str, int] = False,
|
|
1553
|
+
alpha: float = 0.05
|
|
1554
|
+
) -> Union[
|
|
1555
|
+
Tuple[DataFrame, DataFrame],
|
|
1556
|
+
Tuple[
|
|
1557
|
+
DataFrame,
|
|
1558
|
+
DataFrame,
|
|
1559
|
+
str,
|
|
1560
|
+
str,
|
|
1561
|
+
list[str],
|
|
1562
|
+
np.ndarray
|
|
1563
|
+
]
|
|
1564
|
+
]:
|
|
1463
1565
|
"""로지스틱 회귀 적합 결과를 상세 리포트로 변환한다.
|
|
1464
1566
|
|
|
1465
1567
|
Args:
|
|
1466
1568
|
fit: statsmodels Logit 결과 객체 (`fit.summary()`와 예측 확률을 지원해야 함).
|
|
1467
|
-
data: 종속변수와 독립변수를 모두 포함한 DataFrame.
|
|
1468
|
-
threshold: 예측 확률을 이진 분류로 변환할 임계값. 기본값 0.5.
|
|
1469
|
-
full: True이면 6개 값 반환, False이면 주요 2개(cdf, rdf)만 반환. 기본값 False.
|
|
1470
|
-
alpha: 유의수준. 기본값 0.05.
|
|
1569
|
+
data (DataFrame): 종속변수와 독립변수를 모두 포함한 DataFrame.
|
|
1570
|
+
threshold (float): 예측 확률을 이진 분류로 변환할 임계값. 기본값 0.5.
|
|
1571
|
+
full (bool | str | int): True이면 6개 값 반환, False이면 주요 2개(cdf, rdf)만 반환. 기본값 False.
|
|
1572
|
+
alpha (float): 유의수준. 기본값 0.05.
|
|
1471
1573
|
|
|
1472
1574
|
Returns:
|
|
1473
1575
|
tuple: full=True일 때 다음 요소를 포함한다.
|
|
@@ -1652,7 +1754,25 @@ def logit_report(fit, data, threshold=0.5, full=False, alpha=0.05):
|
|
|
1652
1754
|
# ===================================================================
|
|
1653
1755
|
# 로지스틱 회귀
|
|
1654
1756
|
# ===================================================================
|
|
1655
|
-
def logit(
|
|
1757
|
+
def logit(
|
|
1758
|
+
df: DataFrame,
|
|
1759
|
+
yname: str,
|
|
1760
|
+
report: Union[bool, str, int] = False
|
|
1761
|
+
) -> Union[
|
|
1762
|
+
BinaryResultsWrapper,
|
|
1763
|
+
Tuple[
|
|
1764
|
+
BinaryResultsWrapper,
|
|
1765
|
+
DataFrame
|
|
1766
|
+
],
|
|
1767
|
+
Tuple[
|
|
1768
|
+
BinaryResultsWrapper,
|
|
1769
|
+
DataFrame,
|
|
1770
|
+
DataFrame,
|
|
1771
|
+
str,
|
|
1772
|
+
str,
|
|
1773
|
+
List[str]
|
|
1774
|
+
]
|
|
1775
|
+
]:
|
|
1656
1776
|
"""로지스틱 회귀분석을 수행하고 적합 결과를 반환한다.
|
|
1657
1777
|
|
|
1658
1778
|
종속변수가 이항(binary) 형태일 때 로지스틱 회귀분석을 실시한다.
|
|
@@ -1734,7 +1854,7 @@ def logit(df: DataFrame, yname: str, report=False):
|
|
|
1734
1854
|
# ===================================================================
|
|
1735
1855
|
# 선형성 검정 (Linearity Test)
|
|
1736
1856
|
# ===================================================================
|
|
1737
|
-
def ols_linearity_test(fit, power: int = 2, alpha: float = 0.05) -> DataFrame:
|
|
1857
|
+
def ols_linearity_test(fit, power: int = 2, alpha: float = 0.05, plot: bool = False, title: str = None, save_path: str = None) -> DataFrame:
|
|
1738
1858
|
"""회귀모형의 선형성을 Ramsey RESET 검정으로 평가한다.
|
|
1739
1859
|
|
|
1740
1860
|
적합된 회귀모형에 대해 Ramsey RESET(Regression Specification Error Test) 검정을 수행하여
|
|
@@ -1747,6 +1867,9 @@ def ols_linearity_test(fit, power: int = 2, alpha: float = 0.05) -> DataFrame:
|
|
|
1747
1867
|
power=2일 때 예측값의 제곱항이 추가됨.
|
|
1748
1868
|
power가 클수록 더 높은 차수의 비선형성을 감지.
|
|
1749
1869
|
alpha (float, optional): 유의수준. 기본값 0.05.
|
|
1870
|
+
plot (bool, optional): True이면 잔차 플롯을 출력. 기본값 False.
|
|
1871
|
+
title (str, optional): 플롯 제목. 기본값 None.
|
|
1872
|
+
save_path (str, optional): 플롯을 저장할 경로. 기본값 None
|
|
1750
1873
|
|
|
1751
1874
|
Returns:
|
|
1752
1875
|
DataFrame: 선형성 검정 결과를 포함한 데이터프레임.
|
|
@@ -1829,13 +1952,16 @@ def ols_linearity_test(fit, power: int = 2, alpha: float = 0.05) -> DataFrame:
|
|
|
1829
1952
|
"해석": [interpretation]
|
|
1830
1953
|
})
|
|
1831
1954
|
|
|
1955
|
+
if plot:
|
|
1956
|
+
ols_residplot(fit, lowess=True, mse=True, title=title, save_path=save_path)
|
|
1957
|
+
|
|
1832
1958
|
return result_df
|
|
1833
1959
|
|
|
1834
1960
|
|
|
1835
1961
|
# ===================================================================
|
|
1836
1962
|
# 정규성 검정 (Normality Test)
|
|
1837
1963
|
# ===================================================================
|
|
1838
|
-
def ols_normality_test(fit, alpha: float = 0.05) -> DataFrame:
|
|
1964
|
+
def ols_normality_test(fit, alpha: float = 0.05, plot: bool = False, title: str = None, save_path: str = None) -> DataFrame:
|
|
1839
1965
|
"""회귀모형 잔차의 정규성을 검정한다.
|
|
1840
1966
|
|
|
1841
1967
|
회귀모형의 잔차가 정규분포를 따르는지 Shapiro-Wilk 검정과 Jarque-Bera 검정으로 평가한다.
|
|
@@ -1844,6 +1970,9 @@ def ols_normality_test(fit, alpha: float = 0.05) -> DataFrame:
|
|
|
1844
1970
|
Args:
|
|
1845
1971
|
fit: 회귀 모형 객체 (statsmodels의 RegressionResultsWrapper).
|
|
1846
1972
|
alpha (float, optional): 유의수준. 기본값 0.05.
|
|
1973
|
+
plot (bool, optional): True이면 Q-Q 플롯을 출력. 기본값 False.
|
|
1974
|
+
title (str, optional): 플롯 제목. 기본값 None.
|
|
1975
|
+
save_path (str, optional): 플롯을 저장할 경로. 기본값 None
|
|
1847
1976
|
|
|
1848
1977
|
Returns:
|
|
1849
1978
|
DataFrame: 정규성 검정 결과를 포함한 데이터프레임.
|
|
@@ -1922,6 +2051,10 @@ def ols_normality_test(fit, alpha: float = 0.05) -> DataFrame:
|
|
|
1922
2051
|
if not results:
|
|
1923
2052
|
raise ValueError("정규성 검정을 수행할 수 없습니다.")
|
|
1924
2053
|
|
|
2054
|
+
|
|
2055
|
+
if plot:
|
|
2056
|
+
ols_qqplot(fit, title=title, save_path=save_path)
|
|
2057
|
+
|
|
1925
2058
|
result_df = DataFrame(results)
|
|
1926
2059
|
return result_df
|
|
1927
2060
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|