easymlops 0.0.8__tar.gz → 0.1__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.
Files changed (60) hide show
  1. {easymlops-0.0.8 → easymlops-0.1}/PKG-INFO +1 -1
  2. easymlops-0.1/README.rst +178 -0
  3. easymlops-0.1/easymlops/__init__.py +8 -0
  4. easymlops-0.1/easymlops/core/__init__.py +2 -0
  5. easymlops-0.1/easymlops/core/pipe_object.py +279 -0
  6. easymlops-0.1/easymlops/core/pipeline_object.py +46 -0
  7. easymlops-0.1/easymlops/nlp/core/__init__.py +2 -0
  8. easymlops-0.1/easymlops/nlp/core/pipe_object.py +10 -0
  9. easymlops-0.1/easymlops/nlp/core/pipeline_object.py +10 -0
  10. {easymlops-0.0.8 → easymlops-0.1}/easymlops/nlp/preprocessing.py +102 -222
  11. {easymlops-0.0.8 → easymlops-0.1}/easymlops/nlp/representation.py +91 -162
  12. easymlops-0.1/easymlops/table/callback/__init__.py +1 -0
  13. easymlops-0.1/easymlops/table/callback/check.py +492 -0
  14. easymlops-0.1/easymlops/table/classification.py +456 -0
  15. easymlops-0.1/easymlops/table/core/__init__.py +2 -0
  16. easymlops-0.1/easymlops/table/core/pipe_object.py +502 -0
  17. easymlops-0.1/easymlops/table/core/pipeline_object.py +314 -0
  18. easymlops-0.1/easymlops/table/decomposition.py +115 -0
  19. {easymlops-0.0.8/easymlops/ml → easymlops-0.1/easymlops/table}/encoding.py +97 -184
  20. easymlops-0.1/easymlops/table/ensemble.py +109 -0
  21. {easymlops-0.0.8/easymlops → easymlops-0.1/easymlops/table}/extend/normalization.py +15 -24
  22. {easymlops-0.0.8/easymlops/ml → easymlops-0.1/easymlops/table}/feature_selection/embed.py +51 -15
  23. {easymlops-0.0.8/easymlops/ml → easymlops-0.1/easymlops/table}/feature_selection/filter.py +50 -39
  24. {easymlops-0.0.8/easymlops/ml → easymlops-0.1/easymlops/table}/perfopt.py +22 -24
  25. easymlops-0.1/easymlops/table/preprocessing/__init__.py +3 -0
  26. easymlops-0.1/easymlops/table/preprocessing/bivar_operation.py +397 -0
  27. easymlops-0.1/easymlops/table/preprocessing/core.py +300 -0
  28. easymlops-0.1/easymlops/table/preprocessing/onevar_operation.py +698 -0
  29. easymlops-0.1/easymlops/table/regression.py +185 -0
  30. easymlops-0.1/easymlops/table/storage/__init__.py +1 -0
  31. easymlops-0.1/easymlops/table/storage/local_storage.py +162 -0
  32. {easymlops-0.0.8/easymlops → easymlops-0.1/easymlops/table}/utils/__init__.py +2 -0
  33. easymlops-0.1/easymlops/table/utils/cpu_mem_detector.py +45 -0
  34. {easymlops-0.0.8/easymlops → easymlops-0.1/easymlops/table}/utils/faster_lgbm_predictor_multiclass.py +5 -4
  35. {easymlops-0.0.8/easymlops → easymlops-0.1/easymlops/table}/utils/faster_lgbm_predictor_single.py +12 -8
  36. easymlops-0.1/easymlops/table/utils/pandas_utils.py +63 -0
  37. {easymlops-0.0.8 → easymlops-0.1}/easymlops.egg-info/PKG-INFO +1 -1
  38. easymlops-0.1/easymlops.egg-info/SOURCES.txt +46 -0
  39. {easymlops-0.0.8 → easymlops-0.1}/setup.py +5 -1
  40. easymlops-0.0.8/README.md +0 -3886
  41. easymlops-0.0.8/easymlops/__init__.py +0 -3
  42. easymlops-0.0.8/easymlops/base.py +0 -435
  43. easymlops-0.0.8/easymlops/ml/classification.py +0 -547
  44. easymlops-0.0.8/easymlops/ml/decomposition.py +0 -131
  45. easymlops-0.0.8/easymlops/ml/ensemble.py +0 -82
  46. easymlops-0.0.8/easymlops/ml/preprocessing.py +0 -756
  47. easymlops-0.0.8/easymlops/ml/regression.py +0 -174
  48. easymlops-0.0.8/easymlops/pipebase.py +0 -366
  49. easymlops-0.0.8/easymlops/pipeml.py +0 -5
  50. easymlops-0.0.8/easymlops/utils/cpu_mem_detector.py +0 -7
  51. easymlops-0.0.8/easymlops.egg-info/SOURCES.txt +0 -32
  52. {easymlops-0.0.8 → easymlops-0.1}/LICENSE +0 -0
  53. {easymlops-0.0.8/easymlops/ml → easymlops-0.1/easymlops/nlp}/__init__.py +0 -0
  54. {easymlops-0.0.8/easymlops/nlp → easymlops-0.1/easymlops/table}/__init__.py +0 -0
  55. {easymlops-0.0.8/easymlops → easymlops-0.1/easymlops/table}/extend/__init__.py +0 -0
  56. {easymlops-0.0.8/easymlops/ml → easymlops-0.1/easymlops/table}/feature_selection/__init__.py +0 -0
  57. {easymlops-0.0.8 → easymlops-0.1}/easymlops.egg-info/dependency_links.txt +0 -0
  58. {easymlops-0.0.8 → easymlops-0.1}/easymlops.egg-info/requires.txt +0 -0
  59. {easymlops-0.0.8 → easymlops-0.1}/easymlops.egg-info/top_level.txt +0 -0
  60. {easymlops-0.0.8 → easymlops-0.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: easymlops
3
- Version: 0.0.8
3
+ Version: 0.1
4
4
  Summary: MLOps Toolkit In Pipeline
5
5
  Home-page: https://github.com/zhulei227/EasyMLOps
6
6
  Author: zhulei227
@@ -0,0 +1,178 @@
1
+ EasyMLOps
2
+ =========
3
+
4
+ 介绍
5
+ ----
6
+
7
+ ``EasyMLOps``\ 包以\ ``Pipline``\ 的方式构建建模任务,可直接进行模型训练、预测(离线,在线),测试(离线在线预测一致性、预测性能)、特征存储、监控、分析等功能,通过外套一层Flask或FastApi即可直接部署生产,更多内容请访问\ `使用文档1>> <http://www.easymlops.com>`__
8
+ 或 `使用文档2>> <http://43.153.61.105>`__
9
+
10
+ 安装
11
+ ----
12
+
13
+ .. code:: bash
14
+
15
+ pip install easymlops
16
+
17
+ 使用
18
+ ----
19
+
20
+ .. code:: ipython3
21
+
22
+ import pandas as pd
23
+ data=pd.read_csv("./data/demo.csv")
24
+ print(data.head(5).to_markdown())
25
+
26
+
27
+ .. parsed-literal::
28
+
29
+ | | PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
30
+ |---:|--------------:|-----------:|---------:|:----------------------------------------------------|:-------|------:|--------:|--------:|:-----------------|--------:|:--------|:-----------|
31
+ | 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | nan | S |
32
+ | 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
33
+ | 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | nan | S |
34
+ | 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S |
35
+ | 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | nan | S |
36
+
37
+
38
+ .. code:: ipython3
39
+
40
+ # 拆分训练测试
41
+ x_train=data[:500]
42
+ x_test=data[500:]
43
+ y_train=x_train["Survived"]
44
+ y_test=x_test["Survived"]
45
+ del x_train["Survived"]
46
+ del x_test["Survived"]
47
+
48
+ 表格型任务
49
+ ~~~~~~~~~~
50
+
51
+ .. code:: ipython3
52
+
53
+ from easymlops import TablePipeLine
54
+ from easymlops.table.preprocessing import *
55
+ from easymlops.table.encoding import *
56
+ from easymlops.table.decomposition import *
57
+ from easymlops.table.classification import *
58
+ from easymlops.table.ensemble import *
59
+
60
+ .. code:: ipython3
61
+
62
+ table = TablePipeLine()
63
+ table.pipe(FixInput()) \
64
+ .pipe(FillNa()) \
65
+ .pipe(Parallel([OneHotEncoding(cols=["Pclass", "Sex"]), LabelEncoding(cols=["Sex", "Pclass"]),
66
+ TargetEncoding(cols=["Name", "Ticket", "Embarked", "Cabin", "Sex"], y=y_train)])) \
67
+ .pipe(Parallel([PCADecomposition(n_components=2, prefix="pca"), NMFDecomposition(n_components=2, prefix="nmf")]))\
68
+ .pipe(Parallel([LGBMClassification(y=y_train, prefix="lgbm"), LogisticRegressionClassification(y=y_train, prefix="lr")]))
69
+
70
+ table.fit(x_train)
71
+
72
+
73
+
74
+
75
+ .. parsed-literal::
76
+
77
+ <easymlops.table.core.pipeline_object.TablePipeLine at 0x213de1f9988>
78
+
79
+
80
+
81
+ .. code:: ipython3
82
+
83
+ print(table.transform(x_test).head(5).to_markdown())
84
+
85
+
86
+ .. parsed-literal::
87
+
88
+ | | lgbm_0 | lgbm_1 | lr_0 | lr_1 |
89
+ |----:|---------:|----------:|---------:|---------:|
90
+ | 500 | 0.965218 | 0.0347825 | 0.651417 | 0.348583 |
91
+ | 501 | 0.98153 | 0.0184698 | 0.65506 | 0.34494 |
92
+ | 502 | 0.979139 | 0.0208607 | 0.647266 | 0.352734 |
93
+ | 503 | 0.808796 | 0.191204 | 0.656613 | 0.343387 |
94
+ | 504 | 0.184484 | 0.815516 | 0.449149 | 0.550851 |
95
+
96
+
97
+ .. code:: ipython3
98
+
99
+ table.transform_single(x_test.to_dict("record")[0])
100
+
101
+
102
+
103
+
104
+ .. parsed-literal::
105
+
106
+ {'lgbm_0': 0.9652175316373408,
107
+ 'lgbm_1': 0.03478246836265923,
108
+ 'lr_0': 0.6514166695229407,
109
+ 'lr_1': 0.3485833304770593}
110
+
111
+
112
+
113
+ 文本特征提取
114
+ ~~~~~~~~~~~~
115
+
116
+ .. code:: ipython3
117
+
118
+ from easymlops import NLPPipeline
119
+ from easymlops.nlp.preprocessing import *
120
+ from easymlops.nlp.representation import *
121
+
122
+ .. code:: ipython3
123
+
124
+ nlp = NLPPipeline()
125
+ nlp.pipe(FixInput()) \
126
+ .pipe(FillNa()) \
127
+ .pipe(SelectCols(cols=["Name"]))\
128
+ .pipe(ReplaceDigits())\
129
+ .pipe(RemovePunctuation())\
130
+ .pipe(Parallel([Word2VecModel(embedding_size=4), FastTextModel(embedding_size=4)]))
131
+
132
+ nlp.fit(x_train)
133
+
134
+
135
+
136
+
137
+ .. parsed-literal::
138
+
139
+ <easymlops.nlp.core.pipeline_object.NLPPipeline at 0x213e69dda88>
140
+
141
+
142
+
143
+ .. code:: ipython3
144
+
145
+ print(nlp.transform(x_test).head(5).to_markdown())
146
+
147
+
148
+ .. parsed-literal::
149
+
150
+ | | w2v_Name_0 | w2v_Name_1 | w2v_Name_2 | w2v_Name_3 | fasttext_Name_0 | fasttext_Name_1 | fasttext_Name_2 | fasttext_Name_3 |
151
+ |----:|-------------:|-------------:|-------------:|-------------:|------------------:|------------------:|------------------:|------------------:|
152
+ | 500 | -0.0160304 | 0.00341222 | 0.131879 | 0.227311 | 0.0470462 | -0.00434371 | 0.0662056 | 0.0268283 |
153
+ | 501 | -0.168437 | -0.0802843 | 0.188844 | 0.0576391 | 0.00569692 | -0.00443027 | 0.00559943 | 0.0177013 |
154
+ | 502 | -0.168437 | -0.0802843 | 0.188844 | 0.0576391 | -0.00195689 | -0.0279951 | 0.00245144 | 0.0229158 |
155
+ | 503 | -0.233626 | -0.181061 | 0.165193 | 0.226518 | 0.00192385 | -0.0182485 | -0.005737 | 0.032779 |
156
+ | 504 | -0.233626 | -0.181061 | 0.165193 | 0.226518 | 0.010348 | -0.0144759 | 0.028474 | 0.00600368 |
157
+
158
+
159
+ .. code:: ipython3
160
+
161
+ nlp.transform_single(x_test.to_dict("record")[0])
162
+
163
+
164
+
165
+
166
+ .. parsed-literal::
167
+
168
+ {'w2v_Name_0': -0.01603037677705288,
169
+ 'w2v_Name_1': 0.003412220859900117,
170
+ 'w2v_Name_2': 0.13187919557094574,
171
+ 'w2v_Name_3': 0.227310910820961,
172
+ 'fasttext_Name_0': 0.04704619571566582,
173
+ 'fasttext_Name_1': -0.004343707114458084,
174
+ 'fasttext_Name_2': 0.06620561331510544,
175
+ 'fasttext_Name_3': 0.026828348636627197}
176
+
177
+
178
+
@@ -0,0 +1,8 @@
1
+ __version__ = "0.1"
2
+
3
+ from .table.core import TablePipeLine
4
+ from .nlp.core import NLPPipeline
5
+
6
+ import warnings
7
+
8
+ warnings.filterwarnings("ignore")
@@ -0,0 +1,2 @@
1
+ from .pipe_object import *
2
+ from .pipeline_object import *
@@ -0,0 +1,279 @@
1
+ import warnings
2
+
3
+ warnings.filterwarnings("ignore")
4
+
5
+
6
+ class PipeObjectBase(object):
7
+ """
8
+ 所有Pipe以及PipeLine的父类
9
+ """
10
+
11
+ def __init__(self, name=None, **kwargs):
12
+ """
13
+ :param name: 该pipe模块名称,默认self.__class__
14
+ :param kwargs:
15
+ """
16
+ super().__init__(**kwargs)
17
+ if name is None:
18
+ name = self.__class__
19
+ self.name = name
20
+
21
+ def fit(self, x, **kwargs):
22
+ """
23
+ fit:依次调用before_fit,_fit,after_fit
24
+
25
+ :param x:
26
+ :param kwargs:
27
+ :return:
28
+ """
29
+ self.udf_fit(self.before_fit(x, **kwargs), **kwargs)
30
+ return self.after_fit(x, **kwargs)
31
+
32
+ def before_fit(self, x, **kwargs):
33
+ """
34
+ :param x: 入参x
35
+
36
+ :param kwargs:
37
+ :return:
38
+ """
39
+ return x
40
+
41
+ def udf_fit(self, x, **kwargs):
42
+ """
43
+ 用户自己实现的fit模块
44
+
45
+ :param x: 输入x
46
+ :param kwargs:
47
+ :return:
48
+ """
49
+ return self
50
+
51
+ def after_fit(self, x=None, **kwargs):
52
+ """
53
+ 在udf_fit之后被调用
54
+
55
+ :param x: 入参x
56
+ :param kwargs:
57
+ :return:
58
+ """
59
+ return self
60
+
61
+ def transform(self, x, **kwargs):
62
+ """
63
+ 用于批量数据的transform:依次调用before_transform,udf_transform,after_transform
64
+
65
+ :param x:
66
+ :param kwargs:
67
+ :return:
68
+ """
69
+ return self.after_transform(self.udf_transform(self.before_transform(x, **kwargs), **kwargs), **kwargs)
70
+
71
+ def before_transform(self, x, **kwargs):
72
+ """
73
+ 在udf_transform之前被调用,并将return的结果,作为udf_transform的x
74
+
75
+ :param x:
76
+ :param kwargs:
77
+ :return:
78
+ """
79
+ return x
80
+
81
+ def udf_transform(self, x, **kwargs):
82
+ """
83
+ 用户自定义transform
84
+
85
+ :param x:
86
+ :param kwargs:
87
+ :return:
88
+ """
89
+ return x
90
+
91
+ def after_transform(self, x, **kwargs):
92
+ """
93
+ 在udf_transform之后被调用
94
+
95
+ :param x:
96
+ :param kwargs:
97
+ :return:
98
+ """
99
+ return x
100
+
101
+ def transform_single(self, x, **kwargs):
102
+ """
103
+ 用于单条数据的transform函数:调用顺序before_transform_single,_transform_single,after_transform_single
104
+
105
+ :param x:
106
+ :param kwargs:
107
+ :return:
108
+ """
109
+ return self.after_transform_single(
110
+ self.udf_transform_single(self.before_transform_single(x, **kwargs), **kwargs), **kwargs)
111
+
112
+ def before_transform_single(self, x, **kwargs):
113
+ """
114
+ 在udf_transform_single之前被调用
115
+
116
+ :param x:
117
+ :param kwargs:
118
+ :return:
119
+ """
120
+ return x
121
+
122
+ def udf_transform_single(self, x, **kwargs):
123
+ """
124
+ 用户自定义单条数据预测实现
125
+
126
+ :param x:
127
+ :param kwargs:
128
+ :return:
129
+ """
130
+ return x
131
+
132
+ def after_transform_single(self, x, **kwargs):
133
+ """
134
+ 在udf_transform_single之后被调用
135
+
136
+ :param x:
137
+ :param kwargs:
138
+ :return:
139
+ """
140
+ return x
141
+
142
+ def get_params(self):
143
+ """
144
+ return 当前pipe需要被保存的所有参数
145
+
146
+ :return:
147
+ """
148
+ return self.udf_get_params()
149
+
150
+ def udf_get_params(self):
151
+ """
152
+ return 前pipe需要被保存的参数(不需要考虑父类)
153
+
154
+ :return:
155
+ """
156
+ return {"name": self.name}
157
+
158
+ def set_params(self, params):
159
+ """
160
+ 恢复所有参数
161
+
162
+ :param params:
163
+ :return:
164
+ """
165
+ self.udf_set_params(params)
166
+
167
+ def udf_set_params(self, params):
168
+ """
169
+ 恢复参数(不需要考虑父类) \n
170
+
171
+ :param params:
172
+ :return:
173
+ """
174
+ self.name = params["name"]
175
+
176
+ def callback(self, callback_func, data, return_callback_result=False, *args, **kwargs):
177
+ """
178
+ 回调函数接口 \n
179
+
180
+ :param callback_func: 回调函数
181
+ :param data: 回调入参x
182
+ :param return_callback_result: 是否返回回调函数结果
183
+ :param args:
184
+ :param kwargs:
185
+ :return:
186
+ """
187
+ result = callback_func(self, data, *args, **kwargs)
188
+ if return_callback_result:
189
+ return result
190
+
191
+ def set_branch_pipe(self, pipe_obj):
192
+ """
193
+ 挂载支线的pipe模块,不影响主线的执行任务(支线的输出结果不会并入到主线中),比如存储监控模块等; \n
194
+ branch_pipe的fit/transform/transform_single运行均在当前挂载对象之后 \n
195
+
196
+ :param pipe_obj:
197
+ :return:
198
+ """
199
+ pass
200
+
201
+ def get_branch_pipe(self, index):
202
+ """
203
+ 获取到对应的模块,注意branch pipe可以有多个,所以通过index索引 \n
204
+
205
+ :param index:
206
+ :return:
207
+ """
208
+ raise Exception("need to implement!")
209
+
210
+ def remove_branch_pipe(self, index):
211
+ """
212
+ 移除指定的branch pipe
213
+
214
+ :param index:
215
+ :return:
216
+ """
217
+ raise Exception("need to implement!")
218
+
219
+ def set_master_pipe(self, master_pipe):
220
+ """
221
+ 当前pipe作为branch时所绑定的master的pipe
222
+
223
+ :param master_pipe:
224
+ :return:
225
+ """
226
+ raise Exception("need to implement!")
227
+
228
+ def get_master_pipe(self):
229
+ """
230
+ 当前pipe作为branch时所绑定的master的pipe
231
+
232
+ :return:
233
+ """
234
+ raise Exception("need to implement!")
235
+
236
+ def set_parent_pipe(self, parent_pipe=None):
237
+ """
238
+ 设置父类pipe模块,有时候需要在内部回溯之前的transform操作
239
+
240
+ :param parent_pipe:
241
+ :return:
242
+ """
243
+ raise Exception("need to implement!")
244
+
245
+ def get_parent_pipe(self):
246
+ """
247
+ 返回父类pipe模块
248
+
249
+ :return:
250
+ """
251
+ raise Exception("need to implement!")
252
+
253
+ def get_all_parent_pipes(self):
254
+ """
255
+ 返回所有父类(从头到尾的顺序)
256
+
257
+ :return:
258
+ """
259
+ raise Exception("need to implement!")
260
+
261
+ def transform_all_parent(self, x, **kwargs):
262
+ """
263
+ 顺序运行当前pipe之前父类的transform
264
+
265
+ :param x:
266
+ :param kwargs:
267
+ :return:
268
+ """
269
+ raise Exception("need to implement!")
270
+
271
+ def transform_single_all_parent(self, x, **kwargs):
272
+ """
273
+ 顺序运行当前pipe之前父类的transform_single
274
+
275
+ :param x:
276
+ :param kwargs:
277
+ :return:
278
+ """
279
+ raise Exception("need to implement!")
@@ -0,0 +1,46 @@
1
+ from .pipe_object import *
2
+
3
+
4
+ class PipeLineBase(PipeObjectBase):
5
+ """
6
+ PipeLine设计为Pipe的子类,目的是为了方便嵌套使用;这个类名称虽为PipeLine的Base,但更多是起一个规范作用
7
+ """
8
+
9
+ def __init__(self, **kwargs):
10
+ super().__init__(**kwargs)
11
+
12
+ def auto_test(self, x):
13
+ """
14
+ 测试功能
15
+
16
+ :param x:
17
+ :return:
18
+ """
19
+ raise Exception("need to implement!")
20
+
21
+ def save(self, path):
22
+ """
23
+ 保存模型
24
+
25
+ :param path:
26
+ :return:
27
+ """
28
+ raise Exception("need to implement!")
29
+
30
+ def load(self, path):
31
+ """
32
+ 加载模型
33
+
34
+ :param path:
35
+ :return:
36
+ """
37
+ raise Exception("need to implement!")
38
+
39
+ def pipe(self, module):
40
+ """
41
+ 加入pipe模块
42
+
43
+ :param module:
44
+ :return:
45
+ """
46
+ raise Exception("need to implement!")
@@ -0,0 +1,2 @@
1
+ from .pipe_object import *
2
+ from .pipeline_object import *
@@ -0,0 +1,10 @@
1
+ from easymlops.table.core import TablePipeObjectBase
2
+
3
+
4
+ class NLPPipeObjectBase(TablePipeObjectBase):
5
+ """
6
+ 由于NLP任务也可以存放于表格数据中,这里借用pandas dataframe做NLP任务
7
+ """
8
+
9
+ def udf_get_params(self):
10
+ return {}
@@ -0,0 +1,10 @@
1
+ from easymlops.table.core import TablePipeLine
2
+
3
+
4
+ class NLPPipeline(TablePipeLine):
5
+ """
6
+ 借用PipeTable做相关任务
7
+ """
8
+
9
+ def udf_get_params(self):
10
+ return {}