几种推荐系统综述
协同过滤,KNN,深度学习,迁移学习,tfi df…等等探索所有这些
Photo by Alfons Morales on Unsplash
在本文中,我们将回顾几种推荐算法,通过 KPI 进行评估,并实时比较它们。我们将依次看到:
- 一种基于流行度的推荐系统
- 基于内容的推荐器(通过 KNN、TFIDF、Transfert Learning)
- 基于用户的推荐器
- 混合推荐器
- 深度学习推荐器
N.B :我受到了Gabriel more IRA的伟大笔记本的极大启发,感谢他https://www . ka ggle . com/gspmoreira/recommender-systems-in-python-101一些类似用户剖析器和评估功能的模型或功能都来自于他的笔记本。
介绍
我将介绍数据库,并定义什么将允许我们评估我们的模型。我有动漫元数据,我稍微修改了一下,以便有更可靠的内容推荐。
然后是带有评级的用户项目数据库
加入这两者后,我们将分层将其分为训练集和测试集
interactions_train_df, interactions_test_df = train_test_split(interactions_full_df,
stratify=interactions_full_df['user_id'],
test_size=0.20,
random_state=42)#Indexing by personId to speed up the searches during evaluation
interactions_full_indexed_df = interactions_full_df.set_index('user_id')
interactions_train_indexed_df = interactions_train_df.set_index('user_id')
interactions_test_indexed_df = interactions_test_df.set_index('user_id')
现在,我们可以定义一个评估函数。
评价函数
我们使用前 N 名准确性指标,它评估向用户提供的前几名推荐的准确性,与用户在测试集中实际交互的项目进行比较。
该评估方法的工作原理如下:
- 对于每个用户
- 对于用户在测试集中交互的每个项目
- 抽样 100 个用户从未互动过的其他项目。
Ps。这里,我们天真地假设那些未交互的项目与用户无关,这可能不是真的,因为用户可能只是不知道那些未交互的项目。但是让我们保持这个假设。 - 要求推荐器模型从由一个交互项目和 100 个非交互(非相关)项目组成的集合中产生推荐项目的排序列表
- 计算推荐排名列表中该用户和交互项目的前 N 名准确性指标
- 汇总全球前 N 名准确性指标
选择的前 N 名准确度度量是 Recall@N ,其评估交互项目是否在 101 个推荐给用户的排序列表中的前 N 个项目(命中)中。
基于流行度的模型
流行度模型是一种常见的(通常也是难以超越的)基线方法。这个模型实际上不是个性化的,它只是向用户推荐用户以前没有消费过的最流行的动画。
item_popularity_df = interactions_full_df.groupby('anime_id')['user_rating'].sum().sort_values(ascending=False).reset_index()
这里,我们根据上述方法执行流行度模型的评估。
实现了 0.59 的召回@5 ,这意味着测试集中大约 60 % 的交互项目被流行度模型排在前 5 位(从 100 个随机项目的列表中)。而召回@10 甚至更高(77 % ),不出所料。
这个模型对于我们投入的努力来说是非常好的!
基于内容的模型
基于内容的过滤方法利用来自用户已经交互的项目的描述或属性来推荐相似的项目。它仅依赖于用户先前的选择,使得该方法稳健以避免冷启动问题。对于文本项目,如文章、新闻和书籍,很容易使用原始文本来构建项目简档和用户简档。
为了从基于内容的模型中获得个性化推荐,我们将实施以下步骤:
对于每个用户:
- 拿到他的监视名单
对于他的观察列表中的每个动画
- 恢复动画与所有其他动画的相似性(感谢距离/特征矩阵),如 tfidf one
- 恢复每个用户评级
最后,用来自评级的项目强度对我们从内容模型(我们的距离矩阵)获得的项目值进行加权平均。
术语频率逆文档频率(TFIDF)
我们将使用一种在信息检索(搜索引擎)中非常流行的技术,名为 TF-IDF 。这种技术将非结构化文本转换为向量结构,其中每个单词由向量中的一个位置表示,值衡量给定单词与文章的相关程度。由于所有的项目都将在同一个向量空间模型中表示,所以是为了计算文章之间的相似度。
word_vectorizer = TfidfVectorizer(ngram_range =(1,4),
min_df=5, max_df=0.9,
strip_accents='unicode',
stop_words = 'english',
analyzer = 'word',
use_idf=1,
smooth_idf=1,
sublinear_tf=1)
tfidf_matrix = word_vectorizer.fit_transform(anime['soup'])
tfidf_feature_names = word_vectorizer.get_feature_names()
*""" compute users profiles """*
U2P = Users_Profiler(tfidf_matrix, anime_ids)
U2tfifd = U2P.build_users_profiles()
现在,由于我们的基本推荐器和用户分类器,我们可以向特定用户推荐动画:
ContentBasedmodel = BaseRecommender(U2tfifd, tfidf_matrix, anime)ContentBasedmodel.recommend_anime(8)
我们来评价一下
print('Evaluating Content-Based Filtering model...')cb_global_metrics, cb_detailed_results_df = evaluate_model(ContentBasedmodel)print('**\n**Global metrics:**\n%s**' % cb_global_metrics)cb_detailed_results_df = cb_detailed_results_df[['_user_id', 'watched_count', "hits@3_count", 'hits@5_count','hits@10_count',
'recall@3','recall@5','recall@10']]
cb_detailed_results_df.head(10)
实现了 0.755 的召回@5 ,这意味着测试集中大约有 75 % 个交互项被流行度模型排在前 5 位(从 100 个随机项的列表中)。而召回@10 更高(81 % )。
这种内容模型似乎非常可靠。
k-最近邻
这里我们使用 k-最近邻算法,这是一种试图通过查看数据点周围的数据点来确定数据点属于哪个组的算法。这个与分类方法有点不同,因为他不是预测每个数据点属于哪个组,而是根据余弦距离度量返回每个数据点的 6 个最近邻居。由此我们将提取距离矩阵,并从中获得用户偏好。
from sklearn.neighbors import NearestNeighbors
from scipy.sparse import csr_matrix
from sklearn.preprocessing import MaxAbsScaler
mabs = MaxAbsScaler()# build dummies matrix
anime_features = pd.concat([anime["genre"].str.get_dummies(sep=","),
pd.get_dummies(anime[["type"]]),
pd.get_dummies(anime[["episodes"]]),
pd.get_dummies(anime[["members"]]),anime_ids = anime["anime_id"].tolist()
anime_features_scale = mabs.fit_transform(anime_features)nbrs = NearestNeighbors(n_neighbors=6, algorithm='brute', metric = "cosine").fit(anime_features_scale)distances, indices = nbrs.kneighbors(anime_features_scale)
distances = csr_matrix(distances)
U2KNN = Users_Profiler(distances, anime_ids)
KNN_model = U2KNN.build_users_profiles()KNN_RECO = BaseRecommender(KNN_model, distances, anime)
print('Evaluating Content-Based Filtering model...')
global_metrics, detailed_results_df = evaluate_model(KNN_RECO)
print('**\n**Global metrics:**\n%s**' % global_metrics)
KNN 模型似乎没有产生有用的建议。它实现了 0.16 的召回@5 ,这意味着仅在测试集中就有大约 16 % 个交互项目被流行度模型排在前 5 个项目中(从具有 100 个随机项目的列表中)。
迁移学习(单词嵌入)
对于该方法,我们将依靠预训练的嵌入矩阵来创建嵌入向量。在神经网络的上下文中,嵌入是离散变量的低维、学习的连续向量表示。它们可以减少分类变量的维度并且有意义地表示变换空间中的类别。这里,目的是在嵌入空间中找到最近的邻居。这些可以用来根据用户兴趣进行推荐。
xtrain_embeddings = sc.fit_transform(xtrain_embeddings)
xtrain_embeddings = csr_matrix(xtrain_embeddings)
U2f = Users_Profiler(xtrain_embeddings, anime_ids)
U2fastt = U2f.build_users_profiles()
fastcontent = BaseRecommender(U2fastt, xtrain_embeddings, anime)
我们现在可以使用它进行推荐和评估。
print('Evaluating Content-Based Filtering model...')
fglobal_metrics, fdetailed_results_df = evaluate_model(fastcontent)
print('**\n**Global metrics:**\n%s**' % fglobal_metrics)
fdetailed_results_df = fdetailed_results_df[['_user_id', 'watched_count', "hits@3_count", 'hits@5_count','hits@10_count',
'recall@3','recall@5','recall@10']]
fdetailed_results_df.head(10)
Transfert Learning 比 KNN 好,但与 TFIDF 方法相比性能较差,其性能几乎是 tfi df 方法的一半,召回率为 37%。
协同过滤
协同过滤是一种通过收集众多用户的喜好或品味信息,对用户的兴趣进行自动预测(过滤)的方法。
奇异值分解
在这里,我们使用流行的潜在因素模型命名为奇异值分解。潜在因素模型根据潜在因素将用户项目矩阵压缩成低维表示。使用这种方法的一个优点是,我们将在低维空间中处理一个更小的矩阵,而不是拥有一个包含大量缺失值的高维矩阵。因素越多,模型越具体,如果因素太多,可能会导致过度拟合。
U, sigma, Vt = svds(R, k= 300)
sigma = np.diag(sigma)
predicted_ratings = np.dot(np.dot(U, sigma), Vt)
cf_preds_df = pd.DataFrame(predicted_ratings,
columns = pivpiv.columns,
index=iddd).transpose()
实现了 0.755 的召回@5 ,这意味着测试集中大约有 75 % 的交互项被流行度模型排在前 5 位(从 100 个随机项的列表中)。而召回@10 更高(81 % )。
混合模型
我们将构建一个简单的混合方法,只需将 SVD 分数与基于内容的分数相乘,然后根据结果分数进行排序。
评估我们的混合 tfidf/svd 模型:
在这里,我们对每个召回都有几乎相同的@ n 82 %,这相当不错。
深度学习
最后,我们将使用深度学习来构建深度协同过滤模型,以结合我们之前看到的 2 个概念,潜在因素模型和嵌入。
由于这个模型,我们可以预测用户对未知商品的评价。
history = DeepCF.fit([train.user_id, train.anime_id], train.user_rating, batch_size=512, epochs=5,
validation_data=([valid.user_id, valid.anime_id],
valid.user_rating))
我没有评价是因为预测方法很慢但是不要犹豫去做。
我们将查看每个模型为单个用户提出的建议。
rated, compare = comparison(25, 5)
我没有显示这个用户的“著名”文集,因为有超过 100 篇文章,但从经验来看,除了 KNN,大多数这些建议似乎非常可靠。
最后
我们已经看到了几种类型的推荐系统,从非常简单的到更复杂的模型,你可以自由地改进或丰富它们。有趣的是,一些非常简单的模型,如流行度,可能是可靠的。我希望这些模型中的一个会对你的项目有用,如果你想看其他奇异的推荐模型,可以看看我的另一篇文章,比如:
- image-recommendation-engine-with-keras:https://towards data science . com/image-recommendation-engine-with-keras-d227b 0996667
- 图片推荐引擎—杠杆迁移学习:https://towards data science . com/image-recommendation-engine-leverage-transfert-learning-EC 9 af 32 f 5239
- Anime2vec:一个序列推荐系统:https://towards data science . com/anime 2 vec-A-sequence-recommender-1e 0 a3 e 558 c 44
谢谢大家!
代码可在此处获得:https://github . com/AlexWarembourg/Medium/blob/master/a-panel-of-recommender . ipynb
梯度下降算法概述
优化参数的微妙而强大的算法
优化参数是每个机器学习算法的最终目标。在线性回归问题中,您希望获得斜率和截距的最佳值,以获得最佳拟合线。您还希望在逻辑回归问题中获得 s 形曲线参数的最佳值。如果我告诉你梯度下降就可以了呢?
在了解它是如何工作的之前,让我们先弄清楚梯度和下降以及其他一些关键术语的含义。
术语
**损失函数:**该函数返回与模型相关联的成本,并测量我们的模型在训练数据上做得如何。如果成本太高,这意味着我们的模型的预测与观察到的数据偏离太多。在任何机器学习算法中,我们的最终使命都是最小化损失函数。我们使用的各种损失函数是:
回归损失:
- L1 损耗/平均绝对误差
- L2 损耗/均方误差
- 均方根误差
分类损失:
- 对数损失(交叉熵损失)
- SVM 损耗(铰链损耗)
**学习率:**这是决定梯度下降算法步骤的超参数。梯度下降对学习速率太敏感。如果太大,算法可能会绕过局部最小值而超调。如果它太小,可能会在很大程度上增加总计算时间。我们将在本文的后面深入了解学习速度的影响。
**坡度:**基本上是衡量一个斜坡的陡度。从技术上来说,当我们对一个函数中所有变量的一阶导数求和时,就会得到梯度。例如,如果我们考虑线性回归,我们有两个参数,斜率和截距,以尽量减少。因此,我们计算 w.r.t .的导数,两者都使截距倾斜&,然后将它们相加,得到截距的梯度。
**下降:**为了优化参数,我们需要最小化误差。梯度下降算法的目标是达到局部最小值(尽管我们总是以达到函数的全局最小值为目标。但是如果梯度下降算法一旦达到局部最小值,就几乎不可能达到全局最小值。).该算法通过在每次迭代中计算步长的迭代过程来实现这一点。并且,这种迭代计算步长以达到局部最小值(或者换句话说,下降到最小值点)被称为下降(足够的下山例子)。
履行
现在,让我们进入算法的技术细节。我们将使用一阶导数来计算梯度。在演示中,我们将使用 NumPy 对线性回归问题应用梯度下降。
让我们首先使用 NumPy 的 random 函数生成一个随机化的数据集,并用散点图来显示我们的数据集分布。
**# Importing Libraries**
import numpy as np
import matplotlib.pyplot as plt**# Generating Randomized dataset**
X = 3*np.random.rand(100,1)
y = 9 + 2*X+np.random.rand(100,1)# Scatter plot
plt.scatter(X,y)
plt.xlabel('X')
plt.ylabel('y')
plt.title('X vs y')
plt.figure(figsize=(15,25))
Scatter Plot: X vs Y
在上面的代码中,我们为自变量和因变量分别取了两个 NumPy 数组,即 X 和 y。从图中可以清楚地看出,这种关系是线性的。我们知道,可以将线性关系放入如下函数中:
Hypothesis function for our linear problem
分析方法
我们可以使用如下所示的分析方法计算θ_ 0 和θ_ 1 的值:
**# mean of x and y vector**
mean_x = X.mean()
mean_y = y.mean()**# calculating cross-deviation and deviation about x**
sum_yx = (X*y).sum()
x_sq = (X**2).sum()
ssxy = sum_yx - (len(X)*mean_x*mean_y)
ssxx = ((X - mean_x)**2).sum()**# calculating regression coefficients**
theta_1 = ssxy/ssxx
theta_0 = mean_y - (theta_1*mean_x)**# printing both the values**
print('Theta 0: {:0.3f}'.format(theta_0))
print('Theta 1: {:0.3f}'.format(theta_1))**Output:**
**Theta 0:** 9.482 **Theta 1:** 1.998
如果我们可以解析地计算最佳参数,为什么我们需要梯度下降?这是因为当我们拥有一个包含数百万个数据点的数据集时,分析方法在计算上变得非常昂贵。另一方面,梯度下降给我们类似的结果,同时大大减少了计算时间。让我们用梯度下降法求解 0 和 1,自己看看。
在数学上,成本函数和梯度可以表示如下:
Gradient & Cost Function for our problem
成本函数背后的直觉
我们的目标是以尽可能接近零的方式最小化成本函数。对于成本函数来说,高负值与高正值一样糟糕。因此,为了保持成本函数值> =0,我们将其平方。我们可以使用 absolute 来做同样的事情,但是我们没有这样做有两个主要原因。
- 将绝对值而不是平方值放在一起会对高残差和低残差的模型进行同等惩罚,而我们需要一个加权惩罚规则,其中具有较高残差的数据点受到更多惩罚,而较低残差受到较少惩罚。这可以简单地通过对残差/误差求平方来实现。
- 还有,根据高斯噪声概念,有两种误差,系统性和随机性。简单地说,系统误差是沿着某个方向的东西。它在本质上是一致的,并且是可预测的。另一方面,随机误差是分布中的噪声。一旦我们考虑了系统噪声成分,当随机噪声最小化时,就获得了最佳预测值。换句话说,最佳预测值是预测值周围分布最紧密(方差最小)的预测值。最小化最小平方损失和最小化方差是一回事!这解释了为什么最小平方损失适用于广泛的问题。由于 CLT(中心极限定理),潜在的噪声通常是高斯噪声,而最小化平方误差被证明是正确的事情!
我们这样做是为了在计算梯度时最小化成本函数的导数,从而抵消掉“2 ”,使梯度更简洁。无论如何,它是一个常数,在计算θ值时无关紧要(因为我们要对它求导)。
此外,我们对 m 上的函数进行平均,m 是训练数据集中数据点的总数。这是为了使计算出的梯度值不会改变比例,并且在出现新数据点的情况下总是平均到一个中心值。
梯度下降实现
在我们实施梯度下降之前,了解其背后的直觉是必须的。既然我们现在已经完成了这一部分,让我们深入到它的实际实现中。
我们想要计算 0 和 1 的值,但是我们可以有多个特征(> =2)。在这种情况下,计算连续步长的一般公式为
The general formula for getting consecutive theta value
其中,α是学习率。我们现在可以从公式中推断出,α对步长的影响很大,因为我们在每次迭代中将梯度与α相乘。
数学讲够了,让我们从实际的代码开始。首先,我们将为要优化的参数初始化一个随机值,0 和 1。我们将编写两个函数,通过迭代计算成本和梯度下降,并将它们存储在两个不同的 NumPy 数组中。上述公式已经用于使用梯度计算成本和θ的连续值。
**def cost(theta,X,y):**
'''
Calculates cost of the function.
X & y have their usual meaning.
theta - vector of coefficients.
'''
m = len(y)
**# Calculating Cost**
c = (1/2*m) * np.sum(np.square((X.dot(theta))-y))
return c**def gradient_descent(X,y,theta,alpha,iterations):**
'''
returns array of thetas, cost of every iteration
X - X matrix with added bias.
y - target variable matrix
theta - matrix of regression coefficients
alpha - learning rate
iteration - number of iteration to be run
'''
**#Getting number of observations.**
m = len(y)
**# Initializing cost and theta's arrays with zeroes.**
thetas = np.zeros((iterations,2))
costs = np.zeros(iterations)
**# Calculating theta for every iteration.**
for i in range(iterations):
theta = theta - (1/m)*alpha*(X.T.dot((X.dot(theta))-y))
thetas[i,:] = theta.T
costs[i] = cost(theta,X,y)
return theta,thetas,costs**# Learning Rate**
alpha = 0.01**# Number of iterations**
iterations = 3000**# Initializing a random value to give algorithm a base value.**
theta = np.random.randn(2,1)**# Adding a biasing constant of value 1 to the features array.**
X_bias = np.c_[np.ones((len(X),1)),X]**# Running Gradient Descent**
theta,thetas,costs = gradient_descent(X_bias,y,theta,alpha,iterations)**# printing final values.**
print('Final Theta 0 value: {:0.3f}\nFinal Theta 1 value: {:0.3f}'.format(theta[0][0],theta[1][0]))
print('Final Cost/MSE(L2 Loss) Value: {:0.3f}'.format(costs[-1])) **Output:**
**Final Theta 0 value:** 9.448
**Final Theta 1 value:** 2.015
**Final Cost/MSE(L2 Loss) Value:** 411.001
在代码中,我们可以看到我们已经运行了 3000 次迭代。但是,这是明确传递给函数的东西。在现实生活中,我们不会这样做。梯度下降停止运行的实际停止点应该是步长接近零时。
分析
让我们通过绘制图表来检查 L2 损失如何随着迭代次数的增加而减少。
**# Plotting Line Plot for Number of Iterations vs MSE**
plt.plot(range(iterations),costs)
plt.xlabel('Number of Iterations')
plt.ylabel('Mean Squared Error')
plt.title('Cost vs Iterations Analysis')
Number of Iterations vs MSE (Mean Squared Error): The Elbow Method
在上图中,我们看到,最初,误差显著减小。但是随着迭代次数的增加,误差并没有减少多少。在某个值之后,它几乎稳定下来,或者我们可以说它的下降可以忽略不计。
这就是梯度下降的美妙之处。当它开始接近局部最小值时,它开始向它迈出非常非常小的步伐,以便不超过它。另一方面,当它很远时,为了减少计算时间,需要更大的步长来更快地达到局部最小值。
因此,为了使用该图选择迭代次数的最佳可能值,我们使用肘方法。简单地说,MSE 值开始下降到可以忽略不计的点就是我们迭代次数的值(图的肘部)。
还有各种类型的梯度下降。我们上面所做的就是所谓的批量梯度下降。其他类型包括:
结论
梯度下降可用于优化每个算法的参数,该算法的损失函数可被公式化并具有至少一个最小值。此外,我们澄清了我们对臭名昭著的梯度下降损失函数方程的理解。
我们学习了如何使用可视化方法来估计所需的迭代次数。最后,我们了解了著名的梯度下降算法背后的实际工作原理。
时间序列预测模型综述
我们描述了 10 个预测模型,并应用它们来预测工业生产指数的演变
Photo by Drew Beamer on Unsplash
这篇文章是关于什么的?
这篇文章提供了一个单变量时间序列建模和预测其演变可用的主要模型的概述。这些模型是用 R 和 Python 开发的。相关代码可在这里获得。
时间序列预测是一个热门话题,有许多可能的应用,如股票价格预测,天气预报,商业规划,资源分配等。尽管预测可以被认为是监督回归问题的一个子集,但由于观察的时间性质,一些特定的工具是必要的。
什么是时间序列?
时间序列通常通过随机过程Y(t)建模,即随机变量序列。在预测设置中,我们发现自己在时间 t 并且我们对仅使用在时间t可用的信息来估计*Y(t+h)*感兴趣
如何验证和测试时间序列模型?
由于时间序列数据的时间依赖性,我们不能依靠通常的验证技术。为了避免有偏见的评估,我们必须确保训练集包含在验证集中的观察之前发生的观察。
克服这个问题的一个可能的方法是使用滑动窗口,正如这里所描述的。这个过程称为时间序列交叉验证,总结如下图,其中蓝色点代表每个“折叠”中的训练集,红色点代表相应的验证集。
Time series cross-validation. Credits to Rob J Hyndman
如果我们对预测下一个 n 时间步骤感兴趣,我们可以对前面的 1,2,…,n 步骤应用交叉验证程序。通过这种方式,我们还可以比较不同时间范围的预测的准确性。
一旦我们选择了最佳模型,我们就可以将其应用于整个训练集,并在随后的单独的测试集中评估其性能。可以通过使用用于交叉验证的相同滑动窗口技术来完成性能估计,但是不需要重新估计模型参数。
短数据探索
在下一节中,我们将应用不同的预测模型来预测工业生产指数的演变,该指数量化了在欧元区制造的电气设备。
数据可以通过 R 中的 fpp2 包轻松下载。要使数据在 R 之外可用,只需在 R 环境中运行以下代码。
library(fpp2)
write.csv(elecequip,file = “elecequip.csv”,row.names = FALSE)
该数据集对应于 1996 年 1 月至 2012 年 3 月期间欧元区(17 个国家)电气设备(计算机、电子和光学产品)的月度制造量。我们保留最后两年用于测试目的。
该时间序列在 2000 年底有一个峰值,在 2007 年有另一个峰值。我们在 2008 年底观察到的巨大下降可能是由于当年发生的全球金融危机。
似乎有一个每年的季节性模式。为了更好地显示这一点,我们用原始坐标和极坐标分别显示了每年的数据。
我们观察到强烈的季节性模式。特别是由于夏季假期,8 月份的产量大幅下降。
时间序列预测模型
我们将考虑以下模型:
- 天真,幼稚
- 季节分解(+任何模型)
- 指数平滑
- ARIMA、萨里玛
- GARCH
- 动态线性模型
- TBATS
- 先知
- 尼塔尔
- LSTM
我们对预测 12 个月的工业生产指数感兴趣。因此,给定到时间 t 的数据,我们希望预测指数在时间 t+1,…,t+12 的值。
我们将使用平均绝对误差(MAE) 来评估模型的性能。
1)天真,幼稚
在天真模型中,每个时段的预测都对应于最后的观察值。
ŷ(t+h|t)= y(t)
这种预测假设产生时间序列的随机模型是随机行走的。
天真模型的扩展是由天真(季节性天真)模型给出的。假设时间序列具有季节性成分,并且季节性的周期为 T ,则由 s nave 模型给出的预测为:
ŷ(t+h|t)= y(t+h-t)
因此,对随后的 T 时间步的预测等于先前的 T 时间步。在我们的应用程序中,对下一年的简单预测等于去年的观测值。
这些模型通常被用作基准模型。以下图表显示了 2007 年两种模型的预测结果。
利用预测 R 软件包的naive
和snaive
功能对模型进行拟合。
2)季节分解(+任何模型)
如果数据显示出一定的季节性(如每日、每周、每季度、每年),将原始时间序列分解为三个部分的总和可能是有用的:
*Y(T)=*S(T)+T(T)+R(T)
其中 S(t) 是季节性成分, T(t) 是趋势周期成分, R(t) 是余数成分。
存在几种技术来估计这样的分解。最基本的一种称为经典分解,它包括:
- 通过滚动平均值估计趋势 T(t)
- 计算 S(t) 作为每个季节(例如每个月)的平均去趋势序列 Y(t)-T(t)
- 计算剩余数列为 R(t)=Y(t)-T(t)-S(t)
经典分解在几个方面得到了扩展。它的扩展允许:
- 具有非恒定的季节性
- 计算分解的初始值和最后值
- 避免过度平滑
要获得时间序列分解方法的概述,您可以点击此处。我们将利用 STL 分解,它被认为是通用的和健壮的。
STL decomposition on industrial production index data
下面是使用分解进行预测的一种方法:
- 用某种分解算法(如 STL)对训练时间序列进行分解: Y(t)= S(t)+T(t)+R(t)。
- 计算经季节调整的时间序列 Y(t)-S(t) 。使用任何你喜欢的模型来预测季节性调整时间序列的演变。
- 将时间序列中最后一个时间段的季节性添加到预测中(在我们的示例中,去年的拟合 S(t) )。
在下图中,我们展示了经季节性调整的工业生产指数时间序列。
下图显示了通过使用 STL 分解和 nave 模型来拟合季节性调整时间序列而获得的对 2007 年的预测。
分解是通过使用 stats R 包的stl
函数来拟合的。
3)指数平滑
指数平滑法是最成功的经典预测方法之一。其基本形式被称为简单指数平滑,其预测由下式给出:
ŷ(t+h|t)= ⍺y(t)+⍺(1-⍺)y(t-1)+⍺(1-⍺)y(t-2)+…
用 0 < ⍺ < 1 。
我们可以看到,预测等于过去观测值的加权平均值,随着时间的推移,相应的权重呈指数下降。
已经提出了简单指数平滑的几种扩展,以便包括趋势或阻尼趋势和季节性。指数平滑系列由 9 个模型组成,在此处有详细描述。
下图显示了通过使用指数平滑模型(自动选择)来拟合原始时间序列和季节性调整时间序列而获得的 2007 年预测。
使用预测 R 软件包的ets
功能对模型进行拟合。
4) ARIMA,萨里玛
至于指数平滑,ARIMA 模型也是时间序列预测中最广泛使用的方法之一。这个名字是自回归综合移动平均的缩写。
在自回归模型中,预测对应于变量过去值的线性组合。在移动平均模型中,预测对应于过去预测误差的线性组合。
基本上,ARIMA 模型结合了这两种方法。由于它们要求时间序列是平稳的,差分(积分)时间序列可能是一个必要的步骤,即考虑差分的时间序列而不是原始的时间序列。
SARIMA 模型(季节性 ARIMA)通过添加季节性过去值和/或预测误差的线性组合来扩展 ARIMA。
关于 ARIMA 和萨里玛车型的完整介绍,请点击此处。
下面的图显示了通过使用季节调整时间序列的萨里玛模型和 ARIMA 模型获得的对 2007 年的预测。
使用预测 R 软件包的auto.arima
和Arima
功能对模型进行拟合。
5) GARCH
以前的模型假设产生时间序列的随机过程中的误差项是同伦的,即具有恒定的方差。
相反, GARCH 模型假设误差项的方差遵循自回归移动平均(ARMA)过程,因此允许它随时间变化。它对于模拟波动性随时间变化的金融时间序列特别有用。这个名字是广义自回归条件异方差的首字母缩写。
通常,均值也采用 ARMA 过程。关于 GARCH 模型的完整介绍,你可以点击这里和这里。
下面的图显示了通过使用 GARCH 模型来拟合季节性调整的时间序列而获得的 2007 年的预测。
使用 rugarch R 软件包的ugarchfit
功能对模型进行拟合。
6)动态线性模型
动态线性模型代表了时间序列预测的另一类模型。想法是在每个时间 t 这些模型对应一个线性模型,但是回归系数随时间变化。下面给出一个动态线性模型的例子。
y(t) = ⍺(t) + tβ(t) + w(t)
⍺(t) = ⍺(t-1) + m(t)
β(t) = β(t-1) + r(t)
w(t)N(0,W),m(t)N(0,M),r(t)~N(0,R)
在前一个模型中,系数 ⍺(t) 和 β(t) 遵循随机游走过程。
动态线性模型可以在贝叶斯框架中自然建模;然而,最大似然估计技术仍然可用。有关动态线性模型的完整概述,请点击此处。
下图显示了通过使用动态线性模型来拟合季节性调整时间序列而获得的对 2007 年的预测。由于巨大的计算成本,我不得不保持模型极其简单,这导致了糟糕的预测。
使用 dlm R 包的dlmMLE
功能对模型进行拟合。
7) TBATS
TBATS 模型是一种基于指数平滑的预测模型。该名称是三角函数、Box-Cox 变换、ARMA 误差、趋势和季节分量的缩写。
TBATS 模型的主要特点是能够处理多个季节性,通过基于傅立叶级数的三角表示法模拟每个季节性。复杂季节性的一个典型例子是每天对销售量的观察,通常同时具有每周和每年的季节性。
关于 TBATS 型号的完整介绍,请点击此处。
下图显示了使用 TBATS 模型拟合时间序列获得的 2007 年预测值。
通过使用预测 R 软件包的tbats
功能对模型进行拟合。
8)先知
Prophet 是另一个预测模型,它可以处理多重季节性。它是脸书核心数据科学团队发布的一款开源软件。
prophet 模型假设时间序列可以分解如下:
y(t)= g(t)+s(t)+h(t)+ε(t)
三个术语 g(t) 、 s(t) 和 h(t) 分别对应趋势、季节性和节假日。最后一项是误差项。
模型拟合被框定为曲线拟合练习,因此没有明确考虑数据中的时间依赖结构。这也允许进行不规则间隔的观察。
趋势时间序列有两种选择:饱和增长模型和分段线性模型。多期季节性模型依赖傅立叶级数。已知和定制假日的效果可以很容易地整合到模型中。
prophet 模型被插入到贝叶斯框架中,它允许进行充分的后验推断,以将模型参数不确定性包括在预测不确定性中。
如需对 Prophet model 的完整介绍,请点击此处的。
下图显示了通过使用 Prophet 模型拟合时间序列获得的 2007 年预测。
通过使用 prophet R 软件包的prophet
功能对模型进行拟合。
9)内塔尔
NETAR 模型是一个完全连接的神经网络。首字母缩写代表神经网络自回归。
NNETAR 模型在时间 t 之前接受输入序列的最后元素,并在时间 t+1 输出预测值。为了进行多步预测,网络被反复应用。
在存在季节性的情况下,输入也可能包括季节性滞后的时间序列。有关 NNETAR 型号的完整介绍,请点击此处。
下面的图显示了 2007 年的预测结果,这些预测结果是通过使用带有季节性滞后输入的 NNETAR 模型和基于季节性调整时间序列的 NNETAR 模型获得的。
使用预测 R 软件包的nnetar
功能对模型进行拟合。
10) LSTM
LSTM 模型可用于预测时间序列(以及其他递归神经网络)。LSTM 是长短期记忆的首字母缩写。
LSTM 网络的状态通过状态空间向量来表示。这种技术允许跟踪新观测值与过去观测值的相关性(即使是非常远的观测值)。
一般来说,LSTMs 是复杂的模型,它们很少用于预测单个时间序列,因为它们需要大量的数据来估计。然而,当需要对大量时间序列进行预测时,通常使用它们(检查此处)。
关于使用 LSTM 预测时间序列的完整介绍,点击此处。
下图显示了通过对季节性调整时间序列拟合 LSTM 模型而获得的测试集中第一年的预测。
使用 Python 中的 Keras 框架对模型进行拟合。
估价
我们通过前述的交叉验证程序进行型号选择。我们没有计算动态线性模型和 LSTM 模型,因为它们的计算成本高,性能差。
在下图中,我们展示了每个模型和每个时间跨度的交叉验证 MAE。
我们可以看到,对于时间跨度大于 4 的情况,基于季节性调整数据的 NNETAR 模型比其他模型表现得更好。让我们检查通过在不同时间范围内求平均值计算出的总 MAE。
Cross-validated MAE
基于经季节性调整的数据的 NNETAR 模型是该应用的最佳模型**,因为它对应于最低的交叉验证 MAE。**
为了获得最佳模型性能的无偏估计,我们在测试集上计算 MAE,获得等于 5,24 的估计。在下面的图片中,我们可以看到在每个时间范围的测试集上估计的 MAE。
如何进一步提高性能
提高模型性能的其他技术可以是:
- 对不同的时间范围使用不同的模型
- 组合多个预测(例如,考虑平均预测)
- 引导汇总
最后一种技术可以总结如下:
- 分解原始时间序列(例如使用 STL)
- 通过随机打乱剩余部分的块来生成一组相似的时间序列
- 对每个时间序列拟合模型
- 每个模型的平均预测
有关引导聚合的完整介绍,请单击此处的。
结束语
该项目的目标不是拟合工业生产指数的最佳预测模型,而是给出预测模型的概述。在现实世界的应用中,大量的时间应该花费在预处理、特征工程和特征选择上。
大多数先前描述的模型允许容易地结合时变预测器。这些可以从相同的时间序列中提取,或者可以对应于外部预测值(例如,另一个指数的时间序列)。在后一种情况下,我们应该注意不要使用来自未来的信息,这可以通过预测预测器或使用它们的滞后版本来满足。
最后,请注意,在本文中,我们只考虑了只有一个时间序列需要预测的情况。当我们有很多时间序列时,一个全局的方法可能是首选,因为它允许我们估计一个更复杂和可能更准确的模型。有关全球方法的介绍,请点击此处。
弹性搜索及其应用综述
简介
Elasticsearch 是一个高度可扩展的开源全文搜索和分析引擎。它允许您以接近实时的速度快速存储、搜索和分析大量数据。它通常用作支持具有复杂搜索功能和需求的应用程序的底层引擎/技术。Elasticsearch 在 Lucene StandardAnalyzer 之上提供了一个分布式系统,用于索引和自动类型猜测,并利用一个基于 JSON 的 REST API 来引用 Lucene 特性。
它很容易开箱设置,因为它提供了合理的默认设置,并对初学者隐藏了复杂性。它有一个短的学习曲线来掌握基础知识,所以任何人只要稍加努力就可以很快变得富有成效。它是无模式的,使用一些缺省值来索引数据。
在消费者从电子商务网站搜索产品信息的情况下,目录面临着产品信息检索时间长等问题。这导致了糟糕的用户体验,进而错失了潜在客户。如今,企业正在寻找替代方法,以快速检索的方式存储大量数据。这可以通过采用 NOSQL 而不是 RDBMS(关系数据库管理系统)来存储数据来实现。
Elasticsearch 是一个 NOSQL 数据库,因为:
- 它易于使用
- 有一个很棒的社区
- 与 JSON 的兼容性
- 广泛的使用案例
后端组件
为了更好地理解 Elasticsearch 及其用法,对主要后端组件有一个大致的了解是有好处的。
结节
节点是作为集群一部分的单个服务器,存储我们的数据,并参与集群的索引和搜索功能。就像集群一样,节点由名称标识,默认情况下,名称是启动时分配给节点的随机通用唯一标识符(UUID)。如果需要,我们可以编辑默认的节点名。
串
集群是一个或多个节点的集合,这些节点共同保存您的全部数据,并提供联合索引和搜索功能。可以有 N 个节点具有相同的集群名称。
Elasticsearch 在分布式环境中运行:通过跨集群复制,辅助集群可以作为热备份发挥作用。
索引
索引是具有相似特征的文档的集合。例如,我们可以为特定的客户建立一个索引,为产品信息建立一个索引,为不同类型的数据建立一个索引。执行索引搜索、更新和删除操作时,索引由引用该索引的唯一名称来标识。在一个集群中,我们可以定义任意多的索引。索引类似于 RDBMS 中的数据库。
文件
文档是可以被索引的基本信息单元。例如,您可以有一个关于产品的索引,然后有一个针对单个客户的文档。该文档以 JSON (JavaScript 对象符号)表示,这是一种无处不在的互联网数据交换格式。类似于数据库中的单个原始数据。在一个索引中,您可以存储任意多的文档,因此在同一个索引中,您可以有一个针对单个产品的文档,还有一个针对单个订单的文档。
碎片和复制品
Elasticsearch 提供了将索引细分为多个片段的能力。当您创建一个索引时,您可以简单地定义您想要的碎片数量。每个碎片本身就是一个全功能的独立“索引”,可以托管在集群中的任何节点上。
Shards 非常重要,因为它允许水平分割您的数据量,还可能在多个节点上并行操作,从而提高性能。还可以通过将索引的多个副本制作成副本碎片来使用碎片,这在云环境中有助于提供高可用性。
弹性叠层
尽管搜索引擎是其核心,但用户开始使用 Elasticsearch 搜索日志,并希望轻松地摄取和可视化它们。 Elasticsearch、Logstash、Kibana 是弹性栈的主要组成部分,被称为 ELK 。
基巴纳
Kibana 让您可视化您的 Elasticsearch 数据并浏览 Elastic 堆栈。您可以从一个问题开始,选择赋予数据形状的方式,找出交互式可视化将把您引向何处。您可以从经典图表(直方图、折线图、饼图、太阳图等)开始,或者设计自己的可视化并在任何地图上添加地理数据。
您还可以执行高级时间序列分析,发现数据中的视觉关系,并利用机器学习功能探索异常情况。更多详情请看官方页面。
Kinbana console
Logstash
Logstash 是一个开源的服务器端数据处理管道,它同时从多个来源获取数据,对其进行转换,然后将其发送到 collect。数据通常以多种格式分散或污染在多个系统中。在 Logstash 上,可以接收日志、指标、web 应用程序、数据存储和各种 AWS 服务,所有这些都以连续流的方式进行。它可以与不同的模块一起使用,如 Netflow ,以获得对您的网络流量的见解。
它通过识别命名字段来构建结构,动态地转换和准备数据,而不考虑格式,并将其转换为通用格式。您可以使用 X-Pack 中的监控特性来深入了解关于您的 Logstash 部署的指标。在 overview dashboard 中,您可以看到 Logstash 接收和发送的所有事件,以及关于内存使用和正常运行时间的信息。然后,您可以深入查看特定节点的统计信息。更多详情请访问官方页面。
logstash node stats
弹性搜索用例
Elasticsearch 可以以如此多的方式使用,以至于我很难捕捉到所有最有趣的用例。为了简单起见,我选择了三个主要类别和三个主要公司用例,如果你想深入了解,可以看看它们的用例[页](https://www.elastic.co/use-cases)。
- 主数据存储:创建可搜索的目录、文档存储和日志系统。
- 补充技术:给 SQL、mongoDB 增加可视化能力,给 Hadoop 增加 cast 索引和搜索,或者给 kafka 增加处理和存储。
- 附加技术:如果您已经登录了 Elasticsearch,您可能希望添加指标、监控和分析功能。
网飞
幕后的网飞信息系统正在使用 Elasticsearch。消息系统分为以下几类:
- 加入服务时收到的消息。
- 一旦人们加入,他们会收到关于他们可能喜欢的内容或服务器上的新功能的消息。
- 一旦他们通过机器学习算法对你有了更多的了解,他们就会发送更多关于你可能喜欢或喜欢看什么的迷人和个性化的信息。
- 如果你决定退出服务,他们会告诉你如何回来。
这些都是通过邮件、app 推送通知、短信来完成的。为了有效地实现这一点,他们需要几乎立即知道消息传递中可能出现的问题。为此,为消息生命周期引入了 Elasticsearch(以前他们使用分布式 grep)。
简而言之,每条状态信息都记录在 Elasticsearch 上,合适的团队可以通过在 Kibana 上编写查询来过滤每个类别。
假设推出了一部新电影,在这种情况下,必须将“新片名”消息发送给所有客户。
使用 Kibana,他们可以实时看到有多少人收到了新消息的通知,以及消息发送的成功率。他们还可以验证某些消息失败的原因。这带来了更快地调查和解决问题的能力,例如 2012 年巴西的高比率消息失败。
通过使用 Kibana 中的饼图,他们几乎可以立即发现大量的无效会员失败。他们跟踪调查了国家提供商,发现在 7 月 29 日,在许多巴西地区,所有现有手机号码的左边都添加了数字 9,而不管它们之前的初始数字是多少。这一变化旨在增加圣保罗等大都市地区的电话号码容量,从而消除该地区长期存在的号码短缺问题。
多亏了 Elasticsearch,他们能够近乎实时地发现所有这些故障,并及时与提供商跟进。
国外手机交友软件
这是一家大型 tec 公司和 Elasticsearch 社区相互合作的例子。Tinder 的核心是一个搜索引擎。搜索查询非常复杂,涉及两位数的事件、数百个国家和 50 多种语言。
大多数用户交互都会触发 Elasticsearch 查询。
根据位置不同,与 tinder 的交互方式也不同。例如在亚洲,他们也用它作为语言交换或寻找导游。
因此,Tinder 中的查询非常复杂。它们必须是:
- **个性化:**机器学习算法也在这种情况下使用。
- **基于位置:**根据您在某个时间点的位置来查找匹配。
- **双向:**知道哪些用户会互相向右滑动,基本上就是匹配了。
- **实时:**大量用户的整个交互必须在几毫秒内发生,并且每个用户都有许多相关的变量。
考虑到所有这些功能,后端现实非常复杂,从数据科学和机器学习扩展到双向排名和地理定位。Elasticsearch 的基石是让这些组件以一种非常高效的方式协同工作。在这种情况下,绩效是一个障碍。为此,他们一直在与 Elasticsearch 团队合作,微调许多参数并解决问题。通过这种方式,他们一直在支持 Elasticsearch 社区,并帮助改善整个 Elastic stack 产品,同时改善 Tinder 本身的用户体验。
思科商务交付平台
Elasticsearch 于 2017 年推出,当时他们升级了他们的商业平台。他们从 RDBMS 转向 Elasticsearch 的原因如下:
- 添加在主动/主动模式下工作的容错功能。RDBMS 不是分布式的,也不是容错的。
- 基于等级和类型的提前搜索来自 30/40 属性的多个数据库的数据,以获得亚秒级响应。
- 全局搜索:如果在搜索中没有指定特定的对象,搜索引擎将根据多个对象查找结果。
思科威胁情报部门
简而言之,思科威胁情报部门或思科 Talos 正在阻止恶意软件和垃圾邮件使*“互联网管道”*饱和。
在这个思科部门,他们每天查看超过 150 万个恶意软件样本。恶意负载和垃圾邮件占所有电子邮件流量的 86%(每天超过 6000 亿封电子邮件)。
Talos 的威胁情报团队负责在网络上发现新的全球规模的漏洞,并找出真正的坏人。
他们通过分析 ssh 终端和路由器蜜罐的流量模式来检测新的漏洞利用工具包,以收集异常行为,如使用暴力攻击猜测用户和密码的尝试登录。通过这种方式,他们记录了攻击者登录后使用的命令,他们从服务器下载和上传的文件(虽然难以置信,但互联网上的大多数凭证都像行密码和用户名 admin 一样简单)。
是他们在 2015 年阻止了所谓的ssh psychs。众所周知,该组织通过从特定类别的 IP 生成 SSH 暴力登录尝试,在互联网上创建了大量的扫描流量。一旦他们能够以 root 用户身份进入服务器,他们就可以下载并安装 DDoS rootkits。
自 2017 年以来,他们使用 logstash 和 kibana 来检测和分析可能的全球规模线程。
结论
Elasticsearch 是一个分布式、RESTful 和分析型搜索引擎,能够解决各种各样的问题。
许多公司正在转向 it 并将其集成到当前的后端基础设施中,因为:
- 它允许使用聚合缩小到您的数据,并理解数十亿条日志行。
- 它结合了不同类型的搜索:结构化、非结构化、地理、应用程序搜索、安全分析、指标和日志记录。
- 它真的很快,可以在只有一个节点的笔记本电脑上运行,也可以在有数百台服务器的集群上运行,这使得非常容易原型化。
- 它使用标准的 RESTful APIs 和 JSON。该社区还以多种语言构建和维护客户端,如 Java、Python、.NET、SQL、Perl、PHP 等。
- 通过使用Elasticsearch-Hadoop(ES-Hadoop)连接器,可以将 elastic search 的实时搜索和分析功能应用于您的大数据。
- 像 Kibana 和 Logstash 这样的工具允许你通过使用图表和执行粒度搜索,以非常简单和直接的方式理解你的数据。
在本文中,我们仅仅触及了弹性搜索能力和用例的皮毛,而各种业务挑战是可以解决的。如果你有兴趣了解更多或测试它,看看他们的产品页面和他们的教程快速开始。如果你对如何使用 django 和 elasticsearch 创建一个基本的搜索应用感兴趣,我鼓励你看看我以前的文章。
从词向量类推?
这些类比有多相似?
A close inspector (Source: own image)
关于词向量的入门级文章往往包含计算类比的例子,比如国王-男人+女人=王后。像这样引人注目的例子显然有它们的位置。它们引导我们对相似性的兴趣,将其视为一个有待挖掘的隐藏宝藏。然而,在真实数据中,类比往往不那么清晰和易于使用。
前段时间对德国维基百科的快照分析,留下了太多的问题,其中之一就是类比。当然,首先要测试的事情之一是国王-王后(或者在德语中:knig-knig in)的例子是否也适用于这个语料库——并不令人惊讶的是,它没有:
Candidates for king-man+woman from German Wikipedia corpus
没有一个候选人与国王和王后完全无关;排名第一和第四的是国王配偶的词汇,排名第二的是国王的单词形式,排名第三的是女儿,最后排名第五的是女王——没有像预期的那样突出。接下来是婚礼、皇位继承人、妃子、登基和妹妹。但是候选集对于某样东西是女性(相对于国王)还是与王权有关并不十分明显。因此结果集的实际直接适用性似乎相当有限。
类比的另一个常见例子是大写的派生。让我们来看看奥地利首都的候选城市有哪些:
Candidates for Austria-Germany+Berlin from German Wikipedia corpus
这一次我们成功了,的确维也纳对于奥地利就像柏林对于德国一样。其他候选人的名单也很有意义,我们发现奥地利五个联邦州的首府(格拉茨、克拉根福、林茨、因斯布鲁克、萨尔茨堡)和波兰一个省的首府(弗罗茨瓦夫)……以及德国萨克森州的两个城市正在竞争谁是真正的首府(德累斯顿、莱比锡)。
万岁。这个结果延伸了吗?让我们编写几行 Python 代码来测试和可视化所有欧洲国家的类比练习——不包括城市国家和哈萨克斯坦,在这些国家,语料库中没有足够的数据供其首都在模型中显示:
Test all pairs of countries and capitals for correctly guessed analogy and visualize the result
经过一些计算,我们得到 57.25%的命中和 42.25%的未命中,比实际希望的要差得多:
Result matrix of the country-capital guessing exercise
一个国家拥有猜测资本好坏的背后似乎没有什么模式。让我们来看看原始频率,下面有一个完整的列表。
有许多猜测失败的国家:英国(2482),捷克共和国(679),意大利(91024),冰岛(37591),摩尔多瓦(2585)。相比之下,一些国家有许多正确的猜测:奥尔巴尼(7067),丹麦(34079),爱尔兰(23024),葡萄牙(29124),罗马尼亚(22700)。英国和捷克共和国的官方名称很少被使用,这也许可以解释为什么在提到他们的首都时不会出现这种情况。此外,摩尔多瓦可能会因为国名和河流名不清而遭受损失。但这并不能解释意大利或冰岛。
同样,让我们对那些有许多猜测失败的城市做同样的比较:伦敦(114,921),布拉格(34,565),罗马(70,952),Rejkyavik (2,890),Chișinău (851)和有许多正确猜测的城市:地拉那(2,240),哥本哈根(18,092),都柏林(9630),里斯本(11,196),布卡拉斯特(8,350)。同样,我们没有明确的案例,这次也没有额外知识的支持。有人能解释一下这个吗?
总的来说,给人的印象是,类比有时效果惊人地好,有时则不然。在利用这些数据时,我们应该记住这一点,并为意外失败做好准备。
使用 Apache Drill 通过 SQL 查询分析 Kafka 消息
原文发布于此:https://blog . contact sunny . com/tech/analyse-Kafka-messages-with-SQL-queries-using-Apache-drill
在上一篇文章中,我们弄清楚了如何将 MongoDB 与 Apache Drill 连接起来,并使用 SQL 查询来查询数据。在这篇文章中,让我们扩展这方面的知识,看看如何使用类似的 SQL 查询来分析我们的 Kafka 消息。
在 Apache Drill 中配置 Kafka 存储插件非常简单,与我们配置 MongoDB 存储插件的方式非常相似。首先,我们运行 Apache Drill、Apache Zookeeper 和 Apache Kafka 的本地实例。在这之后,前往http://localhost:8047/storage,在那里我们可以启用 Kafka 插件。您应该在页面右侧的列表中看到它。单击启用按钮。存储插件将被启用。在这之后,我们需要添加一些配置参数来开始从 Kafka 查询数据。单击 Kafka 旁边的 Update 按钮,这将打开一个带有 JSON 配置的新页面。用以下内容替换 JSON:
{
"type": "kafka",
"kafkaConsumerProps": {
"key.deserializer": "org.apache.kafka.common.serialization.ByteArrayDeserializer",
"auto.offset.reset": "earliest",
"bootstrap.servers": "localhost:9092",
"group.id": "drill-query-consumer-1",
"enable.auto.commit": "true",
"value.deserializer": "org.apache.kafka.common.serialization.ByteArrayDeserializer",
"session.timeout.ms": "30000"
},
"enabled": true
}
如果需要,您可以更改此配置。如果您要连接到远程引导服务器,请更改引导服务器地址。一旦完成这些,我们就可以开始从 Kafka 主题中查询数据了。因此,让我们切换到终端,看看一些查询。
使用 Drill SQL 查询查询 Apache Kafka 消息
首先,我们来看看 Kafka 存储插件是否确实启用了。为此,我们只需运行 *show 数据库;*查询。这将列出我们已启用的所有存储插件,以及这些服务中的数据库(如果适用)。如果您运行此查询,您的输出应该类似于:
可以看到,卡夫卡被列为数据库。让我们使用下面的命令切换到这个模式:
use kafka;
要开始从 Kafka 主题中读取数据,我们需要首先查看该主题是否被 Drill 识别。Kafka 中的每个主题都会在 Drill 中以表格的形式出现在 kafka 数据库中。所以我们只需要列出这个数据库中的所有表。出于测试目的,您可以创建一个新主题。我创建了主题“drill ”,用于使用 Drill 进行测试。让我们看看它是否在这个数据库中显示为一个表。
这就是了。我们将在这个表上运行我们的查询。
这里你需要注意的一件事是,现在,对于最新版本的 Apache Drill 和 Kafka 存储插件,只有 JSON 消息可以工作。如果你发送的不是 JSON,Drill 会抛出一个异常,并且不能工作。所以让我们来解决这个问题。
让我们使用 Kafka 控制台生成器发送一些随机的 JSON 消息,看看 Drill 是否能够查询这些消息。
我将从一个控制台生成器向“drill”主题发送以下 JSON 消息(总共四条)。这是我在简单的谷歌搜索后在网上得到的一些样本数据。
{
"id": 1,
"first_name": "Jeanette",
"last_name": "Penddreth",
"email": "jpenddreth0@census.gov",
"gender": "Female",
"ip_address": "26.58.193.2"
}
{
"id": 2,
"first_name": "Giavani",
"last_name": "Frediani",
"email": "gfrediani1@senate.gov",
"gender": "Male",
"ip_address": "229.179.4.212"
}
{
"id": 3,
"first_name": "Noell",
"last_name": "Bea",
"email": "nbea2@imageshack.us",
"gender": "Female",
"ip_address": "180.66.162.255"
}
{
"id": 4,
"first_name": "Willard",
"last_name": "Valek",
"email": "wvalek3@vk.com",
"gender": "Male",
"ip_address": "67.76.188.26"
}
现在,让我们对 Drill 中的表运行以下简单的 SQL 命令,看看会得到什么输出:
select * from drill;
这就是我们想要的结果。从 Drill 查询阿帕奇卡夫卡就是这么简单。我不知道为什么我没有早点遇到这个工具。
分析比利时选举结果
对数据的深入研究
Photo by Element5 Digital on Unsplash
介绍
2019 年 5 月 26 日,比利时组织了联邦选举。在本文中,我不想讨论这些选举的政治含义。我想研究一下这些数据,看看我们能从中学到什么。
更具体地说,我想回答这样一个问题:“自上次选举以来,选民是如何改变他们的想法的”。
看总的结果,不可能回答这个问题。请注意,这是真的,即使只有两个政党参加选举。
举个例子,我们想象一下,连续两次选举,两党都拿到了半数选票。那么仍然不可能得出是没有一个选民改变主意,还是所有的选民都改变了主意,或者介于两者之间。
资料组
一切有趣的事情都始于数据集。所以我开始为自己寻找一个包含选举结果数据的数据集。
我偶然发现这个网站,上面有每个地区 2019 年和 2014 年(以前的选举)的投票结果数据。我所说的区在比利时被称为“行政区”,大约有 200 多个。
我是手动复制粘贴这个网站上的所有结果,还是采用不太合法的方法编写 Python 脚本来自动抓取结果,这是任何人的猜测。我只能说我强烈推荐“ BeautifulSoup ”库进行截屏。
我最终得到了一个数据集,它提供了 2019 年和 2014 年 200+个地区中每个政党的票数。
为了准确起见,我必须提到比利时分为三个自治区:佛兰德、瓦隆和布鲁塞尔首都,并非所有政党在所有地区都有代表。在这篇文章的结果部分,我将把重点放在最大的部分(佛兰德),但该方法也测试了其他部分。
模型描述
为了了解哪些选民改变了主意,我建立了一个非常简单的模型。
我将选举简化为一个 N 党制,放弃所有在 2014 年和 2019 年获得少于 15 万张选票的政党。
然后我假设所有在 2014 年投票的人,在 2019 年会以同样的方式改变他们的想法。更具体地说,在 2014 年投票给 Pᵢ党的人,在 2019 年投票给 Pᵣ党的概率是一样的。(我称这个概率为 X ᵢᵣ).
我们的目标是找到概率 X ᵢᵣ.的最佳值换句话说:“x 的哪些值 *ᵢᵣ,*根据 2014 年的结果最好地解释了 2019 年的结果”。
为了“解释”或“预测”2019 年政党 Pᵣ 的票数 V ᵣ ⁰ ⁹,基于 2014 年的结果,我可以使用概率 X ᵢᵣ 如下:
那看起来很熟悉不是吗?这是一个简单的线性回归。所以我开始着手用 Python 实现这个模型。
应该注意的是,即使我们在谈论预测 2019 年的结果,我们也不关心预测 2019 年的选举,因为它们已经过去了。我们只是试图创建一个预测模型,然后研究“这个模型的内部”(概率 X ᵢᵣ).
初步结果
我将在热图中展示这个线性回归的结果。热图中的每个单元格都包含一个概率 X ᵢᵣ.
这个热图应该这样理解:每个单元格位于一行和一列的交叉点上。行代表在 2014 年投票给某个政党的人,列代表他们在 2019 年投票给的政党。单元格中的值表示 2014 年投票给第一个政党的人与 2019 年投票给第二个政党的人的比率。
举个例子:如果所有人在 2014 年和 2019 年以完全相同的方式投票,热图对角线上的值为 1,其他地方的值为 0。
我的第一个结果显示在下面的热图中。
Results of the first model: Not what I was hoping for
一张图说了千言万语,这次却是只喊一件事:“模型错了!”。
模型的问题
这个模型给出了无意义的结果,因为这个问题当然不是传统的线性回归问题,原因有二。
首先,在我对模型的解释中,参数 X ᵢᵣ 不能取任意值。因为它们代表选民转向另一个政党的概率,所以它需要是 0 到 1 之间的一个数字。在 2019 年,某个群体的选民有-59%的概率投票给某个政党,这根本没有意义。
其次,概率 X 和ᵢᵣ 并不是相互独立的。所有选民都需要在 2019 年投下新的一票,否则就有成为非法移民的风险,因为投票在比利时是强制性的。
因此,每个政党的总和 X ᵢᵣ 需要“大约”100%(因为在 2014 年和 2019 年之间,人们可能已经死亡、迁移或达到允许投票的最低年龄)。
我可以多做一点,添加 2014 年至 2019 年每个地区的人口变化信息,但为了简化问题,我假设它大致不变。
改进模型
因此,我修改了模型,将这些限制因素考虑在内。
该模型在两个方面进行了调整:
- 我从默认的线性回归转向最小二乘问题,用独立变量的界限来限制我的概率在 0 和 1 之间。
- 我为每个政党添加了一个等式,以迫使所有 2014 年的选民在 2019 年再次投票。这个方程用一个超参数加权来表示它的相对权重。
有趣的是,模型的“性能”(将在本文末尾讨论)只有在考虑到这些约束的情况下才会下降。但是鉴于我们对模型的解释比对预测能力更感兴趣,我们很乐意接受这种性能上的打击。
超参数调谐
上面提到的超参数定义了这个约束相对于“正确预测”的相对重要性。
我通过检查作为超参数函数的性能图来调整这个参数的值。在误差达到最高点之前,我选择了高原上的某个点。
为了让自己相信结果不太依赖于超参数,我很快检查了超参数值不同的模型之间的结果差异。结果并没有太大的不同,这是令人欣慰的。
改进模型的结果
在下面的热图中,您可以看到改进模型的结果。
Results of the improved model
该模型明确显示了一些有趣的结果。有些非常符合预期和“常识”。
该模型表明,人们在“志同道合”的政党之间改变主意。这方面的一些例子:
- PVDA、格罗恩和 SP-A(都是左翼政党)主要是相互失去选票。
- NV-A 只输给了另一个右翼政党(Vlaams Belang)
一些观察结果出乎意料:
- 22%的七党联盟投票者,改变了他们对 OpenVLD(左翼转右翼)的看法
- Vlaams Belang(一个相当极端的右翼政党)输给了一个相当极端的左翼政党(PVDA)10%的选票
- OpenVLD(一个右翼政党)的选票输给了几乎所有政党(除了最极端的左翼政党)
表演
为了比较模型,(甚至为了训练模型),我需要选择一个“性能度量”。
一个很好的例子是“所有地区的错误预测票数”。
如果我在以下型号上使用此指标:
- 初始线性回归模型: 9.9%错误预测选票
- 改进后的模型: 13.5%误预测票
- 基于投票的模型。我很幸运地找到了来自代表组织的一份研究报告,代表组织是一个由比利时五所大学的政治学家组成的联盟,描述了他们对选举结果进行的一次民意调查。使用他们的投票结果导致 18.9 %的选票被错误预测。
从这些绩效得分中观察到的一些情况:
- 约束模型的表现比“初始线性回归”差(如预期的)。
- 我很高兴地看到,我的模型比大学进行的民意调查表现得更好。这表明这种方法可能优于选举后投票。
可能的后续步骤
目前的模型只有有限的可用信息作为决策的基础。它使用的唯一数据点是:“一个人在 2014 年投票给了哪个政党?”。
因此,它必须认为所有在 2014 年投票给同一政党的人都是平等的。这当然是非常粗糙的简化。人们可以想象,在 2014 年投票给某个政党的人,有不同的背景和理由这样做。这些不同的原因可能会导致 2019 年选举中的不同行为。
如果我们希望模型能够做出类似于“Y 党失去了 X 党的大量富裕选民,同时重新获得了大量老年选民”的预测,我们需要对模型进行改进。为模型添加每个地区的财富分布、城市化或年龄分布信息,可能会释放这种潜力。
提高模型性能的另一种方法是改进训练数据,这种方法很容易实现。运行分析后,我发现选举结果也可以在更细粒度的级别上获得(称为“Gemeente”)。对这个更丰富的数据集重新运行相同的分析应该会产生更准确的结果。这也将使我能够纳入更多的政党,而不仅仅是最大的政党。
结论
使用相当简单的机器学习技术,绝对有可能获得一些关于选举结果的有趣见解。它比一个政治科学家财团进行的民意调查(样本规模为 3400 人)更好地解释了 2019 年的结果。
有足够的机会来改进模型或对该数据集执行不同的分析。
但最重要的是:下次当你怀疑你的投票是否会有所不同时,要知道你至少会成为线性回归的一部分;-)
使用深度学习分析乳腺癌
用于检测乳腺癌的过程非常耗时,小的恶性肿瘤区域可能会被遗漏。
为了检测癌症,将组织切片放在载玻片上。然后,病理学家在显微镜下检查这张载玻片,目视扫描没有癌症的大区域,以便最终找到恶性区域。由于这些载玻片现在可以数字化,计算机视觉可以用来加快病理学家的工作流程,并提供诊断支持。
一些术语
组织病理学
这包括在显微镜下检查玻璃组织切片,看是否存在疾病。在这种情况下,这将是检查淋巴结的组织样本,以检测乳腺癌。
整个载玻片图像(WSI)
用扫描仪拍摄的载玻片的数字化高分辨率图像。这些图像的大小可能有几千兆字节。因此,为了让它们用于机器学习,这些数字图像被切割成小块。
小块
小块是图像的一小块,通常为矩形。例如,一个 50×50 的小块是一个包含 2500 个像素的正方形小块,取自一个更大的图像,比如 1000×1000 个像素。
淋巴结是一个小豆状结构,是人体免疫系统的一部分。淋巴结过滤通过淋巴液的物质。它们含有淋巴细胞(白细胞),帮助身体对抗感染和疾病。
前哨淋巴结
在肿瘤附近注射蓝色染料和/或放射性示踪剂。这种注射物质到达的第一个淋巴结称为前哨淋巴结。我们将使用的图像是取自前哨淋巴结的所有组织样本。
转移
癌细胞扩散到身体新的区域,通常通过淋巴系统或血液。
数据
浸润性导管癌(IDC)是所有乳腺癌中最常见的亚型。几乎 80%确诊的乳腺癌都是这种亚型。这个 kaggle 数据集由 277,524 个大小为 50 x 50 的小块组成(198,738 个 IDC 阴性,78,786 个 IDC 阳性),这些小块是从 162 个以 40 倍扫描的乳腺癌(BCa)标本的整块载玻片图像中提取的。每个补片的文件名格式为:u_xX_yY_classC.png(例如,10253 _ idx 5 _ X 1351 _ Y 1101 _ class 0 . png),其中 u 为患者 ID (10253_idx5),X 为该补片裁剪位置的 X 坐标,Y 为该补片裁剪位置的 Y 坐标,C 表示类别,其中 0 为非 IDC,1 为 IDC。
下载和准备数据
首先,我们需要下载数据集并解压。这些图像将保存在“IDC_regular_ps50_idx5”文件夹中。每 279 名患者都有一个文件夹。患者文件夹包含 2 个子文件夹:文件夹“0”包含非 IDC 补丁,文件夹“1”包含相应患者的 IDC 图像补丁。
IDC dataset structure
50x50 图像补丁看起来像这样:
IDC images
现在,我们需要将所有患者的所有 IDC 图像放入一个文件夹,并将所有非 IDC 图像放入另一个文件夹。可以手动完成,但是我们编写了一个简短的 python 脚本来完成:
**import** os
**from** shutil **import** copyfile src_folder = 'IDC_regular_ps50_idx5'
dst_folder = 'train' os.mkdir(os.path.join(dst_folder, '0')) os.mkdir(os.path.join(dst_folder, '1')) folders = os.listdir(src_folder)
**for** f **in** folders:
f_path = os.path.join(src_folder, f)
**for** cl **in** os.listdir(f_path):
cl_path = os.path.join(f_path, cl)
**for** img **in** os.listdir(cl_path):
copyfile(os.path.join(cl_path, img), os.path.join(dst_folder, cl, img))
结果将如下所示。我们可以把它作为我们的训练数据。
然后,我们将 10%的训练图像放入一个单独的文件夹中,用于测试。为此,我们创建一个“test”文件夹,并执行以下 python 脚本:
**import** numpy **as** np
**import** os
**from** shutil **import** movesrc_folder = 'train'
dst_folder = 'test'
test_ratio = 0.1 os.mkdir(os.path.join(dst_folder, '0')) os.mkdir(os.path.join(dst_folder, '1')) **for** cl **in** os.listdir(src_folder):
class_path = os.path.join(src_folder, cl)
class_images = os.listdir(class_path)
n_test_images = int(test_ratio*len(class_images))
np.random.shuffle(class_images)
**for** img **in** class_images[:n_test_images]:
move(os.path.join(class_path, img), os.path.join(dst_folder, cl, img))
安装机器学习工具
我们将使用 Intelec AI 创建一个图像分类器。你可以从这里免费下载并安装。
训练图像分类器
Intelec AI 为图像分类提供了 2 种不同的训练器。第一个是简单图像分类器,它使用浅层卷积神经网络(CNN)。训练速度很快,但是最终的准确度可能没有另一个更深层次的 CNN 那么高。第二个是深度图像分类器,训练时间更长,但准确率更高。
首先,我们使用简单的图像分类器创建了一个训练,并开始它:
Train a simple image classifier
培训总结如下:
Training summary on test data
测试集准确率为 80%。对于一个小车型来说也算是不错的成绩了。但是我们可以做得更好。因此我们尝试了“深度图像分类器”,看看我们是否能训练出更准确的模型。
Train a deep CNN for image classification
我们得到了更好的测试集准确性:
Deep CNN training summary
我们能够通过训练更深层次的网络来提高模型的准确性。添加更多的训练数据也可能提高准确性。
专家对计算病理学有什么看法?
计算病理学副教授、2016 年和 2017 年非常成功的camelion grand challenges的协调员耶鲁安·范德拉克教授认为,计算方法将在病理学的未来发挥重要作用。
在下一个视频中,诺丁汉大学的癌症病理学教授伊恩·埃利斯,他无法想象没有计算方法的病理学:
感谢
使用的来源:
用历史数据分析优秀运动员的跑步成绩
1960 Olympic marathon (credit)
简介
每个级别的跑步者都努力提高自己的成绩。无论是旨在创造新的个人最好成绩的业余选手,还是志在赢得重大比赛的精英运动员,他们都面临着同一个问题:我如何跑得更快?
这是一个引人入胜的问题,直觉上我们可以预期答案是一个复杂的因素混合物。这一分析试图通过检查关于优秀跑步者表现的历史数据来为这一讨论做出贡献。具体而言,它解决了以下问题:
- 历史上,优秀跑步运动员的表现是如何变化的?
- 奥运选手的特征(身高、体重、年龄、体重指数(身体质量指数))在历史上有什么变化?
- 奥运跑者的特质和成绩有关系吗?
数据
数据集可以在 Kaggle 上获得,数据清理和分析的完整过程可以在 GitHub 上找到——参见下面的参考文献部分。值得注意的是,数据的一个局限性是性别失衡——男子比赛的数据比女子比赛的数据多。这是因为直到最近,女性才被允许参加所有现代奥林匹克距离的比赛。然而,通常有足够的数据来得出结论。
分析和调查结果
性能有所提高
绘制特定事件中最佳表现(指比赛中的完成时间)与日期的图表显示,历史上表现有显著改善。图 1 中的图表(来自参考文献[4])显示了一个例子:男子 200 米的成绩在 117 年间提高了近 20%。
Figure 1: Graph showing the improvement in men’s 200 m performances over time
不仅仅是 200 米的成绩有所提高,所有项目的男女运动员都有所提高。人们很自然会想是什么因素导致了这种情况。
运动员已经适应
一个原因是现代运动员与奥运会早期的运动员有很大不同。图 2 [4]是一个例子,显示了几个奥运会径赛项目中女运动员平均年龄的变化。很明显,平均年龄增加了,男运动员也有同样的趋势。这可能是成绩提高的一个因素:运动员在达到巅峰之前花更多的时间训练,这使得他们的成绩更好。
Figure 2: Graph showing the increase in mean age of female track athletes over time
年龄的变化只是运动员特征的几个变化之一。例如,短跑运动员的平均体重指数(身体质量指数)在历史上一直在增加,而长跑运动员的平均体重指数却在下降。这显示在图 3 [4]中。这是有道理的:短距离运动员依靠高身体质量指数产生的爆发性加速度。长距离运动员不需要太多的加速度,而是需要长时间有效工作的能力——低身体质量指数有助于这一点。运动员身体特征的变化证明了他们适应了每个项目的要求,从而取得更好的成绩。
特定项目的运动员有共同的特点
图 3 [4]显示了事件距离和平均身体质量指数之间的明确关系。对于短距离项目,平均体重指数都相对较高;对于长距离项目,平均身体质量指数较低,中距离项目介于两者之间。
Figure 3: Graph showing body mass index of male track athletes
身体质量指数并不是每个事件中围绕一个明显平均值分组的唯一特征:体重、身高和年龄也显示出这种效应。例如,比赛时间越长,运动员的平均年龄就越高。
具有一系列特征的运动员表现出色
每个项目似乎都有一套特定的特征值,一个运动员最有可能表现良好的“甜蜜点”。然而,最好的表现往往来自那些与平均水平有很大差异的运动员。图 4 [4]显示了最好的(意味着最低的)女子 400 米成绩分布在很大的身高值范围内,数据中没有特别的趋势。这也表明内某个特定奥运项目的运动员群体,相对于所有运动员的一般人群,身高和成绩之间没有很强的关系。年龄、体重和身体质量指数也是如此。
Figure 4: Scatter plot showing variation in women’s 400 m times with athlete height
运动员体重是一个重要因素
在所有考虑的特征(身高、体重、年龄、身体质量指数)中,决定成绩最重要的是运动员体重。图 5 [4]显示每个项目的运动员平均体重被很好地分开。特别是,比较长跑运动员和短跑运动员的平均体重:他们相距甚远。具有短跑运动员体重的运动员不太可能成为成功的马拉松运动员,反之亦然。
Figure 5: mean and standard deviation of male athlete’s weights in different events
身体质量指数,作为一个重量的函数,显示了类似的模式。运动员在不同项目中的平均身高比体重更容易重叠。这表明,在特定项目中,身高对表现的影响较小。不同项目的平均年龄有很大的重叠。这表明年龄的影响很小,尽管需要谨慎对待:数据告诉我们关于顶尖运动员的表现,而且他们的年龄范围相当窄。这些数据无法告诉我们年龄对那些年龄明显偏大的老运动员的影响。
运动员和教练的实际应用
这一分析引出了一些有用的见解。
- 为了在某项比赛中取得优异成绩,运动员的身高、体重、年龄和身体质量指数最好接近该项比赛中奥运会运动员的平均值。了解这一点可以影响训练和运动员选择参加的项目。
- 然而,顶级运动员表现出的特征值的范围很广,一些非常优秀的运动员的特征值远离平均值。尤塞恩·博尔特是这种运动员的一个很好的例子——对于一个 100 米短跑运动员来说不寻常的高大和沉重,但却是世界纪录保持者。
- 在所考察的四个特征中,体重对表现的影响最大。这也是一个运动员可以通过训练改变的特征。
结论
我们看到了精英运动员的表现是如何变化的,运动员是如何变化的,并对运动员特征与表现的关系有了一些了解。这项研究只调查了四个特征——身高、体重、年龄和身体质量指数。许多顶级运动员的特征值远低于平均水平,这一事实表明,其他因素肯定对成绩有重大影响。未来研究的一个很好的机会是检查各种因素的影响,如训练计划(如每周跑步距离、举重训练等技术)、饮食和运动员特征(如最大摄氧量)。
参考
使用的数据集是:
- [1]https://www . ka ggle . com/hee soo 37/120-years-of-Olympic-history-sports-and-results
- [2]https://www.kaggle.com/jayrav13/olympic-track-field-results
- [3]https://www.kaggle.com/jguerreiro/running
详细的数据清理和分析,包括本文中的所有图表,可以在这里找到:
致谢
感谢那些创建了这三个数据集(参考文献[1]、[2]、[3])并在 Kaggle 上发布它们的人。
文章顶部的图片来源:维基媒体 Commons,https://Commons . Wikimedia . org/wiki/File:Abebe _ biki la _ 1960 _ Olympics . jpg,来自原始来源:https://Roma . Corriere . it/foto-gallery/cron ACA/14 _ dicembre _ 15/olimpiadi-Roma-1960-4 e5b c10c-8491-11e 4-b9cc-80 d61e 8955
使用 Kibana 和 Elasticsearch 分析蜜罐数据
oneypots 是一个有趣的数据来源,应该用来加强商业网络战略。一些公司已经部署了镜像一些核心服务的蜜罐,只是为了监控黑客正在进行何种攻击,而其他公司正在使用蜜罐来丰富其他系统并建立系统规则*(即,如果 IP 出现在我们的蜜罐数据中,在我们的防火墙上拦截)*。然而,对于学生来说,使用蜜罐数据来了解真实的网络攻击可能是进入日志分析、机器学习和威胁情报的 f̵u̵n̵好方法。我最近发表了一篇关于如何使用 Elastic Stack (Elasticsearch,Logstash & Kibana) 部署蜜罐的帖子,在两周的时间里,蜜罐已经在 GCP(谷歌云平台)——欧盟地区上线,在这篇帖子中,我们将了解它所遭受的所有攻击,威胁者是谁,以及我们如何利用这些数据。
蜜罐下面是什么?
- Debian 10 ( Buster ) — 2 个 vCPUs,9GB RAM & 40GB 存储。
- 蜜罐—T-Mobile 的 Tpot
- Elastic Stack: Elasticsearch,Logstash & Kibana 版本 6.4 (D̳o̳c̳k̳e̳r̳s̳)
T-Pot 是用于此分析的一个很好的部署,因为它包括从电子邮件服务器到 RDP 服务器的 15 个不同的蜜罐系统,这确保了我可以获得足够大的数据池。
运行在 T-Pot 中的蜜罐的完整列表:
由于数据是在 Elasticsearch 中收集的,仪表盘是可用的,但我也可以构建自己的仪表盘来更好地理解数据。如果你以前从未设置过 Elasticsearch 集群,我推荐你阅读并尝试一下 Digital Ocean 关于设置 Elastic Stack 的教程。
弹性集群分析📉
由于这是一个运行 6.8.2 版本的单节点设置,我们无法访问机器学习(需要黄金/白金许可证,但有 30 天的试用期,您可以试用一些功能,或者可以试用 2 周的弹性云)。但是,我们确实使用了第三方工具 Elasticsearch Head ,它为我们提供了集群运行情况的概述。
The Elastic Cluster
那么,这一切的意义何在?
**威胁情报是简单的答案。威胁情报(Threat intelligence)或网络威胁英特尔(cyber threat intel)简称(看起来更长)被描述为,“一个组织用来了解 已经、将要或当前 针对该组织的威胁的信息。”使用这个标准定义和我们的蜜罐数据,我们可以看到我们有一个关于正在进行的攻击、谁在进行攻击以及他们针对什么端口的数据池。这些数据可用于生成英特尔报告,这些报告可输入到 SOAR 系统或用于生成报告。知道谁是持久的攻击者也会帮助你抵御他们的攻击,你对敌人了解得越多越好,对吗?对于 EWS(预警系统)来说,什么是更好的数据源?
翱翔?
安全协调、自动化和响应正在成为事件响应和管理 SIEM 平台的重要组成部分。比如 Splunk 的用户会对 Phantom 比较熟悉。一个很好的有社区版的 SOAR 平台是德米斯图拉。可以将数据从您的蜜罐弹性集群直接馈送到连接到 SIEM 的 SOAR 平台。您可以将其用作事件的丰富工具,或者搜寻零日攻击。蜜罐给你的是持续不断的“真实”攻击和恶意行为者,随着你走向自动化决策,访问真实的威胁数据将有助于丰富你的威胁情报。
最后但同样重要的是,数据!📊
正在考虑构建一个数据湖?数据越多越好,对吗?即使你是一个渗透测试人员,想要更新你的密码列表,拥有一个收集最新用户名和密码组合的蜜罐意味着如果有任何数据泄漏和凭据被使用,你的蜜罐将让你访问数据。
Shout out to everyone still using admin/admin credentials!
让我们打开蜜罐吧!🍯
由于部署的系统已经运行了一段时间,我想看看已经发生的攻击,并调查一些恶意威胁行为者。由于数据在 Elasticsearch 中,可以通过 Kibana 查看,我们不需要抓取任何日志文件,这本身就是一个胜利。
最常见的攻击是什么?
The Cowrie honeypot had over 100k attacks!
Telnet 和 SSH 蜜罐受到的攻击最多也就不足为奇了。Cowrie 是一个中高交互蜜罐,旨在吸引和记录攻击者的暴力攻击和任何外壳交互。它的主要目的是与攻击者互动,同时监控他们在认为自己已经入侵系统时的行为。你可以在这里阅读更多关于 T2 的内容。
毫不奇怪,在 102,787 起攻击中, 32,607 起 攻击来自中国,美国以适度的 14,115 攻击位居第二。
Top 10 Attacking nations
*Cowrie 标记任何已知的攻击者、大规模扫描仪、不良信誉攻击者、垃圾邮件机器人和 tor 出口节点,在 102,787*99.95%的攻击中,这些都是已知的攻击者,之前已经报告过恶意活动。我决定调查攻击蜜罐最多的 IP(你好,128.199.235.18🙃)并使用 AbuseIPDB 我们可以看到,该 IP 因各种恶意活动已被报告超过 928 次。
This server is hosted on Digital Ocean (I notified them)
但是他们登录后会做什么呢?
Top 10 attacker input
了解攻击者在获得访问权限后正在做什么是构建防御的关键。并非所有攻击都来自来自未知 IP 的未知用户。对于大多数 SIEMs,如果用户使用任何列出的命令,都有可能触发警报。这样,如果您网络上的用户丢失了他们的凭证,如果使用了其中的任何命令,您可以将其标记为可疑行为,并设置规则来阻止帐户,直到确认这不是违规行为。
注意:不要阻塞’ top '命令,我们仍然需要它!😭
并不总是通常的嫌疑人!
A map where all the attacks have come from
网络攻击不仅仅是四大(俄罗斯、中国、美国和伊朗)。对于安全团队来说,理解这一点是制定策略的关键。定期检查您的服务在哪里被访问/攻击也有助于确定是否有任何内部破坏正在进行。
这篇文章的主要目的是向网络安全爱好者介绍蜜罐背后发生的事情,数据以及你可以用它做什么。如果您对部署自己的蜜罐感兴趣,可以看看我的教程,了解如何设置我使用的部署。然而,我确实注意到,一些蜜罐码头工人在一次小的暴力攻击后一直在敲门,我单独设置了一个弹性集群来监控服务器,看它是否受到攻击,事实确实如此。我的下一篇文章将介绍如何使用最新版本的 Elastic 来使用 SIEM 功能监控一些测试环境。我还计划清理蜜罐,并单独部署它们以进行更好的分析,并利用来自 Elastic 的机器学习。
RDPY Attacks — Not all data has to be on Excel!
斯蒂芬·查彭达玛
分析空间和时间上的运动数据
时间序列和数据驱动的时空动画,包含 33 只鸟(金雕),历时十年。
空间和时间上的运动数据提供了关于所研究的物体,即车辆、人和动物的行为的关键信息。
对空间和时间运动的洞察推动了许多人类和生态研究。这些研究有助于深入分析和理解复杂的过程,如动物和人类的迁移、森林火灾和自然灾害以及流动性和运输。
Somayeh Dodge, A Data Science Framework for Movement
由于数据科学、人工智能和跟踪设备,科学家现在可以研究、模拟和预测鸟类。此外,他们可以了解自己的迁移模式、迁移原因、迁移目的地以及许多其他关键问题。
在本文中,我使用来自 Movebank 的数据集进行了深入的时空分析。数据集由北美西部 10 年来 33 只鸟(金雕)的轨迹组成。
探索性数据分析
我们像往常一样用熊猫读数据。
df = pd.read_csv(“goldenEagles_dataset.csv”)
df.head()
该数据由时间戳、纬度和经度列以及鸟的个人本地标识符组成。
让我们计算出每只鸟有多少行,并用 Seaborn 绘制出来。
fig, ax = plt.subplots(1, figsize=(14,12))
sns.countplot(y=’individual-local-identifier’, data=df);
Countplot
大多数鸟都有超过 500 分,但是我们也有超过 1000 分的鸟。低于 100 分的鸟可能是由于死亡或追踪器的技术问题。
让我们用简单的一行代码创建一个点的 Plotly Express 地图。
px.scatter_mapbox(df, lat=’location-lat’, lon=’location-long’, zoom=2, width=900, height=800)
Plotly Express 是 Plotly 的高级 API。有些人甚至把 Plotly Express 比作 Seaborn 之于 Matplotlib。从下面的地图可以看出,鸟类的飞行轨迹大多是墨西哥和北美的狭窄走廊。接下来我们将更深入地分析,但是现在,一些异常值需要我们注意——海洋中的那些点和东部的其他一些点是异常值。
数据集具有来自算法标记以及手动标记的离群值列。我们可以根据纬度和经度进行排除,但由于数据集中有标记异常值,我们从数据帧中过滤掉这些标记异常值。
# Filter out outliers
df= df[(df[‘algorithm-marked-outlier’].isnull())&(df[‘manually-marked-outlier’].isnull())]# Plot scatter map with Plotly Express
px.scatter_mapbox(df, lat=’location-lat’, lon=’location-long’, zoom=2, width=900, height=800)
如下所示,这是我们去除异常值后的曲线图。
最后,对于我们的探索性数据分析,我们参考数据集附带的参考表来了解这些鸟的附加属性。
ref_df = pd.read_csv(“reference_table.csv”)
ref_df.head()
下表显示了引用表的一些列。我们这里有一些有价值的栏目,可以揭示这种鸟的特征,即性别、产地、生命阶段和部署日期。
Reference table
这是这张桌子的一些引人注目的图像。
fig, ax = plt.subplots(2,2, figsize=(18,12))
sns.countplot(ref_df[‘animal-sex’], ax= ax[0,0])
sns.countplot(ref_df[‘animal-life-stage’], ax= ax[0,1])
sns.countplot(ref_df[‘study-site’], ax= ax[1,0])
sns.countplot(ref_df[‘age’], ax= ax[1,1])
plt.tight_layout()
plt.show()
下图显示了某些特征的计数图。左上角显示了雌鸟和雄鸟的分布——大多数鸟碰巧都是雄性。右上是部署开始时动物的年龄等级或生命阶段。左下显示了最初的研究地点,而右下是鸟类的年龄分布
Counplots
此外,在追踪这些分类特征的过程中,我们可以将鸟的年龄联系起来。比如我们可以看到学习地点和年龄的关系。
sns.catplot(x=”age”, y=’study-site’, kind=”boxen”, orient=”h”, height=8, aspect=10/8, data=ref_df);
现在,我们对数据集有了更好的理解,让我们进入动画和分析运动数据。然而,在此之前,我们将引用表合并到我们的数据框架中。
df_merged = pd.merge(df, ref, left_on=”individual-local-identifier”, right_on=”animal-id”)
这些鸟迁徙到哪里?什么时候?
让我们为数据帧创建一些时间戳。
df_merged['month'] = pd.DatetimeIndex(df_merged['timestamp']).month
df_merged['month_year'] = pd.to_datetime(df_merged['timestamp']).dt.to_period('M')
df_merged['quarter_year'] = pd.to_datetime(df_merged['timestamp']).dt.to_period('Q')
df_merged['quarter'] = df_merged['quarter_year'].astype(str).str[-2:]
df_merged['month_year_st'] = df_merged["month_year"].dt.strftime('%Y-%m')
上面显示的地图很拥挤,并且没有提供太多关于它们何时何地迁移的信息。这就是动画发挥重要作用的地方。
让我们首先为一年中的每个月(从 1999 年到 2009 年)制作鸟的动画。
px.scatter_mapbox(df,
lat=’location-lat’,
lon=’location-long’,
color= ‘individual-local-identifier’,
animation_frame=”month_year”,
zoom=2
).update(layout={“mapbox”:{“style”: “satellite-streets”}})
下面的 GIF 展示了数据集十年来每个月每只鸟的动画。
更好的洞察力,但不是那么细粒度的运动洞察力,因为这显示了一年中所有月份的顺序。然而,你可以看到这些鸟往返于墨西哥、美国和加拿大的所有动向。我们还可以将所有数据汇总到一年的各个季度,并制作动画,看看是否有什么模式。
px.scatter_mapbox(df_merged,
lat=’location-lat’,
lon=’location-long’,
color= ‘study-site’,
animation_frame=str(‘quarter’),
zoom=2,
)
此外,这是基于季度的动画的 GIF。
这一较高的总量显示了一种更好的模式。在 Q1,几乎所有的鸟都在美国境内,只有少数在加拿大。相反 Q3,没有一只鸟在墨西哥。
结论
在本教程中,我们已经看到了如何通过使用 Panda 和 Plotly 库制作鸟类迁徙动画来获得洞察力。本文的代码可以从 Github 获得。
[## shaka som/运动
空间和时间中的运动数据提供了关于所研究物体(即车辆)行为的重要信息
github.com](https://github.com/shakasom/movement)
要直接体验本教程,请通过以下链接使用 Binder,无需任何安装。
单击运行此交互式环境。来自活页夹项目:可复制、可共享、交互式计算…
mybinder.org](https://mybinder.org/v2/gh/shakasom/movement/master)
使用 Python 和 Jupyter 笔记本分析调查数据
笔记本环境非常适合处理调查数据的特殊性质
调查是数据世界的变形虫。不是因为它们会吃掉你的大脑(反正不是字面上的意思),而是因为它们的形状和结构一直在变化。
即使是那些旨在保持不变的调查——定期追踪我们对从政客到马桶刷等一切事物的感受的研究——也在不断变化。客户以他们可爱的创造力,抛弃问题,发明新的问题,并想出无穷无尽的新聚合来执行结果。
在本文中,我们将展示为什么 Jupyter 笔记本,一个交互式脚本和故事讲述环境,与 python 库 Quantipy 相结合,是驯服食脑者并使他们屈从于我们意愿的完美工具集。
A screenshot of a Jupyter Lab setup optimised for analysing survey data with the Python open source library Quantipy. The window on the right shows a list of all the variables in the data for quick lookup.
从 SPSS(或 CSV 或 ddfs)导入数据
调查数据通常一方面存储为数据,另一方面存储为元数据。在 SPSS 中,用户可以查看数据(在下图的左侧)或变量信息,即元数据(在图像的右侧)。
SPSS splits the data and the variable information (the metadata) into two seperate views. The open source python library Quantipy can read SPSS and other survey specific file types and remove the pain of mapping the numeric results in the data to human readable labels.
开箱即用,python 并不擅长处理丰富的调查元数据,其主要用途是处理结构简单得多的事务性数据。这意味着,在我们使用标准 python 库运行计算之后,我们必须将元数据中的变量标签映射到我们的结果上(清楚地表明,在我们的输出中,相对于“1”的百分比数字实际上是指“男性”)。这在处理 python 无法理解的专有数据格式(如 Unicom Intelligence 的 ddf/mdd 文件)时变得更加棘手。
但是,Quantipy 为 SPSS 和 Unicom Intelligence(以前称为 Dimensions)文件提供现成的阅读器,并将数据和元数据转换为 pandas 数据框架和自己的元数据模式。
快速浏览结果
我们首先命名并创建一个数据集(数据集就是数据和元数据的组合):
dataset = qp.DataSet("Customer satisfaction wave 1")
dataset.read_spss("customer_satisfaction.sav")
Quantipy 将响应存储在 dataframe( dataset._data
)中,将元数据存储在 python 字典(dataset._meta
)中。我们可以通过查看字典的 columns 元素来引用关于特定变量的元数据。
dataset._data.head()
dataset._meta['columns']['gender']
数据部分看起来和在 SPSS 中一样,但是 json 元数据模式是 Quantipy 独有的。它支持多种语言和各种类型的变量(列):单选、分隔集和网格。
Quantipy 提供了一个方便的快捷功能,可以通过命令查看元数据
dataset.meta('gender')
那么,让我们看看有多少男性和女性做了顾客满意度调查。
#the pct parameter decides whether we show percentages or the count
dataset.crosstab(“gender”, pct=True)
等等,我们知道只有 59%的顾客是女性,但她们却是调查对象的 64.1%。我们需要权衡我们的变量,这样我们的结果才能真正代表我们的客户群。
对答案进行加权以正确代表总体
我们将使用 Quantipy 的 RIM 加权算法实现(它有其他加权选项),这允许我们使用任意数量的目标变量进行加权。在这种情况下,我们只使用一个;性别。
# Quantipy's Rim class implements the RIM weighting algorithm
scheme = qp.Rim('gender weights')# Men should be 41% and women 59%
scheme.set_targets({'gender':{0: 41, 1: 59}})dataset.weight(scheme,
unique_key='RespondentId',
weight_name="Weight",
inplace=True)
当 Quantipy 运行权重时,它会生成一个权重报告,这允许我们仔细检查权重是否做了任何疯狂的事情。这里的最大重量是 1.14,我们对此很满意。现在,我们的数据集中有了一个新变量,叫做“权重”,我们可以在计算中使用它。
dataset.crosstab(‘gender’, pct=True, w=’Weight’)
现在我们可以看到,我们的客户群中有 41%是男性,这在结果中并没有被低估。
快速可视化我们的结果
我们在 Jupyter 实验室环境中的事实意味着我们可以很容易地看到结果。我们关注价格变量,它显示了客户对定价的满意程度。
dataset.crosstab('price', 'gender', w='Weight', pct=True)
现在让我们想象一下,以便更好地了解结果。为了简洁起见,我们不会深入细节,但是您可以看到使用标准功能来可视化数据是多么容易。
import blender_notebook.plot as plots
plots.barplot(dataset.crosstab('price',
'gender',
w='Weight',
pct=True),
stacked=False)
为未来的项目自动化我们的工作
在 Jupyter 笔记本上工作还有另外一个好处:它让我们的笔记本可以重复使用,从而使我们的工作自动化。基于网飞数据科学团队的想法(参见:B eyond Interactive:网飞笔记本创新),我们之前已经报道过如何自动化数据处理任务,如清理、加权和重新编码以及如何自动化生成 PowerPoint 幻灯片组。这些都是因为我们的工作是在笔记本上完成的。
Jupyter 笔记本正在数据科学界掀起风暴,这一次,调查数据分析不应落后。用笔记本分析调查数据消除了数据处理专业人员和研究人员的全部痛苦,并能对双方的生产力产生奇迹。
Geir Freysson 是 Datasmoothie 的联合创始人,这是一个专门从事调查数据分析和可视化的平台。如果你对使用开源软件进行调查数据分析感兴趣,注册我们的时事通讯,名为自发认知。
分析美国队对澳大利亚队的篮球推文
在 R 中使用 rtweet 和 tidyverse
2019 年 8 月 24 日,澳大利亚男子篮球队 Boomers 创造了历史,他们能够上演自己的大卫和歌利亚时刻,有史以来第一次击败美国队。更令人印象深刻的是,美国队 13 年来从未输过一场比赛。这是澳大利亚篮球历史上的一个奇妙时刻,当美国派出了被广泛认为是他们中较弱的球队之一时,这是一个让我们都回味的时刻。不管结果如何,我们能够让世界上最好的国家参加表演赛,这是值得庆祝的。
事实并非如此…
在漫威体育场历史性的第一场男子篮球赛后,媒体的叙述似乎充满了负面,主要集中在昂贵的座位上,球迷的视野很差。
我怀疑这种情况在任何地方都会发生,但我们澳大利亚人似乎比大多数人更容易让自己的观点摇摆不定——当事情进展不顺利时,我们非常乐意取笑个人或团队,但当事情进展顺利时,我们会迅速转变态度(尼克·克耶高斯打招呼)。
这项分析将着眼于两场比赛前后的 Twitter 活动,试图证明或反驳叙事的变化。
为了收集 tweet 数据,使用了rtweet
和ROAuth
包。blow analysis 收集并分析了 8 月 22 日至 8 月 25 日下午 2 点之间的推文。使用官方标签- #BoomersUSA
引用@BasketballAus
的推文被删除。
这个项目的完整代码库和数据可以在这里找到
如果这条推文是在2019-08-24 04:00:00 UTC
(第二场比赛的提示时间)之后录制的,它将被归类为Game2 Starts
中的推文。这使得我们可以将历史性的第二场比赛之前的推文与神奇之夜期间和之后发生的推文进行比较。
推特分析
查看自第一场比赛以来的所有推文,我们可以看到第二场比赛每小时的推文更多。毫无疑问,令人震惊的结果在其中起了很大的作用。
Tweets per hour peaked during the historic game 2
在 4019 条“收藏夹”中,NBATV 的以下推文是最受欢迎的推文:
感觉棒极了。…我希望我们都能以此为基础。@Patty_Mills 描述了他带领篮球队首次战胜美国队后的心情
在所分析的时间段内,被转发次数最多的推文来自 NBL,有 833 次转发。推文是:
第四节帕蒂·米尔斯是一件艺术品🔥# BoomersUSA @ SBSVICELAND @ SBSOnDemand
使用的 TWEET 单词
在我们可以测量推文的情绪之前,推文字符串需要被分割成“令牌”(或单个单词)。
一旦这些标记被取消嵌套(分离),我们就可以画出最常用的单词。重要的是,停用词和其他我们在分析中不想要的词已经被省略了。停用词包括“and”、“the”、“a”等,这些词对情感分析没有太大帮助。此外,“BoomersUSA”被删除了,因为这是游戏的标签,几乎在所有的推文中都会提到。
下面列出了第二场比赛前后推特上最常用的 20 个词。
不出所料,“座椅”、“塑料”、“座椅”是第二场比赛开始前推特中频繁出现的词汇,而第二场比赛开始后推特中只出现了“座椅”。对于第二场比赛开始后的推文,“历史”,“帕蒂·米尔斯”,“真棒”和“爱”都频繁出现在推文中——非常软和糊状嘿?
Not so many seating issues for tweets after game 2 started (left panel)
下面的图表可以让我们更好地了解第二场比赛前后使用的单词之间的差异。贯穿剧情的对角线右下方的单词表示在第二场比赛之前在推特上更频繁使用的单词,而该线上方的单词在第二场比赛期间和之后更频繁使用。
看起来我们终于是快乐的一群了…
推特情感分析
一旦标记被分离,就可以计算情感分数。
将使用的方法是由芬恩·厄普·尼尔森(http://www2.imm.dtu.dk/pubdb/views/publication_details.php?)创建的情感分析常用词典 id=6010 ),称为 AFINN 词典。更积极的词(比如“棒极了”)比更消极的词(比如“崩溃了”)得分更低,前者得分更低。
为了感受情绪分析的力量,下面这条推文是最积极的推文,积极指数为 17:
对婴儿潮一代今天的胜利感到非常激动,帕蒂·米尔斯在关键时刻表现得非常出色。非常棒的团队合作。带来世界杯!#BoomersUSA
在光谱的(完全)另一端,下面的推文是最负面的,得分为-18(抱歉,我已经尽最大努力清除它们):
谁他妈的!&%雇了这些人来组织这次活动,真是愚蠢!&%ing bs stich up。邦宁斯的$椅子有分叉的障碍吗?&%.像 WTF 一样,投资建造体育场的公司肯定没有那么穷。#BoomersUSA
不出意外,最积极的推文是在我们赢了之后,最消极的是在第一场比赛之后。
绘制每条推文的情绪得分分布,我们可以清楚地看到,第二场比赛开始后的推文变得更加积极——这些推文的积极得分中位数(积极词与消极词的比率)为 0.95,是第二场比赛前推文中位数 0.43 的两倍多。
正如我所料,我们在历史性的胜利后变得更加开心…几乎到了忘记座位“崩溃”的地步,尽管第二场比赛是在确切的场地进行的,座位安排也是确切的…非常奇怪。
总有一天,我会将我们澳大利亚人的这一理论进行终极测试,看看我们如何回应基尔吉奥斯的成功……如果他尝到了终极成功的滋味!
本帖原创,发布在不怪数据博客【https://www.dontblamethedata.com】
分析英国退出欧盟的影响:统计方法
了解英国退出欧盟事件如何影响我们周围的世界
Photo by Habib Ayoade on Unsplash
依我拙见,数据科学家的武器库中最强大的武器之一无疑是将统计应用于特定用例的能力,以提取关于相应数据的底层结构的有意义的见解。通过统计建模和分析,数据科学家将能够更好地理解正在研究的领域;从而为进一步的机器学习建模和其他分析打下坚实的基础。因此,鉴于我的背景,我决定加强我的统计能力,这是我所知道的唯一有效的方法——用用例来练习。
随着对英国退出欧盟越来越多的关注,我立即发现这是一个绝佳的实践机会。下面是不同过程、技术和分析的总结。
首先,我想从最重要的英国退出欧盟事件开始,如下图所示。
The Major Brexit Events
获得这些主要数据后,我们就可以着手分析、关联和测试这些英国退出欧盟事件和其他影响之间的潜在因果关系。这一统计分析背后的计划如下:抓取重大事件,分析英镑/欧元汇率、英镑有效汇率指数、英国交易数据、英国消费者价格指数,最后分析对加密货币金融市场的影响。
英镑/欧元汇率
OHLC
从 2014 年 1 月 1 日到 2019 年 6 月 19 日的英镑/欧元历史汇率数据是通过 quantmod R 的软件包从雅虎财经获得的。第一步是按年份分组,以便能够绘制 OHLC 图表,并计算每一年的一些描述性统计指标。
OHLC 图是一种条形图,显示每个时期的开盘价、最高价、最低价和收盘价。OHLC 图表很有用,因为它们显示了一段时间内的四个主要数据点,收盘价被许多交易者认为是最重要的。— 投资媒体
此外,在 OHLC 图表的顶部,还绘制了各种其他统计图表,如布林线(BB)、移动平均线收敛背离(MACD)、变化率(ROC)、随机动量指数(SMI)、相对强弱指数(RSI)、商品通道指数(CCI)、和止损反转(SAR) 。这些图表都提供了对特定时间序列所遵循的趋势的统计洞察。不用说,这些统计工具在金融交易和投资领域被广泛采用。
OHLC charts of the GBP/EUR Exchange Rate along with some other statistical charts.
因果效应
除了分析 OHLC 价格,我还想确定一个特定的事件是否对时间序列有直接的因果影响。经过一番研究,我找到了谷歌发布的这篇论文,它完美地完成了我想要分析的内容。简而言之,本文介绍了一种通过构建贝叶斯结构时间序列模型来确定单个事件因果影响的统计显著性的方法。反过来,这个模型然后被用来预测时间序列可能是什么样子,假设该事件从一开始就没有发生过。然后,基于贝叶斯单侧尾区概率,获得 p 值来说明这种因果影响的统计显著性。
Causal Impact Result Visualisation taken from the package’s Github page.
此外,所提供的软件包还可以生成可视化结果(如下图所示),并能够将统计结果输出为通俗易懂的报告。总之,感谢参与这项研究的每一个人。工作做得非常好!
分析
基于上述设想,2016 年初,英镑相对于欧元的价值遭受重创,英镑/欧元汇率开始下跌。正如布林线(描述波动性)所示,英镑/欧元汇率波动极大,在上下区间波动。然而,在 2016 年 6 月(英国退出欧盟投票)前后,汇率遭受了毁灭性的负面影响,导致不断触及布林波动较低波段。与此一致,MACD 也支持英国退出欧盟投票对汇率产生负面影响的假设。后者主要是因为 MACD 线已跌破信号线,而不是投票前后的时间点,这似乎更符合信号。同样,中华民国路线也支持和暗示英国退出欧盟投票所带来的不利影响的事实。就在 2016 年 7 月开始之前,ROC 线描绘了一个急剧的负尖峰,这强烈表明熊市投资,意味着投资亏损。此外,在构建贝叶斯模型并测试获得这种效果的概率后,获得的 p 值具有统计学意义;因此,这表明英国退出欧盟的投票确实损害了英镑/欧元的汇率。
同样,SMI 也暗示了 2016 年 6 月下旬左右的看跌投资,该信号继续下降到 2016 年 7 月的最终低点-60(投资者通常认为 SMI-40 是高度看跌的趋势)。除此之外,基于 RSI,作为投资的英镑/欧元似乎在 2016 年 6 月下旬极度走软。诚然,蜡烛图以及之前讨论的统计方法似乎在 2016 年 7 月中旬开始企稳,这大约是特里萨·梅(Theresa May)被任命为英国首相的时间。然而,这一事件在统计上可能不会对汇率产生积极影响,因为汇率在今年剩余时间里仍然高度不稳定。这一结论也得到了因果贝叶斯推理模型的支持,该模型得出了一个不显著的 p 值。
进入 2017 年,英镑/欧元外汇收盘价再次持续触及布林带下轨,导致持续高度波动的下行模式,主要是在参考 ROC 图时。今年的第一个重大英国退出欧盟事件发生在 1 月 17 日;因此,大约在那个时候,所有图表都显示汇率收盘价出现了负峰值。CCI 甚至达到了-200 的数值,证明了在那个时候,汇率遭受了坚定的下跌趋势。除此之外,还可以看到 SMI 线已经跌破了均线信号线。此外,当在原始时间序列上绘制 SAR 图时,除了确认 1 月中旬的大幅下跌之外,它还突出了该月剩余时间内收盘价的上涨。同样,这种变动可能与这一汇率表现出的极度波动行为高度相关,因为从贝叶斯模型获得的 p 值未能拒绝具有统计显著性的零假设。CCI 表明 2017 年 3 月下旬左右的看涨趋势(绝佳的投资机会-表明未来收盘价上涨),这可能与里斯本条约第 50 条的触发有关,这也导致了因果推断的统计显著 p 值。在此期间,汇率达到了今年迄今为止的最高值。正如 CCI 所代表的,汇率的下一个令人兴奋的运动将发生在 2017 年 5 月下旬,接近英国大选(6 月 8 日)。
此外,CCI 的分析也潜在地暗示了 6 月初的稳定下降;然而,像 SMI 和 RSI 这样的其他方法在这一天似乎没有受到太大的影响。因此,解释这种行为的一个假设可能是,投资者可能在选举日之前就采取了行动,从而产生了早期效应。为了支持这一结论,2017 年 4 月 18 日举行了一次提前选举,因此,这也是今年最重要的价值下跌的开始,在 8 月底达到最低点。因此,这是一个非常可行的假设,即提前大选的影响主要是在事件本身之前观察到的。接下来,从尾区概率获得的 p 值显示了对汇率的统计上显著的不利影响。
今年的最后一件大事是北爱尔兰无缝边境支持协议(12 月 8 日)。从年底到 2018 年,收盘价似乎再次上涨,这是有道理的,因为支持协议将意味着英国与欧盟保持密切的关系。一致的是,在构建贝叶斯模型之后,p 值也显示出在这一事件之后统计学上显著的值增加。此外,2018 年的表现与前几年非常相似,显示出类似的波动特征,市场数据在布林线之间来回波动。ROC 似乎相当稳定,只有 6 月下旬(负峰值)和 11 月下旬(负峰值)是例外。巧合的是,在此期间,也有两个与英国退出欧盟相关的重大事件,可能引发了极端运动。然而,CCI 圆图在这些时期没有显示出显著的效果,并且 SMI 似乎平滑地跟随信号,然而,发现在影响负面效果方面是显著的(两个 p 值都< 0.05)。
目前,2019 年似乎为英镑/欧元汇率提供了一些稳定性。虽然仍然相当不稳定,但 CCI、SMI 和 RSI 图显示交易中性,尤其是在 2 月和 4 月之间,价值似乎也相对保持在布林线之间。在 1 月 15 日和 3 月 12 日,May 失去了两次必要的投票,这两次投票都导致了所有统计指标的上升趋势,这是基于获得的尾部区域概率 p 值的具有统计意义的结果。此外,英国退出欧盟的初始结束日期(2019 年 4 月 12 日)导致价值下降,后来通过延迟英国退出欧盟的决定重新平衡。令人惊讶的是,乍一看,梅的辞职似乎并没有改变交易所的行为,因为 ROC 图显示当时几乎没有显著的变化率;尽管如此,ROC 图表明,在该特定事件之后,交易所的价格可能会上升(正的 ROC 表明潜在的看涨趋势)。此外,使用贝叶斯模型获得的 p 值表明对英镑/欧元值有显著的不利影响。然而,如上所述,ROC 非常小,并且积极影响的指示也没有得到其他指标的支持。
Analysing the Statistical Significance and Impact (positive or negative) of the Causal Effect on the GBP/EUR per Major Brexit Event.
英镑/欧元投资风险
为了有效地确定构建风险评估的最佳模型,我们必须首先检查正态性、独立性和统计平稳性。
Basic Descriptive Statistics for the GBP/EUR Exchange per year.
首先,对组成时间序列的描述性统计数据进行一些分析对于开始理解这些数据的基本结构是必不可少的。2016 年是方差最大、负偏差最大、对数收益峰值最高(峰度较高)且均值最低(也是负值)的一年。计算归一化的对数回归,并绘制成折线图和直方图,以便更好地理解回归的密度,同时还绘制了一些描述性统计数据,如下所示。
Descriptive Statistics Plots for GBP/EUR Closing Log Returns per year.
此外,如下所示,对数回归时间序列通过降低其幅度进行了清理,然后绘制在原始对数回归时间序列上,这有助于提供一些关于潜在异常值的见解。
Outlier Detection for the Closing Log Returns of the GBP/EUR
此外,还创建了每年对数收益的分位数-分位数(Q-Q)图。很明显,Q-Q 图显示了一些偏离正态分布的情况,表明这个时间序列并不遵循高斯分布。为了进一步检查正态性,进行了两个统计测试——Jarque-Bera 测试(对整个时间序列执行)和夏皮罗-维尔克测试(每年子集)。对于这两种检验,零假设表示数据确实来自正态分布。Jarque-Bera 测试得出 p 值< 0.05;因此,拒绝了零假设,并确认了从 Q-Q 图得出的结论。
此外,对数据子集(每年)运行夏皮罗-维尔克检验,得出 2014 年、2016 年、2018 年和 2019 年的 p 值< 0.05,这进而拒绝了正态性的零假设。此外,在其他年份,测试未能拒绝零假设。尽管如此,鉴于股票市场数据不遵循正态分布的已知性质,假设这些年也不遵循正态分布。这个假设也是基于这样一个事实,即整个数据集上的 Jarque-Bera 测试返回了一个显著的 p 值。为了检验时间序列的独立性,使用了永盒检验。该测试获得了一个不显著的 p 值;因此,不能拒绝自相关的零假设。基于这个测试,然后假设这个时间序列没有任何自相关。最后,使用扩展的 Dickey-Fuller 检验来检验平稳性,其返回了拒绝单位根的零假设的显著 p 值。基于这些统计检验,构建了 AR 和 MA 值为 0 的 ARIMA 模型。通过构建扩展的自相关和互相关函数(EACF)来选择这些值。使用 ARCH 的拉格朗日乘数(LM)检验对 ARIMA 模型的残差进行了检验。该测试返回的 p 值是显著的;因此,表明 ARIMA 模型的残差中存在 ARCH 效应。由于没有 ARCH 效应的零假设被拒绝,该时间序列然后由 GARCH 模型建模。
在拟合时,模型的拟合优度使用调整后的皮尔逊检验进行测试,结果发现残差之间没有相关性。拟合优度也使用 Box-Ljung 检验进行了测试,该检验未能拒绝零假设。因此,基于这两个结果,该模型被认为是一个很好的拟合。
此外,如侧图所示,绘制了自相关函数(ACF)和偏自相关函数(PACF)、Q-Q 图和标准化残差的经验密度,以进一步总结拟合模型。使用拟合的 GARCH 模型,绘制了对数收益波动率,如下所示。
Volatility plots of the GBP/EUR exchange based on the GARCH Model
最终,使用 GARCH 模型和蒙特卡洛模拟,计算出未来 20 个交易日的投资风险,结果是-2.784%,显著性水平为 0.05。因此,该风险分析表明,英镑/欧元汇率高度波动且不可预测,任何外汇投资都可能导致不良结果。
英镑有效汇率指数
作为有效模拟英镑汇率强度的尝试,英镑有效汇率指数的历史数据以. csv 文件的形式从英国国家统计局获得。然后将指数时间序列可视化,并在图上添加代表主要英国退出欧盟事件的标记。该图的强大之处在于能够进一步支持前面讨论的因果推断分析,并且能够有效地将欧元的类似兑换行为映射到其他货币。
英国贸易数据
分析英国进出口贸易数据的目的是为了了解英镑汇率的实际波动,以及英国退出欧盟以外的外部事件对英镑汇率的影响。与前一小节类似,对这一方面进行的主要分析集中在按国家显示进出口数据的流动。通过使用垂直线标记,每个标记代表一个特定的英国退出欧盟事件,可以估计对单个国家的价值的影响。从结果来看,英国退出欧盟事件和各自与欧盟国家的进口关系之间似乎没有关联。然而,德国似乎是一个例外,在英国退出欧盟发生重大事件后,德国的进出口似乎都出现了变化。诚然,这一特征可以用不断增长的物质市场和人口来解释,这反过来会导致更多的进口和出口。
另一方面,英国退出欧盟事件后,来自/非欧盟国家的进出口似乎受到很大影响。无论是进口还是出口,数量似乎都会在特定事件发生后立即激增,这表明了直接的因果关系和影响。这种行为在中国、挪威和美国尤其明显。因此,根据这一分析,可以假设英国退出欧盟事件对英镑汇率指数有很大影响;然而,进一步的假设检验将有助于接受这一基于统计学意义的观察结果。
UK Trading Data filtered by the top EU and non-EU Countries.
英国消费者价格指数
这部分分析是为了更好地理解英国退出欧盟事件如何影响英国的生活质量。选定数量的消费物价指数(从英国国家统计局获得)的原始时间序列数据被绘制出来,通货膨胀百分比也是根据这些数据计算出来的。虽然所有被调查的消费物价指数都受到通货膨胀持续上升的影响,但似乎没有明显的迹象表明这些指数受到英国退出欧盟事件的深刻影响。尽管如此,值得一提的是,从英国退出欧盟交易开始(2016 年 6 月),英国公民的平均生活成本上升了 6.362%。同样,这种差异可能被认为是不属于本分析项目调查范围的其他事件。
UK Inflation for a number of CPI’s.
加密货币金融市场
Top 10 Cryptocurrencies by Market Cap.
如上图所示,目前市值排名前 5 的加密货币分别是比特币、以太坊、Ripple (XRP)、莱特币、比特币现金。因此,这五种加密货币在一些英国退出欧盟事件后的表现也进行了分析。从比特币开始,英国退出欧盟似乎对其价值产生了积极影响。
在每一次重大的英国退出欧盟事件之后,比特币的价格都会上涨。在使用贝叶斯推理对时间序列进行建模后,突然大选和支持交易的因果影响概率为 0.9998,尾部概率为 0.0002。因此,根据构建的贝叶斯模型,英国退出欧盟事件对比特币价值的明确提升具有统计学意义。
同样,以太坊在后台交易会议后的价格上涨也导致了统计上的显著性。以以太坊为例,在’ lost '标记处,事件发生后价格似乎会下跌;我们还对这种潜在的因果关系进行了调查,得出了一个不显著的结果,该结果可以解释为基于英国退出欧盟以外其他不同事件的随机波动。英国退出欧盟事件似乎也没有影响莱特币的走势,使其流通在整个时期相对稳定。然而,也有人指出,在背景会议后的一段时间内进行的测试导致 p 值<为 0.05,这使得莱特币在统计上具有显著的正面因果影响,约为+150%。比特币现金也受益于显著的积极影响,有时收益高达 100%。同样,Ripple 似乎也受到了这些英国退出欧盟事件的积极影响;然而,在这种情况下,涨幅只有 10%左右。
总结
总之,该分析彻底调查了英国退出欧盟事件如何影响英镑/欧元外汇指数以及加密货币金融市场。除此之外,作为分析的一部分,英镑有效汇率指数也进行了研究,以更好地了解英镑在整个外汇市场的实际实力。这种分析允许将使用英镑/欧元兑换调查的结果复制到英镑兑换的其他货币,从而允许进行更全面的分析。此外,该项目还考虑了英国进出口贸易数据方面,其中主要国家(欧盟和非欧盟)的贸易量以及英国的通货膨胀率都进行了检查。这一方面为关于英国退出欧盟事件和 GBP 事件之间的相关性和因果关系推论的评论提供了更确凿的证据。这一部分有助于确定英镑的升值或贬值是直接受到英国退出欧盟的影响,还是受到其他外部因素的影响,如进出口贸易的下降/上升。
此外,该分析还提供了一个额外的分析视角,即英国退出欧盟是否对英国的进出口货物贸易有任何影响。反过来,这个项目在建立统计知识和应用于现实世界的基础方面具有很高的价值,并成为真正展示适当的统计分析和建模的好处的一种方式。此外,尽管这一分析面临一些限制,如没有考虑其他股票市场,特别是欧盟内部的股票市场,或者未能从统计上证明对英国进出口贸易的重大影响,但这一分析仍然设法得出了相对可靠和结论性的结果。
扩展这项工作
- 考虑其他金融市场,如富时 100 指数、标准普尔 500 指数和道琼斯工业平均指数。
- 通过纳入其他国家的贸易数据,对比变化率,对进出口贸易数据进行更深入的统计分析。
- 分析英国退出欧盟对汇丰银行、劳埃德银行和巴克莱银行等英国公司的影响。
- 分析英国退出欧盟对英国和欧盟失业率的影响。
这个项目的更多信息和完整源代码可以在这个 GitHub 资源库中找到。
如果你想联系——davidfarrugia53@gmail.com
熊猫艺术调查分析
熊猫 是用于数据科学的 Python 开源库,它允许我们轻松地处理结构化数据,如 csv 文件、 SQL 表或 Excel 电子表格。在这篇文章中,我们用熊猫来分析布拉迪斯拉发的夸美纽斯大学统计学学生进行的艺术调查的结果。学生们被要求从 1 到 5(意思是 1“一点也不喜欢”)给 39 幅知名画作打分。该数据集包括评级,以及绘画、艺术运动和艺术家的名称,每个艺术运动包含 3 幅绘画。数据集可以在中找到。 Kaggle 是一个数据科学家和机器学习者的在线社区,其中包含了各种各样的数据集**。**
学生评价不同艺术运动的名画。
www.kaggle.com](https://www.kaggle.com/miroslavsabo/paintings)
探索性数据分析和数据清理
探索性数据分析包括分析数据集的主要特征,通常采用可视化方法和汇总统计。目标是理解数据,发现模式和异常,并在我们执行进一步评估之前检查假设。
从 Kaggle 下载 csv 文件后,我们可以使用Pandas . read _ CSV函数将其加载到 Pandas dataframe 中,并使用 pandas 可视化前 5 行。data frame . head方法。
由于列的数量太大,我们无法使用 head 方法看到所有的列。一种选择是改变显示选项,以便我们可以可视化整个数据帧。另一种选择是使用列属性,如下所示:
正如我们所看到的,dataframe 包含 51 列:48 个评级,以及绘画、艺术运动和艺术家的名称。学生们总共给 39 幅画打分。
不适当的数据类型和缺失值是数据集最常见的问题。我们可以使用 **熊猫轻松分析这两者。**data frame . info方法。这个方法打印关于数据帧的信息,包括索引数据类型和列数据类型、非空值和内存使用情况。
我们已经验证了不存在空值,并且数据类型是预期的类型。列 S1-S48 包含整数,其他列(艺术运动、艺术家和绘画)包含对象(熊猫中的字符串)。在这种特殊情况下,我们不需要执行任何清理操作,但这与其说是一种规则,不如说是一种例外,因为数据集通常非常混乱。
我们还可以评估数据集是否包含空值,如下所示:
或者,我们可以使用熊猫来评估数据类型。DataFrame.dtypes** 属性。这将返回包含每列数据类型的序列。**
**Pandas 提供了一个名为pandas 的方法。DataFrame.describe 生成数据集的描述性统计数据(集中趋势、离散度和形状)。默认情况下,describe 方法只分析数字列,但是它也可以通过向参数 include 提供 all 来分析对象列。由于 describe 方法返回的 summary 是一个 dataframe,我们可以通过使用 pandas 轻松访问它的元素。DataFrame.loc 方法。
如上图所示,每个学生总共评价了 39 张图片。我们还可以得出结论,一些学生比其他人更挑剔。例如,学生 9 给出的平均评分为 1.8974,比学生 10 低 1 分左右。除了学生 9(最大值=4)和学生 46(最小值=2)之外,大多数学生给出的最低评分为 1,最高评分为 5。虽然五个数字的摘要(最小值、25%、50%、75%、最大值)为我们提供了关于观察值分布的信息,但通过可视化的方式来分析评级的分布将会很有趣。我们会做到的!继续读😉
我们还可以验证专栏、艺术运动、艺术家和绘画中独特元素的数量,如下所示:
熊猫。series . nunicque方法返回多个唯一元素。如上所示,dataframe 包含不同艺术家的 39 幅画,包括每个艺术运动的 3 幅画。
该数据集不包含大量样本。为此,它不需要重要的清洁操作;但是,我们可以执行一些小的更改,以便于进一步分析数据集。
- 消除列名中的空格→使用点符号按名称选择单个列。
- 通过绘画计算平均评分→评估对绘画和艺术运动的偏好。
- 将绘画列设置为索引→以便使用绘画名称而不是索引轻松访问信息。
执行更改后,我们可以使用数据轻松地得出结论。💪 😊我们开始吧!
回答问题并得出结论
探索性数据分析和数据清理是让我们对数据集有所了解并准备好数据集以便使用它轻松得出结论的步骤。现在!我们准备使用数据集回答以下问题。****
哪 5 幅是评价最高的画?
要获得最高评分的画作,我们可以使用之前创建的平均评分栏,如下所示:
我们还可以创建一个条形图来可视化结果。条形图与分类数据一起使用,其中每个条形图代表一个特定的类别。条形的高度与它们所代表的值成比例。
我们可以很容易地访问关于最佳评级画作的所有信息,如下所示:
评分最高的画作是穆卡的《四季》,平均评分为 3.96。阿尔丰斯·穆夏是捷克画家和新艺术运动大师,最著名的是他独创的女性海报,海报周围环绕着装饰性的植物图案。《四季》描绘了以乡村季节景色为背景的年轻女性。他总共画了 3 个系列(1896-1897-1900)。因为没有提供日期,我们不能断定哪个系列被展示给学生。但是都很神奇!😍
Four Seasons — Serie 1896
下面的情节描绘了其他的顶级画作。我相信你知道其中一些😍
哪 5 幅画的评分最低?
为了分析评分最低的画,我们像以前一样进行。首先,我们创建一个包含平均评级的系列。然后,我们使用条形图来可视化信息。
********
和以前一样,我们可以通过以下方式轻松访问关于最低评级绘画的所有信息:
评分最低的画是弗朗西斯科·戈雅画的裸体玛雅。戈雅是西班牙浪漫主义画家,也是 18 世纪末 19 世纪初最重要的艺术家之一。裸体的玛嘉被认为是最早展示全裸女性的肖像画之一,它可以在马德里的普拉多博物馆找到。虽然他的画是调查中评分最低的,但我不得不承认戈雅是我最喜欢的画家之一,他有大量的绘画作品,从宫廷肖像到可怕的战争场景。
哪些被认为是评价最高的艺术运动?
该数据集包含 13 种不同艺术运动的绘画:(1)文艺复兴,(2)巴洛克,(3)新古典主义,(4)浪漫主义,(5)印象主义,(6)后印象主义,(7)象征主义,(8)新艺术,(9)立体主义,(10)抽象艺术,(11)超现实主义,(12)欧普艺术,(13)波普艺术。要评估最高评级的艺术运动,我们必须计算属于每个艺术运动的三幅绘画的平均评级。我们可以很容易地通过使用 熊猫来计算。DataFrame.groupby 方法 T3。groupby 操作包括拆分对象、应用函数和组合结果的组合。
首先,我们按艺术运动分组。然后,我们计算每组的平均值。如前所述,我们可以通过使用如下条形图轻松解释结果:
如上图所示,评价最高的艺术运动是印象派。我们可以通过以下方式获得本次调查中使用的印象派画作:
哪个学生给了最高分?哪个学生得分最低?
之前,我们已经计算了每幅画的平均评分。现在,我们必须计算每个学生提供的平均评分。
前面的代码返回一个数列,其中包含每列值的平均值。我们可以按以下方式使用 head 方法观察数列的第一个值:
我们可以使用以下方法获得最高分和最低分的学生
- 熊猫。Series.idxmin → 返回最小值的行标签。
- 熊猫。series . idx max→返回最大值的行标签。
如上所示,学生 48 提供了平均 4.05 的最高分。相反,21 号学生得分最低,平均为 1.84 分。
我们可以用柱状图直观地显示两个学生各自的分数。
********
学生如何分配他们的分数?
我们可以通过绘制之前创建的 series(students _ average)来可视化学生提供的平均评分。
毕加索的《格尔尼卡》在排名中占据什么位置?
《格尔尼卡》是西班牙艺术家巴勃罗·毕加索的一幅大型布面油画,被认为是毕加索最著名的画作之一。《格尔尼卡》展现了战争的悲剧,是为了回应西班牙内战(1936-1939)期间位于西班牙北部的小镇格尔尼卡的轰炸而创作的。这幅画位于欧洲和美洲的不同城市。佛朗哥独裁统治结束后,西班牙成为一个民主国家,这幅画于 1981 年回到西班牙。如今埃尔·格尔尼卡被认为是现代艺术和强有力的反战绘画中最重要的标志之一。
因为 python 和 pandas 中的索引是从 0 开始的,所以 el Gernica 的排名位置是 16。
关键要点
- 探索性数据分析包括分析数据集的主要特征,通常采用可视化方法和汇总统计。熊猫**。头(),。info()** ,。形容()。努尼克()、、和。形状是探索性数据分析的有用方法。****
- 我们可以使用来访问一组行和列。loc() 法。
- 我们可以用熊猫。DataFrame.plot 方法使用 matplotlib 对数据帧进行绘图。图的类型在参数种类中指定。**
- 如果未指定条形图的 x 轴,则使用数据框的索引。
- 。value_counts() 方法返回一个包含唯一值计数序列。
- 。sort_values() 方法用于对数据帧中的值进行排序。参数 ascending=False 用于按降序排序。
感谢阅读!!!😍**
使用 Pandas 分析波士顿犯罪事件公开数据
当我在 Python 中使用 Pandas 学习数据分析时,我对分析我目前居住的城市的开放数据很感兴趣。
开放数据为人们提供了无数的机会,让他们随心所欲、不受限制地使用和分析数据。通过查看一个城市的犯罪事件公开数据,您可以了解这个城市或特定社区是否安全。因此,我使用波士顿犯罪事件报告的公开数据,通过使用 Pandas 来分析和可视化它们。希望你看完我的经历,能对获取、分析、可视化开放数据有更好的理解。
获取数据
- 为了获得数据,我复制了下载 csv 格式数据的链接:
url = “[https://data.boston.gov/dataset/6220d948-eae2-4e4b-8723-2dc8e67722a3/resource/12cb3883-56f5-47de-afa5-3b1cf61b257b/download/tmppj4rb047.csv](https://data.boston.gov/dataset/6220d948-eae2-4e4b-8723-2dc8e67722a3/resource/12cb3883-56f5-47de-afa5-3b1cf61b257b/download/tmppj4rb047.csv)”
- 使用
wget
命令下载数据。
- 进口熊猫
import pandas as pd
- 使用熊猫中的
read_csv
读取数据并保存到数据框中
df = pd.read_csv('tmppj4rb047.csv')
- 检查是否成功获取数据。
df.head()
数据分析
1.犯罪类型
获得数据后,我想知道波士顿有多少种犯罪类型。
- 在熊猫身上用
value_counts
。
value_counts
帮助统计不同类型犯罪的出现次数,并进行排序。
df.OFFENSE_CODE_GROUP.value_counts().iloc[:10]
为了便于展示,我只要求返回前十个结果。
Top 10 Crime Incidents in Boston
在这里,我们可以看到波士顿发生最频繁的犯罪事件是“机动车事故反应”,“盗窃”也发生得非常频繁。
然后,为了更好的可视化,我绘制了结果。
df.OFFENSE_CODE_GROUP.value_counts().iloc[:10].sort_values().plot(kind= “barh”)
2.分析具体的犯罪
我想具体分析一下波士顿的盗窃罪。因此,我将数据帧中包含盗窃的部分放到另一个数据帧中,并将其称为“盗窃”
larceny = df[df.OFFENSE_CODE_GROUP.str.contains(“Larceny”)]
larceny.head()
- 检查“盗窃”数据的大小
larceny.shape()
盗窃事件记录 17961 条,每条记录 17 列。
3.分析地点
我想知道波士顿不同地点的犯罪事件数据,更具体地说,波士顿哪些地方更危险。
我用熊猫里的groupby
函数对犯罪地点类型进行分组,用size
函数查看条目数量。
larceny.groupby(“STREET”).size().sort_values(ascending = False)
First few entires of the result
查看结果,我们可以看到波士顿盗窃案发生率较高的地点是华盛顿街、博伊尔斯顿街和纽伯里街。
4.分析时间
我还想知道波士顿盗窃事件的趋势。
larceny.groupby(“MONTH”).size().plot(kind = “bar”)
根据我计算的柱状图,盗窃在 5 月、6 月和 12 月发生最多,而 9 月、10 月和 8 月似乎更安全。
让我们看看盗窃事件的数量在一天内是如何变化的。
larceny.groupby(“HOUR”).size().plot(kind= “bar”)
在这里,我们可以告诉你波士顿一天中最不容易发生盗窃的时间是凌晨 5 点。然而,人们需要在下午 4 点到 6 点更加小心。
现在,我想全面了解一下波士顿每月和 24 小时内的盗窃事件数据。由于 2019 年还没有结束,数据不完整,我们具体看一下 2018 年的数据。
如果我们在熊猫中使用groupby
对月和小时进行分组,我们会得到以下结果。
larceny[larceny.YEAR == 2019].groupby([‘MONTH’, ‘HOUR’]).size()
但是,这对我们轻松读取数据没有帮助。为了使它更好,我使用了unstack
,这将把结果转换成可读性更好的形式。
larceny[larceny.YEAR==2018].groupby([‘MONTH’,’HOUR’]).size().unstack(0)
现在,我想把结果可视化。
因为我将 12 个月的数据可视化为 12 张图表,所以我想使用分面图。在熊猫的plot
中有一个参数叫做subplots
。初始化为True
。我还可以通过使用figsize
来调整图形的长度和宽度。
larceny[larceny.YEAR==2018].groupby([‘MONTH’,’HOUR’]).size().unstack(0).plot(subplots=True, kind = “bar”, figsize = (5, 30)
现在,我们对 2018 年发生在波士顿的盗窃事件有了完整的可视化。
摘要
通过使用 Pandas,我分析并可视化了波士顿犯罪事件报告的公开数据。在提取、分组、排序、分析和绘制数据方面,Pandas 确实是一个非常强大的 Python 包。如果你对数据分析感兴趣,使用熊猫来分析一些真实的数据集是一个很好的开始。
使用 Pandas、Matplotlib 和 lyum 分析巴塞罗那的车祸
巴塞罗那开放数据是巴塞罗那的数据服务,包含约 400 个数据集,涵盖广泛的主题,如人口,商业或住房。该项目诞生于 2010 年,主要目标是最大限度地利用可用的公共资源,允许公司、公民、研究人员和其他公共机构利用生成的数据。
在本文中,我们采用了包含 2017 年巴塞罗那市当地警方管理的起事故的数据集。该数据集包括按严重程度划分的受伤人数、涉及的车辆数量、日期和事故的地理位置等信息。
巴塞罗那市当地警方处理的事故清单。将受伤人数纳入…
open data-a jument . Barcelona . cat](https://opendata-ajuntament.barcelona.cat/data/en/dataset/accidents-gu-bcn)
由于数据集是加泰罗尼亚语的,我们将使用 Kaggle 中可用的英语版本。
下载数千个项目的开放数据集+在一个平台上共享项目。探索热门话题,如政府…
www.kaggle.com](https://www.kaggle.com/xvivancos/barcelona-data-sets#accidents_2017.csv)
探索性数据分析和数据清理
探索性数据分析包括分析数据集的主要特征,通常采用可视化方法和汇总统计。目标是理解数据,发现模式和异常,并在我们执行进一步评估之前检查假设。
从 Kaggle 下载 csv 文件后,我们可以使用Pandas . read _ CSV函数将其加载到 Pandas dataframe 中,并使用 pandas 可视化前 5 行。data frame . head方法。
正如我们所观察到的,数据帧包含 15 列:Id、地区名称、邻居、街道、工作日、月、日、小时、一天的一部分、轻伤、重伤、受害者、涉及的车辆、经度、纬度。
我们可以很容易地使用 **熊猫来打印带有列名的列表。**data frame . columns方法。另外,号熊猫。DataFrame.info 方法提供关于 DataFrame 的信息,包括列类型、非空值和内存使用情况。
显然,没有空值,因为所有列都有 10339 个条目。但是,有些条目包含字符串 Unknown。我们可以用非数字替换这个字符串,并通过使用 熊猫来再次评估空值的数量。DataFrame.info 方法。
正如我们所看到的,只有列 District Name 和 Neighborhood Name 包含空值。因为我们在进一步的分析中不打算使用这些列,所以我们不需要考虑空值。我们不会用区名和街坊名来分析事故发生在哪里,而是用经纬度来分析。
在我们开始使用我们的数据得出结论之前,我们要清理它。第一步清理包括删除不必要的列以简化数据帧。
删除列后,我们修改了一些数据类型。我们可以通过使用 pandas 来查阅数据类型。data frame . info方法或熊猫。DataFrame.dtypes 属性。后者返回包含每列数据类型的序列。****
正如我们所观察到的,月、日和小时不是日期时间对象。我们可以使用pandas . to _ datetime函数轻松地将这些列合并成一列。在使用这个函数之前,我们修改列名,用下划线代替空格,用小写字母代替大写字母。此外,我们还包括一个年份栏。
现在,我们可以将工作日、月、日、小时和年合并到一个名为 date 的列中。为了避免值错误,我们必须在使用pandas . to _ datetime函数之前将月份名称转换成整数。
转换后,我们可以使用上述函数获得日期时间列,如下所示:
通过使用熊猫,我们可以很容易地检查日期列的数据类型。DataFrame.dtypes 属性。
要访问日期的单个元素,如月、日或小时,我们可以使用 熊猫。Series.dt 属性。我们甚至可以通过使用 熊猫来访问星期几。Series.dt.dayofweek 属性,其中星期一=0,星期日=6。💪
因为我们可以使用 pandas 访问我们需要的与事故日期相关的所有信息。Series.dt 属性,我们可以删除月、年、小时、日和星期几列,因为不再需要它们。
最后,我们也可以删除街道列,因为我们将只使用经度和纬度来可视化事故发生的位置。
如上所示,获得的数据帧包含 8 列:id、轻伤、重伤、受害者、涉及的车辆、经度、纬度和日期。
为了方便地访问有关车祸的信息,我们将把 id 设置为数据帧的索引,删除 id 条目前面的尾随空格。
最后的清理步骤包括评估数据帧中是否有重复条目。如果是这样,我们将从数据框中移除这些重复的条目,因为它们代表相同的车祸。
数据清理完成!!👏现在!我们准备回答问题,并利用我们的数据得出结论。👌 🍀
回答问题并得出结论
探索性数据分析和数据清理是让我们对数据集有所了解并准备好数据集以便使用它轻松得出结论的步骤。现在!我们准备使用数据集回答以下问题。****
时间分析
2017 年巴塞罗那警方登记了多少起事故?
我们用 熊猫就能轻松获得巴塞罗那登记的事故总数。DataFrame.shape 属性,因为数据帧的每个条目都代表一次不同的车祸。
2017 年,巴塞罗那警方登记了 10330 起事故。
每月车祸分布
为了分析每月车祸的分布,我们雇佣了 熊猫。DataFrame.groupby 函数。groupby 操作包括拆分对象、应用函数和组合结果的组合。首先,我们按月分组,然后我们计算每个月的事故数量。我们可以通过使用如下柱状图轻松解释结果:
********
正如我们所观察到的,事故数量在八月和十二月减少了。一个原因可能是这几个月开车上班的人少了。
一周中每天的车祸分布
正如我们对月份所做的那样,我们也可以通过使用条形图来分析车祸在一周中的分布情况。
如上图所示,周末车祸数量减少了。工作日平均每天发生 1656 起车祸,比周末多 600 起左右(平均每天 1025 起车祸)。
下一幅图描绘了一年中每天的事故数量。正如我们所观察到的,每天有 10-50 起事故,周五的事故数量通常比周日的事故数量高得多。
每小时车祸分布
按照与之前相同的程序,我们根据时间绘制这次车祸的分布。
正如我们在图中所观察到的,更多的事故发生在清晨 8-9 点和 12-20 点之间。
一周内每天和每小时的车祸分布
我们还可以使用并排条形图来分析一周中每天和每小时的事故数量。在这种特殊情况下,我们使用一个水平图来更好地可视化。
正如我们很容易观察到的,周末晚上发生的事故比平日多。相反,工作日从清晨(8)到下午(19)的交通事故比周末多得多。
时间分析—结论
- 8 月份是 2017 年车祸数量最低的月份,为 651 起。接下来的几个月里会发生 800-900 起事故。
- 周末车祸的数量减少了。
- 更多的车祸发生在(8-9)和(12-20)。
- 大多数事故发生在周末的晚上。
我们总是可以根据不同的时间变量进行分组,并创建更复杂的图,以便提取关于时间相关性的更复杂的模式和结论。
事故分析的类型
我们正在分析的数据包含与(1)事故日期,(2)事故类型,(3)事故地点相关的信息。关于事故类型,数据框包括诸如受害者人数、事故中涉及的车辆数量以及伤害类型(轻微或严重)等信息。和以前一样,我们可以用柱状图来检验所有这些变量的分布。
涉及的车辆
前面的图按照涉及车辆的数量描绘了 2017 年的事故数量。在大多数事故中,涉及两辆车(2017 年 7028 起事故)。此外,警方记录了涉及多达 14 辆车的车祸;但是,车辆多的车祸并不常见。
轻度——严重伤害
数据框包括关于在每起车祸中有多少受害者遭受轻度和重度伤害的信息。我们可以很容易地用饼图表示轻度和重度伤害的百分比,如下所示:
剧情显示只有 2%的伤是重伤。虽然车祸中的大多数伤害都是轻微的,但分析在何种情况下(时间、日期、地点)严重伤害更频繁会很有趣。
下图显示了一周中各天的受伤百分比。轻度伤害遵循一个预期的模式,因为在工作日,当更多的事故发生时,他们呈现较高的比率。然而,尽管周末的平均事故数量(1656 起)低于平日(1025 起),但严重伤害在周末的发生率很高。这表明周末的事故往往比平日更严重。
我们还可以根据小时绘制受伤的百分比。
正如我们所观察到的,事故往往在深夜和夜间更加严重。
事故分析类型——结论
(1)在大多数事故中,涉及 1、2 或 3 辆车。巴塞罗那警方在 2017 年登记的车祸中,涉及的车辆多达 14 辆。
(2)2017 年车祸受伤的人,大部分是轻伤(98%)。
(3)事故往往在夜间、深夜和周末更加严重。
位置分析
分析空间数据的最佳方式是使用地图。follow是一个 python 库,可以帮助你创建几种类型的传单地图。我们可以很容易地生成巴塞罗纳的地图,创建一个叶子地图对象。位置参数允许将地图置于特定位置的中心(在我们的例子中是巴塞罗纳)。我们还可以提供一个初始缩放级别到那个位置,将地图缩放到中心。
尽管有初始缩放级别,但生成的地图是交互式的,这意味着您可以轻松地放大和缩小。
数据集包括每起车祸的经纬度。我们可以很容易地用圆圈标记来形象化它们。下图显示了造成严重伤害的事故,通过弹出标签显示了严重伤害的数量。
在 flour 中,我们还可以使用 MarkerCluster 对象将标记分组到不同的簇中。下面的情节描述了和以前一样的有严重受伤的受害者的车祸,但是这次事故被分组。
叶子的一个显著特点是可以创建动画热图,根据特定维度(如小时)改变显示的数据。我们可以通过使用 HeatMapWithTime() 类方法轻松实现这一点。首先,我们创建一个嵌套列表,其中每个位置都包含特定小时内所有车祸的经度和纬度。例如,hour_list[0]包含从 00:00:00 到 00:59:00 发生的车祸(例如,hour_list[0] → [[lat1,lon1],[lat2,lon2],[lat3,lon3],…,[latn,logn])。然后,我们调用方法并将其添加到地图中。
查看上面的时间线,我们可以观察到事故数量如何从 8 小时开始增加,一直保持高水平,直到 21 小时开始下降。
感谢阅读!!!😊 🍀