TowardsDataScience 博客中文翻译 2016~2018(三十二)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

吴恩达的 Python(神经网络)机器学习课程

原文:https://towardsdatascience.com/andrew-ngs-machine-learning-course-in-python-neural-networks-e526b41fdcd9?source=collection_archive---------5-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Machine Learning — Andrew Ng

本文将着眼于吴恩达的机器学习课程中关于神经网络的编程作业 3 和 4。这也是我们在课程中遇到的第一个复杂的非线性算法。我不知道你是怎么想的,但是对我来说,这个任务绝对有一个陡峭的学习曲线。神经网络形成深度学习的基础,深度学习具有广泛的应用,例如计算机视觉或自然语言处理。因此,获得最基本的权利是很重要的,用 python 编写这些赋值代码是确保这一点的一种方法。

B 在进入神经网络之前,让我们完成逻辑回归的最后一部分——多类逻辑回归。

这一系列练习利用了由 5000 个训练示例组成的手写数字数据集,其中每个示例都是数字的 20 像素乘 20 像素灰度图像。

加载数据集

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat# Use loadmat to load matlab files
mat=loadmat("ex3data1.mat")
X=mat["X"]
y=mat["y"]

因为数据集是在。mat 格式而不是通常的格式。txt 格式,我不得不使用 scipy loadmat 函数来完成这项工作。官方文档可以在这里找到。自装载垫装载以来。mat 文件作为一个以变量名为关键字的字典,给 X 和 y 赋值就像用变量的关键字访问字典一样简单。

X.shape, y.shape

为了更好地理解数据集,拥有数据的形状可以告诉我们数据的维度。X 具有对应于 5000 个训练样本的形状5000,400,每个训练样本具有来自其 20×20 像素的 400 个特征。y 有一个5000,1的形状,其中每个训练样本有一个从 1 到 10 的标签(在这个数据集中‘0’数字被标记为‘10’)。

可视化数据

import matplotlib.image as mpimg
fig, axis = plt.subplots(10,10,figsize=(8,8))
for i in range(10):
    for j in range(10):
        axis[i,j].imshow(X[np.random.randint(0,5001),:].reshape(20,20,order="F"), cmap="hot") #reshape back to 20 pixel by 20 pixel
        axis[i,j].axis("off")

上面的代码块构建了 100 个子情节,并使用 plt.imshow 从 5000 个训练示例中随机可视化 100 个。请注意,我们必须将训练样本重新整形回 20 X 20 像素,然后才能将其可视化,并将order="F"作为参数添加到整形函数中,以确保图像的方向是垂直的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

计算成本函数和梯度

def sigmoid(z):
    """
    return the sigmoid of z
    """

    return 1/ (1 + np.exp(-z))def lrCostFunction(theta, X, y, Lambda):
    """
    Takes in numpy array of theta, X, y, and float lambda to compute the regularized logistic cost function 
    """

    m=len(y)
    predictions = sigmoid(X @ theta)
    error = (-y * np.log(predictions)) - ((1-y)*np.log(1-predictions))
    cost = 1/m * sum(error)
    regCost= cost + Lambda/(2*m) * sum(theta[1:]**2)

    # compute gradient
    j_0= 1/m * (X.transpose() @ (predictions - y))[0]
    j_1 = 1/m * (X.transpose() @ (predictions - y))[1:] + (Lambda/m)* theta[1:]
    grad= np.vstack((j_0[:,np.newaxis],j_1))
    return regCost[0], grad

这类似于我们在逻辑回归任务中使用的成本函数。

theta_t = np.array([-2,-1,1,2]).reshape(4,1)
X_t =np.array([np.linspace(0.1,1.5,15)]).reshape(3,5).T
X_t = np.hstack((np.ones((5,1)), X_t))
y_t = np.array([1,0,1,0,1]).reshape(5,1)
J, grad = lrCostFunction(theta_t, X_t, y_t, 3)
print("Cost:",J,"Expected cost: 2.534819")
print("Gradients:\n",grad,"\nExpected gradients:\n 0.146561\n -0.548558\n 0.724722\n 1.398003")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在是分类任务。由于我们有不止一个类,我们将不得不使用一对一的分类方法来训练多个逻辑回归分类器(每个类一个分类器)。

def gradientDescent(X,y,theta,alpha,num_iters,Lambda):
    """
    Take in numpy array X, y and theta and update theta by taking num_iters gradient steps
    with learning rate of alpha

    return theta and the list of the cost of theta during each iteration
    """

    m=len(y)
    J_history =[]

    for i in range(num_iters):
        cost, grad = lrCostFunction(theta,X,y,Lambda)
        theta = theta - (alpha * grad)
        J_history.append(cost)

    return theta , J_history def oneVsAll(X, y, num_labels, Lambda):
    """
    Takes in numpy array of X,y, int num_labels and float lambda to train multiple logistic regression classifiers
    depending on the number of num_labels using gradient descent. 

    Returns a matrix of theta, where the i-th row corresponds to the classifier for label i
    """
    m, n = X.shape[0], X.shape[1]
    initial_theta = np.zeros((n+1,1))
    all_theta = []
    all_J=[]
    # add intercept terms

    X = np.hstack((np.ones((m,1)),X))

    for i in range(1,num_labels+1):
        theta , J_history = gradientDescent(X,np.where(y==i,1,0),initial_theta,1,300,Lambda)
        all_theta.extend(theta)
        all_J.extend(J_history)
    return np.array(all_theta).reshape(num_labels,n+1), all_J

gradientDescent函数是我们之前实现的常用优化函数。至于oneVsAll,它遍历所有的类,并使用梯度下降为每个类训练一组θ(在赋值中使用了fmincg函数)。all_theta然后在一个列表中捕获所有优化的 theta,并作为一个 numpy 数组返回,重新整形为一个 theta 矩阵,其中第 I 行对应于标签 I 的分类器。np.where在这里派上用场,为每个类获取一个 1/0 的 y 向量,以在每次迭代中执行我们的二元分类任务。

绘制成本函数只是为了确保梯度下降按预期工作

plt.plot(all_J[0:300])
plt.xlabel("Iteration")
plt.ylabel("$J(\Theta)$")
plt.title("Cost function using Gradient Descent")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

alpha = 1, num_iters = 300

为了进行预测,计算每个类别的 x(i)的概率,并且该预测是具有最高概率的类别

def predictOneVsAll(all_theta, X):
    """
    Using all_theta, compute the probability of X(i) for each class and predict the label

    return a vector of prediction
    """
    m= X.shape[0]
    X = np.hstack((np.ones((m,1)),X))

    predictions = X @ all_theta.T
    return np.argmax(predictions,axis=1)+1pred = predictOneVsAll(all_theta, X)
print("Training Set Accuracy:",sum(pred[:,np.newaxis]==y)[0]/5000*100,"%")

打印报表打印:Training Set Accuracy: 91.46 %

最后,神经网络的时间到了。对于相同的数据集,我们旨在使用更复杂的算法(如神经网络)来实现更高的准确性。对于练习的第一部分,优化的θ值被给我们,我们应该实现前馈传播以获得预测和模型精度。

优化 theta 的加载

mat2=loadmat("ex3weights.mat")
Theta1=mat2["Theta1"] # Theta1 has size 25 x 401
Theta2=mat2["Theta2"] # Theta2 has size 10 x 26

使用前馈传播进行预测

def predict(Theta1, Theta2, X):
    """
    Predict the label of an input given a trained neural network
    """
    m= X.shape[0]
    X = np.hstack((np.ones((m,1)),X))

    a1 = sigmoid(X @ Theta1.T)
    a1 = np.hstack((np.ones((m,1)), a1)) # hidden layer
    a2 = sigmoid(a1 @ Theta2.T) # output layer

    return np.argmax(a2,axis=1)+1pred2 = predict(Theta1, Theta2, X)
print("Training Set Accuracy:",sum(pred2[:,np.newaxis]==y)[0]/5000*100,"%")

打印报表打印:Training Set Accuracy: 97.52 %。与多类逻辑回归相比,准确度高得多!

在作业 4 中,我们从零开始实现一个神经网络。我们从计算成本函数和θ的梯度开始。

def sigmoidGradient(z):
    """
    computes the gradient of the sigmoid function
    """
    sigmoid = 1/(1 + np.exp(-z))

    return sigmoid *(1-sigmoid) def nnCostFunction(nn_params,input_layer_size, hidden_layer_size, num_labels,X, y,Lambda):
    """
    nn_params contains the parameters unrolled into a vector

    compute the cost and gradient of the neural network
    """
    # Reshape nn_params back into the parameters Theta1 and Theta2
    Theta1 = nn_params[:((input_layer_size+1) * hidden_layer_size)].reshape(hidden_layer_size,input_layer_size+1)
    Theta2 = nn_params[((input_layer_size +1)* hidden_layer_size ):].reshape(num_labels,hidden_layer_size+1)

    m = X.shape[0]
    J=0
    X = np.hstack((np.ones((m,1)),X))
    y10 = np.zeros((m,num_labels))

    a1 = sigmoid(X @ Theta1.T)
    a1 = np.hstack((np.ones((m,1)), a1)) # hidden layer
    a2 = sigmoid(a1 @ Theta2.T) # output layer

    for i in range(1,num_labels+1):
        y10[:,i-1][:,np.newaxis] = np.where(y==i,1,0)
    for j in range(num_labels):
        J = J + sum(-y10[:,j] * np.log(a2[:,j]) - (1-y10[:,j])*np.log(1-a2[:,j]))

    cost = 1/m* J
    reg_J = cost + Lambda/(2*m) * (np.sum(Theta1[:,1:]**2) + np.sum(Theta2[:,1:]**2))

    # Implement the backpropagation algorithm to compute the gradients

    grad1 = np.zeros((Theta1.shape))
    grad2 = np.zeros((Theta2.shape))

    for i in range(m):
        xi= X[i,:] # 1 X 401
        a1i = a1[i,:] # 1 X 26
        a2i =a2[i,:] # 1 X 10
        d2 = a2i - y10[i,:]
        d1 = Theta2.T @ d2.T * sigmoidGradient(np.hstack((1,xi @ Theta1.T)))
        grad1= grad1 + d1[1:][:,np.newaxis] @ xi[:,np.newaxis].T
        grad2 = grad2 + d2.T[:,np.newaxis] @ a1i[:,np.newaxis].T

    grad1 = 1/m * grad1
    grad2 = 1/m*grad2

    grad1_reg = grad1 + (Lambda/m) * np.hstack((np.zeros((Theta1.shape[0],1)),Theta1[:,1:]))
    grad2_reg = grad2 + (Lambda/m) * np.hstack((np.zeros((Theta2.shape[0],1)),Theta2[:,1:]))

    return cost, grad1, grad2,reg_J, grad1_reg,grad2_reg

该赋值一步一步地遍历整个过程,首先计算成本,然后是正则化成本、梯度,最后是正则化梯度。如果您想继续,我修改了代码,只要您使用正确的索引,它就会返回中间步骤的值。

input_layer_size  = 400
hidden_layer_size = 25
num_labels = 10
nn_params = np.append(Theta1.flatten(),Theta2.flatten())
J,reg_J = nnCostFunction(nn_params, input_layer_size, hidden_layer_size, num_labels, X, y, 1)[0:4:3]
print("Cost at parameters (non-regularized):",J,"\nCost at parameters (Regularized):",reg_J)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

flatten()这里的函数将数组折叠成一维,而np.append将参数“展开”成一个向量。

讲座中讨论了初始θ的对称性问题。为了打破这种对称性,需要随机初始化。

def randInitializeWeights(L_in, L_out):
    """
    randomly initializes the weights of a layer with L_in incoming connections and L_out outgoing connections.
    """

    epi = (6**1/2) / (L_in + L_out)**1/2

    W = np.random.rand(L_out,L_in +1) *(2*epi) -epi

    return Winitial_Theta1 = randInitializeWeights(input_layer_size, hidden_layer_size)
initial_Theta2 = randInitializeWeights(hidden_layer_size, num_labels)
initial_nn_params = np.append(initial_Theta1.flatten(),initial_Theta2.flatten())

最后,轮到我们使用前馈传播和反向传播来优化θ值。我使用的优化算法还是以前的梯度下降法。

def gradientDescentnn(X,y,initial_nn_params,alpha,num_iters,Lambda,input_layer_size, hidden_layer_size, num_labels):
    """
    Take in numpy array X, y and theta and update theta by taking num_iters gradient steps
    with learning rate of alpha

    return theta and the list of the cost of theta during each iteration
    """
    Theta1 = initial_nn_params[:((input_layer_size+1) * hidden_layer_size)].reshape(hidden_layer_size,input_layer_size+1)
    Theta2 = initial_nn_params[((input_layer_size +1)* hidden_layer_size ):].reshape(num_labels,hidden_layer_size+1)

    m=len(y)
    J_history =[]

    for i in range(num_iters):
        nn_params = np.append(Theta1.flatten(),Theta2.flatten())
        cost, grad1, grad2 = nnCostFunction(nn_params,input_layer_size, hidden_layer_size, num_labels,X, y,Lambda)[3:]
        Theta1 = Theta1 - (alpha * grad1)
        Theta2 = Theta2 - (alpha * grad2)
        J_history.append(cost)

    nn_paramsFinal = np.append(Theta1.flatten(),Theta2.flatten())
    return nn_paramsFinal , J_historynnTheta, nnJ_history = gradientDescentnn(X,y,initial_nn_params,0.8,800,1,input_layer_size, hidden_layer_size, num_labels)
Theta1 = nnTheta[:((input_layer_size+1) * hidden_layer_size)].reshape(hidden_layer_size,input_layer_size+1)
Theta2 = nnTheta[((input_layer_size +1)* hidden_layer_size ):].reshape(num_labels,hidden_layer_size+1)

对执行代码的人的警告。根据您的计算能力,计算将花费相当多的时间,如果您正在优化 alpha 和 num_iters 值,时间甚至会更长。我对 alpha 使用 0.8,对 num_iters 使用 800,但是我相信通过更多的调整可以得到更好的精确度。

pred3 = predict(Theta1, Theta2, X)
print("Training Set Accuracy:",sum(pred3[:,np.newaxis]==y)[0]/5000*100,"%")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

至此,我已经完成了这个系列的一半。Jupyter 笔记本会上传到我的 GitHub 上(https://GitHub . com/Ben lau 93/Machine-Learning-by-Andrew-Ng-in-Python)。

对于本系列中的其他 python 实现,

感谢您的阅读。

吴恩达的机器学习教程 Python(正则化 Logistic 回归)+ Lasso 回归

原文:https://towardsdatascience.com/andrew-ngs-machine-learning-course-in-python-regularized-logistic-regression-lasso-regression-721f311130fb?source=collection_archive---------8-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Machine Learning — Andrew Ng

从编程任务 2 (逻辑回归)继续,我们现在将继续进行 python 中的正则化逻辑回归,以帮助我们处理过度拟合的问题。

正则化是收缩方法,通过减少模型的方差,将系数收缩到零,以防止过度拟合。

直接进入任务,我们从导入所有相关的库和数据集开始。这一次,数据集包含了一个工厂中微芯片的两个测试结果,我们将使用测试结果来预测微芯片应该被接受还是被拒绝。

import numpy as np
import pandas as pd
import matplotlib.pyplot as pltdf=pd.read_csv("ex2data2.txt", header=None)
df.head()
df.describe()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如您所见,这是一个多变量、二元分类问题,我们可以使用逻辑回归来解决。

现在来看数据。与之前的逻辑回归可视化一样,x1 和 x2 的每种组合导致接受微芯片,相对于导致拒绝的组合作图

X=df.iloc[:,:-1].values
y=df.iloc[:,-1].valuespos , neg = (y==1).reshape(118,1) , (y==0).reshape(118,1)
plt.scatter(X[pos[:,0],0],X[pos[:,0],1],c="r",marker="+")
plt.scatter(X[neg[:,0],0],X[neg[:,0],1],marker="o",s=10)
plt.xlabel("Test 1")
plt.ylabel("Test 2")
plt.legend(["Accepted","Rejected"],loc=0)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

绘制数据清楚地表明,区分不同类别的决策边界是非线性的。这导致下一步的特征映射,我们添加额外的多项式项来尝试和更好地拟合数据(正常的逻辑回归只能拟合线性决策边界,在这种情况下不会做得很好)。在作业中决定,我们将增加多项式的 6 次方项。

def mapFeature(x1,x2,degree):
    """
    take in numpy array of x1 and x2, return all polynomial terms up to the given degree
    """
    out = np.ones(len(x1)).reshape(len(x1),1)
    for i in range(1,degree+1):
        for j in range(i+1):
            terms= (x1**(i-j) * x2**j).reshape(len(x1),1)
            out= np.hstack((out,terms))
    return outX = mapFeature(X[:,0], X[:,1],6)

mapFeature函数还将一列 1 加到 X 上,这样我们就不必在以后处理它了。这里,我决定使用np.hstack而不是np.append向 numpy 数组添加一个新列。我发现与我通常使用的np.append相比,np.hstack的代码更加简洁。在这里,我允许 degree 作为一个参数,而不是像在作业中那样将其固定为 6,可以随意使用不同的 degree 并比较结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个图表有助于形象化我们正在做的事情和涉及的多项式项。

接下来,我们继续定义计算正则化成本函数和梯度的函数。请记住,成本函数现在有一个由λ控制的附加收缩损失。

def sigmoid(z):
    """
    return the sigmoid of z
    """

    return 1/ (1 + np.exp(-z))def costFunctionReg(theta, X, y ,Lambda):
    """
    Take in numpy array of theta, X, and y to return the regularize cost function and gradient
    of a logistic regression
    """

    m=len(y)
    y=y[:,np.newaxis]
    predictions = sigmoid(X @ theta)
    error = (-y * np.log(predictions)) - ((1-y)*np.log(1-predictions))
    cost = 1/m * sum(error)
    regCost= cost + Lambda/(2*m) * sum(theta**2)

    # compute gradient
    j_0= 1/m * (X.transpose() @ (predictions - y))[0]
    j_1 = 1/m * (X.transpose() @ (predictions - y))[1:] + (Lambda/m)* theta[1:]
    grad= np.vstack((j_0[:,np.newaxis],j_1))
    return regCost[0], grad

您可以使用相同的costFunction代码并添加一个λ项来计算正则化成本函数。根据官方 numpy 文档,我发现用@替换np.dot是矩阵乘法的首选选项。写@也容易多了,所以我觉得很酷。如果你不熟悉 numpy 广播,你可以在这里查看。广播是我需要使用y=y[:,np.newaxis]给 y 添加一个新轴的原因,以确保线性代数操作如我所料。如果你已经注意到了,我在之前的实现中使用了reshape()来处理广播(告诉你们我正在边做边学)。顺便说一下,np.vstack在这里添加到新的一行而不是一列,用于np.hstack

# Initialize fitting parameters
initial_theta = np.zeros((X.shape[1], 1))# Set regularization parameter lambda to 1
Lambda = 1#Compute and display initial cost and gradient for regularized logistic regression
cost, grad=costFunctionReg(initial_theta, X, y, Lambda)print("Cost at initial theta (zeros):",cost)

打印报表 print:初始θ(零)处的成本:0.6931471805599461

至于优化算法,我再次使用标准梯度下降,而不是fminunc。python 做fminunc的方式可以在这里找到。

def gradientDescent(X,y,theta,alpha,num_iters,Lambda):
    """
    Take in numpy array X, y and theta and update theta by taking num_iters gradient steps
    with learning rate of alpha

    return theta and the list of the cost of theta during each iteration
    """

    m=len(y)
    J_history =[]

    for i in range(num_iters):
        cost, grad = costFunctionReg(theta,X,y,Lambda)
        theta = theta - (alpha * grad)
        J_history.append(cost)

    return theta , J_historytheta , J_history = gradientDescent(X,y,initial_theta,1,800,0.2)print("The regularized theta using ridge regression:\n",theta)

print 语句将打印:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

同样,没有给出 alpha、num_iters 和λ值,尝试一些值的组合,得出最佳值。

plt.plot(J_history)
plt.xlabel("Iteration")
plt.ylabel("$J(\Theta)$")
plt.title("Cost function using Gradient Descent")

使用我陈述的值,这是相对于迭代次数绘图的结果成本函数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

降低成本函数—检查
成本函数平稳—检查

def mapFeaturePlot(x1,x2,degree):
    """
    take in numpy array of x1 and x2, return all polynomial terms up to the given degree
    """
    out = np.ones(1)
    for i in range(1,degree+1):
        for j in range(i+1):
            terms= (x1**(i-j) * x2**j)
            out= np.hstack((out,terms))
    return outplt.scatter(X[pos[:,0],1],X[pos[:,0],2],c="r",marker="+",label="Admitted")
plt.scatter(X[neg[:,0],1],X[neg[:,0],2],c="b",marker="x",label="Not admitted")# Plotting decision boundaryu_vals = np.linspace(-1,1.5,50)
v_vals= np.linspace(-1,1.5,50)
z=np.zeros((len(u_vals),len(v_vals)))
for i in range(len(u_vals)):
    for j in range(len(v_vals)):
        z[i,j] =mapFeaturePlot(u_vals[i],v_vals[j],6) @ thetaplt.contour(u_vals,v_vals,z.T,0)
plt.xlabel("Exam 1 score")
plt.ylabel("Exam 2 score")
plt.legend(loc=0)

绘制非线性决策边界,包括绘制分隔不同类别的等高线。我做了一些谷歌搜索,这个 stackoverflow 答案可能会对在座的一些人有所帮助。代码只是简单的翻译了作业中给出的八度音阶代码,为了代码背后的数学和直觉,请查看上面给出的 stackoverflow 链接。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我会说非常好!

为了检查模型的准确性,我们再次利用训练数据的正确分类百分比。

def classifierPredict(theta,X):
    """
    take in numpy array of theta and X and predict the class 
    """
    predictions = X.dot(theta)

    return predictions>0p=classifierPredict(theta,X)
print("Train Accuracy:", (sum(p==y[:,np.newaxis])/len(y) *100)[0],"%")

打印报表打印:训练精度:83.05084745762711%。接近,但没有使用fminunc在赋值中获得的88.983051%高。

接下来,我想谈谈套索回归,另一种用于防止过度拟合的正则化方法。参考《统计学习导论》,Lasso 回归比岭回归(我们刚刚做的正则化)有明显的优势。也就是说,虽然岭回归将系数缩小到零,但它永远不会将其减小到零,因此,无论系数的值有多小,所有要素都将包含在模型中。另一方面,套索回归能够将系数缩小到恰好为零,减少特征的数量,同时充当特征选择工具。这使得套索回归在高维情况下很有用,并有助于模型的可解释性。

对于 Lasso 回归,要最小化的成本函数与岭回归非常相似。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它不是将θ平方之和相加,而是使用绝对值,由于它涉及绝对值,计算起来很困难,因为它是不可微的。各种算法可用于计算这一点,使用 sklearn 库可以找到一个这样的例子。

from sklearn.linear_model import LogisticRegressionclf = LogisticRegression(penalty="l1")
clf.fit(X,y)thetaLasso=clf.coef_
print("The regularized theta using lasso regression:\n",thetaLasso.reshape(28,1))

θ值的并排比较。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如您所见,lasso 回归将几个要素减少到 0,从而降低了问题的维度并提高了模型的可解释性。

这是我所有的正规化。Jupyter 笔记本会上传到我的 GitHub 上(https://GitHub . com/Ben lau 93/Machine-Learning-by-Andrew-Ng-in-Python)。

对于本系列中的其他 python 实现,

感谢您的阅读。

Android 中的 ConvolutionNeuralNetwork(CNN)——TIC tactoe . ai(第 1 部分)

原文:https://towardsdatascience.com/android-with-tensorflow-part-1-6897ba617b1e?source=collection_archive---------3-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image source from- https://techcrunch.com/2017/05/17/googles-tensorflow-lite-brings-machine-learning-to-android-devices/

Google Tensorflow 现在已经在 Android 中用于集成机器学习模型。

所以我想用 Tensorflow 创建一个 Android 应用程序,因为其他人只是使用 Tensorflow 的预训练模型,并将其集成到应用程序中。但我想尝试一些新的东西,所以我训练了自己的模型,并了解了 Tensorflow 如何与 Android 交互。了解如何保存模型以供移动使用。

张量流

我已经实现了卷积神经网络的代码来分类 TicTacToe 游戏的 X 和 O。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image sources from :- https://www.analyticsvidhya.com/blog/2017/06/architecture-of-convolutional-neural-networks-simplified-demystified/

输入图像大小为 28x28,输出图层大小为 2。因为我们必须将图像分类为 X 和 o。

在建立模型的时候,你必须定义哪个是你的输出节点,哪个是你的输入节点,给那些节点一些特定的名字。

然后是模型的训练,我已经在 6000 张不同的 X 和 O 的图像上训练了我的模型,运行了 3 个时期

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Training result of CNN

由于训练模型已经训练了权重,这给出了 X 和 o 的完美分类。现在,我们必须保存具有权重的张量流的图形。

冻结图形时,我们需要输入和输出节点名称的列表,这就是为什么我们给输入和输出节点命名,这在冻结图形时很有帮助。

冻结图由获得输出必须执行的操作序列组成。操作包括矩阵乘法、加法和用训练模型的冻结权重对矩阵进行整形。

下面是冻结保存模型的代码。

freeze_graph.freeze_graph('out/' + MODEL_NAME + '.pbtxt', **None**, **False**,'out/' + MODEL_NAME + '.chkp', output_node_name, "save/restore_all","save/Const:0", 'out/frozen_' + MODEL_NAME + '.pb', **True**, "")

input_graph_def = tf.GraphDef()
**with** tf.gfile.Open('out/frozen_' + MODEL_NAME + '.pb', "rb") **as** f:
    input_graph_def.ParseFromString(f.read())

input_node_names = ['input']

output_graph_def = optimize_for_inference_lib.optimize_for_inference(
        input_graph_def, input_node_names, [output_node_name],
        tf.float32.as_datatype_enum)

**with** tf.gfile.FastGFile('out/opt_' + MODEL_NAME + '.pb', "wb") **as** f:
    f.write(output_graph_def.SerializeToString())

查看我的项目的冻结图

带 Tensorflow 的 Android

从 Android 开始,首先,我们已经集成了 Tensorflow 库,只需将它添加到依赖项中。

dependencies {
.....
implementation ‘org.tensorflow:tensorflow-android:+’
}

由于 Tensorflow 是用 C++编写的,所以你必须将 NDK 集成到我们的 Android 项目中。然后将模型复制到 android 目录的 asset 文件夹中。

如何使用 Java 在 Android 中运行图形?

// added the path of model
private static final String MODEL_FILE_CNN = "file:///android_asset/opt_xo_differ_v2.pb";
//declare the input and output
private static final String INPUT_NODE = "input";
private static final String OUTPUT_NODE = "output"private TensorFlowInferenceInterface inferenceInterface;//load graph
inferenceInterface = new TensorFlowInferenceInterface(getAssets(),MODEL_FILE_CNN);

正在加载模型。pd 文件,并创建一个tensorflowenceinterface对象

为了检测,我创建了一个方法来读取浮动中的图像像素。因为 DrawView 是一个画布,它为我们提供画布绘制图像的像素值,然后将它们转换为 float,并将其传递给tensorflowenceinterface对象。

因此,首先您必须将数据输入到输入节点(input_node 和 keep_prob),中,然后使用输出节点运行推理接口

public float[] getDetectofDV(DrawView d){float pixels[] = d.getPixelData();inferenceInterface.feed(INPUT_NODE, pixels,1,28,28,1);
inferenceInterface.feed("keep_prob", new float[] { 1 });final Operation operation = inferenceInterface.graphOperation(OUTPUT_NODE);final int numClasses = (int) operation.output(0).shape().size(1);// this run the operation of the graph
inferenceInterface.run(new String[]{OUTPUT_NODE},false);float [] outputarray = new float[numClasses];
//get the output
inferenceInterface.fetch(OUTPUT_NODE,outputarray);return outputarray;
}

outputarray 如果一个索引 0 值大于索引 1,则返回具有 2 个值的检测结果。则图像被检测为‘0’,否则为‘X’。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是将模型与 Android 整合后的结果。就像在触摸监听器上工作一样,当你从画布上拿起手指时,它会传递图像进行分类,你会在下面的矩阵中得到输出。

查看 playstore 上的应用程序。https://play.google.com/store/apps/details?id=com.harsh.xo

未来的工作

首先,我会尽量缩小模型的尺寸。CNN 的模型大小是 17MB,因为它在应用程序中占用了大量空间。应用程序的最终大小为 55 MB。

致力于在同一应用程序中集成新模型。一个人可以玩电脑。

https://play.google.com/store/apps/details?id=com.harsh.xo

动画 RNN,LSTM 和 GRU

原文:https://towardsdatascience.com/animated-rnn-lstm-and-gru-ef124d06cf45?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

gif 中的递归神经网络细胞

变更日志:

【2020 年 7 月 4 日:移除 GRU 的“输出门”标签

R 通用神经网络(RNNs)是一类人工神经网络,通常用于序列数据。3 种最常见的递归神经网络是

  1. 香草 RNN,
  2. 长短期记忆(LSTM),由 Hochreiter 和 Schmidhuber 于 1997 年提出,以及
  3. 门控循环单元(GRU),由 Cho 等人提出。2014 年的 al。

请注意,我将使用“RNNs”来统称固有递归的神经网络架构,使用“香草 RNN”来指代最简单的递归神经网络架构,如图图 1 所示。

有许多关于循环神经网络的图解。我个人最喜欢的是迈克尔·阮(Michael Nguyen)在《走向数据科学》中发表的文章,因为他为我们提供了对这些模型的直觉,更重要的是,他提供了美丽的插图,使我们易于理解。但是我的帖子背后的动机是为了更好地可视化这些细胞中发生的事情,以及节点是如何被共享的,以及它们如何转化为输出节点。我也受到了迈克尔的动画的启发。

这篇文章探讨了香草 RNN,LSTM 和 GRU 细胞。这是一篇简短的阅读材料,是为那些对这些主题有所了解的人准备的。(我建议在看这个帖子之前先看看 Michael 的文章。)重要的是要注意,以下动画是连续的以引导人眼,但并不反映矢量化机器计算期间的时间顺序。

这是我在插图中使用的图例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig. 0: Legend for animations

注意,动画显示了在一个时间步长中发生的数学运算(由 t 索引)。此外,我使用了输入大小为 3(绿色)和 2 个隐藏单元(红色),批量大小为 1。

我们开始吧!

香草 RNN

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig. 1: Animated vanilla RNN cell

  • t —时间步长
  • X — 输入
  • h — 隐藏状态
  • X 的长度— 输入的大小/尺寸
  • h 的长度— 隐蔽单元的数量。注意,不同的库对它们的称呼不同,但意思是一样的:
    • Keras — [state_size](https://keras.io/layers/recurrent/) [units](https://keras.io/layers/recurrent/#lstm) -py torch—[hidden_size](https://pytorch.org/docs/stable/nn.html#rnn)
      -tensor flow—[num_units](https://www.tensorflow.org/api_docs/python/tf/nn/rnn_cell/BasicLSTMCell)

LSTM

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig. 2: Animated LSTM cell

  • C — 细胞状态

请注意,单元状态的维度与隐藏状态的维度相同。

苏军总参谋部情报总局

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig. 3: Animated GRU cell

希望这些动画对你有所帮助!以下是静态图像中单元格的摘要:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig. 4: Vanilla RNN cell

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig. 5: LSTM cell

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig. 6: GRU cell

笔记

我用谷歌制图创建了这些图形。

参考

[## 了解 LSTM 网络——colah 的博客

这些循环使得循环神经网络看起来有点神秘。然而,如果你想得更多一点,事实证明…

colah.github.io](https://colah.github.io/posts/2015-08-Understanding-LSTMs/) [## LSTM 和 GRU 的图解指南:一步一步的解释

嗨,欢迎来到长短期记忆(LSTM)和门控循环单位(GRU)的图解指南。我是迈克尔…

towardsdatascience.com](/illustrated-guide-to-lstms-and-gru-s-a-step-by-step-explanation-44e9eb85bf21)

深度学习相关文章

逐行 Word2Vec 实现(关于单词嵌入)

带随机梯度下降的线性回归分步指南

10 种梯度下降优化算法+备忘单

统计深度学习模型中的参数数量

经办人:图文并茂

图文并茂:自我关注

感谢 德里克*任杰 对本文的想法、建议和修正。*

关注我上 推特 @remykarem 或者LinkedIn。你也可以通过 raimi.bkarim@gmail.com 联系我。欢迎访问我的网站remykarem . github . io*。*

使用 broom 和 ggplot2 在 R 中制作回归模型动画

原文:https://towardsdatascience.com/animating-regression-models-in-r-using-broom-and-ggplot2-da798e6638be?source=collection_archive---------9-----------------------

这可能对信息没有帮助,但在 Twitter 上看起来不错

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我在《走向数据科学》中的第一篇文章是我给自己设定的一个小练习的结果,这个小练习是为了让那些灰色的小细胞保持运转。这是一个类似的练习,尽管与我正在做的一个项目更相关一些。由于我在营销部门工作,我不得不习惯于身兼两职。

通常,这些帽子是相互排斥的。在这种情况下,分歧是另一个动画数据可视化的形式。与动画苏格兰橄榄球冠军图一样,这个例子并没有真正受益于添加动画作为情节的另一个维度。

这张图表只是为了显示英国大学筹款的一些指标随时间变化的趋势。我只需要用 xy 来表示价值和年份,但是这有什么意思呢?这是那种我们可以用ggplot2轻松可笑地绘制出来的东西:

ggplot(fund_tidy, aes(x = year, 
                      y = value,
                      colour = kpi)) +
  geom_line()

为什么不把它作为一个学习练习呢?我以前玩过gganimate包,但是从来没有真正花过时间。这似乎是一个好机会。

dataviz 冲突

这就把我们带到了帽子的对接上。我不认为一个动画情节是表现这些数据的最佳方式。我不知道它在技术上是否算作非数据墨水,但你会明白:它只是没有必要。如果已经拍摄了 xy ,并且我想展示这两个值是如何随时间变化的,那么动画以一种易于理解的方式呈现了这些变化。在这种情况下,它是多余的。

要进一步探索市场营销与数据科学的结合, 在 Twitter 上关注 Chris

但是很多图做出来并不是为了尽可能简单准确的表示数据,而是为了引起注意。在许多情况下,特别是在营销机构的世界里,有一种趋势是把一个清晰、直截了当的条形图变成一个完全新颖的信息图。一段时间内的游客流量用一只卡通脚表示,脚趾的大小代表每年的价值,有人知道吗?但那是以后的事了。

事实是,动画吸引眼球,它可以增加停留时间,让读者有时间来理解标题、坐标轴标签、图例和信息。可能吧。以及增加任何品牌的曝光率。不过,我确实有一些原则,所以我不会故意制作一张误导人的图表。摆弄配色方案和布局,让它看起来更时尚一点?当然,但是数据必须是第一位的。

趋势的例子

我一直在做一些大学筹款工作,看着历史性的罗斯案例报告,觉得看看一些关键绩效指标如何随着时间的推移而变化会很有趣。我以前看过一些主要的,但没有看过其他几个,觉得把它们放在一起看可能会很有趣。这将是一些很好的ggplot2gganimate练习。让我们开始吧。

注意:因为这个练习的目的是比较潜在的趋势,并花更多的时间在 gganimate 上,而不是产生一个出版物质量的数字,因此对 y 轴标签的态度有点“漫不经心”!

这里没有洋葱皮

和以往一样,导入我预先制作的数据集并快速浏览是我的首要任务:

# import yearly data (total, summed values, not means or medians)
# dataset compiled from historical Ross-CASE reportslibrary(readr)fund_df <- read_csv("year_sum.csv")# quick look at datalibrary(dplyr)glimpse(fund_df) Observations: 12
Variables: 6
$ year               <int> 2005, 2006, 2007, 2008, 2009, 2...
$ new_funds_raised   <int> 452, 548, 682, 532, 600, 693, 7...
$ cash_received      <int> 324, 413, 438, 511, 506, 560, 5...
$ fundraising_staff  <int> 660, 734, 851, 913, 1043, 1079,...
$ contactable_alumni <dbl> 5.7, 6.2, 6.9, 7.7, 8.3, 8.0, 8...
$ contact_alum_x100  <dbl> 570, 620, 690, 770, 830, 800, 8... library(ggplot2)ggplot(fund_df, aes(x = year,
                    y = new_funds_raised)) +
  geom_line()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

好了,我们有了一个数据集,它看起来像是我从以前的工作中期望的那样,所以希望我没有在第一个障碍就把事情搞砸了。前进!

因为 contactable _ aluminum 的值与其他值相差几个数量级,所以我创建了一个新列,将这些值乘以 100,使它们处于相同的范围内。然后,我将数据整理成一个整齐的“长”格式:

# create contactable alumni x100 variable to place values on equivalent scalefund_df <-
  fund_df %>%
  mutate(contact_alum_x100 = contactable_alumni * 100)# create tidy dataframelibrary(tidyr)fund_tidy <-
  fund_df %>%
  gather(kpi, value, - year) %>%
  mutate(kpi = as.factor(kpi))glimpse(fund_tidy) Observations: 60
Variables: 3
$ year  <int> 2005, 2006, 2007, 2008, 2009, 2010, 2011, 20...
$ kpi   <fct> new_funds_raised, new_funds_raised, new_fund...
$ value <dbl> 452, 548, 682, 532, 600, 693, 774, 681, 807,...

随着数据的转换,我们准备创建我们的第一个动画情节,记得从过滤掉原始的contactable_alumni变量开始:

# create animated plotlibrary(gganimate)
library(transformr)first_animate <-
  fund_tidy %>%
  filter(kpi != "contactable_alumni") %>%
  ggplot(aes(x = year, 
             y = value,
             colour = kpi)) +
  geom_line() + 
# this next line is where the magic happens:
  transition_reveal(kpi, year) +
  labs(title = "Trends in University Fundraising KPIs Over Time",
       subtitle = "Data from Ross-CASE reports",
       x = "Year",
       y = 'Value',
       caption = "y axis labelling omitted due to differences in scale between KPIs",
       colour = "KPI") +
  scale_colour_discrete(labels = c("Cash received", 
                                   "Contactable alumni",
                                   "Fundraising staff",
                                   "New funds raised")) +
  scale_y_discrete(labels = NULL) +
  theme_chris()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们出发了。但这是最好的结果吗?我不这么认为。对我来说最重要的是,因为我们对趋势感兴趣,我们也应该有趋势线。如何着手去做…?

为了以非动画的方式做到这一点,我们只需在绘图代码中添加一个geom_smooth():

# create non-animated plot with trendlinesfund_tidy %>%
  filter(kpi != "contactable_alumni") %>%
  ggplot(aes(x = year, 
             y = value,
             colour = kpi)) +
  geom_line() +
  geom_smooth(method = "lm", linetype = "dashed", se = FALSE) +
  labs(title = "Trends in University Fundraising KPIs Over Time",
       subtitle = "Data from Ross-CASE reports",
       x = "Year",
       y = 'Value',
       caption = "y axis labelling omitted due to differences in scale between KPIs",
       colour = "KPI") +
  scale_colour_discrete(labels = c("Cash received", 
                                   "Contactable alumni",
                                   "Fundraising staff",
                                   "New funds raised")) +
  scale_y_discrete(labels = NULL) +
  theme_chris()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

但是我们能简单地这样做并添加transition_reveal()行以同样的方式制作动画吗?我不能以任何方便的方式找到并相信我,在我失败的过程中产生了一些令人印象深刻的情节。很可能有一种简单的方法可以用geom_smooth()来实现,但是搜索 Stackoverflow 五分钟都没有找到,于是我有了另一个想法。我的下一个想法是创建趋势线作为过程中的一个独立阶段,建立另一个数据框架来构建我的动画情节:

#---- create linear model and augmented dataframe ----# build pre-filtered dataframefund_tidy2 <-
  fund_tidy %>%
  filter(kpi != "contactable_alumni")# build linear modellin_mod <- lm(value ~ year + kpi, data = fund_tidy2)# augment linear model to produce tidy dataframe with fitted valueslibrary(broom)aug_mod <- augment(lin_mod)# create animated graphaug_animate <-
  aug_mod %>%
  ggplot(aes(x = year, 
             y = value,
             colour = kpi)) +
  geom_line(aes(group = kpi, y = .fitted), size = 0.5, linetype = "dashed") +
  geom_point(size = 2) +
  geom_line(aes(group = kpi)) +
  transition_reveal(kpi, year) +
  labs(title = "Trends in University Fundraising KPIs Over Time",
       subtitle = "Data from Ross-CASE reports",
       x = "Year",
       y = 'Value',
       caption = "y axis labelling omitted due to differences in scale between KPIs",
       colour = "KPI") +
  scale_colour_discrete(labels = c("Cash received", 
                                   "Contactable alumni",
                                   "Fundraising staff",
                                   "New funds raised")) +
  theme_chris()# animate and saveaug_animated <- animate(aug_animate, height = 500, width = 800)anim_save("aug_animated.gif", animation = aug_animated)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

哦,亲爱的,当然,这没有用。嗯,动画部分已经完全如我们所愿,但趋势线是错误的。由于我们构建模型的方式,我们已经创建了一个平行斜率类型的线性回归。在这样做的时候,我们失去了数据的关键发现:筹款人员的数量增长速度快于新基金的收购。

多个模型

为了得到我们想要的,我们必须为每个 KPI 建立一个单独的模型。使用 r 中的 tidy 原则很容易做到这一点。通过按 KPI 分组并嵌套在 tibble 中,我们可以使用purrr包中的map函数快速轻松地构建多个模型。

另一种方法是为每个 KPI 创建一个单独的数据框架,分别构建和扩充模型,然后将它们重新绑定在一起。这是一个很好的解决方案,但不具备真正的可扩展性。也就是说,这是我在决定咬紧牙关尝试以“正确”的方式做这件事之前首先做的事情:

#---- build multiple models for animated plot with trendlines ----# build nested tibblefund_nested <-
  fund_tidy2 %>%
  group_by(kpi) %>%
  nest()# build separate regression modelsfund_models <- 
  fund_nested %>%
  mutate(lm_mod = map(data, 
                     ~lm(formula = value ~ year, 
                         data = .x)))# augment models and unnest tibblefund_models_aug <-
  fund_models %>%
  mutate(aug = map(lm_mod, ~augment(.x))) %>% 
  unnest(aug)case_animate <-
fund_models_aug %>%
  ggplot(aes(x = year, 
             y = value,
             colour = kpi)) +
  geom_line(aes(group = kpi, y = .fitted), size = 0.5, linetype = "dashed") +
  geom_point(size = 2) +
  geom_line(aes(group = kpi)) +
  transition_reveal(kpi, year) +
  labs(title = "Trends in University Fundraising KPIs Over Time",
       subtitle = "Data from Ross-CASE reports",
       x = "Year",
       y = 'Value',
       caption = "y axis labelling omitted due to differences in scale between KPIs",
       colour = "KPI") +
  scale_colour_discrete(labels = c("Cash received", 
                                   "Contactable alumni",
                                   "Fundraising staff",
                                   "New funds raised")) +
  scale_fill_discrete() +
  theme_chris()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就是我们想要的。为了美观,我添加了一个单独的 geom_point(),我们还可以做一些事情来使事情变得更漂亮,但是,总的来说,任务完成了,知识得到了加强!

F 在 Twitter 上关注克里斯

本文中的代码可以在 GitHub 上找到。

使用 R 将您的数据可视化制作成动画,就像老板一样

原文:https://towardsdatascience.com/animating-your-data-visualizations-like-a-boss-using-r-f94ae20843e3?source=collection_archive---------2-----------------------

R 中动画库的回顾与教程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Gapminder Inspired: Animated Viz by Pedersen

在讲述数据驱动的故事时,没有什么比动作更能吸引眼球了。我们的眼睛自然会被明亮的颜色和运动所吸引。一个好的视觉效果能抓住观众的兴趣并留下印象。幸运的是,通过一些易于使用的 R 包,制作这样的显示器变得非常简单。本文中的所有可视化示例都可以从这个 Github repo 中派生出来。我假设你对基本的绘图有所了解。

在你开始让你的图表跳舞之前,你应该先问问你自己:这样做有意义吗?如果您正在进行探索性的数据分析,一个运动图形可能不值得您投入时间。然而,如果你正在做一个演示,一些放置得很好的动画图片可以比静态图片更好地帮助观众理解你的主题。

创建动画时,情节实际上并不移动。相反,许多单独的情节被构建,然后缝合在一起成为电影帧,就像一个老派的翻页书或漫画一样。当传达运动时,每一帧都是不同的图,这是使用聚合数据的一些相关子集构建的。当拼接在一起时,子集驱动动画的流动。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

How Animation is Done For Data Visualizations

子集越多,你的图就越平滑。这是你制作动画的重要考虑因素。如果您的数据太薄,您将只有几帧,这可能不会引人注目。在这种情况下,使用静态面板图而不是动画可能会更好。这些可以在 ggplot 中创建,例如,使用。另一个选择是使用插值和 tweener 包来扩展你的数据集。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Panel Plot Structure with 2 rows and 4 columns

动画的最大好处是,它允许您可以可视化的变量数量的扩展。动画图的运动由数据集中的变量“驱动”。上面的图是使用包含六个变量的数据集构建的。动画很好地捕捉到了这六个场景!以下是数据示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A Sample of the Gapminder Data

我们可以对这六个值中的任何一个进行动画处理。然而,这是危险的!有些变量比其他变量更适合制作动画。例如,随着时间的推移动画变化是显而易见的;然而,对分类变量采用同样的方法会造成混乱。

**GDP 的好动画:放慢你的脚步中国!**😯

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

糟糕的 GDP 动画:我不知道发生了什么…🙄

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以下是动画创造有价值见解的几次机会:

  • 随着时间的变化
  • 迭代/递归技术的变化(如梯度下降或贝尔曼方程)
  • 模拟过程中的变化

这里的关键点是突出显示驱动动画的变量的数据中的重要变化。说够了-让我们建立一些动画可视化!所有创建这些可视化效果的源代码都可以在 Github repo 这里找到。

包裹

我通常使用四个包选项来制作 R 中的数据动画:

一般来说,动画包提供了最大的控制,对于基本图来说很棒,但是可能会很冗长。另一方面,gganimate 包只限于一个绘图库,但它使在 ggplot 中构建运动变得极其容易(在您的绘图中有一两行额外的代码)。与 gganimate 类似,plotly 只能从自己的库中制作可视化动画。Googlevis 是最受限制的,只提供一种需要 flash 的动作情节,这种东西越来越不常见。出于这个原因,我不会做这个库的例子,看看这里如果你已经安装了 flash。

使用动画

使用 animate 包,您有五个导出选项,假设您安装了正确的依赖项(参见文档)。

  • HTML(带控件)
  • 视频(mp4)
  • GIF 格式
  • 乳液
  • 闪光

这个包很棒,部分是因为它内置了一些惊人的统计图形作为示例。这是一个动画渐变下降并创建一个带有控件的 HTML 页面:

library(animate)desc = c("This is a super cool example of Gradient Descent")saveHTML({ f1 = function(x, y) x^2 + 3 * sin(y)
  xx = grad.desc(f1, pi * c(-2, -2, 2, 2), c(-2 * pi, 2))

 xx$persp(col = "lightblue", theta = 30, phi = 30)},title = "Demo of Gradient Descent", description = desc, verbose = FALSE)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Gradient Descent Example from The animate package

有时你希望你的用户能够控制动画。在本例中,最后一帧是您可能想要暂停的表面的 3D 图像。此处链接的 Github repo 中有这个动画的现场版,带有这样的控件。

这个包最强大的地方是你可以用任何可视化工具来构建你的框架。例如,上面的好的和坏的动画都是使用这个库和 ggplot 构建的(参见 Github repo)。

使用 gganimate

使用 gganimate,默认的导出是 GIF(使用 gifski ,你必须安装 rust ,但是根据你的具体需求也有其他选项。本文中的第一个动画示例是使用 gganimate 包构建的(事实上,它是该包的自述文件中唯一完整的真实数据示例)。这是 wiki(作者 Tom Westlake )渲染成视频文件的另一个例子。一个有趣的关于安斯科姆的四重奏,这个动画是一系列的情节,都有相同的汇总统计,其中一个是恐龙!所有这一切只需要对一个基本的 ggplot 添加几行代码。

library(datasauRus)
library(ggplot2)
library(gganimate)

ggplot(datasaurus_dozen, aes(x=x, y=y))+
  geom_point()+
  theme_minimal() +
  transition_states(dataset, 3, 1) + 
  ease_aes('cubic-in-out')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The datasauRus!

使用 Plotly

这里涉及的最后一个包是 plotly。许多可视化实践者和这个包有一种爱恨交加的关系。它允许简单地创建美丽的互动情节。然而,这种轻松带来了灵活性和风格上的一些损失。你还必须处理所有东西上的 plotly 标志。但是,我个人认为权衡通常是值得的。以下是我们在 gganimate 包中看到的同一 gapminder 数据集的 plotly 文档(使用帧参数)中的动画示例:

library(plotly)
library(gapminder)p <- gapminder %>%
  plot_ly(
    x = ~gdpPercap, 
    y = ~lifeExp, 
    size = ~pop, 
    color = ~continent, 
    frame = ~year, 
    text = ~country, 
    hoverinfo = "text",
    type = 'scatter',
    mode = 'markers'
  ) %>%
  layout(
    xaxis = list(
      type = "log"
    )
  )

一旦你有了情节,你可以把它推给 plotly 服务托管。这将允许您嵌入包含所有组件的情节,包括播放按钮。这实际上是在介质上获得交互式图形的唯一方法之一!一个缺点是 plotly 托管服务在免费层上有 25 个地块的限制。

Plotly Version of Gapminder Visualization

包扎

现在,您已经拥有了在 r 中构建自己令人惊叹的动画可视化所需的一切。您可以将这些产品整合到您的演示文稿、网站和博客中。记住,权力越大,责任越大。别让我抓到你在分类变量上动来动去🤨。

在 LinkedIn 上与我联系!https://www.linkedin.com/in/isaacfaber/

动漫推荐引擎:从矩阵分解到学习排序

原文:https://towardsdatascience.com/anime-recommendation-engine-from-matrix-factorization-to-learning-to-rank-845d4a9af335?source=collection_archive---------9-----------------------

动漫痴迷过头了!!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

宅男 张哲伦、陈可辛、、普瑞蒂卡·斯里瓦斯塔瓦和切莉·阿加瓦尔

如今,互联网上托管的大量数据导致了信息泛滥,因此不断需要改善用户体验。推荐引擎是一个通过为用户提供适当的预测建议来帮助支持用户决策的系统。它们已经成为我们日常生活的一部分。从购物到美食到娱乐,他们无处不在。动漫是一种新的狂热,每天都在流行,尤其是在非亚洲国家。然而,没有一个推荐引擎可以帮助新手和经验丰富的宅男在这个领域里聪明地进步。因此,我们这些宅男决定开发一个作为我们学术项目的一部分。

数据预处理和探索

该数据取自 Kaggle 。它包含了动漫的信息和看过的用户以及对它的评价。这个数据集中有超过 3000 万的观测,10 万的用户,6K 的动画电影。启发性地,我们决定去掉那些评价很少的动漫和没有评价的动漫,来训练我们的推荐引擎。通过研究数据,我们发现大多数用户来自美国,其次是巴西和波兰。最受欢迎的类型是喜剧、音乐和冒险。此外,我们的大多数用户年龄在 20 到 30 岁之间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig: Exploratory Data Analysis

模型和算法

协同过滤

已经有推荐引擎来满足各种需求,它们都有不同的底层算法来解决问题。最传统的是使用协同过滤,你倾向于将评级矩阵®分成 U ser-Embedding (U) 和 Anime -Embedding § 。这些嵌入本质上就是我们所说的潜在特征(在监督机器学习中)。为了探索这种方法,我们尝试了三种算法,即。即。交替最小二乘法、奇异值分解和神经网络。

ALS :这是一个两步迭代优化过程。在每次迭代中,它试图通过求解 U 来优化评级矩阵(U*P ),首先保持 P 不变,然后 P 保持 U 不变。我们使用 P ySpark 来运行这个使用 MLlib 的算法。

SVD: 为了估计所有的未知量并得到嵌入,我们通过随机梯度下降最小化正则化平方误差。我们偶然发现了伟大的“惊喜,并使用其奇异值分解的实现来训练我们的算法。

**神经网络:**这里我们使用两个嵌入层来表示用户,动画作为我们的输入。互动(评级矩阵)是目标变量。对于每个用户-动画对,我们计算一个分数,取其潜在表示的点积。然后,我们尝试通过反向传播将损耗降至最低,并优化嵌入层(示意图如下所示)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig: Neural Network schematic for estimating embedddings

我们运行了这个模型 10 个时期,由于计算量很大,我们在谷歌云平台上用 Keras(Tensorflow backend)运行了这个模型。这个模型比之前的要好,但并没有全面超越它们。我们得到了另一个绝对免费的模型!猜猜看?合奏!!。这个模型只是将上述三个模型的预测结果进行了平均。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig: Comparison of different algorithms with NDCG@10 and MAP@10

正如可以看到的,集成特别优于所有三种算法,并给出了与 NDCG 和地图(稍后更多)的伟大结果。最初,我们基于 RMSE 评估我们的模型。然而,我们的教授 Ghosh 博士建议我们研究学习排序(LTR)算法。

问题来了,为什么我们需要转移到 LTR 算法?请这样想:假设我们有两个项目 I 和 j,已知它们的真实评分分别为 3 和 4,两种不同的方法预测 I 和 j 的评分分别为{2,5}和{4,3}。就通过与真实评级的绝对偏差来测量的评级预测准确性而言,两组预测之间没有差异。然而,使用预测{4,3},项目 I 和 j 将被错误地排序,而预测{2,5}确保了正确的顺序。

学习排名

学习排序预测项目列表的排序,而不是评级。基于 LTR 算法的现状,python 中没有太多的开源资源可以实现它们。在这个项目中,我们有机会深入研究了微软关于 LTR 的论文,并从头开始用 python 对它们进行编码。这是我们给致力于 reco-engine 的开源社区的两分钱,如果他们想试验这些算法的话。因为这是一个学术项目,这些被证明对我们的概念学习也非常有益。我们成功地通过了其中的两个,即 EigenRank 和 LambdaMART。EigenRank 是面向排序的协同过滤版本,而 LambdaMART 是监督机器学习 weds 信息检索的典型。

Eigen Rank:It是第一个基于排序的协同过滤算法。对于每个用户 u,它试图使用 Kendall Tau 等级相关系数找到它的邻域(Nu ),然后计算如下所示的偏好函数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig: Formula for Preference function. Nu represents neighborhood and r represents rating by user ‘u’ to item ‘i’

Nu 中的用户分配比 j 更高的 i 的次数越多,ψ(I,j) > 0 和ψ(j,i) < 0 的证据就越强。偏好函数给邻居的动画列表中的每对动画 I,j 分配一个分数。最后为了给这些动漫排序,我们使用了一种贪婪算法的方法。

LambdaMART: 使用梯度提升树直接优化特定等级成本函数(如 NDCG)。不幸的是,成本函数不是在所有的点上都是可微的。因此,我们需要梯度的代理,这里称为λ。它可以被认为是一种推动动画在排行榜上上下移动的力量(如下图)。最好的部分是,它还利用了动漫和用户的特点,如受欢迎程度,持续时间,类型,特定用户观看的次数,发行年份等。利用 LambdaMART 的这一特性,我们可以为新用户提供建议。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig: Schematic of Lambda pushing the items in list up and down and thus reducing incorrectly ordered pair. source: original paper

对于这些 LTR 模型,我们再次使用 NDCG(归一化累积贴现收益)和 MAP(平均精度)等评估指标。

如前所述,因为我们为前面提到的两个算法编写了代码,所以它不是超级可伸缩的。在我们努力使我们的代码成为黄金标准的同时,我们在较小的数据(~0.5M)上测试了它的效用,它表现很好,实现了 NDCG as: 0.72(本征秩)和 0.60(λmart);映射为 0.63 (EigenRank)和 0.56(LambdaMART)。

所以让我们打破 NDCG 和地图上的悬念…

评估措施

NDCG 归一化折扣累积收益:量化预测排名列表与理想排名列表(将只是基于评分的项目排序)的偏差。它还认识到高度相关的文档比不太相关的文档更有用的事实。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig: Zu is the Normalization factor (inverse of Ideal NDCG), Q represents all the users and R(u,p) is the rating given by user u to anime at rank p

NDCG@K 只是从我们的引擎为前 K 个推荐计算的 NDCG。

**MAP-Mean Average Precision:**它捕捉了所有推荐动漫中相关动漫的百分比(测试数据中的用户已经看过这些动漫并给予了高度评价)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fig: Formula for Mean Average Precision. AP(q) is the average precision for each user q

MAP@K 只是为来自我们引擎的前 K 个推荐计算的 MAP。

到目前为止,我们推荐是基于用户的观看历史。 如果有新用户来向我们推荐动画,我们该怎么办? 为了帮助新用户加入动画世界,我们使用 K-means 聚类 将对不同类型有共同爱好的用户分组到不同的群中。总之,我们提出了 5 个不同的群体:科幻迷、无偏好者、憎恨者、活泼的年轻人热血战士

开演时间

这里有一个很酷的视频,展示了我们尝试过的算法的相对优势:

Fig: Video Demonstration of the recommendation engine

前进的道路
(i)用于学习排序算法的可扩展性增强,可能通过在 Cython 中编码它们。
(ii)LambdaMART 更好的特征工程。(iii)建立一个前端来托管我们的推荐引擎
(iv)完成(I)、(ii)和(iii),然后可能会尝试接近一个风险投资家来资助我们的推荐引擎网站!!

完整的项目和代码可以在https://github.com/Preetikasri/Anime-Recommendation-Engine查看

感谢阅读!!

公告:TensorFlow 2.0 来了!

原文:https://towardsdatascience.com/announcement-tensorflow-2-0-is-coming-7e17e8e333e3?source=collection_archive---------4-----------------------

而 TensorFlow 1.x 将会是…

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

备受期待的流行机器学习框架 TensorFlow 的更新于 8 月初由谷歌人工智能的马丁·维克(Martin Wicke)宣布。

这个令人兴奋的消息是在他的谷歌团队上宣布的,它已经引起了关于框架的下一个主要版本——tensor flow 2.0 的讨论。如果你和我一样兴奋,并渴望了解 2.0 开发的最新细节,我强烈建议你订阅 谷歌群组

更吸引人的是,您可以成为即将到来的公共设计评审的一部分,甚至通过表达您的关注和提出更改来为 TensorFlow 2.0 的功能做出贡献!这正是我喜欢开源开发的原因,因为社区为了共同的目标一起工作并相互支持。

那么 TensorFlow 1.x 有什么问题呢?

如果你是 TensorFlow 的初学者,你可能会发现学习曲线非常陡峭,因为它是一个低级框架,不像 Keras 。因此,一些用户可能会发现学习和应用起来相对困难。

然而,TensorFlow 已经成为世界上最广泛采用的机器学习框架,迎合了广泛的用户和用例。

这些快速的变化推动了 TensorFlow 的下一个主要版本,这将是一个以易用性为重点的重要里程碑

虽然在 TensorFlow 2.0 的早期版本中,TensorFlow 1.x 仍将得到维护和开发,但已宣布一旦 TensorFlow 2.0 的最终版本发布,将不再开发 TensorFlow 1.x。 TensorFlow 团队仍将在 TensorFlow 2.0 发布日期后的一年内继续发布上一个 TensorFlow 1.x 版本的安全补丁。

我们对 TensorFlow 2.0 有什么期待?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(Source)

高级 API

  • Keras、Eager 和 Estimators 更强的集成,使用相同的数据管道、API 和序列化格式(保存的模型)。
  • TensorFlow Core 中常用 ML 模型(如时间序列、RNNs、TensorForest、附加提升树功能)和相关功能(如序列功能列)的固定估计器(从 contrib 迁移,如果存在)。

急切的执行

  • 使用 DistributionStrategy 利用多个 GPU 和多个 TPU 内核。
  • 分布式训练支持(多机)。
  • 性能改进。
  • 更简单地导出到 GraphDef/SavedModel。

参考模型

  • 构建一套横跨图像识别、对象检测、语音、翻译、推荐和强化学习的模型,展示最佳实践,并作为高性能模型开发的起点。
  • 越来越多的高性能云 TPU 参考模型。

贡献

  • 弃用[tf.contrib](https://www.tensorflow.org/api_docs/python/tf/contrib)中存在于[tf.contrib](https://www.tensorflow.org/api_docs/python/tf/contrib)之外的优选实现的部分。
  • 尽可能将[tf.contrib](https://www.tensorflow.org/api_docs/python/tf/contrib)内部的大型项目转移到单独的存储库。
  • 在 TensorFlow 2.0 中,当前形式的[tf.contrib](https://www.tensorflow.org/api_docs/python/tf/contrib)模块将停止使用。实验性开发将在未来的其他存储库中进行。

最后的想法

(Source)

感谢您的阅读。

这么多激动人心又人性化的功能,真的很期待 TensorFlow 2.0 的早日发布。TensorFlow 2.0 的预览版将于今年晚些时候发布,也就是下个月的 12 月份!

同时,如果您有兴趣了解 TensorFlow 2.0 下一版本的最新发展,您可以随时订阅邮件列表在此加入社区

一如既往,如果您有任何问题或意见,请随时在下面留下您的反馈,或者您可以随时通过 LinkedIn 联系我。在那之前,下一篇文章再见!😄

关于作者

Admond Lee 目前是东南亚排名第一的商业银行 API 平台 Staq 的联合创始人/首席技术官。

想要获得免费的每周数据科学和创业见解吗?

你可以在 LinkedInMediumTwitter脸书上和他联系。

[## 阿德蒙德·李

让每个人都能接触到数据科学。Admond 正在通过先进的社交分析和机器学习,利用可操作的见解帮助公司和数字营销机构实现营销投资回报。

www.admondlee.com](https://www.admondlee.com/)

宣布 fast.ai 第 1 部分现在作为 Kaggle 内核提供

原文:https://towardsdatascience.com/announcing-fast-ai-part-1-now-available-as-kaggle-kernels-8ef4ca3b9ce6?source=collection_archive---------6-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在是开始使用 Kaggle 内核进行深度学习的好时机!

最近,我有机会在哥伦布的 PyOhio 做了我的第一次会议演讲。我谈到了进入深度学习,我使用 Kaggle 内核演示了来自 fast.ai 课程第一课的一些材料。

第二天我偶然看到了一篇名为“使用支持 GPU 的 kaggle 内核和 fastai MOOC 学习深度学习”的媒体文章,我很高兴看到更多人认识到这个平台的能力。

所以我想,如果我们要让人们容易地开始在 Kaggle 内核上进行深度学习,为什么不把整个 fast.ai 课程公之于众?

ka ggle 内核的好处

根据该文档,“ Kaggle Kernels 是一个云计算环境,支持可重复的协作分析。基本上,你可以专注于编写代码,Kaggle 负责设置执行环境并在他们的服务器上运行。我认为这种设置为刚开始学习深度学习的人提供了优势,有几个原因:

  • **无需等待/批准的免费 GPU:**你可以立即免费访问 GPU,这是开始深度学习的一大步。当我第一次开始时,你唯一的选择是等待 AWS 批准你的 GPU 实例,然后付钱给他们运行它(希望你没有忘记关闭它)。在 GPU 和 CPU 上运行意味着你的训练可以在几分钟内完成,而不是几个小时。
  • **预装深度学习包:**这对初学者来说是又一个巨大的胜利,为你节省了几个小时的设置时间和谷歌模糊的错误信息。使用 Kaggle 维护的 docker-python repo 中的 docker 文件设置内核环境。它设置了 CUDA 和 CUDNN,即 NVIDIA 用于在 GPU 上加速深度学习的库,并安装了用于深度学习的流行 python 库:除了 fastai 之外,还有 keras、tensorflow、pytorch 和 pytorch 等。
  • **访问数据:**大多数 fast.ai 课程都使用 Kaggle 比赛来获取训练数据,而在 Kaggle 内核中,访问这些数据就像点击“添加数据集”一样简单。这也使得无需任何额外的步骤就可以很容易地将经验应用到其他过去的比赛中。如果你找不到你需要的数据,你可以上传你自己的数据集并与 Kaggle 社区分享。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

It’s as easy as a single click!

  • **平台的社交特性:**我认为 Kaggle 内核的一些社交特性也使其成为一个很好的学习环境。您可以“派生”现有的内核,并对它们进行调整以制作您自己的版本,这使您能够进行实验并查看不同代码更改的影响。您可以对内核进行评论,向作者提问或试图追踪一个 bug。向上投票有助于你看到流行的内核,这可能会引导你进入下一个你想学习的有趣话题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

抓到你了

如果您习惯于在 AWS 或您自己的机器上工作,或者如果您正在遵循针对这些环境的说明,那么在使用内核时需要注意一些事情。这些差异解释了我需要对最初的 fast.ai 笔记本进行的大部分更改,以使它们作为内核运行。

  • **只读输入数据:**默认情况下,您加载到内核中的数据位于../input下。但是数据所在的目录是只读的。这给 fast.ai 带来了两个问题——首先,在某些情况下,您需要移动数据以符合特定的目录结构。这可以通过以不同的形式将数据传递给学习者来解决(在第 1 课中,我使用了文件名和标签的列表,这是由from_names_and_array 方法支持的)。此外,默认情况下,学习者将 tmp 数据和模型权重写入与数据相同的目录,这可以通过将tmp_namemodels_name选项传递给学习者来修改。
  • **等待软件包更新:**我提到过,软件包安装由 Kaggle 维护在 Dockerfile 中,这在很大程度上对您有利,节省了您配置东西的时间。唯一的缺点是,当他们重建 Docker 映像时,您只能获得软件包更新。当我处理这些问题时,我注意到在最新的 fast.ai 版本中已经修复了几个问题,我不得不通过猴子修补一些类来将这些修复移植到我自己身上。我也无法完成第 4 课和第 6 课(RNN),因为 pytorch 0.3.1 和 CUDNN 7.1 中出现了一个错误。(针对 GPU 内核的 pytorch 0.4.0 更新正在进行中)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Not fun when your debugging path eventually leads here…

  • 非持久文件系统:如果你重启你的内核,你会丢失你已经写到磁盘上的文件。对于运行 fast.ai 课程来说,这不是一个主要问题,但如果你正在试验不同的模型或超参数,并试图节省权重,这对你来说可能很难。

内核

事不宜迟,他们来了!我希望这有助于你的深度学习之旅——没有什么比看到这些东西以新的有趣的方式被分叉、调整和应用更让我高兴的了。

第一课
第二课 第三课 第四课
第五课
第六课【SGD】
第六课【RNN】 第七课【cifar 10】
第七课【CAM】

如果你有任何问题,请随时联系 fast.ai 论坛或 Twitter:@ hortonhearsafoo

宣布 Google Sheets 为 ParallelDots APIs 添加插件

原文:https://towardsdatascience.com/announcing-google-sheets-add-on-for-paralleldots-apis-c67907c97d5b?source=collection_archive---------11-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

去年 12 月,我们发布了 ParallelDots Excel 插件,它无需编写一行代码就能提供最先进的文本分析功能。因为我们的主要目标是面向业务分析师,所以我们推出了适用于 Windows 操作系统的 Excel 插件。从那时起,我们的 Excel 插件已经被下载了 10,000 多次,并被用于处理超过 500 万个不同行业的文本文档,如金融、市场研究、教育和消费零售。

随着我们的 Excel 插件越来越受欢迎,我们也收到了许多关于 Mac 等其他操作系统上类似解决方案的查询。经过几次讨论,我们决定建立一个 Google Sheets 插件,使我们的服务跨平台,并向我们将人工智能带到用户指尖的目标迈进了一步。

今天,我们很高兴地宣布推出我们的 Google Sheets 插件,其工作方式与我们的 Excel 插件相同。该插件可用于在大型文本语料库上运行文本分析,并从中发现见解(如来自社交媒体活动的用户生成内容、收入电话会议记录、开放式用户反馈等)。).点击此处将插件安装到您的 Google Sheets 中。

请阅读我们的以前的博客来了解更多关于插件的真实使用案例。

Google Sheets 附加组件入门

首先,从您在 xlsx(或 CSV 格式)中使用的任何 BI 工具中导入您的数据,并安装我们的附加组件,用情绪和情感来注释数据,找到突出的关键词或将它们归类到 IAB 分类法中。

在本帖中,我们将展示如何使用我们的 Google Sheets 插件快速分析大量文本文档,并做出强有力的、有数据支持的决策。

安装和使用附加软件

在开始使用 Google Sheets 插件之前,你需要注册一个免费的 ParallelDots AI APIs 帐户。在我们网站上填写表格并验证您的电子邮件后,您可以通过 google sheets 直接登录您的帐户。请将帐户凭证存放在安全的位置,因为未经授权访问您的帐户将导致您的配额提前用完。如果您丢失了密码,或者您觉得其他人可能会访问您的密码,请立即更改您的密码。

验证电子邮件后,将 ParallelDots 扩展添加到您的 Google Sheets,并按照屏幕上的说明安装该插件。成功安装附加组件后,Google Sheets 屏幕顶部导航栏的附加组件下拉列表中将有一个 ParallelDots 按钮,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

单击显示/隐藏窗格后,您可以切换设置屏幕来激活您的附加帐户。在任务窗格中输入在上一步中创建的帐户凭据,然后单击登录开始分析数据。

就是这样,现在您可以使用我们的附加组件带来任何类型的非结构化文本内容并进行分析。在下一节中,我们将解释附加组件中可用于执行不同类型的文本分析的不同功能。

Google Sheets 插件中的文本分析功能

我们的 Google Sheets 插件允许您访问以下 API:

情感分析

使用 Google Sheets 的情感分析可以通过调用函数paralledots _ perspective来访问,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你需要知道上面的parallel dots _ 情操函数返回的情感标签的概率,你可以通过调用函数parallel dots _ 情操 _ <情操 _ 标签>_ 概率来实现,其中情操 _ 标签可以是中性的,积极的或者消极的。

情感分析 API 的细节可以在这里找到。

多语言情感分析

我们的情感分析算法支持 14 种其他语言。对这些语言的分析可以通过调用函数**parallel dots _ 情操(text," language_code ")来调用。**也可以通过在每种语言的函数后面附加“_confidence”来检索它们的置信度得分,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

多语言情感分析 API 的详情可以在这里找到。

关键词生成器

可以通过调用 paralleldots_keywords 函数来调用。返回输入文本中重要关键字的列表。这个功能的细节可以在这里找到

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

多语言关键字生成器

我们的关键字生成器算法支持 13 种不同的语言。可以通过调用函数 **paralleldots_keywords(text," language_code ")来调用这些语言的分析。**也可以通过在每种语言的函数后面附加“_confidence”来检索它们的置信度得分,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

多语言关键字生成器 API 的详细信息可以在这里找到

文本分类

可以通过调用 paralleldots_taxonomy 函数来调用。返回文本可能属于的类别列表。

文本分类 API 的详细内容可以在这里找到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

命名实体识别

可以通过调用parallel dots _ ner _ organization、paralleldots_ner_personparalleldots_ner_place 分别提取组织名称或人员或地点。

命名实体识别 API 的细节可以在这里找到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

语义分析

可以通过调用parallel dots _ similarity来调用。输出是 0-5 之间的分数,其中接近 5 的分数表示两个句子的意思非常接近(语义相似),而接近 0 的分数表示两个句子的意思非常不同。

注意,为了使用这个函数,你需要在两个句子上运行它,更多细节和用例可以在这里找到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

情绪分析

可以通过调用 paralleldots_emotion 得到情绪标签,调用parallel dots _ emotion probability得到不同情绪的概率得分,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更多关于情感功能的细节请点击查看

多语言情感分析

我们的情感分析算法支持 14 种其他语言。可以通过调用函数 **paralleldots_emotion(text,“language_code”)来调用这些语言的分析。**也可以通过在每种语言的函数后面附加“_confidence”来检索它们的置信度得分,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

多语言情感分析 API 的详细信息可以在这里找到。

意图分析

可以通过调用 paralleldots_intent 来查找输入文本的意图,并调用 parallel dots _ intent _

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

点击查看关于意图功能的更多详情。

辱骂内容分类器

可以通过调用paralleldots _ abuse来将输入文本分类为滥用或不滥用。置信度得分(概率得分)可以通过调用parallel dots _ abuse _ confidence得到。

更多关于意图功能的细节可以在这里找到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

安全和隐私

Google Sheets add-on 建立在我们的 API 之上,这意味着您的数据在我们的服务器上进行处理,以获得最终输出。我们非常重视用户隐私,我们的隐私政策可以在这里访问。所有用户数据都根据我们的隐私政策进行存储,以确保高标准的安全性。

然而,在某些情况下,由于合同义务或其他原因,用户可能希望将数据保存在内部,在这种情况下,我们可以在内部部署这些算法,并相应地构建插件。请向我们发送一个请求以在内部部署这些 API 以及您希望我们构建的任何自定义功能。

Google Sheets add-on 是一种强大且经济高效的方式,可以开始将尖端智能添加到您的分析中。我们的 Google Sheets 插件可以让你每天免费分析每个功能的 100 个句子,而不需要给出你的信用卡信息。我们希望这将让您了解附加组件中提供的不同功能,并在升级到我们的大规模使用付费计划之前了解使用案例。

如有任何疑问或反馈,请给我们 support@paralleldots.com 公司写信。

我们希望你喜欢这篇文章。请注册一个免费的 ParallelDots 账户,开始你的 AI 之旅。你也可以在这里查看 PrallelDots AI API的演示。

此处阅读原文

宣布 Optimus v2 —简化敏捷数据科学工作流程

原文:https://towardsdatascience.com/announcing-optimus-v2-agile-data-science-workflows-made-easy-c127a12d9e13?source=collection_archive---------13-----------------------

作为一名数据科学家,您是否正在寻找一个库来提升您的工作效率?看看这个。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Timothy Eberly on Unsplash

几年前,我们为一个零售客户项目清理、处理和应用 ML 聚类算法。

当时,我们正在寻找一种工具,让我们能够轻松地处理数据。我们尝试了 trifacta,这是一个制作精美的工具,可以让你通过点击界面以可视化的方式应用转换。问题是可用的脚本语言不足以按照我们喜欢的方式处理数据。

我们还尝试了令人惊叹的熊猫图书馆,但我们的数据大到足以让它哭泣。

所以,大约一年前我们推出了擎天柱。Optimus 由 Spark (Pyspark)提供支持,允许您使用自己的或一组预先创建的数据转换函数清理数据,对其进行分析并应用机器学习,所有这些都很容易,并且具有 python 的所有功能。

🚚Optimus v2 测试版推出

现在,我们准备发射擎天柱 v2。借助 Apache Spark 和 Pyarrow 的全面重写,Optimus 提供了一种访问、转换数据和创建大规模机器学习和深度学习模型的单一方式。

对于这个新版本,在我们惊人的用户反馈后,我们决定致力于三个主要目标:

  • 创建一个可靠的 API 来访问和处理数据。
  • 让用户可以轻松地从熊猫迁移。
  • 让数据探索更容易。

目标 1:创建可靠的 API 来访问和处理数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们经营游泳池快一年了。结论,Pandas 和 Spark 是用于数据清理的主要库。因此,我们使用 Optimus 的目标是创建一种可预测的、简单的方法来访问和处理数据。不管是来自熊猫,还是火花。

下表显示了火花,熊猫和我们用擎天柱创造的东西。

Basic data operations API for Pandas Spark and Optimus

我们在这里看到了一些东西:

  • Spark API 对于基本函数没有任何一致性。
  • 对于 Pandas,只有追加列/过滤器不一致。

因此,第一步是为我们认为的核心数据操作创建一个一致的基础:

  • 创建数据帧
  • 追加行或列()
  • select() 选择行或列
  • apply() 更新或转换列数据
  • drop()删除行或列

其他基本功能是 read()write() 操作,用于加载和保存数据帧。因为我们认为 Apache Spark API 是一致且强大的,所以我们将其直接映射到 Optimus,不做任何更改。

下面是所有基本操作的示例:

df = op.create.df(
    [
        ("names", "str", True),
        ("height", "float", True),
        ("function", "str", True),
        ("rank", "int", True),
    ],
    [
        ("bumbl#ebéé  ", 17.5, "Espionage", 7),
        ("Optim'us", 28.0, "Leader", 10),
        ("ironhide&", 26.0, "Security", 7),
    ]).show()df.rows.append(["Grimlock",80.0,"Commander",9])+------------+------+---------+----+
|       names|height| function|rank|
+------------+------+---------+----+
|bumbl#ebéé  |  17.5|Espionage|   7|
|    Optim'us|  28.0|   Leader|  10|
|   ironhide&|  26.0| Security|   7|
+------------+------+---------+----+df.rows.append(["Grimlock",80.0,"Commander",9])\
    .rows.select(df["rank"]>7)\
    .cols.select(["names","height","function"])\
    .cols.apply_expr("height", df["height"]-1)\
    .cols.drop("function")\
.table()+--------+------+
|   names|height|
+--------+------+
|Optim'us|  27.0|
|Grimlock|  79.0|
+--------+------+

列操作

除了这个基本操作之外,我们还识别了列上的其他操作。这里的想法是一样的,创建一个简单和一致的方法来操作数据。所有手术的设计和命名都尽可能接近熊猫。此外,您可以轻松地对单个、多个或整个列数据集应用操作。

聚集

让我们从聚合开始。我们扩展了 Apache Spark 操作,并创建了一种访问统计函数的简单方法。

print(df.cols.min("height"))
print(df.cols.percentile(['height', 'rank'], [0.05, 0.25, 0.5, 0.75, 0.95]))
print(df.cols.max("height"))
print(df.cols.median(["height","rank"]))
print(df.cols.range(["height","rank"]))
print(df.cols.std(["height","rank"]))17.5   
{'height': {0.05: 17.5, 0.25: 17.5, 0.5: 26.0, 0.75: 28.0, 0.95: 28.0}, 'rank': {0.05: 7.0, 0.25: 7.0, 0.5: 7.0, 0.75: 10.0, 0.95: 10.0}}
28.0
{'height': 26.0, 'rank': 7.0}
{'height': {'min': 17.5, 'max': 28.0}, 'rank': {'min': 7, 'max': 10}}
{'height': {'stddev': 5.575242894559244}, 'rank': {'stddev': 1.7320508075688772}}

转换和链接

有了擎天柱,你不仅可以链接擎天柱变形,还可以链接火花操作👏。让我们来看看这个:

。行和。 cols 可能会觉得有点冗长,但是看看你如何可以很容易地看到你的数据发生了什么,哪些列或行受到了影响,以及将要应用什么转换。

通过链接,您可以利用 Spark 惰性评估的强大功能。链接转换,apache Spark 将通过 Catalyst 处理这个问题的更好的方法。

df = df\
    .rows.sort(["rank","height"])\
    .cols.lower(["names","function"])\
    .cols.remove_accents("names")\
    .cols.remove_special_chars("names")\
    .cols.trim("names").show()+---------+------+---------+----+
|    names|height| function|rank|
+---------+------+---------+----+
|  optimus|  28.0|   leader|  10|
| ironhide|  26.0| security|   7|
|bumblebee|  17.5|espionage|   7|
+---------+------+---------+----+

嵌套操作

这是从多个列创建一个新列的操作*->1。()可以压缩到字符串数组向量列。

df.cols.nest(["names", "function"], output_col = "new_col", shape ="string").show()+---------+------+---------+----+-------------------+
|    names|height| function|rank|            new_col|
+---------+------+---------+----+-------------------+
|  optimus|  28.0|   leader|  10|     optimus leader|
| ironhide|  26.0| security|   7|  ironhide security|
|bumblebee|  17.5|espionage|   7|bumblebee espionage|
+---------+------+---------+----+-------------------+

非嵌套操作

从单个列创建多个列的操作 1–> *。 unnest() 可以扩展字符串数组向量列。

df.cols.unnest("new_col", " ").cols.drop("new_col")+---------+------+---------+----+---------+---------+
|    names|height| function|rank|new_col_0|new_col_1|
+---------+------+---------+----+---------+---------+
|  optimus|  28.0|   leader|  10|  optimus|   leader|
| ironhide|  26.0| security|   7| ironhide| security|
|bumblebee|  17.5|espionage|   7|bumblebee|espionage|
+---------+------+---------+----+---------+---------+

自定义转换

Spark 有多种多样的方式来转换数据:

  • 列表达式
  • 南非民主统一战线(United Democratic Front)
  • 熊猫 UDF
  • 结构化查询语言
  • RDD

这里的问题是你必须学习如何处理每个 API 的细节。Optimus 有两个函数 apply()apply_expr() ,在其中你可以实现函数(UDF 或熊猫 UDF)或列表达式。

from pyspark.sql import functions as F
def func(value, args):
    return value + 1df\
    .cols.apply("height", func, "int")\
    .cols.apply_expr("rank", F.col("rank")+1)\
    .show()+---------+------+---------+----+
|    names|height| function|rank|
+---------+------+---------+----+
|  optimus|    29|   leader|  11|
| ironhide|    27| security|   8|
|bumblebee|    18|espionage|   8|
+---------+------+---------+----+

列表达式是最快的,所以总是尝试将它们与 apply_expr() 一起使用

如果你需要更多的灵活性,你可以使用 apply() 来转换你的数据。如果 PyArrow 出现,apply() 将尝试使用熊猫 UDF,否则擎天柱将退回到标准的 UDF。

熊猫 UDF 比标准 UDF 快很多。检查下面的基准:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Pandas UDF Vs UDF

如图表所示,Pandas UDFs 的性能比一次一行的 UDF 好得多,从 3 倍到 100 倍不等。https://databricks . com/blog/2017/10/30/introducing-vectorized-UDFs-for-py spark . html

抽象 UDF

Optimus 提出了抽象 UDF 的概念,其中你可以使用列表达式、UDF 和熊猫 UDF,而不用担心下划线的实现。抽象 udf 函数就是什么权力 apply()apply_expr()。

from optimus.functions import abstract_udf as audf
def func(val, args):
    return val>8df.rows.select(audf("rank", func, "bool")).show()+-------+------+--------+----+
|  names|height|function|rank|
+-------+------+--------+----+
|optimus|  28.0|  leader|  10|
+-------+------+--------+----+

你可以发挥想象力,使用一些论据:

def func(val, args):
    return val+args[0]+args[1]df.withColumn("height", audf ("height", func, "int", [1,2])).show()+---------+------+---------+----+
|    names|height| function|rank|
+---------+------+---------+----+
|  optimus|    31|   leader|  10|
| ironhide|    29| security|   7|
|bumblebee|    20|espionage|   7|
+---------+------+---------+----+

或者只使用列表达式

def func(col_name, args):
    return F.col(col_name) + argsdf.withColumn("height", audf ("height", func, "int", 2, "column_exp")).show()+---------+------+---------+----+
|    names|height| function|rank|
+---------+------+---------+----+
|  optimus|  30.0|   leader|  10|
| ironhide|  28.0| security|   7|
|bumblebee|  19.5|espionage|   7|
+---------+------+---------+----+

正如你所看到的,可以将抽象 udf 与标准 Spark 函数一起使用。

结构化查询语言

如果你觉得使用 SQL 很舒服,你可以通过 df.sql() 轻松使用它。例如:

df.registerTempTable("autobots")
df.sql("SELECT * FROM autobots").show()+---------+------+---------+----+
|    names|height| function|rank|
+---------+------+---------+----+
|  optimus|  28.0|   leader|  10|
| ironhide|  26.0| security|   7|
|bumblebee|  17.5|espionage|   7|
+---------+------+---------+----+

目标 2:让用户轻松地从熊猫迁移

让我们再次回顾一下池图表:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在总共 106 名投票者中,73%的人使用熊猫作为数据清理库。这给了我们一个很好的启示,告诉我们应该如何对待擎天柱。让擎天柱对熊猫尽可能友好。

在总共 106 名投票者中,73%的人使用熊猫作为数据清理库。

考虑到这一点,我们搜索并找到了来自 riselab 的 Devin Petersohn 的惊人作品。他在 ka ggle(https://rise . cs . Berkeley . edu/blog/Pandas-on-ray-early-lessons/)上发表了一篇关于更常用的 Pandas 方法的文章。我们用这个来增强和调整擎天柱。下面你可以找到这个功能,以及它与 Spark 和 Optimus 的比较。

Top 20 most used Pandas compared with Spark and Optimus

NI=未实施
NA=未实施

我们实现了几乎所有可以应用于 Spark 的函数(暂时没有 get 或者 subtract )。有些像 reset_index() 是不可能的,因为 Spark 不处理索引。

这一定够每个熊猫新人追上擎天柱了🙌

让数据探索更容易

Optimus 有一个强大的内置数据分析器,除了所有的基本操作外,它还能给你一些独特的东西。您可以看到特定列中存在多少数据类型。

例如,您有一百万行,颜色值为白色、黑色、红色和数百种其他颜色。你怎么能确定一百万行中没有“1”呢?此功能是一个额外的步骤,可以帮助您使您的数据处于完美的状态,以做您的 ML 和 DL 模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Optimus Profiler

但是我们想更进一步。虽然 Jupyter 笔记本是一个不可思议的数据转换和模型创建工具,但我们认为数据探索领域可以大大改进。工作区似乎永远不足以可视化你的东西,你有很多绘图选项,如 plotly,seaborn,matplotlib an a big 等,每个人都有不同的 API,你必须做很多工作才能使它们交互。

🚗大黄蜂 Alpha 卷展

我们希望为用户提供探索数据的最佳工具。

Bumblebee 是一个使用 Vue.js 构建的 GUI,它与 Optimus 协同工作,并向您准确地展示您需要什么来决定如何转换您的数据。

Bumbleebee in action

此刻,邦布尔伯可以:

  • 使用交互式绘图浏览您的数据。
  • 轻松检查丢失的数据。
  • 查看数据样本以检查数据结构。
  • 查看描述性和分位数分析。
  • 查看直方图和频率表。
  • 检测数字和分类列,并相应地为您提供额外的数据。

大黄蜂和擎天柱不是直接连在一起的。事实上,Bumblebee 可以与从 Pandas 到 dplyr®的任何数据处理库一起使用。如果你想从你最喜欢的库中创建一个“连接器”,你只需要用 bumblebee 格式写一个 JSON 文件。

想了解更多关于大黄蜂的信息,请访问 Github repo

包裹

我们希望 Optimus/Bumblebee 成为处理、探索和制作大数据模型的事实库。为此,我们需要您的反馈,所以我们将推出 Optimus v2 的测试版,为期几周,以听取您对我们所走道路的意见。

如果您想投稿,请:

  • 安装擎天柱,玩一玩,跟我们说说你在 Gitter 上的经历。
  • 如果你对擎天柱对我们的回购有意见,请填写问题。

在这里,我们只是在探索擎天柱的表面功能。请访问 docs.hioptimus.com 的,访问我们的网站或访问笔记本示例,看看 Optimus 能为您的数据做些什么。

宣布数据旅程播客

原文:https://towardsdatascience.com/announcing-the-data-journeys-podcast-57dbbab0f21e?source=collection_archive---------19-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我很激动地宣布我的新播客正式发布,数据之旅:https://www.ajgoldstein.com/podcast/

数据之旅是一个面向有抱负的数据科学家的播客,在这里我将采访世界级的数据科学家,讲述他们的学习之旅。

在每一集里,我们的目标是让他们讲述自己的故事,用世界上最优秀的人曾经使用过的战略、战术和工具来装备后起之秀,让他们达到今天的成就。

我与从美国军方到硅谷、从学术界高层到澳大利亚基层的嘉宾交谈,重点是他们如何弥合获取技术技能和创造现实世界影响之间的差距。

例如,两位即将到来的嘉宾是斯坦福大学 Coursera 的联合创始人吴恩达和加州大学伯克利分校 Jupyter 笔记本的创始人费尔南多·佩雷兹

你可以通过 iTunes、Soundcloud、Google Play Music 等网站的链接收听或订阅该节目:https://www.ajgoldstein.com/podcast/

享受表演吧!

[## 播客

数据之旅数据之旅是 AJ Goldstein 为有抱负的数据科学家制作的播客,他采访了世界一流的…

www.ajgoldstein.com](https://www.ajgoldstein.com/podcast)

宣布推出新的文本分析 Excel 插件版本:这是什么改进!

原文:https://towardsdatascience.com/announcing-the-launch-of-new-text-analytics-excel-add-in-version-heres-what-improved-c3592a9a162?source=collection_archive---------11-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

去年 11 月,我们推出了 Excel 插件,作为我们为那些想使用我们的文本分析产品而无需编写一行代码的用户提供的服务的重要组成部分。这个插件已经被下载了 1000 多次,用来分析超过百万行文本。

我们还从用户那里得到了一些关于 Excel 插件的反馈。在 ParallelDots,我们将客户的反馈放在心上,因此,我们很高兴地宣布我们新的改进版 ParallelDots Excel 加载项的发布。新版本可以立即下载,并且可以从这里访问。

这个新的、改进的 Excel 加载项版本将具有以下主要功能:

  1. **不需要记住 API 键:**使用你的 ParallelDots 帐户直接从加载项的任务窗格登录。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. **修复了错误并提高了稳定性:**当前版本不会冻结超过 1000 行的数据,并允许您在分析数据时最小化 Excel 以执行其他任务。它还为您提供了一个任务进度条,这样您就知道已经分析了多少文本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.**在任务窗格中检查您的 API 使用情况:**登录您的帐户后,您可以在任务窗格中检查 API 使用情况。免费和高级用户都可以使用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

感谢您的反馈和建议,这有助于我们使这个版本更加稳定和用户友好。

安全和隐私

Excel 插件建立在我们的 API 上,这意味着您的数据在我们的服务器上处理,以获得最终输出。我们非常重视用户隐私,我们的隐私政策可在此处访问。所有用户数据都根据我们的隐私政策进行存储,以确保高标准的安全性。

然而,在某些情况下,由于合同义务或其他原因,用户可能希望将数据保存在内部,在这种情况下,我们可以在内部部署这些算法,并相应地构建插件。请向我们发送一个请求来部署本地 API 和您希望我们构建的任何自定义功能。

我们希望新的插件版本将帮助您分析客户满意度调查中成千上万个开放式问题的答案,或者分析来自电子商务门户网站的产品评论,而无需离开您舒适的电子表格。

点击阅读更多关于 Excel 插件的使用案例。

Excel 插件已被证明是一种强大且经济高效的方式,可以开始将尖端智能添加到您的分析中。在您决定扩展您的分析之前,大量的免费层可让您测试并了解加载项中可用的不同功能。

我们希望你喜欢这篇文章。请注册免费的 ParallelDots 账户,开始你的 AI 之旅。你也可以在这里查看的人工智能 API 的演示。

异常检测-关键特性

原文:https://towardsdatascience.com/anomaly-detection-def662294a4e?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我最近与 CleverTap 合作了一个项目,其中包括为定期拥有时间序列类型数据的客户创建“异常检测”功能。异常检测对于每个营销人员密切关注公司的发展非常有帮助。在我实习期间,我们实现了一些基本方法,然后转向更复杂的算法。

“这个特性有什么帮助?”

异常检测可以手动完成。但是由于事件和 KPI 的增加,这个任务很难维持。此外,营销人员没有兴趣知道异常是否发生在 4 个月或 6 个月前。因此,如果营销人员每天都收到异常情况发生时的警报,这将有助于找到其背后的原因,并尽快修复它。这就是为什么我们决定每天都这样做,如果事件以令人惊讶的方式发生,营销人员将收到“检测到异常”的警报。

“什么是异常?”

在深入研究我们开发的这项功能背后的算法之前,我们先来回答上面的问题。

“异常是观察到的世界中意料之外的行为”。

从营销人员的角度来看,异常的例子有 :

  1. 电影票销售数量的减少。
  2. 该应用程序的下载量上升。
  3. 网站访问量的增加。

异常可以是正的,也可以是负的。积极的异常现象在市场上最受欢迎。

“有哪些方法?”

有各种方法来检测异常。在讨论这些方法之前,让我们先看看我们的时间序列数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1: Time Series of a number of visits to a particular website.

这里,图 1 中的时间序列是社交媒体上特定网站每天的访问次数的数据示例(横轴为日期,纵轴为计数)。在这个时间序列中,我们的目标是能够检测到 1 月 21 日之后的异常情况。

1.移动平均法:

在这种方法中,借助于过去数据的移动平均值,可以估计当前值。移动平均线可以是指数移动平均线或简单移动平均线。与简单移动平均线给出的同等权重不同,指数移动平均线给最近的数据更多的权重。

该方法可以通过两种方式执行 :

A.每日移动平均线

在我们将要讨论的所有方法中,这是一个非常基本且易于执行的方法。在这种方法中,前几天的移动平均值被认为是当天的期望值。下一步包括检查估计值是否在预定义的置信带内。置信区间是一个范围,我们将其定义为前一天移动平均线的标准差的倍数

在对上述时间序列应用该算法后,产生了两个异常 :

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2 : Anomalies detected in Moving Average Method(daily basis) are flagged.

下表解释了上述标记值的异常性质:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3 : Results from MA(Daily Basis) method.

如果我试着用置信带来表示,2 月 3 日的反常性质可以解释如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 4 : Plot showing the anomalous nature of 3rd February through Confidence band.

在上图中,该值被标记为(异常),因为它超过了当天的预期最大值(置信区间上限)。

B.工作日移动平均值

这个方法是对上面解释的方法的一个微小的修改。在这种方法中,会考虑以前工作日的数据。也就是说,为了估计当前星期一的价值,以前星期一的数据是有用的。置信区间是以前工作日数据标准差的倍数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 5: Anomalies detected in Moving Average Method(Weekday basis) are flagged

上图中的反常自然点可以用下表来解释:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 6: Results from MA(Weekday Basis)

但是这种方法也导致了类似 2 月 4 日(星期日)的虚假异常。我们来看看周日的数据:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 7: Sunday Counts

如果你看上面显示周日数据的表格,你会发现在 2 月 4 日之前,访问量平稳增长。因此,这不是一个异常现象。相反,它应该将 2 月 18 日显示为异常,因为正如您从上表中看到的,计数在 2 月 18 日突然下降。

  1. ARIMA :

与上面的方法相比,这是一种更复杂的方法。 ARIMA (自回归综合移动平均)方法优于上述方法,因为它使用了自回归移动平均的组合来估计当天的值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 8: Anomalies detected in the ARIMA method are flagged

上述各点的异常性质如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 9: Results from ARIMA method

ARIMA 模型检测到这些点是一个异常,乍一看似乎是一个异常。

3.先知:

脸书出版的《预言家》使用了加性回归模型。这个模型有助于发现异常。Prophet 通过从数据中选择变化点来自动检测趋势的变化,并通过傅立叶变换等技术对季节成分(年、月)进行一些修改。Prophet 使用蒙特卡罗模拟来估计不确定性区间。“不确定性 _ 样本”参数控制模拟。它是用于估计不确定性区间的样本数(默认为 1000)。我们可以使用“interval_width”参数设置这个间隔的宽度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 10: Anomalies detected in the Prophet method are flagged

Prophet 根据下表计算了异常情况:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 11: Results from Prophet method

  1. SH-ESD :

在我实习期间,我们希望实现一些简单的统计计算和更透明的过程。Twitter 发布了季节性杂交极端学生化偏离技术。在 CleverTap 我们修改了(S-ESD)算法并试图实现它。

算法

这一两步过程允许 SH-ESD 检测超出预期季节性最小值和最大值的全球异常和被季节性掩盖的局部异常。

这种改进的算法是在时间序列的“余数”部分上实现的。

残差=时间序列—中位数—季节性

“为什么余数?”

上式中的“余数”项是时间序列中“无法解释的部分”。残差具有单峰分布,该分布服从于异常检测技术的应用,例如 ESD( 极端学生化偏差)。

残差计算:

如上所述,残差计算对于无法解释的行为非常重要。在计算残差时,从原始值中去除了中值和季节性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 12: Remainder component of the time series

这里,季节性是使用STL变量法计算的(使用黄土法计算季节性)。使用中值代替趋势,以避免虚假异常。

“为什么季节性被去除了?”

考虑一个电影预订应用程序,其中电影票的销售额在每个星期六都很高,那么特定一周中的星期六的高价值对于营销人员来说不应该是一个惊喜。因此,季节性被去除以避免由于季节性行为造成的虚假异常。

“如何处理剩余组件?”

为了找出异常值,我们对剩余数据进行了修正的 ESD 测试。这种改进的 ESD 测试分为两步:

。该测试的第一步是计算修改后的 z 分数。这是对原始分数低于或高于中位数的平均偏差的度量。z 分值越高,意味着与中位数的平均偏差越高。

修改后的 Z 得分= (X 中值)/MAD

X =原始数据

MAD =中位数绝对偏差

注意:与一般的 z 值不同,中值和 MAD(中值绝对偏差)术语用于代替“平均值”和“标准差”。原因是后来离群值对它们有更多的影响。这解释了上述术语中的“修改”部分。

。第二步从移除与中值偏差最大的值开始。我们再次计算 Z 得分的新值。在应用置信度后,新的修改后的 z 分值将给出实际的异常值。原始数据中对应于残差数据中异常值索引的值是异常值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 13: Anomalies detected from the modified SH-ESD method

在对剩余数据进行修改后的 ESD 测试后,结果标记为 1 月 31 日,乍一看并不像异常。

“为什么 1 月 31 日是个例外?”

由于我们使用的是每周季节性,周三图应该可以解释 1 月 31 日的反常性质。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 14: The above plot shows the Wednesday trend

1 月 31 日周三数据计数的下降导致了一个异常现象。

“如何利用异常信息?”。

有许多方法可以使用这些信息。此功能的主要用途是,营销人员将收到警报,这将有助于保护这种异常行为的任何负面影响。

考虑一个例子,其中应用规范已经被修改,第二天公司收到关于应用下载数量突然减少的警报。营销人员会在公司特定团队的帮助下,试图在修改后的规范中找到问题。

结论:

我们看到了各种检测异常的方法。这些方法在执行难度和结果方面各不相同。移动平均等基本方法易于执行,但结果较差,而 ARIMA、Prophet 等复杂方法的结果较好,但在大型数据库级别难以执行。因此,改进的 SH-ESD 是最好的方法,具有简单的统计计算、更透明的过程和令人敬畏的结果。

基于机器学习的移动传感器数据异常检测

原文:https://towardsdatascience.com/anomaly-detection-in-mobile-sensor-data-48ef62d0f7fc?source=collection_archive---------3-----------------------

本帖摘自我们的解决方案教程—“收集、可视化和分析物联网数据。该教程将引导您设置物联网设备,在 Watson 物联网平台中收集移动传感器数据,探索数据并创建可视化效果,然后使用高级机器学习服务来分析数据并检测历史数据中的异常。

那么,什么是异常检测呢?

异常检测是一种用于识别不符合预期行为的异常模式(称为异常值)的技术。它在商业中有许多应用,从入侵检测(识别网络流量中可能预示黑客攻击的奇怪模式)到系统健康监控(在 MRI 扫描中发现恶性肿瘤),从信用卡交易中的欺诈检测到操作环境中的故障检测。

在我们的日常生活中,无论是有意还是无意,我们都会携带物联网设备。它是我们内置传感器的手机,提供来自加速度计和陀螺仪的数据。将这些传感器数据保存在某个地方并检测数据中的异常情况如何?

那听起来是个很酷的主意。如何才能实现这一点?我需要编写一个应用程序并要求用户从商店下载吗?不需要。运行在移动浏览器上的简单 node.js 应用程序将为我们提供传感器数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本教程使用以下 IBM 产品:

这是流程或架构图,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Architecture diagram

因此,您将创建一个 node.js 应用程序,在浏览器上运行它,将加速度计和陀螺仪数据存储到 Cloudant NoSQL 数据库,然后我如何检测异常?

这就是 IBM Watson Studio 派上用场的地方。您将使用 IBM Watson Studio 服务中提供的 Jupyter 笔记本来加载历史数据,并使用 z-score 检测异常。您将首先创建一个新项目,然后导入 Jupyter 笔记本(。ipynb)通过 URL。

将使用 z 分数进行异常检测。Z-score 是一个标准分数,表示一个元素相对于平均值的标准偏差。可以通过以下公式计算 z 得分:z = (X - µ) / σ其中 z 是 z 得分,X 是元素的值,是总体均值,σ是标准差。

此链接https://cloud.ibm.com/docs/solution-tutorials?提供最新教程 topic =解决方案-教程-收集-可视化-分析-物联网-数据

又一次机器学习演练和挑战

原文:https://towardsdatascience.com/another-machine-learning-walk-through-and-a-challenge-8fae1e187a64?source=collection_archive---------3-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不要只是阅读机器学习——实践它!

在花费大量时间和金钱学习课程、书籍和视频后,我得出了一个结论:学习数据科学最有效的方法是做数据科学项目。阅读、倾听和记笔记是有价值的,但是直到你解决了一个问题,概念才从抽象固化为你有信心使用的工具。

在本文中,我将介绍 Python 中的另一个机器学习演练,并留给您一个挑战:尝试开发一个更好的解决方案(包括一些有用的技巧)!这个项目完整的 Jupyter 笔记本可以在 Kaggle 上运行——不需要下载——或者在 GitHub 上访问

问题陈述

目前正在 Kaggle 上运行的纽约市出租车费用预测挑战赛,是一项监督回归机器学习任务。给定上下车地点、上下车时间戳和乘客数量,目标是预测出租车的费用。像大多数 Kaggle 竞赛一样,这个问题并不能 100%反映行业中的问题,但它确实提供了一个现实的数据集和任务,我们可以在其上磨练我们的机器学习技能。

为了解决这个问题,我们将遵循一个标准的数据科学管道攻击计划:

  1. 了解问题和数据
  2. 数据探索/数据清理
  3. 特征工程/特征选择
  4. 模型评估和选择
  5. 模型优化
  6. 结果和预测的解释

这个大纲似乎从头到尾呈现了一个线性路径,但数据科学是一个高度非线性的过程,其中的步骤是重复的或无序完成的。随着我们对数据越来越熟悉,我们经常想回去重新审视我们过去的决定或采取新的方法。

虽然最终的 Jupyter 笔记本可能会呈现一个有凝聚力的故事,但开发过程非常混乱,包括重写代码和更改早期的决定。

在整篇文章中,我会指出一些我认为有进取心的数据科学家——您——可以改进我的解决方案的地方。我将这些潜在的改进标记为因为作为一个主要的经验领域,机器学习没有保证。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

New York City Taxi Fare Prediction Challenge (Link)

入门指南

出租车费用数据集相对较大,有 5500 万个训练行,但易于理解,只有 6 个特征。fare_amount是目标值,我们将训练一个模型来预测的连续值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Training Data

在整个笔记本中,我只使用了 5,000,000 行样本来加快计算速度。因此,我的第一个建议是:

  • 潜在改进 1:使用更多数据训练模型

不确定大量的数据是否会有所帮助,但是经验研究发现,一般来说,随着用于训练模型的数据量增加,性能也会提高。根据更多数据训练的模型可以更好地学习实际信号,特别是在具有大量特征的高维问题中(这不是高维数据集,因此使用更多数据的回报可能有限)。

尽管数据集的庞大规模可能令人生畏,但是像 Dask 这样的框架允许你在个人笔记本电脑上处理甚至是海量的数据集。此外,一旦数据超出了你的机器的能力,学习如何设置和使用云计算,比如 Amazon ECS,是一项至关重要的技能。

幸运的是,理解这些数据并不需要太多的研究:我们大多数人以前都乘坐过出租车,我们知道出租车是根据行驶里程收费的。因此,对于特征工程来说,我们需要找到一种方法,根据给定的信息来表示行进的距离。我们也可以阅读其他数据科学家的笔记本或竞赛讨论来寻找解决问题的方法。

数据探索和清理

尽管 Kaggle 数据通常比真实世界的数据更干净,但该数据集仍存在一些问题,即多个要素中存在异常。我喜欢将数据清理作为探索过程的一部分,纠正我发现的异常或数据错误。对于这个问题,我们可以通过使用df.describe()查看数据的统计来发现异常值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Statistical description of training data

通过结合领域知识和查看数据分布,解决了passenger_count、坐标和fare_amount中的异常。例如,阅读纽约市的出租车费用,我们看到最低费用金额为 2.50 美元,这意味着我们应该根据费用排除一些乘坐。对于坐标,我们可以查看分布,并排除那些超出正常范围的值。一旦我们确定了异常值,我们就可以使用如下代码来删除它们:

*# Remove latitude and longtiude outliers*
data = data.loc[data['pickup_latitude'].between(40, 42)]
data = data.loc[data['pickup_longitude'].between(-75, -72)]
data = data.loc[data['dropoff_latitude'].between(40, 42)]
data = data.loc[data['dropoff_longitude'].between(-75, -72)]

一旦我们清理了数据,我们就可以进入有趣的部分:可视化。下面是纽约市上下客地点的图表,用装箱后的票价进行着色(宁滨是将连续变量转化为离散变量的一种方式)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Pickups and Dropoffs plotted on New York City

我们还想看看目标变量。以下是目标变量票价金额的经验累积分布函数(ECDF) 图。对于一个变量来说,ECDF 可能是比直方图更好的可视化选择,因为它没有来自宁滨的伪像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ECDF of Target

除了看起来有趣之外,图可以帮助我们识别异常、关系或新功能的想法。在地图中,颜色代表票价,我们可以看到从机场(右下角)开始或结束的票价往往是最贵的。回到领域知识,我们读到去 JFK 机场的标准费用是 45 美元,所以如果我们能找到识别机场乘车的方法,那么我们就能准确地知道费用。

虽然我在这本笔记本中没有谈到那么远,但是使用领域知识进行数据清理和特性工程是非常有价值的。我的第二个改进建议是:

  • 潜在改进 2:试验不同的离群点去除和数据清理方法。

这可以通过领域知识(如地图)或统计方法(如 z 分数)来完成。解决这个问题的一个有趣的方法是在这个笔记本中,作者删除了在水中开始或结束的游乐设施。

包含/排除异常值会对模型性能产生重大影响。然而,像机器学习中的大多数问题一样,没有标准的方法(这里有一个 Python 中的统计方法你可以试试)。

特征工程

要素工程是从现有数据集中创建新要素(预测变量)的过程。因为一个机器学习模型只能从给定的特征中学习,这是机器学习流水线 中 最重要的一步。

对于有多个表和表之间关系的数据集,我们可能想要使用自动化特征工程,但是因为这个问题只有相对较少的列和一个表,我们可以手工构建一些高价值的特征。

例如,因为我们知道乘坐出租车的费用与距离成正比,所以我们想要使用起点和终点来尝试并找到行驶的距离。距离的一个粗略近似值是起点和终点纬度和经度之差的绝对值。

# Absolute difference in latitude and longitude
data['abs_lat_diff'] = (data['dropoff_latitude'] - data['pickup_latitude']).abs()data['abs_lon_diff'] = (data['dropoff_longitude'] - data['pickup_longitude']).abs()

功能不一定要复杂才有用!下面是这些新功能的图表,用装箱的费用来着色。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Absolute Longitude vs Absolute Latitude

这些特征给我们的是距离的相对度量,因为它们是根据纬度和经度计算的,而不是实际的度量。这些特征对于比较是有用的,但是如果我们想要以公里为单位进行测量,我们可以在旅行的开始和结束之间应用哈弗辛公式,该公式计算大圆距离。这仍然是一个近似值,因为它给出了沿着地球球形表面(我被告知地球是一个球体)上连接两点的直线的距离,显然,出租车不是沿着直线行驶的。(详见笔记本)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Haversine distance by Fare (binned)

这个问题的其他主要特征来源是基于时间的。给定一个日期和时间,我们可以提取许多新的变量。构建时间特性是一项常见的任务,我在笔记本中包含了一个有用的函数,它可以从一个时间戳构建十几个特性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fare amount colored by time of day

虽然我在这个项目中构建了将近 20 个特性,但是还有更多的特性有待发现。特征工程最难的部分是你永远不知道什么时候你已经用尽了所有的选择。我的下一个建议是:

  • 潜在的改进 3:构建更多的特征或将特征选择应用于现有的特征,以找到最优集合。

特征工程还包括问题专家或应用自动为你构建特征的算法。在构建特征之后,你经常需要应用特征选择来找到最相关的特征。

一旦有了干净的数据和一组特征,就可以开始测试模型了。尽管特征工程在大纲建模之前,我经常在项目过程中一次又一次地回到这一步。

模型评估和选择

建立回归任务基线的首选模型是简单的线性回归。此外,如果我们查看该问题中要素与票价金额的 Pearson 相关性,我们会发现如下所示的几个非常强的线性关系。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Pearson Correlations of Features with Target

基于一些特征和目标之间的线性关系的强度,我们可以期望线性模型做得相当好。虽然集成模型和深度神经网络得到了所有的关注,但如果一个简单、可解释的模型可以实现几乎相同的性能,那么就没有理由使用过于复杂的模型。尽管如此,尝试不同的模型仍然是有意义的,特别是因为它们很容易用 Scikit-Learn 来构建。

初始模型是一个只对三个特征(abs位置差异和passenger_count)进行训练的线性回归,其验证均方根误差(RMSE)为 5.32 美元,平均绝对百分比误差为 28.6%。简单线性回归的好处是,我们可以检查系数,例如,根据模型,一名乘客的增加会使票价增加 0.02 美元。

# Linear Regression learned parametersIntercept 5.0819
abs_lat_diff coef:  113.6661 	
abs_lon_diff coef: 163.8758
passenger_count coef: 0.0204

对于 Kaggle 竞赛,我们可以使用验证集(这里我使用了 1,000,000 个示例)和向竞赛提交测试预测来评估模型。这使我们能够将我们的模型与其他数据科学家进行比较-线性回归放置大约 600/800。理想情况下,我们希望只使用测试集一次,以评估我们的模型在新数据上的表现,并使用验证集(或交叉验证)执行任何优化。Kaggle 的问题是,排行榜可能会鼓励竞争对手建立对测试数据过度优化的复杂模型。

我们还希望将我们的模型与不使用机器学习的原始基线进行比较,在回归的情况下,原始基线可以猜测训练集上目标的平均值。这导致 9.35 美元的 RMSE,这使我们有信心机器学习适用于该问题。

即使在额外的特征上训练线性回归也不会产生很高的排行榜分数,下一步是尝试更复杂的模型。我的下一个选择通常是随机森林,这也是我上交这个问题的地方。与线性回归相比,随机森林是一种更灵活的模型,这意味着它具有更小的偏差,可以更好地拟合训练数据。随机森林通常也具有低方差,这意味着它可以推广到新数据。对于这个问题,随机森林优于线性回归,在相同的功能集上实现了 4.20 美元的验证 RMSE。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Test Set Prediction Distributions

随机森林通常优于线性回归的原因是因为它具有更大的灵活性——更低的偏差——并且它减少了方差,因为它将许多决策树的预测结合在一起。线性回归是一种简单的方法,因此具有较高的偏差,它假设数据是线性的。线性回归也可能受到异常值的高度影响,因为它以最小的误差平方和来求解拟合。

模型(和超参数)的选择代表了机器学习中的偏差-方差权衡:具有高偏差的模型甚至无法准确地学习训练数据,而具有高方差的模型本质上是记忆训练数据,无法推广到新的例子。因为机器学习的目标是对新数据进行归纳,所以我们想要一个同时具有低偏差和低方差的模型。

一个问题上的最佳模型不一定是所有问题上的最佳模型,因此研究跨越复杂范围的几个模型是很重要的。应使用验证数据评估每个模型,然后在模型调整中优化表现最佳的模型。由于验证结果,我选择了随机森林,并且我鼓励您尝试一些其他模型(或者甚至将模型组合在一起)。

模型优化

在机器学习问题中,我们有几种提高性能的方法:

  1. 获取更多数据
  2. 构建更多特征/执行特征选择
  3. 优化选择的模型
  4. 尝试更复杂的模型

1 英镑仍有收益。第二。(这是挑战的一部分),但我也想提供一个优化所选模型的框架。

模型优化是在给定数据集上为模型找到最佳超参数的过程。因为超参数的最佳值取决于数据,所以对于每个新问题,都必须再次这样做。

我喜欢将模型优化(也称为模型调整)视为寻找机器学习模型的理想设置。

优化的方法有很多种,从手动调整到自动超参数调整,但是在实践中,随机搜索效果很好,并且易于实现。在笔记本中,我提供了运行随机搜索进行模型优化的代码。为了使计算时间合理,我再次对数据进行采样,只运行了 50 次迭代。即使这样也需要相当长的时间,因为超参数是使用三重交叉验证来评估的。这意味着在每一次迭代中,模型都要用超参数的选定组合训练 3 次!

The best parameters were {'n_estimators': 41, 'min_samples_split': 2, 'max_leaf_nodes': 49, 'max_features': 0.5, 'max_depth': 22, 'bootstrap': True}with a negative mae of -2.0216735083205952

我还尝试了许多不同的功能,发现最好的模型只使用了 27 个功能中的 12 个。这是有意义的,因为许多特性是高度相关的,因此是不必要的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Heatmap of Correlation of Subset of Features

在运行随机搜索并选择特征之后,最终的随机森林模型实现了 3.38 的 RMSE,这表示 19.0%的百分比误差。这比原始基线的误差减少了 66%,比第一个线性模型的误差减少了 30%。这种表现说明了机器学习中的一个关键点:

特征工程的回报远远大于模型优化的回报。因此,在开始担心是否有最好的超参数之前,确保您有一组好的特征是至关重要的。

尽管我运行了 50 次随机搜索迭代,超参数值可能还没有完全优化。我的下一个建议是:

  • 潜在的改进 4:在更多的数据上运行更多迭代的模型调优。

这样做的回报可能会比特性工程少,但是仍然有可能发现性能的提高。如果您觉得能够胜任这项任务,您也可以使用诸如 Hyperopt 之类的工具来尝试自动化模型调优(我写了一个指南,可以在这里找到)。)

解释模型并做出预测

虽然随机森林比线性回归更复杂,但它不是一个完整的黑箱。一个随机森林由一群决策树组成,这些决策树本身就是非常直观的流程图模型。我们甚至可以检查森林中的每棵树,了解它们是如何做决定的。查看随机森林黑盒的另一种方法是检查特征的重要性。技术细节目前并不重要,但是我们可以使用相对值来确定哪些特性被认为与模型相关。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Feature Importances from training on all features

到目前为止,最重要的特征是乘坐出租车的欧几里德距离,其次是时间变量之一的pickup_Elapsed。鉴于我们制造了这两个特性,我们应该相信我们的特性工程得到了很好的利用!因为我们不需要保留所有的变量,所以我们也可以突出特征工程或选择的重要性。

最后,我们可以看看验证数据和测试数据上的模型预测。因为我们有了验证答案,我们可以计算预测的误差,并且我们可以检查极值的测试预测(在线性回归中有几个)。下面是最终模型的验证预测图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Random Forest validation predictions and true values.

模型解释仍然是一个相对较新的领域,但是有一些有前途的方法来检查模型。虽然机器学习的主要目标是对新数据做出准确的预测,但同样重要的是要知道为什么模型是准确的,以及它是否能教会我们关于这个问题的任何东西。

后续步骤

尽管我们尝试了许多不同的技术并实现了一个完整的解决方案,但仍有一些步骤可以改进模型。我的下一个方法是尝试一个更复杂的模型,比如深度神经网络或梯度推进机器。我还没有在笔记本上实现这些,但是我正在努力实现它们。我让你先试试(我不能把所有答案都给你!).

有了机器学习项目,总是有更多的方法可以尝试,如果你对现有的选项不满意,你甚至可以想出自己的方法!机器学习在很大程度上是一个经验领域,没有标准化的规则,知道某样东西是否有效的唯一方法是测试它。

在这一点上,我将留给您自己的设备来改进模型。我已经给了你五个不同的建议,应该可以让你打破我在笔记本上取得的最好的交叉验证分数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Final Model Results

这当然是一个友好的挑战,所以不要沮丧,如果你需要帮助,不要犹豫。所有这些建议都是潜在的改进,因为我不能保证它们会提高分数。尽管如此,我知道构建一个更好的模型是可能的,我也会努力尝试并构建它!

如果你需要更多的灵感,这里有我做过的另外两个完整的机器学习项目,可以给你一些思路:

接下来的步骤就看你的了!

结论

在这篇文章和附带的 Jupyter 笔记本中,我展示了一个真实数据集上的完整机器学习走查。我们用 Python 代码实现了该解决方案,并触及了机器学习中的许多关键概念。机器学习不是一门神奇的艺术,而是一门可以通过重复磨练的手艺。没有什么可以阻止任何人学习如何使用机器学习来解决现实世界的问题,而变得熟练的最有效的方法是完成项目。

本着边做边学的精神,我对你们的挑战是改进我在笔记本电脑中的最佳模型,我给你们留下了一些建议,我相信它们会提高性能。在数据科学中没有一个正确的答案,我期待看到每个人都可以提出什么!如果你接受挑战,请在评论中留下你笔记本的链接。希望这篇文章和笔记本已经给了你解决这个问题或其他问题所必需的开始。此外,当您确实需要帮助时,请不要犹豫,因为数据科学界总是支持您。

一如既往,我欢迎反馈、讨论和建设性的批评。可以通过 Twitter @koehrsen_will 或者评论这篇文章找到我。

又一次尝试内核技巧(为什么?)

原文:https://towardsdatascience.com/another-stab-at-the-kernel-trick-why-f73c70ce98dd?source=collection_archive---------16-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Markos Mant on Unsplash

有很多很棒的关于支持向量机的教程,以及如何在二分类中应用(这里有一个还有一个)。但是我想更深入地探究内核技巧以及为什么使用它。

支持向量机依赖于将特征空间扩大到允许两个类别可由线性超平面分开的维度。实现这一点的第一种方法更简单,就是转换输入数据。这意味着将输入要素转换为方形、立方体或其他形式,以生成新的附加要素。另一种方法是使用内核。

核是一个函数,它在一个期望的维度上表示两个观察值之间的相似性(数学上由 Mercer 定理定义,有谷歌)。具有相同坐标的两个观测值之间的相似性是 1,并且随着它们之间的欧几里德距离的增加而趋向于 0。

不用太数学化,解决 SVM 优化问题以找到超平面位置所需的计算是观测值之间的内积。内积的输出是一个标量,这意味着我们感兴趣的输出存在于一个维度中,而不是我们为了分离数据而访问的任何疯狂的维度空间。内积计算等价于线性核函数,并在线性空间中表示相似性。

这很重要的原因是,这意味着在更高维度中的观察值与我们无关,我们只关心内积结果。这个内积可以通过方法一的两个步骤来计算,转换输入数据,然后计算内积。或者对输入数据应用内核。方法二的好处是计算效率。

计算效率源于以下事实:核计算比将输入数据变换到线性分离数据所需的更高维度所需的计算更快。

您可以直观地思考为什么这样会更快,因为不需要首先执行数据转换,然后执行内积计算,您只需在一个步骤中应用一个核函数,就可以得到内积结果,瞧!

当问题非常简单,并且只对输入数据进行二次或三次变换就足以允许数据是线性可分的时,使用核技巧没有什么好处。

但是假设你有一个两个类之间的径向边界,如下图所示。要弄清楚如何转换输入数据,以便能够线性地分离下面的类,这是令人难以置信的,因为它的计算成本很高。这就是内核(在这种情况下为径向/高斯)真正发挥作用的地方,观察值之间的相似性计算在转换输入数据时得到了极大的改进。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image credit: https://chrisalbon.com/machine_learning/support_vector_machines/svc_parameters_using_rbf_kernel/

这只是一个简短的故事(也是我的第一个),关于为什么内核技巧在困难的二进制分类问题中被广泛使用,我希望很快就能在参数调整等方面使用内核技巧。

原载于 2018 年 11 月 17 日【medium.com

另一个使用 Python 的 Twitter 情感分析—第 1 部分

原文:https://towardsdatascience.com/another-twitter-sentiment-analysis-bb5b01ebad90?source=collection_archive---------1-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Clint Patterson on Unsplash

距离我上次发帖已经有一段时间了。我不在灵媒期间,我的生活发生了很多事情。我最终鼓起勇气辞去了工作,加入了伦敦大会的数据科学沉浸式课程。

这是我一生中的一个重大决定,但我不后悔。事实上,我认为这是我迄今为止做的最好的决定。这门课程相当紧张,但我很享受其中的每一点。我学到了很多更严谨的数据科学方法,最重要的是,我从导师和同学那里得到的反馈真的帮助我提高了。不容易但是绝对值得!

我目前在第八周,并为我的顶点项目做准备。正如标题所示,这将是关于 Twitter 的情绪分析。

起初,我并不确定我应该为我的顶点做些什么,但毕竟,我感兴趣的领域是自然语言处理,Twitter 似乎是我 NLP 之旅的一个很好的起点。你可以从这里找到我最初的项目创意提案。

给你一个关于这个项目的简要总结,它是关于建立一个可以检测情绪的模型,这样我就可以将这个模型应用到来自不同城市的推文中,并比较/分析来自不同城市的推文有多快乐。这是从我自己的好奇心开始的。对我来说,快乐是生活中相当重要的因素,我认为它很大程度上取决于你的环境。所以很自然地,我想看看不同城市的市民有多幸福。

训练数据

可以有许多不同的方法来进行情感分析,一些库提供了开箱即用的情感分析功能,你可以直接在文本上使用,但这并不有趣(是吗?).所以我决定训练我自己的模型,我可以将它应用到我收集的推文中。为了让一个模型有不错的性能,我需要一个相对较大的数据集来训练。用于训练的数据集,我选择的是源自斯坦福大学的“Sentiment140”。关于数据集的更多信息可以从链接中找到。【http://help.sentiment140.com/for-students/

数据集可以从下面的链接下载。
http://cs . Stanford . edu/people/Alec MgO/training and test data . zip

通过查看链接中数据集的描述,可以找到每个字段的信息。

0 —推文的极性(0 =负,2 =中性,4 =正)
1 —推文的 id(2087)
2—推文的日期(2009 年 5 月 16 日星期六 23:58:44 UTC)
3—查询(lyx)。如果没有查询,那么这个值就是 NO_QUERY。
4 —发推文的用户(robotickilldozr)
5 —推文的文本(Lyx 很酷)

好,我们先来看看数据

import pandas as pd  
import numpy as np
import matplotlib.pyplot as plt
cols = ['sentiment','id','date','query_string','user','text']
df = pd.read_csv("./trainingandtestdata/training.1600000.processed.noemoticon.csv",header=None, names=cols)
# above line will be different depending on where you saved your data, and your file name
df.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

df.sentiment.value_counts()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据集有 160 万个条目,没有空条目,重要的是对于“情绪”列,即使数据集描述提到了中性类,训练集也没有中性类。
50%的数据带有负标签,另外 50%带有正标签。我们可以看到在阶级划分上没有偏斜。

df.drop(['id','date','query_string','user'],axis=1,inplace=True)

我首先删除了不需要用于情感分析的列。

“id”列是每条推文的唯一 ID
“date”列是推文的日期信息
“QUERY _ string”列指示推文是否使用任何特定的查询关键字收集,但是对于该列,100%的条目都具有值“NO _ QUERY”
“user”列是发布推文的用户的 twitter 句柄名称

我决定放弃四列以上。

df[df.sentiment == 0].head(10)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

df[df.sentiment == 4].head(10)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过查看每个类的一些条目,似乎所有负类都是从 0 ~ 799999 索引,正类条目从 800000 开始到数据集的末尾。

数据准备

作为健全性检查的一种方式,让我们看看每个条目的文本列中字符串的长度。

df['pre_clean_len'] = [len(t) for t in df.text]

数据字典—初稿

下面是数据集的数据字典的第一稿,但在我准备的过程中,这将需要更新。

from pprint import pprint
data_dict = {
    'sentiment':{
        'type':df.sentiment.dtype,
        'description':'sentiment class - 0:negative, 1:positive'
    },
    'text':{
        'type':df.text.dtype,
        'description':'tweet text'
    },
    'pre_clean_len':{
        'type':df.pre_clean_len.dtype,
        'description':'Length of the tweet before cleaning'
    },
    'dataset_shape':df.shape
}pprint(data_dict)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我还将使用方框图绘制 pre_clean_len,这样我可以看到每个条目中字符串长度的总体分布。

fig, ax = plt.subplots(figsize=(5, 5))
plt.boxplot(df.pre_clean_len)
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这看起来有点奇怪,因为 twitter 的字符限制是 140。但是从上面的方框图来看,一些推文的长度远远超过了 140 个字符。

df[df.pre_clean_len > 140].head(10)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看起来是时候打扫卫生了!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

资料准备 1: HTML 解码

看起来 HTML 编码没有被转换成文本,并以’ &amp ‘,’ &quot '等形式出现在文本字段中。将 HTML 解码为一般文本将是我数据准备的第一步。我会用 BeautifulSoup 来做这个。

df.text[279]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

from bs4 import BeautifulSoup
example1 = BeautifulSoup(df.text[279], 'lxml')
print example1.get_text()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据准备 2: '@ '提及

准备的第二部分是处理@提及。
即使 another 携带了某种信息(该推文提到的另一个用户),这些信息并没有为建立情感分析模型增加价值。

df.text[343]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

import re
re.sub(r'@[A-Za-z0-9]+','',df.text[343])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据准备 3: URL 链接

清理的第三部分是处理 URL 链接,与@ reference 相同,即使它携带一些信息,出于情感分析的目的,这可以被忽略。

df.text[0]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

re.sub('https?://[A-Za-z0-9./]+','',df.text[0])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据准备 4: UTF-8 BOM(字节顺序标记)

df.text[226]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过查看上面的条目,我可以看到奇怪的字符模式“\xef\xbf\xbd”。经过一些研究,我发现这些是 UTF-8 炸弹。
“UTF-8 BOM 是一个字节序列(EF BB BF),它允许读者识别以 UTF-8 编码的文件。”

通过用“utf-8-sig”解码文本,这个 BOM 将被替换为 unicode 无法识别的特殊字符,然后我可以将它处理为“?”

testing = df.text[226].decode("utf-8-sig")
testing

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

testing.replace(u"\ufffd", "?")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据准备 5:标签/数字

有时与 hashtag 一起使用的文本可以提供关于 tweet 的有用信息。将所有文本和标签一起删除可能有点冒险。所以我决定保持文本不变,只去掉“#”。我将在清理包括数字在内的所有非字母字符的过程中这样做。

df.text[175]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

re.sub("[^a-zA-Z]", " ", df.text[175])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

定义数据清理功能

有了以上五个数据清洗任务,我将首先定义数据清洗函数,然后将应用于整个数据集。当使用计数矢量器或 Tfidf 矢量器创建矩阵时,将在稍后阶段处理标记化、词干化/词元化、停用词。

from nltk.tokenize import WordPunctTokenizer
tok = WordPunctTokenizer()
pat1 = r'@[A-Za-z0-9]+'
pat2 = r'https?://[A-Za-z0-9./]+'
combined_pat = r'|'.join((pat1, pat2))def tweet_cleaner(text):
    soup = BeautifulSoup(text, 'lxml')
    souped = soup.get_text()
    stripped = re.sub(combined_pat, '', souped)
    try:
        clean = stripped.decode("utf-8-sig").replace(u"\ufffd", "?")
    except:
        clean = stripped
    letters_only = re.sub("[^a-zA-Z]", " ", clean)
    lower_case = letters_only.lower()
    # During the letters_only process two lines above, it has created unnecessay white spaces,
    # I will tokenize and join together to remove unneccessary white spaces
    words = tok.tokenize(lower_case)
    return (" ".join(words)).strip()testing = df.text[:100]test_result = []
for t in testing:
    test_result.append(tweet_cleaner(t))
test_result

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

nums = [0,400000,800000,1200000,1600000]
print "Cleaning and parsing the tweets...\n"
clean_tweet_texts = []
for i in xrange(nums[0],nums[1]):
    if( (i+1)%10000 == 0 ):
        print "Tweets %d of %d has been processed" % ( i+1, nums[1] )                                                                    
    clean_tweet_texts.append(tweet_cleaner(df['text'][i]))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

剩下的,你明白了,我把整个数据集分成四批,并清理它们。

将清理的数据保存为 csv

clean_df = pd.DataFrame(clean_tweet_texts,columns=['text'])
clean_df['target'] = df.sentiment
clean_df.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

clean_df.to_csv('clean_tweet.csv',encoding='utf-8')
csv = 'clean_tweet.csv'
my_df = pd.read_csv(csv,index_col=0)
my_df.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由于帖子越来越长,我将在这里停下来,并尝试在下一个帖子继续。如果你有任何问题,或意见,或建议,请不要犹豫留下评论!谢谢你。

你可以在 Github repo 下面找到 Jupyter 的笔记本文件。

https://github . com/tthustle sa/Twitter _ 情操 _ 分析 _ part 1/blob/master/Capstone _ part 2 . ipynb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值