如何建立用于语音分类的神经网络
Python 的完整代码演练
图片来自 Adobe Stock281653938 作者 korkeng
如果能将我们的 Zoom 会议记录下来,用纯文本的形式告诉我们谁在会议中说了什么,这不是很好吗?这个项目诞生于记录会议告诉你每个人说了什么的想法。我们有许多将语音转换为文本的转录工具,但没有多少工具可以识别每个说话者。为此,我们将使用这里包含的所有代码从头开始构建一个 python 语音分类器。
首先,一如既往,我们需要数据。这个数据来自 OpenSLR 。对于我们的训练数据,我们将使用 30 个不同的说话者和每个说话者 4 个样本,给我们 120 个样本。每个样本平均 15 秒,因此每个说话者大约一分钟用于训练。对于我们的问题陈述来说,30 个演讲者是一个很好的数量;因为我已经进行了这个项目,我可以断言一分钟足够给我们带来好的结果。
除了用于训练的 120 个样本,我们还需要验证和测试数据。我们将对 3 个样品进行验证,并对 3 个样品进行测试。由于我们有 30 个扬声器,我们需要 90 个样品进行验证,90 个样品进行测试。因此,我们将需要每个发言者的 10 个语音剪辑。
为了总结样本,我们将使用 120 个语音剪辑作为训练数据,90 个语音剪辑作为验证数据,90 个语音剪辑作为测试数据,总共 300 个语音剪辑。
一旦我们在三个不同的文件夹中有了用于训练、验证和测试的语音剪辑,我们就可以创建我们的熊猫数据框架了。我们需要导入操作系统,这样我们就可以从文件夹中的文件创建一个数据框架(我在 mac 上工作,对于其他操作系统,这个过程可能会有点不同)。我训练的文件夹叫 30_speakers_train 。
import os#list the files
filelist = os.listdir('30_speakers_train') #read them into pandas
train_df = pd.DataFrame(filelist)
这将为我的训练数据创建一个数据框架。检查数据帧的大小非常重要,这样可以确保它与文件夹中的文件数量相匹配。
让我们将文件列命名为“文件”。
# Renaming the column name to file
train_df = train_df.rename(columns={0:'file'})
有时一个’。DS_Store’ 文件已创建,我们必须找到并删除该特定文件才能继续。之后,我们需要重置数据帧的索引。这里有一个例子:
如何删除’的示例。“DS_Store”文件
# Code in case we have to drop the '.DS_Store' and reset the index
train_df[train_df['file']=='.DS_Store']
train_df.drop(16, inplace=True)
train_df = train_df.sample(frac=1).reset_index(drop=True)
现在,我们需要确定每个发言者。在我的文件名中,第一组数字是发言者 ID,因此我写了一点代码来创建一个具有该 ID 的列。
# We create an empty list where we will append all the speakers ids for each row of our dataframe by slicing the file name since we know the id is the first number before the hashspeaker = []
for i in range(0, len(df)):
speaker.append(df['file'][i].split('-')[0])# We now assign the speaker to a new column
train_df['speaker'] = speaker
我们的数据帧应该是这样的:
我们对验证和测试文件做同样的工作,得到三个不同的数据帧。
现在我们有了数据帧,我们需要写一个函数来提取每个音频文件的音频属性。为此,我们使用 librosa,这是一个很好的用于音频操作的 python 库。我们需要 pip 安装 librosa 并导入 librosa。下面是解析我们文件夹中的每个文件并从每个文件中提取 5 个数字特征的函数,即 mfccs、chroma、mel、contrast 和 tonnetz。
def extract_features(files):
# Sets the name to be the path to where the file is in my computer
file_name = os.path.join(os.path.abspath('30_speakers_train')+'/'+str(files.file))# Loads the audio file as a floating point time series and assigns the default sample rate
# Sample rate is set to 22050 by default
X, sample_rate = librosa.load(file_name, res_type='kaiser_fast')# Generate Mel-frequency cepstral coefficients (MFCCs) from a time series
mfccs = np.mean(librosa.feature.mfcc(y=X, sr=sample_rate, n_mfcc=40).T,axis=0)# Generates a Short-time Fourier transform (STFT) to use in the chroma_stft
stft = np.abs(librosa.stft(X))# Computes a chromagram from a waveform or power spectrogram.
chroma = np.mean(librosa.feature.chroma_stft(S=stft, sr=sample_rate).T,axis=0)# Computes a mel-scaled spectrogram.
mel = np.mean(librosa.feature.melspectrogram(X, sr=sample_rate).T,axis=0)# Computes spectral contrast
contrast = np.mean(librosa.feature.spectral_contrast(S=stft, sr=sample_rate).T,axis=0)# Computes the tonal centroid features (tonnetz)
tonnetz = np.mean(librosa.feature.tonnetz(y=librosa.effects.harmonic(X),
sr=sample_rate).T,axis=0)return mfccs, chroma, mel, contrast, tonnetz
每个 mfcc 是长度为 40 的数组,色度为 12,mel 为 128,对比度为 7,tonnetz 为 6。总的来说,从我们选择的音频特征中,每个语音片段有 193 个数字特征。如果你愿意,请随意尝试不同的方法:l ibrosa 特征提取。我们将该函数应用于每个单独的音频文件,并存储该信息。请注意,这确实需要几分钟,甚至可能需要几个小时,这取决于您使用的数据量和您的计算能力。
train_features = train_df.apply(extract_features, axis=1)
现在,我们将每个文件的所有这些数字特征连接起来,这样我们就有一个包含 193 个数字的单个数组来输入我们的神经网络。
features_train = []
for i in range(0, len(train_features)):
features_train.append(np.concatenate((
train_features[i][0],
train_features[i][1],
train_features[i][2],
train_features[i][3],
train_features[i][4]), axis=0))
现在,我们可以将 X_train 设置为我们的特性的 numpy 数组:
X_train = np.array(features_train)
类似地,我们从一开始就为我们的验证和测试数据做同样的步骤。我们应该得到一个 X_val 和 X_test 。
现在,我们完成了我们的 X 数据。对于 Y ,我们需要演讲者的 id。请记住,我们正在进行监督学习,因此我们需要目标数据。我们从原始数据帧中得到这些,因此我们只得到这些值。
y_train = np.array(train_df['speaker'])
y_val = np.array(val_df['speaker'])
我们需要对 y 进行热编码,以便能够将其用于我们的神经网络。您需要从 sklearn 中导入 LabelEncoder ,从使用 Tensorflow 的 keras 中导入to _ categorial。
from sklearn.preprocessing import LabelEncoder
from keras.utils.np_utils import to_categorical# Hot encoding y
lb = LabelEncoder()
y_train = to_categorical(lb.fit_transform(y_train))
y_val = to_categorical(lb.fit_transform(y_val))
现在我们需要扩展我们的 X :
from sklearn.preprocessing import StandardScalerss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_val = ss.transform(X_val)
X_test = ss.transform(X_test)
最后,我们准备好了有趣的部分:构建神经网络!我们将使用一个简单的前馈神经网络。输入将是我们的 193 个特征。我摆弄了一下辍学率,但是如果你愿意,你可以改变这些数值。使用 relu 是相当标准的。输出是 softmax,因为我们有 30 个不同的类,并且因为不同的类,我们使用分类交叉熵。
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.callbacks import EarlyStopping# Build a simple dense model with early stopping and softmax for categorical classification, remember we have 30 classesmodel = Sequential()model.add(Dense(193, input_shape=(193,), activation = 'relu'))
model.add(Dropout(0.1))model.add(Dense(128, activation = 'relu'))
model.add(Dropout(0.25))model.add(Dense(128, activation = 'relu'))
model.add(Dropout(0.5))model.add(Dense(30, activation = 'softmax'))model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')early_stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=100, verbose=1, mode='auto')
现在,我们用训练和验证数据拟合模型:
history = model.fit(X_train, y_train, batch_size=256, epochs=100,
validation_data=(X_val, y_val),
callbacks=[early_stop])
这是一些代码,用于查看训练和验证准确性的图表:
# Check out our train accuracy and validation accuracy over epochs.
train_accuracy = history.history['accuracy']
val_accuracy = history.history['val_accuracy']# Set figure size.
plt.figure(figsize=(12, 8))# Generate line plot of training, testing loss over epochs.
plt.plot(train_accuracy, label='Training Accuracy', color='#185fad')
plt.plot(val_accuracy, label='Validation Accuracy', color='orange')# Set title
plt.title('Training and Validation Accuracy by Epoch', fontsize = 25)
plt.xlabel('Epoch', fontsize = 18)
plt.ylabel('Categorical Crossentropy', fontsize = 18)
plt.xticks(range(0,100,5), range(0,100,5))plt.legend(fontsize = 18);
它应该是这样的:
看起来我们得到了一些很好的准确性!让我们用测试数据来检查这些值。我们可以用神经网络的结果生成预测,并将它们与实际值进行比较。
# We get our predictions from the test data
predictions = model.predict_classes(X_test)# We transform back our predictions to the speakers ids
predictions = lb.inverse_transform(predictions)# Finally, we can add those predictions to our original dataframe
test_df['predictions'] = predictions
现在,我们的测试数据 dataframe 应该是这样的:
# Code to see which values we got wrong
test_df[test_df['speaker'] != test_df['predictions']]# Code to see the numerical accuracy
(1-round(len(test_df[test_df['speaker'] != test_df['predictions']])/len(test_df),3))*100
您应该得到这样的结果:
98.9%的正确预测!我不得不运行神经网络四次,最终得到一个错误的预测。在前三次运行中,神经网络得到了所有正确的预测,但我想展示如何找到一个错误的预测。因此,通过一分钟的训练音频,神经网络对于 30 个扬声器来说近乎完美!
这证明了一个简单的神经网络有多么强大!希望对你有帮助!
这里是我的 jupyter 笔记本的链接,里面有所有的代码。我也使用卷积神经网络(CNN)做了这个和类似的项目,如果你感兴趣,你可以在这里 看到我的另一篇解释那个过程的帖子 。
来源:
数据集:http://www.openslr.org/12/
[1]大卫·卡斯帕,亚历山大·贝利,帕特里克·富勒, Librosa:一个 Python 音频库(2019)
[2] Rami S. Alkhawaldeh,DGR:使用一维常规神经网络的人类语音性别识别 (2019)
[3]科里·贝克尔,使用机器学习识别声音的性别 (2016)
[5] Youness Mansar ,音频分类:一种卷积神经网络方法 (2018)
[6] Faizan Shaik h,使用深度学习开始音频数据分析(附案例研究) (2017)
[7] 麦克·斯梅尔斯,利用深度学习的声音分类,(2019)
[8] Aaqib Saeed ,城市声音分类,第 1 部分,(2016)
[9] Marc Palet Gual,使用运行在 FPGA 上的深度神经网络进行声音性别识别,(2016)
[10] Kamil Ciemniewski ,在 TensorFlow ,【2019】中使用扩展卷积和 CTC 从零开始进行语音识别
[11] Admond Lee ,如何用 Python 构建语音识别机器人 (2019)
[12] 阿德里安·易捷·许,利用卷积神经网络结合 Keras 进行城市声音分类:理论与实现,【2019】
[13] Sainath Adapa,K aggle freesound 音频标记 (2018)
[14] 歌词特征提取
如何为 Twitter 建立一个(准)实时仇恨言论分类器
资料来源:联合国人类住区规划署
从培训到新推文中的模型部署
社交平台上的网络欺凌和攻击性语言是我们现代的瘟疫之一。网上言论自由很容易演变成对性、政治和宗教信仰的攻击性、不合理和无建设性的批评。机器学习分类器和社交平台上可用的大量数据为缓解这一问题提供了有效的解决方案。
在这个项目中,一系列分类器,如逻辑回归、决策树和 CNN,在 40000 万条人类标记为冒犯性或非冒犯性的推文中进行了训练。这 4 万条推文是通过合并两个不同的数据集汇编而成的。其中一个最初取自于一个 Analytics Vidhaya 竞赛,而第二个数据集是在这个 Github 回购上发现的 20000 条攻击性推文的集合。
整个项目可以在这个 Github 页面上找到。
仇恨言论的定义取自《剑桥词典》:“基于种族、宗教、性别或性取向等因素,针对某个人或群体表达仇恨或鼓励暴力的公开言论”。这个项目的主要目标是建立一个能够识别 Twitter 上仇恨言论的模型。在最后一部分,获胜的模型运行了每天从英国和美国的 Twitter API 收集的新推文,显示了被标记为攻击性语言或仇恨言论的推文占总推文的百分比。可以在这里 找到最终仪表板的链接(如果没有任何东西出现,给它 20 秒的时间来加载和刷新页面)。
我曾尝试手动复制任何数据科学家在将模型投入生产时都会经历的流程(例如在 AWS SageMaker 上):
亚马逊 Sagemaker 上的典型循环来源:AWS 文档
项目的整体结构分为 5 个主要部分:
- Tweets 和 EDA 的数据清理
- 模特培训
- Twitter API 获取新数据到本地 MySQL 数据库
- 使用离线模型对新推文进行预测
- 通过 Streamlit 应用展示结果
数据清理
在循环的最开始,有必要处理我们可用的推文,并对它们进行一些转换,以便我们的算法能够以可理解的方式理解文本。与此同时,我们需要合并两个不同的数据集,以便获得负面和正面推文的例子。从最初的数据集中,我有意从每个类别(负面/正面)中选择了大约 20000 条推文,这样最终的数据集就已经平衡了。
现在一切就绪,预处理步骤可以应用于我们所有的最终推文。下面我分解了所有的预处理步骤(每个步骤的所有代码都可以在 data_cleaning.ipynb 笔记本中找到):
- 降低推文中的所有单词
- 删除重复
- 删除转发
- 移除 Twitter 句柄并计数*
- 移除特殊字符并测量推文长度
- 词类词汇化
- 在引理化之后重新格式化所有的空间和 ashtags
- 移除停用字词和短于 3 个字符的字词
- 删除不必要的列并保存最终的数据帧用于探索性数据分析
(在 Twitter 中,句柄用于在推文中指代某人,例如“今天塔图因阳光明媚,我们去喝杯奶昔吧@LukeSkywalker”。)
探索性数据分析
从这一点来看,所有这些 tweets 都准备好进行标记化,我们还可以对它们执行一些其他操作。下面是我创建的一些代码片段,用于创建最常见单词的数据框架,并根据词频构建单词云:
在这个阶段,已经有一些潜在的模式和初步的见解可以揭示出来:
你能从一条微博的长度来判断它吗?
推特的答案是肯定的!推文是否具有攻击性和长度似乎有关系。更具体地说,更长的推文与更积极的信息相关联。
基于推文长度的比率(正 0/负 1)
如上图所示,负面推文似乎比正面推文平均要短。1 代表负面推文,0 代表正面推文。可以看到,大多数负面推文集中在图表的左侧,对应于较短的长度。简单的 t 检验证实,p 值小于 0.001 时,平均差异显著。
手柄越多的推文攻击性越强吗?
答案似乎是肯定的。
基于每条推文的句柄数量的比率(正 0/负 1)
在最后一节中,手柄数量和攻击性之间的关系通过再次绘制正/负手柄数量与手柄总数的关系来衡量。绝大多数推文的句柄介于 0 和 3 之间,0 和 1 句柄推文之间存在明显差异,后者的攻击性推文比例明显高于 2 和 3 类。这可以解释为人们通过使用把手对某人咆哮。
*由于敏感语言,在 EDA 笔记本上可以找到更多 EDA 和 wordclouds】
模特培训
我在建模中使用的唯一预测器只是文本本身。用 tf-idf 方法对我们文本的词条化和精炼版本进行矢量化。Tf-idf 优于词袋(B-o-w ),因为在这种情况下词的稀有性非常重要。
tf-idf 矩阵用于所有模型,除了 CNN(它只将单词的符号化序列作为输入)和 Naive Bayes,在 Naive Bayes 中,我还尝试使用 B-o-w 框架来查看性能是否会受到影响。
CNN 的性能没有添加到下面的图表中,但是,它非常低,在验证集上的准确率刚刚超过 50%。在神经网络部分还需要做更多的工作,我可能会在低性能的 CNN 上实现 RNN。
跨培训和验证的所有模型的性能概述
所有模型都用 GridSearch CV 进行了调整和优化。如前所述,最终表现最好的模型是一个逻辑回归,在测试集上有 98%的 f-1 分数。由于初始数据集从一开始就被设计为平衡的,因此上述任何指标在这种情况下实际上都是有意义的。如果数据集是不平衡的,ROC 曲线或宏观/微观精度将是更好的拟合。
**最后,获胜模型的高性能可以用缺乏中立类别的推文来解释。**f1 如此高的分数是因为该模型可以轻松识别非常令人不快的推文和非常积极的推文。在这种情况下,引入第三类中性推文肯定会降低性能,也有助于模型拾取既不一定非常积极也不一定非常消极的推文。
Twitter API 获取和 MySQL 存储
现在我们已经有了一个分类推文的离线模型,我们还需要一个基础设施来收集和处理实时和新鲜的推文。
为了连接到 Twitter API,Twitter 开发团队需要批准您的登录请求。这可以通过点击链接这里来完成,并给出一些关于你打算如何使用 Twitter 数据的基本信息。Twitter 团队通常需要 2-3 个工作日才能获得最终批准和登录凭证。
在请求访问 Twitter 开发者门户后,可以在本地 MySQL 数据库上定期收集新的推文,该数据库的创建只是为了容纳推文的输入流。python 库 Tweepy 用于创建与 Twitter API 的连接。我们从原始 JSON 流中存储在 SQL 数据库上的唯一信息是:
- Twitter ID
- 推文时间
- Twitter 文本
所有文本都必须去掉表情符号,才能存储在数据库中。Tweepy 的流监听器可以基于特定主题和其他过滤器(如语言)收集信息。在这种情况下,所有标签为“冠状病毒”的词都被跟踪,以确保大量的推文流。同时,为了方便起见,只选择了英语。
请在下面找到用于此项目的 Tweepy 监听器对象的代码片段:
下面是 Listener 对象的实现,它只流式传输带有“冠状病毒”的标签,也是英文的。Wait_on_rate_limit 还确保不会达到每天的流媒体 tweets 限额。
在与数据库建立连接后,使用以下函数将数据传递并存储到 MySQL 数据库:
使用离线模型对新推文进行预测
有了基本的管道,我们现在可以在一个单独的笔记本上从 MySQL 数据库中提取批量的新流推文,在那里应用完全相同的预处理和数据清理(下面的 fresh_tweets_to_df 笔记本)。下图描述了管道的整体结构:
数据管道
在 df_to_heroku 部分,召回最终获胜的模型和 tf-idf 酸洗对象。唯一合适的 tf-idf 对象被转换到新的 tweets 上,以便生成每次都具有完全相同数量的列(9000 个单词)的矩阵。在这种情况下,单词之外的词汇被丢弃,而其余的由矩阵保留。
随后,将 predict_proba 函数应用于矢量化矩阵,并且仅过滤高于 0.9 的值,希望仅收集模型认为非常令人不快的推文。最后一步,绘制攻击性推文和大多数重复出现的词随时间的波动。这个数字然后通过 Streamlit 上传到 Heroku 上。
使这些笔记本运行的整个过程是通过一系列 cron 命令自动完成的,这些命令每隔 4 小时定期执行这些笔记本,使用 papermill 和 nbconvert 来触发和转换笔记本(下面的示例显示了计划在每天晚上 8.52 到 9.09 之间执行一次的整个过程):
自动化管道的 Cron 命令
请注意,nbconvert 和 papermill 的超时命令(设置为 150 秒)是一种额外的安全措施,以防止 Tweepy 对象随着时间的推移下载大量的 Tweepy。
通过 Streamlit 应用展示结果
在 df_to_heroku 笔记本中,一些非常高级的数据被汇总并保存到 matplotlib 图中,如下所示:
添加到 Streamlit 的 Matplotlib 图形的快照
最终仪表板应用程序的底层结构由几行代码构建而成:
局限性和未来工作
虽然最终的模型性能即使在我们数据集的测试结果上也非常好,但这个项目的一个主要限制是测量模型在新推文中的性能。实际上,我们可以只看一些被贴上负面标签的推文,就主观地认为它们是否具有攻击性。这最后一点提出了这个框架中的另一个重要问题,它与人类手动标记推文的固有偏见有关。
用来标记最初的基本事实的判断也是谬误的,因为对一些人来说是冒犯性的,对另一些人来说可能不是冒犯性的。单词以外的词汇可能是这种模式的主要缺点之一。该算法不能很好地处理包含大量单词的句子,这些单词不包含在我们最初的 9000 万单词长的词汇表中。递归神经网络可能是处理词汇外单词的最佳选择。
感谢阅读!
如何使用 Apache Beam、Pub/Sub 和 SQL 为在线商店构建实时数据管道
为虚拟在线商店(我们也将创建)构建实时数据管道的分步指南,以便稍后对其进行分析。
我的设置正在运行
看到我们的数据变得如此具有可塑性是一件令人着迷的事情。如今,我们有工具可以将高度嵌套的复杂日志数据转换为简单的行格式,有工具可以存储和处理数 Pb 的事务数据,还有工具可以在原始数据生成后立即捕获原始数据,并从中处理和提供有用的见解。
在本文中,我想分享一个这样的一步一步的过程,从我们自己的虚拟在线商店生成、摄取、处理并最终利用实时数据。
先决条件
- 谷歌云平台账户(如果你没有账户,请在此注册获得 3 个月的免费试用,可使用 300 美元的信用点数)。
- Linux 操作系统。
- Python 3。
体系结构
我在白板上设计流程图的技巧,当然还有一些编辑😉
步骤 1:创建发布/订阅主题和订阅者
Pub/Sub 是谷歌云平台中可用的消息服务。可以认为是 Apache Kafka 或者 Rabbitmq 的托管版。
消息服务基本上将产生数据的系统(在我们的例子中是虚拟存储应用程序)与处理数据的系统(在我们的例子中是 Apache beam on Dataflow)分离开来。
首先,我们需要在 GCP 创建一个服务帐户,允许我们从应用程序和 Apache beam 访问 Pub/Sub:
登录你的 GCP 控制台,从左侧菜单中选择 IAM & Admin :
创建服务帐户。
选择服务账户选项并创建一个新的服务账户:
插入新的服务帐户详细信息。
为我们的服务帐户提供发布/订阅管理角色:
提供访问发布/订阅所需的角色。
最后,创建一个密钥并下载私钥 JSON 文件以备后用:
正在下载服务帐户密钥。
接下来,我们将在 Pub/Sub 中创建一个主题,将我们的虚拟商店数据发布到其中,并创建一个订阅者,使用 Apache Beam 从其中提取数据。
从 GCP 控制台的左侧菜单中选择发布/订阅。
从控制台选择发布/订阅工具。
从子菜单中选择主题。从顶部选择创建主题。输入合适的名称,点击创建主题。
创建新主题。
现在,从左侧选择订阅选项,从顶部选择创建订阅。输入一个合适的名称,从下拉列表(我们在上一步中创建的)中选择订阅者将监听数据流的主题。之后点击在最后创建,保持其他选项不变。
为已创建的主题创建新的订阅者。
第二步:为生成实时数据创建一个虚拟存储
现在,我们将创建一个虚拟在线商店,将交易数据推送到我们在前面步骤中创建的发布/订阅主题中。
我使用过 Dash ,这是一个由 Plotly 创建的工具,使用不同的预构建 UI 组件(如按钮、文本输入等)快速构建 web 应用程序。构建 web 应用程序的完整教程超出了本文的范围,因为我们的主要焦点是构建实时管道。所以你可以在这里 从 GitHub repo 下载完整的应用。
唯一重要的是将我们的数据发布到发布/订阅主题的脚本:
让我们开始我们的在线虚拟商店,从 Git 下载项目后,创建一个虚拟 python 环境,并使用 需求安装所有的包。txt文件。现在打开终端中的文件夹,运行 app.py 文件。您将看到以下输出:
正在运行虚拟存储 dash 应用程序服务器。
进入你的网络浏览器,打开 localhost:8085。 你会看到虚拟商店的主页。
我自己的虚拟商店😜。如果你有密码,你可以改名字😉。
现在有趣的部分让我们订购一些商品,看看我们的数据是如何被发布到发布/订阅主题中,然后被我们之前创建的订阅者获取的。为每个项目添加一些数量,然后点击提交:
通过下单进行测试。
您可以在终端中看到,每次下订单时,都会打印出 JSON 格式的一些交易数据。同样的 JSON 数据也被推送到发布/订阅主题。让我们从我们的订户那里获取数据,进入 GCP 的发布/订阅仪表板,从左侧菜单中选择订阅选项,然后点击顶部的查看消息,然后点击获取以查看发布的数据:
在酒吧/酒馆登记。
步骤 3:创建 Apache Beam 管道并在数据流上运行它
在这个阶段,我们从虚拟在线商店向我们的发布/订阅用户实时获取数据。现在,我们将在 Apache Beam 中编写我们的管道,以解除数据嵌套,并将其转换为类似行的格式,以将其存储在 MySQL 服务器中。最后,我们将使用 GCP 数据流运行器运行我们的管道。
在我们开始编写数据管道之前,让我们在 GCP 创建一个云 SQL 实例,这将是我们存储已处理数据的最终目的地,您也可以使用其他云 SQL 服务,我已经为 MySQL 服务器编写了管道。
在 GCP 控制台上,从左侧菜单中选择 SQL 选项:
从 GCP 控制台选择 SQL 工具。
选择创建实例:
正在创建云 SQL 实例。
选择 MySQL:
选择 MySQL 服务器。
为 root 用户输入实例名和密码,将其他设置保留为默认设置,然后单击**创建,**现在可以休息了,启动实例需要 5-10 分钟:
插入细节并创建云 SQL 实例。
数据库启动并运行后,我们需要创建一个数据库和表。使用任何 SQL 客户端连接您的 MySQL 实例,并运行以下查询:
CREATE DATABASE virtual_store;CREATE TABLE transaction_data(
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` VARCHAR(255),
`timestamp` INT(11),
`item_id` VARCHAR(255),
`item_name` VARCHAR(255),
`category_name` VARCHAR(255),
`item_price` FLOAT,
`item_qty` INT,
PRIMARY KEY(`id`)
);
到目前为止,我们已经创建了我们的源(发布/订阅用户)和接收器(MySQL),现在我们将创建我们的数据管道。
下面给出了我们管道的目录表示,你可以从我的 GitHub repo 这里 克隆完整的目录:
├── dataflow_pipeline
│ ├── mainPipeline.py
│ ├── pipeline_config.py
│ ├── requirement.txt
│ └── setup.py
让我们首先从配置文件 pipeline_config.py、 开始。该文件包含所有配置,如发布/订阅订户详细信息、服务帐户密钥路径、MySQL DB 连接详细信息和表详细信息。
接下来是主管道文件,main pipeline . py,这是不同运行者(本地、数据流等)运行管道的入口点。在这个管道脚本中,我们从发布/订阅中读取数据,取消数据嵌套,并将最终数据存储在关系数据库中。稍后,我们将使用谷歌数据工作室可视化它。让我们看看代码:
首先,让我们在本地运行管道:
python mainPipeline.py
您将看到下面的输出,这意味着我们的管道现在正在侦听传入数据的发布/订阅。
本地运行管道的输出。
让我们从我们的虚拟在线商店下一些订单,看看管道的输出。
下样品订单。
单击提交后,您将立即在管道终端中看到输出:
通过下订单测试管道。
如您所见,我们的输入是嵌套数据,其中所有项目都嵌套在一个对象中,但是我们的管道将数据非嵌套到行级别。
让我们检查一下我们的数据库表:
检查最终目的表。
正如预期的那样,我们的单个订单被转换成项目式的行级数据,并实时地插入到我们的数据库中。
现在,我们将在 GCP 数据流中运行我们的管道,为此,我们需要运行以下命令:
python mainPipeline.py --runner DataflowRunner \
--project hadooptest-223316 \
--temp_location gs://dataflow-stag-bucket/ \
--requirements_file requirement.txt \
--setup_file ./setup.py
确保像我一样在 GCP 创建一个 staging bucket,并在上面的命令中的" temp_location "选项下提供链接,并在您的目录中创建一个包含以下内容的 setup.py ,这将防止 ModuleNotFoundError 。
高枕无忧,启动 GCP 数据流管道需要 5-10 分钟。现在转到 GCP 数据流仪表板,检查服务器是否启动。
检查在 GCP 运行的数据流作业。
您还可以看到管道的不同阶段,单击正在运行的作业可以查看详细信息。
数据流中管道所有阶段的可视化表示。
从虚拟商店下一些订单,并测试数据是否进入数据库。在我的情况下,它像预期的那样工作。MySQL 表中的数据行被实时插入:
最终测试检查数据流处理的数据。
注意:关闭我们在 GCP 部署管道的本地终端不会影响管道在 GCP 数据流中的运行。确保从 GCP 也终止管道。
步骤 4:创建 Datastudio Dashboard 以可视化我们的实时数据
Google Data Studio 是一款免费的数据可视化工具。它使用户能够从不同的数据源非常快速地创建一个交互式的、有效的报告仪表板。
让我们将我们的接收器(MySQL 服务器)连接到 Data Studio,并在我们的实时数据上创建一个仪表板。
转到https://datastudio.google.com。点击创建并选择数据源。
正在为 data studio 仪表板创建数据源。
在左上角为您的源命名,并选择 Cloud SQL for MYSQL 作为源(如果您的 MYSQL 数据库不在 GCP,请仅选择 MySQL
命名我们的数据源并选择云 SQL 进行连接。
输入您的数据库凭证并点击验证。之后选择自定义查询,进入查询,选择右上角的连接。
放入所有需要的细节和一个自定义查询从数据库中提取数据。
Data Studio 将连接到云 SQL 实例,并向我们显示我们的表的模式。现在点击右上角的创建报告:
Data Studio 提取的表架构。
根据您的要求添加图表和图形。您可以在这里 了解更多数据工作室 :
在 data studio 中添加图表和图形的选项。
我已经创建了一个基本的,2 图表仪表板,显示 项目销售数量 和 项目销售。
我的最终控制面板会在收到订单后立即更新:
最终控制面板,查看我们实时数据的见解。
结论
在本文中,我解释了实时管道是如何工作的。我们已经创建了数据管道的所有组件,一个实时生成数据的源应用程序,一个接收数据的缓冲区,一个在 Google 云平台中处理数据的实际管道,一个存储已处理数据的接收器,以及一个显示最终数据的仪表板。
请在下面留下您对本文的评论,如果您在上面指定的任何步骤中遇到问题,您可以通过insta gram和LinkedIn联系我。
如何使用 Faust 和 MLFlow 构建实时欺诈检测管道
关于使用类似 Kafka Streams 的 python 库(Faust)和使用 MLFlow 服务的欺诈检测模型构建低延迟 ML 管道的教程
在本教程中,我们将学习在本地启动一个 Kafka 集群,编写一个发送消息的生成器,创建一个简单的欺诈检测机器学习训练流程,通过 REST 接口公开模型,并进行实时预测。
我们将使用的主要框架是:
- Faust :流处理库,使用 async/away 范例,需要 python 3.6 以上版本
- Kafka :我们将使用 Kafka 的融合版本作为我们的流媒体平台
- MLFlow :一个开源平台,用于监控和保存训练后的机器学习模型
- Jupyter 实验室:我们运行代码的环境
我们还需要一些数据来进行培训。我们可以使用来自 Kaggle 信用卡欺诈竞赛的 CSV 源。
TL;DR:代码在GitHub上。
第一步:进行培训
让我们首先构建我们的欺诈检测模型。我们将读取代表信用卡交易的 CSV 数据,并在两个类0(not fraud)
和1(fraud)
之间应用简单的二元逻辑回归分类。
df = pd.read_csv('creditcard.csv')df.dtypesTime float64
V1 float64
V2 float64
V3 float64
V4 float64
V5 float64
V6 float64
V7 float64
V8 float64
V9 float64
V10 float64
V11 float64
V12 float64
V13 float64
V14 float64
V15 float64
V16 float64
V17 float64
V18 float64
V19 float64
V20 float64
V21 float64
V22 float64
V23 float64
V24 float64
V25 float64
V26 float64
V27 float64
V28 float64
Amount float64
Class int64
正如我们所看到的,我们读取的大多数列都是float
,除了Class
,它是我们的目标变量。现在让我们开始训练:
x_name = df.iloc[:, 1:30].columns
y_name = df.iloc[:1, 30: ].columnsdata_x = df[x_name]
data_y = df[y_name]train_x, test_x, train_y, test_y = train_test_split(data_x, data_y, train_size=0.7, test_size=0.3)model = LogisticRegression()
model.fit(train_x, train_y.values.ravel())
对于特征,我们使用V1 — V28
和Amount
。我们在train
和test
数据之间进行分割,并拟合模型。我们可以检查一些性能指标:
pred_y = model.predict(test_x)accuracy_score(test_y, pred_y)
0.9993094811745842f1_score(test_y, pred_y)
0.7773584905660378precision_score(test_y, pred_y)
0.8272727272727273recall_score(test_y, pred_y)
0.6776315789473685
如果我们仅仅使用准确性作为衡量标准,我们可能会搬起石头砸自己的脚。始终使用更好的绩效指标,如f1_score
、precision
和recall
。
步骤 2:通过 REST 服务模型
培训结束后,我们可以保存新的欺诈检测模型:
mlflow.sklearn.save_model(model, path='./fraud_model')
我们在 MLFlow 中使用sklearn
模块,因为这将帮助我们处理 servis 部分。
让我们在项目的根目录下启动一个终端,并键入以下命令:
mlflow models serve -m fraud_model
这需要一点时间,因为除了部署微服务之外,还会创建一个conda
环境。这是为了确保下次我们进行部署时,我们将依赖关系锁定在某个版本和单独的虚拟环境中。如果一切运行正常,我们会注意到我们的服务有了一个 url:
Listening at: [http://127.0.0.1:5000](http://127.0.0.1:5000)
我们可以使用cURL
从终端进行快速测试:
curl [http://127.0.0.1:5000/invocations](http://127.0.0.1:9999/invocations) -H 'Content-Type: application/json' -d '{
"columns":["V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17","V18","V19","V20","V21","V22","V23","V24","V25","V26","V27","V28","Amount"],
"data":[[12.8,0.029,0.48,0.98,6.2,29.1,3.33,1.2,0.39,75.1,0.66,1.2,1.3,44.2,12.8,0.029,0.48,0.98,6.2,29,3.33,1.2,0.39,75.3,0.66,1.2,1.3,44.2,1.1]]
}'
我们使用包含特性列和一组值的JSON
对象发送一个POST
请求。我们将从分类器[0]
中得到答案。
步骤 3:运行 docker compose 来启动 kafka 集群
为了构建集群,我们将使用一个docker-compose
文件来启动所有需要的 docker 容器:zookeeper 和一个代理。
现在简单地说,kafka 是一个分布式流媒体平台,能够处理大量的消息,这些消息被组织或分组到主题中。为了能够并行处理一个主题,必须将它分成多个分区,来自这些分区的数据存储在称为代理的独立机器中。最后,zookeeper 用于管理集群中代理的资源。为了读写 kafka 集群,我们需要一个代理地址和一个主题。
docker-compose
将启动端口2181
上的zookeper
,端口9092
上的kafka broker
。除此之外,我们使用另一个 docker 容器kafka-create-topic
的唯一目的是在 kafka broker 中创建一个主题(称为 test)。
要启动 kafka 集群,我们必须在定义 docker compose 文件的同一文件夹中运行以下命令行指令:
docker-compose up
这将启动所有带有日志的 docker 容器。我们应该在控制台中看到类似这样的内容:
第四步:运行卡夫卡制作程序
为了能够实时消费数据,我们首先必须将一些消息写入 kafka。我们将使用 python 中的confluent_kafka
库来编写一个生产者:
我们将发送格式如下的JSON
消息:
{
"columns":["V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17","V18","V19","V20","V21","V22","V23","V24","V25","V26","V27","V28","Amount"],
"data":[]
}
这与我们用于 MLFlow web 服务的格式相同,其中data
可以包含多个特性值列表。
对于我们写入队列的每条消息,我们还需要分配一个键。我们将根据uuid
随机分配一个,以在集群中实现良好的分布。最后,我们还运行一个flush
命令来确保所有的消息都被发送出去。
一旦我们运行confluent_kafka_producer
,我们应该会收到一个日志,告诉我们数据已经正确发送:
we’ve sent 6 messages to 127.0.0.1:9092
第五步:经营浮士德消费者
我们已经到达了教程的最后一步。使用 Faust 框架,我们将运行一个简单的 worker,它将使用来自 Kafka 的数据,并将预测应用到新功能上。我们需要为此创建一个单独的 python 脚本。首先,我们定义我们的 Faust 应用程序,以及主题:
app = faust.App(
'fraud_detection_app',
broker='kafka://localhost:9092',
value_serializer='raw',
)kafka_topic = app.topic('test')
我们定义从中读取数据的代理和序列化程序格式。我们很乐意使用raw
,因为我们只是将数据传递给机器学习算法。
现在,让我们定义协程。在浮士德框架中,它被称为agent
:
代理是一个异步进程。我们连接到 Kafka 主题,对于我们读取的每个值,我们调用 REST 服务并获得结果。正如预期的那样,在 Kafka 中有了新的值之后,它会立即运行。
剧本定稿了。姑且称之为fraud_detection_worker.py
。现在我们可以运行它了。从项目根目录的终端开始,我们需要键入:
faust -A fraud_detection_worker worker -l info
这将启动一个 worker,它是应用程序的一个实例。如果我们需要更多的计算能力,我们可以启动额外的工人。
如果一切运行正常,我们将开始看到以下日志:
Input data: b'{"columns": ["V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20", "V21", "V22", "V23", "V24", "V25", "V26", "V27", "V28", "Amount"], "data": [[12.8, 0.029, 0.48, 0.98, 6.2, 29.1, 3.33, 1.2, 0.39, 75.1, 0.66, 11.2, 1.3, 0.2, 12.8, 0.029, 0.45, 0.98, 6.2, 29, 3.33, 1.2, 0.39, 75.3, 0.3, 2.2, 1.3, 2.2, 1.01]]}'Fraud detection result: [0]
我们已经到了本教程的结尾。我希望你喜欢它,并发现它有用。我们看到了现在如何选择使用纯 python 框架来进行实时数据处理。这是一个很大的优势,因为这种编程语言中有很多数据科学工作。
如何使用潜在因素模型在图形数据库中建立推荐系统
数据库内训练避免了将数据从 DBMS 导出到其他机器学习平台,从而更好地支持连续的模型更新
什么是推荐系统?
推荐系统是基于可用数据预测个人偏好选择的任何评级系统。推荐系统被用于各种服务,例如视频流、在线购物和社交媒体。通常,系统基于其对用户将给予项目的评级的预测向用户提供推荐。推荐系统可以从两个方面进行分类,利用的信息和预测模型。
图。1(图片作者)。这个示例数据集包括两个用户,Alice 和 Bob,两部电影,玩具总动员和钢铁侠,以及三个评级记录(实线)。每个用户和电影都标有其属性。
内容过滤与协同过滤
两种主要的推荐方法,内容过滤和协作过滤,主要根据用于评级预测的信息而不同。图 1 显示了一组电影分级数据以及一些用户和电影的标签。注意用户对电影的评分来自一个图结构:用户和电影是图的顶点,评分是图的边。在这个例子中,内容过滤方法利用电影和用户的标签属性。通过查询标签,我们知道爱丽丝是漫威电影的忠实粉丝,而钢铁侠是漫威电影,因此钢铁侠系列将是对她的一个很好的推荐。内容过滤评分系统的一个具体例子是 TF-IDF,用于对文档搜索进行排名。
用户和电影上的标签可能并不总是可用。当标签数据稀疏时,内容过滤方法可能不可靠。另一方面,协同过滤方法主要依赖于用户行为数据(例如,评级记录或电影观看历史)。在上面的例子中,爱丽丝和鲍勃都喜欢电影玩具总动员,他们分别给这部电影打了 5 分和 4.5 分。基于这些评级记录,可以推断这两个用户可能共享相似的偏好。现在考虑到鲍勃喜爱钢铁侠,我们可以预期爱丽丝也会有类似的行为,向爱丽丝推荐钢铁侠。k-最近邻( KNN )是一种典型的协同过滤方法。然而,协同过滤有所谓的冷启动问题——它不能为没有评级记录的新用户产生推荐。
基于内存与基于模型的对比
根据所使用特征的隐含性,推荐系统还可以分为基于记忆的方法和基于模型的方法。在上面的例子中,所有的用户和电影特征都是显式给出的,这使得我们可以根据他们的标签直接匹配电影和用户。然而,有时需要深度学习模型来从用户和电影的信息中提取潜在特征(例如,基于电影的轮廓对电影进行分类的 NLP 模型)。基于模型的推荐系统利用机器学习模型进行预测。而基于记忆的推荐系统主要利用显式特征。
不同类型的推荐系统的一些典型例子如下所示。
(图片由作者提供)
图因子分解如何为推荐系统工作
如上所述,诸如 KNN 的协作过滤方法可以在不知道电影和用户属性的情况下预测电影评级。然而,当评级数据稀疏时,即典型用户只对几部电影进行了评级时,这种方法可能不会产生准确的预测。在图 1 中,如果鲍勃没有对玩具总动员评分,KNN 无法预测爱丽丝对钢铁侠的评分,因为爱丽丝和鲍勃之间没有路径,爱丽丝本身也没有“邻居”。为了应对这一挑战,图分解方法[1]将基于模型的方法与协作过滤方法相结合,以提高评级记录稀疏时的预测准确性。
图 2 说明了图分解方法的直觉。图分解也称为潜在因素或矩阵分解方法。目标是获得每个用户和电影的向量,该向量代表他们的潜在特征。在这个例子中(图 2),向量的维数被指定为 2。电影向量的两个元素 x ( i )表示这部电影的浪漫程度和动作内容,用户向量的两个元素 θ ( j )分别表示用户对浪漫和动作内容的偏好程度。对用户 j 将给予电影 i 的评价的预测是 x ( i )和 θ ( j )的点积,因为我们预期这两个向量的更好的对齐表示用户对电影的更高程度的偏好。
图。2(图片由作者提供)。该表显示了由 4 个用户给出的 6 部电影的评级记录。等级在 0 到 5 的范围内。缺失的评级用问号表示。 θ(j) 和 x(i)代表潜在因子向量。Alice 的评级预测是根据潜在因素计算得出的,并在真实值旁边显示为橙色。
图 2 中的例子仅仅是为了说明图分解方法的直观性。实际上,每个矢量元素的含义通常是未知的。向量实际上是随机初始化的,并通过最小化下面的损失函数得到“训练”[1]。
其中 M 为评分记录数, n 为潜在因子向量的维数, y ( i , j )为用户 j 给电影 i 的评分,𝝀为正则化因子。第一项本质上是预测的平方误差(k 上的 θ(j)_k 和x(i)_k 之和),第二项是避免过拟合的正则化项。损失函数的第一项也可以用矩阵的形式表示,
其中 R 是以 y ( i , j )为元素的评分矩阵, U 和 V 分别是由用户和电影的潜在因素向量构成的矩阵。最小化预测的平方误差等价于最小化 R - UV^T 的 Frobenius 范数。因此,这种方法也被称为矩阵分解法。
您可能想知道为什么我们也将这种方法称为图分解方法。如前所述,评级矩阵 R 很可能是一个稀疏矩阵,因为不是所有的用户都会给所有的电影评级。基于存储效率的考虑,这种稀疏矩阵往往存储为一个图,其中每个顶点代表一个用户或一部电影,每个边代表一条评分记录,其权重作为评分。如下所示,用于优化损失函数并由此获得潜在因子的梯度下降算法也可以表示为图形算法。
θ(j)_k 和 x(i)_k 的偏导数可以表示如下:
上面的等式表明,顶点上的潜在向量的偏导数只取决于它的边和邻居。对于我们的例子,用户向量的偏导数仅由用户之前已经评级的电影的评级和潜在向量来确定。这一特性允许我们将评级数据存储为图表(图 5 ),并使用图表算法来获取电影和用户的潜在因素。用户和电影特征可通过以下步骤获得:
(图片由作者提供)
值得一提的是,计算导数和更新潜在因子可以在 Map-Reduce 框架中进行,其中步骤 2 可以针对每个边 _( i 、 j )(即评级)并行进行,步骤 3 也可以针对每个顶点 i (即用户或电影)并行进行。
为什么您需要一个图表数据库来进行推荐
对于工业应用程序,数据库可以容纳数亿用户和电影,以及数十亿条评级记录,这意味着评级矩阵 A、特征矩阵 U 和 V,加上其他中间变量,在模型训练期间可以消耗万亿字节的内存。这种挑战可以通过在图形数据库中训练潜在特征来解决,其中评级图形可以分布在多节点集群中并且部分存储在磁盘上。此外,图形结构的用户数据(即评级记录)首先存储在数据库管理系统中。数据库内模型训练还避免了将图形数据从 DBMS 导出到其他机器学习平台,从而更好地支持对进化训练数据的连续模型更新。
如何在 TigerGraph 中构建推荐系统
在这一部分,我们将在 TigerGraph Cloud 上提供一个图形数据库(免费),加载一个电影评级图,并在数据库中训练一个推荐模型。按照下面的步骤,你将在 15 分钟内拥有一个电影推荐系统。
按照创建您的第一个 TigerGraph 实例(前 3 步)到在 TigerGraph Cloud 上提供一个免费实例。第一步,选择数据库内机器学习推荐作为入门套件。第三步,选择 TG.Free。
按照tiger graph 云门户入门和登录 GraphStudio 。在将数据映射到图形页面,您将看到数据文件是如何映射到图形的。在这个初学者工具包中, MovieLens-100K 文件已经上传到实例中。 MovieLens-100K 数据集有两个文件:
- movieList.csv 有两列显示每部电影的 id 和电影名称(电影年份)。
- rating.csv 是用户对电影的评级列表。这三列包含用户 id、电影 id 和分级。
图 3(图片由作者提供)。将数据映射到图形页面
进入加载数据页面,点击开始/恢复加载。加载完成后,您可以在右侧看到图表统计信息。MovieLens-100K 数据集有 944 个用户对 1682 部电影给出的 100,011 条评级记录。
图 4(图片由作者提供)。加载数据页面。
加载完成后,您可以在右侧看到图表统计信息。在 Explore Graph 页面中,您可以看到我们刚刚创建了一个二分图,其中每个电影和用户的信息存储在顶点中,评级记录存储在边中。
图 5(图片由作者提供)。探索图页面。
在编写查询页面中,您会发现我们的推荐系统所需的查询已经添加到数据库中。这些查询是用 TigerGraph 的查询语言 GSQL 编写的。点击安装所有查询将所有 GSQL 查询编译成 C++代码。您还可以在此页面上看到自述文件查询。按照下面的步骤用电影分级记录建立一个推荐。
图 6(图片由作者提供)。编写查询页面
运行 splitData 查询
该查询将评级数据分为验证集和训练集。测试数据的分数默认设置为 30%。(即 30%的评级数据将用于模型验证,其余 70%将用于模型训练)。该查询还输出总数据集、验证数据集和训练数据集的大小。
运行规范化查询
该查询通过用电影的平均评分减去每个评分来标准化评分。每部电影的平均评级是根据训练数据计算的。
运行初始化查询
该查询初始化用户和电影的潜在因素向量。潜在因素向量中的元素由正态分布随机数生成器初始化。查询输入是标准偏差和正态分布的平均值。
运行培训查询
该查询使用梯度下降算法训练推荐器模型。默认情况下,特征数量设置为 19。该数字必须与初始化查询中的 num_latent_factors 相同。查询输入是学习率、正则化因子和训练迭代次数。该查询输出每次迭代的均方根误差(RMSE)
计算出潜在因素后,我们可以测试并使用该模型进行推荐。
运行测试查询
该查询输出用户提供的真实评级以及模型预测的评级。查询输入是一个用户 id。查询输出是用户给出的所有评级和评级预测
运行推荐查询
该查询输出推荐给用户的前 10 部电影。基于评级预测推荐电影。
结论
在图数据库中训练机器学习模型有可能实现推荐模型的实时更新。在本文中,我们介绍了图分解方法的机制,并展示了一个使用 TigerGraph 云服务构建自己的电影推荐系统的分步示例。一旦您熟悉了这个例子,您应该有信心根据您的用例定制这个推荐系统。
参考
[1] Ahmed,Amr 等.“分布式大规模自然图分解”第 22 届国际万维网会议论文集 (2013)
如何构建递归神经网络检测假新闻
在一个联系越来越紧密的世界里,谎言更容易传播。事实证明,有了由被分类为可靠或不可靠的新闻文章组成的数据集,就有可能检测出假新闻。在本教程中,我们将建立一个具有卷积和 LSTM 细胞的神经网络,在 Kaggle 假新闻挑战中给出前 5 名的性能。
由 u/Borysk5 制作的地图
我们试图探测什么? 如上图所示,假新闻是全世界的问题。中国对假新闻的定义可能与中东或美国有很大不同。数据决定了检测假新闻的定义。我们在这个例子中使用的数据集来自 Kaggle,一个举办机器学习竞赛的网站。数据集由带有可靠或不可靠标签的新闻文章组成。如果一条新闻不可靠,它就被认为是假新闻。
数据集中的假新闻文章示例:
被证明是真的五大阴谋论因为唐纳德·特朗普在每个选举年都竞选总统,媒体上对他偏袒的指控飞来飞去,这和共和国本身一样古老。但今年,阴谋论者声称,MSM 不仅是不诚实的希拉里的囊中之物,而且还积极努力,通过虚假的民调、虚假的故事以及与候选人的猖獗和非法勾结来确保她的当选。谢谢你,维基解密(……)我知道希拉里克林顿删除的邮件在哪里,也知道如何合法获取。
数据集中一篇可靠文章的例子:
美国职业棒球大联盟的春季训练又开始了,纽约大都会队的游击手路易斯·吉约莫已经给这个大联盟俱乐部留下了深刻的印象。周四,迈阿密马林鱼队的游击手 Adeiny Hechavarria 挥棒丢掉了球棒。球棒飞向大都会队的休息区,队员们争先恐后地躲开。然而,吉约姆没有离开他的位置,而是在蝙蝠飞过他的头时抓住了它。
算法如何工作 文本有多种格式。推特上的文字可能真的很乱。新闻文章可以使用大量的空行。每个自然语言处理任务的第一步是清理文本,删除空行和不必要的标点符号。
下一步是将单词转换成数字,因为计算机不能阅读单词。有多种方法可以做到这一点。最简单的方法是为每个独特的单词分配数字,然后将其用作模型的输入。因此,句子“去年夏天,歌手游览了美国西海岸”将变成[1 2 3 4 5 3 6 7 3 8]。如你所见,每个独特的单词都被赋予了一个新的编号。另一种更常见的方法是使用预训练的单词嵌入。单词被转换成张量表示,而不是转换数字中的每个单词。因此,当使用四维嵌入时,每个(唯一的)单词都被转换成四个数字的组合。单词嵌入工作得如此好是因为单词的语义被捕获,具有相同含义的单词具有相似的张量值,并且与其他单词组的差异也是相似的。下面的例子形象地说明了这一点。正如你所看到的,当单词是阴性时,所有的单词都有更大的 Y 值。
来源:斯坦福大学
在单词被转换成单词嵌入之后,单词被输入到神经网络中。这个神经网络由不同的层组成。第一层是卷积层。卷积是一种可以从数据中提取要素的过滤器。例如,在图像检测中,卷积可用于检测边缘或形状。在自然语言处理中,卷积也可以提高性能。下面的示例显示了一个过滤器,它提取中间有一个单词的两个单词之间的关系。在每一步中,滤波器与字嵌入值相乘。过滤值 1 乘以单词嵌入值得到单词嵌入值,而过滤值 0 得到 0。
下一层是最大池层。这一层在张量上迭代并取最大值。这样,特征空间被压缩。这一步确保重要的特征被保留,而空白被删除。
下一层是长短期记忆(LSTM)层。普通的 LSTM 单元由一个单元、一个输入门、一个输出门和一个遗忘门组成。细胞在任意的时间间隔内记忆数值,三个门调节进出细胞的信息流。更多关于 LSTM 层的信息可以在这里找到。
进行预测之前的最后一层是完全连接的层。这是一个常规的神经网络层,其中所有节点都相互连接。整体网络架构如下所示:
代码 代码是在 Google Colab 中编程的。数据可在此下载:
https://www.kaggle.com/c/fake-news/data
Google Colab 环境可以在以下位置找到:
https://github . com/matdekoning/FakeNewsClassifier/blob/master/FakeNewsClassifier . ipynb
这个 Google Colab 环境将引导你通过编码递归卷积神经网络。在代码中,首先导入所需的库(即 Keras 和 Tensorflow)。该代码检查是否安装了 Tensorflow 2.0,如果安装了旧版本,将进行更新。如果您更新了 Tensorflow,请重新启动网页。在第二个单元格中,您可以填充您的 Google Drive 环境。这是一种连接数据集的简单方法。将数据集上传到 Google drive 上的主文件夹,挂载 Google drive,在 cell 3 中可以在 Google Colab 环境中导入数据集。
结果 结果如下图所示:
经过 5 分钟的训练,该模型达到了 0.9041 的验证精度,这意味着 10 篇新闻文章中有超过 9 篇被正确分类为可靠与否。在 Kaggle 的提交数据集上进行预测后,该算法获得了 0.96 的分数。这个分数是前 5 名的表现。
事实证明,这种架构对于假新闻检测非常有效。具有池层的卷积的优点是执行时间短得多,而性能保持不变。这种架构在其他自然语言分类任务中也很有用。该模型在有毒评论分类以及情感分析方面给出了良好的结果。
如何用 Python 构建回归模型
数据科学
详细直观的分步演练
如果你是一名有抱负的数据科学家或资深数据科学家,这篇文章就适合你!在本文中,我们将使用 Python 构建一个简单的回归模型。为了增加一点趣味,我们将不会使用广受欢迎且无处不在的波士顿房屋数据集,而是使用一个简单的生物信息学数据集。特别是,我们将使用 德莱尼溶解度 数据集,它代表了计算药物发现中一个重要的物理化学性质。
有抱负的数据科学家会发现逐步教程特别容易获得,而经验丰富的数据科学家可能希望找到一个新的具有挑战性的数据集,以尝试他们最先进的机器学习算法或工作流。
1.我们今天在建造什么?
一个回归模型!我们将使用 Python 来完成这项工作。在此过程中,我们将使用一个生物信息学数据集(从技术上讲,它是化学信息学数据集)来建立模型。
特别是,我们要预测小分子水溶性的对数值。水溶性值是分子溶于水的能力的相对量度。它是有效药物的重要理化性质。
有什么比卡通插图更好的方式来了解我们今天正在建造的概念呢?
**化学信息学数据集的机器学习模型构建的示意性工作流程的卡通图示,其中目标响应变量被预测为输入分子特征的函数。**从技术上讲,这一过程被称为定量构效关系 (QSAR)。(由 Chanin Nantasenamat 绘制
2.德莱尼溶解度数据集
2.1.数据理解
顾名思义, 德莱尼溶解度 数据集由一组 1144 个分子的 水溶性 值及其相应的化学结构组成。对于这些,在生物学领域之外,有一些术语我们将花一些时间来澄清。
分子 或有时被称为小分子或化合物是由原子组成的化学实体。让我们打个比方,让我们把原子想象成乐高积木,1 个原子就是 1 个乐高积木。当我们用几块乐高积木来建造某样东西时,不管是房子、汽车还是某个抽象的实体;这样构建的实体可与分子相媲美。由此,我们可以将原子形成一个分子的具体排列和连接方式称为 化学结构 。
**把分子的构造比喻成乐高积木。**这个黄色的房子来自乐高 10703 创意建造者盒子。(由 Chanin Nantasenamat 绘制)
那么你正在构建的每个实体有什么不同呢?它们的不同之处在于区块的空间连通性(即各个区块是如何连接的)。在化学术语中,每个分子的化学结构不同。因此,如果你改变了积木的连接性,那么你就有效地改变了你正在建造的实体。对于分子,如果原子类型(例如碳、氧、氮、硫、磷、氟、氯等。)或原子团(例如羟基、甲氧基、羧基、醚基等。)被改变,那么分子也将被改变,从而成为新的化学实体(即产生新的分子)。
**一个分子模型的卡通插图。**红色、蓝色、深灰色和白色代表氧、氮、碳和氢原子,而连接这些原子的浅灰色是键。每个原子都可以媲美一块乐高积木。上面显示的构建分子可与构建的乐高实体(如本文上面显示的黄色房子)相媲美。(由 Chanin Nantasenamat 绘制)
要成为一种有效的药物,分子将需要被人体吸收和分布,这种特性直接由 水溶性 决定。溶解性是研究人员在设计和开发治疗药物时考虑的一个重要特性。因此,由于溶解性差而不能到达所需目的地的有效药物将是差的候选药物。
2.2.正在检索数据集
Delaney 在名为 ESOL:从分子结构直接估算水溶性的研究论文中进行的水溶性数据集可作为补充文件获得。为了您的方便,我们还下载了整个 德莱尼溶解度数据集 ,并在数据 GitHub 教授上提供。
Delaney 溶解度数据集原始版本的预览。完整版可在数据教授 GitHub 上获得。
代码练习
我们开始吧,好吗?
启动 Google Colab 或您的 Jupyter 笔记本,运行以下代码单元。
代码解释
现在让我们来看看每个代码单元的含义。
第个编码单元,
- 正如代码字面上所说,我们将把
pandas
库作为pd
导入。
第二代码单元:
- 将德莱尼溶解度数据集所在的 URL 分配给
delaney_url
变量。 - 通过
pd.read_csv()
函数读入德莱尼溶解度数据集,并将结果数据帧分配给delaney_df
变量。 - 调用
delaney_df
变量返回输出值,该输出值实际上打印出包含以下 4 列的数据帧:
- 化合物 ID —化合物的名称。
- 实测对数(溶解度:mol/L)—Delaney 在原始研究文章中报告的实验水溶性值。
- ESOL 预测对数(溶解度:mol/L)—Delaney 在原始研究文章中报告的预测水溶性值。
- SMILES —化学结构信息的一维编码
2.3.计算分子描述符
需要注意的一点是,作者最初提供的上述数据集还不能开箱即用。特别是,我们将不得不使用 SMILES 符号 通过 rdkit Python 库来计算 分子描述符 ,这在以前的媒体文章( 如何使用机器学习进行药物发现 )中以逐步的方式进行了演示。
需要注意的是, 微笑符号 是对分子化学结构信息的一维描绘。 分子描述符 是对分子独特的物理化学性质的定量或定性描述。
让我们将分子描述符视为一种以数字形式唯一表示分子的方法,机器学习算法可以理解这种方法,以学习、预测和提供关于 结构-活性关系 的有用知识。如前所述,原子的特定排列和连接产生不同的化学结构,从而决定了它们将产生的最终活性。这种概念被称为结构-活性关系。
包含计算的分子描述符及其相应响应变量(对数)的数据集的处理版本如下所示。这个处理过的数据集现在准备好用于机器学习模型构建,其中前 4 个变量可以用作 X 变量,而对数变量可以用作 Y 变量。
**德莱尼溶解度数据集处理版本的预览。**实际上,原始版本中的 SMILES 符号被用作计算 4 个分子描述符的输入,这在之前的媒体文章和 YouTube 视频中有详细描述。完整版可在数据教授 GitHub 上获得。
4 个分子描述符和响应变量的快速描述如下:
- cLogP —辛醇-水分配系数
- MW —分子量
- RB—可旋转债券数量
- AP — 芳香比例=芳香原子数/重原子总数
- 日志 —水溶性的日志
代码练习
让我们继续读入包含计算出的分子描述符的 CSV 文件。
代码解释
现在让我们来看一下代码单元的含义。
- 将 Delaney 溶解度数据集(带有计算的描述符)所在的 URL 分配给
delaney_url
变量。 - 通过
pd.read_csv()
函数读入德莱尼溶解度数据集(带有计算出的描述符),并将结果数据帧赋给delaney_descriptors_df
变量。 - 调用
delaney_descriptors_df
变量返回输出值,该输出值实际上打印出包含以下 5 列的数据帧:
- 莫洛格普
- MolWt
- NumRotatableBonds
- 芳香比例
- 日志
前 4 列是使用rdkit
Python 库计算的分子描述符。第五列是响应变量日志。
3.数据准备
3.1.将数据分离为 X 和 Y 变量
在使用scikit-learn
库构建机器学习模型时,我们需要将数据集分成输入特征( X 变量)和目标响应变量( Y 变量)。
代码练习
遵循并实现以下 2 个代码单元,将包含在delaney_descriptors_df
数据帧中的数据集分成 X 和 Y 子集。
代码解释
让我们来看看这两个代码单元。
第一个编码单元格:
- 这里我们使用 drop()函数专门“删除”logS 变量(这是 Y 变量,我们将在下一个代码单元格中处理它)。因此,我们将有 4 个剩余变量分配给 X 数据帧。特别是,我们将
drop()
函数应用于delaney_descriptors_df
数据帧,如在delaney_descriptors_df.drop(‘logS’, axis=1)
中,其中第一个输入参数是我们想要删除的特定列,而axis=1
的第二个输入参数指定第一个输入参数是一列。
第二编码单元:
- 这里,我们通过
delaney_descriptors_df.logS
从delaney_descriptors_df
数据帧中选择一列(‘logS’列),并将其分配给 Y 变量。
3.2.数据分割
在评估模型性能时,标准做法是将数据集拆分为 2 个(或更多分区)分区,这里我们将使用 80/20 的拆分比率,其中 80%的子集将用作训练集,20%的子集将用作测试集。由于 scikit-learn 要求将数据进一步分离到它们的 X 和 Y 组件,因此train_test_split()
函数可以轻松执行上述任务。
代码练习
让我们实现以下两个代码单元。
代码解释
让我们看看代码在做什么。
第一个编码单元格:
- 这里我们将从 scikit-learn 库中导入
train_test_split
。
第二个编码单元格:
- 我们首先定义
train_test_split()
函数将生成的 4 个变量的名称,这包括X_train
、X_test
、Y_train
和Y_test
。前 2 个对应于训练和测试集的 X 数据帧,而后 2 个对应于训练和测试集的 Y 变量。
4.线性回归模型
现在,有趣的部分来了,让我们建立一个回归模型。
4.1.训练线性回归模型
代码练习
这里,我们将使用 scikit-learn 中的LinearRegression()
函数,使用普通的最小二乘线性回归建立一个模型。
代码解释
让我们看看代码在做什么
第一个编码单元:
- 这里我们从 scikit-learn 库中导入了 linear_model
第二编码单元:
- 我们将
linear_model.LinearRegression()
函数赋给model
变量。 - 使用命令
model.fit(X_train, Y_train)
构建模型,由此 model.fit()函数将把X_train
和Y_train
作为输入参数来构建或训练模型。特别是,X_train
包含输入特征,而Y_train
包含响应变量(日志)。
4.2.应用经过训练的模型来预测来自训练和测试集的日志
如上所述,model.fit()
训练模型,训练后的模型保存在model
变量中。
代码练习
我们现在将应用经过训练的模型对训练集进行预测(X_train
)。
我们现在将应用训练好的模型对测试集进行预测(X_test
)。
代码解释
让我们开始解释。
以下解释将仅涵盖训练集(X_train
),因为通过执行以下简单调整,完全相同的概念可以同样地应用于测试集(X_test
):
- 将
X_train
替换为X_test
- 将
Y_train
替换为Y_test
- 将
Y_pred_train
替换为Y_pred_test
其他一切都完全一样。
第一个编码单元格:
- 通过调用
model.predict()
并使用X_train
作为输入参数来执行对日志值的预测,这样我们就可以运行命令model.predict(X_train)
。产生的预测值将被赋给Y_pred_train
变量。
第二个编码单元:
模型性能指标现已打印。
- 回归系数值从
model.coef_
获得, - y 轴截距值从
model.intercept_
获得, - 使用
mean_squared_error()
函数计算均方误差(MSE ),使用Y_train
和Y_pred_train
作为输入参数,因此我们运行mean_squared_error(Y_train, Y_pred_train)
- 使用
Y_train
和Y_pred_train
作为输入参数,使用r2_score()
函数计算决定系数(也称为 R ),因此我们运行r2_score(Y_train, Y_pred_train)
4.3.打印出回归方程
线性回归模型的方程实际上是模型本身,您可以插入输入特征值,方程将返回目标响应值(对数)。
代码练习
现在让我们打印出回归模型方程。
代码解释
第一个编码单元格:
- 回归模型方程的所有组成部分都是从
model
变量中导出的。在model.intercept_
、model.coef_[0]
、model.coef_[1]
、model.coef_[2]
和model.coef_[3]
中提供了 y 截距和 LogP、MW、RB 和 AP 的回归系数。
第二码单元格:
- 在这里,我们通过
print()
功能将组件放在一起并打印出方程式。
5.实验测井与预测测井的散点图
现在,我们将通过散点图来直观显示实验与预测测井曲线的相对分布。这样的情节可以让我们很快看到模型的性能。
代码练习
在接下来的例子中,我将向你展示如何不同地布置 2 个子图,即:(1)垂直图和(2)水平图。
代码解释
现在让我们看看实现垂直和水平图的底层代码。在这里,我提供了两个选项供您选择,让您选择是在垂直布局还是水平布局中使用这个多点图的布局。
导入库
两者都从导入必要的库开始,即matplotlib
和numpy
。特别是,大部分代码将使用matplotlib
来创建绘图,而numpy
库在这里用于添加趋势线。
定义图尺寸
接下来,我们通过plt.figure(figsize=(5,11))
为垂直绘图指定图形尺寸(图形的宽度和高度),通过plt.figure(figsize=(11,5))
为水平绘图指定图形尺寸。特别是,(5,11)告诉 matplotlib,垂直图的图形应该是 5 英寸宽和 11 英寸高,而水平图则使用相反的图形。
定义子图 的占位符
我们将告诉 matplotlib,我们希望有 2 行和 1 列,因此它的布局将是垂直绘图。这是由plt.subplot(2, 1, 1)
指定的,其中2, 1, 1
的输入参数指的是 2 行 1 列以及我们在它下面创建的特定子图。换句话说,让我们把使用plt.subplot()
功能看作是通过为图形包含的各种子图创建占位符来构建图形的一种方式。垂直图的第二个子图由plt.subplot()
功能的第三个输入参数中的值 2 指定,如plt.subplot(2, 1, 2)
所示。
通过应用相同的概念,通过容纳 2 个子图的plt.subplot(1, 2, 1)
和plt.subplot(1, 2, 2)
创建水平图的结构为 1 行 2 列。
创建散点图
既然图的一般结构已经就绪,现在让我们添加数据可视化。分别使用plt.scatter(x=Y_train, y=Y_pred_train, c=”#7CAE00", alpha=0.3)
中的plt.scatter()
函数添加数据散点,其中x
指的是用于 x 轴的数据列,y
指的是用于 y 轴的数据列,c
指的是用于散点数据的颜色,alpha
指的是 alpha 透明度级别(散点数据的透明度,数值越低,透明度越高)。
添加趋势线
接下来,我们使用来自numpy
的np.polyfit()
和np.poly1d()
函数以及来自matplotlib
的plt.plot ()
函数来创建趋势线。
*# Add trendline*
*# https://stackoverflow.com/questions/26447191/how-to-add-trendline-in-python-matplotlib-dot-scatter-graphs*
z = np.polyfit(Y_train, Y_pred_train, 1)
p = np.poly1d(z)
plt.plot(Y_test,p(Y_test),"#F8766D")
添加 x 和 y 轴标签
为了给 x 和 y 轴添加标签,我们使用了plt.xlabel()
和plt.ylabel()
功能。需要注意的是,对于垂直图,我们省略了顶部子图的 x 轴标签(为什么?因为对于底部子图,x 轴标签是多余的。
保存图
最后,我们将把构建好的图形保存到文件中,我们可以使用来自matplotlib
的plt.savefig()
函数,并指定文件名作为输入参数。最后,以plt.show()
结束。
plt.savefig('plot_vertical_logS.png')
plt.savefig('plot_vertical_logS.pdf')
plt.show()
视觉解释
上一节提供了基于文本的解释,在这一节中,我们将对这个视觉解释做同样的解释,它利用颜色高亮来区分情节的不同组成部分。
**创建散点图的可视化说明。**这里我们用颜色高亮显示特定的代码行和它们对应的绘图组件。(由 Chanin Nantasenamat 绘制)
需要您的反馈
作为一名教育工作者,我喜欢听我如何改进我的内容。请在评论中告诉我:
- 可视化插图有助于理解代码是如何工作的,
- 视觉插图是多余的和不必要的,或者是否
- 可视化插图补充了基于文本的解释,有助于理解代码是如何工作的。
订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!
关于我
我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。
数据科学、机器学习、生物信息学、研究和教学是我的激情所在。数据教授 YouTube…
www.youtube.com](https://www.youtube.com/dataprofessor?sub_confirmation=1)
在社交网络上与我联系
✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
♇insta gram:【t2t
如何使用 Python 和 Heroku 从 CSV 文件构建关系数据库
通过三个简单的步骤免费构建您自己的 PostgreSQL 数据库
对于较小的项目,CSV 是存储数据的好格式。但是,如果您想升级您的数据管理游戏呢?关系数据库为组织和管理您的数据提供了一种更可靠的方式。在这篇文章中,我展示了如何通过三个简单的步骤将 CSV 文件转换成 PostgreSQL 数据库。我还将讨论使用关系数据库的一些优点。
关系数据库的优势
关系数据库是一种将数据划分到具有共享数据点的链接表中的数据库。这些共享的数据点允许我们通过一个简单的查询来组合信息并创建新颖的表或视图。流行的关系数据库包括 MySQL 、 SQLite 和 PostgreSQL 。
构建一个合适的关系数据库需要时间和精力。但是,如果做得好,它有许多优势。
首先,关系数据库使您能够更容易地看到数据不同部分之间的关系。数据被划分到表中,并且可以使用包含简单数学运算的结构化查询语言(SQL)查询来组合(“联接”)。
其次,关系数据库提供了更好的数据管理,具有更高的一致性和灵活性。CSV 文件等其他格式很快变得难以管理,即使对于较小的项目也是如此。关系数据库允许您使用模式强制数据类型,从而减少了主要的潜在错误源。关系数据库还提供了更大的灵活性,因为您可以使用复杂的查询从相对简单的表中生成更复杂的数据。
第三,关系数据库解决了数据冗余的问题:一个好的关系数据库是围绕最小化数据重复和不一致的依赖关系而设计的,通过一个称为“规范化”的过程。标准化是组织数据库中数据的过程,包括创建表格和定义表格之间的关系。
第四,关系数据库已成为行业标准,数据库管理系统(DBMS)通常会提供一组您希望用于任何数据库的高级功能,如备份、故障转移和镜像。
阅读下面的说明时有一个重要的警告:这篇文章是而不是用来解释如何为你的关系数据库设计和建立一个生产级架构。在为生产环境设计数据库时,您需要更仔细地考虑权限、创建只读版本还是写版本、版本控制等等。相反,我将展示如何快速、轻松地创建自己的数据库供个人使用。
记住这一点,让我们开始使用 Heroku 和 Python 从 CSV 文件构建一个关系数据库。
步骤 1:在 Heroku 上设置 PostgreSQL 数据库
我们将从在 Heroku 上设置 PostgreSQL 实例开始。Heroku 是基于亚马逊网络服务(AWS)的平台即服务(PaaS),而为 PostgreSQL 提供了一个免费层。free 计划限制为 10,000 行,最大并发数为 20。您也将无法使用回滚和故障转移等更高级的功能,这两种功能对于任何生产级数据库都是可取的。它有一个手动备份功能,允许您生成和下载数据库的备份。
要在 Heroku 上设置 PostgreSQL 实例,首先登录您的 Heroku 帐户,从下拉菜单中创建一个新的应用程序。
创建一个新的应用程序(由作者创建)
为你的应用程序选择一个名称和地区,然后点击“创建应用程序”按钮。
为你的应用程序选择一个名字和地区
为您的新应用程序配置 PostgreSQL 数据库。
为你的 Heroku 应用提供一个数据库
最后,找到并复制您的数据库凭证(您将需要它们来设置 Python 中的连接)。就这样,您拥有了自己的 PostgreSQL 数据库并正在运行!
在 Heroku 上找到并复制你的数据库凭证
步骤 2:定义您的模式
在本例中,我们将构建一个由随机生成的媒体作者及其文章组成的数据库,并将这些数据存储为两个 CSV 文件。第一个 CSV 文件(或:“表”)是“作者表”,第二个 CSV 文件包含他们的帖子的数据。这些 CSV 文件和用于生成它们的脚本可以在 Github 上获得。
让我们来看看这些表的模式。“模式”是数据库中表的正式语言表示。它定义了列、它们的名称和类型、分区规则等等。
authors 表包含条目写入表中的时间戳(row_timestamp
)、作者的通用唯一标识符(UUID(author_id
)、作者的名和姓(author_first_name
);author_last_name
),以及他们的电子邮件地址(email
)。
row_timestamp TIMESTAMP NOT NULL,
author_id VARCHAR PRIMARY KEY NOT NULL,
author_first_name VARCHAR NOT NULL,
author_last_name VARCHAR NOT NULL,
email VARCHAR NOT NULL
posts 表还包括一个row_timestamp
,每篇文章的唯一标识符(post_id
),一个引用回authors
表中author_id
列的二级键,以及每篇文章的标题(article_title
)。
row_timestamp TIMESTAMP NOT NULL,
post_id VARCHAR PRIMARY KEY NOT NULL,
author_id VARCHAR REFERENCES authors(author_id),
article_title VARCHAR NOT NULL
稍后在 PostgreSQL 数据库中设置表时,我们将使用这些模式。
第三步:一点 Python 的魔力
在我们的第三步也是最后一步,我们需要一些 Python 代码来使用 psycopg2 库建立与 PostgreSQL 数据库的连接。我们首先创建三个函数,将表添加到数据库中,并将数据注入到数据库中。第一个函数run_syntax
是一个助手函数,它使用数据库连接执行语法。第二个函数create_table
接受模式定义、表和数据库名称,并将表添加到我们的数据库中。第三个函数populate_table
获取一个 pandas 数据帧,并用该数据填充数据库中指定的表。
注意,我使用环境变量作为数据库访问凭证。即使对于较小的(非生产)项目,也不要在代码中包含这样的凭证,这是一个很好的做法。当您将代码推送到 Github 时,您可能会忘记删除它们,从而将您的数据库暴露给其他用户。
把所有的放在一起
要在 PostgreSQL 实例中设置表,您必须添加我们之前定义的模式定义,并添加一些代码来执行下面脚本中所示的create_table
函数。
要将数据从 CSV 文件注入到这些表中,请使用以下脚本:
使用 IDE 或终端
要在 IDE 中使用上述代码,您必须将您的凭证作为环境变量添加到 Python 配置中(我使用 Pycharm)。或者,如果您想从终端运行上述脚本,您需要采取一些额外的步骤。首先,通过运行以下语法,将凭证作为环境变量添加到终端中,用您之前从 Heroku 获得的数据库凭证替换占位符。
hostname = <my_hostname>
user = <my_user>
password = <my_password>
database = <my_database>
第二步,您需要将环境变量传递给 Python 进程,方法是将以下代码添加到上面所示的db_management
模块中:
os.environ["hostname"] = hostname
os.environ["user"] = user
os.environ["password"] = password
os.environ["database"] = database
最后,使用下面的命令,使用上面显示的create_tables.py
和populate_table.py
脚本,从终端执行 Python 代码来填充数据库:
python create_tables.py
python populate_tables.py
后续步骤:使用您的数据库
现在您有了一个可以连接和查询的 PostgreSQL 数据库。让我们检查一下这是否有效。Heroku 有一个简洁的数据剪辑功能,你可以用它在你的网站上嵌入查询输出,或者与合作者分享。
一个 Heroku 数据剪辑,显示了我们的数据库中前 5 名最多产的作者(语法:SELECT author_id,COUNT(post _ id)AS number _ of _ posts FROM posts GROUP BY author _ id ORDER BY number _ of _ posts desc 限制 5) (i mage by author )
准备好数据库后,您可以继续使用 psycopg2 库直接在 Python 中管理数据,或者开始使用免费的数据库工具,如 DBeaver 。现在,您可以使用一系列简单的 SQL 命令来查看、管理您的数据并从中获得新的见解,或者将您的数据库用于其他应用程序,如仪表板或网站。
感谢阅读!
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@ndgoet/membership)
如果你喜欢这篇文章,这里还有一些你可能喜欢的文章:
从 CSV 文件创建 ES 索引以及使用 Python Elasticsearch 管理数据的实践指南…
towardsdatascience.com](/creating-and-managing-elasticsearch-indices-with-python-f676ff1c8113) [## 使用假设在 Python 中自动化单元测试
单元测试是产生高质量代码的关键。以下是如何自动化测试 Python 代码。
towardsdatascience.com](/automating-unit-tests-in-python-with-hypothesis-d53affdc1eba) [## 如何用预提交钩子改进 Python 代码风格
实施代码风格是简化开发过程的关键,下面是如何实现自动化。
medium.com](https://medium.com/python-in-plain-english/how-to-improve-your-python-code-style-with-pre-commit-hooks-e7fe3fd43bfa)
请仔细阅读 本免责声明 中的任何内容后再依托 我的 Medium.com 文章 。
如何构建简历解析工具
我发现的最有效的方法
当我还是一个大学的学生时,我很好奇简历的自动化信息提取是如何工作的。我将准备各种格式的简历,并将它们上传到求职门户网站,以测试背后的算法实际上是如何工作的。我总是想自己造一个。因此,在最近几周的空闲时间里,我决定构建一个简历解析器。
起初,我认为这相当简单。只是用一些模式去挖掘信息但是事实证明我错了!建立一个简历解析器是很困难的,你可以想象简历的布局有很多种。
例如,有些人会把日期放在简历标题的前面,有些人不写工作经历的时间,有些人不在简历中列出公司。这使得简历解析器更加难以构建,因为没有固定的模式可以捕获。
经过一个月的工作,根据我的经验,我想分享一下哪些方法效果很好,以及在开始构建自己的简历解析器之前应该注意哪些事项。
在进入细节之前,这里有一个视频短片,展示了我的简历解析器的最终结果。
数据收集
我刮了多个网站检索了 800 份简历。简历要么是 PDF 格式,要么是 doc 格式。
我使用的工具是谷歌的 Puppeteer (Javascript ),从几个网站收集简历。
数据收集的问题之一是找到一个好的来源来获取简历。在您能够发现它之后,只要您不太频繁地访问服务器,抓取部分就不会有问题。
之后我选择了一些简历,手动将数据标注到各个字段。标记工作已经完成,这样我就可以比较不同解析方法的性能。
预处理数据
剩下的部分,我用的编程是 Python。有几个软件包可以将 PDF 格式解析成文本,如 PDF Miner 、 Apache Tika 、PDF tree等。让我比较一下不同的文本提取方法。
使用 PDF Miner 的一个缺点是当你处理的简历与 Linkedin 简历的格式相似,如下所示。
PDF Miner 在 PDF 中的读取方式是逐行读取。因此,如果发现左右部分的文本在同一行,它们将被组合在一起。因此,你可以想象,在随后的步骤中,你将更难提取信息。
另一方面,pdftree 将省略所有的’ \n '字符,因此提取的文本将类似于一大块文本。因此,很难将它们分成多个部分。
所以我用的工具是 Apache Tika,这似乎是解析 PDF 文件的更好选择,而对于 docx 文件,我用 docx 包解析。
数据提取流程概述
这是棘手的部分。有几种方法可以解决这个问题,但是我会和你分享我发现的最好的方法和基线方法。
基线方法
先说基线法。我使用的基线方法是首先为每个部分(这里我指的部分是experience
、education
、personal details
和others
)抓取关键字,然后使用 regex 来匹配它们。
比如我要提取大学的名字。所以,我先找一个包含大部分大学的网站,把它们刮下来。然后,我使用 regex 来检查这个大学名称是否可以在特定的简历中找到。如果找到,这条信息将从简历中提取出来。
这样,我就能够构建一个基线方法,用来比较我的其他解析方法的性能。
最佳方法
另一方面,这是我发现的最好的方法。
首先,我将把纯文本分成几个主要部分。比如experience
、education
、personal details
、others
。我所做的是为每个主要部分的标题设置一组关键字,例如,Working Experience
、Eduction
、Summary
、Other Skills
等等。
当然,你可以尝试建立一个机器学习模型来进行分离,但我选择了最简单的方法。
之后,将有一个单独的脚本来分别处理每个主要部分。每个脚本将定义自己的规则,利用抓取的数据提取每个字段的信息。每个剧本里的规则其实都挺脏挺复杂的。由于我想让这篇文章尽可能简单,我不会在这个时候披露它。如果有兴趣了解详情,在下面评论!
我使用的机器学习方法之一是区分company name
和job title
。我在这里使用机器学习模型的原因是,我发现有一些明显的模式来区分公司名称和职位名称,例如,当你看到关键词“ **Private Limited”或“Pte Ltd”,**时,你肯定这是一个公司名称。
我从哪里得到数据来训练?
我从绿皮书上搜集数据,得到公司名称,并从这个 Github 回购上下载职位名称。
得到数据后,我只是训练了一个非常简单的朴素贝叶斯模型,它可以将职称分类的准确率提高至少 10%。
简而言之,我解析简历解析器的策略是通过分而治之。
估价
我使用的评估方法是 fuzzy-wuzzy 令牌集比率。比方说
- s = #个公共令牌
- S1 = Sorted _ tokens _ in _ intersection
- S2 = Sorted _ tokens _ in _ intersection+Sorted _ rest _ of _ str 1 _ tokens
- S3 = Sorted _ tokens _ in _ intersection+Sorted _ rest _ of _ str 2 _ tokens
并且 token_set_ratio 将被计算如下:
token _ set _ ratio = max(fuzz.ratio(s,s1),fuzz.ratio(s,s2),fuzz . ratio(s,s3))
我使用 token_set_ratio 的原因是,如果解析后的结果与带标签的结果相比有更多的公共标记,这意味着解析器的性能更好。
如果你对评估绩效的指标有其他想法,也欢迎在下面发表评论!
最终想法
安德烈亚斯·韦兰在 Unsplash 上拍摄的照片
非常感谢你一直读到最后。这个项目实际上消耗了我很多时间。然而,如果你想解决一些具有挑战性的问题,你可以尝试这个项目!😃
关于作者
Low 魏宏是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。
他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问这个网站查看他的作品集,也可以联系他获取的抓取服务。
在媒体上阅读低纬鸿的作品。数据科学家|网络抓取服务:https://www.thedataknight.com/.每…
medium.com](https://medium.com/@lowweihong?source=post_page-----6bef8cb1477a----------------------)
你可能喜欢的故事
由数据科学家分享
towardsdatascience.com](/brutal-truths-that-nlp-data-scientists-will-not-tell-you-7f387de66cd5)
如何构建可扩展的大数据分析管道
大规模建立端到端系统
D ata 是当今创新企业的重要元素。数据驱动的决策使企业能够适应不可预测的世界。报告数据的能力是商业分析的支柱。随着 21 世纪数据的空前增长,大数据不再是一个时髦词,而是企业必须面对的现实。
你应该像爱自己一样爱你的数据
数据呈指数级增长,这要求数据系统始终具有可扩展性。构建大规模的大数据管道以及整合到现有的分析生态系统中,对于那些不熟悉这两者的人来说将是一个巨大的挑战。
要构建可扩展的大数据分析渠道,您必须首先确定三个关键因素:
输入数据
无论是时间序列还是非时间序列,你都必须知道你的管道输入数据的性质。它将决定以何种格式存储数据,当数据丢失时如何处理,以及在管道的其余部分使用何种技术。
输出数据
构建分析渠道时,你需要关心终端用户。数据分析师使用您的管道来构建报告仪表板或可视化。鉴于最终用户可能缺乏数据工程方面的强有力的技术专长,输出数据需要是可访问和可操作的。如今,著名的分析引擎简化了大数据生态系统和分析仓库之间的集成。
管道可以摄取多少数据?
您的数据系统的可扩展性可以决定企业的长期生存能力。一天处理 100 GB 和 1 TB 之间没有什么相似之处。硬件和软件基础设施必须跟上数据量的突然变化。由于业务的有机增长,您不想让您的数据系统过载。以最佳方式扩展您的数据管道!
典型的大数据分析渠道。作者署名
数据收集
数据收集是数据管道的第一个也是最重要的模块,在这里您必须评估数据的来源。它们是来自另一个数据源还是顶级应用程序?数据是结构化的还是非结构化的?您需要执行任何数据清理吗?我们可能认为大数据是一堆杂乱无章的数据,但实际上,大多数大数据都是结构化的。非结构化数据需要额外的技术来构建数据管道。
您的管道架构将因您选择的数据收集方法而异:批处理或通过流服务。批处理流水线需要一个高效的存储系统来进行 I/O 操作,而流处理流水线更喜欢容错传输协议。
说到结构化数据,无论是文本、数字还是图像,要将它们输入管道,都必须经过一个必不可少的过程:数据序列化。数据序列化是将结构化数据转换为一种格式的过程,这种格式允许以允许恢复其原始结构的形式共享或存储数据。
来源:https://devopedia.org/data-serialization
数据串行化导致跨管道的同质数据结构,从而保持所有数据处理模块的一致性。 XML 、 CSV 、 YAML 、 JSON 是数据序列化中最流行的一些格式。序列化数据在存储和传输方面更加优化。将数据从一个系统传输到另一个系统可能会遇到不兼容的问题,因此逐位通信可以确保没有信息丢失。
JSON 对于处理互联网上的平面和嵌套数据结构来说非常方便。它提供了人类可读的格式和与 JVM 系统的高度集成。然而,在大数据处理中,JSON 的使用不如其他方法受欢迎,因为它没有经过优化的存储和缺乏结构验证。
一个 JSON 例子来模拟一个地址簿
【proto buf】协议缓冲区是 Google 内部序列化结构化数据的机制。使用 protobuf,您可以定义一个通用模式,然后用您喜欢的编程语言执行读/写操作。想想像 XML 这样的语言神经格式,但是更快更小。除了非人类可读的缺点,protobuf 的执行速度比 JSON 快 6 倍。
来源:https://developers . Google . com/protocol-buffers/docs/Java tutorial
***Key takeaways:***- Storage is essential for batch processing while the transmission is critical for streaming service
- Serialization maintains a stable communication transferring between systems
- Use protobuf to serialize data for a better performance
数据存储
假设您已经启动并运行了数据收集模块,那么您将在哪里存储所有这些数据呢?取决于很多东西:硬件资源、数据管理专业知识、维护预算等。在决定把钱花在哪里之前,你需要下定决心,因为这是一场长期的比赛。
数据是新的石油,所以最好把石油放在你的后院
资料来源:https://architecht.io/what-happened-to-hadoop-211aa52a297
如果你有大笔资金,最好的办法是建立自己的数据基础设施。数据是新的石油,所以最好把石油放在你的后院。雇佣最好的硬件工程师,组装一个合适的数据中心,并在此基础上构建您的管道。 Hadoop 文件系统(HDFS) 一直是内部数据架构的首选。它提供了一个紧密集成的生态系统,包含所有可用于数据存储和 ETL 的工具和平台。设置一个可行的 Hadoop 堆栈只需付出最少的努力。它的强大之处在于横向扩展的能力,这意味着并排捆绑商用硬件以最大化性能和最小化成本。
您甚至可以通过优化存储格式来更进一步。将文件存储在。txt 或者。在 HDFS 的领导下,csv 格式可能不是最明智的想法。 Apache Parquet 是一种列格式,适用于 Hadoop 中的任何项目,并且是每个数据工程师都推荐的格式。作为一种基于列的存储格式,Parquet 提供了更好的压缩,从而优化了 I/O 操作。它唯一的缺点是模式修改的限制,例如,添加或删除一列需要花费更多的精力。
这是你的数据在 Hadoop 分区下的样子。照片由 Kolar.io 在 Unsplash 上拍摄
来自 SQL 后台,也可以建立一个更易访问的查询系统。 Apache Hive 数据仓库软件有助于使用 SQL 读取、写入和管理驻留在分布式存储中的大型数据集。 Hive 提供了一种类似 SQL 的查询语言(HiveQL)来直接在 HDFS 上执行查询。尽管 HiveQL 没有遵循所有的 SQL 标准,但它仍然简化了那些不懂 Hadoop 的人的查询过程。另一个常见的查询引擎是由脸书工程师开发的。
同样,如果你没有足够的资源来构建自己的数据仓库,你可以将整个系统外包给基于云的平台。许多著名的科技公司都提供一体化的大数据架构,如 【谷歌大查询】亚马逊 AWS微软 Azure 。通过外包,你不必费心建立或维护生态系统,但这带来了无法控制你的管道的风险。在高成本、低维护和低成本、高维护之间有一个折衷方案。然而,你可以把赌注压在科技巨头管理你的管道的专业技能上。
***Key takeaways:***-If you have big money, go for DIY data architecture, if not, our-sourcing is your answer
- Use parquet to store files in Hadoop ecosystem
- Setup a query system upon Hadoop for easy access
分析引擎
**Hadoop 生态系统及其替代品有利于大数据存储系统,但它们不适合作为分析引擎。它们不是为执行快速查询而构建的。出于分析目的,我们经常执行特别查询,因此需要一个能快速返回结果的系统。从属存储需要建立在分析引擎之上。
Vertica 是一个数据库管理系统,专为大规模分析和快速查询性能而设计。它以列格式存储数据,并创建投影以将数据分布在其节点上,用于高速查询。由于其提供强大的分析引擎和高效的查询系统的声誉,Vertica 被许多科技公司广泛使用。由于使用 Java 、 Scala 、 Python 、 C++ 的简单集成,Vertica 可以为众多与数据相关的外部应用程序扮演数据库的角色。
分析仪表板示例。卢克·切瑟在 Unsplash 上拍摄的照片
然而,Vertica 显示了处理实时数据或高延迟分析的一些缺点。它对更改模式或修改投影的约束限制了它对快速转换数据的使用。 德鲁伊 是一个开源的分析数据库,专门为*【OLAP】*在线分析处理而设计。时间序列数据需要优化的存储机制和快速的聚集器。它主要包含时间戳和指标。 Druid 将指标存储为列,并基于索引和指标对数据进行分区,以便快速访问,因此提供了敏捷的聚合操作。
***Key takeaways:***- Vertica is great for low-latency analytics but requires much expertise to scale
- Druid is built for time series data and provide a fast access system
- Choose analytics database with maximum integration to visualization tools
监控和质量
完成数据收集、存储和可视化集成后,您可能想要即插即用。但是还有最后一件事就是万一发生事故该怎么办。当您的管道无缘无故崩溃时,您会向谁求助?这就是整个监控过程的目的。它可以帮助您跟踪、记录和观察系统的健康状况和性能。一些工具甚至允许你动态调试。也就是说,如果你想建立一个持久的数据管道,一个合适的监控系统是必不可少的。这里我们区分两种: IT 监控和数据监控**。**
IT 监控对于任何软件开发都是必要的。它显示各种与系统相关的指标,如 CPU、磁盘使用、资源消耗、分配的内存等。您可以查看 IT 监控,看看能否将管道的容量增加一倍或两倍。借助 Hadoop 或 Vertica 等预优化的生态系统,我们不需要太担心 IT 性能。你可以选择任何基本的 IT 监控工具,如 Grafana 或 Datadog 来建立一个简单的仪表板,跟踪你的指标。
Grafana 仪表板示例。来源:佩尔科纳
**数据监控与大数据分析管道中的其他模块一样重要。它检测与数据相关的问题,如延迟、数据缺失、数据集不一致。数据管道的质量反映了系统内数据流通的完整性。这些指标确保从一个地方传输到另一个地方的数据丢失最小或为零,而不会影响业务成果。我们无法说出数据监控工具记录的所有指标,因为每个数据管道都有其特定的需求,因此需要特定的跟踪。如果你正在建立一个时间序列数据管道,关注延迟敏感指标。如果您的数据是成批出现的,请确保正确跟踪传输过程。一些数据监控工具可以帮助您构建一个简单的数据监控仪表板,但是为了适合您的特定用途,最好自己构建一个。
***Key takeaway:***- Monitoring tools are indispensable in a data pipeline, but not all metrics are equally important *-* Data pipeline quality means the integrity of your data
结论
我们花了相当多的时间讨论基本的端到端大数据分析管道,我希望您已经获得了一些有用的知识。构建这样的管道没有万能的公式,但是您可以基于基本的蓝图来创建自己的管道。
如何建立一个搜索引擎
用几行代码在 Python 中创建健壮的全文搜索
这篇文章概述了当今使用的最重要的搜索算法之一,并展示了如何用几行代码用 Python 实现它。
来源:作者
搜索的价值
我们认为搜索数据的能力是理所当然的。现代搜索引擎现在如此复杂,以至于我们的大部分搜索“刚刚好”。事实上,我们经常只注意到网站或应用程序上的搜索没有执行。我们对这一领域的期望从未如此之高。
搜索引擎的智能一直在增长,原因很简单,一个有效的搜索工具能给企业带来的价值是巨大的;一项重要的知识产权。搜索栏通常是客户和企业之间的主要界面。因此,一个好的搜索引擎可以通过改善用户体验来创造竞争优势。
MckKinsey 估计,2009 年这一价值在全球范围内总计达到 7800 亿美元。这将使每次搜索的价值为 0.50 美元[1]。当然,自 2009 年以来,这一数值无疑有了大幅增长…
考虑到这一点,创建一个现代搜索引擎超出了大多数开发团队的能力,需要大量的资源和复杂的算法,这是可以理解的。然而,有点令人惊讶的是,大量的企业业务搜索引擎实际上是由非常简单和直观的规则驱动的,这些规则可以使用开源软件轻松实现。
例如,优步、Udemy Slack 和 Shopify(以及 3000 家其他企业和组织[2])都在使用 Elasticsearch。直到 2016 年,这个搜索引擎都是由极其简单的词频、逆文档频率(或 tf-idf)单词分数驱动的。[3](关于这是什么的更多细节,我已经在这里和这里写了关于 tf-idf 。
在这之后,它切换到更复杂(但仍然非常简单)的 BM25,这种 BM25 一直沿用至今。这也是 Azure 认知搜索中实现的算法[4]。
BM25:你从未听说过的最重要的算法
那么 BM25 是什么呢?它代表“最佳匹配 25”(其他 24 次尝试显然不太成功)。它是在 1994 年第三届文本检索会议上发布的,是的,的确有一个致力于文本检索的会议…
它可能被认为是 tf-idf 的“兴奋剂”,实现了两个关键的改进:
- 项频率饱和。BM25 为与文档匹配的术语数量提供递减的回报。这是相当直观的,如果你想搜索一个在文档中非常常见的特定术语,那么这个术语的出现次数对搜索来说就变得不那么有用了。
- 公文长度。 BM25 在匹配过程中考虑文档长度。同样,这是直观的;如果一篇较短的文章包含与一篇较长的文章相同数量的匹配项,那么这篇较短的文章可能更相关。
这些改进还引入了两个超参数来调整这些项目对排名函数的影响。“k”用于调整术语饱和的影响,“b”用于调整文档长度。
综上所述,BM25 的计算公式为:
简化的 BM25 算法。来源:作者
实施 BM25,一个成功的例子
实现 BM25 非常简单。多亏了 rank-bm25 Python 库,这可以用几行代码实现。
在我们的示例中,我们将创建一个搜索引擎来查询英国公共部门组织发布的合同通知。
我们的起点是一个 dateset,它包含合同通知的标题、描述以及通知本身的链接。为了简单起见,我们将标题和描述组合在一起,在数据集中创建“文本”列。我们将使用该列进行搜索。我们想要搜索 50,000 个文档:
要在搜索引擎中使用的数据格式(50,000 行中的前两行)。来源:作者
在本文的底部可以找到数据和代码的链接。
本练习的第一步是提取该数据集的“文本”列中的所有单词,以创建一个由每个文档及其单词组成的“列表列表”。这被称为标记化,可以由优秀的空间库来处理:
import spacy
from rank_bm25 import BM25Okapi
from tqdm import tqdm
nlp = spacy.load("en_core_web_sm")text_list = df.text.str.lower().values
tok_text=[] # for our tokenised corpus#Tokenising using SpaCy:
for doc in tqdm(nlp.pipe(text_list, disable=["tagger", "parser","ner"])):
tok = [t.text for t in doc if t.is_alpha]
tok_text.append(tok)
构建 BM25 索引只需一行代码:
bm25 = BM25Okapi(tok_text)
查询这个索引只需要一个已经标记化的搜索输入:
query = "Flood Defence"tokenized_query = query.lower().split(" ")import timet0 = time.time()
results = bm25.get_top_n(tokenized_query, df.text.values, n=3)
t1 = time.time()print(f'Searched 50,000 records in {round(t1-t0,3) } seconds \n')for i in results:
print(i)
这将返回与搜索查询“防洪”高度相关的前 3 个结果:
*Searched 50,000 records in 0.061 seconds:*Forge Island Flood Defence and Public Realm Works Award of Flood defence and public realm works along the canal embankment at Forge Island, Market Street, Rotherham as part of the Rotherham Renaissance Flood Alleviation Scheme. Flood defence maintenance works for Lewisham and Southwark College **AWARD** Following RfQ NCG contracted with T Gunning for Flood defence maintenance works for Lewisham and Southwark College Freckleton St Byrom Street River Walls Freckleton St Byrom Street River Walls, Strengthening of existing river wall parapets to provide flood defence measures
我们可以根据执行搜索的用户的预期偏好来微调“k”和“b”的值,但是默认的 k=1.5 和 b=0.75 在这里似乎也很好。
最后
希望这个例子突出了用 Python 实现健壮的全文搜索是多么简单。这可以很容易地用来驱动一个简单的 web 应用程序或智能文档搜索工具。还有很大的空间来进一步提高这方面的性能,这将在下面的后续帖子中介绍!
用 Python 创建智能搜索服务
towardsdatascience.com](/how-to-build-a-smart-search-engine-a86fca0d0795)
参考文献:
这篇文章的代码和数据可以在这个 Colab 笔记本中找到。
[2] 据 StackShare 报道,2020 年 8 月。
[3]从 Elasticsearch v5.0 开始,BM25 成为默认搜索:https://www.elastic.co/blog/elasticsearch-5-0-0-released
[4]https://docs . Microsoft . com/en-us/azure/search/index-ranking-similarity
如何用 Transformers 和 Faiss 构建语义搜索引擎
实践教程
图片由 Kostas Stathoulopoulos 提供
介绍
您是否想过如何使用 Transformers 创建最先进的句子嵌入,并将其用于下游任务,如语义文本相似性?
在本教程中,你将学习如何用句子变形器和 Faiss 构建一个基于向量的搜索引擎。如果你想直接进入代码,看看 GitHub repo 和 Google Colab notebook 。
在本教程的第二部分,您将学习如何在一个 Streamlit 应用程序中服务搜索引擎,使用 Docker 和 AWS Elastic Beanstalk 部署它。
为什么要建立一个基于向量的搜索引擎?
基于关键字的搜索引擎易于使用,并且在大多数情况下都工作得很好。你查询机器学习论文,它们会返回一堆结果,这些结果包含与查询完全匹配或相近的变体,比如机器学习。其中一些甚至可能返回包含查询同义词或出现在相似上下文中的单词的结果。其他的,如 Elasticsearch ,以快速和可扩展的方式做所有这些事情,甚至更多。然而,基于关键字的搜索引擎通常会遇到以下问题:
- 复杂的查询或具有双重含义的单词。
- 长查询,如论文摘要或博客中的段落。
- 不熟悉某个领域的行话的用户或希望进行探索性搜索的用户。
基于向量的(也称为语义的)搜索引擎通过使用最先进的语言模型找到文本查询的数字表示,在高维向量空间中索引它们,并测量查询向量与索引文档的相似程度来解决这些缺陷。
索引、矢量化和排序方法
在深入本教程之前,我将简要解释基于关键字和基于向量的搜索引擎如何(1) 索引文档(即以易于检索的形式存储它们),(2) 对文本数据进行矢量化和(3) 测量文档与查询的相关性。这将有助于我们突出两个系统之间的差异,并理解为什么基于向量的搜索引擎可能会为长文本查询提供更有意义的结果。
1。基于关键词的搜索引擎
让我们用一个过于简化的版本 Elasticsearch 作为例子。Elasticsearch 使用一个标记器将一个文档分割成标记(即有意义的文本单元),这些标记被映射成数字序列并用于构建一个倒排索引。
倒排索引:倒排索引使我们能够一次查找一个术语并检索包含该术语的所有文档的列表,而不是遍历每个文档来检查它是否包含查询术语。 图片 作者:Morten Ingebrigtsen
与此同时,Elasticsearch 用一个高维的加权向量来表示每个索引文档,其中每个不同的索引项都是一个维度,它们的值(或权重)用 TF-IDF 来计算。
为了找到相关的文档并对它们进行排序,Elasticsearch 结合了布尔模型(BM)和向量空间模型(VSM)。BM 标记哪些文档包含用户的查询,VSM 对它们的相关程度进行评分。在搜索期间,使用相同的 TF-IDF 管道将查询转换为向量,然后文档d
对于查询q
的 VSM 分数是加权查询向量V(q)
和V(d)
的余弦相似度。
这种度量相似性的方式非常简单,并且不可扩展。Elasticsearch 背后的主力是 Lucene,它采用了各种技巧,从增强字段到改变向量的标准化方式,来加速搜索并提高搜索质量。
Elasticsearch 在大多数情况下都很有效,然而,我们也想创建一个关注单词上下文的系统。这就把我们带到了基于向量的搜索引擎。
2.基于向量的搜索引擎
我们需要创建考虑单词上下文的文档表示。我们还需要一种高效可靠的方法来检索存储在索引中的相关文档。
创建密集文档向量
近年来,NLP 社区在这方面取得了长足的进步,许多深度学习模型都是开源的,并由像 Huggingface 的变形金刚这样的软件包分发,这些软件包提供了对最先进的预训练模型的访问。使用预训练模型有许多优点:
- 它们通常产生高质量的嵌入,因为它们是在大量文本数据上训练的。
- 他们不要求你创建一个定制的标记器,因为变形金刚有他们自己的方法。
- 根据您的任务微调模型是很简单的。
这些模型为文档中的每个标记生成一个固定大小的向量。但是,我们如何获得文档级向量呢?这通常是通过平均或汇集单词向量来完成的。然而,这些方法产生低于平均水平的句子和文档嵌入,通常比平均手套向量更差。
为了构建我们的语义搜索引擎,我们将使用句子转换器来微调基于 BERT 的模型,以生成语义上有意义的长文本序列嵌入。
建立指数和衡量相关性
检索相关文档最简单的方法是测量查询向量和数据库中每个文档向量之间的余弦相似性,并返回得分最高的那些向量。不幸的是,这在实践中非常慢。
首选的方法是使用 Faiss ,一个用于高效相似性搜索和密集向量聚类的库。Faiss 提供了大量的指数和综合指数。此外,给定一个 GPU,Faiss 可以扩展到数十亿个向量!
教程:用句子转换器和 Faiss 构建基于向量的搜索引擎
在这个实际例子中,我们将使用真实世界的数据。我通过用 Orion 查询微软学术图,创建了一个包含 2010 年至 2020 年间发表的 8430 篇关于错误信息、虚假信息和假新闻的学术文章的数据集。
我检索了论文的摘要、标题、引文、出版年份和 ID。我做了最少的数据清理工作,比如拿走没有摘要的文件。数据如下所示:
图片由 Kostas Stathoulopoulos 提供
导入 Python 包并从 S3 读取数据
让我们导入所需的包并读取数据。该文件是公开的,所以你可以在 Google Colab 上运行代码,或者通过访问 GitHub repo 在本地运行代码!
使用句子转换器对文档进行矢量化
接下来,让我们对论文摘要进行编码。句子变形器提供了许多预训练的模型,其中一些可以在这个电子表格中找到。这里,我们将使用在语义文本相似性任务中表现出色的distilbert-base-nli-stsb-mean-tokens
模型,它比 BERT 快得多,因为它要小得多。
在这里,我们将:
- 通过将模型名称作为字符串传递来实例化转换器。
- 如果可用,切换到 GPU。
- 使用`. encode()'方法对所有论文摘要进行矢量化处理。
使用转换器对文档进行矢量化时,建议使用 GPU。Google Colab 免费提供一个!如果你想在 AWS 上运行它,请查看我的指南 如何在 AWS 上启动用于机器学习的 GPU 实例 。
用 Faiss 索引文档
Faiss 包含在任意大小的向量组中搜索的算法,甚至是不适合 RAM 的向量组。要了解 Faiss 的更多信息,你可以阅读他们在 arXiv 或 wiki 上的论文。
Faiss 是围绕Index
对象构建的,该对象包含可搜索向量,有时还对其进行预处理。它处理固定维度的向量集合d
,通常是几十到 100 个。
Faiss 只使用 32 位浮点矩阵。这意味着我们必须在构建索引之前改变输入的数据类型。
这里,我们将使用执行强力 L2 距离搜索的IndexFlatL2
索引。它适用于我们的数据集,但是,对于大型数据集,它可能会非常慢,因为它与索引向量的数量成线性关系。Faiss 还提供快速索引!
为了用抽象向量创建索引,我们将:
- 将抽象向量的数据类型更改为
float32
。 - 建立一个索引,并向它传递它将操作的向量的维数。
- 将索引传递给
IndexIDMap
,这个对象使我们能够为索引向量提供一个定制的 id 列表。 - 将抽象向量及其 ID 映射添加到索引中。在我们的例子中,我们将把向量映射到 Microsoft Academic Graph 中的论文 id。
为了测试索引是否按预期工作,我们可以用一个索引向量查询它,并检索它最相似的文档以及它们的距离。第一个结果应该是我们的查询!
因为我们使用索引向量查询 Faiss,所以第一个结果必须是查询,并且距离必须等于零!图片由 Kostas Stathoulopoulos 提供
使用用户查询进行搜索
让我们尝试为一个新的、看不见的搜索查询找到相关的学术文章。在这个例子中,我将使用 的第一段来查询我们的索引。WhatsApp 可以从被揭穿的事实核查的故事中受益以减少错误信息吗? 发表在《HKS 误传评论》上的文章。
图片由 Kostas Stathoulopoulos 提供
要为新的查询检索学术文章,我们必须:
- 用我们用于抽象向量的相同的句子蒸馏模型对查询进行编码。
- 将其数据类型更改为
float32
。 - 使用编码的查询搜索索引。
为了方便起见,我将这些步骤包装在了vector_search()
函数中。
这篇文章讨论了错误信息、事实核查、WhatsApp 以及巴西和印度的选举。我们希望基于向量的搜索引擎能够返回这些主题的结果。通过检查论文标题,大多数结果看起来与我们的查询非常相关。我们的搜索引擎工作正常!
图片由 Kostas Stathoulopoulos 提供
结论
在本教程中,我们使用句子转换器和 Faiss 构建了一个基于向量的搜索引擎。我们的索引运行良好,但相当简单。我们可以通过使用领域特定的转换器来提高嵌入的质量,比如 SciBERT 已经在来自 semanticscholar.org 语料库的论文上进行了训练。我们还可以在返回结果之前删除重复项,并尝试使用其他索引。
对于那些使用 Elasticsearch 的人,Open Distro 引入了一个近似 k-NN 相似性搜索特性,它也是 AWS Elasticsearch 服务的一部分。在另一篇博客中,我也会深入探讨这个问题!
最后,你可以在 GitHub 上找到代码,然后用 Google Colab 试一试。
参考
[1]n . tha kur,n . Reimers,n . daxen Berger,j .和 Gurevych,I .,2020 年。增强 SBERT:用于改进成对句子评分任务的双编码器的数据增强方法。 arXiv 预印本 arXiv:2010.08240 。
[2]j .约翰逊,m .杜泽和 h .杰古,2019 年。用 GPU 进行亿级相似性搜索。 IEEE 大数据汇刊。
如何使用 AWS Chalice 构建无服务器应用程序
动手教程,云计算系列
立即构建和部署基于 Python 的无服务器 REST API
图片作者。由 Pixabay 通过 Canva 生成的原始图像
我最近偶然发现了 AWS Chalice,并被它提供的简单性和可用性迷住了。AWS Chalice 是一个无服务器框架,允许您使用 Python 构建无服务器应用程序,并使用 Amazon API Gateway 和 AWS Lambda 将它们部署在 AWS 上。
我决定尝试一下,并在几分钟之内在 AWS 上创建和部署了一个示例 REST API。在本文中,我将带您了解构建和部署一个无服务器应用程序所需的步骤,该应用程序使用 AWS Chalice 从 Google News 获取最新新闻。
先决条件
本教程需要一个 AWS 帐户。如果你还没有,那么创建一个。我们的应用程序将只使用自由层资源,因此成本应该不是问题。您还需要配置安全性,并为您的访问创建用户和角色。
配置 AWS 凭据
Chalice 在幕后使用 AWS 命令行界面(CLI)来部署项目。如果您以前没有使用过 AWS CLI 来处理 AWS 资源,您可以按照这里的指南安装它。
安装完成后,您需要配置您的 AWS CLI,以使用来自您的 AWS 帐户的凭证。
$ aws configure
AWS Access Key ID [****************OI3G]:
AWS Secret Access Key [****************weRu]:
Default region name [us-west-2]:
Default output format [None]:
安装圣杯
接下来,你需要安装圣杯。在本教程中,我们将使用 Python 3,但是您可以使用 AWS Lambda 支持的任何 Python 版本。
验证 Python 安装
$ python3 --version
Python 3.8.6
安装圣杯
$ python3 -m pip install chalice
验证圣杯安装
$ chalice --version
chalice 1.20.0, python 3.8.6, darwin 19.6.0
创建项目
接下来,运行chalice
命令创建一个新项目:
$ chalice new-project daily-news
这将在当前目录下创建一个daily-news
文件夹。你可以看到 Chalice 在这个文件夹中创建了几个文件。
作者图片
让我们看看app.py
文件:
new-project
命令创建了一个定义单一视图的示例应用程序,/
在被调用时返回 JSON 主体{"hello": "world"}
。您现在可以修改这个模板并添加更多代码来阅读来自 Google 的新闻。
我们将使用 Google 的 RSS 提要,并且需要一个名为 Beautiful Soup 的 Python 库来解析 XML 数据。您可以使用pip
安装 Beautiful Soup 及其 XML 解析库。
$ python3 -m pip install bs4
$ python3 -m pip install lxml
接下来将下面的导入添加到app.py
。这实际上增加了从urllib
进行 HTTP 调用的导入和从bs4
解析 XML 的导入。
接下来,您需要添加一个方法来从 Google 获取 RSS 提要,解析它以提取新闻标题和发布日期,并创建一个新闻条目列表。为此,将以下代码添加到您的app.py
中
更新app.py
中的 index 方法来调用它并返回新闻条目列表作为结果。
请注意,您安装了一些依赖项来使代码工作。这些依赖项是本地安装的,在运行时对 AWS Lambda 容器不可用。为了使它们对 AWS Lambda 可用,您需要将它们与您的代码打包在一起。为此,将以下内容添加到requirements.txt
文件中。在构建期间,Chalice 将这些依赖项打包成代码的一部分,并作为 Lambda 函数的一部分上传。
部署项目
让我们部署这个应用程序。从daily-news
文件夹中,运行chalice deploy
命令。
部署(图片由作者提供)
这将使用 Amazon API Gateway 和 AWS Lambda 在 AWS 上部署您的 API。
API 网关中的每日新闻 API(图片由作者提供)
每日新闻-dev Lambda 函数(图片由作者提供)
您现在可以尝试访问 API 了。
调用新闻 API(图片由作者提供)
清理
您还可以使用chalice delete
命令删除运行chalice deploy
命令时创建的所有资源。
删除资源(作者图片)
结论
恭喜你!!您刚刚使用 Chalice 在 AWS 上部署了一个无服务器应用程序。这并不太难,是吗?
现在,您可以继续对您的app.py
文件进行任何修改,并重新运行chalice deploy
来重新部署您的更改。
您还可以使用 Chalice 将您的无服务器应用程序与亚马逊 S3、亚马逊 SNS、亚马逊 SQS 和其他 AWS 服务集成在一起。看看教程继续探索。
本教程的完整源代码可以在这里找到。
如何使用 AWS SAM 构建无服务器应用程序
动手教程,云计算系列
立即构建和部署基于 Java 的无服务器 REST API
在我之前的文章中,我谈到了 AWS Chalice,以及我们如何快速构建一个基于 Python 的无服务器应用程序,并在几分钟内将其部署到 AWS 上。
虽然 Python 是一个快速而有趣的原型,但在运行大规模生产应用程序时,它可能不是许多人的首选语言。许多组织使用 Java 作为他们的主要开发语言,许多开发人员也在转向更新的语言,如 Go。
在本文中,我将带您了解构建和部署从 Google News 获取最新新闻的无服务器应用程序所需的步骤。但这一次,我们将使用 AWS 无服务器应用程序模型(SAM)和 Java 进行开发。像 Chalice 一样,AWS SAM CLI 提供了一组丰富的工具,使开发人员能够快速构建无服务器应用程序。
先决条件
本教程需要一个 AWS 帐户。如果你还没有,那么创建一个。我们的应用程序将只使用自由层资源,因此成本应该不是问题。
您还需要配置安全性,并为您的访问创建用户和角色。
如何配置 AWS 凭据
SAM 在幕后使用 AWS 命令行界面(CLI)来部署项目。如果你以前没有使用过 AWS 的 CLI 来使用 AWS 资源,你可以按照这里的指南来安装它。
安装完成后,您需要配置您的 AWS CLI,以使用来自您的 AWS 帐户的凭证。
作者图片
如何安装 SAM
接下来,您需要安装 SAM。我们将在本教程中使用 Java,但是您可以使用 AWS Lambda 支持的任何语言运行时。
验证 Java 安装
$ java --versionopenjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)
安装 SAM CLI
根据您的操作系统,SAM CLI 的安装说明会有所不同。本文介绍了在 MacOS 上安装它的说明。
在 macOS 上安装 SAM CLI 的推荐方法是使用 Homebrew 软件包管理器。
确认你是否安装了自制软件。
$ brew --versionHomebrew/homebrew-core (git revision fe68a; last commit 2020-10-15)
Homebrew/homebrew-cask (git revision 4a2c25; last commit 2020-10-15)
如果没有,您可以使用以下命令安装 Homebrew。
$ /bin/bash -c "$(curl -fsSL [https://raw.githubusercontent.com/Homebrew/install/master/install.sh](https://raw.githubusercontent.com/Homebrew/install/master/install.sh))"
接下来,使用以下命令安装 SAM。
brew tap aws/tap
brew install aws-sam-cli
验证 SAM 安装
$ sam --versionSAM CLI, version 1.6.2
如何创建项目
接下来,运行sam-init
命令创建一个新项目。
sam init -r java11 -d maven --app-template hello-world -n daily-news-java
默认情况下,SAM 会创建一个 Python 项目。因为我们想要创建一个 Java 项目,所以我们需要传递一些额外的参数。
参数:
-r java11
:使用 Java 11 运行时-d maven
:使用 maven 作为依赖管理器--app-template hello-world
:使用 HelloWorld 快速入门模板-n daily-news-java
:我们项目的名称
这将在当前目录下创建一个daily-news-java
文件夹。您可以看到 SAM 在这个文件夹中创建了几个文件。
作者图片
我们来看看App.java
文件。
sam-init
命令创建了一个简单的 Lambda 函数,该函数在被调用时返回 JSON 主体{"message": "hello world"}
和机器的 IP 地址。我们现在可以更改这个模板并添加更多代码来阅读来自 Google 的新闻。
现在我们来看看template.yml
文件。
这包含了创建我们的 Amazon API 网关和 AWS Lambda 资源的 CloudFormation 模板。
Lambda 配置指定我们有一个运行在Java 11
和512 MB
内存上的HelloWorldFunction
lambda。
API 网关配置定义了一个带有/hello
路径的GET
方法,我们将使用它来调用 API。
我们将使用 Java 的内部 HTTP 和 XML 解析库,所以我们不需要向我们的pom.xml
文件添加任何依赖项。请注意,作为样板代码的一部分提供的默认pom.xml
带有设置为1.8.
的编译器源代码,我们需要将其更新为11
,这样我们就可以使用 Java 11 中的新 HTTP 库。
按照 Java 面向对象的方式,让我们也创建一个包含新闻标题和出版日期的NewsItem
类。
注意,我们已经覆盖了toString
方法。这是为了创建对象的 JSON 表示,避免使用任何 JSON 解析库。
接下来,您需要添加一个方法来从 Google 获取 RSS 提要,解析它以提取新闻标题和发布日期,并创建一个新闻条目列表。为此,将以下代码添加到您的App.java
现在让我们更新App.java
中的handleRequest
方法来调用这个方法并返回新闻条目列表作为结果。
不要忘记更新单元测试。编写它们是为了测试响应中是否存在“hello world ”,它们将在我们更改后开始失败。
如何构建
从daily-news-java
文件夹中,运行sam build
命令。
作者图片
这将编译您的源代码并构建您在应用程序中拥有的任何依赖项。然后,它将所有文件移动到.aws-sam/build
文件夹中,这样它们就可以打包和部署了。它也会相应地更新template.yml
文件。
如何在本地测试
这是萨姆最精彩的部分。您可以在本地部署和测试您的应用程序!!在开发阶段,当您想测试代码而不必将它部署到 AWS 时,这非常有用。
SAM CLI 提供了sam local
命令来本地运行您的应用程序。这在内部使用 Docker 来模拟 Lambda 的执行环境。如果没有安装 Docker,可以从这里获取。
我们可以用两种方式在本地测试我们的应用程序:
- 本地托管 API
- 直接调用 Lambda 函数
让我们来看看这两个选项。
本地托管
使用以下命令在本地启动 API。
sam local start-api
这在内部创建了一个本地服务器,并公开了一个复制 REST API 的本地端点。
作者图片
一旦 Docker 容器被加载,您就可以访问localhost
上的 api。
curl [http://127.0.0.1:3000/hello](http://127.0.0.1:3000/hello)
直接调用
使用以下命令调用 Lambda 函数。
sam local invoke "HelloWorldFunction" -e events/event.json
作者图片
这直接调用 Lambda 函数(就像我们调用main
方法一样)并将event.json
文件作为有效载荷传递。
如何部署项目
让我们部署应用程序。从daily-news-java
文件夹中,运行sam deploy --guided
命令。遵循提示并提供所需的输入(或按 Enter 键接受默认值)。
作者图片
这将使用 Amazon API Gateway 和 AWS Lambda 在 AWS 上部署我们的应用程序。它采用我们用sam build
命令构建的部署工件,打包并上传到由 AWS SAM CLI 创建的亚马逊 S3 桶,并使用 AWS CloudFormation 部署应用程序。
作者图片
API 网关中的每日新闻 API(图片由作者提供)
每日新闻 Lambda 函数(图片由作者提供)
我们现在可以尝试使用上面提供的端点 URL 来访问 API。
作者图片
如何清理资源
我们可以使用aws cloudformation delete-stack
命令删除 AWS CloudFormation 堆栈以及我们运行sam deploy
命令时创建的所有资源。
作者图片
结论
恭喜你!!您刚刚使用 AWS SAM 在 AWS 上部署了一个无服务器应用程序。它确实比之前的多做了一点工作,但也不太难。
现在,您可以继续对您的App.java
文件进行任何修改,并重新运行sam deploy
来重新部署您的更改。
本教程的完整源代码可以在这里找到。
如何用 Python 构建一个简单的机器学习 Web 应用
数据科学
第 2 部分:不到 50 行代码的 ML 支持的 Web 应用程序
在本文中,我将向您展示如何使用 streamlit 库在不到 50 行代码中用 Python 构建一个简单的基于机器学习的数据科学 web 应用程序。
(快速提示:你可能还想看看这个 streamlit 教程系列的第一部分来构建你的第一个 web 应用。大喊到 西门 为提示提及第 1 部分。)
数据科学生命周期本质上由数据收集、数据清理、探索性数据分析、模型构建和模型部署组成。如需了解更多信息,请查看 Ken Jee 关于 不同数据科学角色的精彩视频(由数据科学家) 。此生命周期的摘要信息图如下所示:
数据科学生命周期。由 Chanin Nantasenamat 绘制。
作为一名数据科学家或机器学习工程师,能够部署我们的数据科学项目极其重要,因为这将有助于完成数据科学生命周期。使用 Django 或 Flask 等已建立框架的机器学习模型的传统部署可能是一项艰巨和/或耗时的任务。
这篇文章基于我在数据教授 YouTube 频道 ( 如何用 Python 构建一个简单的机器学习 Web 应用)上制作的同一主题的视频,你可以边看边看这篇文章。
鸢尾花预测应用概述
今天,我们将构建一个简单的基于机器学习的 web 应用程序,用于预测鸢尾花的分类标签,如 setosa、versicolor 和 virginica。
或许,你已经在教程和机器学习的例子中看到过太多臭名昭著的 Iris 数据集的使用。在这一点上请原谅我,因为 Iris 数据集仅用作一种" lorem ipsum" (通常用作书写内容中的填充词)。我向您保证,在本系列教程的后续部分中,我将使用其他示例数据集。
这将需要使用三个 Python 库,即streamlit
、pandas
和scikit-learn
。
让我们来看看应用程序的概念流程,它将包括两个主要组件:(1)前端和(2)后端。
在 前端 中,左侧的侧边栏将接受与鸢尾花的特征相关的输入参数(即花瓣长度、花瓣宽度、萼片长度和萼片宽度)。这些特征将被传递到后端,在后端,经过训练的模型将根据输入参数来预测分类标签。预测结果送回前端显示。
在 后端 中,用户输入的参数将被保存到一个数据帧中,该数据帧将被用作测试数据。同时,将使用来自scikit-learn
库中的随机森林算法构建分类模型。最后,该模型将被应用于对用户输入数据进行预测,并将预测的类别标签作为三种花类型之一返回:setosa、versicolor 或 virginica。此外,还将提供预测概率,这将允许我们辨别预测类标签中的相对置信度。
安装必备库
在本教程中,我们将使用三个 Python 库,即streamlit
、pandas
和scikit-learn
。您可以通过pip install
命令安装这些库。
要安装 streamlit:
*pip install streamlit*
要安装熊猫:
*pip install pandas*
要安装 scikit-learn:
*pip install -U scikit-learn*
web 应用程序的代码
好的,让我们看一下幕后,我们会看到我们今天要构建的应用程序不到 50 行代码(即或确切地说是 48 行)。如果我们删除空行和注释(即占 12 行),我们可以把数字减少到 36 行。
对代码的逐行解释
好的,那么让我们解码,看看每一行(或代码块)在做什么。
导入库
- 第 1–4 行
分别导入别名为st
和pd
的streamlit
和pandas
库。具体来说,从 scikit-learn 库(sklearn
)导入datasets
包,我们随后将利用 loader 函数加载 Iris 数据集(第 30 行)。最后,我们将专门从sklearn.ensemble
包中导入RandomForestClassifier()
函数。
侧面板
- 第 11 行
我们将使用st.sidebar.header()
函数添加侧边栏的标题文本。注意在st
和header
之间使用sidebar
(即因此st.sidebar.header()
函数)告诉 streamlit 您想要将标题放在侧边栏面板中。 - 值得注意的是,每个输入参数将通过滑块按钮接受用户指定的值,如
st.sidebar.slider(‘Sepal length’, 4.3, 7.9, 5.4)
中的萼片长度。四个输入参数中的第一个对应于将在滑动按钮上方指定的标签文本,在我们的例子中是‘Sepal length’
,而接下来的两个值对应于滑动条的最小值和最大值。最后,最后一个输入参数表示加载 web 应用程序时将选择的默认值,该值设置为 5.4。
模型结构
- 第 25 行
如前所述,数据帧形式的综合用户输入参数信息将被赋给df
变量。 - *第 30–38 行
该代码块属于实际的模型构建阶段。- 第 30 行— 从
sklearn.datasets
包加载 Iris 数据集,并将其赋给iris
变量。 - 第 31 行— 创建包含
iris.data
中提供的 4 个花特征(即萼片长度、萼片宽度、花瓣长度和花瓣宽度)的X
变量。 - 第 32 行— 创建与
iris.target
中提供的虹膜类标签相关的Y
变量。 - 第 34 行— 将随机森林分类器,尤其是
RandomForestClassifier()
函数,分配给clf
变量。 - 第 35 行— 使用
X
和Y
变量作为输入参数,通过clf.fit()
函数训练模型。这实质上意味着将通过使用 4 个花特征(X
)和类别标签(Y
)来训练分类模型来构建分类模型。*
- 第 30 行— 从
主面板
- 第 27–28 行 第一部分将被赋予
‘User Input parameters’
的副标题文本(通过使用st.subheader function
分配)。在下一行中,我们将通过使用st.write()
函数显示df
数据框的内容。 - 第 40–41 行
在主面板的第二部分,打印出类别标签(即 setosa、versicolor 和 virginica)及其相应的索引号(即 0、1 和 2)。 - 第 43–44 行
预测类标签显示在主面板的第三部分。这里应该注意的是,prediction
变量(第 45 行)的内容是预测的类别索引号,对于要显示的类别标签(即 setosa、versicolor 和 virginica),我们需要使用prediction
变量作为iris.target_names[prediction]
括号内的参数。 - 第 47–48 行
在主面板的第四个也是最后一个部分,显示预测概率。该值允许我们辨别预测类别标签的相对置信度(即概率值越高,我们对该预测的置信度越高)。
运行 web 应用程序
因此,web 应用程序的代码保存在 iris-ml-app.py 文件中,现在我们可以运行它了。您可以通过在命令提示符(终端窗口)中键入以下命令来运行该应用程序:
***streamlit run iris-ml-app.py***
之后,您应该会看到以下消息:
***> streamlit run iris-ml-app.pyYou can now view your Streamlit app in your browser.Local URL: [http://localhost:8501](http://localhost:8501/)
Network URL: http://10.0.0.11:8501***
几秒钟后,应会弹出一个互联网浏览器窗口,并通过将您带到如下所示的[http://localhost:8501](http://localhost:8501./)
来引导您找到创建的 web 应用程序。
鸢尾花预测 App 截图。单击左上角的按钮(顶部窗口),我们将看到侧面板将被显示(底部窗口)。
恭喜你!您已经用 Python 创建了 ML 驱动的 web 应用程序!
现在,是时候表扬一下自己了,因为你已经创建了一个基于机器学习的 web 应用程序。现在是时候在您的数据科学产品组合和网站中展示这一点了(即您可能希望通过使用您感兴趣的数据集来定制 web 应用程序)。请务必查看这些关于指针和建议的视频(使用 GitHub 建立您的数据科学组合和如何使用 Hugo & Github Pages 建立数据科学组合网站【壮举。【数据教授】)。
订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!
关于我
我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub 页面)。
数据科学、机器学习、生物信息学、研究和教学是我的激情所在。数据教授 YouTube…
www.youtube.com](https://www.youtube.com/dataprofessor?sub_confirmation=1)
在社交网络上与我联系
✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
♇insta gram:***