原文:
www.kdnuggets.com/2021/08/5-things-job-data-scientist-easier.html
评论
由Shree Vandana,数据科学家
图片由Boitumelo Phetla提供,来源于Unsplash
1. 谷歌网络安全证书 - 快速开启网络安全职业之路。
2. 谷歌数据分析专业证书 - 提升你的数据分析技能
3. 谷歌 IT 支持专业证书 - 支持你的组织的 IT 需求
如果你处理时间序列数据,你可能花费了大量时间来处理缺失记录或通过 SQL 查询或编写自定义函数在特定时间粒度下聚合数据。Pandas 有一个非常高效的重采样函数,通过将 DataFrame 索引设置为时间戳列,你可以按特定频率处理数据。
我将使用房间占用数据集来举例说明这个函数。你可以在这里找到数据集。这个数据集记录了每分钟的观察数据。
import pandas as pd
data = pd.read_csv('occupancy_data/datatest.txt').reset_index(drop = True)
data.head(5)
首先,我展示一个简单的聚合方法,用于在每小时级别获取指标。
data.index = pd.to_datetime(data['date'])
pd.DataFrame(data.resample('H').agg({'Temperature':'mean',
'Humidity':'mean',
'Light':'last',
'CO2':'last',
'HumidityRatio' : 'mean',
'Occupancy' : 'mean'})).head(5)
尽管这个数据集并不稀疏,但在现实世界中,我们常常遇到缺失记录的数据。处理这些记录非常重要,因为你可能需要将缺失的记录填充为 0,或者使用前一个或下一个时间步长进行插补。下面,我删除了 15 小时的记录,展示了如何使用 14 小时的时间戳来填补缺失的值:
data = pd.read_csv('occupancy_data/datatest.txt').reset_index(drop = True)data_missing_records = data[~(pd.to_datetime(data.date).dt.hour == 15)].reset_index(drop = True)data_missing_records.index = pd.to_datetime(data_missing_records['date'])data_missing_records.resample('H', base = 1).agg({'Temperature':'mean',
'Humidity':'mean',
'Light':'last',
'CO2':'last',
'HumidityRatio' : 'mean',
'Occupancy' : 'mean'}).fillna(method = 'ffill').head(5)
从分析到模型训练再到模型报告,通常需要可视化。特别是在时间序列图中,我发现自己花费了很多时间尝试自定义 matplotlib 中 x 轴刻度的大小和角度。在切换到使用 Plotly Express 后,我将使图表看起来更清晰的时间减少了大约 70%。如果我想在我的可视化中实现特定的细节,我仍然可以使用 Plotly Graph Objects。此外,Plotly 通过 Express 提供了很多简单的选项,例如在图表中设置组颜色,这样可以产生更强大的可视化效果。
import plotly.express as px
data['Temp_Bands'] = np.round(data['Temperature'])
fig = px.line(data, x = 'date',
y = 'HumidityRatio',
color = 'Temp_Bands',
title = 'Humidity Ratio across dates as a function of
Temperature Bands',
labels = {'date' : 'Time Stamp',
'HumidityRatio' : 'Humidity Ratio',
'Temp_Bands' : 'Temperature Band'})
fig.show()
使用上述提到的占用数据集,我用 Plotly Express 创建了颜色分组的折线图。我们可以看到仅用两个函数就能轻松创建这些图表。
我有时遇到处理 pandas 列时的长时间等待,即使在一个大实例的笔记本上运行代码也是如此。相反,只需添加一个简单的单词就可以加快 pandas DataFrame 中的 apply 功能。只需导入 swifter 库即可。
def custom(num1, num2):
if num1 > num2:
if num1 < 0:
return "Greater Negative"
else:
return "Greater Positive"
elif num2 > num1:
if num2 < 0:
return "Less Negative"
else:
return "Less Positive"
else:
return "Rare Equal"import swifter
import pandas as pd
import numpy as npdata_sample = pd.DataFrame(np.random.randint(-10000, 10000, size = (50000000, 2)), columns = list('XY'))
我创建了一个 5000 万行的数据框,并比较了通过 swifter 的 apply() 和原生 apply() 处理它所需的时间。我还创建了一个具有简单 if else 条件的虚拟函数,以测试这两种方法。
%%timeresults_arr = data_sample.apply(lambda x : custom(x['X'], x['Y']), axis = 1)
%%timeresults_arr = data_sample.swifter.apply(lambda x : custom(x['X'], x['Y']), axis = 1)
我们将处理时间从 7 分钟 53 秒减少了 64.4%,到 2 分钟 38 秒。
在减少时间复杂度的话题上,我经常需要处理多个粒度的数据集。使用 Python 中的多线程可以通过利用多个工作线程来节省时间。
我展示了使用相同的 5000 万行数据框的多线程效果,除了这次我添加了一个分类变量,这是从一组元音中随机选择的值。
import pandas as pd
import numpy as np
import randomstring = 'AEIOU'data_sample = pd.DataFrame(np.random.randint(-10000, 10000, size = (50000000, 2)), columns = list('XY'))
data_sample['random_char'] = random.choices(string, k = data_sample.shape[0])
unique_char = data_sample['random_char'].unique()
我使用了一个 for 循环与来自 concurrent.futures 的 Process Pool 执行器,展示了我们可以实现的运行时减少。
%%timearr = []for i in range(len(data_sample)):
num1 = data_sample.X.iloc[i]
num2 = data_sample.Y.iloc[i]
if num1 > num2:
if num1 < 0:
arr.append("Greater Negative")
else:
arr.append("Greater Positive")
elif num2 > num1:
if num2 < 0:
arr.append("Less Negative")
else:
arr.append("Less Positive")
else:
arr.append("Rare Equal")
def custom_multiprocessing(i):
sample = data_sample[data_sample['random_char'] == \
unique_char[i]]
arr = []
for j in range(len(sample)):
if num1 > num2:
if num1 < 0:
arr.append("Greater Negative")
else:
arr.append("Greater Positive")
elif num2 > num1:
if num2 < 0:
arr.append("Less Negative")
else:
arr.append("Less Positive")
else:
arr.append("Rare Equal")
sample['values'] = arr
return sample
我创建了一个函数,允许我单独处理每个元音分组:
%%time
import concurrentdef main():
aggregated = pd.DataFrame()
with concurrent.futures.ProcessPoolExecutor(max_workers = 5) as executor:
results = executor.map(custom_multiprocessing, range(len(unique_char)))if __name__ == '__main__':
main()
我们看到 CPU 时间减少了 99.3%。不过,必须记住谨慎使用这些方法,因为它们不会序列化输出,因此通过分组使用它们可以很好地利用这一能力。
随着时间序列预测中机器学习和深度学习方法的兴起,使用的指标不仅仅基于预测值和实际值之间的距离。预测模型的指标还应考虑时间趋势中的错误,以评估模型的表现,而不仅仅是瞬时误差估计。引入均值绝对尺度误差! 该指标考虑了如果我们使用随机游走方法,即最后一个时间戳的值将是下一个时间戳的预测值时,我们会得到的误差。它将模型的误差与天真预测的误差进行比较。
def MASE(y_train, y_test, pred):
naive_error = np.sum(np.abs(np.diff(y_train)))/(len(y_train)-1)
model_error = np.mean(np.abs(y_test - pred))return model_error/naive_error
如果 MASE > 1,则模型的表现不如随机游走。MASE 越接近 0,预测模型的效果越好。
在这篇文章中,我们介绍了一些我经常使用的技巧,以便作为数据科学家让自己的工作更轻松。评论分享你的一些技巧吧!我很想了解其他数据科学家在工作中使用的技巧。
这也是我的第一篇 Medium 文章,我感觉像是在对着虚空发言,如果你有任何反馈,请随时批评和联系我 :)
感谢 Anne Bonner。
个人简介:Shree Vandana 是亚马逊的数据科学家,拥有罗切斯特大学的数据科学硕士学位,对数据和机器学习充满热情!
原文。经许可转载。
相关:
-
如何为你的数据科学问题选择初始模型
-
ROC 曲线解释
-
如何查询你的 Pandas 数据框