hossam 0.4.9__py3-none-any.whl → 0.4.11__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/__init__.py CHANGED
@@ -6,6 +6,7 @@ from . import hs_prep
6
6
  from . import hs_stats
7
7
  from . import hs_timeserise
8
8
  from . import hs_util
9
+ from . import hs_cluster
9
10
  from .hs_util import load_info
10
11
  from .hs_util import _load_data_remote as load_data
11
12
  from .hs_plot import visualize_silhouette
@@ -25,7 +26,7 @@ except Exception:
25
26
 
26
27
  my_dpi = hs_plot.config.dpi
27
28
 
28
- __all__ = ["my_dpi", "load_data", "load_info", "hs_classroom", "hs_gis", "hs_plot", "hs_prep", "hs_stats", "hs_timeserise", "hs_util", "visualize_silhouette"]
29
+ __all__ = ["my_dpi", "load_data", "load_info", "hs_classroom", "hs_gis", "hs_plot", "hs_prep", "hs_stats", "hs_timeserise", "hs_util", "hs_cluster", "visualize_silhouette"]
29
30
 
30
31
  # 내부 모듈에서 hs_fig를 사용할 때는 아래와 같이 import 하세요.
31
32
  # from hossam import hs_fig
hossam/hs_classroom.py CHANGED
@@ -8,8 +8,8 @@ from kmodes.kmodes import KModes
8
8
  from matplotlib import pyplot as plt
9
9
  import seaborn as sns
10
10
  from .hs_util import load_data, pretty_table
11
- from . import hs_plot
12
11
  from .hs_plot import config
12
+ from . import hs_plot
13
13
 
14
14
  # ===================================================================
15
15
  # 학생들을 관심사와 성적으로 균형잡힌 조로 편성한다
hossam/hs_cluster.py ADDED
@@ -0,0 +1,119 @@
1
+ from typing import Literal
2
+ from kneed import KneeLocator
3
+ from pandas import Series
4
+ from matplotlib.pyplot import Axes # type: ignore
5
+
6
+ from . import hs_plot
7
+
8
+ import numpy as np
9
+
10
+ def elbow_point(
11
+ x: Series | np.ndarray | list,
12
+ y: Series | np.ndarray | list,
13
+ dir: Literal["left,down", "left,up", "right,down", "right,up"] = "left,down",
14
+ S: float = 0.1,
15
+ plot: bool = True,
16
+ title: str = None,
17
+ marker: str = None,
18
+ width: int = hs_plot.config.width,
19
+ height: int = hs_plot.config.height,
20
+ dpi: int = hs_plot.config.dpi,
21
+ linewidth: int = hs_plot.config.line_width,
22
+ save_path: str | None = None,
23
+ ax: Axes | None = None,
24
+ **params,
25
+ ) -> tuple:
26
+
27
+ """
28
+ 엘보우(Elbow) 포인트를 자동으로 탐지하는 함수.
29
+
30
+ 주어진 x, y 값의 곡선에서 KneeLocator를 활용해 엘보우(혹은 니) 포인트를 탐지하고, 필요시 시각화까지 지원함.
31
+
32
+ Args:
33
+ x (Series | np.ndarray | list): x축 값(일반적으로 K값 등).
34
+ y (Series | np.ndarray | list): y축 값(일반적으로 inertia, SSE 등).
35
+ dir (Literal["left,down", "left,up", "right,down", "right,up"], optional):
36
+ 곡선의 방향 및 형태 지정. 기본값은 "left,down".
37
+ - "left,down": 왼쪽에서 오른쪽으로 감소(볼록)
38
+ - "left,up": 왼쪽에서 오른쪽으로 증가(오목)
39
+ - "right,down": 오른쪽에서 왼쪽으로 감소(볼록)
40
+ - "right,up": 오른쪽에서 왼쪽으로 증가(오목)
41
+ S (float, optional): KneeLocator의 민감도 파라미터. 기본값 0.1.
42
+ plot (bool, optional): True면 결과를 시각화함. 기본값 True.
43
+ title (str, optional): 플롯 제목.
44
+ marker (str, optional): 마커 스타일.
45
+ width (int, optional): 플롯 가로 크기.
46
+ height (int, optional): 플롯 세로 크기.
47
+ dpi (int, optional): 플롯 해상도.
48
+ linewidth (int, optional): 선 두께.
49
+ save_path (str | None, optional): 저장 경로 지정시 파일로 저장.
50
+ ax (Axes | None, optional): 기존 matplotlib Axes 객체. None이면 새로 생성.
51
+ **params: lineplot에 전달할 추가 파라미터.
52
+
53
+ Returns:
54
+ tuple: (best_x, best_y)
55
+ - best_x: 엘보우 포인트의 x값(예: 최적 K)
56
+ - best_y: 엘보우 포인트의 y값
57
+
58
+ Examples:
59
+ ```python
60
+ x = [1, 2, 3, 4, 5, 6]
61
+ y = [100, 80, 60, 45, 44, 43]
62
+ elbow_point(x, y)
63
+ ```
64
+
65
+ Note:
66
+ - KneeLocator는 kneed 패키지의 클래스로, 곡선의 형태(curve)와 방향(direction)에 따라 엘보우 포인트를 탐지함.
67
+ - dir 파라미터에 따라 curve/direction이 자동 지정됨.
68
+ - plot=True일 때, 엘보우 포인트에 수직/수평선과 텍스트가 표시됨.
69
+ """
70
+
71
+ if dir == "left,down":
72
+ curve = "convex"
73
+ direction = "decreasing"
74
+ elif dir == "left,up":
75
+ curve = "concave"
76
+ direction = "increasing"
77
+ elif dir == "right,down":
78
+ curve = "convex"
79
+ direction = "increasing"
80
+ else:
81
+ curve = "concave"
82
+ direction = "decreasing"
83
+
84
+ kn = KneeLocator(x=x, y=y, curve=curve, direction=direction, S=S)
85
+
86
+ best_x = kn.elbow
87
+ best_y = kn.elbow_y
88
+
89
+ if plot:
90
+ def hvline(ax):
91
+ ax.axvline(best_x, color="red", linestyle="--", linewidth=0.7)
92
+ ax.axhline(best_y, color="red", linestyle="--", linewidth=0.7)
93
+ ax.text(
94
+ best_x + 0.1,
95
+ best_y + 0.1,
96
+ "Best K=%d" % best_x,
97
+ fontsize=8,
98
+ ha="left",
99
+ va="bottom",
100
+ color="r",
101
+ )
102
+
103
+ hs_plot.lineplot(
104
+ df = None,
105
+ xname = x,
106
+ yname = y,
107
+ title = title,
108
+ marker = marker,
109
+ width = width,
110
+ height = height,
111
+ linewidth = linewidth,
112
+ dpi = dpi,
113
+ save_path = save_path,
114
+ callback = hvline,
115
+ ax = ax,
116
+ **params
117
+ )
118
+
119
+ return best_x, best_y
hossam/hs_plot.py CHANGED
@@ -5,10 +5,10 @@ from typing import Callable
5
5
 
6
6
  # ===================================================================
7
7
  import numpy as np
8
- import pandas as pd
9
8
  import seaborn as sb
10
9
  import matplotlib.pyplot as plt
11
10
  from matplotlib.pyplot import Axes # type: ignore
11
+ from pandas import Series, DataFrame
12
12
  from math import sqrt
13
13
  from pandas import DataFrame
14
14
 
@@ -200,9 +200,9 @@ def show_figure(ax: Axes | np.ndarray, callback: Callable | None = None, outpara
200
200
  # 선 그래프를 그린다
201
201
  # ===================================================================
202
202
  def lineplot(
203
- df: DataFrame,
204
- xname: str | None = None,
205
- yname: str | None = None,
203
+ df: DataFrame | None = None,
204
+ xname: str | Series | np.ndarray | list | None = None,
205
+ yname: str | Series | np.ndarray | list | None = None,
206
206
  hue: str | None = None,
207
207
  title: str | None = None,
208
208
  marker: str | None = None,
@@ -219,13 +219,13 @@ def lineplot(
219
219
  """선 그래프를 그린다.
220
220
 
221
221
  Args:
222
- df (DataFrame): 시각화할 데이터.
223
- xname (str|None): x축 컬럼명.
224
- yname (str|None): y축 컬럼명.
225
- hue (str|None): 범주 구분 컬럼명.
226
- title (str|None): 그래프 제목.
227
- marker (str|None): 마커 모양.
228
- palette (str|None): 팔레트 이름.
222
+ df (DataFrame | None): 시각화할 데이터.
223
+ xname (str | Series | np.ndarray | list | None): x축 컬럼명 혹은 x축 값 시퀀스.
224
+ yname (str | Series | np.ndarray | list | None): y축 컬럼명 혹은 y축 값 시퀀스.
225
+ hue (str | None): 범주 구분 컬럼명.
226
+ title (str | None): 그래프 제목.
227
+ marker (str | None): 마커 모양.
228
+ palette (str | None): 팔레트 이름.
229
229
  width (int): 캔버스 가로 픽셀.
230
230
  height (int): 캔버스 세로 픽셀.
231
231
  linewidth (float): 선 굵기.
@@ -2122,8 +2122,8 @@ def categorical_target_distribution(
2122
2122
  # ===================================================================
2123
2123
  def roc_curve_plot(
2124
2124
  fit,
2125
- y: np.ndarray | pd.Series | None = None,
2126
- X: pd.DataFrame | np.ndarray | None = None,
2125
+ y: np.ndarray | Series | None = None,
2126
+ X: DataFrame | np.ndarray | None = None,
2127
2127
  title: str | None = None,
2128
2128
  width: int = config.height,
2129
2129
  height: int = config.height,
@@ -2450,7 +2450,7 @@ def distribution_plot(
2450
2450
  if hue not in data.columns:
2451
2451
  raise ValueError(f"hue column '{hue}' not found in DataFrame")
2452
2452
 
2453
- categories = list(pd.Series(data[hue].dropna().unique()).sort_values())
2453
+ categories = list(Series(data[hue].dropna().unique()).sort_values())
2454
2454
  n_cat = len(categories) if categories else 1
2455
2455
 
2456
2456
  fig, axes = get_default_ax(width, height, rows=n_cat, cols=2, dpi=dpi, title=title)
hossam/hs_util.py CHANGED
@@ -10,10 +10,13 @@ from typing import TYPE_CHECKING
10
10
  from importlib.metadata import distributions
11
11
  import pandas as pd
12
12
  import numpy as np
13
+ import glob as gl
14
+ # -------------------------------------------------------------
13
15
  from pandas import DataFrame, DatetimeIndex, read_csv, read_excel
14
16
  from scipy.stats import normaltest
15
17
  from tabulate import tabulate
16
18
  from os.path import join, exists
19
+ import os
17
20
  from io import BytesIO
18
21
  from pandas import DataFrame, read_csv, read_excel
19
22
  from typing import Optional, Tuple, Any
@@ -24,11 +27,13 @@ BASE_URL = "https://data.hossam.kr"
24
27
  def __get_df(path: str, index_col=None) -> DataFrame:
25
28
  p = path.rfind(".")
26
29
  exec = path[p+1:].lower()
30
+ tmp_dir = None
27
31
 
28
32
  # 파일 확장자가 압축파일인 경우 로컬에 파일을 다운로드 후 압축 해제
29
33
  if exec == "zip":
30
- tmp_dir = Path(tempfile.mkdtemp())
31
- zip_path = tmp_dir / "data.zip"
34
+ tmp_dir = os.getcwd() + "/.hossam_tmp"
35
+ os.makedirs(tmp_dir, exist_ok=True)
36
+ zip_path = join(tmp_dir, "data.zip")
32
37
 
33
38
  # 원격 URL인 경우 파일 다운로드
34
39
  if path.lower().startswith(('http://', 'https://')):
@@ -49,7 +54,7 @@ def __get_df(path: str, index_col=None) -> DataFrame:
49
54
  zip_ref.extractall(tmp_dir)
50
55
 
51
56
  # 압축 해제된 파일 중 첫 번째 파일을 데이터로 로드
52
- extracted_files = list(tmp_dir.glob('*'))
57
+ extracted_files = list(gl.glob(join(tmp_dir, '*')))
53
58
  if not extracted_files:
54
59
  raise FileNotFoundError("압축 파일 내에 데이터 파일이 없습니다.")
55
60
 
@@ -57,10 +62,6 @@ def __get_df(path: str, index_col=None) -> DataFrame:
57
62
  p = path.rfind(".")
58
63
  exec = path[p+1:].lower()
59
64
 
60
- # 생성된 임시 디렉토리 삭제
61
- shutil.rmtree(tmp_dir)
62
-
63
-
64
65
  if exec == 'xlsx':
65
66
  # If path is a remote URL, fetch the file once and reuse the bytes
66
67
  if path.lower().startswith(('http://', 'https://')):
@@ -100,6 +101,9 @@ def __get_df(path: str, index_col=None) -> DataFrame:
100
101
  else:
101
102
  df = read_csv(path, index_col=index_col)
102
103
 
104
+ if tmp_dir:
105
+ shutil.rmtree(tmp_dir)
106
+
103
107
  return df
104
108
 
105
109
  # -------------------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hossam
3
- Version: 0.4.9
3
+ Version: 0.4.11
4
4
  Summary: Hossam Data Helper
5
5
  Author-email: Lee Kwang-Ho <leekh4232@gmail.com>
6
6
  License-Expression: MIT
@@ -61,9 +61,9 @@ title: 🎓 Hossam Data Helper
61
61
 
62
62
  - 📊 **풍부한 시각화**: 25+ 시각화 함수 (Seaborn/Matplotlib 기반)
63
63
  - 🎯 **통계 분석**: 회귀, 분류, 시계열 분석 도구
64
+ - 🤖 **머신 러닝**: 예측, 분류, 군집 학습 모델 구축 및 성능 평가
64
65
  - 📦 **샘플 데이터**: 학습용 데이터셋 즉시 로드
65
66
  - 🔧 **데이터 전처리**: 결측치 처리, 이상치 탐지, 스케일링
66
- - 🤖 **MCP 서버**: VSCode/Copilot과 통합 가능한 Model Context Protocol 지원
67
67
  - 📈 **교육용 최적화**: 데이터 분석 교육에 특화된 설계
68
68
 
69
69
 
@@ -87,6 +87,8 @@ pip install hossam
87
87
  - **hs_timeserise**: 시계열 분석 기능 지원
88
88
  - **hs_gis**: GIS 데이터 로드 및 시각화 (대한민국 지도 지원)
89
89
  - **hs_util**: 예쁜 테이블 출력, 그리드 서치 등
90
+ - **hs_cluster**: 군집분석, PCA 등 (작업중)
91
+ - **hs_ml**: 예측, 분류 분석 (예정)
90
92
 
91
93
  자세한 사용법은 [API 문서](https://py.hossam.kr/api/hossam/)를 참고하세요.
92
94
 
@@ -0,0 +1,16 @@
1
+ hossam/NotoSansKR-Regular.ttf,sha256=0SCufUQwcVWrWTu75j4Lt_V2bgBJIBXl1p8iAJJYkVY,6185516
2
+ hossam/__init__.py,sha256=4cGvavSotmQKhkHS4UCANhzszrMNwXNESAhh0RuFF-w,2893
3
+ hossam/hs_classroom.py,sha256=Sb1thy49LKn2zU90aiOVwHWhyWSMHLZbZX7eXmQlquc,27523
4
+ hossam/hs_cluster.py,sha256=anjoZ12JsIDWoGhm6agd0IF4N_md5czutyW4rbXnDEM,4255
5
+ hossam/hs_gis.py,sha256=DVmndBK-_7GMK3J1_on3ieEQk1S0MfUZ8_wlX-cDdZQ,11581
6
+ hossam/hs_plot.py,sha256=5j498vga_1wZBRlMUZ047LswNSvfTEpGP6uL7yzl3-g,92744
7
+ hossam/hs_prep.py,sha256=ypuX97mCxpo7CLoI_S79bUw7th0ok5LCZjt4vzRaGiI,38326
8
+ hossam/hs_stats.py,sha256=MDS3rvaXDP8aYwcE36JTetWiZgE4fkXnNo0vwlXu-pA,119890
9
+ hossam/hs_timeserise.py,sha256=NzGV4bJmVQr3qUFySOP25qENItmloYjgh3VgwSbSmXc,43163
10
+ hossam/hs_util.py,sha256=ptl-2W7-0Ad_BemZMR8cFnDt6-SHCRRCk1Gh7giFjSs,16149
11
+ hossam/leekh.png,sha256=1PB5NQ24SDoHA5KMiBBsWpSa3iniFcwFTuGwuOsTHfI,6395
12
+ hossam-0.4.11.dist-info/licenses/LICENSE,sha256=nIqzhlcFY_2D6QtFsYjwU7BWkafo-rUJOQpDZ-DsauI,941
13
+ hossam-0.4.11.dist-info/METADATA,sha256=POoVivyFd3rFLoQny6kigfNmsDbHdyvndbZ71Sz2NjY,3803
14
+ hossam-0.4.11.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
15
+ hossam-0.4.11.dist-info/top_level.txt,sha256=_-7bwjhthHplWhywEaHIJX2yL11CQCaLjCNSBlk6wiQ,7
16
+ hossam-0.4.11.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- hossam/NotoSansKR-Regular.ttf,sha256=0SCufUQwcVWrWTu75j4Lt_V2bgBJIBXl1p8iAJJYkVY,6185516
2
- hossam/__init__.py,sha256=pPq8agagol9Vhl_CFwa3QNpM8z278Qd_TZ_W4eJ0ziE,2854
3
- hossam/hs_classroom.py,sha256=oNRnHPXOu0-YqtPY7EJeS1qteH0CtKxNk5Lt7opti_w,27523
4
- hossam/hs_gis.py,sha256=DVmndBK-_7GMK3J1_on3ieEQk1S0MfUZ8_wlX-cDdZQ,11581
5
- hossam/hs_plot.py,sha256=u3nev3MRvp_n45K9feQdWhPmNVeCXavnX7xpS3zekXw,92535
6
- hossam/hs_prep.py,sha256=ypuX97mCxpo7CLoI_S79bUw7th0ok5LCZjt4vzRaGiI,38326
7
- hossam/hs_stats.py,sha256=MDS3rvaXDP8aYwcE36JTetWiZgE4fkXnNo0vwlXu-pA,119890
8
- hossam/hs_timeserise.py,sha256=NzGV4bJmVQr3qUFySOP25qENItmloYjgh3VgwSbSmXc,43163
9
- hossam/hs_util.py,sha256=_IME9IRbjOWZDBZwMQhKMMHdvWT3fjCRLtIt2RK-Yd0,16007
10
- hossam/leekh.png,sha256=1PB5NQ24SDoHA5KMiBBsWpSa3iniFcwFTuGwuOsTHfI,6395
11
- hossam-0.4.9.dist-info/licenses/LICENSE,sha256=nIqzhlcFY_2D6QtFsYjwU7BWkafo-rUJOQpDZ-DsauI,941
12
- hossam-0.4.9.dist-info/METADATA,sha256=rZsVu2NMwdxHp2stQbgoAGIMGkGK9eF6oGe9JuJ0i7k,3706
13
- hossam-0.4.9.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
14
- hossam-0.4.9.dist-info/top_level.txt,sha256=_-7bwjhthHplWhywEaHIJX2yL11CQCaLjCNSBlk6wiQ,7
15
- hossam-0.4.9.dist-info/RECORD,,