hossam 0.4.3__py3-none-any.whl → 0.4.4__py3-none-any.whl

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/hs_plot.py CHANGED
@@ -35,12 +35,12 @@ if pd.__version__ > "2.0.0":
35
35
 
36
36
  config = SimpleNamespace(
37
37
  dpi=200,
38
- width=800,
39
- height=520,
40
- font_size=10,
38
+ width=600,
39
+ height=350,
40
+ font_size=7,
41
41
  font_weight="normal",
42
- frame_width=0.7,
43
- line_width=1.5,
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
- if (rows > 1 or cols > 1) and (ws != None and hs != None):
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|list): 대상 Axes (단일 Axes 또는 subplots 배열).
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|list): 대상 Axes (단일 Axes 또는 subplots 배열).
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보다 훨씬 빠름)
hossam/hs_prep.py CHANGED
@@ -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 = []
hossam/hs_stats.py CHANGED
@@ -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
- # 각 컬럼별 결측치 수(null_count) 추가
271
- null_counts = data[list(fields)].isnull().sum()
272
- desc.insert(1, 'null_count', null_counts)
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=1)
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=2)
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(fit, data, threshold=0.5, full=False, alpha=0.05):
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(df: DataFrame, yname: str, report=False):
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hossam
3
- Version: 0.4.3
3
+ Version: 0.4.4
4
4
  Summary: Hossam Data Helper
5
5
  Author-email: Lee Kwang-Ho <leekh4232@gmail.com>
6
6
  License-Expression: MIT
@@ -3,14 +3,14 @@ hossam/__init__.py,sha256=OkMeP15jt6aCy7QNXMtkO0YRVvgOQYumkb7GuVKrbcs,2712
3
3
  hossam/data_loader.py,sha256=oUIsqbHQoRiHA_1tdElDaYo1ipmUB5fYSXYMB5gLOl0,6395
4
4
  hossam/hs_classroom.py,sha256=rgayol3U5PSo4rLfdbClfiAtG21bFrASaSW56PUsjus,27144
5
5
  hossam/hs_gis.py,sha256=DLogaf5nxJBbG-d8QoH2g8UfZ1omMtmEXDYgNg8jtT0,11410
6
- hossam/hs_plot.py,sha256=A_nS8dP4cijp7LZs253SWxfBUp5qvvTlSPGKjDj0BIA,83712
7
- hossam/hs_prep.py,sha256=2ptFFxV4G1IFmy-B89TqXaPkA8jROZutr2XIkaXNHW4,36006
8
- hossam/hs_stats.py,sha256=qAor-RE5qNsytoZW1mriK3yql9PVif5bBGyG64YC2PM,110780
6
+ hossam/hs_plot.py,sha256=tsJMi2q9SzHRSs25dXsHkkImW-Jk7su1M6TbKwX9koU,83887
7
+ hossam/hs_prep.py,sha256=ocZNGzHzqgasVNLcb_LClTZaAeTYiIg4mzrixeEzBQU,37693
8
+ hossam/hs_stats.py,sha256=LpUG8U9ybnh6qSMW2SKCSDJZTeMhLH2xH2Pj4i7U6TU,114889
9
9
  hossam/hs_timeserise.py,sha256=gSj3cPgOGLOZEXhfW1anXbwpoJja847ZY9F8l9piJPE,42601
10
10
  hossam/hs_util.py,sha256=8byLj_VR93vS__lyf0xgQKArgMy9qFm2VvZVSCxfQX0,8444
11
11
  hossam/leekh.png,sha256=1PB5NQ24SDoHA5KMiBBsWpSa3iniFcwFTuGwuOsTHfI,6395
12
- hossam-0.4.3.dist-info/licenses/LICENSE,sha256=nIqzhlcFY_2D6QtFsYjwU7BWkafo-rUJOQpDZ-DsauI,941
13
- hossam-0.4.3.dist-info/METADATA,sha256=0VAI5TJKWSFwZriKBYnf5a4MSB5cdOLUh9lV_vYDPJY,3676
14
- hossam-0.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- hossam-0.4.3.dist-info/top_level.txt,sha256=_-7bwjhthHplWhywEaHIJX2yL11CQCaLjCNSBlk6wiQ,7
16
- hossam-0.4.3.dist-info/RECORD,,
12
+ hossam-0.4.4.dist-info/licenses/LICENSE,sha256=nIqzhlcFY_2D6QtFsYjwU7BWkafo-rUJOQpDZ-DsauI,941
13
+ hossam-0.4.4.dist-info/METADATA,sha256=R6qOrcnZhbTzUrRK2x9vNksDjw8rVK1DVZrbRIPSPQQ,3676
14
+ hossam-0.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ hossam-0.4.4.dist-info/top_level.txt,sha256=_-7bwjhthHplWhywEaHIJX2yL11CQCaLjCNSBlk6wiQ,7
16
+ hossam-0.4.4.dist-info/RECORD,,
File without changes