写给Python开发者:机器学习十大必备技能
云栖号:https://yqh.aliyun.com
第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策!
有时候,作为一个数据科学家,我们常常忘记了初心。我们首先是一个开发者,然后才是研究人员,最后才可能是数学家。我们的首要职责是快速找到无 bug 的解决方案。
我们能做模型并不意味着我们就是神。这并不是编写垃圾代码的理由。
自从我开始学习机器学习以来,我犯了很多错误。因此我想把我认为机器学习工程中最常用的技能分享出来。在我看来,这也是目前这个行业最缺乏的技能。
我称他们为不懂软件的数据科学家,因为他们中很大一部分人都没有系统地学习过计算机科学课程。而我自己也是如此。
如果要选择雇佣一个伟大的数据科学家和一个伟大的机器学习工程师,我会选择雇佣后者。
下面开始我的分享。
学习编写抽象类
一旦开始编写抽象类,你就能体会到它给带来的好处。抽象类强制子类使用相同的方法和方法名称。许多人在同一个项目上工作, 如果每个人去定义不同的方法,这样做没有必要也很容易造成混乱。
1import os 2from abc import ABCMeta, abstractmethod 3 4 5class 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_directory 9 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 tqdm 2import time 3 4tqdm.pandas() 5 6df['col'] = df['col'].progress_apply(lambda x: x**2) 7 8text = "" 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 time 2 3def timing(f): 4 """Decorator for timing functions 5 Usage: 6 @timing 7 def function(a): 8 pass 9 """ 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 os 2 3def run_command(cmd): 4 return os.system(cmd) 5 6def 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 json 2import os 3 4from sklearn.metrics import (accuracy_score, classification_report, 5 confusion_matrix, f1_score, fbeta_score) 6 7def 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://c.tb.cn/F3.Z8gvnK
更多系列直播,请关注 云栖号在线课堂 圈子 及时了解课程更新动态!
原文发布时间:2020-03-09
本文作者:Pratik Bhavsar
本文来自:“AI科技大本营公众号”,了解相关信息可以关注“AI科技大本营”
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
数字化转型如何影响CIO角色?
云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 如果你认为CIO的角色和职责在过去10年中没有发生变化,那你只说对一部分。在HMG Strategy 2020年硅谷全球创新峰会中,高管小组讨论并辩论了数字化转型对CIO角色的影响,他们都认同的一件事是,CIO过去一直负责的事情并没有消失。 NetApp公司高级副总裁兼CIO William Miller表示:“CIO的旧角色已经不复存在。随着我们转向数字化销售活动(而不是面对面销售活动),业务转型将继续进行。”但是,在承担这些新职责的过程中,不要指望过去CIO负责的工作会神奇地消失。 Miller说:“尽管CIO现在开始管理基础设施、减少合约并试图为客户提供前进的道路,但他们没有放弃任何传统的CIO角色。”该评论引发C级高管听众的笑声,他们被要求承担更多的职责,同时还必须承担在数字化转型前的所有工作。 Miller的建议?“你越感到不舒服,就会越可能获得成功。” e.l.f. Cosmetics公司数字副总裁Ekta Chopra负...
- 下一篇
关于Java序列化的问题你真的会吗?
引言 在持久化数据对象的时候我们很少使用Java序列化,而是使用数据库等方式来实现。但是在我看来,Java 序列化是一个很重要的内容,序列化不仅可以保存对象到磁盘进行持久化,还可以通过网络传输。在平时的面试当中,序列化也是经常被谈及的一块内容。 谈到序列化时,大家可能知道将类实现Serializable接口就可以达到序列化的目的,但当看到关于序列化的面试题时我们却常常一脸懵逼。 1)可序列化接口和可外部接口的区别是什么? 2)序列化时,你希望某些成员不要序列化?该如何实现? 3)什么是 serialVersionUID ?如果不定义serialVersionUID,会发生什么? 是不是突然发现我们对这些问题其实都还存在很多疑惑?本文将总结一些Java序列化的常见问题,并且通过demo来进行测试和解答。 问题一:什么是 Java 序列化? 序列化是把对象改成可以存到磁盘或通过网络发送到其它运行中的 Java 虚拟机的二进制格式的过程,并可以通过反序列化恢复对象状态。Java 序列化API给开发人员提供了一个标准机制:通过实现 java.io.Serializable 或者 java.io...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度