写给 Python 开发者的 10 条机器学习建议
作者 | Pratik Bhavsar
译者 | 明明如月,责编 | 夕颜
出品 | CSDN(ID:CSDNnews)
有时候,作为一个数据科学家,我们常常忘记了初心。我们首先是一个开发者,然后才是研究人员,最后才可能是数学家。我们的首要职责是快速找到无 bug 的解决方案。
我们能做模型并不意味着我们就是神。这并不是编写垃圾代码的理由。
自从我开始学习机器学习以来,我犯了很多错误。因此我想把我认 机器学习工程中最常用的技能分享出来。在我看来,这也是目前这个行业最缺乏的技能。
我称他们为不懂软件的数据科学家,因为他们中很大一部分人都没有系统地学习过计算机科学课程。而我自己也是如此。????
如果要选择雇佣一个伟大的数据科学家和一个伟大的机器学习工程师,我会选择雇佣后者。
下面开始我的分享。
学习编写抽象类
一旦开始编写抽象类,你就能体会到它给带来的好处。抽象类强制子类使用相同的方法和方法名称。许多人在同一个项目上工作, 如果每个人去定义不同的方法,这样做没有必要也很容易造成混乱。
1import os2from abc import ABCMeta, abstractmethod345class DataProcessor(metaclass=ABCMeta):6 """Base processor to be used for all preparation."""7 def __init__(self, input_directory, output_directory):8 self.input_directory = input_directory9 self.output_directory = output_directory
10
11 @abstractmethod
12 def read(self):
13 """Read raw data."""
14
15 @abstractmethod
16 def process(self):
17 """Processes raw data. This step should create the raw dataframe with all the required features. Shouldn't implement statistical or text cleaning."""
18
19 @abstractmethod
20 def save(self):
21 """Saves processed data."""
22
23
24class Trainer(metaclass=ABCMeta):
25 """Base trainer to be used for all models."""
26
27 def __init__(self, directory):
28 self.directory = directory
29 self.model_directory = os.path.join(directory, 'models')
30
31 @abstractmethod
32 def preprocess(self):
33 """This takes the preprocessed data and returns clean data. This is more about statistical or text cleaning."""
34
35 @abstractmethod
36 def set_model(self):
37 """Define model here."""
38
39 @abstractmethod
40 def fit_model(self):
41 """This takes the vectorised data and returns a trained model."""
42
43 @abstractmethod
44 def generate_metrics(self):
45 """Generates metric with trained model and test data."""
46
47 @abstractmethod
48 def save_model(self, model_name):
49 """This method saves the model in our required format."""
50
51
52class Predict(metaclass=ABCMeta):
53 """Base predictor to be used for all models."""
54
55 def __init__(self, directory):
56 self.directory = directory
57 self.model_directory = os.path.join(directory, 'models')
58
59 @abstractmethod
60 def load_model(self):
61 """Load model here."""
62
63 @abstractmethod
64 def preprocess(self):
65 """This takes the raw data and returns clean data for prediction."""
66
67 @abstractmethod
68 def predict(self):
69 """This is used for prediction."""
70
71
72class BaseDB(metaclass=ABCMeta):
73 """ Base database class to be used for all DB connectors."""
74 @abstractmethod
75 def get_connection(self):
76 """This creates a new DB connection."""
77 @abstractmethod
78 def close_connection(self):
79 """This closes the DB connection."""
固定随机数种子
实验的可重复性是非常重要的,随机数种子是我们的敌人。要特别注重随机数种子的设置,否则会导致不同的训练 / 测试数据的分裂和神经网络中不同权重的初始化。这些最终会导致结果的不一致。
1def set_seed(args):
2 random.seed(args.seed)
3 np.random.seed(args.seed)
4 torch.manual_seed(args.seed)
5 if args.n_gpu > 0:
6 torch.cuda.manual_seed_all(args.seed)
先加载少量数据
如果你的数据量太大,并且你正在处理比如清理数据或建模等后续编码时,请使用 `nrows `来避免每次都加载大量数据。当你只想测试代码而不是想实际运行整个程序时,可以使用此方法。
非常适合在你本地电脑配置不足以处理那么大的数据量, 但你喜欢用 Jupyter/VS code/Atom 开发的场景。
1f_train = pd.read_csv(‘train.csv’, nrows=1000)
预测失败 (成熟开发人员的标志)
总是检查数据中的 NA(缺失值),因为这些数据可能会造成一些问题。即使你当前的数据没有,并不意味着它不会在未来的训练循环中出现。所以无论如何都要留意这个问题。
1print(len(df))
2df.isna().sum()
3df.dropna()
4print(len(df))
显示处理进度
在处理大数据时,如果能知道还需要多少时间可以处理完,能够了解当前的进度非常重要。
方案1:tqdm
1from tqdm import tqdm2import time34tqdm.pandas()56df['col'] = df['col'].progress_apply(lambda x: x**2)78text = ""9for char in tqdm(["a", "b", "c", "d"]):
10 time.sleep(0.25)
11 text = text + char
方案2:fastprogress
1from fastprogress.fastprogress import master_bar, progress_bar
2from time import sleep
3mb = master_bar(range(10))
4for i in mb:
5 for j in progress_bar(range(100), parent=mb):
6 sleep(0.01)
7 mb.child.comment = f'second bar stat'
8 mb.first_bar.comment = f'first bar stat'
9 mb.write(f'Finished loop {i}.')
解决 Pandas 慢的问题
如果你用过 pandas,你就会知道有时候它的速度有多慢ーー尤其在团队合作时。与其绞尽脑汁去寻找加速解决方案,不如通过改变一行代码来使用 modin。
1import modin.pandas as pd记录函数的执行时间
并不是所有的函数都生来平等。
即使全部代码都运行正常,也并不能意味着你写出了一手好代码。一些软错误实际上会使你的代码变慢,因此有必要找到它们。使用此装饰器记录函数的时间。
1import time23def timing(f):4 """Decorator for timing functions5 Usage:6 @timing7 def function(a):8 pass9 """
10
11
12 @wraps(f)
13 def wrapper(*args, **kwargs):
14 start = time.time()
15 result = f(*args, **kwargs)
16 end = time.time()
17 print('function:%r took: %2.2f sec' % (f.__name__, end - start))
18 return result
19 return wrapp
不要在云上烧钱
没有人喜欢浪费云资源的工程师。
我们的一些实验可能会持续数小时。跟踪它并在完成后关闭云实例是很困难的。我自己也犯过错误,也看到过有些人会有连续几天不关机的情况。
这种情况经常会发生在我们周五上班,留下一些东西运行,直到周一回来才意识到????。
只要在执行结束时调用这个函数,你的屁股就再也不会着火了!
使用 `try` 和 `except` 来包裹 main 函数,一旦发生异常,服务器就不会再运行。我就处理过类似的案例????
让我们多一点责任感,低碳环保从我做起。????
1import os23def run_command(cmd):4 return os.system(cmd)56def shutdown(seconds=0, os='linux'):7 """Shutdown system after seconds given. Useful for shutting EC2 to save costs."""8 if os == 'linux':9 run_command('sudo shutdown -h -t sec %s' % seconds)
10 elif os == 'windows':
11 run_command('shutdown -s -t %s' % seconds)
创建和保存报告
在建模的某个特定点之后,所有的深刻见解都来自于对误差和度量的分析。确保为自己和上司创建并保存格式正确的报告。
不管怎样,管理层都喜欢报告,不是吗?????
1import json2import os34from sklearn.metrics import (accuracy_score, classification_report,5 confusion_matrix, f1_score, fbeta_score)67def get_metrics(y, y_pred, beta=2, average_method='macro', y_encoder=None):8 if y_encoder:9 y = y_encoder.inverse_transform(y)
10 y_pred = y_encoder.inverse_transform(y_pred)
11 return {
12 'accuracy': round(accuracy_score(y, y_pred), 4),
13 'f1_score_macro': round(f1_score(y, y_pred, average=average_method), 4),
14 'fbeta_score_macro': round(fbeta_score(y, y_pred, beta, average=average_method), 4),
15 'report': classification_report(y, y_pred, output_dict=True),
16 'report_csv': classification_report(y, y_pred, output_dict=False).replace('\n','\r\n')
17 }
18
19
20def save_metrics(metrics: dict, model_directory, file_name):
21 path = os.path.join(model_directory, file_name + '_report.txt')
22 classification_report_to_csv(metrics['report_csv'], path)
23 metrics.pop('report_csv')
24 path = os.path.join(model_directory, file_name + '_metrics.json')
25 json.dump(metrics, open(path, 'w'), indent=4)
写出一手好 API
结果不好,一切都不好。
你可以做很好的数据清理和建模,但是你仍然可以在最后制造巨大的混乱。通过我与人打交道的经验告诉我,许多人不清楚如何编写好的 api、文档和服务器设置。我将很快写另一篇关于这方面的文章,但是先让我简要分享一部分。
下面的方法适用于经典的机器学习 和 深度学习部署,在不太高的负载下(比如1000 / min)。
见识下这个组合: Fastapi + uvicorn + gunicorn
最快的ー用 fastapi 编写 API,因为这 是最快的,原因参见这篇文章。
文档ー在 fastapi 中编写 API 为我们提供了 http: url/docs 上的免费文档和测试端点,当我们更改代码时,fastapi 会自动生成和更新这些文档。
workerー使用 gunicorn 服务器部署 API,因为 gunicorn 具有启动多于1个 worker,而且你应该保留至少 2 个worker。
运行这些命令来使用 4 个 worker 部署。可以通过负载测试优化 worker 数量。
1pip install fastapi uvicorn gunicorn
2gunicorn -w 4 -k uvicorn.workers.UvicornH11Worker main:app
原文链接:
https://towardsdatascience.com/10-great-ml-practices-for-python-developers-b089eefc18fc
本文为CSDN翻译文章,转载请注明出处。
【End】
《原力计划【第二季】- 学习力挑战》正式开始!
即日起至 3月21日,千万流量支持原创作者,更有专属【勋章】等你来挑战
推荐阅读
☞微信七年「封链」史
☞倾家荡产、隐私全无?独家揭秘撞库攻击!
☞Javascript函数之深入浅出递归思想,附案例与代码!
☞华为、阿里员工在听的英语资源,即将过期,请自取
☞不看就亏系列!这里有完整的 Hadoop 集群搭建教程,和最易懂的 Hadoop 概念!| 附代码
☞智能合约编写之Solidity的基础特性
你点的每一个在看,我认真当成了喜欢
写给 Python 开发者的 10 条机器学习建议相关推荐
- 写给开发者的 10 条机器学习建议
作者 | Pratik Bhavsar 译者 | 明明如月,责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 有时候,作为一个数据科学家,我们常常忘记了初心.我们首先是一个开发者,然后才 ...
- 成为最差开发者的10条建议
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 这里有个[1024]红包等你来领取 昨天在devto上面 ...
- 老程序员的10条中肯建议
以下十条建议是一个老程序员给出的建议,句句中肯,希望能引起你的思考,而不是笑笑就过去了.觉得在理,不妨随手点赞收藏转发分享,谢谢~ 程序员的二八定律: 程序员的二八定律(这个图是我自己做的) 1.想清 ...
- 劝人学医,天打雷劈?给医学新生的 10 条入学建议
又来到新一年的九月,又是新一批医学生们满怀憧憬入学的日子. 作为如今的医生,曾经的医学生,你对医学新生们有什么 实用的建议? ▶︎ 现在退学还来得及( ?????) [外链图片转存失败,源站可能有防盗 ...
- 凯文凯利10条人生建议,送给迷茫的你!(上)
Most Interesting Man In The World. 名人作家 Kevin Kelly (KK) 凯文凯利,在他今年的70岁生日时,在网站分享了103条生活建议送给读者,都非常的实用有 ...
- 写给Python开发者:机器学习十大必备技能
作者 | Pratik Bhavsar 译者 | 明明如月,编辑 | 夕颜 来源 | CSDN(ID:CSDNnews) 有时候,作为一个数据科学家,我们常常忘记了初心.我们首先是一个开发者,然后才 ...
- 10年老司机,写好 Python 代码的几条重要技巧!
来源:NightTeam-韦世东 程序设计的好与坏,早在我们青葱岁月时就接触过了,只是那是并不知道这竟如此重要.能够立即改善程序设计.写出"好"代码的知识有以下几点: •面向对象五 ...
- 写好 Python 代码的几条原则
程序设计的好与坏,早在我们青葱岁月时就接触过了,只是那是并不知道这竟如此重要.能够立即改善程序设计.写出"好"代码的知识有以下几点: •面向对象五个基本原则: •常见的三种架构: ...
- 成为更优秀开发者的10条途径
转自 http://blog.jobbole.com/40931/ 读他人的代码 -- Scott Hanselmann 读他人的代码,并从中学习.你会适时得到提升,因为你容易学到其他开发者是如何处理 ...
最新文章
- 微服务发现与注册之Eureka源码分析
- 快速入门分库分表概念原理
- 《Visual Studio程序员箴言》笔记
- Windows 7安装MySQL最后一步提示错误“mysql 终结点映射器中没有更多的终结点可用的” 解决方法...
- Oracle安装完成后如何创建表空间及用户
- UEditor 使用setContent()遇到的奇葩问题
- 关于产品的一些交互理念
- Jquery的DOM
- Android应用开发控件——Gallery和ImageSwitcher
- nuxt.js 引入第三方插件报window is not defined
- 华为手机多久可以摆脱美国技术依赖?任正非放出豪言!
- Windows平台下tomcat+java的web程序持续占cpu问题调试
- hexo -d 部署的时候报错 FATAL Something's wrong Template render error: expected variable
- 看!Mac上好用的流程图软件就是它
- python二元一次方程组用鸡兔同笼的思路来写编程_二元一次方程组的应用一鸡兔同笼问题...
- 使用office tool plus清除office激活状态
- 单片机控制气压海拔模块BMP180之模块化编程(持续更新中)
- 彻底掌握NodeJS中如何使用Sequelize
- Mysql错误Error writing file ‘/home/tmp/xxxx’ (Errcode: 28)的解决方法
- 编程初学者看不懂程序的几点建议
热门文章
- 关于4A系统(我对4A系统的维护的理解)
- 使用证书创建request请求
- CSS background 属性
- [论文阅读] Unifying Global-Local Representations in Salient Object Detection with Transformer
- NVIDIA-SMI has failed because it couldn’t communicate with the NVIDIA driver.
- Windows10 任务栏图标如何居中
- 网站地图生成器_10个相见恨晚的PPT网站 让你看一眼就心动
- LINUX 下的逆向 用 IDA 分析,样本逆向中系统调用的识别方法
- python基本语言元素是_Python-基本语法元素
- 电泳涂装行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)