21

数据科学家常遇到的10个错误

 4 years ago
source link: https://www.tuicool.com/articles/nUzYJfn
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

3IBBFra.jpg!web

数据科学家是“在统计方面比任何软件工程师都要出色,在软件工程方面比任何统计学家都出色的人”。许多数据科学家都有统计学背景,但很少有软件工程经验。我是一位高级数据科学家,在Python编码的Stackoverflow上排名第一,并与许多(初级)数据科学家合作。下面是我经常看到的10个常见错误。

1. 不共享代码中引用的数据

数据科学需要代码和数据。因此,要使其他人能够重现您的结果,他们需要有权访问数据。虽然看起来很基础,但是很多人忘记了共享代码的数据。

import pandas as pd
df1 = pd.read_csv('file-i-dont-have.csv') # 错误
do_stuff(df)

解决方案:使用d6tpipe共享数据文件,或上传到S3 / web / google等或保存到数据库,以他人可以检索文件(但不要将它们添加到git,详见下文)。

2. 硬编码无法访问的路径

与错误1相似,如果您对其他人无法访问的路径进行硬编码,则他们将无法运行您的代码,因此要查看很多地方手动更改路径。

import pandas as pd
df = pd.read_csv('/path/i-dont/have/data.csv') # 错误
do_stuff(df)
# or
impor os
os.chdir('c:\\Users\\yourname\\desktop\\python') # 错误

解决方案:使用相对路径,配置全局路径变量或d6tpipe使数据易于访问。

3. 将数据与代码混合

由于数据科学代码需要数据,为什么不将其存储到同一目录?当您使用它时,也可以在其中保存图像,日志和其他垃圾文件。

├── data.csv
├── ingest.py
├── other-data.csv
├── output.png
├── report.html
└── run.py

解决方案:将目录按照类别进行组织,例如数据,日志,代码等。

4. Git提交带有源代码的数据

现在大多数人都可以控制他们的代码版本(如果不使用,那是另一个错误!参见git)。为了共享数据,可能想将数据文件添加到版本控制中。如果是很小的文件还可以,但是git并没有对数据文件进行优化,尤其是大文件。

git add data.csv

解决方案:使用问题1中提到的工具来存储和共享数据。如果确实要对控制数据进行版本控制,请参阅d6tpipe,DVC和Git大文件存储。

5. 编写函数而不是DAG

有足够的数据,接下来谈谈实际的代码!由于在学习代码时首先要学习的内容之一就是函数,因此数据科学代码通常被组织为一系列线性运行的函数。这可能会导致几个问题。

def process_data(data, parameter):
data = do_stuff(data)
data.to_pickle('data.pkl')
data = pd.read_csv('data.csv')
process_data(data)
df_train = pd.read_pickle(df_train)
model = sklearn.svm.SVC()
model.fit(df_train.iloc[:,:-1], df_train['y'])

解决方案:最好将数据科学代码编写为一组任务,并且它们之间具有依赖性,而不是线性链接函数。使用d6tflow或airflow。

6. 循环

和函数一样,for循环是在学习编码时首先要学习的东西。它们易于理解,但它们速度慢且过于冗长,通常表示您不知道有向量化的替代方案。

x = range(10)
avg = sum(x)/len(x); std = math.sqrt(sum((i-avg)**2 for i in x)/len(x));
zscore = [(i-avg)/std for x]
# should be: scipy.stats.zscore(x)
# or
groupavg = []
for i in df['g'].unique():
dfg = df[df[g']==i]
groupavg.append(dfg['g'].mean())
# should be: df.groupby('g').mean()

解决方案:Numpy,scipy和pandas具有向量化功能,可用于大多数的循环。

7. 不编写单元测试

随着数据,参数或用户输入的更改,您的代码可能会中断,有时您可能不会注意到。这可能会导致错误的输出,如果有人根据您的输出做出决策,那么错误的数据将导致错误的决策!

解决方案:使用 assert 语句检查数据。 pandas 有相等测试, d6tstack 有数据摄取和检查, d6tjoin 数据连接。代码示例:

assert df['id'].unique().shape[0] == len(ids) # 数据是否有所有的id
assert df.isna().sum()<0.9 # 检查缺失的数据
assert df.groupby(['g','date']).size().max() ==1 # 是否有重复的数据
assert d6tjoin.utils.PreJoin([df1,df2],['id','date']).is_all_matched() # 所有的id是否匹配

8. 不记录代码

我明白你着急进行一些分析。您可以一起努力取得成果给客户或老板。然后一个星期后,他们说“请您更新此内容”。您看着您的代码,不记得为什么要这么做。现在想象其他人需要运行它。

def some_complicated_function(data):
data = data[data['column']!='wrong']
data = data.groupby('date').apply(lambda x: complicated_stuff(x))
data = data[data['value']<0.9]
return data

解决方案:即使在完成分析之后,也要花点时间记录所做的工作。您将感谢自己,其他人更加感谢!

9. 将数据另存为csv或pickle

回到数据,毕竟是数据科学。就像函数和for循环一样,通常使用CSV和pickle文件,但它们实际上并不是很好。CSV不包含架构,因此每个人都必须再次解析数字和日期。pickle可以解决此问题,但只能在python中工作,并且不能压缩。两者都不是存储大型数据集的良好格式。

def process_data(data, parameter):
data = do_stuff(data)
data.to_pickle('data.pkl')
data = pd.read_csv('data.csv')
process_data(data)
df_train = pd.read_pickle(df_train)

解决方案:使用parquet 或其他具有数据格式的二进制数据格式,最好是压缩数据的格式。d6tflow自动将任务的数据输出保存为parquet,不需要你进行处理。

10. 使用jupyter笔记本

让我们以一个有争议的结论来结束:jupyter notebooks 与CSV一样普遍。很多人使用它们,那并不是好事。Jupyter notebooks 促进了上述许多不良的软件工程习惯,尤其是:

  1. 很容易将所有文件存储到一个目录中

  2. 编写的代码从上至下而不是DAG运行

  3. 没有模块化代码

  4. 调试困难

  5. 代码和输出混合在一个文件中

  6. 版本控制不好

入门很容易,但是扩展性很差。

解决方案:使用pycharm或spyder。

你也许还想

PyTorch专栏开篇

     深度强化学习(DRL)专栏开篇

    【ECCV 2018】谷歌AI超大规模图像竞赛,中国团队获目标检测冠军

欢迎扫码关注:

J3aYnyj.jpg!web

 点击下方  |   |  了解更多


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK