classifier-toolkit 0.1.0__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.
Files changed (26) hide show
  1. classifier_toolkit/eda/__init__.py +19 -0
  2. classifier_toolkit/eda/bivariate_analysis.py +413 -0
  3. classifier_toolkit/eda/eda_toolkit.py +549 -0
  4. classifier_toolkit/eda/feature_engineering.py +1310 -0
  5. classifier_toolkit/eda/first_glance.py +253 -0
  6. classifier_toolkit/eda/univariate_analysis.py +778 -0
  7. classifier_toolkit/eda/visualizations.py +1248 -0
  8. classifier_toolkit/eda/warnings/__init__.py +4 -0
  9. classifier_toolkit/eda/warnings/automated_warnings.py +20 -0
  10. classifier_toolkit/eda/warnings/default_warnings.py +286 -0
  11. classifier_toolkit/feature_selection/__init__.py +33 -0
  12. classifier_toolkit/feature_selection/base.py +182 -0
  13. classifier_toolkit/feature_selection/embedded_methods/__init__.py +7 -0
  14. classifier_toolkit/feature_selection/embedded_methods/elastic_net.py +178 -0
  15. classifier_toolkit/feature_selection/meta_selector.py +329 -0
  16. classifier_toolkit/feature_selection/utils/__init__.py +17 -0
  17. classifier_toolkit/feature_selection/utils/plottings.py +65 -0
  18. classifier_toolkit/feature_selection/utils/scoring.py +86 -0
  19. classifier_toolkit/feature_selection/wrapper_methods/__init__.py +11 -0
  20. classifier_toolkit/feature_selection/wrapper_methods/rfe.py +345 -0
  21. classifier_toolkit/feature_selection/wrapper_methods/sequential_selection.py +566 -0
  22. classifier_toolkit/model_fitting/__init__.py +0 -0
  23. classifier_toolkit/model_fitting/model_search.py +3 -0
  24. classifier_toolkit-0.1.0.dist-info/METADATA +99 -0
  25. classifier_toolkit-0.1.0.dist-info/RECORD +26 -0
  26. classifier_toolkit-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,253 @@
1
+ from typing import List, Optional
2
+
3
+ import pandas as pd
4
+ from colorama import Fore, Style, init
5
+ from tabulate import tabulate
6
+
7
+ init(autoreset=True) # Initialize colorama
8
+
9
+
10
+ class FirstGlance:
11
+ def __init__(
12
+ self,
13
+ dataframe: pd.DataFrame,
14
+ numerical_columns: Optional[List[str]],
15
+ categorical_columns: Optional[List[str]],
16
+ exclude_columns: Optional[List[str]] = None,
17
+ id_column: Optional[str] = None,
18
+ ) -> None:
19
+ """
20
+ Initialize the FirstGlance class with data and configuration.
21
+
22
+ Parameters
23
+ ----------
24
+ dataframe : pd.DataFrame
25
+ The data to be analyzed.
26
+ numerical_columns : Optional[List[str]]
27
+ List of numerical columns.
28
+ categorical_columns : Optional[List[str]]
29
+ List of categorical columns.
30
+ exclude_columns : Optional[List[str]], optional
31
+ List of columns to exclude from analysis, by default None.
32
+ id_column : Optional[str], optional
33
+ Column to identify duplicates, by default None.
34
+ """
35
+ self.data = dataframe
36
+ self.numerical_columns = numerical_columns or []
37
+ self.categorical_columns = categorical_columns or []
38
+ self.exclude_columns = exclude_columns or []
39
+ self.id_column = id_column
40
+
41
+ # Define the numerical and categorical columns using the _get_analysis_columns method
42
+ self.numerical_columns = self._get_analysis_columns(numerical_columns)
43
+ self.categorical_columns = self._get_analysis_columns(categorical_columns)
44
+ self.columns = self._get_analysis_columns()
45
+
46
+ def _get_analysis_columns(self, column_list: Optional[List] = None) -> List[str]:
47
+ """
48
+ Get the columns to analyze based on the provided column list.
49
+
50
+ Parameters
51
+ ----------
52
+ column_list : Optional[List], optional
53
+ List of columns to analyze, by default None.
54
+
55
+ Returns
56
+ -------
57
+ List[str]
58
+ List of columns to analyze.
59
+ """
60
+ if column_list is None:
61
+ return [col for col in self.data.columns if col not in self.exclude_columns]
62
+ else:
63
+ return [col for col in column_list if col not in self.exclude_columns]
64
+
65
+ def generate_first_glance(self) -> None:
66
+ """
67
+ Display the first few rows and summary statistics of the data.
68
+ """
69
+ print(Fore.GREEN + "First few rows:")
70
+ print(self.data.head().to_string())
71
+ print("-" * 60)
72
+ print(Fore.GREEN + "Summary statistics:")
73
+ print(self.data.describe().to_string())
74
+
75
+ def check_duplicates(self) -> None:
76
+ """
77
+ Check for duplicates based on the provided id column.
78
+ """
79
+ dup_count = self.data[self.id_column].duplicated().sum()
80
+ total_rows = len(self.data)
81
+ print(
82
+ Fore.RED
83
+ + f"""
84
+ WARNING! There are {dup_count:,} duplicates based on the provided id.
85
+ For context, there are {total_rows:,} rows in this dataframe.
86
+ Duplicate percentage: {(dup_count / total_rows) * 100:.2f}% To see the duplicate
87
+ values in more detail, please call the see_duplicates method
88
+ """
89
+ )
90
+
91
+ def check_data_types(self) -> None:
92
+ """
93
+ Check the data types of each column in the dataframe.
94
+ """
95
+ for col, dtype in self.data.dtypes.items():
96
+ print(f"{col}: {dtype}")
97
+
98
+ def check_unique_values(self) -> None:
99
+ """
100
+ Display the number of unique values in each column.
101
+ """
102
+ for col in self.columns:
103
+ unique_count = self.data[col].nunique()
104
+ print(f"{col}: {unique_count:,}")
105
+
106
+ def check_value_counts(self, top_n: int = 10) -> None:
107
+ """
108
+ Display the value counts of the top n values in each column.
109
+
110
+ Parameters
111
+ ----------
112
+ top_n : int, optional
113
+ Number of top values to display, by default 10.
114
+ """
115
+ for col in self.columns:
116
+ print(Fore.GREEN + f"\nColumn: {col}")
117
+ value_counts = self.data[col].value_counts().head(top_n)
118
+ for value, count in value_counts.items():
119
+ print(f"{value}: {count:,}")
120
+ if len(self.data[col].unique()) > top_n:
121
+ print("...")
122
+ print("-" * 60)
123
+
124
+ def see_duplicates(self) -> None:
125
+ """
126
+ Display the duplicate rows in the dataframe.
127
+ """
128
+ # Count occurrences of each ID
129
+ id_counts = self.data[self.id_column].value_counts()
130
+
131
+ # Filter for IDs that appear more than once
132
+ duplicate_counts = id_counts[id_counts > 1]
133
+
134
+ if duplicate_counts.empty:
135
+ print("No duplicates found.")
136
+ else:
137
+ print(
138
+ f"Duplicates found. Number of duplicates grouped by {self.id_column}:\n"
139
+ )
140
+ print(duplicate_counts)
141
+
142
+ def super_vision(self) -> None:
143
+ """
144
+ Perform a complete analysis, including all checks and prints.
145
+ """
146
+ print(Fore.CYAN + Style.BRIGHT + "=== Data Overview ===")
147
+ print(f"Total rows: {len(self.data):,}")
148
+ print(f"Total columns: {len(self.data.columns):,}")
149
+ print(f"Memory usage: {self.data.memory_usage(deep=True).sum() / 1e6:.2f} MB")
150
+ print("\n" + "=" * 50 + "\n")
151
+
152
+ print(Fore.CYAN + Style.BRIGHT + "=== First Glance ===")
153
+ self.generate_first_glance()
154
+ print("\n" + "=" * 50 + "\n")
155
+
156
+ print(
157
+ Fore.CYAN
158
+ + Style.BRIGHT
159
+ + f"=== Duplicate Checks Based on {self.id_column} ==="
160
+ )
161
+ self.check_duplicates()
162
+ print("\n" + "=" * 50 + "\n")
163
+
164
+ print(Fore.CYAN + Style.BRIGHT + "=== Quality Checks ===")
165
+ self.get_column_statistics()
166
+ print("\n" + "=" * 50 + "\n")
167
+
168
+ print(Fore.CYAN + Style.BRIGHT + "=== Value Counts (Top 10) ===")
169
+ self.check_value_counts(top_n=10)
170
+
171
+ def get_column_statistics(self) -> None:
172
+ stats: List[List[str]] = []
173
+ max_col_length = max(len(col) for col in self.columns)
174
+
175
+ for col in self.columns:
176
+ null_count = self.data[col].isnull().sum()
177
+ dtype = self.data[col].dtype
178
+ unique_count = self.data[col].nunique()
179
+ negative_count: Optional[int] = None
180
+
181
+ if col in self.numerical_columns:
182
+ negative_count = (self.data[col] < 0).sum()
183
+
184
+ # Format numbers with thousand separators
185
+ null_count_str = f"{null_count:,}".rjust(10)
186
+ unique_count_str = f"{unique_count:,}".rjust(15)
187
+
188
+ # Handle numpy.int64 and other numeric types
189
+ if negative_count is not None:
190
+ negative_count_str = f"{negative_count:,}".rjust(15)
191
+ else:
192
+ negative_count_str = "N/A".rjust(15)
193
+
194
+ stats.append(
195
+ [
196
+ col.ljust(max_col_length),
197
+ null_count_str,
198
+ str(dtype).ljust(10),
199
+ unique_count_str,
200
+ negative_count_str,
201
+ ]
202
+ )
203
+
204
+ headers = [
205
+ "Column",
206
+ "Null Count",
207
+ "Data Type",
208
+ "Unique Values",
209
+ "Negative Values",
210
+ ]
211
+ table = tabulate(stats, headers=headers, tablefmt="grid")
212
+
213
+ lines = table.split("\n")
214
+ for i, line in enumerate(lines):
215
+ if i <= 2: # Header lines including the top border
216
+ print(Fore.CYAN + line)
217
+ else:
218
+ cells = line.split("|")
219
+ if len(cells) > 1:
220
+ null_count_str = cells[2].strip()
221
+ negative_count_str = cells[5].strip()
222
+
223
+ if null_count_str != "0":
224
+ cells[2] = (
225
+ Fore.RED
226
+ + Style.BRIGHT
227
+ + null_count_str.center(14)
228
+ + Style.RESET_ALL
229
+ )
230
+
231
+ if negative_count_str not in ["0", "N/A"]:
232
+ cells[5] = (
233
+ Fore.RED
234
+ + Style.BRIGHT
235
+ + negative_count_str.center(14)
236
+ + Style.RESET_ALL
237
+ )
238
+
239
+ formatted_line = f"| {cells[1].strip().ljust(max_col_length)} | {cells[2].center(10)} | {cells[3].strip().ljust(10)} | {cells[4].strip().rjust(15)} | {cells[5].strip().rjust(15)} |"
240
+ print(Fore.WHITE + formatted_line)
241
+
242
+ print(Fore.WHITE + lines[-1]) # Bottom border
243
+
244
+ def __str__(self) -> str:
245
+ """
246
+ Return a string representation of the FirstGlance object.
247
+
248
+ Returns
249
+ -------
250
+ str
251
+ String representation of the FirstGlance object.
252
+ """
253
+ return f"FirstGlance object with shape: {self.data.shape}"