TowardsDataScience 博客中文翻译 2019(一百零五)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

多标签与多类分类:Sigmoid 与 Softmax

原文:https://towardsdatascience.com/classification-sigmoid-vs-softmax-2a3585ff740f?source=collection_archive---------14-----------------------

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

当设计一个执行分类任务的模型时(例如,对胸部 x 光检查中的疾病进行分类或对手写数字进行分类),我们希望告诉我们的模型是允许选择多个答案(例如,肺炎和脓肿)还是只允许选择一个答案(例如,数字“8”)。)这篇文章将讨论我们如何通过对分类器的原始输出值应用 sigmoid 或 softmax 函数来实现这一目标。

神经网络分类器

分类有很多算法。在这篇文章中,我们主要关注神经网络分类器。不同种类的神经网络可以用于分类问题,包括前馈神经网络卷积神经网络

应用 Sigmoid 或 Softmax

在神经网络分类器的最后,您将获得一个“原始输出值”的向量:例如[-0.5,1.2,-0.1,2.4],如果您的神经网络有四个输出(例如,对应于胸部 x 射线模型中的肺炎、心脏肥大、结节和脓肿)。但是这些原始输出值意味着什么呢?

我们希望将这些原始值转换成一种可以理解的格式:概率。毕竟,告诉病人他们患糖尿病的风险是 91%比“2.4”(这看起来很武断)更有意义。)

我们使用 sigmoid 函数或 softmax 函数将分类器的原始输出值转换成概率。

下面是一个示例,我们使用 sigmoid 函数将前馈神经网络的原始输出值(蓝色)转换为概率(红色):

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

这里有一个例子,我们使用了一个 softmax 函数将这些相同的原始输出值(蓝色)转换成概率(红色):

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

如您所见,sigmoid 和 softmax 函数产生不同的结果。

一个关键点是,由 sigmoid 产生的概率是独立的,并且而不是被约束为总和为 1:0.37+0.77+0.48+0.91 = 2.53。这是因为 sigmoid 分别查看每个原始输出值。

相反,softmax 的输出都是相互关联的。softmax 产生的概率总和总是设计为 1:0.04+0.21+0.05+0.70 = 1.00。因此,如果我们使用 softmax,为了增加一个类别的概率,至少一个其他类别的概率必须减少相等的量。

乙状结肠示例:胸透和住院

*胸部 x 光片:*一张胸部 x 光片可以同时显示许多不同的医疗状况。如果我们为胸部 x 射线建立一个分类器,我们希望该分类器能够指示存在多种情况。这是一张显示肺炎和脓肿的胸部 x 光图像,以及相应的标签,您会注意到其中有多个“1”:

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

*入院:*给定一个病人的健康记录,我们可能想要预测这个病人将来是否会入院。我们可以把这个问题框架化为一个分类问题:根据病人未来的入院诊断(如果有的话)对他们过去的健康记录进行分类。)患者可能因多种疾病入院,因此可能有不止一个正确答案。

*图表:*下图是两个前馈神经网络,对应这两个分类问题。最后,将 sigmoid 函数应用于原始输出值,以获得最终概率,并允许多个正确答案,因为胸部 x 射线可能包含多种异常,并且患者可能因多种疾病而入院。

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

Softmax 示例:手写数字和虹膜

*手写数字:*如果我们正在对手写数字的图像进行分类(MNIST 数据集),我们希望通过使用 softmax 函数来强制分类器只为数字选择一个身份。毕竟,数字 8 的图片只是数字 8;它不能同时是数字 7。

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

一个来自 MNIST 的“8”。从这里的修改的图像

虹膜:虹膜数据集是 1936 年推出的著名数据集。总共包括 150 个例子,分别来自三种不同的鸢尾(鸢尾海滨鸢尾杂色鸢尾)。数据集中的每个例子包括萼片长度、萼片宽度、花瓣长度和花瓣宽度的测量值。

以下是 Iris 数据集的摘录,显示了来自 Iris setosa 类的 9 个示例:

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

虽然数据集不包含任何图像,但这里的是一张云芝 的照片,因为它很漂亮:

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

如果我们为 iris 数据集构建一个神经网络分类器,我们希望将 softmax 函数应用于原始输出,因为单个 Iris 示例一次只能是一个物种,预测一朵花同时是多个物种是没有意义的。

关于数字“e”的旁注

为了理解 sigmoid 和 softmax 函数,我们需要先介绍数字“e”。在这篇文章中,你需要知道的是 e 是一个数学常数,大约等于 2.71828。

如果你想知道更多,这里有一些关于 e 的有趣事实:

  • e 的十进制表示永远存在,没有重复的数字块——类似于数字 pi。
  • e 出现在复利、赌博和某些概率分布的研究中。
  • 这是 e 的一个公式:

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

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

现在,回到乙状结肠和 softmax…

Sigmoid =多标签分类问题=多个正确答案=非排他性输出(例如,胸部 x 光检查、住院)

  • 当我们为一个有多个正确答案的问题构建分类器时,我们将 sigmoid 函数独立应用于原始输出的每个元素。
  • sigmoid 函数看起来像这样(注意这里的数字 e):

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

这里,sigma 符号σ表示 sigmoid 函数。表达式σ(zj)表示我们将 sigmoid 函数应用于数字 zj。(抱歉我在 WordPress 做不好下标;“zj”里的 j 应该是个下标。)“zj”表示单个原始输出值,例如-0.5。j 代表什么?它告诉我们正在使用哪个输出值。如果我们有四个输出值,则 j = 1、2、3 或 4。在上例中,我们的原始输出为[-0.5,1.2,-0.1,2.4],我们得到 z1 = -0.5,z2 = 1.2,z3 = -0.1,z4 = 2.4

因此,

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

对于 z2、z3 和 z4 以此类推。

因为我们将 sigmoid 函数分别应用于每个原始输出值,这意味着我们的网络可以输出所有类别具有低概率(例如,“此胸部 x 光检查中没有异常”),一个类别具有高概率但其他类别具有低概率(例如,“胸部 x 光检查中只有肺炎”),或者多个或所有类别具有高概率(例如,“此胸部 x 光检查中有肺炎和脓肿。”)

这是一个 sigmoid 函数的图表:

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

Softmax =多类分类问题=只有一个正确答案=互斥输出(例如手写数字、虹膜)

  • 当我们为只有一个正确答案的问题构建分类器时,我们对原始输出应用 softmax。
  • 应用 softmax 会在分母中考虑原始输出的所有元素,这意味着 softmax 函数产生的不同概率是相互关联的。
  • softmax 函数如下所示:

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

这类似于 sigmoid 函数,除了在分母中我们将原始输出中所有东西的 e^thing 相加。换句话说,在计算单个原始输出(例如 z1)的 softmax 值时,我们不能只考虑 z1:我们必须考虑分母中的 z1、z2、z3 和 z4,如下所示:

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

softmax 很酷,因为它确保我们所有输出概率的总和等于 1:

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

这意味着,如果我们正在对手写数字进行分类,并对原始输出应用 softmax,为了让网络增加特定示例被分类为“8”的概率,它需要降低该示例被分类为其他数字(0、1、2、3、4、5、6、7 和/或 9)的概率。

多一个 sigmoid 和 softmax 计算示例

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

总结

  • 如果您的模型的输出类不是互斥的,并且您可以同时选择其中的许多类,请对网络的原始输出使用 sigmoid 函数。
  • 如果您的模型的输出类是互斥的,并且您只能选择一个,那么请对网络的原始输出使用 softmax 函数。

关于特色图片

特色图片是卡尔·布洛赫的一幅名为《在罗马露天剧场》的画 osteria 是一种提供简单食物和葡萄酒的意大利餐馆。我今天在网上偶然发现了这幅画,想了一会儿我如何能使它成为这篇文章的特色图片,因为我认为这是一幅有趣的画。我终于想到了这幅画和 sigmoids/softmaxes 之间的联系:一种视觉记忆术!

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

当你有多个合理的分类器输出时,使用一个“moid”(sigmoid——图片左边的两个“moid”/“maids”)。当你只有一个合理的分类器输出时,使用“max”(soft Max——我把右边皱眉的家伙命名为“Max”)。

结束了!

参考文献

原载于 2019 年 5 月 26 日http://glassboxmedicine.com

使用不同于 logit、probit 的链接函数进行分类[逻辑三部曲,第 3 部分]

原文:https://towardsdatascience.com/classification-using-different-link-function-than-logit-probit-logistic-trilogy-part-3-df9922b1acf1?source=collection_archive---------17-----------------------

让我们学习一些新的东西。做一些新的、创新的事情总是好的。让我们更深入地研究逻辑分类器。实际上不是逻辑分类器,而是类似的东西。

我们使用过哪些不同的链接函数?Logit 链接、probit 链接和 less cloglog 链接。我们能自己想出其他链接功能吗?我们能创建自己的线性分类器吗?为了重新思考,我们需要一些提示,一些方向。让我给你一个。

所有这些上面提到的反向链接函数只不过是一些连续概率分布的 CDF。

逆 logit 环节是标准物流配送的 CDF。逆 probit 环节是标准正态分布的 CDF。逆 cloglog 链接是针对最小值的广义 Gumbel 分布的 CDF。

其中的共同点是相关的随机变量可以取整条实线上的任何值。这个特性非常非常重要。你能想出更多定义在整条实直线上的连续概率分布吗?目前我能想到的有柯西分布拉普拉斯分布我的目标是在这两个分布的帮助下构建两个不同的二元分类器

标准柯西分布的 pdf f(x)和 cdf F(x)为:

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

标准拉普拉斯分布的相同量为:

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

其中 sgn(x)是这样的,如果 x 是负的,则 sgn(x)=-1,如果 x 是正的,则 sgn(x)=+1

两种分布都是关于 0 对称的。因此对于这两者, F(0)=0.5F(x)=1-F(-x) 成立。两个 CDF 的图形类似于

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

Red: Laplace distribution cdf. Blue: Cauchy distribution cdf

看起来很像 sigmoid 函数,不是吗?我希望现在你能看到为什么这两个函数是 logit 分类器的潜在替代者。

由于我们的背景已经准备好,让我们投入分析。我们需要一个可以是 0 或 1 的响应变量 Y 和 p 个预测变量 X1,X2,…,Xp。假设观察总数为 N,并假设:

  1. Yi 是独立的,并且每个 Yi 遵循具有参数 pi 的伯努利分布
  2. 预测因子 X1,X2,…Xp 是不相关的。

这样-

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

其中β是维数为(p+1)×1 的参数向量,xi 是 1×(p+1)阶的第 I 个观测向量。那就是Xi =【1x1i x2i x3i…xpi】。

在柯西分布的情况下,我们将使用-

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

在拉普拉斯分布的情况下-

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

让我们为一般的 F(x)建立理论,在编写 R 代码时,我们将考虑特殊情况。(这意味着您也可以使用这个理论来理解和构建概率单位模型😊😊)

可能性函数是-

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

由于分布关于 0 对称,F(x)=1-F(-x)成立。

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

我们能简化一点吗?假设 **z=2y-1。**所以当 y=1 那么 z=1,当 y=0 那么 z=-1。这将有助于以更方便的方式写出可能性。

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

可能性函数现在可以归结为,

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

类似地,对数可能性为

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

为了训练我们的模型,我们需要通过最大似然估计过程来估计未知参数。参数的最大似然是

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

对数似然相对于参数向量的一阶导数为

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

其中 f(x)是相应的 pdf。

最大似然估计必须满足条件 D=0。但是求 D=0 的根并不是一件容易的事情,因为它没有封闭形式的解。我们可以借助不同的优化技术。我使用的是传统的牛顿-拉夫森方法。

这种方法使我们能够通过如下迭代找到方程 f(x)=0 的根

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

并且当两个连续步骤的输出之间的差异变得太小时,我们停止。在这种情况下,我们将使用

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

让我们找到对数似然的二阶导数。

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

我们正在处理多个预测值,因此相应的矩阵格式为

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

在哪里,

  1. x 是 N 阶 x (p+1)预测值的矩阵,第一列全为 1。
  2. p 是 N×1 阶的列向量,其中第 I 个元素是 pi。
  3. w 是 N×N 对角矩阵,其中第 I 个对角元素为

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

4.n 表示第 n 次迭代。

唷!!!😓😓这需要大量的数学运算。让我们现在开始编码。我在这里用 R。我还在代码中加入了概率单位分类器。在此之前,让我们手边准备好柯西分布和拉普拉斯分布的 pdf 和 cdf。

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

pdf and cdf of Cauchy distribution

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

pdf and cdf of Laplace distribution

#At first lets define the functions for creating the pi values for given predictors and parameters#x is the matrix of parameters, param is the vector of betas, response is the response variable#at first work with probit model**p_i_finder_probit=function(x,param,response){
  n=length(response)
  p_i=array(dim=1)** #initializing an array **for(i in 1:nrow(x)){
    val=0** #temporary variable **for(j in 1:ncol(x)){
      val=val+x[i,j]*param[j]** #x[i,j]=ith value of jth predictor **}
    val=val*response[i]** #pnorm is the cdf of normal **p_i[i]=dnorm(val,0,1)*response[i]/pnorm(val,0,1)
  }** #dnorm is pdf of normal **return(p_i)** #it will return the vector P **}**#lets define the pdf of standard Cauchy distribution **cauchy_pdf=function(x){        
  return((1/(1+x^2))/pi)
}**# similarly function to calculate the cdf of standard Cauchy distribution**cauchy_cdf=function(x){
  return(0.5+atan(x)/pi)
}**# similarly finding the P column vector for Cauchy classifier**p_i_finder_cauchy=function(x,param,response){
  n=length(response)
  p_i=array(dim=1)
  for(i in 1:nrow(x)){
    val=0
    for(j in 1:ncol(x)){
      val=val+x[i,j]*param[j]
    }
    val=val*response[i]
    p_i[i]=cauchy_pdf(val)*response[i]/cauchy_cdf(val)
  }
  return(p_i)
}**# function to calculate the pdf of Laplace distribution**laplace_pdf=function(x){
  return(exp(-abs(x))/2)
}**# function to calculate the cdf of Laplace distribution**laplace_cdf=function(x){
  return(0.5+0.5*sign(x)*(1-exp(-abs(x))))
}**# pi values under Laplace classifier**p_i_finder_laplace=function(x,param,response){
  n=length(response)
  p_i=array(dim=1)
  for(i in 1:nrow(x)){
    val=0
    for(j in 1:ncol(x)){
      val=val+x[i,j]*param[j]
    }
    val=val*response[i]
    p_i[i]=laplace_pdf(val)*response[i]/laplace_cdf(val)
  }
  return(p_i)
}**#now lets write the function for constructing the W matrix
# as input we need the pi value, the matrix of predictors and the parameters**W_matrix_finder=function(p_i,x,param){
  wi=array(dim=1)
  for(i in 1:nrow(x)){
    val=0
    for(j in 1:ncol(x)){
      val=val+x[i,j]*param[j]
    }
    wi[i]=p_i[i]*(val+p_i[i])
  }
  W_matrix=diag(wi)** #diagonal matrix with ith diagonal=wi **return(W_matrix)** #returning the matrix **}**#finally creating own function equivalent to glm function
# as input it will take predictor variables, response variable, the precision for the stopping criteria of Newton Raphson method
and which classifier to use: probit or cauchy or laplace**own_classifier=function(predictor,response,precision,type){
  predictor_new=as.matrix(predictor)** #to be on safe side **distinct=sort(unique(as.numeric(response)),decreasing=FALSE)
  response=as.numeric(response)** #to be on safest side :) **response_new=array(dim=1)
  for(i in 1:length(response)){
    if(response[i]==distinct[1])
      response_new[i]=-1** #instead of 0-1 encoding, making **else** it -1 and 1 for simplicity **response_new[i]=1
  }
  constant=rep(1,length(response_new))** #1st column with all values=1 **X_matrix=cbind(constant,predictor_new)
  beta=rep(0,ncol(X_matrix))** #initializing the parameters **if(type=="cauchy"){** #based on mentioned classifier **dif=100** #R does not have do while loop :( **while(dif>precision){
      p_i=p_i_finder_cauchy(X_matrix,beta,response_new)
      W_matrix=W_matrix_finder(p_i,X_matrix,beta)
  updated=solve(t(X_matrix)%*%W_matrix%*%X_matrix)%*%t(X_matrix)%*%p_i
      beta=beta+updated** #updating beta **dif=sum(updated^2)**#Euclidean distance between old and new beta **}
  }
  else if(type=="probit"){** # for probit model **dif=100
    while(dif>precision){
      p_i=p_i_finder_probit(X_matrix,beta,response_new)
      W_matrix=W_matrix_finder(p_i,X_matrix,beta)
      updated=solve(t(X_matrix)%*%W_matrix%*%X_matrix)%*%t(X_matrix)%*%p_i
      beta=beta+updated
      dif=sum(updated^2)
    }
  }
  else if(type=="laplace"){** #for laplace classifier **while(dif>precision){
      p_i=p_i_finder_laplace(X_matrix,beta,response_new)
      W_matrix=W_matrix_finder(p_i,X_matrix,beta)
      updated=solve(t(X_matrix)%*%W_matrix%*%X_matrix)%*%t(X_matrix)%*%p_i
      beta=beta+updated
      dif=sum(updated^2)
    }
  }
  return(beta)** #returning final parameters **}**

我们的模特训练完成了。让我们在一些任意数据集上应用,并与内置的 glm 函数进行比较。

# I am creating own random dataset containing 2 predictors.**predictor1=rbeta(100,2,4)**#random sample of size 100 from beta(2,4)
**predictor2=rpois(100,10)** #rs from poisson(10)
**predictor=cbind(predictor1,predictor2)
response=sample(c(0,1),100,replace=T)
data=as.data.frame(cbind(predictor1,predictor2,response))**

数据看起来像这样:

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

#train-test split. I am using 80-20 ratio.
**samples=sample(1:nrow(data),size=nrow(data)*0.80,replace=F)
data_train=data[samples,]** #train data **data_test=data[-samples,]** #test data#probit model training using inbuilt glm
**inbuilt=glm(response~predictor1+predictor2,data=data_train,family=binomial(link="probit"))
inbuilt$coefficients**

输出是:

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

让我们看看我们的函数是如何运行的,

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

挺好的!!!!!!不是吗?最多 5 位小数,使用 glm 函数是正确的。

现在我们将应用柯西和拉普拉斯分类器。

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

但是如何衡量它们作为分类器的性能呢?我们将看到他们在测试数据上的表现。为此,让我们构建一个类似于 r 中的预测函数的函数。

#as input it takes the model outputs, test data predictors and the type of classifier to use. **fitted=function(model,test_data_predictor,type){
  predictors=as.matrix(test_data_predictor)
  constant=rep(1,nrow(predictors))
  X_matrix=cbind(constant,predictors)
  pred=array(dim=1)
  if(type=="probit"){
    for(i in 1:nrow(X_matrix)){
      val=0
      for(j in 1:ncol(X_matrix)){
        val=val+X_matrix[i,j]*model[j]
      }
      pred[i]=pnorm(val,0,1)** #cdf of standard normal as inverse link **}
  }
  else if(type=="cauchy"){
    for(i in 1:nrow(X_matrix)){
      val=0
      for(j in 1:ncol(X_matrix)){
        val=val+X_matrix[i,j]*model[j]
      }
      pred[i]=cauchy_cdf(val)**#cdf of standard Cauchy as inverse link **}
  }
  else if(type=="laplace"){
    for(i in 1:nrow(X_matrix)){
      val=0
      for(j in 1:ncol(X_matrix)){
        val=val+X_matrix[i,j]*model[j]
      }
      pred[i]=laplace_cdf(val)**#cdf of standard Laplace as inverse 
                                link
    **}
  }
  return(pred)
}**

最后是对比时间。拟合的概率将判断我们创建的分类器如何表现。手指交叉!!!!!

#probit model using glm function **inbuilt=glm(response~predictor1+predictor2,data=data_train,family=binomial(link="probit"))**#probit model using our own code**model1=own_classifier(data_train[,1:2],data_train[,3],0.000000000000000001,"probit")**# Cauchy classifier using our own code**model2=own_classifier(data_train[,1:2],data_train[,3],0.000000000000000001,"cauchy")**# Laplace classifier using our own code**model3=own_classifier(data_train[,1:2],data_train[,3],0.000000000000000001,"laplace")**#fitted probabilities based on our probit classifier**my_probit=fitted(model1,data_test[,1:2],"probit")**#fitted probabilities based on our Cauchy classifier**my_cauchy=fitted(model2,data_test[,1:2],"cauchy")**#fitted probabilities based on our Laplace classifier**my_laplace=fitted(model3,data_test[,1:2],"laplace")**#fitted probabilities based on probit model through inbuilt glm**r_probit=predict(inbuilt,data_test[,1:2],type="response")****cbind(r_probit,my_probit,my_cauchy,my_laplace)**

输出是:

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

答对了。!!!!!!!!🤩🤩。我们创造的所有模型表现几乎一样。glm 概率单位模型和我们的概率单位模型的拟合值精确到小数点后 6 位。其他两个分类器也给出了与概率单位模型相似的拟合值。

恭喜你!!!!!!现在,您不仅知道了一些新的链接函数,还知道了如何自己使用它们开发模型。

这就是逻辑三部曲的结尾。要想在任何领域大放异彩,有三件事非常非常重要。想象力、创造力和创新。

想象力是无限的。你可以想象任何事情,任何事情。但是如果你把逻辑和想象混合起来,你就会创造出新的东西。这就是创造力。创造新的非传统事物。如果你把创意和创造结合起来,你就会开始创新。

数据科学家需要具备这三个素质。这三个都是通过这个三部曲呈现的。

第一部分 逻辑回归——源自直觉 将帮助你通过纯粹的逻辑和想象得出逻辑分布的想法。

[## 逻辑回归——源自直觉

让我们通过一个故事从头开始推导逻辑回归。我希望这将是有趣和好玩的…

towardsdatascience.com](/logistic-regression-derived-from-intuition-d1211fc09b10)

第二部分在 R 中构建自己的逻辑分类器将帮助你在 R 中创建自己的逻辑分类器函数。这将使你能够创造你自己的东西。

[## 在 R 中构建自己的逻辑分类器[逻辑三部曲,第 2 部分]

一篇关于如何在不使用内置函数的情况下用 R 构建逻辑分类器的独立文章。它会凝固…

towardsdatascience.com](/building-own-logistic-classifier-in-r-logistic-trilogy-part-2-a36be209d2c)

我希望这最后一部分能让你跳出框框思考。你们很多人都用过 logit 或 probit 分类器。但是你有没有想过还有其他的链接功能存在呢?我们能从 logit 和 probit 中想出点什么吗?你猜怎么着!!!!!!他们有很多。你所需要的是一个连续的概率分布,它定义在整个实线上。就拿 t 分布本身来说。通过改变其自由度,您可以创建几个链接函数,并检查其在不同数据集上的性能。深入思考。深入算法。不要只是用算法,从算法开始创新。

如果你不相信,或者有任何疑问或建议,请在评论区提问,或者通过我的 LinkedIn 个人资料联系我。

[## SOUMALYA NANDI -联合健康组织(L2)助理数据科学家| LinkedIn

查看 SOUMALYA NANDI 在全球最大的职业社区 LinkedIn 上的个人资料。SOUMALYA 有 4 份工作列在…

www.linkedin.com](https://www.linkedin.com/in/soumalya-nandi-95176569/)

使用神经网络的分类

原文:https://towardsdatascience.com/classification-using-neural-networks-b8e98f3a904f?source=collection_archive---------4-----------------------

神经网络是那些经常被用来给研究增加可信度的酷词之一。但是它们到底是什么呢?阅读完本文后,您应该对神经网络和卷积神经网络的内部机制有了大致的了解,并且能够用 Python 编写自己的简单神经网络模型。

什么是神经网络

神经网络从人脑的学习过程中获得灵感。它们由称为参数的人工功能网络组成,允许计算机通过分析新数据来学习和微调自己。每个参数,有时也称为神经元,是在接收一个或多个输入后产生输出的函数。这些输出然后被传递到下一层神经元,神经元将它们作为自己功能的输入,并产生进一步的输出。这些输出然后被传递到下一层神经元,如此继续,直到每一层神经元都被考虑,并且末端神经元接收到它们的输入。这些终端神经元然后输出模型的最终结果。

图 1 显示了这样一个网络的可视化表示。初始输入是 x,,然后被传递到第一层神经元(图 1中的 h 气泡),在这里有三个函数考虑它们接收到的输入,并生成一个输出。该输出然后被传递到第二层(图 1 中的 g 气泡)。基于第一层的输出,计算进一步的输出。然后将该次级输出组合起来,以产生模型的最终输出。

图 1:一个简单神经网络的可视化表示

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

Image from: https://en.wikipedia.org/wiki/Artificial_neural_network

神经网络如何学习?

思考神经网络的另一种方式是将其视为一个巨大的函数,它接受输入并获得最终输出。由多层神经元完成的中间功能通常不会被观察到,幸好是自动化的。它们背后的数学既有趣又复杂,值得进一步研究。

如前所述,网络中的神经元与下一层中的神经元相互作用,每个输出都充当未来函数的输入。包括初始神经元在内的每个函数接收数字输入,并基于内化函数产生数字输出,该内化函数包括对每个神经元唯一的偏置项的添加。然后,通过乘以适当的权重,将该输出转换为下一层中函数的数字输入。这一直持续到产生网络的一个最终输出。

困难在于确定每个偏置项的最佳值,以及为神经网络中的每次传递找到最佳加权值。要做到这一点,必须选择一个成本函数。成本函数是一种计算特定解决方案离最佳可能解决方案有多远的方法。有许多不同的可能的成本函数,每一个都有优点和缺点,每一个都在特定的条件下最适合。因此,成本函数应该根据个人的研究需要来定制和选择。一旦确定了成本函数,就可以以最小化该成本函数的方式改变神经网络。

因此,优化权重和偏差的简单方法是简单地多次运行网络。第一次尝试时,预测必然是随机的。每次迭代后,将分析成本函数,以确定模型的表现如何,以及如何改进。从成本函数获得的信息然后被传递到优化函数,优化函数计算新的权重值以及新的偏差值。将这些新值集成到模型中后,模型将重新运行。这种情况一直持续到没有改变改进成本函数为止。

有三种学习方法:监督学习、非监督学习和强化学习。这些学习范例中最简单的是监督学习,其中神经网络被给予标记输入。标记的例子,然后被用来推断可推广的规则,可适用于未标记的情况。这是最简单的学习方法,因为它可以被认为是与“老师”一起操作,以一种函数的形式,允许网络将其预测与真实的、期望的结果进行比较。无监督方法不需要带标签的初始输入,而是不仅基于给定的数据,而且基于网络的输出来推断规则和函数。这妨碍了可以做出的预测类型。这种模型不能够分类,而是局限于聚类。

什么是卷积神经网络?

传统神经网络的一种变体是卷积神经网络。通常所说的神经网络提供了一些优于普通神经网络的显著优势,尤其是在图像分类方面。在这种情况下,初始输入将是由像素组成的图像。图像分类的传统问题是,对于具有许多颜色通道的大图像,训练一些模型在计算上很快变得不可行。CNN 试图做的是将图像转换成一种更容易处理的形式,同时仍然保留最重要的特征。这是通过在初始图像上传递滤波器来完成的,该滤波器在初始图像中的像素的子部分上进行矩阵乘法,它遍历子集,直到考虑了所有子集。过滤器旨在捕捉最关键的特征,同时允许消除冗余特征。过滤器在初始像素上的这种通过被称为卷积层。

卷积图层之后是汇集图层,在该图层中,将尝试减少卷积要素的空间大小。复杂性的降低,有时被称为降维,将降低对数据集进行分析的计算成本,从而使该方法更加稳健。在这一层,内核再次通过图像的所有像素子集。有两种常用的池内核。第一个是 Max Pooling,它保留子集的最大值。另一种内核是平均池,它做的正是您所期望的:它保留子集中所有像素的平均值。图 2 直观地显示了汇集阶段的流程。

图 2:卷积神经网络的汇集阶段

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

Image from: https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53

在汇集阶段之后,信息将有望被压缩到足以用于常规神经网络模型。剩下要做的最后一件事是将合并阶段的最终输出变平,并将其输入到模型中。展平是通过将像素矩阵转换成像素矢量来完成的,然后该矢量可用于神经网络模型。

从那里,卷积神经网络就像常规神经网络一样工作,因为信息将被传递到一组神经元,这些神经元将值传递到其他层,直到达到最终输出。因此,卷积神经网络使得神经网络对于大数据集或复杂图像是可行的,因为它降低了分析所需的计算能力。

神经网络有哪些应用?

诸如神经网络之类的机器学习方法有许多应用。这些应用大多集中在图像的分类上。这些图像可以是任何东西,从某物是否是热狗,到识别笔迹。这种模式的实际可能性是广泛且有利可图的。让我们看一个例子。

许多公司都希望能够自动建立一个对服装进行分类的模型。这样做可以让他们洞察时尚趋势、购买习惯以及文化和社会经济群体之间的差异。为此,我们将使用一个神经网络,看看当给定一组 60,000 张图像时,是否可以构建一个适当的分类模型,这些图像带有标识它们是什么类型服装的标签。

所有这些图片都是由像素组成的,因为我们要做的是一个简单的神经网络,而不是卷积神经网络,所以这些像素将作为像素向量直接传递到网络中。

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

Image taken from: https://medium.com/tensorist/classifying-fashion-articles-using-tensorflow-fashion-mnist-f22e8a04728a

为了创建神经网络,必须指定模型中的层数。为了简单起见,我将模型限制为两层。还必须选择每层的激活类型。同样,为了保持简单,我将为第一层选择一个 sigmoid 激活,最后一层有 10 个节点,并设置为返回 10 个概率得分,指示图像是否属于十件可能的衣服之一的概率。为了编译模型,必须定义一个损失函数,这将是模型评估其自身性能的方式。还必须确定优化器,这就是如何使用来自成本函数的信息来改变每个节点的权重和偏差。

model = keras.Sequential([keras.layers.Flatten(input_shape (28,28)),
                keras.layers.Dense(128,activation = tf.nn.sigmoid),                          
                keras.layers.Dense(10,activation = tf.nn.softmax)])
model.compile(optimizer = 'adam',loss='sparse_categorical_crossentropy',metrics =['accuracy'])

有了这些参数输入,就可以训练一个模型。一旦模型被训练,就必须根据测试数据对其进行评估。要做到这一点,必须指明模型将考虑的历元数。历元决定了应该对数据进行多少次迭代。更多的历元将在计算上更加昂贵,但应该允许更好的拟合。我将考虑 5 个时代。可以看到,随着优化函数改变权重,在每次迭代之后,模型对训练数据的准确性如何提高。

model.fit(x_train, y_train,epochs = 5)

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

The Change in Accuracy for Each Epoch

模型如何执行的真正拟合是通过在测试集上运行模型,而不是用于构建模型。在这种情况下,神经网络的准确度为 0.7203:还不错!

总结

神经网络是复杂的模型,它试图模仿人脑制定分类规则的方式。神经网络由许多不同层的神经元组成,每一层接收来自前一层的输入,并将输出传递给下一层。每一层的输出成为下一层的输入的方式取决于给予特定链接的权重,该权重取决于成本函数和优化器。神经网络迭代预定次数的迭代,称为历元。在每个时期之后,分析成本函数以查看模型可以改进的地方。然后,优化函数根据成本函数提供的信息改变网络的内部机制,例如权重和偏差,直到成本函数最小化。

卷积神经网络是普通神经网络的变形,它试图通过两个独立的阶段减少图像分类中的像素数量来处理高维度问题:卷积阶段和汇集阶段。之后,它的表现就像一个普通的神经网络。

关键词

  • 神经网络
  • 卷积神经网络
  • 汇集阶段
  • 神经元
  • 过滤
  • 价值函数
  • 【计算机】优化程序

用 LSTM 和手套对有毒的网络评论进行分类

原文:https://towardsdatascience.com/classify-toxic-online-comments-with-lstm-and-glove-e455a58da9c7?source=collection_archive---------7-----------------------

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

Photo credit: Pixabay

深度学习,文本分类,自然语言处理

这篇文章展示了如何使用一个简单的 LSTM 和一个预先训练好的手套文件为有毒评论分类问题创建一个强大的基线。

本文由四个主要部分组成:

  • 准备数据
  • 实现一个简单的 LSTM (RNN)模型
  • 训练模型
  • 评估模型

数据

在下面的步骤中,我们将设置关键模型参数并拆分数据。

  • " MAX_NB_WORDS "设置被视为 tokenizer 特征的最大字数。
  • "MAX _ SEQUENCE _ LENGTH"在此字数之后(在 MAX_NB_WORDS 最常用的字中)切断文本。
  • VALIDATION _ SPLIT设置一部分数据用于验证,不用于训练。
  • EMBEDDING _ DIM定义了“矢量空间”的大小。
  • GLOVE_DIR 定义了手套文件的目录。
  • 将数据分为文本和标签。

toxic_data.py

文本预处理

在下面的步骤中,我们删除停用词,标点符号,并使一切小写。

preprocessing_toxic.py

看一看样本数据。

print('Sample data:', texts[1], y[1])

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

  • 我们创建一个分词器,配置成只考虑到 MAX_NB_WORDS 最常见的单词。
  • 我们建立单词索引。
  • 我们可以恢复计算出的单词索引。
tokenizer = Tokenizer(num_words=MAX_NB_WORDS)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
word_index = tokenizer.word_index
print('Vocabulary size:', len(word_index))

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

  • 将整数列表转换为形状的 2D 整数张量(samples,maxlen)
  • 每个序列后填充。
data = pad_sequences(sequences, padding = 'post', maxlen = MAX_SEQUENCE_LENGTH)print('Shape of data tensor:', data.shape)
print('Shape of label tensor:', y.shape)

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

  • 打乱数据。
indices = np.arange(data.shape[0])
np.random.shuffle(indices)
data = data[indices]
labels = y[indices]

创建培训验证分解。

num_validation_samples = int(VALIDATION_SPLIT*data.shape[0])
x_train = data[: -num_validation_samples]
y_train = labels[: -num_validation_samples]
x_val = data[-num_validation_samples: ]
y_val = labels[-num_validation_samples: ]print('Number of entries in each category:')
print('training: ', y_train.sum(axis=0))
print('validation: ', y_val.sum(axis=0))

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

数据看起来是这样的:

print('Tokenized sentences: \n', data[10])
print('One hot label: \n', labels[10])

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

Figure 1

创建模型

  • 我们将使用来自斯坦福的预训练手套向量通过解析预训练嵌入的数据转储来创建映射到已知嵌入的单词索引。
  • 然后将单词嵌入加载到一个**embeddings_index**

embedding_index.py

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

  • 创建嵌入层。
  • 指定嵌入层的最大输入长度。
  • 利用来自先前嵌入层的输出,该嵌入层将 3-D 张量输出到 LSTM 层。
  • 使用全局最大池层将 3D 张量重塑为 2D 张量。
  • 我们设置丢弃层来丢弃 10%的节点。
  • 我们定义密集层以产生 50 的输出尺寸。
  • 我们再次将输出馈入一个漏失层。
  • 最后,我们将输出送入一个“Sigmoid”层。

embedding_layers.py

是时候将模型编译成静态图进行训练了。

  • 定义输入、输出并配置学习过程。
  • 使用“Adam”优化器设置模型以优化我们的损失函数,将损失函数定义为“binary_crossentropy”。
model = Model(sequence_input, preds)
model.compile(loss = 'binary_crossentropy',
             optimizer='adam',
             metrics = ['accuracy'])
  • 我们可以想象模型的设计师。
tf.keras.utils.plot_model(model)

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

Figure 2

培养

  • 为每一批输入 32 个填充的索引句子。验证集将用于评估模型是否过度拟合。
  • 该模型将运行 2 个时期,因为即使 2 个时期也足以过度拟合。
print('Training progress:')
history = model.fit(x_train, y_train, epochs = 2, batch_size=32, validation_data=(x_val, y_val))

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

评估模型

loss = history.history['loss']
val_loss = history.history['val_loss']epochs = range(1, len(loss)+1)plt.plot(epochs, loss, label='Training loss')
plt.plot(epochs, val_loss, label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show();

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

Figure 3

accuracy = history.history['accuracy']
val_accuracy = history.history['val_accuracy']plt.plot(epochs, accuracy, label='Training accuracy')
plt.plot(epochs, val_accuracy, label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.legend()
plt.show();

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

Figure 4

Jupyter 笔记本可以在 Github 上找到。周一快乐!

使用 LSTMs 和 rs-fMRI 数据从健康对照中分类 ADHD

原文:https://towardsdatascience.com/classifying-adhd-from-healthy-controls-using-lstms-with-rs-fmri-data-300c1f3e9697?source=collection_archive---------16-----------------------

实践指南:从提取静息状态网络到计算分类重要性

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

image credit: American health imaging

本教程介绍了使用机器学习分析 rs-fMRI 数据的实际步骤,更具体地说,是区分注意缺陷多动障碍(ADHD)和健康对照组。我讨论了(1)使用掩模的特征提取(2)递归神经网络(RNN)的优点和缺点,特别是用于分类 fMRI 数据的长短期记忆网络(LSTM )( 3)假设检验及其在模型评估中的应用。

有关如何准备用于分析的 fMRI 图像的更多详细信息,请访问 使用 ICAs 从 fMRI 数据中识别静息状态网络的预处理教程

注意:如果你已经读过这些之前的帖子,你可能已经注意到我已经从精神分裂症(SZ)数据集换成了多动症数据集。主要原因是我自己缺乏预处理完整精神分裂症数据集的计算资源。我找不到预处理过的 SZ 数据集,但我找到了一个 ADHD 数据集。

本教程的完整代码可从 这里 **获得。**要做好准备,请下载 python 并安装以下包- nilearnsklearnkeras

数据准备

正如我们之前提到的,fMRI 图像是 4D 矩阵,反映了三维空间和时间中每个体素的激活水平。然而,相关信息常常是由这些数据的子集描述的。比如这里,我们只对静息态网络感兴趣。为了省略不相关的数据,我们应用掩码。掩码是简单的过滤器,它传递所需的数据子集,而丢弃其余的数据。实际上,遮罩将不需要的体素的激活值替换为 0。

屏蔽 fMRI 数据的方式有很多种,这主要是由分析的目标决定的。本教程的重点是通过他们的静息状态网络将 ADHD 患者与对照组进行分类。因此,我应用史密斯的 rs-fMRI 组件图谱(史密斯等人,2009)。Smith atlas 反映了使用独立成分分析(ICA)对数千名健康患者获得的 70 个静息状态网络(RSN)。我更喜欢 Smith atlas,而不是使用特定于数据集的 ICA 组件,因为它有助于避免可能导致过度拟合的双重浸渍(即使用数据两次)。

史密斯地图集可通过 Nilearn 数据集获得:

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

多动症数据集也可以在 Nilearn 上找到。从第一幅图像的头部,我们看到该图像包含 176 个时间戳上的 736161 个体素。此外,每个体素约为 3 毫米。需要注意的是,这一信息在整个数据集中可能并不一致。

OUTPUT: [ 4 61 73 61 176 1 1 1] // [-1. 3. 3. 3. 2. 0. 0. 0.]

为了屏蔽数据,我们首先需要从 Smith 的图集生成屏蔽。应用标准化有助于特性的健壮性。在掩蔽的情况下,它可以通过对每个时间序列的切片进行居中和归一化来帮助增强信号。将数据混淆视为转换过程的一部分,也有助于通过消除混淆噪声来增强信号。

OUTPUT: N control: 20 / N ADHD: 20

如前所述,一个数据集可能不会拥有相同的扫描长度——这 40 名受试者表现出相当大的差异。然而,大多数机器学习算法(包括 Keras)需要所有对象的统一形状。为了优化数据保存,我们可以使用填充;在扫描结束后给每个主题添加零,以匹配最长扫描的长度。除了填充之外,我还重塑了数据,使其符合 Keras 提出的要求;(40,261,10)意味着我们有 40 名受试者,在 10 个地区有 261 个时间戳长的样本。

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

OUTPUT: data shape: (40, 261, 70)

数据准备

我们使用训练/测试分离范例来确保模型在全新的数据上进行测试。下面的函数随机地将数据分成训练和测试,并根据模型的要求重新塑造每个部分。

LSTM 模型

长短期记忆(LSTM)模型在学习功能磁共振成像数据方面提供了一些好处。主要原因是,与大多数机器学习或深度学习方法不同,它们设法保留输入的上下文信息——从而在处理当前输入序列时,纳入输入序列之前部分的细节。也就是说,高度语境化并不总是一件好事。有些情况下,LSTMs 不是最佳选择;依赖上下文可能会导致对数据的过度解读。此外,LSTMs 可能比简单的 NN 运行时间更长,并且可能有更多的参数需要调整。重要的是要考虑各种选项,并从相关场景中找到最合适的模型(Culurciello,2018)。

在这种情况下,我选择展示 LSTMs 在分析 fMRIs 时的能力,因为它们具有上下文相关的性质。fMRI 数据代表了随时间变化的动态大脑活动,因此使用 LSTMs 可以在分析功能连接时利用时间信息(否则会丢失)(Dvornek 等人,2017)。

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

RSN LSTM classifier pipeline

注意-LSTM 的一个常见增强是使用支持分析空间结构的卷积神经网络(CNN)。然而,在这里,我们提取了 70 个反映整个网络激活的独立成分的离散值——因此放弃了数据的空间属性。因此,CNN 不太可能有用。

LSTMs 的一个问题是它们很容易过度拟合训练数据,降低了它们的预测能力。这个问题的解决方案是通过正则化,这阻止了模型的过拟合趋势。LSTM 网络中的一个常规正则化是丢失,它从概率上将单元排除在层连接之外。辍学有两种类型——输入性辍学和经常性辍学。输入的丢失意味着对于给定的概率,每个 LSTM 单元的输入连接上的数据将被排除在节点激活和权重更新之外(参见丢失参数)。递归输入上的漏失以相同的方式工作,但是在递归连接上(参见 reccurent_dropout 参数)。然而,重要的是不要过度正则化,因为这将从根本上阻碍模型学习(这可以通过严格的非指示性预测来检测)。

我在这里展示的模型是一个序列模型,具有三个堆叠的 LSTM 层和一个具有 sigmoid 激活的致密层。坦率地说,对于如何选择超参数,没有一个正确的答案。有很多试错和经验法则。我展示一些我收集的—

  • 一般来说,我们希望至少有两个隐藏层(不包括最后一层),因为神经网络的能力源于它们的深度(即零层只能表示线性函数…).然而,在精确度和训练时间之间有一个折衷——在不花费太多时间的情况下,找到显著增加精确度的层数(更多细节此处)。
  • 我们希望从数量为的单元开始,小于或等于输入大小,并减少它(当时大约减少一半),直到到达最后一层。(参见完整讨论此处)
  • 在分类的情况下,输出层的单元数应该等于类别数。通常,二进制分类问题有一个输出。
  • 输出层激活主要是针对二元分类的 sigmoid,针对多类分类器的 softmax,以及针对回归的线性。
  • 分类损失函数应与标签数量及其类型相匹配。binary_crossentropy 损失函数最适用于二进制分类,categorial _ cross entropy 最适用于具有一个热编码数据的多类,sparse _ categorical _ crossentropy 最适用于类似整数的标注。
  • 准确性指标显示了正确分类的百分比。可以用一个以上!
  • 越多的周期越好,从 30 开始,并遵循您的验证 设置以减少损失并提高精度。如果您看到了改进,请增加历元的数量,否则—回到绘图板。
  • 根据您对数据属性和网络深度的了解,选择优化器。例如,ada 优化器可以很好地处理稀疏数据,但随着网络的深入,性能会越来越差。从 Adam optimizer 开始是一个安全的选择,因为它是一个高效的优化器,不需要大量的调优(参见更多细节此处)。

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

Image Credit: CS231n

这是模型-

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

让我们试试这个模型,看看它是否能够学习。因此,它的精度增加,损失减少;

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

我们看到,随着历元数量的增加,模型的准确性有所提高,模型的损失有所减少。此外,训练集和验证集显示了相似的趋势。因此,我们(1)有了一个工作模型,( 2)可能没有过度拟合——因此,我们将继续。

我们实际上如何使用模型?

假设检验

我使用假设检验框架来评估模型,因为它有助于获得模型的准确性及其重要性。为了计算模型的重要性,我使用了 bootstrapping。简而言之,Bootstrapping 是一种强大的基于计算机的统计推断方法,它不依赖于太多的假设。它帮助我们通过对小数据样本的估计来估计总体的特性。

(简要地)它是如何工作的?

我们要测试的零假设表明,ADHD 患者和对照组之间没有差异,因此使用我们的模型比较两者的准确性应该是大约 0.5(意思是,机会)。

为了评估这一假设,我们将从数据中用替换法反复重新取样;将其分为训练和测试部分,拟合模型,预测测试数据的标签,并计算精度。这种重复将产生精确度的分布。我们使用的迭代次数越多,这种重采样(遵循中心极限定理)很可能接近高斯形状。因此,我们可以采用要求正态分布的统计检验(如 t 检验)。

如果 0.5 位于分布的尾部(即最后 5%),我们可以得出结论,该分布不太可能以 0.5 为中心,并拒绝零假设。否则,我们将无法拒绝它。

下一个函数运行引导实验:

这两个函数计算并绘制与自举实验精度相关的 p 值。

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

最后,让我们用受试者工作特性(ROC)曲线来展示结果。ROC 曲线通过绘制真阳性率对假阳性率来反映模型的敏感性和特异性。

我选择呈现 ROC 曲线的中值(而不是平均值),因为它在数据偏斜的情况下提供了更稳健的测量(如果数据没有偏斜,它不应该呈现任何缺点)。

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

解释

上面看到的 ROC 曲线显示了显著高于平均水平的分类能力。我们看到,中间值及其周围的一个 SD 完全位于机会对角线上方。95%置信区间(由平均 ROC 曲线周围的 2 SD 表示)在机会对角线以下扩展,主要在左下角。这可能意味着该模型更有可能表达更高的敏感性,但特异性较低。

该模型的灵敏度是被正确识别为患有该疾病(即,真阳性)的患者占实际患有该疾病的患者总数的比例。该模型的特异性描述了被正确鉴定为未患病(即真阴性)的患者占未患病患者总数的比例。通常,这两者呈现相反的关系。

敏感性还是特异性?

看情况。然而,在诊断实验中,倾向于敏感性是很常见的——这样就不会漏掉任何真正患病的病人(并冒着错误诊断健康病人的风险)。然而,这样的决定与假设的性质高度相关(Parikh 等人,2008)。

摘要

在本教程中,我们建立了一个 LSTM 模型,通过 rs-fMRI 对 ADHD 患者和健康对照进行分类。我们已经讨论了假设检验,并在诊断实验中展示了它的好处。

参考

Borlase,T. R .梅尔策,Eggleston,M. J .,Darling,K. A .,& Rucklidge,J. J. (2019)。微量营养素治疗 10 周后 ADHD 儿童的静息状态网络和神经代谢产物:一项随机安慰剂对照试验的结果营养神经科学,1–11。

Culurciello,E. (2018)。RNN / LSTM 的陷落。检索于 2019 年 12 月 14 日,来自https://towards data science . com/the-fall-of-rnn-lstm-2d 1594 c74 ce 0

北卡罗来纳州德沃内克,p .文托拉,Pelphrey,K. A .,&邓肯,J. S. (2017 年 9 月)。利用长短期记忆网络从静息态功能磁共振成像中识别自闭症。在医学成像机器学习国际研讨会(第 362–370 页)。斯普林格,查姆。

Parikh,r .,Mathai,a .,Parikh,s .,Sekhar,G. C .,和 Thomas,R. (2008 年)。理解和使用敏感性、特异性和预测值。印度眼科杂志56 (1),45。

史密斯、S. M .、福克斯、P. T .、米勒、K. L .、格拉恩、D. C .、福克斯、P. M .、麦凯、c . e .…&贝克曼、C. F. (2009 年)。激活和休息时大脑功能结构的对应。美国国家科学院院刊106 (31),13040–13045。

利用预训练神经网络提取的特征进行汽车图像分类

原文:https://towardsdatascience.com/classifying-car-images-using-features-extracted-from-pre-trained-neural-networks-39692e445a14?source=collection_archive---------10-----------------------

那是克尔维特吗?

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

Source

介绍

根据 Cox Automotive 发布的 2018 二手车市场报告&展望显示,去年美国售出 4000 万辆二手车。这约占总销量的 70%。这些销售中的很大一部分已经在购买的各个阶段使用了在线资源:搜索、资格预审、申请和最终购买。汽车购买者的热门网站包括 AutoTrader.com,凯利蓝皮书,Cars.com,Carvana.com。

考克斯汽车公司的报告指出,大多数市场领导者和硅谷的初创公司推测,汽车销售将会把完全转移到网上零售。这可能是一个极端的猜测,但这些市场领导者对在网上买车时提供更好的用户体验,以及在用户搜索汽车时提供更好的推荐系统感兴趣。像 Craigslist、Shift、易贝汽车等点对点销售平台也对更好的欺诈检测和用户发帖监控感兴趣。

汽车图像分类系统可以解决这些业务问题:

  1. 点对点销售平台上发布的二手车图片的真相——这些图片真的是他们指定的车吗?多张外景图片代表同一辆车吗?
  2. 基于用户上传的图像组织网页显示
  3. 推荐库存中外观和价格相似的替代汽车

此外,一个简单的汽车分类系统可以帮助识别对自动驾驶汽车的 3D 对象检测很重要的细粒度特征。

方法

用于该分析的方法具有三个阶段:特征提取阶段、模型建立阶段和模型评估/误差分析阶段。

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

Figure 1: Approach Used for the Analysis

斯坦福的汽车图像数据集被用于这项分析。该数据集由总共 16,185 幅图像(列车组+测试)组成,根据汽车的品牌/型号/年份标记了 196 个类别。这些图像有不同的尺寸和分辨率。在此分析中,数据集中的 196 个图像标签被合并为五种车辆类型,如下图所示。尽管这些代表了车辆类型的“粗略”合并,但它们被证明更易于管理,并且足以完成图像分类任务。

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

Figure 2: Vehicle Classes Used in the Analysis

特征抽出

每张汽车图像的特征都是从深度学习卷积神经网络(CNN)中提取的,权重是在 ImageNet 数据集上预先训练的。这些 CNN 的创建者免费提供这些权重,建模平台 Keras 提供了对这些网络架构和权重的一站式访问。总体而言,如下图所示,五个 CNN 用于提取特征,并分别用于分类任务,以比较哪个深度学习架构表现最好。提取的特征来自最终 softmax 层之上的第一个完全连接的隐藏层。

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

*Figure 3: Vehicle Classes Used in the Analysis (*¹ Features were extracted from the fully connected hidden layer below the final softmax layer)

模型结构

在模型构建阶段执行的第一步是降低所提取特征的维度。这一步有助于将特征的尺寸控制在可管理的范围内,并提高迭代模型构建步骤的速度。使用主成分分析(PCA)进行降维,系统搜索导致使用 500 个特征的降维,这捕获了 5 个 CNN 中大约 85-90%的特征差异。

原始数据集大约有 50–50%的训练测试分割。在此分析中,这些测试被组合在一起,并使用了 80–20%的训练测试分割。建立训练测试集,以保持类别分布。

在这一阶段的过程中采用了许多分类方法。这些包括:逻辑回归、随机森林、具有多项式核的支持向量机、XGBoost 和浅层神经网络(来自 sklearn 的多层感知器分类器)。

合并到五个类别后的数据集具有类别不平衡,货车代表约 6%的数据,而其他极端敞篷车/轿跑车和轿车各代表约 32%的数据。为了解决这种类别不平衡,上述分类方法与过采样技术重复:随机过采样和合成少数过采样技术(SMOTE)。

此外,还对堆叠分类器进行了测试,以查看组合最佳逻辑回归和随机森林模型的结果是否会比单独使用其中任何一个模型产生更好的结果。

模型结果和误差分析

为了比较模型性能,考虑了多个指标。但是在几次迭代之后,精确度被认为是评估模型性能的一个足够的度量。选择任何其他指标(比如 F1 分数)都会得出类似的结论。通过检查错误分类的图像并探索这些错误分类中的任何相似性,进行了详细的误差分析。

结果

最佳性能模型的结果如下图所示。如下所示,使用从 InceptionV3 中提取的特征的模型通常表现最佳,逻辑回归比随机森林的精确度略高。使用 InceptionV3 特征、L2 正则化逻辑回归和随机过采样技术的模型被选为本次分析的首选模型

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

Figure 4: Comparison of Model Accuracy for Select Runs

首选模型的混淆矩阵如下图所示:

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

Figure 5: Confusion Matrix for the Preferred Model(InceptionV3 Features + Logistic Regression)

除了跟踪模型的准确性之外,还进行了详细的误差分析,以评估模型表现不佳的地方。这种误差分析对于执行类别标签的质量检查(QC 检查)、识别模型“盲点”和未来改进至关重要。

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

Figure 6: Error Analysis of Convertibles/Coupes for for Preferred Model

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

Figure 7: Error Analysis of Sedans for the Preferred Model

如上面的图 6 和图 7 所示,该模型似乎选择颜色作为分类特征。正确识别的敞篷车/轿跑车色彩丰富,而那些被错误分类为轿车的颜色就不那么丰富了。同样,如图 7 所示,被错误归类为敞篷车/双门轿车的轿车比被正确归类的轿车更加丰富多彩。在大多数情况下,这是一个令人鼓舞的结果,因为这将挑选特定汽车品牌/型号的颜色,但颜色的权重高于代表形状和尺寸的特征的权重。

结论

上述图像分类分析的主要结论是:

  1. 使用预先训练的 CNN 特征建立分类模型的原型是非常有效的,并且比从零开始完全建立深度神经网络更容易。
  2. 误差分析是非常有用的,它提供了关于如何使用模型的见解。

参考

  1. 斯坦福汽车数据集
  2. ImageNet 数据集
  3. Keras 预训练模型
  4. 2018 二手车市场报告&展望

GitHub 回购:

[## mlBhanuYerra/Metis_prj3

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/mlBhanuYerra/Metis_prj3/tree/master/Code)

特征提取:extract _ features . py

模型构建:3 _ finalmodelsruns . ipynb

错误分析:3 _ Results _ presentation . ipynb

最初发布于https://mlbhanuyerra . github . io

GitHub 回购:

https://github.com/mlBhanuYerra/Metis_prj3/tree/master/Code

教电脑看东西

原文:https://towardsdatascience.com/classifying-flowers-with-cnns-and-transfer-learning-a550bde41b14?source=collection_archive---------40-----------------------

基于细胞神经网络和迁移学习的花卉分类

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

Image Credit: Lachlan Gowen

如果我问你上图是什么类型的花,你可能会知道是向日葵。但是如果我问一台电脑同样的问题呢?如果它回答正确,不是很令人印象深刻吗?值得注意的是,计算机不仅可以被训练分类向日葵,还可以分类许多其他的花。而训练计算机的人甚至不需要知道什么是向日葵!

魔法的秘密:卷积神经网络

为了识别花的类型,我开发了一个卷积神经网络(CNN),可以对蒲公英、雏菊、郁金香、向日葵和玫瑰进行分类。查看完整的代码这里

什么是神经网络?人工神经网络模仿人脑的生物神经网络,可以根据过去数据中识别的模式进行预测。这些网络有三种类型的层:提供初始数据的输入层,使用权重和偏差进行计算的隐藏层,以及应用激活函数给出最终结果的输出层。点击阅读关于神经网络的更深入的描述。

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

A neural network visualized

卷积神经网络是一种神经网络,通常包括卷积层和最大池层。卷积就是对构成输入图像的像素集合应用滤镜。这导致激活。这种过滤器的重复应用产生了一种称为特征图的激活图,它本质上告诉计算机关于图像的信息。卷积层之后是最大池层。在 max-pooling 层中,图像上的过滤器检查每个部分中的最大像素值(部分的大小由程序员指定),然后使用最大像素值创建一个新的更小的图像。这些较小的图像有助于计算机更快地运行模型。查看这个视频了解 CNN 更深入的描述

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

当卷积层和最大池层连接到神经网络的输入和输出层时,该模型能够使用过去的标记数据来预测未来图像包含的内容。现在我们已经了解了 CNN 是什么,让我们来看看建立一个 CNN 的步骤。

收集数据

我们可以使用 Python 和 TensorFlow 库对这个项目进行编码。TensorFlow 数据集中已经提供了花卉数据集(包含 5 类花卉的标记图像),因此可以简单地从那里下载。然而,数据集在被传递到模型中之前必须被细化。我们将 70%的数据分成训练集,其余 30%的数据分成验证集。训练集是模型用来拟合分类器参数的一组示例,验证集用于进一步调整这些参数,以便分类器可以对以前没有见过的数据进行处理。由于该数据集的图像大小不同,我们将所有图像的大小调整为标准大小。

将学习转移到构建模型

收集数据后,我们可以开始训练我们的模型。迁移学习是重用一个已经训练好的模型的部分,改变模型最后一层的过程;最后一层然后在 flowers 数据集上重新训练,以给出我们想要的输出。实施迁移学习是因为它可以提高我们模型的准确性。使用 MobileNet v2 模型并且只改变最后一层使得实际模型的代码非常短。

URL = 'https://tfhub.dev/google/tf2preview/mobilenet_v2/feature_vector/4'feature_extractor = hub.KerasLayer(URL, input_shape = (IMAGE_RES, IMAGE_RES, 3))feature_extractor.trainable = Falsemodel = tf.keras.Sequential([feature_extractor, layers.Dense(num_classes, activation='softmax')])

培训模式

在训练模型之后,我们可以绘制它的准确性和损失,以了解它的表现。图表上的 x 轴表示历元数(模型遍历整个训练集并更新权重的次数)。

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

The model reaches a 90% accuracy on the validation set!

做预测

让我们来看看通过模型运行图像批处理后的结果!

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

如您所见,由于迁移学习和 CNN 架构的原因,该模型在测试集上表现非常好。

那么这到底有什么用呢?虽然给花分类可能只对植物学家有帮助,但 CNN 可以有拯救生命的应用,例如从核磁共振成像中检测肺炎,并使无人驾驶汽车成为现实。

先别走

我是 Roshan,16 岁,对人工智能充满热情,尤其是它在金融方面的应用。如果你喜欢读这篇文章,可以看看我的其他文章,比如“用人工智能对抗财务欺诈”,在那里我描述了我如何使用自动编码器来检测会计分录异常。

通过 LinkedIn联系我

基于迁移学习的花卉分类

原文:https://towardsdatascience.com/classifying-flowers-with-transfer-learning-5e17925a1f59?source=collection_archive---------17-----------------------

人工智能在英国花卉分类中的应用

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

Dlanor S (https://unsplash.com/photos/vjDbHCjHlEY)

迁移学习 是一种机器学习技术,旨在使用来自先前训练的模型的知识来帮助改善目标值的预测。有趣的是,之前的分类器可能是用不同的集合训练的,最初是试图解决不同的任务。

在这篇文章中,我将探索一些关于深度学习迁移学习的概念,以便预测英国的花卉种类。这篇文章是基于我为毕业于 Udacity 的数据科学家 Nanodegree 而开发的一个项目而创建的,可以通过我的GitHub资源库访问该项目。

关于数据的一点点

本项目中使用的数据是从牛津大学的视觉几何小组中提取的,可以在此处 访问

该数据包含一个关于英国常见花卉类别的 102 类别数据集。正如原始资料中所解释的,每一种花的种类由 40 到 258 张图片组成。

深度学习框架

深度学习被构建成所谓的神经网络。一个简单的网络基本上由经过加权并通过激活函数的输入组成。这个简单的模式通常被称为单元**,可以如下图所示显示。**

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

Neural Network Unit

当单元被连接起来创建时,这个模式变得非常强大。

激活函数允许网络呈现非线性特性。一些最常见的激活功能是s 形**、整流器(ReLu) 和**双曲正切。****

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

Activation Functions (source)

简单地说,像图中这样的单元的输出可以计算为ŷ=σ( Wx +b)。这就是所谓的前馈传递。该输出是一个预测,可以通过误差(损失)函数与真实目标 y 进行比较。向后运行前馈操作以将计算的误差传播到每个权重的过程被称为反向传播。****

迁移学习

迁移学习是使用为特定任务开发的模型作为不同任务中模型的起点的能力。粗略地说,我们可以使用预训练神经网络的输出作为我们自己网络的特征,我们需要做的就是训练我们自己的层。

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

PyTorch 是基于 Torch 库的开源机器学习库,广泛用于计算机视觉和 NLP(自然语言处理)。

PyTorch 附带了 torchvision 包,其中包含流行的数据集、模型架构和计算机视觉的常见图像转换。此外,如文档中所解释的,模型子包包含用于处理不同任务的模型定义,包括:图像分类、逐像素语义分割、对象检测、实例分割、人物关键点检测和视频分类。

在这个项目中,我将使用 vgg11、vgg13vgg16 网络,它们都由 非常深的卷积网络组成,用于大规模图像识别。

该项目

该项目包括训练一个图像分类器来识别不同种类的花。此外,分类器将以应用方式进行转换,这意味着可以在终端中运行代码,用训练模型对给定图像进行预测。你可以关注我的 GitHub 资源库中的项目。

让我们来看一些我们想要预测的花的例子:

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

Example of Flowers to be Predicted

数据集分为三部分:训练验证测试**。在这些图像中应用了一些变换,例如随机缩放裁剪翻转。这有助于网络泛化,从而提高性能。此外,根据预训练网络的要求,图像被调整为 224x224 像素**。你可以在下面看到一个转换的例子。****

如果我们加载一个预先训练好的 vgg16 ,我们会看到类似这样的内容:

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

请注意,预训练网络被视为功能**。我们需要做的就是建立我们自己的神经网络,取代预训练模型的*(分类器)部分。因此,利用我们自己的网络,利用 vgg16 提供的(特征)部分,利用我们自己的花朵图像,我们可以训练网络的(分类器)部分来构建我们的模型。*

构建网络

将取代预训练网络的(分类器)部分的神经网络可以通过一个简单的类轻松完成,如下所示。

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

请注意,在这个类中使用了所谓的辍学**。dropout 的概念非常简单:在神经网络的每次迭代中,我们将随机删除一定比例的节点,这对我们减少过度拟合有很大帮助!**

训练网络

网络培训将包括以下步骤:

  • 在网络中执行前馈通道并计算 y 的预测值
  • 预测和真实标签必须插入损失函数中(为此,我将使用 NLLLoss 负对数似然损失)。
  • 基于损失函数,执行反向传播传递以将误差传播到其他节点。
  • 通过优化器重新计算权重(为此我将使用 Adam 优化器)。
  • 计算交叉验证结果(损失和准确度)以监控结果。
  • 重复整个过程 N 个周期!

下面我展示了一个 4 代执行的例子。

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

我们可以看到,损失函数降低,而验证数据的准确性显著提高!

保存模型

一旦模型被训练,我们需要保存它来进行预测。在此步骤中,必须完成以下步骤:

  • 保存类到索引的映射,以及类别名称,这样我们可以跟踪预测的花的名称;
  • 使用关于模型的信息(如网络输入大小)创建模型检查点。网络输出大小(在这种情况下是 102,这是不同花的数量);隐藏的层;辍学率等等。

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

做预测

做预测仍然需要一些编码!

我们首先需要以与处理训练数据相同的方式转换每个输入图像,这可以通过特定于该任务的函数来完成:

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

最后,这个过程非常简单:一旦我们处理了输入图像,我们就可以加载我们训练过的模型并进行一次向前传递**。然后,我们从 102 个类中选择最有可能的结果类,并将其索引映射到相应的花。就这些了!预测的示例显示在下面的 top 5 预测中。**

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

Prediction Example

在这种情况下,最有可能的类是无茎龙胆**!**

创建应用程序

上述概念在类和函数中被模块化,允许人们通过终端调用模型进行预测。下面显示了如何使用该应用程序的一些示例。

训练模型:

为了训练模型,应该给出图像的输入路径以及可选参数,例如要使用的预训练模型(vgg11、vgg13 或 vgg16)、是否使用 GPU、期望的学习速率以及隐藏层的大小。

  • python train.py '。/花
  • python train.py ‘。/flowers’ — save_dir ‘。/’
  • python train.py '。/flowers—arch ’ vgg 11 ’
  • python train.py ‘。/flowers’ -l 0.005 -e 2 -a 'vgg13 ’
  • python train.py '。/flowers '-l 0.005-e 2-a ’ vgg 16 '—GPU
  • python train.py ‘。’/flowers '—learning _ rate 0.01—hidden _ units 2048 1024—epochs 20—GPU

预测花朵

为了进行预测,应该给出要预测的图像的输入路径和训练模型的路径(检查点)。而且,一个。json 文件与每个类(category)对应的花名可以作为参数传递。**

  • python predict.py。/flowers/test/15/image _ 06351 . jpg ’ ’ check point . PTH ’
  • python predict.py。/flowers/test/15/image _ 06351 . jpg ’ ’ check point . PTH '—category _ names cat _ to _ name . JSON
  • python predict.py。/flowers/test/15/image _ 06351 . jpg ’ ’ check point . PTH '—category _ names cat _ to _ name . JSON—top _ k 3
  • python predict.py。/flowers/test/15/image _ 06351 . jpg ’ ’ check point . PTH '—category _ names cat _ to _ name . JSON—top _ k 5—GPU

结论

我们首先描述了什么是迁移学习,以及它与深度学习的关系。然后我们明白,可以使用一个预先训练好的网络,它是为一个特定的目的而制作的,因为的特点是用于训练一个不同的神经网络,具有不同的目的。

这些概念然后被用来预测在英国发现的不同种类的花。所获得的函数和类被模块化,以便创建能够训练神经网络并对给定输入图像进行预测的完整应用。

仇恨言论的分类:概述

原文:https://towardsdatascience.com/classifying-hate-speech-an-overview-d307356b9eba?source=collection_archive---------10-----------------------

浅谈标签分类和仇恨言论

雅各布·克拉布雪莉·杨安娜·祖波娃主演。

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

什么是仇恨言论?

争论仇恨言论是一个古老的挑战,但今天仇恨言论的规模、个性化和速度是一个独特的现代困境。虽然仇恨言论没有确切的定义,但一般来说,这种言论不仅仅是为了侮辱或嘲笑,而是通过攻击目标独特的东西来骚扰和造成持久的痛苦。仇恨言论在在线论坛、聊天室和社交媒体中尤为普遍。

Hatebase.org,一家加拿大公司,创建了一个多语种仇恨言论词汇词典,有以下识别仇恨言论的标准(来源):

  • 它针对特定人群(种族、国籍、宗教、性别、残疾或阶级);
  • 有恶意;

仇恨言论有一个很难归类的主要问题:主观性。除了第一修正案的例外,仇恨言论没有法律定义,也不受法律制裁。因此,什么是仇恨言论,什么不是仇恨言论,可以有不同的解释。乔治·华盛顿大学的计算机科学研究员艾琳·卡莉斯坎认为,这在很大程度上取决于领域和语境。

但由于人类无法总是就什么可以被归类为仇恨言论达成一致,因此创建一个通用的机器学习算法来识别它就变得尤为复杂。此外,根据芬兰阿尔托大学的 Tommi grndahl 的说法,用于训练模型的数据集往往“反映了收集或标记数据的人的大多数观点”。

更复杂的是,即使对人类来说,也很难区分仇恨言论和攻击性语言。这就成了一个问题,尤其是当标签是由随机的用户根据他们自己的主观判断来做的时候,就像在这个数据集中,用户被建议将推文标记为“仇恨言论”、“攻击性语言”或“都不是”。因此,在设计模型时,遵循有助于区分仇恨言论和攻击性语言的标准非常重要。

值得指出的是,Hatebase 的数据库在创建仇恨言论检测算法方面非常有用。这是一个多语种词汇,根据在仇恨言论中使用的可能性,这些词被贴上从“温和”到“极度冒犯”的标签。

尽管对于是否应该限制仇恨言论存在不同意见,但一些公司,如脸书、Twitter、Riot Games 和其他公司决定控制和限制仇恨言论,使用机器学习进行检测。

模型灵敏度

检测仇恨言论的另一个问题是机器学习算法对文本异常的敏感性。

模型是“用数据训练的算法的输出”(来源)。机器学习算法或模型可以为我们分类文本,但对微小的变化很敏感,比如删除令人讨厌的单词之间的空格。这一改变可以大大降低一个句子得到的负面分数(来源)。学习模型可能会被愚弄,错误地标注它们的输入。机器学习算法的一个关键挑战是理解上下文。

仇恨言论的阴险本质在于,它可以根据上下文变化成许多不同的形态。如果社会对用词的选择达成共识,歧视性的想法可能隐藏在许多善意的话语中。例如,儿童玩具的名字和标签可以作为仇恨思想的绰号。在布尔逻辑中将意义归属于一个词的静态定义不具有适应为仇恨而改变昵称的灵活性。“人工智能在这一点上没有意识到语境,这就是语言令人憎恶的原因,”哈佛大学伯克曼·克莱恩互联网与社会中心的成员布里坦·海勒说。

每一家允许用户自行发布内容的公司都面临着一个挑战,那就是演讲与他们的品牌相关联。《连线》杂志 4 月刊描述了脸书的持续增长如何引发了一个重大问题,“该公司的商业模式是否与其宣称的使命(让世界更加紧密地联系在一起)相一致。”(来源)仅仅通过给人们更多的工具来分享,我们可能无法让人们团结起来,让世界变得更美好。

在下一节中,我们将研究另一家公司 Riot Games 如何应对缓和仇恨言论的挑战。

案例分析:暴乱游戏的英雄联盟

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

对于那些不知道的人来说,英雄联盟是一个竞争性的游戏,两个队各有五名球员,试图摧毁对方的基地。

当然,在 2009 年发布时,Riot games 希望创造一个友好竞争能够蓬勃发展的有趣环境。这是最初的目标。

英雄联盟使用内置文本,随着游戏的普及和用户群的增长,竞争加剧。玩家开始使用聊天来幸灾乐祸他们在游戏中的表现,或者摧毁敌人团队阻止不可避免的失败的徒劳尝试。这仍然在公司的目标范围内。然而,很快,它就退化了,直到人们普遍看到这样的事情:“你的整个生活都是垃圾”,“自杀吧”,或者无数其他胜利者会对失败者做的下流事情的宣言。这变得如此平常,以至于玩家给它起了个名字:毒性。玩家变得麻木,甚至变得积极,正直的玩家会不假思索地做出有害的行为。Riot Games 发现,在他们的内部玩家分类(消极、中立和积极)中,87%的毒性来自中立或积极的玩家。疾病正在蔓延。(来源)

2011 年,Riot Games 发布了一个名为“法庭”的解决方案。法庭被设计成与另一个游戏内的功能“报告”一起工作(“T2”来源)。在游戏结束时,如果你觉得另一个玩家中毒了,报告是将这些问题发送给 Riot Games 进行审查的一种方式。然后,Riot Games 会将报告交给法庭。该法庭是一个由志愿者组成的陪审团审判系统。担心的玩家可以注册法庭,然后查看游戏报告,并逐案投票决定某人是否真的有毒。如果你的投票与大多数人一致,你将获得少量游戏内货币,违规的有毒玩家将受到少量惩罚,对于屡犯者,惩罚将会增加。Riot Games 还向无毒玩家发放小额奖金。这些共同的努力使玩家群体得到了改善,Riot 发现,法庭的一项处罚就足以遏制大多数玩家的有害行为。

这个系统有两个主要问题:

  1. 它既慢又低效。人工审查需要将这些聊天记录放到法庭网站上,然后必须等待足够多玩家的回应,然后在那里决定处罚。

2.它有时非常不准确(特别是在他们取消每次“成功”惩罚的奖励之前,这导致了系统中的超级先天偏见)。(来源)

2014 年,暴乱导致法庭关闭。它已经工作了一段时间,但毒性仍然是一个问题。

一个机器学习解决方案:

然而,在那之后,Riot Games 获得了他们大约 1 亿份法庭报告(来源),并将其作为训练数据来创建一个机器学习系统,该系统可以检测出有问题的行为,并对这些行为做出定制化的回应(基于玩家在训练数据的法庭案件中的投票方式)。)

虽然法庭速度慢或效率低,有时需要几天或一两周才能做出判决(在玩家忘记他们的有毒行为很久之后),但这个新系统可以在 15 分钟内分析并做出判决。玩家们几乎看到了他们行为的直接后果。

“由于这些治理系统改变了在线文化规范,英雄联盟中同性恋恐惧症、性别歧视和种族主义的发生率已经下降到所有游戏的 2%,”言语虐待下降了 40%以上,91.6%的负面玩家在一次报道的处罚后改变了他们的行为,再也没有犯下其他罪行。(来源)

机器学习方法

机器学习方法在检测网络平台上的仇恨言论方面取得了突破。在本节中,我们将讨论一些传统上用于此任务的技术以及一些新方法。

预处理数据

自然语言处理(NLP)是将人类单词转换为机器可以理解的数字和向量的过程。人类世界和机器世界之间的一种工作方式。自然,这需要相当多的数据清理。通常,清理意味着删除停用词、词干化、标记化,以及实现词频-逆文档频率(TFIDF ),该词频赋予更重要的词比“the”之类的词更重的权重,而“the”之类的词因增加较少的含义而受到惩罚。(来源)词汇化是一种计算量更大的方法,用于提取单词的词干。(来源)

模型实现

一旦数据是干净的,我们使用几种方法进行分类。常见的文本分类方法有“情感分析、主题标注、语言检测、意图检测。”(来源)更高级的工具包括朴素贝叶斯、bagging、boosting 和随机森林。每种方法都可以有一个召回率、精确度、准确度和 F1 分数,与它的分类程度相关联。然后我们要反复测试这些方法。尽管我们的人工智能在训练数据集上非常准确,但它们在测试数据上也同样糟糕。我们需要确保我们的模型不会过度适应我们的训练数据,使其在分类测试数据方面表现出色,但在准确分类未来数据方面表现不佳。下面是另外三种应对文本分类挑战的方法。

多标签分类

基线多标签分类方法,称为二元相关性方法,相当于为每个标签独立训练一个二元分类器(来源)。这种方法将每个标签与其他标签分开处理。例如,如果你试图归类为“我讨厌那种食物,我们午餐不要吃它。”标签:午餐谈话,爱情谈话,仇恨谈话。您的分类器将遍历数据三次,每个标签一次。

对于下面的数据和标签,(预处理后)二元相关性方法将对每个标签进行单独预测。(我们将使用朴素贝叶斯分类器,在这里有很好的解释)

data = pd.read_csv('lunchHateLove.csv')
data.head()

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

# using binary relevance
from skmultilearn.problem_transform import BinaryRelevance
from sklearn.naive_bayes import GaussianNB# initialize binary relevance multi-label classifier
# with a gaussian naive bayes base classifier
classifier = BinaryRelevance(GaussianNB())# train
classifier.fit(x_train, y_train)# predict
predictions = classifier.predict(x_test)#print the keywords derived from our text
#along with the labels we assigned, and then the final predictions
print(data.comment_text[1], '\n',
      data.comment_text[3], '\n',
      y_test, '\n',
      predictions, '\n') hate love kind food okay lunch 
food hate love get lunch 
    lunch_talk  love_talk  hate_talk
1        1          0          1
3        1          1          1 
  (0, 0)	1
  (1, 0)	1
  (1, 1)	1
  (0, 2)	1
  (1, 2)	1

因此,在这个简单的例子中,二元相关性预测第一列(0,0)中第一行的点对于标签“午餐 _ 谈话”是真实的,这是基于我们的原始输入的正确标签。事实上,在这个非常简单的例子中,二元相关性完美地预测了我们的标签。

如果你想更详细地了解这些步骤,这里有一个 Github 上这个例子的链接。或者更好的是,看看这个关于这个主题的博客,它有更多的细节,还有一个到我用作起点的 Github 页面的链接。

转移学习和监督不力

机器学习模型的一个瓶颈是缺乏标记数据来训练我们识别仇恨言论的算法。两种解决方案是迁移学习和弱监督。

迁移学习意味着在新的任务中重用已经存在的模型,这不仅在缺少标记数据是一个问题的情况下,而且在未来可能需要重新标记时都非常有用。如果一个模型不是从零开始学习,而是从另一个为解决类似任务而设计的模型中学习,那么这个模型可以表现得更好,这种想法并不新鲜,但在 Fastai 的 ULMFiT 出现之前,它并没有在 NLP 中使用太多。

ULMFiT 是一种在数百万维基百科页面上使用预训练模型的方法,可以针对特定任务进行调整。这个调整后的模型稍后用于创建分类器。这种方法的效率令人印象深刻:“仅用 100 个已标记的例子(并让它访问大约 50,000 个未标记的例子),【这是可能的】实现与用 10,000 个已标记的例子从头训练一个模型相同的性能” ( 来源)。另一个优点是,这种方法可以用于英语以外的语言,因为用于初始训练的数据来自许多语言的维基百科页面。其他一些用于 NLP 的迁移学习语言模型有:Transformer,Google 的 BERT,Transformer-XL,OpenAI 的 GPT-2,ELMo,Flair,StanfordNLP ( source )。

在缺少标记数据的情况下,可以应用的另一个范例是弱监督,其中我们使用手写的启发式规则(“标签函数”)来创建可以应用的“弱标签”,而不是手动标记数据。在这个范例中,首先建立基于这些弱标签的生成模型,然后使用它来训练判别模型(源)

在本文的中给出了使用这两种方法的例子。来自斯坦福大学的人工智能硕士生亚伯拉罕·斯塔罗斯塔(Abraham Starosta)展示了他如何结合使用弱监督和转移学习来识别反犹太人的推文。

他从一组约 25000 条推文的未标记数据开始,并使用浮潜(一种用于弱监督标记的工具)通过编写简单的标签函数来创建训练集。这些函数用于训练“弱”标签模型,以便对这个大数据集进行分类。

为了将迁移学习应用于这个问题,他通过在一般化的推特上训练 ULMFiT 的语言模型,对其进行了微调。然后,他在用弱监督标签创建的训练集上训练这个新模型。结果相当令人印象深刻:作者能够达到 95%的精确度和 39%的召回率(概率阈值为 0.63),而在不使用弱监督技术的情况下,对于 90%的精确度,召回率为 10%。该模型的表现也优于来自 sklearn、XGBoost 和前馈神经网络的逻辑回归(来源)。

基于投票的分类

基于投票的方法是用于分类的集成学习,有助于平衡单个分类器的弱点。集成方法结合了单独的分类器算法,例如:bagging(或 bootstrap aggregating)、决策树和 boosting。如果我们考虑一个线性回归或一条线来预测给定 x 的 y 值,我们可以看到线性模型不擅长识别非线性聚类。这就是集合方法的用武之地。“这种线性分类器集合的适当组合可以学习任何非线性边界。”()可以一起使用各自具有唯一判定边界的分类器。投票分类器的准确度“通常高于单个分类器”(来源

我们可以通过多数投票(也称为简单投票、加权投票和最大投票)来组合分类器。在多数表决中,“分类系统遵循分而治之的方法,将数据空间划分为更小、更容易学习的分区,每个分类器只学习其中一个更简单的分区。”(来源)在加权投票中,我们可以多次统计更有用的模型。(来源)我们可以用这些方法对外文文本进行有效的分类。(来源)就可用性而言,基于投票的方法有利于优化分类,但不容易解释。

意识到机器学习的强大应该伴随着对如何解决其局限性的理解。用于从我们的社交空间中删除仇恨言论的人工智能通常位于黑盒中。然而,随着对自然语言处理和文本分类的一些探索,我们可以开始解开我们对人工智能的期望,我们不需要成为科技巨头的一部分来永久实现分类器。

通过机器学习分类文学运动

原文:https://towardsdatascience.com/classifying-literary-movements-through-machine-learning-ea49cb4339c1?source=collection_archive---------34-----------------------

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

Photo by Dmitrij Paskevic

谁不喜欢图书馆和书架?他们储存知识的对象和所有故事的大门。负责订购书籍的是图书馆员,他们经过多年的培训,知道人们阅读的是什么类型的文本,因此知道在哪里存放它们。传统上来说,这种排序或“分类”是通过字母来完成的,所以图书管理员可以很容易地通过例如埃德加·艾伦部分 P 来找到书籍。但是,文学运动呢?如果这些图书馆员对作者的名字视而不见,只留下原始文本,他们将被迫仔细阅读每一个文本,以确定文学运动,从而对其进行正确分类。例如,我们知道爱伦坡被认为是一个浪漫主义者(更多关于文学运动在这里),但我们知道这一点是因为我们被告知如此,因为我们已经学会识别构成浪漫主义的关键词、语义形式和文学形式。

在这里,我开始寻求创造(训练)一个 图书管理员算法 ,如果你希望这样称呼它,它可以对来自三个不同文学运动的表现相对较好的文本进行分类:浪漫主义现实主义和*超现实主义。*为此,我将使用 Python 3 环境和典型的机器学习库,以及 TensorFlow 的一个不太典型但相当惊人的预训练深度学习算法,该算法可以通过在 16 种不同语言中嵌入的句子将任何给定的句子编码成数字表示!更令人惊奇的是,这种转换是在没有任何特殊文本处理的情况下完成的,您只需以其原始形式(当然是在任何支持的语言中)使用它,它就会计算各自的嵌入向量。

我希望在本文的最后,你会对如何应用这个算法,如何在你自己的项目中使用它,以及如何改进我为你自己的优势而写的所有代码有一个更好的想法。我现在将详细描述方法和结果,抓紧了!

我们需要做的第一件事是从这三个类别中收集一些报价。为此,我选择了 Goodreads,这是一个令人难以置信的网站,在这里你可以搜索到成千上万作者的语录。对于这个分析,我存储了(手动,这里没有使用抓取方法,正常的复制/粘贴)至少三种不同语言的大约 170 个报价,其中英语是绝对最常见的。有些引文是法语的,有些是西班牙语的,极少数是葡萄牙语的。我本可以只用英文引号,但是我想测试一下这种嵌入算法的灵活性。

然后,我创建了三个文件,每个运动一个:浪漫主义. txt、现实主义. txt 和超现实主义. txt,所有文件都包含作者的名字,后跟每个作者的八段引文,每个运动分别有 8、6 和 7 个作者(总共 168 段引文)。我使用了多少作者和引用完全是随意的选择,但是如果你想知道的话,类别或引用的不平衡是故意的。

你可以在这里找到完整的笔记本和报价文件如果你想亲自尝试的话。

对于整个管道,您需要导入这些模块,因此确保安装了它们( pip 安装包通常会在大多数情况下起作用):

#Tensorflow , tf-hub and tf-sentencepiece, all needed to calculate #embbedings. Check [this discussion](https://github.com/tensorflow/hub/issues/345) to install compatible versions. #At the time of this writing, a compatible mix of packages is tf #v1.13.1, hub v0.5.0 and sentencepiece v0.1.82.1:import tensorflow as tf
import tensorflow_hub as hub
import tf_sentencepiece#numpy and randomimport numpy as np
import random# sklearn and imblearn packages:from sklearn.neural_network import MLPClassifier
from sklearn.metrics import confusion_matrix, f1_score
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import StratifiedShuffleSplit
from imblearn.under_sampling import EditedNearestNeighbours#Visualization:
import seaborn as sns
import matplotlib.pyplot as plt
import networkx as nx

然后,第一个预处理步骤当然是加载数据。为此,我使用了以下代码行:

# This loads each file to variables f_X:
f_rom = open(“Romanticism.txt”, “r”)
f_rea = open(“Realism.txt”, “r”)
f_sur = open(“Surrealism.txt”, “r”)#This creates a list of all author names plus their quotes:
list_all_rom = f_rom.readlines()
list_all_rea = f_rea.readlines()
list_all_sur = f_sur.readlines()

其中每个列表都是这样的:

['"Author1","quote1","quote2","quote3"\n', '"Author2..."\n']

然后,我们可以用这个函数合并每个文学运动的所有引用:

然后简单地运行这个命令,将它们合并成一个大列表:

merged_list_rom = merge_list(list_all_rom)
merged_list_rea = merge_list(list_all_rea)
merged_list_sur = merge_list(list_all_sur)merged_list_all = merged_list_rom + merged_list_rea + merged_list_sur

在这里, merged_list_all 是所有运动(有序)的引用集合,看起来像这样(如果你是一个好的图书管理员,你可能会认出作者,也可能认出某些引用的运动!):

'I have absolutely no pleasure in the stimulants in which I sometimes so madly indulge...',
'Once upon a midnight dreary, while I pondered, weak and weary, Over many a quaint...',
'This is what you shall do; Love the earth and sun and the animals, despise riches, give alms to every...',
...
...
...
'Avec ce coeur débile et blême Quand on est l'ombre de soi-même Comment se pourrait-il comment Comment se ... ,'
... 
x 168

这些引用是我们嵌入分析的输入。现在有趣的部分来了!首先是从 TensorFlow 的 hub 加载我之前谈到的预训练深度神经网络,称为通用句子编码器多语言 ( Yan et al .,2019 )并初始化其会话:

我建议先下载并保存网络,这样你就不用担心每次重启电脑时都要下载了,因为模型总是保存在/tmp 中(至少在 Linux 中是这样),如果你这样做了,就可以避免这一步。反正用网速下载也要 1 分钟左右。你可以在这里阅读更多关于如何做这件事的

到目前为止,我们正在准备我们的环境来进行实际的机器学习。第一个机器学习代码如下,它计算并存储所有句子嵌入,并计算所有可能引用对的距离(内积)(当然是在嵌入空间中)。后者以后会派上用场。

请注意,此函数使用之前加载的会话,因此请确保它在您的 Python 环境中进行了初始化。然后,我们将合并的报价列表提供给这个函数:

sM_All, e_All = similarity_matrix(merged_list_all)

还要注意的是, e_all 是一个维数为 x 512 的数组(这个数字是 TensorFlow 预训练算法使用的默认嵌入向量大小),而 sM_All 是我们将在本次分析结束时使用的语义相似度矩阵。因为我们想要做的是对文本进行分类,所以我们缺少了这个难题的一个重要部分,一个类数组。我们知道 e_All 中所有栏目的排序,我们知道第一大块是浪漫主义,其次是现实主义,最后是超现实主义(所以,三个乐章)。因此,我们可以确定在 merge_list_all 中给出的每个动作有多少报价,因此:

classes = np.asarray([1 for i in range(len(merged_list_rom))] + \
[2 for i in range(len(merged_list_rea))] + [3 for i in range(len(merged_list_sur))])

创建一个类列表,类似于:[1,1,1,1,… 2,2,2,2,…3,3,3],每个类有正确的实例数。现在我们准备建立一个分类器管道来训练我们的图书管理员算法,并做交叉验证来测试它有多好。为此,我编写了这个简单的函数,增加了提供任何分类器作为输入的灵活性:

然后,我们定义一个分类器(在这种情况下,我们将使用 sklearn 的多层感知器,您可以尝试其他人,如 SVM、KNN 等。):

clf = MLPClassifier(max_iter=500,activation="tanh")

然后运行该函数:

class_pred, class_test, f1_score = class_pipeline(StandardScaler().fit_transform(e_All),classes,clf)

注意 e_All 要先标准化,这是另一个常见的预处理步骤

太好了!现在让我们看看结果!所有 k 倍的平均值 F1(我们有一个略微不平衡的类别分布,因此,根据一个众所周知的经验法则,在这些情况下,F1 是一个比精确度更好的性能估计值)为:

>>>print(np.mean(f1_score))>>>0.73

这么小的样本,一个 F1 = 0.73 真的不差!现在让我们来看看混淆矩阵,以便更好地了解正在发生的事情:

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

Confusion Matrix for literary movements

看起来现实主义带来了更多的麻烦。这可能是因为它是最少表示的类,这是机器学习中的一个常见问题。我们可以试着用采样下的(超过采样创建合成数据,所以最好使用我们现有的来自 imblearn 的方法来平衡这些类。现在,我将平衡交叉验证循环之外的类。在实践中,我总是喜欢在验证循环中,并且只在训练集中这样做。为此,只需取消 class_pipeline 中第 6–7 行的注释即可:****

#sm = EditedNearestNeighbours()
#[features, class_ground] = sm.fit_resample(features, class_ground)

现在让我们看看结果:

>>>print(np.mean(f1_score))>>>0.78

越来越好!这可能表明一个更大和更平衡的数据集会显示更好的结果!

你可能最终会争辩说文学运动是主观定义的,那么为什么这些类会足够强大来显示一致的结果呢?为了测试这一点,我们可以重组类并重新运行管道。简单地做:

random.shuffle(classes)

打乱我们一开始定义的课程顺序。再次运行它(使用混排的类)会抛出 F1 = 0.25,反映出我们最初的类边界(浪漫主义现实主义 & 超现实主义)是由文本中存在的真实可测量的特征定义的。有意思!

总之,这一切看起来相当好!请记住,这是用相对较小的样本(总共不到 170 条引文)和四种不同的语言完成的!这种方法似乎很有前途!你如何改进它?你认为用这种方法还能做什么?

我们可以做的最后一个分析是用我们的距离矩阵来查看所有引用之间的语义距离。还记得 sM_All 吗?嗯,现在是我们使用它的时候了:

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

Semantic similarity between all posible quote pairs. Heatmap represents a symmetric matrix with all semantic similarity values where very similar quotes are colored in blue and very different in yellow. Right graph represents a render of this matrix where nodes are quotes and connections portray thresholded (see source code) similarity values. Romanticism highlighted with a turquoise blue line, Realism with green and Surrealism with gray. Final figure tweaked with Inkscape.

太好了!使用这种方法,您可以直观地看到完整的报价生态系统。正如您所看到的,一些引用对比其他引用对更相似(距离更接近 1)。具体报价呢?有了这些信息,我们可以检查任何给定的引用,哪一个引用在语义形式上是最接近的!对此我们可以用:

#Quote 0 as an example (from Poe):
find_closest(sM_All,merged_list_all,names_mult,0)

其输出为:

‘Edgar_Alan_Poe’,
 ‘I have absolutely no pleasure in the stimulants in which I sometimes so madly indulge. It has not been in the pursuit of pleasure that I have periled life and reputation and reason. It has been the desperate attempt to escape from torturing memories, from a sense of insupportable loneliness and a dread of some strange impending doom.’,
 ‘Georges_Bataille’,
 ‘I enjoyed the innocence of unhappiness and of helplessness; could I blame myself for a sin which attracted me, which flooded me with pleasure precisely to the extent it brought me to despair?’

你觉得这些引文在语义内容上看起来相似吗?对我来说是的!其他语录/作者呢?您可以研究一下代码来找出答案。这部分分析是我打算在未来深入探讨的。

提醒:您可以在此查看该项目的完整笔记本

我希望这个演示能为您提供一些关于如何使用句子嵌入、分类以及文本相似性的呈现和可视化的见解。你可以在任何领域应用这个,不要觉得局限于文学。事实上,可能的应用程序数量相当大,并且支持如此多的语言,这种算法将长期存在。就我个人而言,我非常惊讶在如此小的样本中看到如此高的 F1 分数。最后,这就是机器学习的力量(当然包括深度学习):通过正确的处理步骤,你可以构建算法,完成手头原始数据似乎不可能完成的工作。图书管理员会很高兴有这样的算法的帮助。

感谢您的阅读!

根据违约风险对贷款进行分类

原文:https://towardsdatascience.com/classifying-loans-based-on-the-risk-of-defaulting-using-logistic-regression-9bd9c6b44640?source=collection_archive---------9-----------------------

简短的介绍

分类是监督学习中的经典问题之一,我们试图训练一个模型来将数据点分类成* n *个不同的类别。当我在网上浏览数据集时,我发现了一个包含 1000 名贷款申请人信息的数据集(来自城市和农村地区)。数据表中的一列是贷款是否被批准。我立刻想到了一个主意:

如果我们可以建立一个模型,根据申请人的违约风险来预测他或她的贷款是被批准还是被拒绝,会怎么样?

这将是一个普通的分类问题,我们有两个不同的类来分组我们的数据:贷款批准或贷款拒绝。

重要的是不要草率行事,并根据原始数据和未开发的数据开始训练模型。预处理数据不仅有助于我们消除不一致性(缺失值和异常值),还能让我们对数据有一个全面的了解,进而帮助我们选择模型。

这个端到端的机器学习项目主要基于 Python。我使用了以下库来帮助我实现目标:

  1. Numpy 进行数学运算。

2.熊猫进行数据探索和分析

3.用于数据可视化的 MatplotlibSeaborn

  1. Scikit-learn 了解模型培训、交叉验证和评估指标。

导入库

让我们事先做好所有必要的进口工作。

**import** **numpy** **as** np
np**.**seterr(divide**=**'ignore')
**import** **math**
**import** **pandas** **as** pd
**from** **sklearn.linear_model** **import** LogisticRegression
**from** **sklearn.model_selection** **import** train_test_split
**from** **sklearn.preprocessing** **import** OneHotEncoder
**from** **sklearn** **import** metrics
**import** **matplotlib.pyplot** **as** plt
**import** **seaborn** **as** sns

一旦我们有了所有必要的库,我们就可以使用 Pandas 从 CSV 文件中读取数据。

data **=** pd**.**read_csv('credit_risk.csv')

了解功能

在继续进行数据探索之前,我总是喜欢在表面层次上理解我将要处理的特性。这样做将有助于我们把我们做出的任何数学解释用语言表达出来。以下是我们数据集中的要素列表:

  1. 贷款 ID :银行给贷款请求的 ID。
  2. 性别:主申请人的性别。
  3. 已婚:表示主申请人婚姻状况的二元变量。
  4. 家属:主申请人的家属人数。
  5. 教育:二元变量,表示主申请人是否高中毕业。
  6. 自雇:表示个人是否自雇的二元变量。
  7. 申请人收入:主申请人的收入。
  8. 共同申请人收入:共同申请人的收入。
  9. 借款金额:申请人希望借款的金额。
  10. 贷款金额期限:申请人偿还贷款的期限。
  11. 信用历史:代表客户有良好历史还是不良历史的二元变量。
  12. 财产区域:分类变量,表明申请人是来自城市、半城市还是农村地区。
  13. 贷款状态:表示贷款是被批准还是被拒绝的变量。这将是我们的输出(因变量)。

在所有这些变量中,我选择了性别、申请人收入、贷款金额和房产面积作为要深入研究的变量。重要的是从多个角度看待数据,即独立地和与其他变量相关地看待数据。这指出了变量分布中的任何危险信号,也揭示了它们之间有趣的关系。

可视化数据

人类是视觉动物,当我们看到信息时,大多数人会更好地处理信息。因此,在理解我们的数据时,采用可视化的方法比手动处理数百行数据要有效得多。我绘制了可视化图,显示了重要特征的分布以及一些特征之间有趣的关系。我如何决定哪些特性是重要的?我使用了相关矩阵,其中(I,j)处的值表示特征 i 与特征 j 的相关程度。

我们可以使用 seaborn 的热图可视化来帮助我们理解相关矩阵。

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

The Correlation Matrix for the Dataset

sns**.**heatmap(data**.**corr())

在我们开始探索我们的特征变量之前,我想看看我们的因变量,即我们试图使用模型预测的变量。下面是一个简单的分类计数图。

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

A count of the two classes that we are attempting to predict

各阶级之间存在明显的不平衡,这可能是非常危险的!我们的模型最终可能会高度偏向多数类,这对于模型的泛化能力来说并不理想。出于这个原因,我们将执行特征缩放以确保一致性,并确保我们用来构建模型的算法“意识到”这些类是不平衡的。

我也很好奇房产面积和贷款金额是如何共同影响贷款授权的。让我们来看一下贷款金额与批准金额的关系图,该图由物业面积分隔。

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

A Scatter plot of Loan Amount against the Loan Status, color-coded by the Property Area

如果我们将数据分为批准的和未批准的贷款,并查看这些贷款申请中有多少来自每个物业区域,这将会有所帮助。

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

A bar plot depicting the number of approved applicants from each property area

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

A bar plot depicting the number of unapproved applicants from each property area

从表面上看,似乎有更高比例的农村贷款申请被拒绝。我计算了每个房地产领域的贷款批准比率,这些数字证实了我们的假设。

  1. 城市赞成率:0.7368421052631579
  2. 半市区赞成率:0.7822349570200573
  3. 农村赞成率:0.6448275862068965

清理数据

既然我们已经直观地探索了数据,以更好地理解我们正在处理的东西,那么是时候预处理我们的数据,以确保我们训练的模型不受任何嘈杂的训练实例的影响(在 ML 的上下文中,术语“训练实例”指的是作为用于训练和测试模型的数据集的一部分的单个数据点。)我将我们的预处理步骤分为以下子步骤:

  1. 如有必要,检查并替换缺失的值。
  2. 删除不必要的功能。
  3. 对分类特征进行编码,以确保它们得到正确的解释。
*# Replace the categorical values with the numeric equivalents that we have above*
categoricalFeatures **=** ['Property_Area', 'Gender', 'Married', 'Dependents', 'Education', 'Self_Employed']

*# Iterate through the list of categorical features and one hot encode them.*
**for** feature **in** categoricalFeatures:
    onehot **=** pd**.**get_dummies(data[feature], prefix**=**feature)
    data **=** data**.**drop(feature, axis**=**1)
    data **=** data**.**join(onehot)

注意,数据预处理绝不是公式化的,我将要采取的步骤是主观的。

训练模型

最后,激动人心的部分!我们已经准备好了我们的数据,我们将把它提供给我们的模型去吞食!我为这个特殊情况选择的算法是逻辑回归。这是一种更简单的监督学习算法,但已被证明在各种情况下非常可靠。

在我们训练模型之前,我们将利用 Scikit-learn 内置的训练-测试分割模块,将我们的数据集随机分割成训练和测试子集。我们将根据 80-20 法则(这看起来是一个任意的、没有科学依据的选择,但众所周知,当涉及到训练模型时,它“正好起作用”)。

让我们从实例化一个逻辑回归对象(我们将使用 scikit-learn 的模块)开始,并以上述方式分割数据集。

*# Liblinear is a solver that is effective for relatively smaller datasets.*
lr **=** LogisticRegression(solver**=**'liblinear', class_weight**=**'balanced')

请注意,我们指定所讨论的类的权重必须平衡。这确保了类别被适当地加权,从而消除了由类别中的不平衡所产生的任何偏差。如果你对等级是如何加权的感到好奇,Chris Albon的这篇文章提供了一个全面的解释。

在我们传入数据之前,让我们使用 Scikit-learn 的标准缩放器来执行特征缩放。

scaler **=** StandardScaler()
data_std **=** scaler**.**fit_transform(data)*# We will follow an 80-20 split pattern for our training and test data*
X_train,X_test,y_train,y_test **=** train_test_split(data, y, test_size**=**0.2, random_state **=** 0)

现在我们已经有了所有需要的东西,我们让模型适合训练数据。

lr**.**fit(X_train, y_train)

评估模型的性能

评估算法的性能与理解和实现算法一样重要(如果不是更重要的话)。我对混淆矩阵和分类的三个基本评估标准做了简单而全面的介绍。

混淆矩阵是矩阵错误率的简单表格可视化,广泛用于评估分类算法的性能。矩阵的行代表实例的实际标签,而列代表预测的标签。在我们的例子中,我们有一个 2x2 矩阵,因为我们正在执行二进制分类。概括地说,一个“n 元”分类问题将有一个 nxn 混淆矩阵。

混淆矩阵的 (m,n) 条目告诉我们有多少正确标签为类别 m 的实例被分类到类别 n 中。因此,矩阵的对角线代表正确的分类,其余的代表不正确的分类。在二进制分类中,对角线条目通常被称为真阳性真阴性,另外两个是假阳性假阴性

既然模型已经定型,我们将使用从原始数据集中筛选出的测试数据来评估我们的模型对数据的泛化能力。我将评估过程分为以下几个部分:

  1. 对模型做出的预测进行矢量化,并构建混淆矩阵。
  2. 使用混淆矩阵
*# We will compare this vector of predictions to the actual target vector to determine the model performance.*
y_pred **=** lr**.**predict(X_test)

*# Build the confusion matrix.*
confusion_matrix **=** metrics**.**confusion_matrix(y_test, y_pred)
class_names**=**[0,1] *# name of classes*
fig, ax **=** plt**.**subplots()
tick_marks **=** np**.**arange(len(class_names))
plt**.**xticks(tick_marks, class_names)
plt**.**yticks(tick_marks, class_names)

*# The heatmap requires that we pass in a dataframe as the argument*
sns**.**heatmap(pd**.**DataFrame(confusion_matrix), annot**=**True, cmap**=**"YlGnBu", fmt**=**"g")

*# Configure the heatmap parameters*
ax**.**xaxis**.**set_label_position("top")
plt**.**tight_layout()
plt**.**title('Confusion matrix', y**=**1.1)
plt**.**ylabel('Actual label')
plt**.**xlabel('Predicted label')

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

The Confusion Matrix for the Logistic Regression Classifier

乍一看,我们的大部分分类似乎都集中在对角线的词条上。一个极好的开始!回想一下,我们说过矩阵给了我们错误率。但是仅仅从矩阵中很难获得模型性能的具体数值度量。因此,我们使用矩阵中的值来计算三个基本的分类性能度量:准确度、精确度和召回率

Scikit-learn 的内置指标模块让我们可以在一行代码中计算这些指标!

*# Print out our performance metrics*
**print**("Accuracy:",metrics**.**accuracy_score(y_test, y_pred))
**print**("Precision:",metrics**.**precision_score(y_test, y_pred, pos_label**=**'Y'))
**print**("Recall:",metrics**.**recall_score(y_test, y_pred, pos_label**=**'Y'))

对于我们的模型,指标的值结果是:

  1. 精度:0.8116883116883117
  2. 精度:0.875
  3. 召回:0.8567196262

一种公认的做法是结合使用精度和召回来衡量分类模型的性能,因为人们可以简单地使用他或她知道会导致正确预测的实例来获得完美的精度分数。换句话说,如果我有一个已知属于正类的训练实例,我会确保模型只将该实例分类到正类中。F1 分数是精确度和召回率的调和和。这是一个衡量模型性能的单一指标,同时考虑了精确度和召回率,从而确保我们不必经历手动解释数字的麻烦。再一次,Scikitl-learn 的度量模块来帮忙了!

**print**("F1 Score:",metrics**.**f1_score(y_test, y_pred, pos_label**=**'Y'))

F1 得分:0.8625592417061612

结论

好吧,太棒了!我们成功地训练了一个模型,它可以根据我们掌握的数据预测对贷款申请人的反应。对我们人类来说,大规模地这样做是徒劳的,但分类器的性能向我们展示了这些技术有多么强大。分类只是预测建模工具箱中众多可用技术中的一种。我希望这已经被证明是一个信息丰富和引人入胜的主题介绍。

编码快乐!

附录

信用风险数据集:https://docs . Google . com/spreadsheets/d/1 em 8 nmtoh 5 _ gph VI _ eowbkujdvidtnc 5 ykbfuihjwk-g/edit?usp =共享

利用计算机视觉对妊娠试验结果进行分类

原文:https://towardsdatascience.com/classifying-pregnancy-test-results-99adda4bca4c?source=collection_archive---------0-----------------------

我第一次尝试 fast.ai 的《程序员实用深度学习》第二课

我是一名数学助理和有抱负的数据科学家,正在学习 fast.ai 的“程序员实用深度学习”课程(你可以在这里阅读我的第一课的经验),第二课,我们将从 Google Images 收集一组图像,以创建和训练一个深度学习模型来对图像进行分类。

我开始试着不看讲稿就浏览第二课的笔记本,因为它似乎是由第一课维基建议的,但是毫无进展。有些人在第二课录制之前就完成了!我想这不是一场比赛,不是最快的也不是退出的理由。一旦我看了讲座,我就很容易明白如何在笔记本上工作,特别是以杰里米的“实验主义者”风格。

首先,我需要决定对哪些类型的图像进行分类。二元分类——其中图像要么是一种东西,要么是不同的东西,而不是完全的其他东西,也不是这两种东西的组合——听起来是一个不错的选择,但因为我需要能够评估模型的表现如何,所以它进行的分类需要是我具有领域专业知识的东西。我有一个纯数学的硕士学位,并考虑做一些涉及数学的事情,但不要想数字识别( MNIST 做得非常漂亮)和一些远比我准备实现的更复杂的事情之间的任何事情。我也有三个孩子,这两个领域可能是我认为自己有“专长”的领域。所以,跟育儿和二元分类有关…啊哈!

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

我们认为怀孕测试要么是阳性的,要么是阴性的,但还有两种看起来非常相似的模糊情况:微弱的阳性,和阴性的蒸发线。有很多论坛——比如 PeeOnAStick.com 论坛——都是有丰富经验的人来解释怀孕测试。人们可能希望数字怀孕测试可以消除测试中的这种猜测,但对于早期微弱的阳性反应,数字测试通常会显示“不确定”或“阴性”,直到怀孕几天后激素水平升高时才会显示准确的结果。

这里有一个微弱阳性的例子:

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

这是一条蒸发线:

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

蒸发线比上面微弱的阳性要暗,但这是阴性测试!这是一个棘手的问题。下图显示了两者之间的一些差异:

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

Image credit: (https://www.momjunction.com/articles/evaporation-line-test_00475745/#gref)

蒸发线比控制线细,所以这是我们识别它的一种方法。然而,很容易看出人类很难发现这一点,所以我想知道我的模型会有什么机会。最好能知道是否已经建立了一个模型来对这些图像进行分类,这样我就可以将我的模型的准确性与之前发表的模型进行比较,我发现一项研究使用机器学习来预测妊娠测试的准确性,但我没有发现任何使用机器学习来对微弱阳性与蒸发线进行具体分类的研究。

选择了一个项目后,我在谷歌上搜索“微弱阳性妊娠试验”和“妊娠试验蒸发线”,并按照讲座中的说明下载每个项目的图像。txt 文件。讲座视频里也是. txt 文件,但是在笔记本里,找的是. csv,没什么大不了改那个,不过是个东西。

然后还有一件事。我按照 Jeremy 的指示做了,但是得到了下面的错误消息和解释:

好的,这在讲座中没有提到,但是我们在 fastai 库中使用的函数,明确地寻找一个文件名以“urls_”开头的文件。我相应地更改了文件名,一切正常。

查看数据进行得很好,虽然我可以看到有一些图像对于模型来说很难分类,因为要么测试不在焦点上,要么图像中根本没有测试。然而,更糟糕的是:当我搜索蒸发线时出现的许多图像是由人们发布的,他们问结果是蒸发线还是微弱的阳性,事实上,更多的时候是微弱的阳性,所以这些图像将在我的数据集中带有“蒸发线”标签,但实际上应该标记为“微弱阳性”。我预测这将是我的模型不准确的最重要的来源。不过,我现在还不担心这个。我从讲座中了解到,在我们第一次运行模型后,如果需要,我们将进行一些超参数调整和手动数据清理(旁白:这肯定是需要的)。

所以我训练模型,结果如下:

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

所以我的训练损失是 0.9,验证损失是 2.78,错误率是 0.56。相当可怕,但我会坚持下去。

我仔细检查了处理学习率的笔记本单元格,但是在我清理完数据之前,我不打算进行任何超参数调整,因为我已经知道这会很混乱。

这是第一次运行的“混淆矩阵”:

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

这表明,在模型预测为蒸发线的测试中,7 个被正确识别,2 个被错误识别为弱阳性。在预测为弱阳性的测试中,13 个被正确识别,12 个被错误识别为蒸发线。因为我知道大部分的蒸发线图片都被发布它们的用户贴错了标签,尽管这或多或少是我所期望看到的。该模型可能比它认为的更准确!

现在我将清理数据。这是第一批:

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

第一个图像有文字覆盖测试,而第三个图像太小,测试窗口太暗,无法确定分类,我想,所以我删除了这些。我还可以改变图像上的标签,这样我就可以切换那些标记为蒸发线的图像,这些图像应该标记为微弱阳性。然后,我用清理后的数据重新创建数据集群。我并不特别乐观,这将增加模型的准确性,达到讲座中显示的模型所达到的非常高的比率,因为测试以不同的配置显示结果:一些显示 a +当阳性时,而另一些显示单线如果阴性,两条线如果阳性。所以如果模型只是数线,那就不好过了。我们走着瞧。

ImageCleaner 函数为清理后的数据集创建一个 cleaned.csv 文件,我使用该文件创建一个新的 ImageBunch,然后再次训练模型。

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

我的训练集损失下降了 0.2,验证集损失下降了 1.5,错误率下降了 0.12。让我们看看新的混淆矩阵:

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

正如我所想的那样,该模型仍然将 12 个微弱的正线分类为蒸发线,并且这些微弱的正线可能如此微弱,以至于我一点也不惊讶它被混淆了。添加不同风格的测试结果显示,模型有甲板堆叠对它。

为了提高准确性,我想我需要得到一组比从谷歌上抓取图像更好的蒸发线图像。我可能还需要为不同的品牌训练不同的模型,但我想看看我是否可以先用一个模型获得相当的准确性(一个模型统治所有的模型?).怀孕倒计时有可以按品牌和结果分类的测试图像。我选择“所有品牌”和“Evap”,得到数百张图片,所以我用新数据重新开始。这些是用户自己标记的,所以有些仍然会被错误标记,但图像质量比我从谷歌图像得到的要好很多。我认为我最初的微弱的正面图像基本上是好的,所以我保留那些。我所知道的唯一获取图片网址的方法。txt 文件是笔记本的做法,但当我这样做时,我得到的只是一个文件类型为“file”的空文件,而不是. txt。我在网上四处查看,发现这个脚本使用 Python 抓取任何网页的图像 URL。好了,现在我们有进展了!<不祥的音乐响起>

该脚本在每张测试照片旁边下载用户头像图像的完整 URL,但出于某种原因,删除了测试图像的前半部分 URL。我意识到,如果我继续使用这种方法,我将不得不删除所有我不想要的图像的 URL,同时修复我想要的图像的 URL。仅仅复制和粘贴我想要的图片的 URL 会更快,但是效率仍然很低。

更糟糕的是,我刚刚意识到怀孕倒计时的照片有一个严重的缺陷。这里有一个例子。你能发现问题吗?

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

我最近听到一个播客,关于一个深度学习模型,它被训练来发现癌变的皮肤生长,虽然它惊人地准确,但最终研究人员意识到,该模型已经发现,它给定的所有癌变图像都有标尺,而非癌变图像没有标尺,所以它在寻找标尺,而不是癌症。这些蒸发线的照片右上角都有一个“Evap”标签!图像是伟大的,但标签是一个大失望。

但结果是,如果我下载了图片,标签就会消失!我考虑学习如何抓取图像,但是因为我意识到上面每一页上有一半的图像不是我想要的,所以这种方法似乎不太适合这个目的。相反,我在 Chrome 上安装了延续了扩展的图片下载程序,让我点击我想下载的图片。手动选择每张图片感觉很不雅观,但这恰恰是我以后必须要做的,以消除噪音图像,否则,所以我打算这样做。

我将图像上传到 evap_lines 文件夹,并再次运行我的模型。

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

那还是很糟糕。这是学习率查找表:

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

我尝试将学习率设置在 1e-5 到 1e-4 的范围内:

再次运行:

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

这是我遇到的最低的训练集损失,验证损失和错误率也有所改善,但还没有接近我们要达到的标准。这是混淆矩阵:

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

同样,几乎所有的误差都是被归类为蒸发线的微弱正值。提高蒸发线图像的质量很有帮助,但我认为我将限制模型只对一个品牌进行分类,而不是所有品牌,因为结果显示的方式不一致,如上所述。

我选择 ClearBlue Easy,因为这是一个受欢迎的测试(大量图片!),还因为蓝色染料测试似乎最容易出现蒸发线。我下载了大约 100 张图像,每张都是蒸发线和微弱阳性(“微弱”是我的判断),然后再次运行这个模型。

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

这仍然没有很好地工作。我知道我的数据是从用户识别的图像中获得的最好的数据,所以我准备尝试一些超参数调整。我将我的学习率设置在 1e-06 和 1e-04 之间:

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

好一点了。也许运行更多的纪元?不,我得到了基本相同的结果。

我在这方面太新了,不能肯定地说,但我认为这是非常可能的,错误率低到我可以在没有更好的图像集来源的情况下得到它。我从这个项目中学到了很多——关于在 Jupyter 笔记本、fastai 图书馆工作,如何从网页下载 URL 和图像,等等。—如果我想到了更好的方法,也许我会在某个时候重新开始,但现在我将把这个项目留在这里,然后选择一个不太复杂的分类问题,重新开始。

上篇:fast . ai 入门

第二课(续):深度学习能比鸽子表现得更好吗?

第三课:一万种行不通的方法

第四课:预测服务员的小费

第五课:但是泡菜去哪里了?

第六课:每个人都想成为一只猫

我是加州大学东湾分校的数学讲师,也是一名有抱负的数据科学家。在 LinkedIn 上和我联系,或者在 Twitter 上打招呼。

使用文本挖掘将产品分类为禁止或批准产品-第一部分

原文:https://towardsdatascience.com/classifying-products-as-banned-or-approved-using-text-mining-5b48d2eb1544?source=collection_archive---------27-----------------------

根据文本信息将产品分类为禁止或批准。

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

Classifying products as Approved or Rejected based on its content.

让我从一些事实开始,这些事实是我在与基于机器学习的问题的有限接触中确立的——“你无法找到最合适的,因为没有最合适的,只是不断尝试——这是关键”和“数据是你最好的投资选择——花大量时间在它上面”。

回到手头的问题上来——识别 Indiamart 上的“被禁”内容,这是一个每天吸引数百万用户的在线平台。我所说的“禁止”指的是该国现行法律框架不允许的内容,更重要的是,它是动态的。牛皮制成的夹克是“禁售”产品,而皮革装饰的高级转椅则不是。

在继续之前,让我们先了解一下印度集市中的产品是什么

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

This is a product. We have over 60 million such products with us.

注意:我将在文章内容的上下文中使用该产品。这里的产品只不过是对特定项目可用内容的描述。一个产品有一个标题,一个描述,一个你卖的商品的图片,它的价格等等。

理解问题

我们必须根据现有的信息将我们的产品*(新的和现有的)*分为批准的禁止的

例如,任何提及麻醉盐的产品都需要标记为“禁用”,并从主流内容中删除。

基于“关键词”的挑战

在我们目前的方法中,我们根据关键字匹配将产品标记为禁用或批准,即我们有一个禁用关键字列表,如果该关键字存在于产品名称中,我们将其标记为禁用,否则标记为批准。

这导致某些相关产品被列为被禁产品,尽管它们应该被批准,例如,“猫”出现在我们的被禁关键词列表中,所以像“木制猫礼品”、“猫推土机”等产品被禁,这导致了好内容的损失。

解决“猫对猫”的难题

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

‘Cat’ -the animal and the machine

一个监督的基于文本的分类器为我们发挥了作用,该分类器是使用先前标记的例子训练的。该分类器的目标是将产品分为“禁止”或“批准”两种标签。如用于训练的标签

_ label _ 认可的戴尔无线鼠标黑色

_ label _ 禁用牛皮黑色夹克

我们向机器输入一组已有的产品,标签为“禁止”或“批准”,让它建立一种关系,这样它就可以预测某个产品应该被接受还是拒绝。然后,一组不同的产品再次被送入机器,系统会询问该产品是被接受还是被拒绝。

这一次,我们能够更好地捕捉产品的意图和背景- 卡特彼勒推土机或卡特彼勒挖掘机没有被“禁止”,而“猫皮衣”被禁止。

针对产品的可用描述和规范(在现有的关键字服务中未被考虑)也被用于训练和测试模型。

测试机器:引擎盖下是什么

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

Process Flow for the Problem

我们使用 fastText 来训练我们的模型。 fastText 是来自脸书的开源库,用于高效学习单词表示和句子分类。

如果您是 fastText 新手,在运行它时遇到问题,请参考本 视频教程

训练数据:具有带标签的数据行的文件。所有产品本质上都有“禁止”或“批准”两个标签中的一个,语料库是针对该产品的所有可用内容。

训练命令:

*~/fastText/fasttext.exe supervised -input ~/Training_Files/training_file.txt -output ~/Model_path/model.bin -lr 0.5 -epoch 75 -minn 5-thread 4 -wordNgram 2 -lrUpdateRate 100;*

注意:此处使用的超参数是在执行超参数调整后选择的,这使您可以获得有助于提高使用案例准确性的参数。这些可能会因所考虑的数据集而异

用 python 训练模型:

我们也可以使用下面提到的代码在 python 中执行同样的操作,它将创建模型文件(。bin)。

$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ pip install .

import fastText

train_file_name = "training_model.txt"
model_name = "Banned_Model"

classifier = fasttext.train_supervised(str(train_file_name),
                                            str(model_name), label_prefix='__label__',
                                            epoch=75,lr=0.5,word_ngrams=2,minn 5,bucket=200000,dim=100,loss='hs')# To Save the model for further use:
classifier.save_model("Banned_Model.bin")# To Predict the classes/Labels from the above modelmodel = fastText.load_model(model_name+".bin")
Test_String = ['xyz']
Model_Results = model.predict(Test_String,k=1)[0][0][0]

精度和召回率:

P@1    : 0.987
R@1    : 0.987

测试模型:

~/fastText/fasttext.exe predict-prob ~/Model_path/model.bin - 1;

您将在输出屏幕上看到类似这样的内容

imart@DESKTOP-CFGCP74 ~                                                                                                               
$ fastText/fasttext.exe predict-prob ~/Model_path/model4mo1.bin - 1                                         
deca durabolin nandrolene decatonate bottle                                                                                           
__label__Banned 0.995814

采用 k 倍交叉验证对模型进行验证。

**一个有趣的例子:**三星手机不禁售而山寨同行禁售。该模型能发现这种情况吗?让我们测试

imart@DESKTOP-CFGCP74 ~                                                                                                               
$ fastText/fasttext.exe predict-prob ~/Model_path/model4mo1.bin/model4mo1.bin - 1                                         
**samsung mobile phone **                                                                                                                 
__label__**Approved** 1.00001                                                                                                             
**samsung clone mobile phone**                                                                                                            
__label__**Banned** 1.00002

数据清理:主要手段

在机器学习中,垃圾输入就是垃圾输出,所以确保在使用数据训练模型之前执行所需的数据操作——这里我们将整个数据转换为小写,删除 XML、HTML 标签,如<李></李>、< ui > < /ui >等。、与用例相关的特殊符号和停用词。

Images❓产品怎么样

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

包含大量文本的产品图像。

使用 OCR 提取的文本👉复合维生素 b,含抗氧化剂胶囊,促进能量代谢,支持心脏健康

一些产品上有写有文字的图像。提取这些文本并输入到模型中也有助于我们更好地将产品分类为“禁止”或“批准”。这里使用 OCR( **光学字符识别)**从图像中提取相关数据。

什么是 OCR❓

OCR 代表光学字符识别。使用 OCR,我们可以扫描包含文本的图像和文档,并将它们转换成可以编辑的文档。

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

image scanning application using OCR

在我们的例子中,OCR 帮助我们从产品图像中提取文本,更重要的是在产品名称、产品描述和规格中没有文本信息的情况下。

Google Cloud Vision API 和 Tesseract 可以为此进行探索。

前方的路

到目前为止,当我们将结果与人类审计员进行匹配时,该模型对它测试的每 85/100 个产品都是准确的。我能够收集的另一个事实是,现实世界并不像我们倾向于相信的那样容易分类,使用人类总是有必要确定需要人类接触的“灰色区域”。我正在努力减少这些灰色区域,并将很快提出一篇后续文章。进一步阅读请参考本系列第二部分。

Vikram VarshneyAyush Gupta 感谢您的持续贡献。

使用文本挖掘将产品分类为禁止或批准-第二部分

原文:https://towardsdatascience.com/classifying-products-as-banned-or-approved-using-text-mining-part-ii-1cdd9b7ebc6e?source=collection_archive---------20-----------------------

在这一部分,我们将解释如何优化 Part I 中已有的机器学习模型,以及使用 Flask 部署这个 ML 模型。

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

Connecting the dots -moving from M to L in Machine Learning

在本系列的前一篇文章中,我们已经讨论了这个业务问题,展示了如何使用 fastText 训练模型,以及如何根据诸如(产品名称、产品描述和规格)等信息对禁止或批准的产品进行分类。要在Indiamart的背景下理解一个产品,请参考这篇 文章

从 85%提高到 98%,目标更高……

当我们将结果与人类审计员进行匹配时,上一篇文章中提到的模型的准确性是 85%。

为了提高该模型的准确性,我们在训练该模型时加入了一些附加数据,并进行超参数调整。在机器学习中,更精确的训练数据给出更好的结果*(我们可以说对于机器来说,垃圾进就是垃圾出,反之亦然)。*

超参数调谐:

在 fastText 中,有一些调优参数*(像学习率(LR)、wordN-grams、character _ n grams(Minn)、迭代次数(epoch)等。)*可以在训练模型的同时对其进行优化以提高分类器的性能。这些调整参数因情况而异。

在我们的案例中,我们在训练模型时对这些超参数进行了多种排列和组合,然后从中选择了最佳的。使用下面的命令获得具有多种调整参数组合的模型。

while read p; do while read q; do while read r; do while read s; do fasttext  supervised -input ~/Desktop/Banned_Model/train.txt -output ~/Desktop/Banned_Model/hypertuned/$p.$q.$r.$s -lr $p -minn $q -epoch $r -wordNgrams $s -thread 4 -loss hs -lrUpdateRate 100; done ; done

在这个阶段,我们已经创建了超过 2k 个独特的模型。下一步是从中选出最好的一个。根据精确度、召回率和准确度选择最佳模型的测试命令如下:

for b in ~/Desktop/Banned_Model/hypertuned/*.bin ;do ( echo Test results with $b && fasttext test $b /home/Desktop/test\val.txt ); done >> /home/Desktop/banned_hyper_parameters_test.txt

使用这种方法,我们能够根据最合适的超参数组合选择最佳模型。这些超参数可能因不同的用例而异。

模型精度:

在这个阶段,当我们将结果与人类审计员进行匹配时,该模型能够以 98%以上的准确率进行正确预测,并且我们已经完成了我们的机器学习模型,并将其保存为。“bin”文件。下一个目标是将这个机器学习模型投入生产。

模型部署:让事情活起来

这里的简单方法是调用 REST API 并从模型中获取预测。正如我们所知,有许多 web 开发框架是用 javascript、ASP.net、PHP 等编写的。但是在我们的例子中,我们已经使用 python 创建了我们的机器学习模型,并且我们正在 python 本身中寻找一个基于 web 的接口。在这里烧瓶进入画面。

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

ML Model deployment using Flask

什么是烧瓶?

Flask 是一个基于 python 的微框架,可以用来开发 web 应用、网站,部署 ML 模型相当容易。微框架烧瓶基于 Pocoo 项目 Werkzeug 和 Jinja2。Werkzeug 是一个用于 Web 服务器网关接口(WSGI)应用程序的工具包,并获得了 BSD 许可。在进行部署之前,我们需要下载 flask 和其他一些库。

**pip install flask**

让我们创建一个文件夹 Flask_Deploy 并将机器学习模型复制到其中。

**mkdir Flask_Deploy**

下一步是创建两个 python 脚本,一个用于处理数据预处理/清理,另一个用于获取基于文本输入预测结果的请求。

用 python 导入 flask。

app =烧瓶。Flask(name) : 创建 Flask 的实例

**@ app . route("/predict ")😗*用于指定 flask app 在 web 上的路由。例如:http://0.0.0.0:5000/predict?msg =输入字符串。 【预测与消息】这里的关键是

要访问 URL(?msg =输入字符串)我们使用以下属性:

**Input = flask.request.args.get("msg")**

**flask . jasonify(data)😗*用于返回 JSON 格式的 python 字典。

app . run(host = 0 . 0 . 0 . 0):用于在主机地址上运行 flask app。在本例中,我们在本地主机上运行它。

创建 web 应用程序后,我们将获得一个指向 flask 端点的 URL。感谢 Shantanu Aggarwal @阿洛克·库马尔在这么短的时间内帮助编写代码。为了处理数据预处理,我们创建了一个脚本 preprocess.py,并保存在保存 ML 模型文件的同一目录下(Flask_Deploy ),以便我们可以在需要时轻松调用它。

script to get requests and predict results.

在我们的例子中,我们得到了许多不必要的数据,如特殊字符、超链接、一些停用词、重复词等。为了处理这些问题,我们根据我们的用例创建了下面的脚本,并将其保存为 preprocess.py

处理数据清理和预处理的脚本:

preprocess.py script

最后一轮:

**cd Flask_Deploy
python3 flask_banned_model.py**

部署模型后,我们能够检查预测、模型准确性、延迟以及模型的负载处理时间。我们还可以记录结果、数据输入、延迟等。按照我们的要求做成表格。

结论:

任何机器学习模型的最终目标都是不需要太多麻烦就能投入使用。在投入了大量团队努力和辛勤工作后,最终部署了上述简单但有效的模型。此外,我们很高兴地提到,我们能够为上述模型实现大约 4 毫秒的显著延迟。我们正在对该模型进行全面测试,以发现任何问题,本系列的下一篇文章将分享该模型的性能,以及该模型在时间和金钱方面为我们带来的优化。

当团队工作创造奇迹的时候!!

这个模型是整个团队不断努力的成果。感谢@ 维克拉姆·瓦什尼苏尼尔·帕罗莉亚发起项目、普拉奇·贾因进行模型训练和超参数调优、帕拉德普·乔普拉、@里蒂卡·阿加瓦尔确保对模型进行全面测试、@梅达·塔亚吉@安基塔·萨拉斯瓦特提供所有产品方面的知识@阿洛克·库马尔、@普内特·阿加瓦尔、尚塔努·阿加瓦尔、@希普拉·古普塔、@阿布

使用 5 种机器学习算法对罕见事件进行分类

原文:https://towardsdatascience.com/classifying-rare-events-using-five-machine-learning-techniques-fab464573233?source=collection_archive---------5-----------------------

机器学习:监督学习

哪一种最适合不平衡数据?有什么权衡吗?

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

Photo by Franck V. on Unsplash

*** * * * * 最近更新于 2019 年 12 月 28 日******

机器学习是数据科学的皇冠;

监督学习是机器学习皇冠上的宝石。

背景

几年前,《哈佛商业评论》发表了一篇文章,标题是“数据科学家:21 世纪最性感的工作自从它发布以来,数据科学或统计部门受到大学生的广泛追捧,数据科学家(书呆子)第一次被称为性感。

对于一些行业,数据科学家已经重塑了公司结构,并将许多决策重新分配给“一线”员工。能够从数据中产生有用的商业见解从未如此容易。

据吴恩达(机器学习向往,第 9 页),

监督学习算法为行业贡献了大部分价值。

SL 为什么会产生这么大的商业价值,这一点毋庸置疑。银行用它来检测信用卡欺诈,交易员根据模型告诉他们的内容做出购买决定,工厂通过生产线过滤有缺陷的产品(根据吴恩达的说法,这是人工智能和人工智能可以帮助传统公司的一个领域)。

这些业务场景有两个共同的特征:

  1. 二元结果:欺诈 VS 不欺诈,买 VS 不买,有缺陷 VS 无缺陷。
  2. 不平衡的数据分布:一个多数群体对一个少数群体。

正如吴恩达最近指出的那样,小数据健壮性人为因素是人工智能项目成功的三大障碍。在一定程度上,我们的具有一个少数群体的罕见事件问题也是一个小数据问题:ML 算法从多数群体学习更多,可能容易对小数据群体进行错误分类。

以下是价值百万的问题:

对于这些罕见事件,哪种 ML 方法表现更好?

什么指标?

权衡?

在这篇文章中,我们试图通过将 5 ML 方法应用于一个真实的数据集来回答这些问题。

完整描述及原始数据集,请查看原始 数据集;完整的 R 代码请查看我的Github

商业问题

葡萄牙的一家银行实施了一项新银行服务(定期存款)的营销策略,并想知道哪些类型的客户订购了该服务。因此,银行可以调整其营销策略,并在未来瞄准特定人群。数据科学家已经与销售和营销团队合作,提出统计解决方案来识别未来的用户。

r 实现

下面是模型选择和 R 实现的管道。

1。导入、数据清理和探索性数据分析

让我们加载并清理原始数据集。

####load the dataset
banking=read.csv(“bank-additional-full.csv”,sep =”;”,header=T)##check for missing data and make sure no missing data
banking[!complete.cases(banking),]#re-code qualitative (factor) variables into numeric
banking$job= recode(banking$job, “‘admin.’=1;’blue-collar’=2;’entrepreneur’=3;’housemaid’=4;’management’=5;’retired’=6;’self-employed’=7;’services’=8;’student’=9;’technician’=10;’unemployed’=11;’unknown’=12”)#recode variable again
banking$marital = recode(banking$marital, “‘divorced’=1;’married’=2;’single’=3;’unknown’=4”)banking$education = recode(banking$education, “‘basic.4y’=1;’basic.6y’=2;’basic.9y’=3;’high.school’=4;’illiterate’=5;’professional.course’=6;’university.degree’=7;’unknown’=8”)banking$default = recode(banking$default, “‘no’=1;’yes’=2;’unknown’=3”)banking$housing = recode(banking$housing, “‘no’=1;’yes’=2;’unknown’=3”)banking$loan = recode(banking$loan, “‘no’=1;’yes’=2;’unknown’=3”)
banking$contact = recode(banking$loan, “‘cellular’=1;’telephone’=2;”)banking$month = recode(banking$month, “‘mar’=1;’apr’=2;’may’=3;’jun’=4;’jul’=5;’aug’=6;’sep’=7;’oct’=8;’nov’=9;’dec’=10”)banking$day_of_week = recode(banking$day_of_week, “‘mon’=1;’tue’=2;’wed’=3;’thu’=4;’fri’=5;”)banking$poutcome = recode(banking$poutcome, “‘failure’=1;’nonexistent’=2;’success’=3;”)#remove variable “pdays”, b/c it has no variation
banking$pdays=NULL #remove variable “pdays”, b/c itis collinear with the DV
banking$duration=NULL

清理原始数据似乎很繁琐,因为我们必须重新编码缺失的变量,并将定性变量转换为定量变量。在现实世界中,清理数据需要更多的时间。有句话说“数据科学家 80%的时间用来清理数据,20%的时间用来建立模型。”

接下来,让我们探索我们的结果变量的分布。

#EDA of the DV
plot(banking$y,main="Plot 1: Distribution of Dependent Variable")

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

可以看出,因变量(服务订购)的分布并不均匀,其中“否”多于“是”。这种不平衡的分布应该发出一些警告信号,因为数据分布会影响最终的统计模型。使用从多数案例发展而来的模型,很容易将少数案例错误分类。

2。数据分割

接下来,让我们将数据集分成两部分:训练集和测试集。根据经验,我们坚持 80-20 的划分:80%作为训练集,20%作为测试集。对于时间序列数据,我们基于 90%的数据训练模型,剩下的 10%作为测试数据集。

#split the dataset into training and test sets randomly 
set.seed(1)#set seed so as to generate the same value each time we run the code#create an index to split the data: 80% training and 20% test
index = round(nrow(banking)*0.2,digits=0)#sample randomly throughout the dataset and keep the total number equal to the value of index
test.indices = sample(1:nrow(banking), index)#80% training set
banking.train=banking[-test.indices,] #20% test set
banking.test=banking[test.indices,] #Select the training set except the DV
YTrain = banking.train$y
XTrain = banking.train %>% select(-y)# Select the test set except the DV
YTest = banking.test$y
XTest = banking.test %>% select(-y)

这里,让我们创建一个空的跟踪记录。

records = matrix(NA, nrow=5, ncol=2) 
colnames(records) <- c(“train.error”,”test.error”)
rownames(records) <- c(“Logistic”,”Tree”,”KNN”,”Random Forests”,”SVM”)

3。火车模型

在本节中,我们定义了一个新函数( calc_error_rate ),并将其应用于计算每个 ML 模型的训练和测试误差。

calc_error_rate <- function(predicted.value, true.value)
                    {return(mean(true.value!=predicted.value))}

该函数计算预测标签不等于真实值时的比率。

#1 逻辑回归模型

关于 logistic 模型的简介,请查看我的其他帖子: 机器学习 101机器学习 102

让我们拟合一个逻辑模型,其中包括除结果变量之外的所有其他变量。由于结果是二进制的,我们将模型设置为二项分布(“家庭=二项”)。

glm.fit = glm(y ~ age+factor(job)+factor(marital)+factor(education)+factor(default)+factor(housing)+factor(loan)+factor(contact)+factor(month)+factor(day_of_week)+campaign+previous+factor(poutcome)+emp.var.rate+cons.price.idx+cons.conf.idx+euribor3m+nr.employed, data=banking.train, **family=binomial**)

下一步是获得列车误差。我们将类型设置为 response,因为我们预测结果的类型并采用多数规则:如果先验概率超过或等于 0.5,我们预测结果为 yes 否则,答案是否定的

prob.training = predict(glm.fit,**type=”response”**)banking.train_glm = banking.train %>% #select all rows of the train
 mutate(predicted.value=as.factor(ifelse(prob.training<=0.5, “no”, “yes”))) **#create a new variable using mutate and set a majority rule using ifelse**# get the training error
logit_traing_error <-  calc_error_rate(predicted.value=banking.train_glm$predicted.value,  true.value=YTrain)# get the test error of the logistic model
prob.test = predict(glm.fit,banking.test,type=”response”)banking.test_glm = banking.test %>% # select rows
 mutate(predicted.value2=as.factor(ifelse(prob.test<=0.5, “no”, “yes”))) # set ruleslogit_test_error <- calc_error_rate(predicted.value=banking.test_glm$predicted.value2, true.value=YTest)# write down the training and test errors of the logistic model 
records[1,] <- c(logit_traing_error,logit_test_error)#write into the first row

#2 决策树

对于 DT,我们遵循交叉验证,并确定拆分的最佳节点。关于 DT 的快速介绍,请参考 Prashant Gupta 的帖子(链接)。

# finding the best nodes
# the total number of rows
nobs = nrow(banking.train)#build a DT model; 
#please refer to this document ([here](https://www.datacamp.com/community/tutorials/decision-trees-R)) for constructing a DT model
bank_tree = tree(y~., data= banking.train,na.action = na.pass,
 control = tree.control(nobs , mincut =2, minsize = 10, mindev = 1e-3))#cross validation to prune the tree
set.seed(3)
cv = cv.tree(bank_tree,FUN=prune.misclass, K=10)
cv#identify the best cv
best.size.cv = cv$size[which.min(cv$dev)]
best.size.cv#best = 3bank_tree.pruned<-prune.misclass(bank_tree, best=3)
summary(bank_tree.pruned)

交叉验证的最佳规模是 3。

# Training and test errors of bank_tree.pruned
pred_train = predict(bank_tree.pruned, banking.train, type=”class”)
pred_test = predict(bank_tree.pruned, banking.test, type=”class”)# training error
DT_training_error <- calc_error_rate(predicted.value=pred_train, true.value=YTrain)# test error
DT_test_error <- calc_error_rate(predicted.value=pred_test, true.value=YTest)# write down the errors
records[2,] <- c(DT_training_error,DT_test_error)

# 3k-最近邻居

作为一种非参数方法,KNN 不需要任何分布的先验知识。简而言之,KNN 为感兴趣的单元分配 k 个最近邻。

要快速开始,请查看我在 KNN 的帖子:R 中 K 近邻初学者指南:从零到英雄。 关于交叉验证和 do.chunk 函数的详细解释,请重定向到我的帖子

使用交叉验证,我们发现当 k=20 时交叉验证误差最小。

nfold = 10
set.seed(1)# cut() divides the range into several intervals
folds = seq.int(nrow(banking.train)) %>%
     cut(breaks = nfold, labels=FALSE) %>%  
     sampledo.chunk <- function(chunkid, folddef, Xdat, Ydat, k){ 
     train = (folddef!=chunkid)# training indexXtr = Xdat[train,] # training set by the indexYtr = Ydat[train] # true label in training setXvl = Xdat[!train,] # test setYvl = Ydat[!train] # true label in test setpredYtr = knn(train = Xtr, test = Xtr, cl = Ytr, k = k) # predict training labelspredYvl = knn(train = Xtr, test = Xvl, cl = Ytr, k = k) # predict test labelsdata.frame(fold =chunkid, # k folds 
train.error = calc_error_rate(predYtr, Ytr),#training error per fold 
 val.error = calc_error_rate(predYvl, Yvl)) # test error per fold
 }# set error.folds to save validation errors
error.folds=NULL# create a sequence of data with an interval of 10
kvec = c(1, seq(10, 50, length.out=5))set.seed(1)for (j in kvec){
 tmp = ldply(1:nfold, do.chunk, # apply do.function to each fold
 folddef=folds, Xdat=XTrain, Ydat=YTrain, k=j) # required arguments
 tmp$neighbors = j # track each value of neighbors
 error.folds = rbind(error.folds, tmp) # combine the results 
 }**#melt() in the package reshape2 melts wide-format data into long-format data** errors = melt(error.folds, id.vars=c(“fold”,”neighbors”), value.name= “error”)

然后,让我们找到使验证误差最小化的最佳 k 数。

val.error.means = errors %>%
 filter(variable== “val.error” ) %>%
 group_by(neighbors, variable) %>%
 summarise_each(funs(mean), error) %>%
 ungroup() %>%
 filter(error==min(error))#the best number of neighbors =20
numneighbor = max(val.error.means$neighbors)
numneighbor## [20]

按照同样的步骤,我们会发现训练和测试错误。

#training error
set.seed(20)
pred.YTtrain = knn(train=XTrain, test=XTrain, cl=YTrain, k=20)
knn_traing_error <- calc_error_rate(predicted.value=pred.YTtrain, true.value=YTrain)#test error =0.095set.seed(20)
pred.YTest = knn(train=XTrain, test=XTest, cl=YTrain, k=20)
knn_test_error <- calc_error_rate(predicted.value=pred.YTest, true.value=YTest)records[3,] <- c(knn_traing_error,knn_test_error)

#4 随机森林

我们遵循构建随机森林模型的标准步骤。由饶彤彤撰写的 RF ( 链接)快速介绍。

# build a RF model with default settings 
set.seed(1)
RF_banking_train = randomForest(y ~ ., data=banking.train, importance=TRUE)# predicting outcome classes using training and test sets

pred_train_RF = predict(RF_banking_train, banking.train, type=”class”)pred_test_RF = predict(RF_banking_train, banking.test, type=”class”)# training error
RF_training_error <- calc_error_rate(predicted.value=pred_train_RF, true.value=YTrain)# test error
RF_test_error <- calc_error_rate(predicted.value=pred_test_RF, true.value=YTest)records[4,] <- c(RF_training_error,RF_test_error)

#5 支持向量机

同样,我们遵循构建 SVM 的标准步骤。一个好的方法介绍,请参考罗希斯甘地的帖子(链接)。

set.seed(1)
tune.out=tune(svm, y ~., data=banking.train,
kernel=”radial”,ranges=list(cost=c(0.1,1,10)))# find the best parameters
summary(tune.out)$best.parameters# the best model
best_model = tune.out$best.modelsvm_fit=svm(y~., data=banking.train,kernel=”radial”,gamma=0.05555556,cost=1,probability=TRUE)# using training/test sets to predict outcome classes
svm_best_train = predict(svm_fit,banking.train,type=”class”)
svm_best_test = predict(svm_fit,banking.test,type=”class”)# training error
svm_training_error <- calc_error_rate(predicted.value=svm_best_train, true.value=YTrain)# test error
svm_test_error <- calc_error_rate(predicted.value=svm_best_test, true.value=YTest)records[5,] <- c(svm_training_error,svm_test_error)

4.模型度量

我们按照模型选择程序构建了所有的 ML 模型,并获得了它们的训练和测试误差。在本节中,我们将使用一些模型指标来选择最佳模型。

4.1 训练/测试错误

有可能利用训练/测试误差找到最佳模型吗?

现在,让我们检查结果。

records

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

这里,随机森林具有最小的训练误差,尽管与其他方法具有相似的测试误差。您可能已经注意到,训练和测试误差非常接近,很难判断哪一个明显胜出。

此外,分类精度,无论是训练误差还是测试误差,都不应该成为高度不平衡数据集的衡量标准。这是因为数据集是由大多数案例支配的,即使是随机的猜测也有 50%的机会猜对(50%的准确率)。更糟糕的是,一个高度精确的模型可能会严重地惩罚少数情况。出于这个原因,让我们检查另一个指标 ROC 曲线。

4.2 接收机工作特性(ROC)曲线

ROC 是一种图形表示,显示分类模型在所有分类阈值下的表现。我们更喜欢比其他分类器更快接近 1 的分类器。

ROC 曲线在同一图表中不同阈值处绘制了两个参数—真阳性率和假阳性率:

TPR(召回)= TP/(TP+FN)

FPR = FP/(TN+FP)

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

Indon

在很大程度上,ROC 曲线不仅衡量分类精度的水平,而且在 TPR 和 FPR 之间达到了良好的平衡。这对于罕见事件来说是非常可取的,因为我们也希望在多数和少数情况之间达到平衡。

# load the library
library(ROCR)#creating a tracking record
Area_Under_the_Curve = matrix(NA, nrow=5, ncol=1)
colnames(Area_Under_the_Curve) <- c(“AUC”) 
rownames(Area_Under_the_Curve) <- c(“Logistic”,”Tree”,”KNN”,”Random Forests”,”SVM”)########### logistic regression ###########
# ROC
prob_test <- predict(glm.fit,banking.test,type=”response”)
pred_logit<- prediction(prob_test,banking.test$y)
performance_logit <- performance(pred_logit,measure = “tpr”, x.measure=”fpr”)########### Decision Tree ###########
# ROC
pred_DT<-predict(bank_tree.pruned, banking.test,type=”vector”)
pred_DT <- prediction(pred_DT[,2],banking.test$y)
performance_DT <- performance(pred_DT,measure = “tpr”,x.measure= “fpr”)########### KNN ########### 
# ROC
knn_model = knn(train=XTrain, test=XTrain, cl=YTrain, k=20,prob=TRUE)prob <- attr(knn_model, “prob”)
prob <- 2*ifelse(knn_model == “-1”, prob,1-prob) — 1
pred_knn <- prediction(prob, YTrain)
performance_knn <- performance(pred_knn, “tpr”, “fpr”)########### Random Forests ###########
# ROC
pred_RF<-predict(RF_banking_train, banking.test,type=”prob”)
pred_class_RF <- prediction(pred_RF[,2],banking.test$y)
performance_RF <- performance(pred_class_RF,measure = “tpr”,x.measure= “fpr”)########### SVM ########### 
# ROC
svm_fit_prob = predict(svm_fit,type=”prob”,newdata=banking.test,probability=TRUE)
svm_fit_prob_ROCR = prediction(attr(svm_fit_prob,”probabilities”)[,2],banking.test$y==”yes”)
performance_svm <- performance(svm_fit_prob_ROCR, “tpr”,”fpr”)

让我们画出 ROC 曲线。

我们画一条线来表示随机分配的机会。我们的分类器应该比随机猜测表现得更好,对吗?

#logit
plot(performance_logit,col=2,lwd=2,main=”ROC Curves for These Five Classification Methods”)legend(0.6, 0.6, c(‘logistic’, ‘Decision Tree’, ‘KNN’,’Random Forests’,’SVM’), 2:6)#decision tree
plot(performance_DT,col=3,lwd=2,add=TRUE)#knn
plot(performance_knn,col=4,lwd=2,add=TRUE)#RF
plot(performance_RF,col=5,lwd=2,add=TRUE)# SVM
plot(performance_svm,col=6,lwd=2,add=TRUE)abline(0,1)

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

ROC

我们这里有一个赢家。

根据 ROC 曲线,KNN(蓝色的)高于所有其他方法。

4.3 曲线下面积(AUC)

顾名思义,AUC 就是 ROC 曲线下的面积。它是直观 AUC 曲线的算术表示。AUC 提供分类器如何跨越可能的分类阈值的综合结果。

########### Logit ########### 
auc_logit = performance(pred_logit, “auc”)[@y](http://twitter.com/y).values
Area_Under_the_Curve[1,] <-c(as.numeric(auc_logit))########### Decision Tree ###########
auc_dt = performance(pred_DT,”auc”)[@y](http://twitter.com/y).values
Area_Under_the_Curve[2,] <- c(as.numeric(auc_dt))########### KNN ###########
auc_knn <- performance(pred_knn,”auc”)[@y](http://twitter.com/y).values
Area_Under_the_Curve[3,] <- c(as.numeric(auc_knn))########### Random Forests ###########
auc_RF = performance(pred_class_RF,”auc”)[@y](http://twitter.com/y).values
Area_Under_the_Curve[4,] <- c(as.numeric(auc_RF))########### SVM ########### 
auc_svm<-performance(svm_fit_prob_ROCR,”auc”)[@y](http://twitter.com/y).values[[1]]
Area_Under_the_Curve[5,] <- c(as.numeric(auc_svm))

让我们检查一下 AUC 值。

Area_Under_the_Curve

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

此外,KNN 的 AUC 值最大(0.847)。

结论

在这篇文章中,我们发现 KNN,一个非参数分类器,比它的参数分类器表现更好。就度量标准而言,对于罕见事件,选择 ROC 曲线比选择分类准确度更合理。

Medium 最近进化出了自己的 作家伙伴计划 ,支持像我这样的普通作家。如果你还不是订户,通过下面的链接注册,我会收到一部分会员费。

[## 阅读叶雷华博士研究员(以及其他成千上万的媒体作家)的每一个故事

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

leihua-ye.medium.com](https://leihua-ye.medium.com/membership)

喜欢读这本书吗?

请在 LinkedInYoutube 上找到我。

还有,看看我其他关于人工智能和机器学习的帖子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值