通过 Tensorflow 识别蝙蝠的声音来探测蝙蝠
上周我发现我的公寓后面有蝙蝠。我立即抓起我的“蝙蝠探测器”:一种将蝙蝠用来回声定位的超声波信号从听不见的频率范围转换成听得见的频率范围的装置。因此,“蝙蝠探测器”这个名字是一个谎言:你可以用它来探测蝙蝠,但它本身并不能探测蝙蝠。在本教程中,我将向你展示如何使用 Tensorflow 建立一个真正的蝙蝠探测器。
问题陈述
为了解决这个问题,我将蝙蝠探测器连接到我的笔记本电脑上,录下了几个片段。在一个单独的 Jupyter 笔记本上,我创建了一个标签程序。这个程序创建了一秒钟的“声音片段”,我将其分为包含蝙蝠声音的片段和不包含蝙蝠声音的片段。我用数据和标签创建一个分类器来区分它们。
识别声音的图书馆
我导入了一些非常有用的库来构建声音识别管道。我导入的明显的库是 Tensorflow、Keras 和 scikit。我喜欢的一个声音专用库是 librosa ,它帮助我加载和分析数据。
在[1]中:
import random
import sys
import glob
import os
import time
import IPython
import matplotlib.pyplot as plt
from matplotlib.pyplot import specgram
import librosa
import librosa.display
from sklearn.preprocessing import normalize
import numpy as np
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.layers import Dense, Conv2D, MaxPooling2D, Dropout, FlattenUsing TensorFlow backend.
用 Python 加载声音数据
在数据标签笔记本中,我们输入标签,并将声音字节保存到我们输入的文件夹中。通过从这些文件夹加载,我可以加载蝙蝠声音和非蝙蝠声音文件。取决于有多少声音文件加载此数据可能需要很长时间。我把一个压缩文件夹里的所有文件都上传到了谷歌云平台。
注意,这个笔记本本身也可以从 Git 库下载。显然,Jupyter 笔记本中的声音比 wordpress/medium 中的声音要大得多。你可能得把声音调大一点!
在[2]中:
# Note: SR stands for sampling rate, the rate at which my audio files were recorded and saved.
SR = 22050 # All audio files are saved like this
def load_sounds_in_folder(foldername):
""" Loads all sounds in a folder"""
sounds = []
for filename in os.listdir(foldername):
X, sr = librosa.load(os.path.join(foldername,filename))
assert sr == SR
sounds.append(X)
return sounds
## Sounds in which you can hear a bat are in the folder called "1". Others are in a folder called "0".
batsounds = load_sounds_in_folder('labeled/1')
noisesounds = load_sounds_in_folder('labeled/0')
print("With bat: %d without: %d total: %d " % (len(batsounds), len(noisesounds), len(batsounds)+len(noisesounds)))
print("Example of a sound with a bat:")
IPython.display.display(IPython.display.Audio(random.choice(batsounds), rate=SR,autoplay=True))
print("Example of a sound without a bat:")
IPython.display.display(IPython.display.Audio(random.choice(noisesounds), rate=SR,autoplay=True))With bat: 96 without: 1133 total: 1229
Example of a sound with a bat:
您的浏览器不支持音频元素。
Example of a sound without a bat:
您的浏览器不支持音频元素。
用 Librosa 可视化声音
当你用耳机听蝙蝠的声音时,当一只蝙蝠飞过时,你可以听到清晰的声音。Librosa 库可以执行傅立叶变换来提取组成声音的频率。
在构建任何机器学习算法之前,仔细检查你正在处理的数据非常重要。在这种情况下,我决定:
- 听听声音
- 绘制声波图
- 绘制频谱图(频率振幅随时间变化的可视化表示)。
在[3]中:
def get_short_time_fourier_transform(soundwave):
return librosa.stft(soundwave, n_fft=256)
def short_time_fourier_transform_amplitude_to_db(stft):
return librosa.amplitude_to_db(stft)
def soundwave_to_np_spectogram(soundwave):
step1 = get_short_time_fourier_transform(soundwave)
step2 = short_time_fourier_transform_amplitude_to_db(step1)
step3 = step2/100
return step3
def inspect_data(sound):
plt.figure()
plt.plot(sound)
IPython.display.display(IPython.display.Audio(sound, rate=SR))
a = get_short_time_fourier_transform(sound)
Xdb = short_time_fourier_transform_amplitude_to_db(a)
plt.figure()
plt.imshow(Xdb)
plt.show()
print("Length per sample: %d, shape of spectogram: %s, max: %f min: %f" % (len(sound), str(Xdb.shape), Xdb.max(), Xdb.min()))
inspect_data(batsounds[0])
inspect_data(noisesounds[0])
您的浏览器不支持音频元素。
Length per sample: 22050, shape of spectogram: (129, 345), max: -22.786959 min: -100.000000
您的浏览器不支持音频元素。
Length per sample: 22050, shape of spectogram: (129, 345), max: -58.154167 min: -100.000000
数据分析
首先,重要的是要注意,我们正在处理的数据并不完全是大数据…只有大约 100 个阳性样本,深度神经网络很可能在这个 daa 上过度拟合。我们正在处理的一个问题是,收集阴性样本很容易(只需记录一整天没有蝙蝠的情况),而收集阳性样本很难(蝙蝠每天只在这里呆 15-20 分钟左右,我需要手动标记数据)。在确定如何对数据进行分类时,我们会考虑少量的阳性样本。
可听声信号
正如我们从上面可以看到的,信号的幅度随着噪声而降低,而信号的幅度却很高。然而,这并不意味着所有有声音的东西都是蝙蝠。在这个频率下,你还会接收到其他噪音,如手指摩擦声或电话信号。我决定把每一个负面信号放在一个大的“负面”堆上,把电话信号、手指引起的噪音和其他东西放在一个大堆里。
光谱图
我希望能在我们的频谱图中看到蝙蝠产生的准确频率。不幸的是,看起来我的传感器在所有频率上都把它当成了噪音。看着声谱图,你仍然可以看到蝙蝠声音和噪音之间的明显区别。我的第一个尝试是使用这个频谱图作为卷积神经网络的输入。不幸的是,仅使用几个正样本,很难训练这个网络。因此,我放弃了这种方法。
最后,我决定采用“元数据方法”。我把每秒钟的声音分成 22 部分。对于每个部分,我确定样本的最大值、最小值、平均值、标准偏差和最大最小值。我采取这种方法的原因是因为“蝙蝠信号”在音频可视化中确实清楚地显示为非高振幅信号。通过分析音频信号的不同部分,我可以发现信号的多个部分是否具有某些特征(如高标准偏差),从而检测到蝙蝠的叫声。
在[4]中:
WINDOW_WIDTH = 10
AUDIO_WINDOW_WIDTH = 1000 # With sampling rate of 22050 we get 22 samples for our second of audio
def audio_to_metadata(audio):
""" Takes windows of audio data, per window it takes the max value, min value, mean and stdev values"""
features = []
for start in range(0,len(audio)-AUDIO_WINDOW_WIDTH,AUDIO_WINDOW_WIDTH):
subpart = audio[start:start+AUDIO_WINDOW_WIDTH]
maxval = max(subpart)
minval = min(subpart)
mean = np.mean(subpart)
stdev = np.std(subpart)
features.extend([maxval,minval,mean,stdev,maxval-minval])
return features
metadata = audio_to_metadata(batsounds[0])
print(metadata)
print(len(metadata))[0.00088500977, -0.00076293945, 6.7962646e-05, 0.00010915515, 0.0016479492, 0.0002746582, 3.0517578e-05, 0.00017904663, 5.4772983e-05, 0.00024414062, 0.00057983398, -0.00057983398, -2.8137207e-05, 8.1624778e-05, 0.001159668, -9.1552734e-05, -0.0002746582, -0.00019345093, 3.922523e-05, 0.00018310547, 0.00048828125, -0.00076293945, -0.00036187744, 0.00015121402, 0.0012512207, -3.0517578e-05, -0.00057983398, -0.00027001952, 0.00015006117, 0.00054931641, 0.00045776367, -0.00036621094, 5.9234619e-05, 5.0381914e-05, 0.00082397461, 0.00015258789, 6.1035156e-05, 0.00011447143, 1.7610495e-05, 9.1552734e-05, 0.00015258789, 6.1035156e-05, 9.3963623e-05, 1.8880468e-05, 9.1552734e-05, 0.00082397461, -0.00048828125, 7.7423094e-05, 8.6975793e-05, 0.0013122559, 0.00021362305, 6.1035156e-05, 0.00014205933, 2.5201958e-05, 0.00015258789, 0.00054931641, -0.00061035156, 2.8991699e-05, 9.5112577e-05, 0.001159668, -3.0517578e-05, -0.00018310547, -0.00010638428, 2.9584806e-05, 0.00015258789, 3.0517578e-05, -9.1552734e-05, -2.7862548e-05, 2.323009e-05, 0.00012207031, 6.1035156e-05, -3.0517578e-05, 1.8341065e-05, 1.905331e-05, 9.1552734e-05, 0.00018310547, -0.00039672852, 4.9438477e-05, 4.7997077e-05, 0.00057983398, 0.00021362305, 9.1552734e-05, 0.00017184448, 2.1811828e-05, 0.00012207031, 0.00015258789, -6.1035156e-05, 5.0659179e-05, 4.6846228e-05, 0.00021362305, 0.0, -0.00015258789, -5.4656983e-05, 2.7488175e-05, 0.00015258789, -3.0517578e-05, -0.00012207031, -9.0820315e-05, 1.7085047e-05, 9.1552734e-05, 0.0, -0.00012207031, -7.2296141e-05, 1.917609e-05, 0.00012207031, 0.0, -9.1552734e-05, -4.4189452e-05, 1.8292634e-05, 9.1552734e-05]
110
数据管理
正如每个机器学习项目一样,建立输入输出管道非常重要。我们定义了从声音文件中获取“元数据”的函数:我们可以制作音频频谱图,并简单地从音频数据中提取多个元特征样本。下一步是将我们的预处理函数映射到我们的训练和测试数据。我首先对每个音频样本进行预处理,并将低音和非低音保存在两个不同的列表中。后来我加入了声音和标签。
在这种情况下,我们处理的是少量的“阳性”样本和大量的阴性样本。在这种情况下,将你所有的数据标准化是一个非常好的主意。我的阳性样本可能不同于正态分布,并且很容易被检测到。为此,我使用了 scikit learn sklearn .预处理函数“normalize”。在培训期间,我发现我对标准化和规范化的想法与 scikit 的定义完全相反。在这种情况下,这可能不是一个问题,因为正常化蝙蝠声音可能仍然会产生不同于正常化噪音声音的结果。
在[5]中:
# Meta-feature based batsounds and their labels
preprocessed_batsounds = list()
preprocessed_noisesounds = list()
for sound in batsounds:
expandedsound = audio_to_metadata(sound)
preprocessed_batsounds.append(expandedsound)
for sound in noisesounds:
expandedsound = audio_to_metadata(sound)
preprocessed_noisesounds.append(expandedsound)
labels = [0]*len(preprocessed_noisesounds) + [1]*len(preprocessed_batsounds)
assert len(labels) == len(preprocessed_noisesounds) + len(preprocessed_batsounds)
allsounds = preprocessed_noisesounds + preprocessed_batsounds
allsounds_normalized = normalize(np.array(allsounds),axis=1)
one_hot_labels = keras.utils.to_categorical(labels)
print(allsounds_normalized.shape)
print("Total noise: %d total bat: %d total: %d" % (len(allsounds_normalized), len(preprocessed_batsounds), len(allsounds)))
## Now zip the sounds and labels, shuffle them, and split into a train and testdataset
zipped_data = zip(allsounds_normalized, one_hot_labels)
np.random.shuffle(zipped_data)
random_zipped_data = zipped_data
VALIDATION_PERCENT = 0.8 # use X percent for training, the rest for validation
traindata = random_zipped_data[0:int(VALIDATION_PERCENT*len(random_zipped_data))]
valdata = random_zipped_data[int(VALIDATION_PERCENT*len(random_zipped_data))::]
indata = [x[0] for x in traindata]
outdata = [x[1] for x in traindata]
valin = [x[0] for x in valdata]
valout = [x[1] for x in valdata](1229, 110)
Total noise: 1229 total bat: 96 total: 1229
机器学习模型
为了检测蝙蝠,我决定尝试一个非常简单的具有三个隐藏层的神经网络。由于可训练参数太少,网络只能区分无声和有声。有了太多的可训练参数,网络将很容易在我们拥有的小数据集上过度适应。
我决定在 Keras 中实现这个网络,这个库给了我最好的函数,让我可以很容易地在这个简单的问题上尝试不同的神经网络架构。
在[6]中:
LEN_SOUND = len(preprocessed_batsounds[0])
NUM_CLASSES = 2 # Bat or no bat
model = Sequential()
model.add(Dense(128, activation='relu',input_shape=(LEN_SOUND,)))
model.add(Dense(32, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(2))
model.compile(loss="mean_squared_error", optimizer='adam', metrics=['mae','accuracy'])
model.summary()
model.fit(np.array(indata), np.array(outdata), batch_size=64, epochs=10,verbose=2, shuffle=True)
valresults = model.evaluate(np.array(valin), np.array(valout), verbose=0)
res_and_name = zip(valresults, model.metrics_names)
for result,name in res_and_name:
print("Validation " + name + ": " + str(result))_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 128) 14208
_________________________________________________________________
dense_2 (Dense) (None, 32) 4128
_________________________________________________________________
dense_3 (Dense) (None, 32) 1056
_________________________________________________________________
dense_4 (Dense) (None, 2) 66
=================================================================
Total params: 19,458
Trainable params: 19,458
Non-trainable params: 0
_________________________________________________________________
Epoch 1/10
0s - loss: 0.2835 - mean_absolute_error: 0.4101 - acc: 0.9237
Epoch 2/10
0s - loss: 0.0743 - mean_absolute_error: 0.1625 - acc: 0.9237
Epoch 3/10
0s - loss: 0.0599 - mean_absolute_error: 0.1270 - acc: 0.9237
Epoch 4/10
0s - loss: 0.0554 - mean_absolute_error: 0.1116 - acc: 0.9237
Epoch 5/10
0s - loss: 0.0524 - mean_absolute_error: 0.1071 - acc: 0.9237
Epoch 6/10
0s - loss: 0.0484 - mean_absolute_error: 0.1024 - acc: 0.9237
Epoch 7/10
0s - loss: 0.0436 - mean_absolute_error: 0.1036 - acc: 0.9329
Epoch 8/10
0s - loss: 0.0375 - mean_absolute_error: 0.0983 - acc: 0.9481
Epoch 9/10
0s - loss: 0.0327 - mean_absolute_error: 0.0923 - acc: 0.9624
Epoch 10/10
0s - loss: 0.0290 - mean_absolute_error: 0.0869 - acc: 0.9644
Validation loss: 0.0440898474639
Validation mean_absolute_error: 0.101937913192
Validation acc: 0.930894308458
检测流水线的结果和实现
验证集的准确率达到了 95 %,看起来我们做得非常好。下一步是检查我们是否能在一段我们从未处理过的更长的音频中找到蝙蝠。我在蝙蝠几乎消失后录了一段录音,让我们看看是否能找到什么:
在[7]中:
soundarray, sr = librosa.load("batsounds/bats9.m4a")
maxseconds = int(len(soundarray)/sr)
for second in range(maxseconds-1):
audiosample = np.array(soundarray[second*sr:(second+1)*sr])
metadata = audio_to_metadata(audiosample)
testinput = normalize(np.array([metadata]),axis=1)
prediction = model.predict(testinput)
if np.argmax(prediction) ==1:
IPython.display.display(IPython.display.Audio(audiosample, rate=sr,autoplay=True))
time.sleep(2)
print("Detected a bat at " + str(second) + " out of " + str(maxseconds) + " seconds")
print(prediction)
您的浏览器不支持音频元素。
Detected a bat at 514 out of 669 seconds
[[ 0.45205975 0.50231218]]
结论,以及类似项目
最后,在 26 分钟的音频中,我的传感器每次检测到 1 只蝙蝠,而外面可能没有蝙蝠(但我无法证实这一点)。我会断定我的程序有效!现在,我们能够将这个程序集成到一个小管道中,以便每当外面有蝙蝠时向我发出警告,或者我们可以每天进行记录,并每天测量蝙蝠的活动。
在这个项目中,自然智能城市项目创造了 T2 蝙蝠伦敦项目。通过传感器你可以看到蝙蝠的活动。同样有趣的是,它们的传感器能够捕捉更有趣的声音,比如蝙蝠发出的社交叫声。很高兴看到其他人也对这一主题感兴趣,并且可以比较不同的方法。bats London 项目建造了漂亮的盒子,里面有一台计算机,它根据光谱图进行所有的处理。他们使用基于 3 秒声音文件的卷积神经网络,每 6 秒记录一次。将来他们甚至想开始区分不同种类的蝙蝠!他们在一个非常有趣的项目上做得非常好!
利用深度学习检测乳腺癌
乳腺癌是女性中最常见的侵袭性癌症,是仅次于肺癌的女性癌症死亡的第二大原因。在本文中,我将构建一个基于 WideResNet 的神经网络,将幻灯片图像分为两类,一类包含乳腺癌,另一类不使用深度学习工作室(hTTP://Deep cognition . ai/)
浸润性导管癌(IDC)也称为浸润性导管癌,是最常见的乳腺癌类型。美国癌症协会估计**美国每年有超过 180,000 名女性发现她们患有浸润性乳腺癌。**这些癌症中的大多数被诊断为 IDC。
准确识别和分类乳腺癌亚型是一项重要的任务。基于人工智能的自动化方法可以显著节省时间并减少错误。
在这篇文章中,我将使用深度学习工作室构建一个基于 WideResNet 的神经网络,将幻灯片图像分为两类,一类包含乳腺癌,另一类不包含乳腺癌。
如果你不熟悉深度学习,看看这个:)
有关于深度学习的惊人介绍、课程和博文。但这是一种不同的介绍。
towardsdatascience.com](/a-weird-introduction-to-deep-learning-7828803693b0)
如果你想了解更多关于深层认知的知识,请看这个:
在过去的一个月里,我有幸见到了 DeepCognition.ai 的创始人
becominghuman.ai](https://becominghuman.ai/deep-learning-made-easy-with-deep-cognition-403fbe445351)
关于数据集
俄亥俄州克利夫兰凯斯西储大学的研究人员收集了这个问题的数据集。原始数据集在这里(编辑:原始链接不再工作,从 Kaggle 下载)。这个数据集是在 Kaggle 由善良的人预处理的,这是我们工作的起点。
Each slide approximately yields 1700 images of 50x50 patches
数据集中有 162 张完整的载玻片图像。这些幻灯片是以 40 倍的分辨率扫描的。最后,这些幻灯片被分成 275,215 个 50x50 像素的小块。然后将 0 或 1 的一个标签分配给这些补丁中的每一个。对于包含 IDC 的修补程序,标签为 1,不包含 IDC 的修补程序标签为 0。
3 Example of positive and negative IDC tissue. https://doi.org/10.1117/12.2043872
用宽网分类载玻片
使用剩余连接的 ResNet 体系结构在图像分类任务中非常成功。WideResNet 架构表明,可以用小得多的深度(小至 16 层)实现类似的性能。这有助于解决与非常深的结果相关的各种问题,如爆炸/消失梯度和退化。
利用文森特·冯和 T2 博客中的大量信息,我们可以对 ResNet 实际上在做什么有一些直觉。
ResNet 的核心思想是引入所谓的“身份快捷连接”,跳过一层或多层。
Residual Block
该论文的最初作者假设,让堆叠层拟合残差映射比让它们直接拟合所需的底层映射更容易。这表明较深的模型不应该比其较浅的模型产生更高的训练误差。
由于其引人注目的结果,ResNet 很快成为各种计算机视觉任务中最受欢迎的架构之一。
现在,一个宽网的存在是有原因的:每提高百分之一的精度都要花费近两倍的层数,因此训练非常深的残差网络有一个减少特征重用的问题,这使得这些网络训练非常慢。
https://dl.acm.org/citation.cfm?doid=2988450.2988454
为了解决这些问题 Zagoruyko 和 Komodakis 对 ResNet 块的架构进行了详细的实验研究(于 2016 年发表),基于此,他们提出了一种新的架构,其中我们减少了深度,增加了剩余网络的宽度。他们称之为广泛残留网络。
现在,我们将展示使用 WideResNet 架构解决此问题的逐步过程。我们正在使用深度学习工作室,它允许我们快速构建神经网络,而无需担心编码、语法和数据集摄取。
1。项目创建
当你登录到运行在本地或云中的深度学习工作室后,点击+按钮创建一个新项目。
2。数据集摄入
然后,我们在“数据”选项卡中为此项目设置数据集。通常 80% — 20%是训练和验证之间的一个很好的划分,但是如果您愿意,也可以使用其他设置。另外,如果你的机器有足够的内存来在内存中加载完整的数据集,不要忘记将内存中的加载数据集设置为“完整的数据集”。
3。创建神经网络
您可以通过拖放层来创建如下所示的神经网络。
确保在右侧的属性中将 WideResNet 设置为 100%可训练。此外,第一密集层(Dense_3)应该具有 20 个左右的具有 ReLU 作为激活功能的神经元。最终密集层(Dense_1)的输出维度应为 1,激活为 sigmoid。这是因为我们把这个问题设定为回归而不是分类。如果回归输出低于 0.5,那么我们可以说输入属于 0 类(无 IDC 癌症),否则它有 IDC 癌症。
4。 超参数和训练
我们使用的超参数如下所示。请随意更改并尝试它们。
最后,您可以从“培训”选项卡开始培训,并使用培训仪表板监控进度。
完成培训后,您可以在“结果”选项卡中查看结果。我们在一个 K80 GPU 上花了几个小时实现了超过 85%的准确率,这个 GPU 的价格大约是每小时 0.90 美元。
通过将 Deep Learning Studio 部署为 webapp 或 REST API,可以使用如下所示的部署选项卡轻松完成。
5.部署模型
部署的模型可以作为 WebApp 或 REST API 访问,如下所示:
结束语
所以你可以看到,使用 Deep Learning Studio,可以在几分钟内建立深度学习模型,并在几秒钟内部署。这种能力将使许多开发人员能够处理复杂的问题,而不用担心编码、API 等问题。
我在这里重复一下我在“深度认知使深度学习变得容易”博客中关于“黑箱问题”的话:
你脑海中会出现的事情是:好吧,我在做深度学习,但我不知道怎么做。
实际上你可以下载产生预测的代码,你会看到它是用 Keras 写的。然后,您可以上传代码,并用系统提供的笔记本进行测试。
AutoML 特性和 GUI 拥有 Keras 和其他 DL 框架的精华,只需简单的点击,它的好处是为您选择 DL 的最佳实践,如果您对这些选择不完全满意,您可以在 UI 中轻松更改它们,或者与笔记本进行交互。
这个系统建立的前提是让人工智能对每个人来说都很容易,当创建这个复杂的模型时,你不必成为专家,但我的建议是,你对自己正在做的事情有一个想法是好的,阅读一些 TensorFlow 或 Keras 文档,观看一些视频并获得信息。如果你是这方面的专家,那太好了!这将使你的生活更容易,你仍然可以在构建模型时应用你的专业知识。
感谢深度认知帮我搭建这篇文章:)
感谢你阅读这篇文章。希望你在这里发现了一些有趣的东西:)
如果您有任何问题,请在 twitter 上添加我:
Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…
twitter.com](https://twitter.com/FavioVaz)
和 LinkedIn:
[## Favio Vázquez —首席数据科学家— OXXO | LinkedIn
查看 Favio Vázquez 在世界上最大的职业社区 LinkedIn 上的个人资料。Favio 有 15 个工作职位列在…
linkedin.com](http://linkedin.com/in/faviovazquez/)
那里见:)
在为时已晚之前检测数据泄漏
有时候好得难以置信。
更新:我开了一家科技公司。你可以在这里找到更多
在阅读了 Susan Li 的 Expedia 案例研究文章后,我想看看我是否能使用 Mind Foundry 的自动化机器学习平台来重现结果。这些数据可在 Kaggle 上获得,包含酒店预订的客户网络分析信息(对与错)。这个竞赛的目标是预测顾客是否会预订。然而,在清理数据并在 3 分钟的训练后建立我的模型后,我达到了 100%的分类准确率,这立即触发了警报。我是数据泄露的受害者。
在这篇文章中,我们将看到奥达斯是如何拉响警报的,以及我如何在第一时间避免它!
检测泄漏
目标是对客户是否会预订进行分类,因此我在 AuDaS 中启动了一个简单的分类任务,并在达到 100%的准确率后立即触发了一个模型健康警告。
Model Health Warning raised by AuDaS
在进一步检查功能相关性后,我意识到泄漏是由包含与预订相关的$值的总预订列引起的。然后,我返回到 AuDaS 中的数据准备步骤,以排除它,最重要的是,看看是否有任何其他列我应该删除。
Feature Relevance in AuDaS
利用 AuDaS 主动检测数据泄漏
我决定使用 AuDaS 的自动直方图页面来识别完美的预订预测,然后从训练数据中排除。不足为奇的是,总预订量和点击率(无论酒店是否被点击)是预订的强有力的预测因素,因为为了进行预订,我们需要点击,然后链接,然后支付!
在排除总预订量并重新启动分类任务后,我仍然达到了 99%的分类准确率,这使我能够更近距离地观察正在发生的事情。
实际上,因为预订很少,AuDaS 平衡了训练和 10%的验证目的,click bool 列是预订的近乎完美的预测。
利用 AuDaS 进行稳健建模
最后,我决定排除点击来识别预测预订(以及点击)的关键特征,因为这是 Expedia 的主要目标。
分类准确率因此降低到 72%,但 AuDaS 能够识别出一个更细微的预订相关预测指标排名。
所选型号的主要特点是:
- 酒店在搜索结果页面上的位置
- 搜索结果的 A/B 排序方法
- 资产的位置得分和价格
关键外卖
数据科学中的数据泄漏经常会被忽视,这就是为什么拥有发出警告和检测泄漏源的机制非常重要。一旦确定了泄漏,对数据的理解对于解释为什么以及如何导致泄漏是很重要的,以便决定修复泄漏的最佳方式。奥达斯帮助我们避免了一场灾难。
奥达斯
AuDaS 是由 Mind Foundry 开发的自动化数据科学平台,为构建端到端的机器学习解决方案提供了一个强大的框架。该框架有助于识别数据泄漏并及时采取行动。您可以尝试 AuDaS 这里和查看更多演示如下:
团队和资源
Mind Foundry 是牛津大学的一个分支机构,由斯蒂芬·罗伯茨(Stephen Roberts)和迈克尔·奥斯本(Michael Osborne)教授创建,他们在数据分析领域已经工作了 35 年。Mind Foundry 团队由 30 多名世界级的机器学习研究人员和精英软件工程师组成,其中许多人曾是牛津大学的博士后。此外,Mind Foundry 通过其分拆地位,拥有超过 30 名牛津大学机器学习博士的特权。Mind Foundry 是牛津大学的投资组合公司,其投资者包括牛津科学创新、牛津技术与创新基金、、牛津大学创新基金和 Parkwalk Advisors 。
使用深度学习检测面部特征
也许你想知道如何在实时视频聊天中在人脸上放置有趣的物体或检测情绪?在这里,我将向您展示一种利用深度学习的可能方法,并略读一种较老的方法。
在过去,一项具有挑战性的任务是检测人脸及其特征,如眼睛、鼻子、嘴巴,甚至从它们的形状中提取情感。这项任务现在可以通过深度学习“神奇地”解决,任何有天赋的青少年都可以在几个小时内完成。我将在这篇文章中向你展示这样一种方法。
【古典】法(CLM)
如果你像我一样,需要执行面部跟踪(在我的情况下,将一个人的手势从网络摄像头转移到动画角色),你可能会发现,最好的执行算法之一曾经是受约束的本地模型(【CLM】),例如由剑桥面部跟踪器或其更新的 OpenFace 化身实现。这是基于将检测任务分成检测形状向量特征( ASM )和小块图像模板( AAM ),并使用预训练的线性 SVM 来改进检测。
它的工作原理是首先粗略估计关键点的位置,然后对包含面部部分的预训练图像应用 SVM,并调整关键点的位置。重复这一过程,直到误差对于我们的目的来说足够低。此外,值得一提的是,它假设图像上的人脸位置已经被估计,例如通过使用 Viola-Jones 检测器 ( Haar cascades )。然而,CLM 过程是相当复杂和重要的,肯定不会由一个高中巫师来实现。您可以在这里看到整体架构:
Well, fairly complicated, right?
深度学习
相反,我们可以使用一个非常简单的卷积神经网络( CNN )并在我们预期包含人脸的图像部分上执行关键点检测。为此,我们需要一个训练数据集;我们可以使用由 Kaggle 为他们的面部关键点检测挑战提供的一个,包含 15 个关键点,或者一个更复杂的 MUCT 数据集包含 76 个关键点(耶!).
显然,拥有高质量的训练数据集在这里是必不可少的,我们都应该纪念那些不得不牺牲他们的时间和精力来注释一堆人脸以获准毕业的贫困本科生,这样我们就可以轻松地表演这些神奇的把戏。
下面是一张巴洛克风格的脸和它在 Kaggle 数据集中的关键点的样子:
James Madison Jr.
数据集包含分辨率为 96x96 的灰度图像和 15 个关键点,每只眼睛 5 个,嘴/鼻子位置 5 个。
对于任意图像,我们首先需要检测图像中人脸的位置;可以使用前面提到的基于哈尔级联的 Viola-Jones 检测器(如果你看看它是如何工作的,它有点像 CNN)。或者,如果你更有冒险精神,你也可以使用全卷积网络( FCN )和深度估计来执行图像分割。
OpenCV does the trick
无论如何,使用 OpenCV 是小菜一碟:
Grayscale_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)face_cascade = cv2.CascadeClassifier(‘haarcascade_frontalface_default.xml’)bounding_boxes = face_cascade.detectMultiScale(grayscale_image, 1.25, 6)
这段代码返回图像上所有可能的人脸包围盒。
接下来,对于 Viola-Jones 返回的每个边界框,我们提取相应的子图像,将其转换为灰度,并将其大小调整为 96x96。它们将成为我们最终的 CNN 的输入,用于推理。
CNN 架构超级猥琐;一堆 5×5 卷积层(实际上是 3 层,每层有 24、36 和 48 个滤波器),然后是另外 2 层 3×3 卷积层(每层 64 个滤波器),最后是 3 个全连接层(有 500、90 和 30 个节点)。一些防止过度拟合的最大池和减少展平参数数量的全局平均池。输出将是 30 个浮点数,表示 15 个关键点的 x,y 坐标序列。
下面是在 Keras 中的实现:
model = Sequential()model.add(BatchNormalization(input_shape=(96, 96, 1)))model.add(Convolution2D(24, 5, 5, border_mode=”same”, init=’he_normal’, input_shape=(96, 96, 1), dim_ordering=”tf”))
model.add(Activation(“relu”))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), border_mode=”valid”))model.add(Convolution2D(36, 5, 5))
model.add(Activation(“relu”))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), border_mode=”valid”))model.add(Convolution2D(48, 5, 5))
model.add(Activation(“relu”))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), border_mode=”valid”))model.add(Convolution2D(64, 3, 3))
model.add(Activation(“relu”))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), border_mode=”valid”))model.add(Convolution2D(64, 3, 3))
model.add(Activation(“relu”))model.add(GlobalAveragePooling2D());model.add(Dense(500, activation=”relu”))
model.add(Dense(90, activation=”relu”))
model.add(Dense(30))
您可能希望选择[均方根传播](http://Root Mean Square Propagation) (rmsprop)优化器和均方误差 (MSE)作为您的损失函数和精度指标。
仅仅通过一些琐碎的技巧,如对输入图像的批量归一化,全局平均池以及正常权重初始化,你可以在大约 30 个训练时期获得 80-90%的验证准确率和损失< 0.001:
model.compile(optimizer=’rmsprop’, loss=’mse’, metrics=[‘accuracy’])checkpointer = ModelCheckpoint(filepath=’face_model.h5', verbose=1, save_best_only=True)epochs = 30hist = model.fit(X_train, y_train, validation_split=0.2, shuffle=True, epochs=epochs, batch_size=20, callbacks=[checkpointer], verbose=1)
然后,要预测关键点的位置,只需运行:
features = model.predict(region, batch_size=1)
就这样。你现在已经掌握了检测面部关键点的艺术!
请注意,预测的结果将是每个关键点的 15 对 x,y 坐标,顺序如下图所示:
Saving you some time…
如果你想做得更好,你可能需要做一些额外的功课:
- 尝试如何减少卷积层数和滤波器尺寸,同时保持准确性并提高推断速度
- 用迁移学习代替卷积部分(例外是我的最爱)
- 使用更详细的数据集
- 做一些先进的图像增强,以提高鲁棒性
你可能会发现这一切都太容易了;如果你想要一个挑战,那就转向 3D,看看脸书和英伟达是如何追踪人脸的。
显然,你可以使用这种新学到的魔法来完成一些你一直想做但不知道如何做的重要事情:
- 在视频聊天时,在脸上放置令人讨厌的物体,如太阳镜、怪异的帽子、胡子等。
- 在朋友、敌人、动物和物品之间交换面孔
- 通过允许在自拍实时视频上测试新发型、珠宝或化妆品,增加了人们的虚荣心
- 检测您的员工是否喝得太醉(或不够醉)而无法执行分配的任务
- 如果出于某种奇怪的原因,你想自动处理情绪,就要识别视频中人们的主要情绪
- 使用 GANs 进行实时面部到卡通的转换,并根据网络摄像头上你自己的面部弯曲卡通面部,以模仿你的动作、说话和情绪
现在你知道如何制作自己的视频聊天过滤器了吧!现在就写一个怎么样?
用机器学习检测财务报表欺诈
了解机器学习如何检测会计欺诈
查明扭曲财务报表的公司仍然被审计人员视为一项挑战,因为多年来欺诈手段变得越来越复杂——通过其他实体隐瞒损失,过早确认收入,甚至让未注册的审计人员声称财务报表真实、公平。
最近,我完成了一个机器学习项目,根据 2005-2009 年的历史数据来识别 2010 年有故意错报的美国公司。
我认为分享这个数据科学项目的方法和关键学习点会很有趣,如果你想了解更多,请继续阅读。
详细讨论的关键步骤概述:
- 特征工程
- 探索性数据分析
- 特征选择采用 t 检验和卡方检验
- 模型选择与实现
- 随机搜索 CV 模型的微调
- 模型评估
- 模型解释
第一步:特征工程
在这个项目中,第一个挑战是完全没有提供任何功能,不像大多数的 Kaggle 比赛都有训练数据。我们唯一的属性是公司识别码、年份以及该公司在该年是否实施了金融服务欺诈。
特征工程是每个数据科学项目的关键步骤,数据科学家在特征工程上花费大量的时间来创建有意义的特征,以捕捉正在观察的现象的特征。没有高质量的数据,最复杂的机器学习算法将无法胜过具有高质量特征的简单模型。
你会问,我们如何找到可以训练的功能?
利用过去的研究论文
依靠过去的研究论文,如 Dechow(2011) 和 BCE(2018) 非常有助于理解可以提取实施会计欺诈的公司特征的特征类型。
以下是这些研究论文中探索的一些不同类型的变量:
- 捕捉公司财务活动的财务变量:例如,应收账款的变化、存货的变化、账面市值比以及公司是否进行了重组
- 文本风格特征捕捉财务报表的可读性、长度、语气和用词
- 捕捉业务性质的特征:例如,公司是在零售、服务还是计算机行业
将这两篇研究论文的显著特征包括在我们的初始 Lasso 模型中,R 仅能够实现 0.64 的样本外 AUC 得分,这表明该模型仅能够在 64%的时间内正确预测目标。
利用领域知识进行头脑风暴
很明显,我们需要更多的特征工程,然后**问自己,如果我们是审计师、内部审计师、监管者和投资者,我们如何通过利用任何数据来发现存在故意错报的公司?**假设您可以获得任何数据,您会为模型添加哪些功能。经过一番头脑风暴,我们想出了一些可能的变量:
- 审计师将有权访问重大错报的领域/数量、管理审查点的数量、审计师意见、行业以及该行业是否为高风险行业。
- 内部审计员评估公司的内部控制,他们可以得到内部控制强度的分数和内部邮件。一些可能的变量是对内部控制的看法,以及内部电子邮件是否包含表明欺诈的可疑消息。
- 监管机构将有权获得高层管理信息和薪酬详情,一个可能的变量是计算首席执行官或首席财务官的流动率,因为高层管理人员往往会在财务报表操纵期间或监管机构发现欺诈后离开公司。高层管理人员未行使的股票期权的数量也经常与激进的会计方法有关。
- 投资者由于公众可以访问财务报告和股票数据,因此可以关注股价和股票回报的波动性,因为管理层经常操纵财务报表以满足投资者或分析师的预期,从而维持股价。
考虑到可能的变量,我们从 WRDS 数据库中搜索这些变量的可用性,以获得以下变量:
- 审计意见:审计师的意见可能预示着潜在的欺诈案件。例如,反对意见、有保留意见和无保留意见。
- **对内部控制的看法:**不良的内部控制增加了舞弊的机会。例如有效、不利和免责。
- **财务报表审计师:**某些审计公司可能面临更大的压力,要求其签署存在重大错报的财务报表
- **行业:**部分行业易受欺诈打击,且被发现与欺诈案件有关联
- **CEO 更替与薪酬:**该变量因数据缺失过多而未被使用
- **与股票回报和波动性相关的变量:**这个变量后来没有被使用,因为这将限制我们的训练数据集只包含上市公司
第 2 步:数据清理
Photo by pan xiaozhen on Unsplash
将所有变量与给定的包含公司标识符、年份和目标变量的培训数据集合并后。进行探索性数据分析之前,检查缺失数据和重复数据的程度很重要。
- 检查重复项:统计新合并的训练数据帧的行数,并与原始数据帧进行比较,如果有重复项,根据唯一的公司标识进行删除
- **检查缺失数据:**使用 R 的 Visdat package 下的 vis_miss 功能将缺失数据可视化,如果缺失数据占训练数据集的 2%以上(具有国际错报的观察结果的百分比占数据集的 2%),我会完全丢弃该变量
第 3 步:通过探索性数据分析获得见解
3.1 了解目标变量的分布:生成目标变量的频率表
从该表中,我们可以看出,由于预测问题的性质,存在不平衡的类分布,因为在整个训练数据集中只有 2%的观察结果包含有意的错报。这是分类问题中的一个常见问题,有几种方法可以处理不平衡的类分布 ns。一些解决方案包括数据集的重采样、生成的合成样本、较少偏向多数类的挑选算法以及惩罚模型。
3.2 识别有助于预测故意错报的变量:可视化所有变量的分布和相对频率
我们绘制了每个连续/分类变量的密度图和条形图,以比较错报公司和非错报公司。为了使本文简短易懂,以下是一些有趣的观察结果:
The mean of log_total_assets for observations where Restate_Int = 1 is approximately 5, while the mean of log_total_assets for observations where Restate_Int = 0 is approximately 6.5.
平均而言,故意错报财务报表的公司被发现具有较低的总资产对数值,而那些没有故意错报财务报表的公司往往具有较高的总资产对数值。看起来小公司可能会扭曲其财务报表。
As seen from the bar chart above, of all observations where Restate_Int = 0, 70% had engaged a Big N auditor for their financial statement audit. This proportion is relatively higher than the 65% of observations where Restate_Int = 1
似乎没有故意错报的事务所更有可能是雇佣了大型审计事务所的事务所。
3.3 绘制相关矩阵,以移除变量之间高度相关的变量
基于相关矩阵,我们发现与财务报表长度相关的变量倾向于彼此相关,可读性变量也是如此。
然后去除高度相关的变量,只保留一个有意义的变量。这也被称为多重共线性的问题。尽管一些机器学习模型(如 tree methods 和 Lasso)能够处理多重共线性,但是,包括高度相关的变量可能会导致算法选择“不太正确”的变量**,从而**影响模型结果的解释。****
步骤 4:特征选择
特征选择可以通过您自己对问题的了解来完成,或者使用选择模型(Lasso)来自动完成,或者使用简单的相关矩阵来识别与目标变量相关的特征。
最好使用第一种方法,因为使用选择模型来自动化特征选择可能会导致更难解释的结果。
对于该项目,我们对所有连续变量进行了 t 检验,对所有分类变量进行了卡方检验,以确定显著特征。
t-test in R
在 t 检验下,p 值告诉我们公司由于某一特定变量而不是由于随机抽样而不重述其财务报表的概率。因此,如果 p 值低于 0.1,我们拒绝零假设,支持替代方案。
chi-square test in R
而对于卡方检验,p 值告诉我们特征的概率独立于整个群体中的目标。
考虑到 t 检验结果、卡方检验结果和探索性数据分析结果,选择了 32 个特征。
步骤 5:模型选择和实现
有许多机器学习模型可以用来解决这个机器学习问题,列出模型选择的标准是有帮助的。
机器学习算法必须能够:
- **执行监督二元分类:**因为预测一家美国公司是否故意错报其财务报表是一个二元分类问题
- 处理不均衡的班级分布
- 接受更大数量的维度
考虑到这些限制,满足这些标准的算法是支持向量机、随机森林和 LASSO。
为了比较所有机器学习模型的模型性能,我们使用了具有五倍 CV 的样本内平均 AUC 分数,以及从 Kaggle 上的公共领导力仪表板获得的样本外 AUC 分数。
在第一轮模型评估中,我们比较了所有用**默认超参数训练的机器学习模型的样本外 AUC 得分。**R 中的随机森林表现最好(AUC 为 0.68),其次是 Python 中的随机森林(AUC 为 0.65),Lasso (AUC 为 0.63),SVM (AUC 为 0.51)表现最差。
步骤 6:模型的微调
使用默认的超参数,最佳模型能够获得 0.68 的样本外 AUC 分数。为了进一步提高模型性能,我们使用 scikit-learn 软件包中的随机搜索交叉验证功能对随机森林和 SVM 进行了微调。
随机森林模型的超参数调整
超参数调整支持向量分类器模型
点击 查看 Python 中超参数调优的完整实现。
Lasso 不需要超参数调整,因为在 R 的 glmnet 软件包中,Lasso 默认具有内置功能,可以通过交叉验证来选择最佳的 lambda 值。
超参数调整能够将所有模型的 AUC 分数提高约 0.03-0.04。在 R 中训练的随机森林继续以 0.70 的样本外 AUC 胜过其余模型。
在私人领导委员会发布 AUC 分数后,最佳模型是随机森林(Python ),其样本外 AUC 分数为 0.74,因为它在 50%和 100%的测试数据上具有更稳定的 AUC 分数。
AUC 分数 0.74 被认为是可接受的表现,因为该模型有 0.74 的机会能够区分具有故意错报的公司。
步骤 7:模型解释——特征重要性
基于决策树的模型具有特征重要性属性来识别对模型性能贡献最大的特征。有许多方法可以计算特征重要性值,而 scikit-learn 实施了“平均减少杂质”指标,该指标用于测量随机置换变量值后出袋病例的准确性下降。如果准确度的降低很低,则该特征不太重要。
Code to visualize the feature importance in Python
驱动该模型性能的有趣特性包括:
- 财务报表中使用更多的负面词汇表明财务表现不佳,因此操纵账目的压力更大
- 平均每句话字数:该特征衡量财务报表的复杂程度和可读性。难以阅读的财务报表可能表明复杂的会计活动(需要主观判断的会计处理,因此存在更大的操纵风险)或故意措辞,使投资者更难理解以隐藏财务报表操纵
- 软资产百分比:不包括物业、厂房及设备、现金及现金等价物的总资产百分比。应收账款和应收账款是更难核实的账户,因此受到管理层操纵的风险更高
- (Loughran-McDonald 诉讼词比例):包含更多诉讼词的财务报表意味着更大的诉讼风险,因此面临更大的操纵账目的压力
- **Tot 融资:**杠杆率较高的公司破产风险更大,因此面临更大的操纵账目的压力
- 对内部控制持负面意见的公司有更大的机会操纵账目
最终想法
当我们尝试 Kaggle 竞赛时,通常会给出大多数变量,这并不要求我们从头开始执行特征工程。这个项目通过提出正确的问题让我体会到了特征工程的重要性。
我从这个项目中获得的主要收获是:
- 在功能工程上要有创造性,不要在头脑风暴出可能的功能之前就假设某些功能是不可用的
- 利用过去的研究论文来理解选择某些变量和相关限制的基本原理
- 可用于特征选择和处理不平衡类别分布的技术
- 始终执行超参数调整以提高模型性能
我要感谢我的队友们为这个项目付出的努力,也要感谢我们的教授给予的指导和鼓励。
使用张量流对象检测检测视频中的皮卡丘
在 TensorFlow 的众多功能和工具中,有一个名为 TensorFlow 对象检测 API 的组件。顾名思义,这个库的目的是训练一个能够识别帧中对象(例如图像)的神经网络。
在我以前的工作中,在这里找到了,我解释并完成了使用 TensorFlow 包在 Android 设备上检测皮卡丘的过程。此外,我还介绍了该库,讨论了它提供的不同架构和功能,并演示了如何使用 TensorBoard 评估培训过程。
[## 使用 Tensorflow 对象检测在 Android 上检测皮卡丘
本指南解释了如何训练一个对象检测模型,使用皮卡丘作为目标对象,目的是…
towardsdatascience.com](/detecting-pikachu-on-android-using-tensorflow-object-detection-15464c7a60cd)
继续向前,几个月后,我承担了改进我之前训练的皮卡丘检测模型的任务,目的是使用 Python、 OpenCV ,当然还有 TensorFlow 对象检测,直接从视频中检测它们。代码可以在我的 GitHub 上找到:https://github.com/juandes/pikachu-detection
Pikachu
这篇文章讲述了我实现这一目标的步骤。首先,我将陈述我在最初的模型中注意到的问题,以及我做了什么来改进它们。然后,我将继续描述如何通过使用这个新的和改进的模型,我建立了一个视频检测系统。最后,您将能够看到两个视频,其中有几个皮卡丘检测。
但在我们开始之前,这里有一个简短的 gif 展示了一些快速检测。
Pikachu being detected
That’s Pikachu
模型的改进
如前所述,在之前的工作中,我做了皮卡丘检测模型的原始训练,目标是在 Android 设备和 Python 笔记本上使用它。然而,我对模型的表现并不完全满意,这一事实激励并驱使我改进这个系统,因此,我写了这篇文章。
我主要关心的是我用来构建系统的皮卡丘图像的数量,有 230 个。其中,约 70%用于培训,其余 30%用于测试,因此用于培训的不多。虽然这在技术上不是问题(因为模特正在表演“okayish”),但我向训练集添加了 70 多张照片(不是很多,但总比没有好)。
结果,因为现在我有了更多的图像,我不得不扩展模型的训练。我没有从头开始重新训练,而是使用我早期模型的训练检查点,并从那里继续;前者在 15000 个历元训练,新的在 20000 个历元训练。接下来的两幅图显示了总损耗和精度(取自 tensor board);很容易注意到,从公元 15000 年到公元 20000 年没有太大的变化(特别是在损失方面)。
Plot of loss
Plot of precision
我做的最后一个(也是很小的)修正是修改 Android 应用程序的检测阈值。默认值为 0.6,增加到 0.85。
这些改进改变了什么吗?即使抛开我的确认偏见,我也会说,是的。我注意到一个微小的改善。我注意到的最大变化是,由于物体看起来像一个黄色斑点,Android 应用程序中的误报数量减少了;当然,这可能是因为门槛提高了。
现在,有了一个最新的(希望是)改进的模型,我准备用它来检测视频中的皮卡丘。在继续之前,我想提一下,我将跳过冻结和导入模型的整个过程,因为这在我早期的工作中已经解决了。
视频检测
从视频中执行对象检测并不像听起来那么困难或复杂。通俗地说,我们可以说视频是遵循一个序列的图像的集合,因此检测过程相当类似于从正常图像中检测。为什么相当相似?由于视频的性质,在将视频输入检测模型之前,需要解决几个预处理和帧准备的步骤。在接下来的几行中,我将解释这一点,加上我执行检测所遵循的过程,以及我如何创建一个新的视频来显示它们。
我的大部分代码都是基于 TensorFlow 对象检测 repo 中提供的一个 Python 笔记本;这段代码完成了大部分艰苦的工作,因为它包含了许多简化检测过程的函数。另外,我建议你看看我的剧本,并以此作为你阅读以下段落的指南。
从高层次的角度来看,我编写的代码有三个主要任务:
加载资源
首先,必须加载冻结的模型、数据标签和视频。出于简单的原因,我推荐一个短的中等大小的视频,因为它可能需要一点时间来处理整个电影。
迭代视频
该脚本的主要功能基于一个循环,该循环遍历视频的每一帧。在每次迭代中,读取一帧并改变其颜色空间。接下来,进行实际的检测过程,以找到所有这些漂亮的黄色鼠兔。因此,将返回皮卡丘所在的边界框的坐标(如果找到的话)和检测的置信度值。随后,将创建该帧的副本,其中包含只要置信度得分高于给定阈值,皮卡丘就应该所在的边界框。对于这个项目,我将置信度阈值设置为非常低的 20%,因为我注意到视频中被检测到的假阳性数量非常少,所以我决定“冒险”一下它的性能,以便有更多的皮卡丘检测。
创建新视频
前一步骤中讨论的携带检测框的帧的所有新创建的副本被用于构建新的视频。为了构建这个视频,需要一个VideoWriter
对象,在前面讨论的循环的每次迭代中,帧的副本将被写入这个对象(没有任何声音)。
结果和讨论
这两个视频展示了模型的表现。
第一段视频的检测结果相当不错。即使皮卡丘在整个视频中一直拿着一个番茄酱瓶子,但模型在大多数场景中都能够检测到它。另一方面,在 0:22 有一个实例没有被检测到,此外,Scyther(绿色螳螂状的东西)打破番茄酱瓶的镜头(0:40 到 0:44)是一个假阳性。
第二个视频中模型的性能不如第一个,主要问题是在帧中有两只鼠兔的场景中。在这种情况下,模型似乎将他们两个检测为皮卡丘,而不是对每个人进行一次检测——一个明显的例子是在 0:13,两只皮卡丘正在互相拍打(悲伤的场景:(,我知道)。
结论和概述
在这篇文章中,我谈到了我们如何使用 TensorFlow 对象检测包来检测视频中的皮卡丘。在开始,我讨论了一些我以前的工作,其中我使用了一个早期版本的模型在 Android 设备上进行检测。这个模型,尽管它在做它的工作,但是有一些问题我想去解决。这些改进让我做了这个项目,并为视频建立了一个检测模型。
新模型按预期工作。当然,这里和那里有一些小问题——这与假阳性有关,皮卡丘没有被检测到——但它做了它必须做的事情。作为未来的工作,我想在我的训练集中添加更多不同角度的皮卡丘图像,例如,侧视图和后视图,以使数据更加多样化,从而获得更好的结果。
感谢阅读。我真的希望这个指南对你们有些人有所帮助。如果你有任何问题,评论,疑问,或者只是想聊天,留下评论,我将很乐意帮助你。
使用 Tensorflow 对象检测在 Android 上检测皮卡丘
在 TensorFlow 的众多功能和工具的深处,隐藏着一个名为 TensorFlow 对象检测 API 的组件。顾名思义,这个库的目的是训练一个能够识别帧中对象(例如图像)的神经网络。
这个库的用例和可能性几乎是无限的。它可以被训练来检测图像中的人、猫、汽车、浣熊等等。由于这个原因,我开始有兴趣用自己训练的定制模型自己尝试一下。我的用例是什么?检测皮卡丘。
Pikachu
本文的目的是描述我训练自己的自定义对象检测模型所遵循的步骤,并展示我的皮卡丘检测技能,以便您可以自己尝试。首先,我将通过总结原始文件中解释的一些细节来介绍这个包。其次,我将继续讲述如何将我的皮卡丘图片转换成正确的格式并创建数据集。之后我会用 Tensorflow 的 web UI, TensorBoard ,尽可能详细的写训练过程,以及如何评价,以及最终的模型。最后,我将演示如何在 Python 笔记本中使用该模型,以及将其导出到 Android 的过程。
我用于这个项目的代码可以在我的 Github(juandes/pikachu-detection)上获得。本文档中提到的每个脚本都应该在那里可用。
在我开始之前,我确信你们大多数人都很好奇,这是皮卡丘检测的一个例子。
Yep, that’s a Pikachu (screenshot of the detection made on the app)
Tensorflow 对象检测 API
这个包是 TensorFlow 对对象检测问题的回应——即在一帧中检测真实世界对象(或皮卡丘)的过程。根据文档和介绍该库的论文,它的独特之处在于它能够以准确性换取速度和内存使用(反之亦然),因此你可以调整模型以适应你的需求和你选择的平台,如手机。该库包括许多开箱即用的对象检测架构,如 SSD (单次检测器)更快的 R-CNN (更快的基于区域的卷积神经网络) R-FCN (基于区域的完全卷积网络),以及几个特征提取器,如 MobileNet 、 Inception 、Resnet;这些提取器非常重要,因为它们在系统的速度/性能权衡中起着重要作用。
此外,该库还提供了几个已经训练好的模型,准备用于检测,在 Google Cloud 中训练的选项,加上 TensorBoard 的支持,以监控训练。
现在我们已经对这个实验所使用的系统有了一些了解,我将继续解释如何构建您自己的定制模型。
构建您自己的定制模型
装置
在我们开始之前,请确保您的计算机上安装了 TensorFlow。否则,请参见此处的说明了解如何安装。接下来,克隆包含对象检测 API 的 repo。这是链接:https://github.com/tensorflow/models。
一旦您克隆了回购,导航到“研究”目录并执行:
# From tensorflow/models/research/
protoc object_detection/protos/*.proto --python_out=.
这将编译 Protobuf 库。如果你没有安装 Protobuf,可以从这里下载:https://developers . Google . com/protocol-buffers/docs/downloads
最后,您需要将库添加到PYTHONPATH
中。这可以通过执行以下命令来实现:
# From tensorflow/models/research/
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
有关所需的所有依赖项的更多详细信息,请参见官方文档,可从以下位置获得:https://github . com/tensor flow/models/blob/master/research/object _ detection/g3doc/installation . MD
现在,让我们看看我是如何从拥有许多皮卡丘图像变成 TensorFlow 可读的漂亮整洁的数据集的。
创建数据集和处理图像
创建数据集是成功定型模型所需的许多步骤中的第一步,在本节中,我将介绍完成此任务所需的所有步骤。
为了这个项目,我将 230 张中型皮卡丘的图片下载到一个名为 images 的目录中。为了获得更好的效果,我试图获得不同角度和形状的皮卡丘,但老实说,皮卡丘是一种不存在的黄色长耳朵老鼠,所以要找到它的大量图像有点困难。
Some of the images used
一旦你获得了所有的图像,下一步就是给它们贴标签。这是什么意思?因为我们在做物体检测,我们需要一个物体到底是什么的基本事实。为此,我们需要在对象周围绘制一个边界框,让系统知道框内的这个“东西”就是我们想要学习的实际对象。我做这个任务用的软件是一个叫 RectLabel 的 Mac app。
这是带有边框的图像的外观:
Image of an angry Pikachu surrounded by a bounding box
在 RectLabel 中,您需要为图像的每个边界框设置一个标签,在我的例子中,标签是“Pikachu”。一旦您标记了所有的图像,您会注意到您有一个名为“ annotations ”的目录,其中有许多描述每个图像的边界框的 XML 文件。
分成训练和测试数据集
一旦所有的图像都被标记,我的下一步就是将数据集分成训练和测试数据集。在图像所在的同一个目录中,我创建了一个名为" train 和" test "的目录,并将大约 70%的图像及其各自的 XML 添加到训练目录中,剩余的 30%添加到测试目录中。
生成 TFRECORD
分离数据集之后,唯一缺少的就是将我们的图像及其 XML 转换成 TensorFlow 可读的格式。所述格式被称为“ tfrecord ”,为了从我们的图像中生成它,需要两个步骤。首先,为了简单起见,使用 datitran 的GitHub(https://github.com/datitran/raccoon_dataset)上提供的xml_to_csv.py
代码的修改版本,将来自两组 XML 的数据(训练和测试)转换成两个 CSV 文件(同样,训练和测试)。然后,使用 CSV 文件,使用脚本generate_tfrecord.py
(也来自 datitran)创建 tfrecord 数据集。请记住,在运行脚本之前,您必须在函数class_text_to_int
中指定对象的类别。
*** EDIT**(23 . 01 . 17):Will Brickner报告称xml_to_csv.py
在最新版本的 RectLabel 上无法正常工作,他编写了一个更加健壮的新脚本。这里有:https://gist . github . com/wbrickner/efed F8 ab 0 ce 1705 de 1372 C1 e2f 49 DD 98多谢:)
创建标签映射
需要一张“标签图,标明标签及其索引。这是它们的样子。
item {
id: 1
name: 'Pikachu'
}
把“皮卡丘”标签换成你的,重要的是,总是从索引1
开始,因为0
是保留的。我把这个文件作为object-detection.pbtxt
保存在一个名为培训的新目录下。
训练模型
管道
完整的训练过程由一个名为“ 管道 ”的配置文件处理。所述管道被分成五个主要结构,它们负责定义模型、训练和评估过程参数以及训练和评估数据集输入。管道的骨架看起来像这样:
model {
(... Add model config here...)
}
train_config : {
(... Add train_config here...)
}
train_input_reader: {
(... Add train_input configuration here...)
}
eval_config: {
}
eval_input_reader: {
(... Add eval_input configuration here...)
}
但是!您不必从头开始编写整个管道。事实上,TensorFlow 开发人员建议培训应该使用他们自己已经培训过的模型作为起点。这背后的原因是从头开始训练一个全新的模型可能需要相当长的时间。因此,TensorFlow 为提供了几个配置文件,这些文件只需要很少的修改就可以在新的训练环境中工作。我用的型号是ssd_mobilenet_v1_coco_11_06_2017
发现这里。
在我的训练中,我使用配置文件[ssd_mobilenet_v1_pets.config](https://github.com/tensorflow/models/blob/master/research/object_detection/samples/configs/ssd_mobilenet_v1_pets.config)
作为起点。我对变量num_classes
做了更改,因为我的类数只有一个,num_steps
用于提前停止训练,fine_tune_checkpoint
指向模型下载的位置,train_input_reader
和eval_input_reader
的input_path
和label_map_path
变量指向训练和测试数据集以及标签映射。
我不会仔细检查配置文件的每一个细节,因为老实说,我不理解它的某些部分,因为它太大了。不过,我想解释一下 SSD 和 MobileNet 是什么意思,这样你就可以对幕后发生的事情有一点了解。
SSD ,代表单发探测器,是一种神经网络架构,基于单前馈卷积神经网络。它被称为“单次拍摄”,因为它预测了图像的类别和在同一步骤中代表检测(称为锚点)的方框的位置。与此相反的是一种架构,它需要称为“提议生成器”的第二个组件来预测盒子的确切位置。
MobileNet 是一个卷积特征提取器,设计用于移动设备,用于获取图像的高层特征。
准备好管道后,将其添加到“培训目录中。然后,使用以下命令开始训练:
python object_detection/train.py --logtostderr
--train_dir=path/to/training/
--pipeline_config_path=path/to/training/ssd_mobilenet_v1_pets.config
培训期间和培训后评估模型
这个库提供了在训练期间和之后评估模型所需的代码。每次训练产生一个新的检查点时,评估工具将使用给定目录中可用的图像执行预测(在我的例子中,我使用了来自测试集的图像)。
要运行评估工具,请执行以下命令:
python object_detection/eval.py --logtostderr
--train_dir=path/to/training/
--pipeline_config_path=path/to/training/ssd_mobilenet_v1_pets.config
--checkpoint_dir=path/to/training/ --eval_dir=path/to/training/
张量板
使用 TensorFlow 的可视化平台 TensorBoard 可以看到培训和评估阶段的结果。在这里,我们可以监控几个指标,如训练时间、总损耗、步数等等。真正酷的是 TensorBoard 还可以在模型被训练时工作,这使它成为一个确保训练朝着正确方向前进的伟大工具。
要执行 TensorBoard,请运行以下命令:
tensorboard --logdir=path/to/training/
导出模型
训练完成后,下一步是导出模型以便使用。这个库提供了执行这个步骤所需的脚本,名为export_inference_graph.py
。
在导出之前,请确保培训目录中有以下文件:
model.ckpt-${CHECKPOINT_NUMBER}.data-00000-of-00001,
model.ckpt-${CHECKPOINT_NUMBER}.index
model.ckpt-${CHECKPOINT_NUMBER}.meta
您可能有几个格式相同但检查点编号不同的文件。因此,只需选择所需的检查点,并执行以下命令:
python object_detection/export_inference_graph.py --input_type image_tensor --pipeline_config_path=path/to/training/ssd_mobilenet_v1_pets.config --trained_checkpoint_prefix=path/to/training/model.ckpt-xxxxx --output_directory path/to/output/directory
输出将是一个文件,其中保存了名为frozen_inference_graph.pb
的模型的“冻结”版本。
结果
训练阶段结束时,模型的精度为 87% ,总损耗为 0.67 。但是在训练过程中,模型达到了最大精度 95% 。尽管如此,精度最高的模型并没有我预期的那么好。比如它把很多黄色物体(甚至有些人)归为皮卡丘。另一方面,我注意到精度为 87%的模型产生了更少的误报,代价是错过了一些皮卡丘。下图是 TensorBoard 制作的总损耗和精度图。
Total loss. The light orange line are the actual values; the dark one is a smoothed version
Precision metric
TensorBoard 还会自动评估评估集的一些图像。真正好的是,通过使用滑块,您可以看到预测的可信度如何根据模型的哪个检查点而变化。
More Pikachu. This detection was performed in TensorBoard
图像检测包包括一个笔记本,用于测试 TensorFlow 提供的预训练模型之一。然而,这个笔记本可以被改变以与定制训练模型的冻结版本(我们输出的那个)一起工作,我就是这样做的。下面你可以在笔记本上看到一些检测结果。
Pikachu hitting those weights
Pikachu and lil bro
Humans dressed as Pikachu. Not detected.
检测 Android 中的皮卡丘
到目前为止,我们已经训练、导出了模型,并对其进行了评估。现在是时候将它导入 Android 了,这样我们就可以用它来通过手机的摄像头检测皮卡丘了。现在,这部分有点复杂,让我很头疼,所以我会尽可能详细地解释主要步骤。然而,我真的确信你们中的一些复制这个实验的人会有一些问题,所以如果我的向导不支持你,我想事先道歉。
让我们继续讨论 TensorFlow 的 Android 部分。首先,你需要下载 Android Studio 。一旦你有了它,克隆 TensorFlow repo(你可能已经有了),在 Android Studio 中使用刚刚克隆的 TensorFlow repo 的目录导入一个新项目,名为“ Android ”。作为补充说明,我还建议通读 README 来熟悉一下这个库。
自述文件建议保持最简单的构建,并建议将 Gradle 构建的nativeBuildSystem
变量改为none
,然而,我将其改为cmake
来构建它(其他构建替代方案如 Bazel 和 Makefile 都不适合我)。
当构建完成时,下一步是将冻结的模型添加到资产目录中。然后,同样在那个文件夹中,创建一个名为“ labels ”的文件,在第一行写???
(还记得我说过第一类是保留的吗?),并在第二行写下你的对象的标签(在我的例子中我写了Pikachu
)。
然后,打开位于“ java 目录下名为“DetectionActitivity.java的文件;这是应用程序用来执行检测的代码。查找变量TF_OD_API_MODEL_FILE
和TF_OD_API_LABELS_FILE
,在第一个变量中,将其值更改为位于 assets 文件夹中的冻结模型的路径,在第二个变量中,写入带有标签的文件的路径。你应该知道的另一个有用的变量是MINIMUM_CONFIDENCE_TF_OD_API
,它是跟踪检测所需的最小置信度。试着玩玩吧!
现在我们准备好了!点击运行按钮,选择您的 Android 设备,等待几秒钟,直到应用程序安装到手机上。重要的细节,不是一个,而是四个应用程序,将被安装在手机上,然而,我们包含检测模型的是 TF Detect 。如果一切顺利,应用程序启动,找到一些你的对象的照片,看看模型是否能够检测到它们。
就是这样!快乐检测:)
以下是我在手机里做的一些检测。
My Kimono Pikachu. Straight from Kyoto
Several Pikachu. Noticed how most of them were not detected.
编辑 (05.06.2018):这项工作的延续,检测视频中的皮卡丘,可在此处获得:
本指南解释了如何使用 TensorFlow 对象检测模型来查找视频中皮卡丘
towardsdatascience.com](/detecting-pikachu-in-videos-using-tensorflow-object-detection-cd872ac42c1d)
结论和概述
在本文中,我解释了使用 TensorFlow 对象检测库训练自定义模型的所有必要步骤。在开始时,我给出了一些关于这个库的背景信息和它是如何工作的,然后是一个关于如何标记和处理图像以生成数据集的指南。之后,我专注于如何进行训练。在这一节中,我谈到了培训管道,如何使用 TensorBoard 评估模型。然后,一旦训练完成,我就在 Python 笔记本和 Android 中经历了导出模型和导入的过程。
这个项目最困难的部分是让模型在 Android 上运行。毫不夸张地说,这花了我大约一个月的时间,因为我得到了大量的错误,(我甚至在 Github 上开了一期),我几乎要放弃了。对我来说,解决问题的方法是在export.py
文件(由export_inference_graph.py
调用)中,将参数optimize_graph
修改为False
。显然,据我所知,通过优化模型,我的模型创建了一些 Android 库无法识别的节点,因此,它崩溃了。我不是说这是一个解决方案,但它可能是你可以尝试的东西,以防它对你不起作用。我的建议是不要放弃,继续尝试,这样你就可以用自己定制的检测系统打动你的朋友。
感谢您的阅读,我真的希望这篇指南能帮助到你们中的一些人。如果你有任何问题,评论,疑问,或者只是想聊天,留下评论,我将很乐意帮助你。
利用 k-均值聚类和 RANSAC 检测故障线路
k 均值聚类和随机样本一致性
Fig. 1- fitted plane from the last blog
在我的上一篇博文中,我使用主成分分析法(PCA)探测了帕克菲尔德附近圣安地列斯断层沿线的断层线。虽然已知断层线在该区域几乎是垂直的,但拟合的平面却相当水平(图 1)。这大概是因为 PCA 对“异常值”非常敏感,因为它是基于相关/协方差矩阵的方法。也可以假定,由于所有点的权重相同,一些远离主断层线的数据点可能使平面发生了倾斜。为了改善结果,采取了几种不同的方法,我将在这篇博客中详细介绍这些步骤。
K 均值聚类
由于断层结构非常复杂,所以在上一篇博客中,从整个数据集中随机选择一部分来拟合一个平面,而不是将一个平面拟合到整个数据集中。然而,这可能会潜在地导致一个问题,因为我们不知道所选择的点是否属于同一断层结构。因此,不是随机选择一个子集,而是应用 k 均值聚类将数据点分成更多“相似”点的聚类。
k 均值聚类是一种聚类算法,它将数据点分成 n 个聚类。通过 1)将数据点分配到最近的质心,2)将质心位置更新到所分配的数据点的中心,以及 3)将数据点重新分配到最近的质心,来确定每个聚类的最佳质心。这个过程重复进行,直到它稳定下来,一旦完成,分配给质心的数据点就形成一个簇。
轮廓系数
Fig. 2 silhouette coefficient
轮廓系数用于确定最佳聚类数(图 2)。轮廓系数,取值在-1 到 1 之间,表示每个点分配给其分类的情况。测量从一个点到它自己的聚类以及到它的相邻聚类的距离(可以使用任何种类的距离度量,在这种情况下使用欧几里德距离),并且比较这些距离。下面是推导轮廓系数 s 的公式:
其中 a 是从一个数据点到同一聚类中所有数据点的平均距离,而 b 是从该点到最近聚类中所有数据点的平均距离。
高值表示它被很好地分配给自己的簇,低/负值表示它分配得不好。如图 2 所示,3 是该研究的最佳集群数。下图左侧显示了 3 组数据点,右侧显示了拟合的平面(像上次一样使用 PCA 来拟合平面)。
Fig. 3 * black dots are the centroids of the clusters
使用 k-means,拟合的平面看起来更好。但为了进一步改善结果,使用了异常值检测方法来消除一些可能会使平面倾斜的异常值。
随机样本一致性(RANSAC)
随机样本一致性是一种检测异常值的迭代方法。迭代方法使用初始猜测来生成一系列改进的近似。它广泛应用于图像处理领域,用于去除数据集中的噪声。因为它去除了异常值,所以您需要小心它的应用— RANSAC 只有在异常值对您预测的值没有影响时才是可行的。RANSAC 算法查找异常值的方式如下:
- 随机选择一个数据子集(假设内联者)
- 使用该子集,计算模型参数
- 将整个数据集与步骤 2 中建立的模型进行比较,所有与估计模型(基于损失函数)吻合的点将组成共识集 (=内联集)
RANSAC 有一个 sklearn 库,它有一个属性 inlier_mask_,告诉您哪些数据点被视为 inlier:
ransac = linear_model.RANSACRegressor()
ransac.fit(X, y)
inlier_mask = ransac.inlier_mask_
outlier_mask = np.logical_not(inlier_mask)
对于 3 个集群的导出的内层,拟合平面。图 4 中左图上的透明点是异常值,右图显示了拟合的平面。
Fig. 4 transparent data points are the ‘outliers’
结论
使用 k-均值聚类、RANSAC 和 PCA,拟合的断层线变得更加接近现实(而不是垂直平面)。由于 PCA 对远离其他观测值的点非常敏感,RANSAC 非常有助于防止这些点扭曲拟合平面。尽管在绘制主要断层线时忽略了这些异常值,但它们可能是某些潜在断层结构的一部分。将进一步研究这些异常值,以了解断层的复杂结构。
使用机器学习和计算机视觉检测车辆
来自 Udacity 自动驾驶汽车课程的最后一个项目是创建一个软件管道,它能够从汽车上的前置摄像头识别视频中的汽车。
A snapshot from the final output of the project
课程材料建议使用有点过时的方法来检测车辆,这是我在项目中途通过阅读这篇关于自动驾驶汽车的最先进的计算机视觉的伟大论文而发现的。报纸上一小段:
在 Dalal & Triggs (2005)的工作中,线性支持
向量机(SVMs)与
方向直方图(HOG)特征相结合,最大化来自线性决策边界的所有
样本的余量,已经成为流行的
分类工具。然而,所有以前的方法都依赖于难以设计的手工制作的特征。随着深度学习的复兴
,卷积神经网络已经
自动化了这项任务,同时显著提升了性能。
事实证明,深度神经网络优于我使用的方法(线性支持向量机结合梯度方向直方图)。我一定会回到这个项目中,在这个问题上尝试这个列表中的一些最佳表现者:
Table taken from https://arxiv.org/pdf/1704.05519.pdf
检测道路上的车辆的过程可以总结为以下步骤:
训练数据分析
训练数据由 Udacity 提供,由不同角度的汽车(8792)和非汽车 (8968)物体图像组成。这里有两个例子:
Examples from the training data set
特征抽出
为了检测图像上的汽车,我们需要识别唯一代表汽车的特征。我们可以尝试使用简单的模板匹配或依赖颜色特征,但这些方法在改变物体的视角和形状时不够健壮。
为了拥有一个健壮的特征集并提高我们的准确率,我们将使用梯度方向直方图 (HOG)。该特征描述符对流量的动态变化更有弹性。本质上,你应该把特征想象成你感兴趣的物体的指纹。
Scikit-image python 库为我们提供了计算 HOG 特征所必需的 API。我已经使用 YCrCb 颜色空间及其所有通道作为猪特征提取的输入。我尝试过其他颜色空间,但 YCrCb 在训练我的预测模型时给了我最好的准确性。这里有一个车辆和非车辆图像的样本,具有与上述图像相同的 HOG 特征:
Extracted HOG features from sample training data
HOG 特征提取基于 9 个方向,每个单元 8 个像素,每个块 2 个单元。增加方向和每个像元的像素参数确实可以缩短预测时间,但模型的准确率会下降。
模特培训
为了根据我们的特征集检测汽车,我们需要一个预测模型。对于这种特殊情况,我们将使用线性支持向量机(线性支持向量机)。这是一个监督学习模型,在我们训练它之后,它将能够分类某物是否是一辆汽车。
使用标准缩放器将 HOG 特征缩放至零均值和单位方差。
我将提供的数据集分为训练集(80%)和测试集(20%)。在训练开始之前,图片也进行了洗牌。最终提取的 HOG 特征在 YCrCb 颜色空间上的线性支持向量机模型达到了 98.06%的准确率。
推拉窗
一旦我们有了预测模型,就该在测试图像上使用它了。预测模型将应用于一种称为滑动窗口的特殊技术。使用这种技术,我们将在图像的子区域上运行预测模型,该子区域被划分为一个网格。
为了提高这种方法的稳健性,我们将添加多个网格,预测模型将遍历这些网格。我们这样做是因为汽车可以根据其在道路上的位置以各种大小出现在图像上。
Multi-window appraoch for sliding window technique
这是这个概念应用于我们的测试图像时的样子:
我使用了不同的窗口尺寸(从 128x128 的靠近汽车的区域到 64x64 的远离汽车的区域)。窗口重叠设置为 65%。
消除误报
为了提高最终输出的准确性,我们将尝试在相似区域找到感兴趣对象的多个匹配项。这种方法相当于创建一个热图。
下一步是引入阈值,为了将热图中的特定命中计数接受为检测到的汽车,需要满足该阈值。在我们的例子中,阈值的值为 2。
这是一个应用热图并将其阈值设定为特定值的示例。
最后结局
最终结果并不完美,但管道本身显示出良好的潜力。
结论
如果我有机会重新做这个项目,我可能会选择深度神经网络方法。我花了相当多的时间寻找正确的色彩空间、HOG 参数和窗口幻灯片的大小。
管道的性能不是很大,可以改进。深度神经网络方法将具有更好的性能数字。
由于这种汽车检测方法是基于摄像头的,这种传感器很容易遇到常见的挑战(能见度低、反光等)。).
项目可以在我的 Github 个人资料中找到:
CarND-Vehicle-Detection -车辆检测项目
github.com](https://github.com/bdjukic/CarND-Vehicle-Detection)
通过 ConvNets 进行检测和分割
Computer vision — Object detection and segmentation
神经网络在计算机视觉领域有广泛的应用。稍加改变,同样的工具和技术可以有效地应用于各种任务。在本文中,我们将介绍其中的几个应用程序以及接近它们的方法。最常见的四种是
- 语义分割
- 分类和定位
- 物体检测
- 实例分割
语义分割
我们输入一幅图像,并输出每个像素的类别判定。换句话说,我们希望将每一个像素归入几个可能的类别之一。这意味着,所有带有绵羊的像素将被分类到一个类别中,带有草地和道路的像素也是如此。更重要的是,输出不会区分两只不同的羊。
解决这个问题的一个可能的方法是把它当作一个带有滑动窗口的分类问题。通过这种方式,我们获取一个输入图像,并将其分成几个相同大小的裁剪部分。然后,每种作物都会被输入到 CNN,以获取该作物的分类类别作为输出。像素级的作物将对每个像素进行分类。那是超级容易的不是吗?
Semantic segmentation using sliding window
好吧,它甚至不需要一个研究生学位就能看出这种方法在实践中的计算效率有多低。我们需要的是一种将图像的通过次数减少到最多一次的方法。幸运的是,有建立具有所有卷积层的网络的技术来一次对所有像素进行预测。
Fully convolutional layer for semantic segmentation
如你所见,这样的网络将是下采样和上采样层的混合,以便保持输入图像的空间大小(在像素级进行预测)。下采样是通过使用步长或最大/平均池来实现的。另一方面,上采样需要使用一些巧妙的技术,其中两种是— 最近邻和转置卷积。
Up sampling techniques
简而言之,最近邻只是复制其感受野中的特定元素(上面例子中的 2x2)。另一方面,转置卷积努力学习执行上采样所需的滤波器的适当权重。在这里,我们从左上角值开始,它是一个标量,乘以过滤器,并将这些值复制到输出像元中。然后,我们在输出中按输入中一个像素移动的比例移动滤波器的一些特定像素。这个,输出和输入之间的比率,会给我们想要使用的步幅。在重叠的情况下,我们只是将这些值相加。这样,这些滤波器也构成了这些网络的可学习参数,而不是像最近邻的情况那样的某个固定值集。最后,我们可以使用像素级的交叉熵损失通过反向传播来训练这整个网络。
分类和本地化
图像分类处理给图像分配类别标签。但有时,除了预测类别,我们还对图像中该对象的位置感兴趣。用数学术语来说,我们可能想要在图像中的对象周围画一个边界框,如顶部的图片所示。幸运的是,我们可以重用我们在图像分类中学到的所有工具和技术。
Convolutional network for Classification + Localization
我们首先将输入图像输入到一个巨大的 ConvNet,它会给我们每个类别的分数。但是现在我们有了另一个完全连接的层,它从早期层生成的特征图中预测对象边界框的坐标(中心的 x,y 坐标以及高度和宽度)。因此,我们的网络将产生两个输出,一个对应于图像类,另一个对应于边界框。此后,为了训练这个网络,我们必须考虑两个损失,即分类的交叉熵损失和边界框预测的 L1/L2 损失(某种回归损失)。
概括地说,这种预测固定数目集合的思想可以应用于各种各样的计算机视觉任务,而不是定位,例如人类姿势估计。
Human pose estimation
在这里,我们可以通过身体上的一组固定点来定义人的姿势,例如关节。然后,我们将图像输入到 ConvNet,并输出相同的固定点(x,y)坐标。然后,我们可以在这些点上应用某种回归损失,通过反向传播来训练网络。
目标检测
对象检测的思想是,我们从一些我们感兴趣的固定类别集合开始,并且任何时候这些类别中的任何一个出现在输入图像中,我们将在该图像周围绘制边界框,并预测其类别标签。这在某种意义上不同于图像分类和定位,在前者中,我们将只围绕单个对象分类和绘制边界框。而在后一种情况下,我们事先不知道在图像中预期有多少对象。同样,我们也可以应用强力滑动窗口方法来解决这个问题。然而,这也是计算效率低下的。相反,很少有算法被开发来有效地解决这个问题——基于区域提议的算法和 YOLO 对象检测算法。
基于区域提议的算法
给定一幅输入图像,区域提议算法将给出数千个可能存在物体的方框。当然,输出中有可能存在噪声,就像没有物体的盒子一样。然而,如果图像中存在任何对象,则该对象将被算法选为候选框。
Selective search for region proposals
为了使所有的候选盒子大小相同,我们需要将它们扭曲成某个固定的正方形大小,这样我们就可以最终把它提供给网络。然后,我们可以将一个巨大的 ConvNet 应用于从区域建议输出的每个候选框,以获得最终的类别。毫无疑问,与强力滑动窗口算法相比,它的计算效率要高得多。这是 R-CNN 背后的整个想法。现在,为了进一步降低复杂性,使用了快速 R-CNN。快速 R-CNN 背后的思想是首先通过使输入图像通过 ConvNet 来获得高分辨率的特征图,然后将那些区域建议施加到该特征图上,而不是实际图像上。当我们有大量的作物时,这允许我们在整个图像上重复使用大量昂贵的卷积计算。
YOLO(你只看一次)
YOLO object detection
YOLO 背后的想法是,通过将它重新构建为一个单一的回归问题,直接从图像像素到边界框坐标和类概率,而不是在提议的区域中进行独立的处理,来一次做出所有的预测。
我们首先把整个输入图像分成 SxS 网格。每个网格单元预测 C 个条件类概率(Pr(Class | Object))以及 B 个边界框(x,y,w,h),每个边界框都有一个置信度得分。(x,y)坐标表示相对于网格单元边界的框的中心,而宽度和高度是相对于整个图像预测的。概率取决于包含对象的网格单元。我们只预测每个网格单元的一组类概率,而不考虑盒子 b 的数量。置信度得分反映了模型对盒子包含对象的置信度。如果盒子中没有物体,那么置信度得分必须为零。在另一个极端,置信度得分应该与预测框和真实标签之间的交集(IOU)相同。
**Confidence score = Pr(Object) * IOU**
在测试时,我们将条件类概率和单个盒子的置信度预测相乘,这给出了每个盒子的特定于类的置信度得分。这些分数编码了该类出现在框中的概率以及预测的框与对象的匹配程度。
**Pr(Class | Object) ∗ (Pr(Object) ∗ IOU) = Pr(Class) ∗ IOU**
实例分割
实例分割采用语义分割和对象检测技术。给定一幅图像,我们希望预测该图像中对象的位置和身份(类似于对象检测),然而,我们希望预测这些对象的整个分割掩模,即输入图像中的哪个像素对应于哪个对象实例,而不是预测这些对象的边界框。在这种情况下,我们为图像中的每只羊获得单独的分割掩码,这与语义分割形成对比,在语义分割中,所有的羊获得相同的分割掩码。
Mask R-CNN for instance segmentation
Mask R-CNN 是这类任务的首选网络。在这个多阶段处理任务中,我们将输入图像通过一个 ConvNet 和一些学习区域建议网络。一旦我们有了这些区域建议,我们就把这些建议投射到卷积特征图上,就像我们在 R-CNN 中所做的那样。然而现在,除了进行分类和边界框预测之外,我们还为这些区域提议中的每一个预测分割掩模。
资源
我在玩一个最先进的物体探测器,Ross Girshick 最近发布的 RCNN。方法…
cs.stanford.edu](https://cs.stanford.edu/people/karpathy/rcnn/) [## YOLO 算法-对象检测| Coursera
deeplearning.ai 为课程“卷积神经网络”创建的视频。学习如何运用你在…方面的知识
www.coursera.org](https://www.coursera.org/lecture/convolutional-neural-networks/yolo-algorithm-fF3O0)
请让我在评论中知道这篇文章可以容纳的任何改进/修改。
用 Python 开发一个 NLP 模型&用 Flask 逐步部署它
Flask API,文档分类,垃圾邮件过滤器
到目前为止,我们已经开发了许多机器学习模型,根据测试数据生成数值预测,并测试结果。我们在网下做所有的事情。实际上,生成预测只是机器学习项目的一部分,尽管在我看来这是最重要的一部分。
考虑使用机器学习来检测垃圾 SMS 文本消息的系统。我们的 ML 系统工作流程是这样的:离线训练->将模型作为服务提供->在线预测。
- 用垃圾邮件和非垃圾邮件消息离线训练分类器。
- 经过训练的模型被部署为服务用户的服务。
Figure 1
当我们开发一个机器学习模型时,我们需要考虑如何部署它,也就是如何让这个模型可供其他用户使用。
Kaggle 和数据科学训练营非常适合学习如何构建和优化模型,但它们不会教工程师如何将他们带到下一步,在这一步,构建模型和实际准备好让人们在他们的产品和服务中使用模型之间存在重大差异。
在本文中,我们将关注这两个方面:为垃圾短信分类建立一个机器学习模型,然后使用用于构建 web 应用程序的 Python 微框架 Flask 为该模型创建一个 API。这个 API 允许我们通过 HTTP 请求利用预测能力。我们开始吧!
ML 模型构建
这些数据是一组被标记为垃圾短信的短信,可以在这里找到。首先,我们将使用这个数据集来建立一个预测模型,该模型将准确地分类哪些文本是垃圾邮件。
朴素贝叶斯分类器是一种流行的电子邮件过滤统计技术。他们通常使用单词包功能来识别垃圾邮件。因此,我们将使用朴素贝叶斯定理构建一个简单的消息分类器。
NB_spam.py
Figure 2
朴素贝叶斯分类器不仅易于实现,而且能提供非常好的结果。
在对模型进行训练之后,需要有一种方法来保存模型以供将来使用,而不必重新训练。为了实现这一点,我们添加了下面几行代码,将我们的模型保存为一个. pkl 文件,供以后使用。
from sklearn.externals import joblib
joblib.dump(clf, 'NB_spam_model.pkl')
我们可以像这样在以后加载和使用保存的模型:
NB_spam_model = open('NB_spam_model.pkl','rb')
clf = joblib.load(NB_spam_model)
上述过程称为“以标准格式持久化模型”,即模型以特定于开发中语言的某种格式持久化。
并且该模型将在微服务中提供服务,该微服务公开端点以接收来自客户端的请求。这是下一步。
将垃圾邮件分类器转变为 Web 应用程序
在前面的部分中已经准备好了对 SMS 消息进行分类的代码,我们将开发一个 web 应用程序,它由一个简单的 web 页面组成,该页面带有一个表单字段,可以让我们输入消息。在将消息提交给 web 应用程序后,它将在一个新页面上呈现它,这给我们一个垃圾邮件或非垃圾邮件的结果。
首先,我们为这个项目创建一个名为SMS-Message-Spam-Detector
的文件夹,这是文件夹中的目录树。我们将解释每个文件。
spam.csv
app.py
templates/
home.html
result.html
static/
style.css
SMS-Message-Spam-Detector folder
templates folder
static folder
SMS Message Spam Detector folder
子目录templates
是 Flask 在 web 浏览器中查找静态 html 文件的目录,在我们的例子中,我们有两个 HTML 文件:home.html
和result.html
。
app.py
app.py
文件包含了 Python 解释器运行 Flask web 应用程序所要执行的主要代码,它包含了对 SMS 消息进行分类的 ML 代码:
app.py
- 我们将应用程序作为一个单独的模块运行;因此,我们用参数
__name__
初始化了一个新的 Flask 实例,让 Flask 知道它可以在它所在的同一个目录中找到 HTML 模板文件夹(templates
)。 - 接下来,我们使用 route decorator (
@app.route('/')
)来指定应该触发home
函数执行的 URL。 - 我们的
home
函数只是呈现了位于templates
文件夹中的home.html
HTML 文件。 - 在
predict
函数中,我们访问垃圾邮件数据集,预处理文本,进行预测,然后存储模型。我们访问用户输入的新消息,并使用我们的模型对其标签进行预测。 - 我们使用
POST
方法在消息体中将表单数据传输到服务器。最后,通过在app.run
方法中设置debug=True
参数,我们进一步激活了 Flask 的调试器。 - 最后,我们使用了
run
函数,仅在 Python 解释器直接执行该脚本时在服务器上运行应用程序,这是通过使用带有__name__ == '__main__'
的if
语句来确保的。
home.html
以下是home.html
文件的内容,该文件将呈现一个文本表单,用户可以在其中输入消息:
home.html
style.css
在home.html
的头段,我们加载了styles.css
文件。CSS 决定了 HTML 文档的外观和感觉。styles.css
必须保存在一个名为static
的子目录中,这是默认目录,Flask 会在这个目录中查找 CSS 等静态文件。
style.css
result.html
我们创建一个result.html
文件,该文件将通过predict
函数中的render_template('result.html', prediction=my_prediction)
行返回来呈现,我们在app.py
脚本中定义该函数来显示用户通过文本字段提交的文本。result.html
文件包含以下内容:
result.html
从result.htm
我们可以看到一些代码使用了 HTML 文件中通常没有的语法:{% if prediction ==1%},{% elif prediction == 0%},{% endif %}
这是 jinja 语法,它用于在 HTML 文件中访问从我们的 HTTP 请求返回的预测。
我们快到了!
完成上述所有操作后,您可以通过双击appy.py
或从终端执行命令来开始运行 API:
cd SMS-Message-Spam-Detector
python app.py
您应该得到以下输出:
Figure 3
现在,您可以打开 web 浏览器并导航到 http://127.0.0.1:5000/ ,我们应该会看到一个简单的网站,内容如下:
Figure 4
让我们测试我们的工作!
spam_detector_app
恭喜你!我们现在已经以零成本创建了一个端到端的机器学习(NLP)应用。回过头来看,整体流程一点都不复杂。只要有一点耐心和学习的欲望,任何人都可以做到。所有的开源工具让一切成为可能。
更重要的是,我们能够将我们的机器学习理论知识扩展到一个有用和实用的 web 应用程序,并让我们能够向外界提供我们的垃圾短信分类器!
完整的工作源代码可以在这个库获得。祝你一周愉快!
参考:
本书: Python 机器学习
使用 Matplotlib 开发良好的 Twitter 数据可视化
在本文中,我们将学习如何收集 Twitter 数据并使用 Python 创建有趣的可视化。我们将简要探讨如何使用 Tweepy 收集 tweets,并且我们将主要探讨使用 Matplotlib 的 Twitter 数据的各种数据可视化技术。在此之前,将解释数据可视化和实现它的总体统计过程。
首先,什么是数据可视化?
它是数据的图示或视觉表示。我们在报纸、新闻媒体、体育分析、研究论文中看到过,有时也在广告中看到过。数据可视化模型常见的例子有:折线图,散点图,饼图,条形图(使用这些模型很容易做可视化)。
创建数据可视化模型很重要,为什么?
——一张图能说千言万语。表示多行数据的图形可以提供数据的全貌,并可以揭示数据中包含的模式。
-数据可视化是统计分析的一部分。统计学在各个领域都有很多应用。
-开发新算法可以训练你的创造力和解决问题的能力。Matplotlib 有自己的绘制数据的工具,但是我们可能不局限于它,以便有更多的模型和更多种类的可视化。
-不同的模型可以给出关于数据的不同观点。
统计过程(P-C-A-I)
该过程遵循一个简单的流程。流程从提出问题开始,例如:“NatGeo 帐户倾向于发布什么?”。有了问题之后,我们进行适当的数据收集。在收集阶段,也许有许多方法可以获得 Twitter 数据,但这里选择使用 Tweepy。收集完毕后我们将进入一分析部分。这就是我们应该选择适当的数学或统计方法来分析数据的地方。分析数据的一种方式是通过数据可视化。最后,最后一个阶段是解释结果。请注意,我们最终可能会得到另一个问题的答案,这意味着流动可能是循环的。
PCAI flow (source)
我们已经简要讨论了数据可视化和支持它的统计过程。对于我们的调查,我们已经知道要回答的问题将与 Twitter 数据相关,因此在具体定义问题之前,我们将首先查看数据收集。
收集 Twitter 数据
我们可以使用 Python 中的 Tweepy 库自动收集一个比较大的 Twitter 数据。这是一个用于访问 Twitter API 的外部 Python 库。为了使这个库有用,我们必须首先为我们的 Twitter 帐户创建一个 Twitter 应用程序。注册后,我们将获得私有信息:消费者密钥、消费者秘密、访问秘密和访问令牌。使用 Tweepy 访问我们的 Twitter API 需要这些信息。
用 Python 创建 Twitter API 对象的一个例子:
import tweepy
consumer_key = 'ecGxfboL66oO2ZwxfKkg7q3QK'
consumer_secret = 'exVRiv517gdwkPLP19PtlQMEIRjxgJr21JZCAAQYIqJCUW5vmh'
access_token = '3151279508−Ywd662Zv97Ie7E7I97dUm0e3s2X8yYBloJQd6Gr'
access_secret = 'BH5REW4V7RdGadMr31NLY9ksFypG12m8BR04S32ZF7jO3'auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
our_api = tweepy.API(auth)
现在我们可以通过**our_api**
开始使用 Twitter API 了。
我们可以通过应用方法**our_api.home_timeline()**
直接从我们的 home timeline 中收集推文,该方法默认收集 20 条最近的推文(包括转发的推文)。要调整所需的推文数量(以 100 条推文为例),请使用**our_api.home_timeline(count = 100)**
。要收集特定账户的推文(以@NatGeo 为例),使用方法**our_api.user_timeline(screen_name = 'NatGeo', count = 100)**
。
上述方法的一个缺点是,它最多只能收集 200 条推文。为了克服这一点,我们可以使用**tweepy.Cursor**
类。要收集 2000 条@NatGeo tweets,然后将文本、转发数和赞数保存在一个列表中,我们可以执行如下操作。
natgeo_cursor = tweepy.Cursor(our_api.user_timeline, screen_name = 'NatGeo')
natgeo_tweets = [(tweet.text, tweet.retweet_count, tweet.favorite_count) \
for tweet in natgeo_cursor.items(2000)]
**natgeo_cursor.items(n)**
中的每一项都是一个**tweepy.models.Status**
对象,从中我们可以获得 tweet 数据,比如文本、作者信息(以**tweepy.models.User**
对象的形式)、创建时间、转发次数、赞数和媒体。
结果:
>>> natgeo_tweets[0]
("As Chernobyl's gray wolf population increases, their influence
on the surrounding environment is called into questi… https://t.co/elsb4FJQGZ", 428, 1504)
>>> natgeo_tweets[1]
('1,058 temples in the south Indian state of Kerala that have
pledged to eliminate plastic this year [https://t.co/ltJ6mFIWpV',](https://t.co/ltJ6mFIWpV',) 268, 985)
到目前为止,我们已经看到了如何使用 Tweepy 来收集实际的 Twitter 数据。现在让我们好奇,用 Matplotlib 把它们可视化。
*代替上述结果,我们将使用各种 Twitter 数据集进行可视化。
最小数据可视化
首先,让我们看一个在我们的家庭时间轴中绘制推文的用户名频率的例子。用户名频率是在我们的数据中出现的来自特定用户名的推文数量。推文数据将是来自家庭时间轴的 200 条推文。下面是条形图结果后面的代码示例。
import matplotlib.pyplot as plthome_cursor = tweepy.Cursor(api.home_timeline)
tweets = [i.author.screen_name for i in home_cursor.items(200)]
unq = set(tweets)
freq = {uname: tweets.count(uname) for uname in unq}
plt.bar(range(len(unq)), freq.values())
plt.show()
正如你所看到的,该图显示在时间轴中有 42 个不同的 Twitter 帐户发推文,只有一个帐户发推文最多(41 条推文)。万一你想知道,最常去的账号是@CNNIndonesia。但我们必须承认,我们无法看到数据中出现的用户名,从条形图中无法收集到太多信息(尽管这仍然比完全没有可视化要好)。这就是为什么我们应该学习在 Matplotlib 之上开发自己的算法来修改数据可视化(这可以导致各种模型)。
从上面的尝试中我们能学到什么?
根据www.informationisbeautiful.net 的作者 David McCandless 的观点,一个好的数据可视化有 4 个关键要素:信息、故事(概念)、目标、视觉形式(隐喻)。信息是数据,这个元素的关键词是准确性、一致性和诚实。*故事(概念)*就是让数据 vis 变得有趣。目标是数据的有用性和效率。*视觉形式(比喻)*就是美和外观。
by David McCandless
上面的第一个条形图肯定有信息元素,数据是准确的。它还有一点目标和最小视觉形式(横条)。但它根本没有故事(概念)(只有数据的创造者 vis 才知道剧情背后的故事),它至少应该告知观者它是关于 Twitter 数据的。
为了提高我们的视觉效果,我们将应用 4 个关键要素。但是为了有趣,我们将只在 Python 中使用 Matplotlib。
在接下来的部分中,我们将会看到一些与各种 Twitter 数据相关的问题或目标,并执行数据可视化。
案例一。目标:账户对比,模型:修改后的横条图
在这种情况下,我们将使用我几个月前从我的家庭时间轴中收集的 192 条推文的数据。数据将被转换,这样我们可以按账户对推文进行分组,然后我们将通过数据可视化来比较这些数字。值得注意的是,我们将开发一个良好的数据可视化,它结合了各种 Matplotlib 特性,而不局限于它所拥有的绘图模型。
我们将在 Python 中使用的模块有:
import numpy
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import operator
import itertools
数据表示的代码如下所示。它将按用户名对推文进行分组,然后统计推文数量(也可以被视为用户名频率)和每个用户名的关注者数量。它还将按用户名频率对数据进行排序。
home_tweets = list(numpy.load('testfile.npy'))unicity_key = operator.attrgetter('author.screen_name')
tweets = sorted(home_tweets, key=unicity_key)authors_tweets = {}
followers_count = {}
sample_count = {}
for screen_name, author_tweets in itertools.groupby(tweets, key=unicity_key):
author_tweets = list(author_tweets)
author = author_tweets[0].author authors_tweets[screen_name] = author
followers_count[screen_name] = author.followers_count
sample_count[screen_name] = len(author_tweets)maxfolls = max(followers_count.values())sorted_screen_name = sorted(sample_count.keys(), key = lambda x: sample_count[x])
sorted_folls = [followers_count[i] for i in sorted_screen_name]
sorted_count = [sample_count[i] for i in sorted_screen_name]
接下来,我们可以通过**plt.hbar(range(len(sorted_count)),sorted_count)**
轻松地执行水平条形图,然后设置图形和 x-y 轴的标题,但是让我们随机应变。我们将通过添加颜色透明度差异来添加额外的视觉形式,例如:条形的透明度可能代表账户的关注者数量。我们还将把 y 轴上的刻度标签从数字改为用户名字符串。代码如下:
colors = [(0.1, 0.1, 1, i/maxfolls) for i in sorted_folls]fig, ax = plt.subplots(1,1)y_pos = range(len(colors))
ax.set_yticks(y_pos)
ax.set_yticklabels(sorted_screen_name, font_properties = helv_8)ax.barh(y_pos, sorted_count, \
height = 0.7, left = 0.5, \
color = colors)for i in y_pos:
ax.text(sorted_count[i]+1, i, style_the_num(str(sorted_folls[i])), \
font_properties = helv_10, color = colors[i])ax.set_ylim(-1, y_pos[-1]+1+0.7)
ax.set_xlim(0, max(sorted_count) + 8)ax.set_xlabel('Tweets count', font_properties = helv_14)plt.tight_layout(pad=3)
fig.show()
请注意,我们还更改了字体样式,并使用**style_the_num**
函数为关注者计数的字符串即兴创作(将**22441917**
映射到**22,441,917**
)。以下是绘图结果:
很明显,上面的图显示了更多的信息,看起来比第一个图更好。视觉效果也有助于解释数据。剧情在*故事(概念)*元素上也更有价值,看起来相当活灵活现(我们不需要投入太多精力去理解可视化)。
*对不起,但也许情节应该有一个文本解释蓝色透明度的含义(这是帐户的追随者数量)。
案例二。目标:一个账号发布的图片的种类和受众的喜好,模型:图片情节
在这种情况下,我们将 1000 条@NatGeo 推文的数据集(收集于 2018 年 9 月 19 日)。1000 条推文中的每一条都可以有图片,也可以没有。因此,为了实现本案例的目标,我们必须首先收集数据中存在的所有图像。之后会介绍一个形象剧情。Python 的实现是通过创建**PlotDecorator**
类来完成的,然后使用实例来生成图像 plot。**PlotDecorator**
类有方法**gen_img(prev_img, next_img)**
、**put_below(left_img, next_img)**
和**generate(imgs, ncol)**
。对算法的解释:
-
**gen_img(prev_img, next_img)**
:
紧紧在前一幅图像的右侧绘制下一幅图像。**next_img**
参数是一个**matplotlib.image.AxesImage**
对象,而**prev_img**
是一个包含左侧图像的**AxesImage**
对象的字典。该函数使用**next_img.get_extent(...)**
和**next_img.set_extent(...)**
方法设置下一幅图像的属性,使其位于前一幅图像(左侧图像)的旁边。 -
**put_below(left_img, next_img)**
:
与上述第一种方法相似,但下一幅图像位于该行最左侧图像下方的*。这是因为每行只能有**ncol**
个图像。* -
**generate(imgs, ncol)**
:
这是我们生成图像新位置的地方。**imgs**
是我们想要绘制的**AxesImage**
对象的列表。例如,如果**ncol=10**
,该功能将应用**gen_img(prev_img, next_img)**
10 次,然后应用**put_below(left_img, next_img)**
并重新开始新一行图像。
在收集和放置好图片后,我们计算每张图片的转发次数,然后只显示转发次数最多的前 3 张图片的辅助装饰。装饰只是一个紫色的圆圈,图像周围没有填充(透明度给出了等级的线索)。这是结果,它从完整的图像开始,然后放大,然后再次放大转发最多的图像:
让我们评价一下上面的数据可视化。很明显它有着*视觉形式(隐喻)*的体面价值(还不错)概念相当好听(很有意思)。我们得到的信息是转发数最高的前 3 张图片和图片的模式(所有图片都是很棒的照片,没有海报、引用等图片)。
*还是那句话,也许剧情应该有一小段说明剧情的意义。
案例三。目的:两个词之间的关系,模型:Twitter 维恩图
在这种情况下,我们将使用@jakpost(雅加达邮报)3214 条推文的数据集。最早的推文创建于 2018 年 5 月 8 日,最新的创建于 2018 年 6 月 22 日。我们的目标是想知道一组推文中的两个词之间是否有联系。找出答案的一个方法是检查所选的单词是否在一条推文中使用。
有一种叫做 Twitter 维恩图的方法可以用来可视化两个词在一组推文中是如何连接的。我们将采用 Twitter 维恩图,并使用 Matplotlib 进行一点即兴创作(代码示例可在此 repo 中获得)。我使用 TextBlob 从推文中收集单词。
*算法以最明显的方式编写,没有任何优化尝试。
即兴创作:代表每条推文的每个标记都有可见性值,该值代表转发计数比率(在圆圈中的推文中,转发计数最多的推文将具有最高的可见性值,即 1)。
现在让我们挑选两个有趣的词,例如,“雅加达”和“行政”。包含“雅加达”但不包含“行政”的推文将有红色标记,包含“行政”但不包含“雅加达”的推文将有蓝色标记。包含这两个词的推文将有绿色标记。下面是剧情。
上面的情节应该已经讲了意义本身。在 3214 条推文中,有 161 条推文包含“雅加达”,只有 14 条推文包含“行政”,9 条推文包含两者。转发聚集在“雅加达”圈,请注意有 3 条转发量非常高的推文。
现在让我们再举一个例子,用单词‘jokowi’和‘prabowo’。佐科维是红色的,普拉博沃是蓝色的。下面是剧情。
如果你对十字路口的一条推文感到好奇,下面是它的内容:
“普拉博沃指责佐科威政府削弱了 https://t.co/BxJ7hum7Um 的 TNI #杰克波斯特
总的来说,上面的 Twitter 数据可视化示例并不是可视化的最佳示例。但是我们已经看到了如何利用 Tweepy 和 Matplotlib,同时将良好的数据可视化的 4 个元素牢记在心。我们已经看到了如何组合不同的颜色和形状来为*视觉形式(隐喻)和故事(概念)*增加更多的价值。
在下面的链接中可以看到一些很棒的数据可视化示例(一般来说,不限于 Python 或 Matplotlib)。
-https://informationisbeautiful.net/
-https://datavizproject.com/
数据科学家 DevOps:驯服独角兽
当大多数数据科学家开始工作时,他们配备了从学校教科书中学到的所有简洁的数学概念。然而,很快,他们意识到数据科学的大部分工作涉及将数据转换成模型使用所需的格式。除此之外,正在开发的模型是最终用户应用程序的一部分。现在,数据科学家应该做的一件正确的事情是在 Git 上控制他们的模型代码版本。然后 VSTS 会从 Git 下载代码。然后,VSTS 将被包装在 Docker 映像中,该映像将被放在 Docker 容器注册表中。一旦注册,它将使用 Kubernetes 进行编排。现在,对普通的数据科学家说这些,他的大脑会完全关闭。大多数数据科学家知道如何提供带有预测的静态报告或 CSV 文件。然而,我们如何对模型进行版本控制并将其添加到应用程序中?根据结果,人们将如何与我们的网站互动?它将如何扩展!?所有这些都将涉及到信心测试、检查是否有任何东西低于设定的阈值、不同方的签署以及不同云服务器之间的协调(以及所有丑陋的防火墙规则)。这就是一些基本的 DevOps 知识派上用场的地方。
DevOps 是什么?
长话短说,开发人员是帮助开发人员(例如数据科学家)和 IT 人员一起工作的人。
Usual battle between Developers and IT
开发人员有他们自己的指挥链(即项目经理),他们希望尽快为他们的产品获得特性。对于数据科学家来说,这意味着改变模型结构和变量。他们根本不关心机器会发生什么。数据中心冒烟?只要他们得到数据来完成最终产品,他们就不会在乎。在光谱的另一端是它。他们的工作是确保所有的服务器,网络和漂亮的防火墙规则得到维护。网络安全也是他们非常关心的问题。只要机器运转良好,他们就不会对公司的客户不感兴趣。DevOps 是开发者和 IT 之间的中间人。一些常见的 DevOps 功能包括:
-集成
-测试
-打包
-部署
博客的其余部分将详细解释整个持续集成和部署过程(或者至少是与数据科学家相关的内容)。在阅读博客的其余部分之前,有一点很重要。理解业务问题,不要和工具结婚。博客中提到的工具将会改变,但是潜在的问题将会大致保持不变(至少在可预见的将来)。
源代码控制
想象一下将您的代码推向生产。而且很管用!完美。没有抱怨。随着时间的推移,您会不断添加新功能并不断开发它。然而,这些特性中的一个给你的代码引入了一个错误,严重扰乱了你的生产应用程序。您希望您的许多单元测试中的一个能够发现它。然而,仅仅因为一些东西通过了你所有的测试并不意味着它没有错误。这只是意味着它通过了当前编写的所有测试。因为这是生产级代码,所以你没有时间去调试。时间就是金钱,你有愤怒的客户。回到代码工作的时候不是很简单吗???这就是版本控制的用武之地。在敏捷风格的代码开发中,产品在一个不确定的时间周期内保持零碎的开发。对于这样的应用程序,某种形式的版本控制将非常有用。
Bitbucket Repository
我个人喜欢 Git ,但是 SVN 用户依然存在。Git 可以在所有形式的平台上工作,如 GitHub 、 GitLab 和 BitBucket (每种平台都有自己独特的优缺点)。如果你已经熟悉了 Git,可以考虑在 Atlassian 上学习更高级的 Git 教程。我推荐查找的一个高级特性是 Git 子模块,在这里您可以存储多个独立 Git 存储库的特定提交散列,以确保您可以访问一组稳定的依赖项。有一个 README.md 也很重要,它概述了存储库的细节以及必要时的打包(例如使用 Python 的 setup.py)。如果你存储的是二进制文件,可以考虑使用 Git LFS (尽管我建议尽可能避免这种情况)。
Merging Jupyter Notebooks on Git
版本控制的一个数据科学特有的问题是 Jupiter/Zeppelin 笔记本的使用。数据科学家绝对喜欢笔记本。然而,如果你把你的代码存储在一个笔记本模板上,并试图在版本控制中改变代码,当执行 diff 和 merge 时,你将会留下疯狂的 HTML 垃圾。您可以完全放弃在版本控制中使用笔记本(并简单地从版本控制库中导入数学函数),或者您可以使用现有的工具,如 nbdime 。
自动测试
从数据科学家的角度来看,测试通常分为两个阵营。你有通常的单元测试,它检查代码是否正常工作,或者代码是否做了你想要它做的事情。另一个更具体的领域是数据科学,即数据质量检查和模型性能。你的模型能给你一个准确的分数吗?现在,我确信你们中的许多人想知道为什么这是一个问题。您已经完成了分类评分和 ROC 曲线,并且该模型对于部署来说足够令人满意。嗯,有很多问题。主要问题是,开发环境中的库版本可能与生产环境中的完全不同。这将意味着不同实现、近似以及不同的模型输出。
Model output should be the same on dev and prod if integration and deployment are done right
另一个经典的例子是使用不同的语言进行开发和生产。让我们想象一下这个场景。您,这位高贵的数据科学家,希望用 R、Python、Matlab 或上周刚刚发布白皮书的许多新语言中的一种来编写一个模型(可能没有经过很好的测试)。你带着你的模型去生产团队。制作组怀疑的看着你,笑了 5 秒,才意识到你是认真的。他们会嘲笑。生产代码是用 Java 写的。这意味着将整个模型代码重新编写成 Java 用于生产。这又意味着完全不同的输入格式和模型输出。因此,自动化测试是必需的。
Jenkins Home Page
单元测试非常普遍。JUnit 面向 Java 用户,而非 ittest 库面向 Python 开发者。然而,在将代码投入生产之前,有些人可能会忘记在团队中正确运行单元测试。虽然你可以使用 crontab 来运行自动化测试,但我建议使用更专业的工具,比如 Travis CI 、 CircleCI 或 Jenkins 。Jenkins 允许你安排测试,从版本控制库中挑选特定的分支,如果有问题可以发送电子邮件,如果你想保护你的测试,甚至可以旋转 Docker 容器映像。基于集装箱化的沙箱将在下一节详细解释。
集装箱化
Containers vs VMs
沙盒是编码的重要组成部分。这可能涉及到为各种应用程序提供不同的环境。它可以简单地将生产环境复制到开发中。这甚至意味着拥有多个不同软件版本的生产环境,以迎合更大的客户群。如果您想到的最佳方法是使用带有虚拟盒的虚拟机,我相信您已经注意到,要么需要使用完全相同的虚拟机进行多轮测试(糟糕的 DevOps 卫生状况),要么为每次测试重新创建一个干净的虚拟机(根据您的需要,这可能需要近一个小时)。一种更简单的替代方法是在虚拟机上使用容器而不是完整容器。容器只是一个 unix 进程或线程,看起来、闻起来和感觉起来都像 VM。它的优势在于低功耗和低内存消耗(这意味着你可以在几分钟内随意启动或关闭它)。流行的容器化技术包括 Docker (如果您希望只使用一个容器)或 Kubernetes (如果您喜欢为多服务器工作流编排多个容器)。
Kubernetes Workflow
容器化技术不仅有助于测试,还有助于可伸缩性。当您需要考虑多个用户使用基于模型的应用程序时,尤其如此。就训练或预测而言,这可能是真的。
安全性
在数据科学领域,安全性很重要,但往往被低估。用于模型训练和预测的一些数据涉及敏感数据,如信用卡信息或医疗保健数据。在处理此类数据时,需要遵循一些法规遵从性政策,如 GDPR 和 HIPAA。不仅仅是客户需要安全。当在客户端服务器上部署商业秘密模型结构和变量时,它们需要一定级别的加密。这通常通过在加密的可执行文件(例如 JAR 文件)中部署模型,或者在将模型变量存储到客户端数据库之前对其进行加密来解决(但是,除非您完全知道自己在做什么,否则请不要编写自己的加密程序……)。
Encrypted JAR file
此外,明智的做法是在逐个租户的基础上建立模型,以避免可能导致信息从一家公司泄露到另一家公司的意外转移学习。在企业搜索的情况下,数据科学家可以使用所有可用的数据建立模型,并根据权限设置,过滤掉特定用户无权查看的结果。虽然这种方法看起来很合理,但用于训练模型的数据中的部分可用信息实际上是由算法学习并转移到模型中的。所以,无论哪种方式,用户都有可能推断出被禁页面的内容。没有完美的安全保障。但是,它需要足够好(其定义取决于产品本身)。
合作
作为一名数据科学家,在与 DevOps 或 IT 合作时,坦率地说出需求和期望非常重要。这可能包括编程语言、包版本或框架。最后但同样重要的是,互相尊重也很重要。毕竟,DevOps 和数据科学家都有难以置信的困难挑战要解决。开发人员不太了解数据科学,数据科学家也不是开发人员和 IT 方面的专家。因此,沟通是取得成功的关键。
附加说明
当人们开始成为自学的程序员时,很多时候我们想的是创建一个应用程序,简单地…
medium.com](https://medium.com/@sadatnazrul/software-development-design-principles-79d15ef765f3) [## 如何让你的软件开发体验…没有痛苦…
工作在各种形式的组织(从大型软件开发为导向的利基启动到学术实验室),我…
towardsdatascience.com](/how-to-make-your-software-development-experience-painless-2591ebcc69b6) [## 数据科学面试指南
数据科学是一个相当大且多样化的领域。因此,做一个万事通真的很难…
towardsdatascience.com](/data-science-interview-guide-4ee9f5dc778)
DevOps:做还是不做?
unsplash.com
总结
DevOps 是相对最新的“流行语”之一,它会一直存在下去——即使名字不同。DevOps 转型已被证明可以加快软件交付和运营的速度、质量和效率,并提高员工的目的性。受影响最大的将是质量保证团队——因为他们的工作将通过更好的编程工具、自动化和机器学习来解决。在整个企业范围内采用文化转型可以让您通过流程效率、员工福祉和客户幸福来提升交付能力,而这些正是现代组织的最终目标。
在过去几十年中,各组织实施了四项重大变革举措:战略规划、重新设计、全面质量管理和缩编。这些计划的目的是实现经济效益,但是大约 75%的计划失败了或者产生了严重到威胁组织生存的问题 (1) 。人们发现,忽视组织文化是这次失败的最主要原因。当观察在团队层面上采用 Scrum 而没有开发支持这种变化的环境的等级和官僚组织时,这被一次又一次地证明是正确的。在这些公司里,敏捷教练教导人们专注、勇气、尊重、开放和承诺。然而,该系统经常促进指责游戏、政治和升级途径。文化可能促进也可能阻碍公司的战略计划。DevOps 转型是发展高绩效业务的新战略,理想情况下采用自下而上的管理方法。
DevOps 转换—它是什么?
根据最近的调查,大约 50%的企业已经开始实施 DevOps。这些转变的真正成功还有待观察。
DevOps 是关于文化、人员、技术和流程的。DevOps 转型是一项巨大的工作,扩展到组织的所有级别——除了众所周知的 DevOps 承诺为软件交付带来魔力之外,所有的目标都是将组织转变为高绩效的组织思维。
从技术上来说,DevOps 定义了一种状态,在这种状态下,组织在可伸缩环境中使用最新的软件,在具有服务发现和多阶段历史支持的反馈系统的弹性容器中始终准备就绪、自动化、统一和独立的版本。拆开上面的句子,意思是:
- 始终就绪:开发、集成&工具链流程的改进
- 自动化:利用与工具链结合的配置管理工具
- 统一:除数据外,内部&生产环境完全相同。
- 独立:产品独立工作,彼此风险最小;众所周知的概念:高度一致、松散耦合
- 发布:无论何时何地需要;只要有商业意义。
- 可扩展的环境:不需要固定的资源/硬件,因为每个服务都是虚拟化的、可扩展的,而且是不可变的。
- 最新软件:不依赖遗留软件,版本独立。
- 弹性容器:失败被拥抱而不是被避免;不变性、弹性
- 服务发现:用于管理服务和资源的弹性软件
- 多阶段:所有开发阶段的自动化测试
- 历史启用:所有阶段的可靠日志的可用性
- 反馈系统:基于机器学习和动态阈值的推理,同时在任何有意义的时候利用度量标准。
为什么是 DevOps?—好处
组织的 DevOps 转换已经被证明可以加速软件交付的速度、质量和效率,提高员工的积极性和士气。它消除了筒仓(团队之间的沟通障碍)以及软件开发对单个人或团队的依赖。通过使用自动化软件来消除令人厌烦的、单调的任务,工作质量得到了进一步提高。通过建立自动化服务,与人工服务相比,现有的运营成本大大降低。随着手动工作的消除,员工可以专注于提高工作满意度的工作,目的是为组织及其客户增加真正的价值。更快的自动化过程提高了发布过程的质量,因为流水线中的步骤是标准化的,导致可预测的结果、减少的周期时间和更高的部署率。
DevOps 在企业中的实施
DevOps 诞生于敏捷软件开发运动,专注于沟通、协作、集成、自动化、反馈和学习,同时衡量 IT 运营和软件开发人员以及企业中其他 IT 专业人员之间的合作。
DevOps 之前的场景
- 孤立的强大团队导致孤立的孤岛和操作知识块。
- 团队中过度紧张和孤立的高能力专家意味着更多的责任,总体效果是达到最佳绩效,同时也成为瓶颈。
- 团队成员对于哪些能力由谁负责难以忍受的困惑?
- 软件开发团队在不知道特性如何表现的情况下编写代码?客户感觉如何,功能如何满足实际需求?
- 质量保证团队必须确保高质量标准,但不具备所需的所有工具和资源。
- 系统工程团队必须将软件投入生产,并确保其运行。如果它不能黑进去。又名部署和祈祷。
开发运维后的场景
- 由产品经理、UX/UI 专家、软件工程师和其他人组成的产品团队一起工作(质量保证不像以前那么重要了——都是流水线化和自动化的)
- 随着高效工具和技术的到位,现场可靠性团队变得更小 (2) 。
期待什么?
DevOps 已经成为为企业执行运输和运营活动的流行和标准方式,主要是那些涉及某种软件开发的企业。DevOps 转换的采用正在迅速传播,最近,DevOps 一直在沿着这些方向发展。很明显,It 文化正在发生变化,管理产品发布的传统方法变得低效、适得其反且成本高昂。DevOps 正在革新组织,提高性能,构建更多功能软件,并通过减少故障来降低成本。这是所有组织都希望实现的目标。
DevOps 是最新的“流行语”之一,它会一直存在下去(也许没有一个特别的名字——但服务于相同的目的)。DevOps 将会深深扎根于软件生产工具链和交付中,以至于它将不会被单独命名——它将被视为理所当然,它就在那里,它将成为一种商品。然而,DevOps 的文化方面将通过以员工为中心的现代组织变革来采用,而不是等级模式。当员工处于中心时,他们会与共同的动机保持一致;这与员工自身的工作目的 (3) 、组织的利益和顾客的利益直接相关。
在这种组织演变和采用中,受影响最大的将是质量保证团队——因为他们的工作将通过更好的编程工具、自动化和机器学习来解决。因此,质量保证团队成员可以更容易地为未来做准备,并提高软件生产和运输领域中的某种自动化技能。
通过以文化为重点的正确的 DevOps 转型方法,这不仅仅是可以实现的,而且一定会成功。
DevOps 转型帮助您将速度、质量和可靠性融入软件生产业务。通过在企业范围内采用文化转型来采用整体方法,使您能够通过流程效率、员工福祉和客户幸福来提高交付能力,这是现代组织的最终目标。
DFL > DNF > DNS?
去年,我按下了人生的暂停键,搬到了西雅图,当时是暂时的。我参加了 enlight 数据科学沉浸式项目,并在接下来的 3 个月里努力工作,尽情玩耍。
我对“玩”有一种扭曲的看法。我喜欢跑步。你可能会说,这不奇怪…
嗯,我喜欢在小径上跑步…在小径上跑很远,一口气跑 100 英里远(在那个距离上,我是 8 投 5 中)。我渴望有一天能一口气跑 200 英里。它让我能够测试可能的界限,探索自我的深度。
Mile 60 of 2016 Rocky Raccoon 100 Miler. Joy displayed may be related to the fauxhawk?
很自然地,当它来到我的顶点项目时,我想要融入我对(愚蠢的)长距离越野跑和数据科学的热爱。我只是需要正确的“业务问题”…
围绕着极端分子有一个共同的咒语:
DFL > DNF > DNS
“死在最后,总比没有完成好,总比没有开始好.”
这对赛事总监来说意味着什么?
Monte Carlo Simulation for 2017 Western States Endurance Run Lottery, I had 9.6% odds of entry.
好吧,信不信由你,很多比赛很快就卖光了!知名度较高的已经上了彩票系统。三年多来,我一直试图参加西部各州的耐力赛。
了解有多少人不会出现,对于赛事总监来说是很重要的,以判断需要多长时间做一份等待名单,或者一般情况下允许多少人参加比赛。
我可以讲述一个神奇的故事,我是如何根据人们以前的表现对他们进行分类,以映射他们开始 100 英里的倾向。
人类行为是最难建模的主题之一。
见鬼,我们还没有掌握股票市场的建模。
试图确定一个特定的超跑者是否会出现在刘李 120 的起跑线上几乎是不可能的,比如一个 35 岁的男性,他的表现略高于平均水平,已经参加了 15 场比赛。
我相信这可以归结为:
- 如果有办法,超跑者将开始一场比赛。相对而言,很少有人在大型 100 英里比赛中使用域名系统。 即使训练不足或者受伤,他们也会首发,但是 DNF 到时候 。(同样,DFL > DNF > DNS)
- 根据有限的人口统计数据,预测生活环境极其困难。我不知道每个人靠什么谋生,也不知道他们的家庭结构是什么样子。 未开始的最常见原因是由于最后一分钟的工作或家庭义务,这在我的模型中没有考虑。
但并不意味着我没有尝试过。在这个项目中,我非常努力地对个人跑步者进行分类,并取得了一些成功。我还想模拟对赛事总监的财务影响,将结果放入可操作的环境中。
方法:
如果你不是一个数据人员,如果你愿意,请继续阅读,但这是我要花几分钟时间进行技术分析的地方。对于数据爱好者,这里有一些细节…
技术栈 — Python (pandas,scikitlearn,matplotlib,Flask),AWS,Javascript/Ajax,Django
Webscraping —从 ultrasignup.com 收集 39 场比赛和> 10,000 名运动员成绩的 Python 脚本。结果是 json 格式的文件,我将其解析成 pandas 数据帧。
数据清理/特征工程——有一次在 Python 中,我清理了数据,做了一些特征工程。其中一些功能有效(以前的域名数),一些功能相关性很小(年龄组)。总的来说,我的模型有 12 个特征,包括比赛特征(季节,它卖完了吗,等等。)和个人特征(ultrasignup 运动员排名、性别、年龄等。).
建模 —在这种状态下,我实现了三个不同的模型,一个简单的逻辑回归、一个随机森林和一个来自 Python 的 scikitlearn 包的梯度增强分类器。我试图使用网格搜索方法优化每个参数。
结果 —正如预测的那样,梯度增强分类器产生了本研究的最佳预测。根据我的测试/训练划分,我使用 10 倍交叉验证获得了大约 0.67-0.70 的 AUC 分数。
Results from test data split
然而,由于 DNS 类别的高度不均衡性,AUC 分数具有误导性。在任何给定的种族域名系统中只有约 5%。由于比赛只有 100-250 名参赛者,这就造成了一种情况,你可以得到很好的分数(很难不去猜测 95%的参赛者中的大多数),但仍然会错误地分类那些实际上是 DNS 的参赛者。
It performed pretty well, but still only modeled a profit equivalent to a single race entry.
我用这个模型来看看它在我用来训练模型的比赛之外是否有预测能力。再一次,由于职业的平衡,我看起来有很好的结果,通过使用这个模型,我可以节省大约 250 美元。这相当于平均 100 英里比赛的一次报名费。
因此,如果我不能可靠地预测某人是否会出现在起跑线上,并且对赛事总监来说成本节约是最小的, 我能预测运动员是否会完成比赛吗?
预测 DNF 氏症
I DNF’d this race…wonder why? Not shown, second fracture in tibia.
大多数(如果不是全部的话)超跑者想知道他们完成比赛的实际机会。在确定我们的现实机会时,我们会查看 DNF 每年关于我们感兴趣的比赛的统计数据。许多 100 英里赛跑只有不到 50%的参与者跑完全程。
DNFs 的原因多种多样,包括:
- 受伤——无论是在比赛中还是在比赛过程中,我左边的受伤发生在比赛的第 5 英里
- 训练不足——很多时候人们不得不提前一年报名参加比赛。你永远不知道在比赛日之前的几个月里你的时间表会是怎样的,所以这导致生活妨碍了训练。
- 分界点——一些比赛有激进的中间分界点。由于各种各样的情况(天气、营养等)。)跑步者可能错过这些中间的一个终点,并被迫退出比赛。
我发现社区对预测他们是否能完成一场比赛的兴趣比赛事总监优化他们的赛事后勤更大。
因此,我做了任何好奇的超跑者都会做的事情,我使用我已经准备好的数据,创建了一个预测模型,用于完成模型中训练的一场比赛!
同样,梯度增强分类器在我运行的模型中表现最好。
我的 DNF 模型的 AUC 得分为 0.64,低于我的 DNS 模型的 0.67–0.70。然而,我认为这是一个很好的结果,原因有二:
- 它的表现好于 50/50,这是人们所希望的(我没有屏住呼吸)
- 与 DNS 模型相比,它在预测谁能完成 和 方面做得更好
另外,它给了我一个很好的借口来制作一个有趣的 webapp!
对于我用来训练模型的比赛,我能够将模型集成到 webapp 中,以计算完成比赛的条件概率,只要训练得当。除了种族特有的特征之外,我使用每个年龄和性别的平均表现来输入模型。
为此,我需要学习一点 Javascript/Ajax(使用 Django)来将 webapp 集成到我的 AWS 托管模型中。
总之,这是一个有趣的 2 周激情项目,圆满结束了我在镀锌的时间。我展示了我从业务问题开始,构建我的建模方法并在终端产品中部署结果的能力。
现在掷骰子看看我是否能在 11 月完成我的下一个 100 英里跑,里约德尔拉戈…
如果我有先见之明,用我的 DNF 模型训练这场比赛…
也许是时候做更多的网络搜集了!
阅读我在 Galvanize 的经历:https://medium . com/forward-data-science/galvanizing-my-skills-a4b4d 1175 cb4
关于我的项目的更多细节,请访问我的 Github 回购:https://github.com/ophiolite/ultrasignup
要使用 webapp,请访问:http://endurostew.com/
糖尿病预测——人工神经网络实验
作为一名数据科学专业人员,我们倾向于学习所有可用的技术来处理我们的数据,并从中推导出有意义的见解。在本文中,我描述了我用神经网络架构对数据进行探索性分析的实验。
Source : http://legacymedsearch.com/medicine-going-digital-fda-racing-catch/
这里是到我的代码库的 github 链接,我已经用它进行了探索性的数据分析,所有的架构设计都在本文中提到。我使用过 Python 3.6 以及 Pandas、Numpy 和 Keras(tensor flow 上的后端)模块。
神经网络-sklearn -神经网络在 pima 印度糖尿病数据集上的实现
github.com](https://github.com/bmonikraj/neural-network-sklearn)
这是我用于探索性数据分析的数据集的链接,来自 Kaggle 网站。链接中提到了列的数据描述和元数据。
Number of Observations : 768
Number of Features : 8
Input Neurons : 8
Output Neurons : 2 (Diabetic and Non-diabetic)
Test Data size : 20%
Train Data size : 80%
基于诊断方法预测糖尿病的发病
www.kaggle.com](https://www.kaggle.com/uciml/pima-indians-diabetes-database/data)
首先,我创建了 关联矩阵 ,并使用 Seaborn 模块绘制了热图和 pairs 图(数据集的每两个特征之间的图),用于数据可视化。通过相互比较,关联图给出了关于特性依赖性的概念。相关性是任何数据集的双变量分析的一部分。
Correlation Matrix
下面是描述每个特征之间的二元图的配对图,也显示了每个特征的直方图。单元格[i,i]显示直方图,其中 I 是第 I 行/列。
Pair Plot and Histogram of the dataset (Only X)
从上面的直方图可以得出一个推论,很少有特征遵循标准或已知的分布,如高斯、瑞利等,这从图的形状可以明显看出。如果需要,这种假设在建立预测模型时会很方便,因为我们已经知道(或至少假设)了数据的分布及其数学公式。
Correlation Matrix including the target (Outcome) value
从上面的情节可以得出*(因为相关分数高)**【结果-葡萄糖】对和【结果-身体质量指数】*对是最相互依赖的。所以密谋与培生联合密谋培生会关注他们的行为。从下面可以看出,Outcome (Target)只有两种可能的结果。
Outcome — Glucose (Pearson Correlation)
Outcome — BMI (Pearson Correlation)
Glucose — BMI (Pearson Correlation)
根据第一个皮尔逊相关图,显然*‘葡萄糖’与结果高度相关,这使得‘葡萄糖’*成为最重要的特征。
现在这是最有趣的部分,实验神经网络的各种可能的架构。在深入这个问题之前,我想指出关于架构决策的几个关键点。
- 输入神经元数量=中的特征数量 X
- 输出神经元数量=目标中的类别数量
- #隐藏层> 0
- 隐藏层中的神经元数 1 ~ #隐藏层中的神经元数 2 ~ #隐藏层中的神经元数 3 …隐藏层中的神经元数量*(如果架构有 N 个隐藏层)*
- 隐藏层中的神经元数量~ #输入神经元| #隐藏层中的神经元数量~ 2 X #输入神经元
- 权重必须随机初始化
人工神经网络是最流行的机器学习算法之一,广泛应用于预测建模和构建分类器。目前,许多先进的神经网络模型,如卷积神经网络、深度学习模型,在计算机视觉、网络安全、人工智能、机器人应用、医疗保健和许多更先进的技术领域中很受欢迎。
驱使数据科学家使用人工神经网络的几个令人兴奋的事实是
- 适应并训练自己处理复杂的非线性问题。
- 灵活应对各种问题集。
- 从根本上兼容实时学习(在线学习)。
- 在大多数情况下,构建人工神经网络需要大量的数据和快速的 GPU 来进行计算
在这个程序中,在使用的每个架构中,输出层都由’ softmax ‘激活函数激活。中间层由’ relu 激活功能激活。
由于这是一个探索性的数据分析,所以所有的指标和图表都受制于这个特定的问题集。
单一隐藏层架构
Single Layer Architecture — Accuracy vs Neurons in Hidden Layer
在我们的问题中,对于隐藏层中任意数量的神经元(基于上图的强假设),应用单层架构产生了 64.28% 的饱和精度。
两个隐藏层架构
Two hidden layer architecture — X-axis : Neurons in first hidden layer, Y-axis: Nuerons in second hidden layer, Z-axis: Accuracy
在两个隐藏层架构的情况下,观察到类似的行为,其中准确度总是饱和到 64.28%。
多重隐藏层架构
Performance of classifier based on increasing hidden layers
既然我们正在讨论用神经网络进行探索性数据分析,我想提出几个需要记住的要点
- 激活函数的选择在很大程度上影响性能。基于实验、目标类型和我们正在处理的数据选择激活函数的明智决定很重要。
- 隐藏层中神经元的数量应该与输入神经元的数量相似。如果神经元的数量足够多,这可能会提高性能,但也可能会增加复杂性。为此要保持一种折衷。
- 使用带有反向传播的动量可以帮助收敛解,并实现全局最优。
- 在决定隐藏层的架构时,尝试不同的架构会有所帮助,因为每个数据集在不同的架构下可能会有不同的表现。
- 数据的大小很重要,所以尽量相应地选择数据大小。越大越好!
- 当网络从零开始构建时,网络权重的随机初始化是强制性的(没有像初始模型那样预先训练的权重)。
在神经网络之后,我应用了一些其他算法来测试数据集和性能。结果是这样的
关键要点
在每一个现实世界的问题中,构建以解决方案为中心的模型的第一步是执行探索性的数据分析。这将为问题建立合适的模型,该模型可进一步用于调整性能和有效地解决问题。
人工神经网络的探索性数据分析处理隐藏层和激活函数。先进的大数据问题、基于图像的问题和许多其他复杂问题现在都可以用卷积神经网络来解决 (CNN) 。深度学习已经被广泛用于许多复杂的研究问题,因为它能够从大数据中获得洞察力,在许多情况下跳过数据特征提取的过程 (CNN 可以直接对图像进行处理,无需任何特征提取)。计算机视觉应用中的 CNN 的另一个好处是保持图像的空间属性完整,这对于许多基于几何的计算和推理非常有用。
参考
- 探索性数据分析—https://www . ka ggle . com/etakla/exploring-the-dataset-bivariable-Analysis
- https://keras.io/
- 熊猫—【https://pandas.pydata.org/
- https://seaborn.pydata.org/
- 皮尔逊相关性—https://en . Wikipedia . org/wiki/Pearson _ Correlation _ coefficient
- 人工神经网络—https://www . tutorialspoint . com/artificial _ intelligence/artificial _ intelligence _ Neural _ networks . htm
使用 Fastai 库和 Turicreate 从手机捕获的显微图像中诊断疟疾
灵感:在读了卡洛斯·阿蒂科·阿里扎的一篇文章后,我偶然发现了疟疾数据库。
Colorized electron micrograph showing malaria parasite (right, blue) attaching to a human red blood cell. The inset shows a detail of the attachment point at higher magnification. Credit: NIAID
为什么要创建深度学习模型来预测疟疾?
疟疾是一种由蚊子传播的疾病,由不同种类的疟原虫引起。它不成比例地影响世界上资源贫乏的地区,导致生命损失和巨大的经济负担。根据 CDC 网站的数据,2016 年发生了 2.16 亿例疟疾,其中 44.5 万例是致命的。其中大多数是儿童。最初,感染疟疾的患者会出现类似流感的症状。在严重的情况下,患者可能会出现呼吸困难和昏迷。尽早诊断疟疾以防止疾病在社区传播是非常重要的。诊断疟疾的金标准是在显微镜下检查血涂片。将患者的一滴血涂在载玻片上,用姬姆萨染色剂染色。当在显微镜下观察时,这种染色会使寄生虫突出。诊断取决于染色的质量和读片人的专业知识。根据世卫组织协议,受过训练的医生/技术人员必须在 100 倍的放大倍数下观察 20 个微观区域。他们必须计算 5000 个细胞中寄生虫的数量。可以想象,这是一个非常费力的过程,而且容易出错。用于检测具有高阴性预测值的疟疾寄生虫的深度学习算法将使这一过程变得不那么繁琐,并节省医疗保健人员的宝贵时间。
数据库背后的故事
国立卫生研究院意识到了上述问题,并着手创建一个图像数据库。李斯特希尔国家生物医学通信中心(LHNCBC)的研究人员开发了一种移动应用程序,可以在标准的 Android 智能手机上运行,可以连接到显微镜上。在孟加拉国,这个应用程序被用来拍摄感染和未感染疟疾患者的血液涂片图像。后来,泰国的研究人员对这些图像进行了注释。从这些照片中分割出红细胞,并创建了最终的数据库。您可以了解更多相关信息,并在 https://ceb.nlm.nih.gov/repositories/malaria-datasets/下载数据集
NIH 集团提出的当前解决方案
NIH 的研究人员使用上述数据库,使用 AlexNet、VGG-16、Resnet-50、Xception、DenseNet -121 和定制的 CCN 创建了深度学习模型。他们使用“具有英特尔至强 CPU E5–2640 v3 2.60 GHz 处理器、16 GB RAM、支持 CUDA 的英伟达 GTX 1080 Ti 11GB 图形处理单元(GPU)、MATLAB R2017b、Python 3.6.3、Keras 2.1.1(具有 Tensorflow 1.4.0 后端)和 CUDA 8.0/cuDNN 5.1 依赖项的 Windows 系统来训练该模型。”获得的最佳性能指标大多来自 ResNet-50 模型。以下是统计数据
在 15k 迭代后,他们停止运行定制模型,验证准确性停止提高,大约需要 24 小时。国家卫生研究院的文章全文可在https://lhncbc.nlm.nih.gov/system/files/pub9752.pdf获得
为什么要创建另一个模型?
最初,我想修补数据,看看我是否能赶上他们的表现,并在这个过程中提高我的深度学习技能。
项目目标
1.创建一个深度学习模型,可以在不使用 GPU 的情况下匹配 NIH 解决方案的性能。
2.创建一个小得多的模型,这样它就可以部署在手机上。
3.创建一个比 NIH 团队发表的论文中提到的性能指标更好的模型。
4.使用 Fastai ad Turicreate 减少迭代次数和训练时间,但保持性能。
5.开放源代码,这样其他人可以复制我的实验。
为什么图瑞创造?
turcreate是苹果公司的一个机器学习平台。Turicreate 可用于在笔记本电脑上创建深度学习模型,无需使用 GPU。如果 GPU 可用,也可以利用它来提高训练时间。即使没有 GPU,Turicreate 也可以在更短的时间内生成模型。您可以使用几行代码创建最先进的模型。创建的模型可以很容易地部署在 iOS 设备上。它也可以作为 web 服务来部署。
创建统计数据
SqueezeNet 型号小于 5mb。ResNet-50 也进行了尝试,没有看到太大的性能差异。点击此处访问 Github repo 上的源代码。
为什么 Fastai ?
Fastai 是一个深度学习平台,因杰瑞米·霍华德教授的在线课程而走红。新的 fastai 库可以用来用几行代码创建最先进的模型。Fastai 可以在谷歌的 Colab 上运行,Colab 提供免费的 Telsla K80 GPU,每次运行 12 小时。通过结合 Fastai 和 Colab,世界各地的任何研究人员都可以利用免费的 GPU 在更短的时间内创建模型,而不会产生任何成本。
Fastai 模型的完整代码可在这里获得。
Fastai 模型可以作为 web 服务部署。点击此处了解更多信息。
Turicreate、Fastai 和 NIH 方法的比较。
最佳统计数据以粗体显示。(请参见下面的附录)
*NIH 统计数据来自不同的模型。总的来说,NIH 研究中表现最好的模型是 ResNet-50 和 VGG-16 模型。
基于此,Fastai 模型赢得比赛!Mathews 相关系数被认为是具有二元结果的医学测试的最佳度量,Fastai 模型具有最佳 MCC。Turicreate 仅用了 13 分钟就创建了模型,而且性能不相上下。NIH 做了 5 倍交叉验证,我没有对我的模型做这个。如果有兴趣,可以看 NIH 的文章,做 5 折交叉验证。如果你有,请在下面张贴你的回复。
2018 年 11 月 13 日增编
今天,我给 NIH 研究的通讯作者 Sivaramakrishnan Rajaraman 发了电子邮件。他向我指出了细胞水平的指标以及与 Fastai 的精确比较。Rajaraman 博士制作的表格附后。
未经加工的钻石…行动号召
如果你一直跟随我的旅程,你知道过去的 12 个月是旋风!
我改变了我的职业轨迹,提高了我的编码技能,获得了我的第一份“正式”数据科学工作(我认为我的整个职业生涯都在做数据科学),并反思了我在第一个咨询项目中吸取的教训。然而,到目前为止,这个系列的 仅仅触及了我希望促成 的讨论的表面。
我为社区准备了 两个重要问题 :
什么是数据科学的优秀候选人?
那些没有“传统”轨迹的人如何在就业市场中成功定位自己?
这些都是加载题,超载了!
我详细讲述了我是如何获得第一份数据科学工作的。这听起来直截了当,合乎逻辑。不应该吗?我们是数据驱动的人,逻辑是我们的面包和黄油。
不是的。简直是闹剧。
它要求我…
…投入了大量的辛勤劳动、汗水和(有时)泪水。
…花 6 个月的大部分时间远离我的配偶、家人和家,以确保我们在西雅图的未来。
…在第 n 次瞬间失去领先优势后,我重新振作起来。
…当我觉得自己已经没什么可付出的时候,我有一个奇妙的支持网络来鼓励我继续努力。
然而,我仍然很惊讶…
…每次我冷淡地申请职位时,我的简历得到的关注是多么少。
…尽管我有关系,但我得到的牵引力很小。有时候,我接到一个电话,但其他人去了巨大的无底邮件坑。
我认为自己很幸运。在高度不确定的情况下,我有独一无二的机会去冒险。
我有…
…资源
…灵活性
…坚韧
像我这样的大多数人没有这些奢侈品,特别是资源和灵活性。大多数人无法提升并穿越他们的国家重新开始。许多有能力的人不会因为失败的风险而放弃。
我们如何…
- 因为数据科学家有这些困难的对话来承认职业道路的多样性?
- 让人力资源和招聘经理参与进来,在招聘实践中跳出框框?
- 从其他行业的实践中成长和学习而不是嘴上说说?
我们知道,在任何业务的核心,多元化都是必不可少的。
种族、民族、年龄、性别、性别认同、文化或社会经济背景的多样性…都是我们在谈到多样性时会想到的特征。
然而,在我的职业生涯中,一家公司能够从多元化实践中获得的最大收获是 思想上的多元化 。
所有部分的总和才是真正让我们成为组织资产的东西。
实际上很难完成这项任务。
让我们面对现实吧,尽管有增加人数的举措,但在科技行业的技术岗位上,女性的数量仍然远远超过男性*。***
很贵…
筛选软件的好坏取决于它的训练集。凭借历史训练集的狭窄搜索窗口,来自非传统行业的高素质候选人将被筛选出来。
这要求认真对待多元化的公司开始拓宽筛选窗口,多看简历。工时可不便宜。然而,发现“未经雕琢的钻石”的 红利是无价的 。
作为数据科学家,我们有责任不断改进用于整理简历的算法。这对我们自己的立场尤其适用。
要么需要增加筛选容限,要么训练集需要来自更多样化的候选集。
我看待问题的方式与软件工程师不同。部分原因是因为我的地球科学背景和在能源行业的经验。然而,这不应被视为一个净负面因素。这是一个净正数。为公司面临的深层次问题和难题寻找创造性的解决方案。也就是 无形价值增加到任何组织 。
为什么我们不能让 超越 仅仅解决和改善技术领域的性别和种族平等?难道我们不能超越传统的技能和背景来提高多样性吗?一个不能引向另一个吗?
通过将数据科学家的搜索范围扩大到拥有大量技术经验的典型 CS/软件工程师之外,公司将受益于思想的多样性,但也将开始通过引进和吸引其他行业的女性人才来实现性别平等。
行动号召—
对于那些在招聘过程中负有责任的读者:
作为处于职业转折时期的求职者,我们能做些什么来最好地脱颖而出呢?
我/我们如何以建设性的方式促进这一讨论,以推进我们的职业发展和贵公司?
你如何在内部推动卓越,以创造更多不可知的工作描述来解释我们的经历?
对于求职者和候选人:
你在转换职业轨迹和行业时面临的最大的挣扎是什么?
关于你是否适合手头的职位,你希望招聘人员知道的一件事是什么?
有哪些让你的声音被听到的成功策略?
你在打造个人品牌方面取得了哪些成功?
数据科学依靠创造力与科学的结合来提供有影响力的产品和见解。
让我们以有益和建设性的方式继续讨论。做个吱吱响的轮子,大声说出来。请公开或私下与我分享您的反馈。我希望在未来的系列中纳入所有反馈,更深入地探讨数据科学/分析领域的多元化和招聘主题。
也就是说,这是我的职业支点系列的第 8 集,也是最后一集。与此同时,我将过渡到专注于营销分析以及一些有趣的数据科学副业的职位。
补上这部剧之前的参赛作品:第一集、第二集、第三集、第四集、第五集、第六集、第七集
要想快速了解为什么多元化对商业有益,请看麦肯锡的这篇文章。
要全面了解如何雇佣优秀的数据科学家,请查看乔纳森·诺利斯在 Lenati 发表的关于雇佣数据科学家的系列文章。我们的小团队目前拥有从数学和工程到地球科学和商业管理的学位,并且 40%是女性。
Booking.com 数据科学家的日记
由 Booking.com 高级数据科学家 西康德
招聘
大约两年半前,我作为一名数据科学家加入了Booking.com**,此前我在迪拜从事了 3 年的咨询工作。从咨询转向纯粹的数据科学角色是我职业生涯中的一个重大转变,事后看来,我很高兴自己做出了这个选择。事实上,我在面试的时候就已经对这家公司印象深刻了。我最喜欢的是,我接受了已经担任相同职位的同事的面试,这让我在面试过程中有了许多【质量】互动,并再次证实了招聘人员的说法,即该公司有一个【平级结构】。面试官的背景也非常多样化和有趣——一个拥有天文学博士学位,另一个是自己创业公司的首席技术官。**
虽然我必须诚实,但办公室(以及阿姆斯特丹)的美味午餐也对我的决定产生了相当大的影响:)
上车
我还记得我第一天上班时,我的同事问我-’ 你觉得你的屏幕怎么样?’。我不知道该说什么,因为我以前只在一台笔记本电脑上工作过。然后,我有了一台 Mac 笔记本电脑、两个大屏幕(主要是为了展示我的代码,让非技术观众留下深刻印象)和许多其他很酷的小工具。我已经准备好用我新的数据科学家头衔征服世界🤓。
不久后,我得到了我的第一个入职项目,其中涉及分析大量的文本,并产生一些商业见解。以前,我只有结构化数据方面的经验,所以我对这一新挑战感到兴奋。我一头扎进去,设法提高自己的技能,用文本数据做有意义的分析,但没过多久我就碰壁了:'Booking.com数据 '。**
Booking.com每 24 小时售出超过 150 万间客房,数百万人在任何给定时间浏览网站,这意味着我们作为数据科学家接触的所有数据的规模非常大。幸运的是,有一个关于使用 Spark 的分布式计算的内部培训。我立即拿起它,瞧,我的分析现在在多台机器上运行。**
项目
Booking.com Data Scientists presenting their projects at Analytics Fair
我的第二个项目是为我们的合作伙伴网站建立一个推荐相关机会的‘推荐引擎’。这也是非常令人兴奋的,因为以前我只做过标准的回归和分类模型,所以我渴望做一些新的东西。那是我第一次接触到协作过滤和因式分解机器的迷人世界。同样,由于规模的原因,我不得不在 PySpark 中使用稀疏分布矩阵来实现这个解决方案。然后我生产了代码,我们开始了 A/B 测试,看看它是否对我们的业务有积极的影响。这也是我的第一次 A/B 测试经历,但幸运的是,由于 我们出色的实验工具和围绕它的基础设施 ,设置起来并不困难。在几次迭代中,我们也能够处理冷启动问题,我很高兴我成功地完成了另一个项目。**
接下来是一个有趣的项目组合,每个项目都有自己的挑战,需要我作为一名数据科学家保持警觉并不断学习。例如,其中一个项目要求我将业务问题表示为加权网络图,并对其进行有趣的分析;而对于另一个项目,我不得不戴上顾问的帽子,通过从简单的数据分析中产生有意义的见解来验证一个重要的战略决策。
一晃两年半过去了,我现在是 Booking.com的高级数据科学家。挑战的程度只会变得更好,因为现在我正在开发一个人工智能(AI)产品“机器翻译”,并部署神经网络和深度学习解决方案来 建立一个生产中的全面系统 。虽然机器翻译是一个活跃的研究课题,最近取得了一些突破,但我们仍然坚持业务优先的人工智能方法,专注于它如何帮助我们的客户。我很想多谈谈这个特殊的话题,但希望这是另一篇博文。**
团队结构
****简单介绍一下数据科学家如何在组成团队;我们有一个我们称之为‘嵌入式’的结构,其中数据科学家与业务紧密结合。例如,我在一个由开发人员、数据科学家、产品负责人和其他专家组成的团队中。我们以这样一种方式形成,所有的能力都在团队中表现出来,以执行一个想法从概念化到实施。对于我们的日常运营,我们遵循’预约敏捷要点’的处方:每日站立、回顾、待办事项、团队目的、KPI 和 okr(目标和关键结果)。这与两周一次的 sprint 会议一起,使团队能够在小步骤中取得进展,并展示价值,或者失败,并尽快学习。
正是因为与业务的密切互动,作为【Booking.com的一名数据科学家,人们期望他在沟通和商业意识方面表现出色,并具备技术技能。这些是我们在工作面试中测试的基本技能。
这份工作最棒的地方是人
Booking.com Data Scientist Community during weekly Analytics Talk
Booking.com拥有 120 多名数据科学家,这个社区每天都在扩大。我们每个人都有非常不同的个人资料、背景和工作偏好。对一些人来说,这是他们获得博士学位后的第一份工作,而其他人则有很多工作经验;有些是贝叶斯主义,有些是频率主义者;有的喜欢 R,有的更喜欢 Python 一些人强烈支持核外学习(Vowpal Wabbit),而另一些人则更喜欢使用 Spark 和 H2O 的分布式计算。这种多样性允许不断成长和相互学习。我们每周都有会议,比如分析讲座、期刊俱乐部等等。获得同行对分析的反馈,并讨论如何将最新研究论文中的观点应用于解决 Booking.comT21的实际问题。此外,人们自愿定期提供技术培训,主题包括 A/B 测试、Git、Hive、Python、R、Spark、H2O、TensorFlow 等。
对我来说,“人和社区”是这份工作最好的部分,因为它让我每天都能学到新东西,并从中获得乐趣。
一些挑战
像每一个成长中的数据科学实践一样,我们也面临一些挑战。
- 首先,由于我们的数据科学社区发展如此之快,有时很难以可扩展的方式分享知识。为了解决这个问题,我们不断尝试不同的形式,比如关于专业话题的谈话(比如 NLP),电子邮件,黑客马拉松等等。了解在我们成长的每个阶段分享知识的最佳方式。
- 嵌入 数据科学家接近商业也有其弊端。有时,我们在日常工作中会错过批评和友好的同事反馈。为了应对它,我们鼓励每个人经常展示他们的工作,并与同行讨论他们的最新项目。我们还有一个针对新员工的导师计划。
- 尽管我们已经对社区做出了多次贡献(您可以在这里 和 这里 找到我们的一些出版物和演讲),但在更多地向外界分享我们的一些知识和最佳实践方面,我们肯定可以做得更好**。我们目前正在围绕这个问题制定一些指导方针。**
我认为好的一面是,我们认识到了这些和许多其他挑战,并有专门的“任务组”来研究潜在的改进领域。
最后,我可以说,作为 Booking.com 的一名数据科学家,没有一刻是无聊的!!
Booking.com Data Scientists enjoying Amsterdam summer on a boat after office
这听起来让你兴奋吗?你也想成为 Booking.com 的数据科学家吗?来和我们一起工作吧!
此外,点击 查看更多来自 Booking.com的数据科学文章。