Python开发者宝典:10个有用的机器学习实践!

译文
开发 后端 机器学习
您可能是名数据科学家,但本质上仍是开发者。这意味着您的编程技巧应该很熟练。请遵循以下10条提示,确保快速交付没有错误的机器学习解决方案。

[[327915]]

【51CTO.com快译】

有时作为数据科学家,我们忘了自己是干什么的。我们主要是开发者,然后是研究者,最后可能是数学家。我们的首要责任是快速开发没有错误的解决方案。

就因为我们能构建模型并不意味着我们就是神,这没有给我们编写垃圾代码的自由。

自一开始,我犯过很多错误,想透露一下我认为是机器学习工程最常见的技能。我认为,这也是眼下业界最缺乏的技能。

我称他们为不懂软件的数据科学家,因为他们中很多人都是不是计算机专业科班出身的工程师。而我本人就是那样。

如果要聘一位优秀的数据科学家和一位优秀的机器学习工程师,我会聘后者。

1. 学习编写抽象类。

一旦你开始编写抽象类,就知道可以如何让你的代码库清晰许多。它们强制执行同样的方法和方法名称。如果很多人从事同一个项目,每个人会开始采用不同的方法。这会造成严重的混乱。 

import os  
from abc import ABCMeta, abstractmethod  
class DataProcessor(metaclass=ABCMeta):  
"""Base processor to be used for all preparation."""  
def __init__(self, input_directory, output_directory):  
self.input_directory = input_directory  
self.output_directory = output_directory  
@abstractmethod  
def read(self):  
"""Read raw data."""  
@abstractmethod  
def process(self):  
"""Processes raw data. This step should create the raw dataframe with all the required features. Shouldn't implement statistical or text cleaning."""  
@abstractmethod  
def save(self):  
"""Saves processed data."""  
class Trainer(metaclass=ABCMeta):  
"""Base trainer to be used for all models."""  
def __init__(self, directory):  
self.directory = directory  
self.model_directory = os.path.join(directory, 'models' 
@abstractmethod  
def preprocess(self):  
"""This takes the preprocessed data and returns clean data. This is more about statistical or text cleaning."""  
@abstractmethod  
def set_model(self):  
"""Define model here."""  
@abstractmethod  
def fit_model(self):  
"""This takes the vectorised data and returns a trained model."""  
@abstractmethod  
def generate_metrics(self):  
"""Generates metric with trained model and test data.""" 
@abstractmethod  
def save_model(self, model_name):  
"""This method saves the model in our required format."""  
class Predict(metaclass=ABCMeta):  
"""Base predictor to be used for all models.""" 
def __init__(self, directory):  
self.directory = directory  
self.model_directory = os.path.join(directory, 'models' 
@abstractmethod  
def load_model(self):  
"""Load model here."""  
@abstractmethod  
def preprocess(self):  
"""This takes the raw data and returns clean data for prediction.""" 
@abstractmethod  
def predict(self):  
"""This is used for prediction."""  
class BaseDB(metaclass=ABCMeta): 
""" Base database class to be used for all DB connectors."""  
@abstractmethod  
def get_connection(self):  
"""This creates a new DB connection."""  
@abstractmethod  
def close_connection(self):  
"""This closes the DB connection."""  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.

2. 搞定最上面的seed。

试验的可重现性很重要,而seed是大敌。处理好seed。不然,它会导致神经网络中训练/测试数据的不同分隔和权重的不同初始化。这会导致结果不一致。 

def set_seed(args):  
random.seed(args.seed)  
np.random.seed(args.seed)  
torch.manual_seed(args.seed)  
if args.n_gpu > 0:  
torch.cuda.manual_seed_all(args.seed)  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

3. 从几行入手。

如果你的数据太庞大,又处在编程的后期阶段(比如清理数据或建模),就使用nrows避免每次加载庞大数据。如果你只想测试代码、不想实际运行全部代码,就使用这招。

如果你的本地PC配置不足以处理数据大小,这一招很有用,但你喜欢在Jupyter/VS code/Atom上进行本地开发。 

df_train = pd.read_csv(‘train.csv’, nrows=1000) 
  • 1.

4. 预料失败(这是成熟开发者的标志)。

始终检查数据中的NA,因为这些会在以后给你带来问题。即便你目前的数据没有任何NA,也并不意味着它不会出现在将来的再训练循环中。所以无论如何要检查。 

print(len(df))  
df.isna().sum()  
df.dropna()  
print(len(df))  
  • 1.
  • 2.
  • 3.
  • 4.

5. 显示处理的进度。

你在处理庞大数据时,知道要花多少时间、处于整个处理过程中的哪个环节,绝对让人安心。

方法1 — tqdm 

from tqdm import tqdm  
import time  
tqdm.pandas()  
df['col'] = df['col'].progress_apply(lambda x: x**2)  
text = ""  
for char in tqdm(["a""b""c""d"]):  
time.sleep(0.25)  
text = text + char  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

方法2 — fastprogress 

from fastprogress.fastprogress import master_bar, progress_bar  
from time import sleep  
mb = master_bar(range(10))  
for i in mb:  
for j in progress_bar(range(100), parent=mb):  
sleep(0.01)  
mb.child.comment = f'second bar stat'  
mb.first_bar.comment = f'first bar stat'  
mb.write(f'Finished loop {i}.' 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

6. Pandas可能很慢。

如果你接触过pandas,就知道它有时会变得多慢,尤其是执行groupby操作时。不必绞尽脑汁为提速寻找“出色的”解决方案,只要更改一行代码,使用modin就行。 

import modin.pandas as pd 
  • 1.

7. 为函数计时。

不是所有函数都是一样的。

即便全部代码没问题,也不意味着你编写的是出色的代码。一些软错误实际上会使代码运行起来比较慢,有必要把它们找出来。使用这个装饰器来记录函数的时间。 

import time  
def timing(f):  
"""Decorator for timing functions  
Usage:  
@timing  
def function(a):  
pass 
"" 
@wraps(f)  
def wrapper(*args, **kwargs):  
start = time.time()  
result = f(*args, **kwargs)  
end = time.time()  
print('function:%r took: %2.2f sec' % (f.__name__, end - start)) 
return result  
return wrapper  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

8. 别把钱耗费在云上。

没人喜欢浪费云资源的工程师。

一些试验可能持续数小时。很难跟踪试验、云实例用完后关闭。本人就犯过这种错误,也见过有人任由实例运行数天。

只是在执行结束时调用该函数,永远不会有麻烦!

但用try包主代码,并用except再采用这种方法,那样如果出现了错误,服务器不会处于继续运行的状态。是的,我也处理过这种情况。

不妨负责任一点,别生成二氧化碳了。 

import os  
def run_command(cmd):  
return os.system(cmd)  
def shutdown(seconds=0, os='linux'):  
"""Shutdown system after seconds given. Useful for shutting EC2 to save costs."""  
if os == 'linux' 
run_command('sudo shutdown -h -t sec %s' % seconds)  
elif os == 'windows' 
run_command('shutdown -s -t %s' % seconds)  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

9. 创建和保存报告。

建模中某个点之后,所有宝贵的信息只来自错误和度量分析。确保为你自己和你的经理创建和保存格式完好的报告。

不管怎样,管理层爱看报告,不是吗? 

import json  
import os  
from sklearn.metrics import (accuracy_score, classification_report,  
confusion_matrix, f1_score, fbeta_score)  
def get_metrics(y, y_pred, beta=2, average_method='macro', y_encoder=None):  
if y_encoder:  
y = y_encoder.inverse_transform(y)  
y_pred = y_encoder.inverse_transform(y_pred)  
return {  
'accuracy': round(accuracy_score(y, y_pred), 4),  
'f1_score_macro': round(f1_score(y, y_pred, average=average_method), 4),  
'fbeta_score_macro': round(fbeta_score(y, y_pred, beta, average=average_method), 4),  
'report': classification_report(y, y_pred, output_dict=True),  
'report_csv': classification_report(y, y_pred, output_dict=False).replace('\n','\r\n' 
 
def save_metrics(metrics: dict, model_directory, file_name):  
path = os.path.join(model_directory, file_name + '_report.txt' 
classification_report_to_csv(metrics['report_csv'], path)  
metrics.pop('report_csv' 
path = os.path.join(model_directory, file_name + '_metrics.json' 
json.dump(metrics, open(path, 'w'), indent=4)  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

10. 编写出色的API。

所有结尾不好的代码都是不好的。

你的数据清理和建模可能做得很好,但最后还是会造成大混乱。经验告诉我,许多人不清楚如何编写优秀的API、文档和服务器配置。

以下是负载不太高(比如1000/分钟)的典型的机器学习和深度学习部署的好方法。

不妨见识这对组合Fastapi + uvicorn

  • 最快:用fastapi编写API,因为就I/O型操作而言它是速度最快的(https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7),原因在此(https://fastapi.tiangolo.com/benchmarks/)有解释。
  • 说明文档:用fastapi编写API为我们在http:url/docs提供了免费文档和测试端点→我们更改代码时,由fastapi自动生成和更新。
  • Workers:使用uvicorn部署API。

运行这些命令使用4个workers来部署。通过负载测试来优化workers的数量。 

pip install fastapi uvicorn  
uvicorn main:app --workers 4 --host 0.0.0.0 --port 8000  
  • 1.
  • 2.

Python开发者宝典:10个有用的机器学习实践!

原文标题:10 Useful Machine Learning Practices For Python Developers,作者:Pratik Bhavsar

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

 

责任编辑:庞桂玉 来源: 51CTO
相关推荐

2011-07-15 10:02:01

JavaScript

2020-06-15 10:29:10

JavaScript开发 技巧

2015-08-12 11:09:42

开发者设计原则

2019-01-16 18:22:24

机器学习人工智能计算机

2018-10-05 23:26:00

机器学习算法数据

2015-08-11 11:01:22

设计原则开发者

2012-04-17 09:44:08

JavaScript

2011-10-11 10:07:37

2013-11-26 09:43:36

开发日志博客

2015-03-10 09:23:21

前端开发Sublime插件Sublime

2011-03-17 15:25:31

2015-04-21 12:54:21

2014-10-09 09:29:25

AngularJS

2020-07-10 10:39:04

Python开发工具

2017-04-17 13:59:37

机器学习代码TensorFlow

2011-05-10 08:47:55

开发者HTML 5W3C

2018-07-25 15:43:27

机器学习框架开发

2014-07-21 10:00:37

框架HTML5框架模板

2015-03-17 14:31:53

Web开发web开发者云开发环境

2022-07-18 10:15:16

Python
点赞
收藏

51CTO技术栈公众号