TowardsDataScience 博客中文翻译 2019(七十七)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

R 中 K-最近邻初学者指南:从零到英雄

原文:https://towardsdatascience.com/beginners-guide-to-k-nearest-neighbors-in-r-from-zero-to-hero-d92cd4074bdb?source=collection_archive---------2-----------------------

机器学习:监督学习

在 R 中建立具有各种性能指标的 KNN 模型的管道

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

Photo by Mathyas Kurmann on Unsplash

2021 年 1 月 10 日更新

KNN in audio

“如果你住的地方离比尔·盖茨只有 5 分钟的路程,我敢打赌你一定很有钱.”

介绍

在机器学习领域,K 近邻 KNN 最直观,因此很容易被希望进入该领域的数据科学爱好者所接受。为了决定观察的分类标签,KNN 会查看其邻居并将邻居的标签分配给感兴趣的观察。这是 KNN 方法的基本思想,就像一开始用的比尔游戏的比喻一样。不需要更高维度的计算来理解算法是如何工作的。

但是有一个问题。查看一个邻居可能会给模型带来偏差和不准确性,我们必须为该方法设置几个“参与规则”。例如,顾名思义,KNN 可以采用其“k”个邻居的多数情况。

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

A quick look at how KNN works, by Agor153

为了决定新观察的标签,我们查看最近的邻居。

测量距离

为了选择邻居的数量,我们需要采用一个数字来量化邻居之间的相似性或不相似性(数据科学家实用统计)。为此,KNN 根据数据类型有两套距离度量标准。

对于离散变量,KNN 采用海明距离。它测量使两个字符串相似所需的最少替换数( Wikipedia )。

对于连续变量,我们使用欧几里德距离。为了计算两个向量 (x1,x2,…,xp)(μ1,μ2,…,μp) 之间的距离,我们取它们的个体差,平方,求和,然后平方根,如下所示:

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

screenshot of Practical Statistics for Data Scientists

顺便提一下,在数据科学访谈中,为 KNN 选择距离指标是一个备受考验的话题。他们通常会询问选择一个指标的理由,以及他们的权衡。我在一篇相关的文章中阐述了如何处理这类问题:

[## 破解数据科学访谈:基本的机器学习概念

赢在 2021 年:数据科学家/工程师的必读之作,第 1 部分

towardsdatascience.com](/crack-data-science-interviews-essential-machine-learning-concepts-afd6a0a6d1aa)

什么是 K 倍交叉验证?

如上所述,KNN 的关键是设置邻居的数量,我们求助于交叉验证(CV)来决定额外的 K 个邻居。

交叉验证可以简要描述为以下步骤:

  1. 将数据分成 K 个均匀分布的块/折叠
  2. 选择 1 个组块/折叠作为测试集,其余 K-1 个作为训练集
  3. 基于训练集开发 KNN 模型
  4. 仅比较测试集上的预测值和实际值
  5. 将 ML 模型应用于测试集,并使用每个组块重复 K 次
  6. 将模型的指标分数相加,并在 K 倍上求平均值

怎么选 K?

从技术上讲,我们可以将 K 设置为 1 和样本大小 n 之间的任何值。设置 K = n,CV 将 1 个观察值作为训练集,其余 n-1 个案例作为测试集,并对整个数据集重复该过程。这种简历被称为**“留一法交叉验证”(LOOCV)** 。

然而,LOOCV 有直观的意义,但需要大量的计算能力。对于非常大的数据集,它会永远运行。

为了选择最佳的 K 倍,我们必须在偏差和方差之间进行权衡。对于一个小的 K,该模型有一个高偏差,但估计测试误差的方差低。对于一个大 K,我们有一个低偏差但高方差(破解数据科学访谈)。

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

Photo by Jon Tyson on Unsplash

R 中的代码实现

1.软件准备

*# install.packages(“ISLR”)
# install.packages(“ggplot2”) # install.packages(“plyr”)
# install.packages(“dplyr”) # install.packages(“class”)**# Load libraries* **library**(ISLR) 
**library**(ggplot2) 
**library**(reshape2) 
**library**(plyr) 
**library**(dplyr) 
**library**(class)# load data and clean 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 “duration”, b/c itis collinear with the DV
banking$duration=NULL

加载和清理原始数据集后,通常的做法是直观地检查变量的分布,检查季节性、模式、异常值等。

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

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

可以看出,结果变量(银行服务订阅)并不是均衡分布的,“否”比“是”多得多,这给机器学习分类问题带来不便。假阳性率很高,因为许多少数病例会被归类为多数病例。对于这种分布不均匀的罕见事件,非参数分类方法是首选方法。

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

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

towardsdatascience.com](/classifying-rare-events-using-five-machine-learning-techniques-fab464573233)

2。数据分割

我们将数据集分为训练集和测试集。根据经验,我们坚持“80–20”划分,即 80%的数据作为训练集,20%作为测试集。

#split the dataset into training and test sets randomly, but we need to set seed so as to generate the same value each time we run the codeset.seed(1)**#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)

3.火车模型

让我们创建一个新函数(" calc_error_rate ")来记录错误分类率。当使用训练模型预测的标签与实际结果标签不匹配时,该函数计算比率。它衡量分类的准确性。

#define an error rate function and apply it to obtain test/training errorscalc_error_rate <- function(predicted.value, true.value){
 return(mean(true.value!=predicted.value)) 
}

然后,我们需要另一个函数“ do.chunk() ”,来做 k 重交叉验证。该函数返回可能折叠值的数据框。

该步骤的主要目的是为 KNN 选择最佳 K 值。

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 %>%
    #select all rows of validation errors
    filter(variable== “val.error” ) %>% 
    #group the selected data by neighbors
    group_by(neighbors, variable) %>%
    #cacluate CV error for each k
    summarise_each(funs(mean), error) %>%
    #remove existing grouping
    ungroup() %>% 
    filter(error==min(error))*# Best number of neighbors*
*# if there is a tie, pick larger number of neighbors for simpler model*
numneighbor = max(val.error.means$neighbors)
numneighbor## [20]

因此,在使用 10 重交叉验证后,最佳邻居数为 20。

4.一些模型指标

#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)
knn_traing_error[1] 0.101214

训练误差为 0.10。

#test error
set.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)
knn_test_error[1] 0.1100995

测试误差为 0.11。

#confusion matrixconf.matrix = **table**(predicted=pred.YTest, true=YTest)

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

根据上面的混淆矩阵,我们可以计算出下面的数值,为绘制 ROC 曲线做准备。

准确度= (TP +TN)/(TP+FP+FN+TN)

TPR/召回/灵敏度 = TP/(TP+FN)

精度 = TP/(TP+FP)

特异性 = TN/(TN+FP)

FPR = 1 —特异性= FP/(TN+FP)

F1 得分 = 2TP/(2TP+FP+FN) =精度*召回/(精度+召回)

# Test accuracy ratesum(diag(conf.matrix)/sum(conf.matrix))[1] 0.8899005*# Test error rate*1 - sum(drag(conf.matrix)/sum(conf.matrix))[1] 0.1100995

正如您可能注意到的,测试准确率+测试错误率= 1,我提供了计算每个值的多种方法。

# ROC and AUC
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) — 1pred_knn <- prediction(prob, YTrain)performance_knn <- performance(pred_knn, “tpr”, “fpr”)# AUCauc_knn <- performance(pred_knn,”auc”)[@y](http://twitter.com/y).valuesauc_knn[1] 0.8470583plot(performance_knn,col=2,lwd=2,main=”ROC Curves for KNN”)

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

总之,我们已经了解了什么是 KNN,以及在 r 中构建 KNN 模型的流程。此外,我们还掌握了进行 K-Fold 交叉验证的技巧,以及如何在 r 中实现代码

我的Github上有完整的 Python 代码。

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

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

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

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

我的数据科学面试序列

[## 2021 年数据科学家必备的 SQL 技能

数据科学家/工程师的四项 SQL 技能

towardsdatascience.com](/essential-sql-skills-for-data-scientists-in-2021-8eb14a38b97f) [## FAANG 在 2021 年提出这 5 个 Python 问题

数据科学家和数据工程师的必读!

towardsdatascience.com](/5-python-coding-questions-asked-at-faang-59e6cf5ba2a0) [## FAANG 在 2021 年询问这些 Python 模拟

数据科学和数据工程面试的必读材料,第 2 部分

towardsdatascience.com](/statistical-simulation-in-python-part-2-91f71f474f77)

喜欢读这本书吗?

请在 LinkedInYoutube 上找到我。

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

用 R 进行 LDA 主题建模的初学者指南

原文:https://towardsdatascience.com/beginners-guide-to-lda-topic-modelling-with-r-e57a5a8e7a25?source=collection_archive---------0-----------------------

识别非结构化文本中的主题

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

Picture credits

现在许多人想从自然语言处理(NLP)开始。然而,他们不知道从哪里以及如何开始。这可能是因为有太多的“指南”或“读物”可用,但它们并没有确切地告诉你从哪里以及如何开始。这篇文章旨在给读者一步一步的指导,告诉他们如何使用 r 的潜在狄利克雷分配(LDA) 分析进行主题建模。

这种技术很简单,在小数据集上很有效。因此,我建议第一次尝试 NLP 和使用主题建模的人使用这种技术。

什么是主题建模?通俗地说,主题建模是试图在不同的文档中找到相似的主题,并试图将不同的单词组合在一起,这样每个主题将由具有相似含义的单词组成。我经常喜欢打一个比方——当你有一本故事书被撕成不同的书页时。在你尝试运行一个主题建模算法之后,你应该能够提出各种各样的主题,这样每个主题将由来自每个章节的单词组成。否则,你可以简单地使用情绪分析——正面或负面评论。

机器学习自然语言处理中,主题模型是一种统计模型,用于发现文档集合中出现的抽象“主题”。——维基百科

在正式介绍了主题建模之后,文章的剩余部分将描述如何进行主题建模的逐步过程。它由 4 个部分组成:数据加载、数据预处理、建立模型和主题中单词的可视化。

如上所述,我将使用 LDA 模型,这是一个概率模型,它为 word 分配一个最有可能属于它的主题的概率分数。我将跳过 LDA 的技术解释,因为有许多可用的文章。(例:这里这里)不用担心,我会解释所有的术语,如果我使用它的话。

  1. 数据加载

为了简单起见,我们将使用的数据集将是来自 kaggle 的前 5000 行 twitter 情绪数据。对于我们的模型,我们不需要标记数据。我们所需要的只是一个我们想要从中创建主题的文本列和一组唯一的 id。最初有 18 列和 13000 行数据,但是我们将只使用 text 和 id 列。

data <- fread(“~/Sentiment.csv”)
#looking at top 5000 rows
data <- data %>% select(text,id) %>% head(5000)

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

Dataframe after selecting the relevant columns for analysis

2。预处理

正如我们从文本中观察到的,有许多 tweets 由不相关的信息组成:如 RT、twitter 句柄、标点符号、停用词(and、or the 等)和数字。这些会给我们的数据集增加不必要的噪声,我们需要在预处理阶段去除这些噪声。

data$text <- sub("RT.*:", "", data$text)
data$text <- sub("@.* ", "", data$text)text_cleaning_tokens <- data %>% 
  tidytext::unnest_tokens(word, text)
text_cleaning_tokens$word <- gsub('[[:digit:]]+', '', text_cleaning_tokens$word)
text_cleaning_tokens$word <- gsub('[[:punct:]]+', '', text_cleaning_tokens$word)
text_cleaning_tokens <- text_cleaning_tokens %>% filter(!(nchar(word) == 1))%>% 
  anti_join(stop_words)
tokens <- text_cleaning_tokens %>% filter(!(word==""))
tokens <- tokens %>% mutate(ind = row_number())
tokens <- tokens %>% group_by(id) %>% mutate(ind = row_number()) %>%
  tidyr::spread(key = ind, value = word)
tokens [is.na(tokens)] <- ""
tokens <- tidyr::unite(tokens, text,-id,sep =" " )
tokens$text <- trimws(tokens$text)

3。模型构建

有趣的部分终于来了!创建模型。

首先,您必须创建一个 DTM(文档术语矩阵),这是一个稀疏矩阵,包含您的术语和文档作为维度。构建 DTM 时,您可以选择如何对文本进行分词(将一个句子拆分成一个或两个单词)。这将取决于你希望 LDA 如何解读你的话。你需要问问自己,在你的上下文中,单数词或双数词(短语)是否有意义。例如,如果你的文本包含许多单词,如“执行失败”或“不赞赏”,那么你将不得不让算法选择一个最多 2 个单词的窗口。否则,使用单字也可以。在我们的例子中,因为它是 Twitter 情感,我们将使用 1-2 个单词的窗口大小,并让算法为我们决定哪些是更重要的短语连接在一起。我们还将探索术语频率矩阵,它显示了单词/短语在整个文本语料库中出现的次数。如果该项小于 2 次,我们丢弃它们,因为它不会给算法增加任何值,并且它也将有助于减少计算时间。

#create DTM
dtm <- CreateDtm(tokens$text, 
                 doc_names = tokens$ID, 
                 ngram_window = c(1, 2))#explore the basic frequency
tf <- TermDocFreq(dtm = dtm)
original_tf <- tf %>% select(term, term_freq,doc_freq)
rownames(original_tf) <- 1:nrow(original_tf)# Eliminate words appearing less than 2 times or in more than half of the
# documents
vocabulary <- tf$term[ tf$term_freq > 1 & tf$doc_freq < nrow(dtm) / 2 ]dtm = dtm

使用 DTM,您可以运行 LDA 算法进行主题建模。你将不得不手动分配多个主题 k。接下来,算法将计算一个连贯性分数,以允许我们从 1 到 k 中选择最佳主题。什么是连贯性和连贯性分数?连贯性给出了每个主题的概率连贯性。连贯得分是计算同一主题中的单词放在一起时是否有意义的得分。这给了我们正在制作的主题的质量。特定数字 k 的分数越高,就意味着每个主题的相关词越多,主题就越有意义。例如:{狗,说话,电视,书}对{狗,球,吠,骨头}。后者将产生比前者更高的一致性分数,因为单词更紧密相关。

在我们的例子中,我们设置 k = 20 并对其运行 LDA,并绘制一致性分数。由分析师决定他们想要多少主题。

k_list <- seq(1, 20, by = 1)
model_dir <- paste0("models_", digest::digest(vocabulary, algo = "sha1"))
if (!dir.exists(model_dir)) dir.create(model_dir)model_list <- TmParallelApply(X = k_list, FUN = function(k){
  filename = file.path(model_dir, paste0(k, "_topics.rda"))

  if (!file.exists(filename)) {
    m <- FitLdaModel(dtm = dtm, k = k, iterations = 500)
    m$k <- k
    m$coherence <- CalcProbCoherence(phi = m$phi, dtm = dtm, M = 5)
    save(m, file = filename)
  } else {
    load(filename)
  }

  m
}, export=c("dtm", "model_dir")) # export only needed for Windows machines#model tuning
#choosing the best model
coherence_mat <- data.frame(k = sapply(model_list, function(x) nrow(x$phi)), 
                            coherence = sapply(model_list, function(x) mean(x$coherence)), 
                            stringsAsFactors = FALSE)
ggplot(coherence_mat, aes(x = k, y = coherence)) +
  geom_point() +
  geom_line(group = 1)+
  ggtitle("Best Topic by Coherence Score") + theme_minimal() +
  scale_x_continuous(breaks = seq(1,20,1)) + ylab("Coherence")

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

在绘制 k 时,我们意识到 k = 12 给出了最高的一致性分数。在这种情况下,即使一致性分数相当低,也肯定需要调整模型,例如增加 k 以实现更好的结果或具有更多文本。但是出于解释的目的,我们将忽略该值,只使用最高的一致性分数。在了解了主题的最佳数量后,我们想看一下主题中的不同单词。每个主题将为每个单词/短语分配一个 phi 值(pr(word|topic)) —给定主题的单词的概率。所以我们只考虑每个主题中每个单词的前 20 个值。前 20 个术语将描述主题的内容。

model <- model_list[which.max(coherence_mat$coherence)][[ 1 ]]
model$top_terms <- GetTopTerms(phi = model$phi, M = 20)
top20_wide <- as.data.frame(model$top_terms)

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

Preview of top 10 words for the first 5 topic. The first word implies a higher phi value

上图是 12 个题目中的前 5 个题目。单词按 phi 值的升序排列。排名越高,这个词就越有可能属于这个主题。似乎有一些重叠的话题。这取决于分析师来思考我们是否应该通过目测将不同的主题组合在一起,或者我们可以运行一个树形图来查看哪些主题应该被分组在一起。树形图使用 Hellinger 距离(两个概率向量之间的距离)来决定主题是否密切相关。例如,下面的树形图表明主题 10 和 11 之间有更大的相似性。

model$topic_linguistic_dist <- CalcHellingerDist(model$phi)
model$hclust <- hclust(as.dist(model$topic_linguistic_dist), "ward.D")
model$hclust$labels <- paste(model$hclust$labels, model$labels[ , 1])
plot(model$hclust)

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

4。可视化

我们可以创建单词云,根据概率来查看属于某个主题的单词。下面代表主题 2。由于“gopdebate”是 topic2 中最有可能出现的单词,因此其大小将是单词云中最大的。

#visualising topics of words based on the max value of phi
set.seed(1234)final_summary_words <- data.frame(top_terms = t(model$top_terms))
final_summary_words$topic <- rownames(final_summary_words)
rownames(final_summary_words) <- 1:nrow(final_summary_words)
final_summary_words <- final_summary_words %>% melt(id.vars = c("topic"))
final_summary_words <- final_summary_words %>% rename(word = value) %>% select(-variable)
final_summary_words <- left_join(final_summary_words,allterms)
final_summary_words <- final_summary_words %>% group_by(topic,word) %>%
  arrange(desc(value))
final_summary_words <- final_summary_words %>% group_by(topic, word) %>% filter(row_number() == 1) %>% 
  ungroup() %>% tidyr::separate(topic, into =c("t","topic")) %>% select(-t)
word_topic_freq <- left_join(final_summary_words, original_tf, by = c("word" = "term"))pdf("cluster.pdf")
for(i in 1:length(unique(final_summary_words$topic)))
{  wordcloud(words = subset(final_summary_words ,topic == i)$word, freq = subset(final_summary_words ,topic == i)$value, min.freq = 1,
             max.words=200, random.order=FALSE, rot.per=0.35, 
             colors=brewer.pal(8, "Dark2"))}dev.off()

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

Word cloud for topic 2

5。结论

我们用 LDA 完成了这个简单的主题建模,并用 word cloud 实现了可视化。你可以参考我的 github 了解整个脚本和更多细节。这不是一个完整的 LDA 教程,因为还有其他很酷的度量标准,但是我希望这篇文章能为你提供一个很好的指导,告诉你如何使用 LDA 开始 R 中的主题建模。我也强烈建议每个人也阅读其他种类的算法。我相信你不会觉得无聊的!

如果你认为我错过了什么,请随时给我留言。

快乐话题造型!

参考文献:

  1. 维基百科
  2. 泰勒娃娃, LDA 主题造型 (2018)
  3. 托马斯·琼斯,主题建模 (2019)

Python 及其怪癖初学者指南

原文:https://towardsdatascience.com/beginners-guide-to-python-quirks-and-jargon-8dfcf8ebd590?source=collection_archive---------19-----------------------

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

数据科学的繁荣欢迎了来自各行各业的大量新 Python 开发人员:从经验丰富的黑客、统计学家和数学家,到企业高管、记者,以及基本上任何想成为不可避免的数据革命一部分的人。各位,我们正处于激动人心的时代。我们正处于第四次工业革命的风口浪尖,每个人都想加入。

对于初学编程的人来说,Python 是数据科学的两种著名编程语言之一,这非常方便。凭借其简洁的语法、易读性以及对自然语言的接近,难怪美国大学中 70%的编程入门课程都在讲授 i t。我想不出比这更温和的编程入门了。

你可以选择所有的在线课程,所有的博客文章和教程遍布网络,学习语言的资源是不短缺的。此外,感谢像 stackoverflow 这样的网站,如果你有任何问题,总会有一个其他程序员的社区来帮助你(大多数时候,我们大多数人都很好)。

获取知识从未如此简单,我想邀请你们所有人和我一起欣赏这一刻。

但是,虽然这些课程和教程可以让您快速掌握该语言和相关数据科学库的基础知识——仅举几个例子,pandas、numpy、matplotlib 和 sk learn——但大多数课程和教程几乎没有触及 Python 的复杂性。尽管 Python 很简单,但它是一门庞大而丰富的语言,了解它的内部和外部是值得的。

为什么它很重要

你可能只需要了解基础知识和足够的语言知识,就能在你的领域中发挥作用,但是了解你正在使用的语言的特点也有好处:

  • 你可以写出更好、更有创意的代码。编程的核心是解决问题。掌握更多的语言知识可以让你考虑一个问题的多种解决方案。
  • 你有可能加快工作速度。对于小型数据集,您可能不会遇到性能问题。当您开始处理至少几千行时,事情会变得更加冒险和不可原谅。知道哪种语言结构比其他语言结构工作得更快,可以将一个必须运行 34 小时的脚本转换成一个只需要运行 1 分钟的脚本(我很快会写这方面的内容!).
  • 你未来的自己会感谢你。有没有做过六个月都没碰过的代码?没有吗?让我现在就告诉你:这不是一次愉快的经历。您不再是六个月前的问题领域专家。编写干净和一致的代码,即python 化的代码,将引导你养成按照某种风格模式编写的习惯,从而产生可读和可预测的代码。这肯定会节省你拉头发的时间。
  • 最后为自己的工作感到骄傲。好吧,这是我个人的想法,但我还是想分享一下。时间是非常宝贵的资源。如果你打算用它来创造一些东西,不妨创造一些让你自豪的东西。对我来说,在这种情况下,就是将我编写的代码与语言的设计方式结合起来。虽然编程通常被包装为逻辑问题解决,但在设计层面,它更像是艺术而非工程。这是你的创造力可以大放异彩的地方。

你应该知道的事情

学习这些简单的概念,你将很容易成为一名更好的 Python 开发人员:

空序列为假,有元素的序列为真。在条件句中使用时,不必知道列表、字典或集合的长度:

Sequence Truthiness

使用 enumerate()遍历序列。冒着听起来像个老人的风险,过去遍历一个列表和它的索引需要一组len()range()enumerate()让事情变得更简单:

len() and range() vs. enumerate()

你可以从字符串中创建列表。假设您想要创建一个由字母表示的类别列表,将它们制作成一个string并将其传递给list构造函数比手工制作更容易:

Strings as Lists

元组打包,序列解包。当你发现自己需要将多个项目组合在一起或从序列中提取单个项目时,可以使用这些工具。这些分别被称为元组打包和序列解包。

Tuple Packing and Sequence Unpacking

通过利用打包和解包,可以在两个变量之间交换值:

Swapping Values

小心使用这个。虽然它增加了xy之间的语义关系,但它也可能在两个非常不相关的变量之间提供错误的语义关系。

F 弦。从 Python 3.6 开始,您可以使用 f 字符串轻松地在字符串中加入任意表达式。对于旧版本 Python 的用户,有一个简单的解决方案:升级!如果这不是一个选项,您可以使用string.format()方法:

F-strings

f 字符串计算括号内的表达式,并自动将它们包含在字符串中。format 方法用传递给它的参数依次替换字符串中的花括号。如你所见,f 弦更加简洁。

***args,kwargs。 *args**kwargs允许函数接受任意数量的位置和关键字参数。当您事先不知道函数将要接收的参数数量时,这可能会很有用。在函数内部,*args可以作为列表访问,**kwargs可以作为字典访问:

*args and **kwargs

虽然在你的日常编程中找不到,但是当你在野外遇到它们时,这些知识是有用的。

**列表理解。**列表和理解允许你从现有的列表和字典中创建新的列表和字典。它们提供了简洁的语法,优于 for 循环。例子将有助于说明这一点。

假设您想要将列表中的所有值加倍:

Doubling Values in List Using Comprehension

或者可能在列表中找到奇怪的值:

Odds in a List using Comprehensions

列表理解提供了以下好处:

  • 可读性增强
  • 较少的代码行
  • 潜在的性能提升(追加到数组会在运行时调整其大小,这会带来性能开销)

我可以保证你已经是一个更好的 Python 开发者了。

好吧,就这么定了。虽然我还想谈论更多的事情,但我想尽可能保持这篇文章的简洁,同时为读者提供直接相关的信息。毕竟我们都很忙。

实践这些,将它们整合到你的日常代码中,并进行实验。我向你保证,你的 Python 技能将会提高,你将能够编写出令你自豪的代码。

进一步阅读

关于 Python,还有很多东西需要学习,包括我提到的和我没有提到的。如果你想探索更多,我推荐以下这些文章:

Python 爱好者、艺术大师和老手们,你们能给那些刚刚加入这个行列的人提供一些技巧吗?下面评论下来!

关于阿德里安·佩雷亚

兼职数据科学家,兼职科技作家,全职书呆子。我在教授机器学习和可管理的、 字节 大小的程序中找到了乐趣。是的,我也很搞笑。咖啡上瘾者。数据可视化的吸盘。愿意为下一个最好的树状图付出我的 1 和 0。

关注我上TwitterLinkedIn

使用 SnowNLP 进行简体中文情感分析的初学者指南

原文:https://towardsdatascience.com/beginners-guide-to-sentiment-analysis-for-simplified-chinese-using-snownlp-ce88a8407efb?source=collection_archive---------5-----------------------

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

Image made by a colleague from Yoozoo Games

通过阅读本文,您将接触到一种分析任何简体中文文本情感的技术。本教程将基于简体中文,但它也可以用于繁体中文,因为 SnowNLP 能够将繁体中文转换为简体中文。

本教程将分为 4 个部分:

  1. 设置和安装
  2. 用法和 API 调用
  3. 培训模式
  4. 结论

[第 1 节]设置和安装

在本教程中,我将通过 pip 在 Windows 操作系统上安装所需的模块。让我们从一个名为 SnowNLP 的开源模块获取文件,它是一个简体中文文本处理模块。虽然这个模块已经很久没有更新了,但是对于大多数用例来说,结果已经足够好了。

开源代码库

进入下面的链接,下载需要的文件。完成后,将压缩文件解压缩到您喜欢的目录中。你应该有一个 snownlp-master 文件夹,里面包含所有必要的文件。

计算机编程语言

SnowNLP 支持 Python 3,如官方 Github 链接中所述。在本教程中,我将在虚拟环境中使用 Python 3.7.1。

SnowNLP 模块

您可以通过以下命令轻松安装该模块:

pip install snownlp

一旦完成,您将能够看到指示版本号的输出。如果您错过了它,可以通过下面的命令检查它:

pip list

本教程我使用的是 0.12.3 版本。完成后,继续下一部分。

[第 2 节]用法和 API 调用

让我们更深入地研究一下可用于预处理输入文本的基本 API 调用。

初始化

您必须导入它并通过 SnowNLP 类进行初始化,如下所示:

用输入文本作为参数初始化它。建议以一个 u 作为前缀,表明这是一个 Unicode 字符串。这种语法从 Python 2.0 开始使用,但后来在 3.0 到 3.2 版本中被删除。从 3.3 开始, u 前缀Unicode 字符串的有效语法。

单词(标记化)

汉语是一种独特的语言,从某种意义上说,不像世界上的大多数语言,单词之间没有空格。这使得很难确定一个句子中的单词数,因为一个单词可以是一个或多个汉字的组合。因此,当执行任何自然语言处理时,您需要将整个文本块分割成单词,这个过程被称为标记化。您可以很容易地使用以下命令来进行令牌化:

您应该得到以下结果作为输出:

['我', '喜欢', '看', '电影', '。']

词性标注

很多时候,我们会对词性标签更感兴趣,词性标签是指与句子中相邻和相关的词之间的关系。如果你理解这个有困难,可以把它想象成用一个标签来标识一个单词是名词、副词、动词、形容词还是其他。使用以下代码获取每个单词的标签:

函数 tags 返回一个 zip 对象,可以使用 list 函数对其进行解压缩。您应该会得到以下结果:

[('我', 'r'), ('喜欢', 'v'), ('看', 'v'), ('电影', 'n'), ('。', 'w')]

每个单词将与各自的标签配对。请参考下面的列表以了解更多关于某些标签的含义(这不是一个完整的列表,因为我在官方网站上找不到任何关于它的文档):

  • r :指代词,在句子中代替名词的词。
  • v :指动词,一个用来描述动作、状态或事件的词。
  • n :指名词,一个用来标识一类人、一类地方或一类事物的词。
  • w :指标点符号,书写时用来分隔句子及其成分并阐明意思的符号

拼音

还有一个函数可以得到每个字的拼音。但是,声调不包括在拼音中。获取拼音的示例如下:

您应该得到以下输出:

['wo', 'xi', 'huan', 'kan', 'dian', 'ying', '。']

繁体中文到简体中文

正如我前面提到的,这个模块是为简体中文设计的。如果您想处理繁体中文,请使用以下代码将文本转换为简体中文:

您应该得到以下输出"

'这家伙是坏人。'

分成句子

到目前为止,输入文本只包含一个句子。如果你使用一个段落作为输入,你应该在运行任何 API 调用之前把它分成句子块。为此,请键入以下命令:

检查是否得到以下输出:

['在茂密的大森林里',
 '一只饥饿的老虎逮住了一只狐狸',
 '老虎张开大嘴就要把狐狸吃掉',
 '“慢着”',
 '狐狸虽然很害怕但还是装出一副很神气的样子说',
 '“你知道我是谁吗',
 '我可是玉皇大帝派来管理百兽的兽王',
 '你要是吃了我',
 '玉皇大帝是决不会放过你的”']

关键词

还有一个从句子中识别关键词的选项。您可以传递一个整数参数,指示要从输入中获取的关键字的数量。我亲自测试了它,提取 5 个关键词,它对新闻文章和短篇故事非常有效。键入以下命令:

提取的关键词如下:

['狐狸', '大', '老虎', '大帝', '皇']

摘要

如果关键词不是你要找的,你可以试着用摘要从中提取梗概(重要句子)。该模块将把文本分成句子,并提取它认为是最重要的句子。与关键字类似,它接受一个整数作为参数来确定摘要的数量。如果你的文本中的句子少于输入,它将输出整个文本作为摘要。使用以下命令:

您应该得到以下输出:

['老虎张开大嘴就要把狐狸吃掉',
 '我可是玉皇大帝派来管理百兽的兽王',
 '玉皇大帝是决不会放过你的”',
 '一只饥饿的老虎逮住了一只狐狸',
 '你要是吃了我']

情感分析

本教程的重点是情感分析。然而,大多数时候,你需要做文本预处理,以减少输入文本的准确性。因此,您可以使用上面提到的其他 API 调用。让我们用一些示例文本来测试它:

检查是否得到以下结果(注释不是输出的一部分,它们是为了更容易查看而添加的):

0.7853504415636449 #这个产品很好用
0.5098208142944668 #这个产品不好用
0.13082804652201174 #这个产品是垃圾
0.5 #这个也太贵了吧
0.0954842128485538 #超级垃圾
0.04125325276132508 #是个垃圾中的垃圾

值输出范围从 0 到 1,其中 0 表示负面情绪,而 1 表示正面情绪。正如你所看到的,结果并不坏,考虑到大多数结果都是正确的,除了 0.5 这个应该是负面情绪的值。请注意,情绪是根据购买产品时的评论培养出来的。如果你在其他领域测试它,结果会非常糟糕。您可以查看以下文件,了解有关所用培训数据的更多信息:

  1. snownlp-master/snownlp/情操/neg.txt
  2. snownlp-master/snownlp/情操/pos.txt

You will notice that the word 贵 appeared about 600+ times in both neg.txt and pos.txt. This is the reason why the module output a neutral 0.5 value for the sentiment. In contrast, the word 垃圾 appeared 200+ times in neg.txt and only 35 times in pos.txt. To solve this issue, we can train our own model using custom text dataset. It will be explained in the next section.

[第三节]培训模式

正在准备数据集

通过在两个文本文件夹中收集积极和消极的例句来准备你自己的数据集。我在 snownlp-master 文件夹中创建了它们,并将它们命名为 custom_pos.txtcustom_neg.txt 。每个例句用换行符隔开如下:

今天明明是周六,我就不想工作,
你看他,好意思吗?一直在偷懒
...

训练您的模型

准备好数据集后,让运行以下代码(相应地更改名称):

您应该会在 snownlp-master 文件夹中获得一个名为custom _ invision . marshal . 3的输出文件。不要对文件末尾的 .3 扩展名感到惊讶。要使用输出模型,您可以执行以下操作之一:

  1. 修改 snownlp-master/snownlp/impression/_ _ init _ _ . py 中的代码,将数据路径改为新输出的 marshal.3 文件的目录。
  2. 转到snownlp-master/snownlp/sensation文件夹。创建一个名为 backup 的新文件夹,将perspective . marshalperspective . marshal . 3放入备份文件夹。从 snownlp-master 文件夹中复制custom _ sensition . marshal . 3放入snownlp-master/snownlp/sensition文件夹。改名为情操.元帅. 3

就个人而言,我更喜欢第二种方法,因为修改代码有时会有风险。请注意,您只需要 .3 文件。您可以通过重新初始化 SnowNLP 模块并运行以下代码来测试结果(用类似于您的训练数据的内容替换文本):

根据您的训练数据,输出结果会有一些差异。

分段和标签培训

除了情感,你还可以训练分段和标签。参考以下代码进行分段训练:

我们将对标签使用以下代码:

[第四节]结论

本文演示了一种简单有效的方法,使用名为 SnowNLP 的 Python 模块对简体中文进行情感分析。在撰写本文时,官方文档在解释某些功能方面仍然缺乏质量。请随意阅读代码并探索它,以便更好地理解开发人员使用的技术。自然语言处理还有很多其他的模块,每一个都有自己的优缺点。请根据您的用例对它们进行评估,并在您的项目中使用它们。谢谢,祝你有美好的一天!

参考

  1. https://github.com/isnowfy/snownlp

语音分析入门指南

原文:https://towardsdatascience.com/beginners-guide-to-speech-analysis-4690ca7a7c05?source=collection_archive---------5-----------------------

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

Speech signal from Pixabay

本文介绍了语音信号及其分析。此外,我还与文本分析进行了比较,看它与演讲有何不同。

作为交流媒介的语音与文本的对比

语音被定义为通过发音来表达思想和感情。言语是人类最自然、最直观、最喜欢的交流方式。言语的感知可变性以各种语言、方言、口音的形式存在,而言语的词汇也日益增长。在语音信号级别,更复杂的可变性以变化的振幅、持续时间、音调、音色和说话者可变性的形式存在。

文本作为一种通信手段,已经发展到可以远距离存储和传递信息。它是任何言语交流的书面表达。这是一种更简单的交流方式,没有前面提到的言语中复杂多变的现象。

语音中错综复杂的变化使得分析变得更加复杂,但是使用音调和振幅变化提供了额外的信息。

语音和文本的表示

语音和文本分析在当今世界有着广泛的应用。他们有不同的表现,在他们的分析中遇到许多不同和挑战。

让我们看一个取自 CMU 美国 RMS 北极 语音数据库的一个话语的语音信号。每个话语以 16 kHz 的采样频率被记录为 16 位信号,这意味着信号的每秒有 16000 个样本,每个样本的分辨率为 16 位。音频信号的采样频率决定了音频样本的分辨率,采样率越高,信号的分辨率越高。语音信号从语音数据库中的*‘arctic _ a 0005 . wav’文件中读取,该文件持续时间约为 1.4 秒,相当于 22640 个样本的序列,每个样本为 16 位数。下面的语音表示是来自‘arctic _ a 0005 . wav’的语音信号的图,其等效文本是“我们会不会忘记它”*:

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

Speech signal, s[n] for the utterance “will we ever forget it”

从上图可以看出,语音可以表示为振幅随时间的变化。振幅被归一化,使得最大值为 1 。语音基本上是一系列发音单位,如“w”、“ih”,称为音素。语音信号可以被分割成一系列音素和无声/非语音段。

该数据库还包含每个波形文件在句子和音素级别的语音信号的相应文本转录。下面是上述语音信号的一部分的表示,示出了音素及其相应的时间跨度。

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

Phoneme level segments of the signal for ‘will’ as ‘w’, ‘ih’ and ‘l’

从上图可以看出,音素‘w’、‘ih’和‘l’本质上是准周期性的,并且由于它们是由声带的周期性振动产生的,因此被归类为浊音音素。此外,“ih”是元音,而“w”和“l”是半元音。浊音和清音类别是基于声带振动的语音的宽泛分类。对不同音位的研究和分类被称为语音学。

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

Phoneme level segments of the signal for ‘forget’ as ‘f, ‘er’, ‘g’, ‘eh’ and ‘t’

在上图中,我们有像‘f’、‘g’和‘t’这样的清音音素和像‘er’和‘eh’这样的浊音音素。音位‘g’和‘t’被进一步分类为停顿,即沉默之后是突然的脉冲。可以观察到,浊音分量是准周期性的,而清音分量是有噪声的,因为它们不是由声带的周期性振动产生的。

可以使用音素到字形的映射将音素映射到语音的书面形式。下面是文本和相应音素之间的映射:

正文:“我们会忘记吗”

音序:’ w ‘,’ ih ‘,’ l ‘,’ w ‘,’ iy ‘,’ eh ‘,’ v ‘,’ er ‘,’ f ‘,’ er ‘,’ g ‘,’ eh ‘,’ t ‘,’ ih ‘,’ t ’

从上面的映射可以看出,单词“will”映射到了音素 w ',‘ih ',‘l '。

此外,我们将研究语音的帧级频域表示,在语音研究领域也称为短时傅立叶变换(STFT)声谱图是声音频域表示的直观表示。

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

Log scaled spectrogram of the speech signal using a window size of 30 ms and hop size of 7.5 ms

上面绘制的对数标度谱图是 STFT 在对数标度中的振幅。选择 30 ms 的帧大小,这相当于 30 ms×16k Hz = 480 个语音信号样本,而 7.5 ms 的帧移位相当于 120 个样本。将语音信号分成小持续时间的帧的原因是语音信号是非平稳的,并且其时间特性变化非常快。因此,通过采用小的帧尺寸,我们假设语音信号将是稳定的,并且其特征在帧内不会变化太多。此外,选择较短的帧偏移来跟踪语音信号的连续性,并且不会遗漏帧边缘的任何突变。从上图可以看出,每帧的频域表示有助于我们更好地分析语音信号;因为我们可以很容易地看到谐波在浊音区域中是平行的红色段,以及幅度如何针对每个频率和帧索引而变化。因此,语音信号的大部分分析是在频域中完成的。但是时间信息的提取,如信号中的突然变化(突发的开始,如“t”)在时域中被更好地捕获,因为将语音信号分成帧丢弃了信号中的瞬时变化。

我们可以说,通过采用较小的帧尺寸,我们可以在频域中获得更好的时间分辨率。但是在时域和频域的分辨率之间有一个折衷。采用非常小的帧尺寸将在时间上给出更高的分辨率,但是在单个帧中将给出很少的样本,并且相应的傅立叶分量将具有很少的频率分量。并且由于更大数量的样本,采用更大的帧尺寸将给出更低的时间分辨率但是更高的频率分辨率。因此,同时获得时间和频率的高分辨率是不可能的。

可以观察到,对于 16 kHz 的采样频率,对数频谱图中的 y 轴具有高达 8 kHz 的频率。这是因为,根据奈奎斯特-香农采样定理,在离散信号中可以观察到的最大频率最多是采样频率(8 kHz)的一半。

虽然言语有很多可变性,取决于环境、说话者、说话者的情绪和语气,但文本没有所有这些可变性。

等效的文本被表示为字母、符号和空格的序列,如“我们会不会忘记它”。

语音分析的应用

*语音活动检测:*识别音频波形中仅存在语音的片段,忽略非语音和无声片段

*语音增强:*通过过滤和分离语音片段中的噪声来提高语音信号的质量

语音识别:将语音信号转换成文本仍然是一个挑战。在不同的条件下,识别可以是词汇相关的,也可以是独立的

文本到语音:从文本中合成自然语音,使语音听起来非常自然并带有情感是一项挑战

*说话人二元化和说话人识别:*二元化是将语音信号分割成属于不同说话人的片段,而说话人识别是识别在特定时间谁在说话

*音频源分离:*分离混合语音信号,如与来自不同说话者的语音或噪声重叠的语音

*语音修改:*修改语音,如改变其情感、音调,转换成不同说话者所说的语音

*情感语音分类:*识别语音的情感,如高兴、愤怒、悲伤和焦虑

*关键词识别:*识别整个语音话语中的特定关键词

文本分析的应用:

*文本分类:*将整个文本文档分类成各种类别,或者将单词序列分类成不同的类别

*命名实体识别:*识别人、组织、地名、某些缩写和其他实体

*文本摘要:*从文档生成摘要

*文档聚类:*基于相似内容识别相似文本文档

*情感分析:*从文本中识别情绪、情感、情感和观点

语音和噪声分析的挑战:

所有上述语音和噪声分析的应用都很难解决。使语音和噪声分析进一步复杂化的外部因素是伴随语音和文本产生的各种噪声。探索各种信号处理、基于神经科学的方法、有监督和无监督的机器学习技术来解决同样的问题。由于语音信号的非结构化性质,基于深度学习的方法已经在各种应用中显示出成功。

语音和文本中的噪音:

噪声是任何使原始信号失真的无用信号。向语音添加噪声和向文本添加噪声是非常不同的。

给定幅度为s【n】的语音信号,其中 n 为样本索引,噪声为干扰语音的任何其他信号w【n】。噪声语音信号 u[n] 可以被看作:

u[n]=s[n] + w[n]

在上述情况下,噪声本质上是加性的,这是最简单的情况。噪声也可能以卷积形式出现,例如混响、幅度削波和语音信号的其他非线性失真。

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

factory1 noise, w[n] from NOISEX92 database

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

Log scaled spectrogram of the factory1 noise using a window size of 30 ms and hop size of 7.5 ms

上图是取自 NOISEX92 数据库的时域和频域的因子 1 噪声。上述噪声样本被重新采样到与语音样本相同的采样速率,16 kHz,因为我们将语音添加到噪声中,两者应该具有相同的采样速率。

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

Noisy speech, u[n] at an SNR of 0dB

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

Log scaled spectrogram of noisy speech using a window size of 30 ms and hop size of 7.5 ms

上面的图是在时域和频域中的噪声语音。语音信号中的噪声会改变整个信号,并且很难分析和提取语音片段。存在各种语音增强算法来减少噪声分量并提高语音的可懂度。

对于给定的文本句子,噪声可能以拼写错误和遗漏单词的形式出现,这可能会改变句子的意思或创建一个无意义的句子。例如:

‘我们会忘记它吗’

嘈杂的文字句子:《我们永远不会忘记它》

在上面的嘈杂文本中,noise 以单词’ ever’ 的形式出现,改为 'never ',,从而改变了句子的意思。

另一种形式的嘈杂文字:‘我们永远不会忘记它吗’

在上面有噪声的文本中,噪声以单词’ forget’ 变为 *'forggt ',*的形式出现,由于单词 ‘forggt’ 拼写错误,使得句子没有意义。

因此,可以看出,在语音中添加噪声会使整个信号失真,而在文本中,失真是离散的,就像丢失一个字符/单词或拼写错误。

言语分析的例证

我们现在将说明一种重要的语音分析技术。任何音频信号的记录通常包含许多无声区域,我们可能只对存在语音的片段感兴趣。这对于从包含长静默区域的信号中自动提取语音片段是有用的,因为静默区域不传达任何信息。这些语音片段可以被进一步分析用于各种应用,如语音识别、说话者和情感分类。

因此,在大多数语音应用中,静音检测是一个重要的预处理步骤。

给定语音信号s【n】,可以通过比较短持续时间内的片段的相对能量来检测无声区域。我们取 20 ms 的帧大小,并将短期能量信号 e[n] 计算为 s[m] 的平方和,其中 mn *的+/-10 ms(在样本中)内。*根据我们想要检测的语音信号能量的时间变化量来选择帧大小。短帧大小能够检测能量的突然变化,但是由于某些音素中固有的无声部分,如突发和单词之间的无声部分,可能给出许多交替的无声段帧。

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

Short term energy, e[n]of speech signal

从上面的图中可以看出,语音信号的短期能量突然变化,并且可以使用相对阈值来检测静默区域。

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

Silence detection in speech signal

上图显示了通过使用语音信号的平均短期能量的 0.01%的阈值以红色突出显示的静默区域。基于对语音信号中短期能量变化的观察来选择阈值。

无声检测中的一个挑战是在语音信号有噪声的情况下,语音的无声区域中的相对能量也会很高。在噪声主要具有高频分量的情况下,这可以通过观察低通滤波语音信号的短期能量的变化来解决。

本文中所做的模拟演示可以在Githubnb viewer找到。

希望这篇文章和演示对你有用。在接下来的文章中,我将尝试添加更多关于语音信号分析的见解。

关于作者

我是 Belong.co的一名数据科学家,在印度班加罗尔的印度科学研究所完成了博士学位。

三种机器学习的初学者指南

原文:https://towardsdatascience.com/beginners-guide-to-the-three-types-of-machine-learning-3141730ef45d?source=collection_archive---------5-----------------------

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

Visualising KMeans performance with Yellowbrick

python 中的分类、回归和无监督学习

机器学习问题一般可以分为三种。分类和回归,被称为监督学习,以及无监督学习,在机器学习应用的环境中通常指聚类。

在接下来的文章中,我将简要介绍这三个问题中的每一个,并将包括流行的 python 库 scikit-learn 中的一个演练。

在开始之前,我将简要解释一下监督学习和非监督学习这两个术语背后的含义。

监督学习: 在监督学习中,你有一组已知的输入(特征)和一组已知的输出(标签)。传统上,它们被称为 X 和 y。该算法的目标是学习将输入映射到输出的映射函数。以便当给定 X 的新例子时,机器可以正确地预测相应的 y 标签。

无监督学习: 在无监督学习中,你只有一组输入(X),没有对应的标签(y)。该算法的目标是在数据中找到以前未知的模式。这些算法经常被用来寻找 X 的相似样本的有意义的聚类,因此实际上找到了数据固有的类别。

分类

在分类中,输出(y)是类别。这些可以是二进制的,例如,如果我们对垃圾邮件和非垃圾邮件进行分类。它们也可以是多个类别,如对的种类进行分类,这就是所谓的多类分类。

让我们使用 scikit-learn 完成一个简单的分类示例。如果您尚未安装,可以通过 pip 或 conda 安装,如这里的所述

Scikit-learn 有许多可以通过图书馆直接访问的数据集。为了方便起见,在本文中,我将通篇使用这些示例数据集。为了说明分类,我将使用葡萄酒数据集,这是一个多类分类问题。在数据集中,输入(X)由与每种葡萄酒的各种属性相关的 13 个特征组成。已知的输出(y)是葡萄酒类型,在数据集中,这些类型被赋予数字 0、1 或 2。

我在本文中使用的所有代码的导入如下所示。

import pandas as pd
import numpy as npfrom sklearn.datasets import load_wine
from sklearn.datasets import load_bostonfrom sklearn.model_selection import train_test_split
from sklearn import preprocessingfrom sklearn.metrics import f1_score
from sklearn.metrics import mean_squared_error
from math import sqrtfrom sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC, LinearSVC, NuSVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
from sklearn import linear_model
from sklearn.linear_model import ElasticNetCV
from sklearn.svm import SVRfrom sklearn.cluster import KMeans
from yellowbrick.cluster import KElbowVisualizer
from yellowbrick.cluster import SilhouetteVisualizer

在下面的代码中,我正在下载数据并转换成熊猫数据框。

wine = load_wine()
wine_df = pd.DataFrame(wine.data, columns=wine.feature_names)
wine_df['TARGET'] = pd.Series(wine.target)

监督学习问题的下一步是将数据分成测试集和训练集。算法可以使用训练集来学习输入和输出之间的映射,然后可以使用保留的测试集来评估模型学习该映射的程度。在下面的代码中,我使用 scikit-learn model_selection 函数train_test_split来做这件事。

X_w = wine_df.drop(['TARGET'], axis=1)
y_w = wine_df['TARGET']
X_train_w, X_test_w, y_train_w, y_test_w = train_test_split(X_w, y_w, test_size=0.2)

在下一步中,我们需要选择最适合学习所选数据集中的映射的算法。在 scikit-learn 中有许多不同的算法可供选择,它们都使用不同的函数和方法来学习映射,您可以在这里查看完整列表

为了确定最佳模型,我运行以下代码。我正在使用一系列算法来训练这个模型,并获得每一个算法的 F1 分数。F1 分数是分类器整体准确性的良好指标。我已经详细描述了可以用来评估分类器的各种指标这里是

classifiers = [
    KNeighborsClassifier(3),
    SVC(kernel="rbf", C=0.025, probability=True),
    NuSVC(probability=True),
    DecisionTreeClassifier(),
    RandomForestClassifier(),
    AdaBoostClassifier(),
    GradientBoostingClassifier()
    ]
for classifier in classifiers:
    model = classifier
    model.fit(X_train_w, y_train_w)  
    y_pred_w = model.predict(X_test_w)
    print(classifier)
    print("model score: %.3f" % f1_score(y_test_w, y_pred_w, average='weighted'))

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

完美的 F1 分数应该是 1.0,因此,数字越接近 1.0,模型性能越好。上述结果表明,随机森林分类器是该数据集的最佳模型。

回归

在回归中,输出(y)是连续值而不是类别。回归的一个例子是预测一个商店下个月的销售额,或者你房子的未来价格。

为了再次说明回归,我将使用 scikit-learn 的数据集,即波士顿住房数据集。这由 13 个特征(X)组成,这些特征是房子的各种属性,例如房间数量、年龄和该位置的犯罪率。输出(y)是房子的价格。

我使用下面的代码加载数据,并使用与葡萄酒数据集相同的方法将数据分成测试集和训练集。

boston = load_boston()
boston_df = pd.DataFrame(boston.data, columns=boston.feature_names)
boston_df['TARGET'] = pd.Series(boston.target)X_b = boston_df.drop(['TARGET'], axis=1)
y_b = boston_df['TARGET']
X_train_b, X_test_b, y_train_b, y_test_b = train_test_split(X_b, y_b, test_size=0.2)

我们可以使用这个备忘单来查看 scikit-learn 中适用于回归问题的可用算法。我们将使用与分类问题类似的代码来循环选择并打印出每个选项的分数。

有许多不同的指标用于评估回归模型。这些本质上都是误差度量,并测量模型实现的实际值和预测值之间的差异。我使用了均方根误差(RMSE)。对于此指标,该值越接近零,模型的性能越好。这篇文章对回归问题的误差度量给出了很好的解释。

regressors = [
    linear_model.Lasso(alpha=0.1),
    linear_model.LinearRegression(),
    ElasticNetCV(alphas=None, copy_X=True, cv=5, eps=0.001, fit_intercept=True,
       l1_ratio=0.5, max_iter=1000, n_alphas=100, n_jobs=None,
       normalize=False, positive=False, precompute='auto', random_state=0,
       selection='cyclic', tol=0.0001, verbose=0),
    SVR(C=1.0, cache_size=200, coef0=0.0, degree=3, epsilon=0.1,
    gamma='auto_deprecated', kernel='rbf', max_iter=-1, shrinking=True,
    tol=0.001, verbose=False),
    linear_model.Ridge(alpha=.5)                
    ]for regressor in regressors:
    model = regressor
    model.fit(X_train_b, y_train_b)  
    y_pred_b = model.predict(X_test_b)
    print(regressor)
    print("mean squared error: %.3f" % sqrt(mean_squared_error(y_test_b, y_pred_b)))

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

RMSE 分数表明,线性回归和岭回归算法对该数据集的性能最好。

无监督学习

有许多不同类型的无监督学习,但为了简单起见,这里我将集中讨论聚类方法。有许多不同的聚类算法,所有这些算法都使用略有不同的技术来查找输入的聚类。

可能最广泛使用的方法之一是 Kmeans。该算法执行迭代过程,由此启动指定数量的随机生成均值。距离度量计算每个数据点到质心的欧几里德距离,从而创建相似值的聚类。然后,每个聚类的质心成为新的平均值,并且重复该过程,直到获得最佳结果。

让我们使用在分类任务中使用的葡萄酒数据集,去掉 y 标签,看看 k-means 算法从输入中识别葡萄酒类型的能力如何。

因为我们只使用这个模型的输入,所以我使用稍微不同的方法将数据分为测试和训练。

np.random.seed(0)
msk = np.random.rand(len(X_w)) < 0.8
train_w = X_w[msk]
test_w = X_w[~msk]

由于 Kmeans 依赖于距离度量来确定聚类,因此通常有必要在训练模型之前执行特征缩放(确保所有特征具有相同的比例)。在下面的代码中,我使用 MinMaxScaler 来缩放特征,使所有的值都在 0 和 1 之间。

x = train_w.values
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(x)
X_scaled = pd.DataFrame(x_scaled,columns=train_w.columns)

使用 K-means,您必须指定算法应该使用的聚类数。因此,第一步是确定最佳聚类数。这是通过迭代多个 k 值并将结果绘制在图表上来实现的。这就是所谓的肘方法,因为它通常会生成一个曲线,看起来有点像你的肘曲线。yellowbrick (这是一个可视化 scikit-learn 模型的伟大库,可以 pip 安装)对此有一个非常好的规划。下面的代码产生了这种可视化效果。

model = KMeans()
visualizer = KElbowVisualizer(model, k=(1,8))
visualizer.fit(X_scaled)       
visualizer.show()

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

通常,在使用聚类技术的情况下,我们不会知道数据集中有多少个类别。然而,在这种情况下,我们知道数据中有三种葡萄酒类型—曲线正确地选择了三种作为模型中使用的最佳分类数。

下一步是初始化 K-means 算法,使模型适合训练数据,并评估该算法对数据进行聚类的有效性。

用于此的一种方法被称为轮廓评分。这度量了分类中值的一致性。或者换句话说,每个分类中的值彼此有多相似,以及分类之间有多大的间隔。将为每个值计算轮廓分数,范围从-1 到+1。然后将这些值绘制成轮廓图。同样,yellowbrick 提供了一种简单的方法来构建这种类型的地块。下面的代码创建了葡萄酒数据集的可视化。

model = KMeans(3, random_state=42)
visualizer = SilhouetteVisualizer(model, colors='yellowbrick')visualizer.fit(X_scaled)      
visualizer.show()

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

侧影图可以用以下方式解释:

  • 平均分数(上面的红色虚线)越接近+1,聚类中的数据点就越匹配。
  • 得分为 0 的数据点非常接近另一个聚类的判定边界(因此分离度很低)。
  • 负值表示数据点可能被分配到了错误的聚类。
  • 每个聚类的宽度应该相当一致,如果不一致,则可能使用了不正确的 k 值。

上面的葡萄酒数据集的图显示,聚类 0 可能不如其他聚类一致,因为大多数数据点低于平均分数,少数数据点的分数低于 0。

轮廓分数在将一种算法与另一种算法或不同的 k 值进行比较时特别有用。

在这篇文章中,我想简单介绍一下这三种类型的机器学习。在所有这些过程中还涉及许多其他步骤,包括特征工程、数据处理和超参数优化,以确定最佳数据预处理技术和最佳使用模型。

感谢阅读!

卷积神经网络初学者指南

原文:https://towardsdatascience.com/beginners-guide-to-understanding-convolutional-neural-networks-ae9ed58bb17d?source=collection_archive---------3-----------------------

了解构成卷积神经网络的重要组件

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

Camera (Photo by Dariusz Sankowski on Unsplash)

卷积神经网络(CNN)是一种深度神经网络,已被证明在计算机视觉任务中表现良好,如图像分类、对象检测、对象定位和神经类型转移。在这篇文章中,我将解释构成卷积神经网络的不同层:卷积层、池层和全连接层。

卷积层

卷积层对输入图像进行变换,以便从中提取特征。在这个变换中,图像与一个**核(或滤波器)**进行卷积。

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

Image convolution (source)

一个是一个小矩阵,其高度和宽度小于要卷积的图像。它也被称为卷积矩阵或卷积掩模。该内核在图像输入的高度和宽度上滑动,并且在每个空间位置计算内核和图像的点积。内核滑动的长度被称为步幅长度。**在下图中,输入图像的大小为 5X5,内核的大小为 3X3,步长为 1。**输出图像也被称为卷积特征。

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

当用通道 3 卷积彩色图像(RGB 图像)时,滤波器的通道也必须是 3。换句话说,在卷积中,内核中的通道数必须与输入图像中的通道数相同。

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

Convolution on RGB image (source)

当我们想使用卷积从一幅图像中提取多个特征时,我们可以使用多个内核,而不是只使用一个。在这种情况下,所有内核的大小必须相同。输入图像和输出图像的卷积特征被一个接一个地堆叠以创建输出,使得通道的数量等于所使用的滤波器的数量。见下图,供参考。

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

Convolution of RGB image using multiple filters (kernels) (source)

激活函数是卷积层的最后一个组件,用于增加输出中的非线性。通常,ReLu 函数或 Tanh 函数被用作卷积层中的激活函数。这是一个简单卷积图层的图像,其中 6X6X3 输入图像与大小为 4X4X3 的两个核进行卷积,以获得大小为 3X3X2 的卷积特征,激活函数应用于此以获得输出,这也称为特征图。

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

A convolution layer (source)

汇集层

池层用于减小输入图像的大小。在卷积神经网络中,卷积层之后通常是池层。通常添加池层以加快计算速度,并使一些检测到的特征更加健壮。

池操作也使用内核和 stride。在下面的示例图像中,2X2 过滤器用于合并大小为 4X4 的输入图像,跨距为 2。

有不同类型的池。最大池平均池是卷积神经网络最常用的池方法。

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

Max pooling on left, Average pooling on the right (source)

Max Pooling: 在 Max Pooling 中,从特征图的每个面片中,选择最大值来创建缩小图。

**平均池化:**在平均池化中,从特征图的每个小块中,选择平均值来创建缩减图。

全连接层

完全连接的层位于卷积神经网络的末端。先前图层生成的要素地图被展平为矢量。然后,这个向量被馈送到完全连接的层,以便它捕获高级特征之间的复杂关系。这一层的输出是一维特征向量。

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

A simple architecture of a CNN for binary image classification (source)

以上是用于二值图像分类的卷积神经网络的简单架构。该网络将输入分类为两个不同的类别。该网络接收大小为 32×32×3 的 RBG 图像,输出大小为 2(等于用于分类的类的数量)。该网络的第一层是具有 5×5×3 核的卷积层,第二层是具有 2×2 核大小的最大池层,第三层是具有 5×5×3 核的卷积层,第四层是具有 2×2 核大小的最大池层,输出被平坦化为向量并被馈送到最后两层,这两层都是完全连接的层。

现在,你知道什么是卷积神经网络,以及构成卷积神经网络的不同层,即卷积层、汇集层和全连接层。

觉得这个帖子有帮助? 在下面留下你的想法作为评论。

点击这里 阅读我其他关于 AI/机器学习的帖子。

使用 Py thon 不到 3 分钟实现人脸检测

物体检测用不到 10 行代码使用 Python

用不到 10 行代码计算汽车数量使用 Python

参考文献:

[## 盘旋

卷积是一种数学运算,它对两个函数(信号)的乘积进行积分,其中一个…

Leonardo araujosantos . git books . io](https://leonardoaraujosantos.gitbooks.io/artificial-inteligence/content/convolution.html) [## # 006 RGB 图像上的 CNN 卷积|主数据科学

我们已经看到了 2D 图像上的卷积是如何工作的。现在,让我们看看如何不仅在 2D 上实现卷积…

datahacker.rs](http://datahacker.rs/006-cnn-convolution-on-rgb-images/) [## 学生笔记:卷积神经网络(CNN)简介

这些笔记摘自卷积神经网络课程的前两周(深度学习的一部分…

indoml.com](https://indoml.com/2018/03/07/student-notes-convolutional-neural-networks-cnn-introduction/) [## 理解神经网络中的激活函数

最近,我的一个同事问了我几个类似“为什么我们有这么多激活功能?”,“为什么是…

medium.com](https://medium.com/the-theory-of-everything/understanding-activation-functions-in-neural-networks-9491262884e0) [## 卷积神经网络池层的简明介绍

卷积神经网络中的卷积层总结了输入图像中特征的存在。一个问题…

machinelearningmastery.com](https://machinelearningmastery.com/pooling-layers-for-convolutional-neural-networks/)

żejmo、米沙&科瓦尔、马雷克&科尔比茨、约瑟夫&蒙扎克、罗曼。(2018).基于卷积神经网络和 Hough 变换的细胞核识别。316–327.10.1007/978–3–319–64474–5_26.

Java 初学者——面向对象编程入门

原文:https://towardsdatascience.com/beginners-in-java-getting-started-with-oop-6398f0dcdf86?source=collection_archive---------15-----------------------

Java 是一种面向对象的编程语言——这是什么意思?

每当一种编程方法是基于对象或类,而不仅仅是函数和过程,它就被称为面向对象的OOOOP编程( OOP )。

Java 中的所有代码都必须包含在类中

面向对象语言中的对象被组织成类,或者用更简单的术语来说,一个类产生对象。Java 就是这样一种编程语言。

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

Photo by Émile Perron on Unsplash

类别和对象

java 程序中的一切都包含在一个类中。一个类可以被认为是一个生产对象的工厂**。**对象内部包含数据。它可以有一个或多个数据项。例如,午餐盒对象可能包含 3 个数据项

  1. 薯条(固体食物类型
  2. 汉堡(固体食物
  3. 冷饮(类型流食

我们对象中的这三个不同的项目被称为字段。每个字段都必须有一个类型。在上面的例子中,我们有 3 个字段,但是其中两个具有相同的类型。同时,我们使用方法来处理数据。例如,可以使用方法来查看对象中包含什么数据。这些被称为访问器方法。我们也可以拥有修改对象内部数据的方法。这些被称为更新方法。

假设我们有一个食品厂()。它制造饭盒(物体)。午餐盒包含 3 种不同的食物(字段)。其中两个是同类型(固体食物)一个是不同类型(液体食物)。我们有 3 个人互动使用这种食物。厨师**(方法 1)** 加热食物,服务员(方法 2 )上菜,消费者(方法 3 )吃食物。

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

How OOP Works

在 Java 程序中,主要的“参与者”是 对象 。每个对象都是一个类的 实例 ,它作为对象的*类型和蓝图,定义了对象存储的数据以及访问和修改这些数据的方法。
— *迈克尔·t·古德里奇、罗伯托·塔玛西亚、迈克尔·h·戈德瓦瑟(Java 中的数据结构与算法 )

理解对象

一个对象是类的一个实例,即一个类可以产生许多对象。例如

对象 1

  1. 固体食物项目 1——薯条
  2. 固体食物项目 2——汉堡
  3. 液体食品项目 1——冷饮

对象 2

  1. 固体食物项目 1——大米
  2. 固体食物项目 2——鱼
  3. 液体食品项目 1 —水

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

该过程

让我们试着看看如何构建一个基本的工厂类。让我们先来看看完整的代码。

文件名

public class Factory{} 包含了完整的代码。该文件必须以类名命名。所以文件名也是 Factory.java。

*public class Factory{
   ...
}*

字段/实例变量

现在最上面的 3 行给出了你想要的午餐盒中的 3 个项目(实例变量)。现在你可以看到所有 3 个都有相同的类型= 字符串。 Java 给了你创建自己的类型的灵活性,这实质上意味着用那个名字创建一个类。例如,如果你要创建一个 SolidFood 类,你就必须编写 public class SolidFood{} ,如此而已。

现在我们有 3 个 String 类型的实例变量,命名为 SolidFood1、SolidFood2 和 LiquidFood1。

 *private String SolidFood1;    // **Solid Food 1st Instance Variable**
 private String SolidFood2;    // **Solid Food 2nd Instance Variable** 
 private String LiquidFood1;   // **Liquid Food 3rd Instance Variable***

构造器

*创建对象的代码位于**构造函数内部。*构造函数可以是空的,也可以接受一些用于定义对象的输入参数。在我们的例子中 sf1、sf2 和 lf1 是定义我们的午餐盒中包含哪些项目的参数。

简单地说,构造函数定义了对象的字段是什么样子的。

*public Factory(){}      // **0-arg constructor (Not used)**
// **3-arg constructor**
 public Factory(String sf1, String sf2, String lf1){      
  SolidFood1   = sf1;
  SolidFood2   = sf2;
  LiquidFood1  = lf1;
 }*

方法

方法用于获取或修改对象字段。在我们的例子中,我们只编写了获取项目名称的字段。

*public String getSF1(){return SolidFood1;} // **Method to get the name of 1st Instance Variable**
 public String getSF2(){return SolidFood2;} // **Method to get the name of 2nd Instance Variable**
 public String getLF1(){return LiquidFood1;} // **Method to get the name of 3rd Instance Variable***

main 方法是每个程序中唯一需要的方法。它是 java 编译器唯一运行的东西。在 main 中,你可以创建对象,在这些对象上使用方法并打印东西。

对象创建

对象是通过调用构造函数创建的。一旦创建了一个对象,您可以使用各种方法来理解或修改该对象。这里我们只是展示如何访问字段名。

*Factory lunchBox = new Factory("s1","s2", "l1"); // **Object Created Yay!!!***

怎么跑

万一你没有 java,请访问这个页面。

* [## 如何为我的 Mac 安装 Java?

如果 web 浏览器中禁用了 Java 内容,安装程序会通知您,并提供启用它的说明。如果…

java.com](https://java.com/en/download/help/mac_install.xml)

假设您的系统中安装了 java,您应该能够使用以下命令运行该程序。

> javac Factory.java (**This command compiles your code into Machine Readable Code)**> java Factory (**Running the Program**)

您看到的输出如下所示

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

OOP 中包含了更多的东西。这只是开始。后面的文章将包括更多的面向对象编程的概念。

参考

  1. 要点链接
  2. Java 下载
  3. 数据结构书

矩阵入门

原文:https://towardsdatascience.com/beginners-introduction-to-matrices-bd39289cc66a?source=collection_archive---------15-----------------------

从理论物理到神经网络,矩阵运算无处不在。

矩阵是数据科学的基石。他们以不同语言的不同形象出现。从 Python 中的 numpy 数组,到 R 中的 dataframes,再到 MATLAB 中的 matrix。

矩阵最基本的形式是以矩形或类似阵列的方式排列的数的集合。这可以代表一个图像,或者一个网络,甚至一个抽象的结构。

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

A rectangular array of 3 rows and 4 columns.

矩阵,矩阵的复数形式,比你想象的要普遍得多。

我们所有通过 Adobe Photoshop 制作的迷因都使用矩阵处理线性变换来渲染图像。一个方阵可以表示一个几何对象的线性变换。

例如,在笛卡尔 X-Y 平面中,矩阵

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

Interesting matrix

用于创建对象在垂直 Y 轴上的倒影。在视频游戏中,这将呈现倒映在血泊中的刺客图像。如果视频游戏有弯曲的反射面,比如一间镜子房,矩阵会更复杂,以拉伸或收缩反射。

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

xkcd — Rotation

在应用物理学中,矩阵用于研究电路、量子力学和光学。航天工程、化学工程等。所有这些都需要从矩阵变换中获得完全校准的计算。在医院、医学成像、CAT 扫描和 MRI 中,使用矩阵来生成输出。

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

Photo by JESHOOTS.COM on Unsplash

在编程中,矩阵和逆矩阵用于编码和加密消息。在机器人和自动化中,矩阵是机器人运动的基本组成部分。基于使用矩阵的计算获得用于控制机器人的输入。

他们长什么样?

按照惯例,矩阵中的行数由 m 表示,列数由 n 表示。由于矩形的面积是 x 宽,我们用mx*n .***来表示矩阵的大小,因此该矩阵被称为 **A,**它在符号上可以写成

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

Matrix notation

这里 m=3,n=4。因此,矩阵 A 中有 12 个元素。方阵是具有 m=n 的矩阵。

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

Square matrix

只有一行的矩阵称为行矩阵,只有一列的矩阵称为列矩阵。

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

我们能用它们做什么?

矩阵就像数字一样,可以加减乘除。不过,这种划分略有不同。不是所有的矩阵都可以整除。

连加减乘除都有一定的规律。

矩阵加法

两个矩阵 A( mn* ) 和B( mn* ) 相加得到一个矩阵 C( mn* )。C 的元素是 A 和 B 中相应元素的和

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

减法的工作原理类似。

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

这里需要注意的是,您只能对具有相同行数和列数的矩阵进行加减运算,即相同的顺序(顺序=行 x 列)

  • A 的行数= B 的行数
  • A 的列数= B 的列数

注意事项

  • 矩阵的加法是可交换的,这意味着 A+B = B+A
  • 矩阵的加法是结合的,这意味着 A+(B+C) = (A+B)+C
  • 矩阵的减法是不可交换的,这意味着 A-B ≠ B-A
  • 矩阵的减法是非关联的,意思是 A-(B-C)≦(A-B)-C
  • 矩阵 A、B、A-B 和 A+B 的顺序总是相同的
  • 如果 A 和 B 的顺序不同,A+B,A-B 就无法计算
  • 加法/减法运算的复杂度是 O(mn ),其中 mn 是矩阵的阶

尽管乘法有点复杂

矩阵乘法

两个矩阵 A( mn* ) 和B(n** p)相乘得到一个矩阵 C( mp )。请注意,对于乘法运算,您不需要 A 和 B 的行/列相同。你只需要**

  • A 的列数= B 的行数
  • 或者,B 的列数= a 的行数。

要计算结果矩阵 C 的左上元素,将 A 的第一行元素与 B 的第一列元素相乘并相加

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

Multiplication

注意事项

  • 矩阵的乘法是不可交换的,这意味着 AB ≠ BA
  • 矩阵的乘法是结合律,这意味着 A(BC) = (AB)C
  • AB 的存在并不意味着 BA 的存在
  • 乘法运算(AB)的复杂度为 O(mnp)其中 mn 和 n*p 分别是 A 和 B 的阶
  • 作为 AB 计算的矩阵 C 的阶是 mp,其中 mn 和 np 分别是 A 和 B 的阶

在这篇文章的下一个版本中,我们将看到更多可以在矩阵上执行的操作,例如矩阵的逆矩阵、矩阵的行列式、矩阵的伴随矩阵等等。

我们还将看到这些矩阵如何在神经网络和图像处理领域发挥作用。

KNN(K-最近邻算法)到随机森林,矩阵在几乎所有的机器学习算法中都非常重要。

矩阵入门—第二部分

原文:https://towardsdatascience.com/beginners-introduction-to-matrices-part-ii-42b86e791b8b?source=collection_archive---------35-----------------------

从设计游戏到发射火箭,矩阵运算无处不在

在第一部分中,我们讨论了像加法、减法和乘法这样的基本运算。在这一部分,让我们看看如何计算矩阵的行列式,以及术语矩阵求逆是什么意思。

继续前面的例子,让我们看看我们的方阵(方阵的行数等于列数

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

Square matrix with m=3, n=3 | A(mxn)

这个矩阵的行列式将是一个单一的数字。它不会是一个矩阵。行列式可以看作是将矩阵转化为数字的函数。矩阵 A 的行列式写成 |A|

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

determinant of a 2x2 matrix

行列式只存在于方阵中。它是方阵的一个性质。对于一个 3×3 的矩阵,行列式的计算应该是这样的

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

注意**++模式(+a…b…+c…d…)。记住这一点很重要。这种模式在 4x4 矩阵和更高矩阵中继续存在。这种计算行列式的方法叫做拉普拉斯展开。**这决不是唯一的方法,还有其他方法。

行列式不仅用作计算工具(解线性方程,计算面积和体积),而且在力学中也有重要的应用。它们可以用来计算桁架或其他机械结构的稳定性。

具有讽刺意味的是,行列式的最大用途是它的零。如果一个矩阵的行列式为 0,那么就是需要注意的情况。好坏取决于应用。

矩阵的逆

在数学中,数的倒数写为

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

所以一个数和它的倒数相乘总是得到 1。(除非数字为 0,在这种情况下,不定义逆本身)。

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

对于矩阵,逻辑是一样的。如果矩阵的逆矩阵存在,则将矩阵与其逆矩阵相乘得到**单位矩阵。**这里需要注意两件事

  • 如果 1)矩阵是正方形的,2)它的行列式不为零,则存在逆
  • 单位矩阵的所有元素除了主对角线都是 0。主对角线元素都是 1。单位矩阵总是用字母 I. 表示

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

这是一个非常特殊的矩阵,因为如果你试图将它与另一个 mx3 矩阵相乘,结果将是同一个矩阵。

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

为什么我们需要一个反义词

在矩阵的世界里,没有除法运算。因此,如果你必须在一个方程中求解 X ,其中 A,X 和 B 都是矩阵

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

唯一的方法就是取 a 的倒数。

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

There is no B/A in matrices

反演的最大应用是在电脑游戏中——光线追踪。在游戏世界中,为了实现 3d 效果,需要将鼠标点击转化为游戏的 3d 空间中的实际动作。这个操作和无数其他操作需要矩阵求逆。反演也用于反射。

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

Photo by Ales Nesetril on Unsplash

在下一部分,我们将计算一个实际的逆矩阵,并探索矩阵乘法的 python 库。

机器学习的初学者学习路径

原文:https://towardsdatascience.com/beginners-learning-path-for-machine-learning-5a7fb90f751a?source=collection_archive---------2-----------------------

您在机器学习领域开始职业生涯的完整学习路径

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

Photo by Franck V. on Unsplash

下定决心要进行机器学习,但却困惑于从哪里开始。我面临着同样的困惑,什么应该是一个好的开始?我应该学 Python,还是去 R?数学对我来说总是一个可怕的部分,我总是担心我应该从哪里学习数学?我还担心我应该如何获得机器学习的强大基础。不管怎样,至少你已经下定决心了,这是值得祝贺的。

在这篇文章中,我将告诉你在开始实用的机器学习之前,你应该采取的一些基本步骤和课程。

数学是机器学习的第一步吗?

机器学习的第一步(基本编程)

第一步是你应该学习编程,很可能是 Python。如果你从未写过一行代码,我会向你推荐哈佛大学的 CS50,这是编程初学者的最佳课程,它将教你从零开始,直到所有的 C 语言和大量的 Python 和 JavaScript,以及 SQL 和 JSON 的基础知识。这个非常激动人心的课程在 edx.org是免费的,你可以在这里找到它。点击阅读一篇关于 cs50 的文章

如果你想直接从 Python 开始,那么我会推荐你在 edx 上免费学习麻省理工学院的 Python 计算机科学入门。请注意,高中代数是这门课的先决条件,因为它们会让你解决许多现实世界中的数学问题。

如果你觉得你的计算逻辑不好,你在编程中不是一个很好的问题解决者,我会推荐微软的这门课程,它都与 edx all 上免费的计算思维有关。这门课真的很酷,教了很多计算逻辑和批判性思维。

如果你有足够好的编程基础,但是没有面向对象编程的知识,那么我推荐你学习面向对象编程。虽然它在机器学习(基础水平)中用得不多,但肯定很有帮助。我会推荐这个课程,它教你 oop 的基础和 python 中的算法。你可以在 edx.org 找到这门免费的课程。

下一步是熟悉数据结构和算法。一个好的程序员必须知道一些基本的算法,如链表、二叉树等。这个课程微软会教你

  • 算法分析
  • 算法的排序和搜索
  • 数据结构:链表、栈、队列

这门课程在 edx.org 的免费提供。

如果想深入数据结构和算法,加州大学圣地亚哥分校的专业是一个杰作。它有 6 门课程,将带你从 0 到数据结构和算法的英雄水平。你可以点击每门课程并免费审核它的材料,但如果你想要证书,它的价格是 50 美元/月,取决于你多早可以完成它。在 Coursera.org 找到这个专业或点击这里

机器学习的第二步

是的,你猜对了,对大部分初学者来说最危险的部分,数学。

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

Photo by Antoine Dautry on Unsplash

但是不要担心,它并没有我们想象的那么难,如果你认为你有很好的高中数学基础(向量、矩阵、微积分、概率和统计),你可以简单地参加一个复习课程,但是如果你认为你不够好,那么任何人学习数学的最好地方是可汗学院。可汗学院的内容非常丰富,非常有用,而且一切都是免费的。你可以在那里找到所有的线性代数、概率统计和多变量微积分课程。

另一个很好的课程是伦敦帝国理工学院 coursera 的机器学习专业化数学。这是一门很棒的课程,它教授基础知识,修正概念,但不会太深入。练习和测验很有挑战性。上面有三道菜。

麻省理工学院有一门很棒的统计学课程

  • 使用矩法和极大似然法构造估计量,并决定如何在它们之间进行选择
  • 使用置信区间和假设检验量化不确定性
  • 使用拟合优度测试选择不同的模型
  • 使用线性、非线性和广义线性模型进行预测
  • 使用主成分分析(PCA)进行降维

在 edx.org免费可以买到。

如果你想边编码边学数学,微软有一门真的很好的课程《机器学习必备数学:Python 版》。这是一门交互式课程,使用 python 著名的库 Numpy、pandas、matplotlib 以图形方式教授数学,这些库是本课程的先决条件。在 edx.org 找到免费的 T4 课程。

Udacity 有 3 门很棒的统计学免费课程。

你也可以在学习实用机器学习的同时学习数学,遇到你不知道的事情,只需在可汗学院或 YouTube 上搜索这个主题的 100 多个好视频。

机器学习的第三步

现在你已经熟悉了线性代数、多变量微积分和统计学,所以现在你需要学习 Python 著名的数据可视化库,它们是 Numpy、Pandas、Matplotlib 和 Scipy,可以帮助你分析任何类型的数据,操纵数据,并以图形方式查看数据。当然,还有很多数据可视化库,但这些是最重要的一个。用图形实现你的线性代数和微积分概念,并将其形象化。

这方面的代表作之一是密歇根大学的 Python specialization 统计学,它详细讲授了数据可视化及其操作。当然可以在 coursera.org 上免费(点击每门课程免费审核)。

密歇根大学为数据分析初学者开设的另一门课程是 Python 中的数据科学导论,它以一种非常好的方式教授从数字到熊猫的基础知识。可在 coursera.org免费购买。本课程的下一部分将改变游戏规则。在 Python 中被命名为应用绘图、图表和数据表示,它教授所有的图形可视化及其技巧和技术。

另一门很好的课程是哈佛大学的“Python for Research ”,它教授这些库以及一些著名的案例研究,它的期末项目非常令人兴奋,教授了很多新东西。edx.org 免费可用。

另一门非常全面的课程是加州大学圣地亚哥分校的数据科学 Python,它教授

  • 计算机编程语言
  • Jupyter 笔记本
  • 熊猫
  • NumPy
  • Matplotlib
  • 饭桶
  • sci 工具包-学习
  • NLTK

也就是说,这门课还会教你机器学习的基础知识,但更重要的是,这门课所教授的数据科学库。可在 edx.org 上免费获得(别忘了阅读它的先决条件)。

实用的机器学习

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

Photo by Franck V. on Unsplash

到目前为止,您已经学习了线性代数、多变量微积分、概率和统计、python 及其数据可视化库,所以现在您已经准备好跳到最激动人心的部分,即机器学习。第一道菜意义重大。如果不好,他可能只是改变领域,因为他只是不喜欢这个过程。所以这里所有的课程都是高质量的,在你开始你的第一门 ML 课程之前,做一些研究。

这门入门课程不会教你机器学习,相反,它会让你了解什么是机器学习,机器学习术语的含义是什么,什么是人工智能策略,以及它的伦理。本课程将向您概述什么是机器学习,它是如何工作的,它的工作流程是什么,以及如何在您的公司中构建人工智能。它很好地介绍和概述了人工智能。该课程由非常著名的机器学习导师吴恩达教授,可在 coursera.org免费获得。

你可以谷歌一下或者在任何博客上看到,每个人推荐的第一门课程是斯坦福大学的机器学习,由 Andrew NG 教授,该死的,这是一门多么美丽的课程。超过 250 万名学生注册了这门课程,超过 20 万名学生对它进行了评分(4.9*)。它教授从非常基础的概念到高级的概念,对初学者来说是一门非常全面的课程。本课程的总时长为 56 小时以上。想看看这门课的评论吗?这里你去吧。另一篇在此回顾。这里是 Quora 上对这门课程的另一个回顾。这是里面的目录。

  • 线性回归
  • 多项式回归
  • 逻辑回归
  • 多类分类
  • 神经网络
  • 支持向量机(SVM)
  • k 均值聚类
  • 主成分分析
  • 异常检测
  • 推荐系统

唯一的问题(根据一些人的说法)是它是在 octave/Matlab 中教授的,但对我来说这没什么大不了的,因为它将清除机器学习的所有基础和深层概念,在任何其他语言中实现它们都不会是任何问题,而且 Matlab 是一项额外的技能。该课程在斯坦福官网(此处)和 coursera.org( 此处)免费提供。

这门课对每个人来说都是必去的,因为它好得无法解释。

学完这门课程后,你需要实现你在 python 中学到的所有东西,并超越你所学的东西,所以我们自己的吴恩达在 coursera 上的 deeplearning.aiKian KatanfroshYounes Bensouda 的专业化也是必须的。该专业有 5 门课程,分别是

  • 神经网络和深度学习
  • 改进深度神经网络:超参数调整、正则化和优化
  • 构建机器学习项目
  • 卷积神经网络
  • 序列模型

你将获得的主要技能是

  • 张量流
  • 卷积神经网络
  • 人工神经网络
  • 深度学习

好了,现在你已经很好地掌握了 TensorFlow 和机器学习,你可能不喜欢 TensorFlow,或者你只是想测试 TensorFlow 的著名参赛者 PyTorch(由脸书设计),那么为什么不开始这个免费的深度学习课程呢? Udacity 由脸书与亚马逊网络服务合作提供,是 Udacity 著名的深度学习纳米学位的一部分,价值 1400 美元。

当然,这仅仅是一个开始,还有很多需要学习和发现的,但是如果你做了这些事情,希望你会知道你的立场和下一步该做什么。

一些意见和建议:

以下是一些建议。

祝你好运,并祝你在学习如何让机器变得智能的过程中过得愉快。

Python 初学者推荐系统

原文:https://towardsdatascience.com/beginners-recommendation-systems-with-python-ee1b08d2efb6?source=collection_archive---------7-----------------------

用 TMDB 5000 电影数据集构建我们自己的推荐系统

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

Photo by Myke Simon on Unsplash

本教程的目标

以下是您的一些目标:

  • 了解什么是推荐系统,它们是如何工作的,以及它们的不同风格
  • 使用 Python 和 TMDB 5000 部电影数据集实现几个推荐系统

什么是推荐系统?

一个推荐系统(通常也被称为推荐/推荐引擎/平台)试图预测用户对可用项目(例如 Spotify 上的歌曲)的兴趣,并相应地给出推荐。有两种主要类型的推荐系统:

  • 基于内容的过滤系统根据项目本身的特点做出推荐。因此,如果网飞用户一直在狂看科幻电影,网飞会更快地推荐另一部科幻电影,而不是浪漫喜剧。我们将用 Python 实现这个推荐系统。
  • 协同过滤系统基于用户交互做出推荐。假设我们都在亚马逊上买了一把电吉他,我也买了一个功放。然后亚马逊会预测你也会对这款功放感兴趣,并向你推荐。

Ibtesam Ahmed 在这个数据集上的 Kaggle 内核值得称赞。这篇文章旨在以中等风格的格式遵循她的教程。

建立一个基本的推荐系统

设置

和往常一样,我们将首先导入必要的包和数据集:

Setup for our notebook

这两条打印语句给出了以下输出:

  • 演职员表:(4803,4)
  • 电影 _ 不完整:(4803,20)

所以我们正在研究 4803 部电影。请注意,我们的数据现在被分成两个数据帧。参考本要点了解如何组合和清理数据帧。在遵循教程的同时保持这个要点是最容易的。

我们将从两个非常基本的推荐系统开始——我们将向用户推荐评分最高的电影列表和另一个最受欢迎的电影列表。但是首先我们要找到每部电影的平均评分的加权平均值( vote_average 值)。在 Ibtesam 的带领下,我们将使用 IMDB(以前)用于计算电影加权评分的公式。

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

Source

这里有一个如何得到加权平均值的例子:

我选择了 0.70 作为我对 quantile() 的参数,以表明我只关心那些至少获得了我们的电影数据集中 70%的投票的电影。选择我们的值为 m 有点武断,所以在这里做一些实验。

推荐者 Mk1:

现在我们已经为我们的第一个推荐系统做好了准备。下面推荐十部加权平均收视率最高的电影:

我们得到了这张最受欢迎的照片:

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

我们看到我们的就职系统推荐了一些经典。但是如果我们想推荐在 TMDB 用户中受欢迎的电影呢?

推荐者 Mk2:

我们可以使用我们数据的流行度特性来根据流行度推荐电影:

现在,我们可以看到基于受欢迎程度分数的推荐:

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

啊,正如我们所料:来自小兵的出色表现。现在,如果我们想根据电影的加权平均评分受欢迎程度评分来推荐电影,该怎么办呢?

推荐者 Mk3:

为了避免小黄人的巨大受欢迎度得分扭曲我们的新评分系统,我对加权平均受欢迎度列中的值进行了归一化。我决定采用 50/50 的比例加权平均评分和受欢迎程度评分,但同样不要害怕尝试这种分割:

现在我们有了一个新的评分栏,它考虑了一部电影的加权平均评分及其受欢迎程度评分,我们可以看到我们的推荐系统将为我们提供哪些电影:

以下是我们基于五五分成的建议:

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

这些推荐者按预期工作,但我们当然可以改进。现在我们必须转向基于内容的过滤。

基于内容的过滤

所以现在我们感兴趣的是使用一部电影的特征来向用户推荐其他电影。再次遵循 Ibtesam 的例子,我们现在将根据概述栏中给出的电影情节概要提出建议。因此,如果我们的用户给我们一个电影名称,我们的目标是推荐具有相似情节概要的电影。

单词矢量化和 TF-IDF

在我们开始对情节摘要进行任何分析之前,我们必须将概述列中的文本转换为单词向量,并且我们还必须在概述上安装一个 TF-IDF:

我们会收到以下输出:

  • (4803,10417)

所以在情节摘要中使用了大约 10,000 个独特的词来描述我们的 5,000 部电影(注意,这个数字比 Ibtesam 的小,因为我用 min_df=3 将最小词频增加到了 3)。如果你有兴趣了解更多,我在这篇文章中也谈到了 TF-IDF。

计算相似性得分

现在我们有了一个单词矩阵,我们可以开始计算相似性得分。这个指标将帮助我们挑选出与用户提交的电影情节概要相似的电影。Ibtesam 选择了线性内核,但是我想尝试一下 sigmoid 内核,以获得乐趣。幸运的是,我得到了相似的结果:

既然我们已经构建了基于内容的过滤系统,让我们用永恒的最爱间谍小子来测试一下:

以下是我们对基于内容的过滤系统的建议:

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

因此,我们的推荐系统给了我们一些与间谍小子相关的精选,但也有一些失误,如《太深了中的埃斯科瓦尔:失乐园*。*

限制

基于上述结果,我们可以看到我们的基于内容的过滤系统有一些局限性:

  1. 我们的推荐者挑选了一些可能被搜索与 *Spy Kids 相关的标题的用户认为不合适的电影。*为了改进我们的系统,我们可以考虑用字数来代替 TF-IDF,我们还可以探索其他相似性得分。
  2. 我们的系统只考虑每部电影的情节概要。如果我们像 Ibtesam 一样,考虑其他特征,如演员、导演和类型,我们可能会在找到相关电影方面有所改进。
  3. 我们目前的系统只根据特征的相似性来推荐电影。所以我们的推荐器遗漏了用户可能喜欢的其他类型的电影。我们需要尝试协同过滤来解决这个问题,但是我们的数据集不包括用户信息。

摘要

总而言之,我们涵盖了以下内容:

  • 什么是推荐系统,它们如何工作,以及一些不同的类型
  • 如何基于加权平均评分、受欢迎程度以及两者的混合来实现非常基本的推荐系统
  • 如何创建基于内容的过滤系统,以及如何认识到基于内容的推荐的局限性

附录/进一步阅读

从零开始的机器学习

原文:https://towardsdatascience.com/beginning-machine-learning-650add627e79?source=collection_archive---------11-----------------------

我是如何学会不再担心反向传播的

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

Actor Peter Sellers in “Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb”

问题是

“我对机器学习真的很感兴趣,但我没有计算机科学或数学的背景。”

你可能以前遇到过这种情绪。如果你带着任何目的和意图阅读这篇文章,你很有可能经常遇到这种情绪。事实上,我猜测你有可能亲身体验过这种情绪。

我当然有。这是本文的缘起和基础。在相当长的一段时间里,我真的沮丧到了发狂的地步,因为我真的真诚地相信,像我这样的教育背景和经验的人很可能无法理解或使用机器学习技术。

一个“一般”的人能做机器学习吗?

简短的回答是是的。我们可以争论“平均”在这种情况下意味着什么,但我自己的个人经验(无可否认是相当有限的)向我表明,在那些被假定为必需的学科背景下(例如计算机科学、微积分和其他形式的更高层次的数学、统计学、编程等。),虽然肯定是有帮助的,但是或者根本不需要 (i) ,或者 (ii) (如果实际需要的话),典型地在比最初感觉到的显著更多的表面水平上。

成为机器学习初学者

概述

我不能告诉你如何成为一名机器学习专家,因为我自己也刚刚开始走上这条道路。但是,我确实可以放心地说,我已经开始的“机器学习初学者”之路是可以实现的,并且应该可以在具有各种背景的广泛人群中重复。

我是谁?

正如我上面提到的,我一直对机器学习、人工智能、自然语言处理和其他前沿计算领域感兴趣,但诚实而真实地感觉到,我缺乏“技术”教育背景正在阻碍我。

明确地说,按照社会将文凭等同于实际智力成就的奇怪标准,我被认为是受过良好教育的。我在达特茅斯学院获得俄罗斯语言文学本科学位,在哈佛大学获得硕士学位,在萨福克大学(位于马萨诸塞州波士顿)获得法律学位。

直到 2016 年,我一直在一家非常大、非常著名的国际律师事务所担任公司律师,在那里我非常专注于私募股权交易。2016 年年中,我做了一个完全符合年龄的决定(在 45 岁的时候),放弃了一份非常赚钱的职业,成为一名计算机程序员,这是一个我之前没有接受过正式培训,也没有真正实质性知识的学科。

为了透明起见,T2 并没有那么糟糕。我一直对计算机感兴趣,在进入法学院之前,我曾在几家软件公司工作过,但我的任何编程经验都是 (i) 非常少, (ii) 完全自学,并且 (iii) 是在 2001-2002 年获得的,这意味着这些知识实际上基本上是无用的。

经过大约一年的自学,我说服了一家公司给我一个机会。我利用那份工作学习 C#,提高我的 JavaScript,继续学习 web 应用程序架构等等。快进到今天,我在临床数据科学中心工作,但不是作为数据科学家。

因此,这是我在 2019 年下半年开始数据科学之旅时的立场:

  • 我没有接受过任何计算机科学方面的正规教育,从 1989 年高中三年级开始,我就没有上过数学课。
  • 我从 2016 年开始专业从事程序员工作,但我对 Python 的经验相当有限。
  • 我的工作与数据科学家非常接近,但我不与他们中的任何人一起工作,当然也不知道从他们那里学到的任何东西,否则这些东西很难从谷歌那里收集到。**

如果你相信你和我一样,或者可能和我一样,我真诚地鼓励你继续读下去。

如何失败

教程和帮助文章很擅长告诉你应该肯定做什么,但是它们通常很少花时间解释什么不要做。我相信,为自己的成功做准备包括确保避免潜在的陷阱和失败,这个旅程对粗心的人来说有太多的好处。

在成为机器学习初学者的过程中,如果出现以下情况,你几乎肯定会失败:

你缺乏耐心和决心

作为一名程序员,如果不是作为一名机器学习实践者,我可以告诉你,学习编程是对耐心的锻炼。从一个非常重要(然而具有讽刺意味)的意义上来说,计算机是非常愚蠢的机器——它们只做你告诉它们的事情,除此之外别无其他。

如果你没有耐心坐在电脑前,参与编码、调试、研究的迭代过程,这可能不会让你感到愉快。

你缺乏好奇心

无论你最终选择哪种途径来获取机器学习知识,几乎可以肯定的是,你会得到这样的建议:“键入所有代码”或“按照练习进行工作”或“出去构建我们刚刚构建的东西,但略有不同”。这些都只是同一个想法的变体,即仅仅“修补”是有价值的——试验,当某些东西失败时阅读文档,查看其他人的源代码,等等。如果你没有从根本上被自己的好奇心和“建设”欲望所驱动和支撑,你几乎肯定会跟不上那些人。

你高估了学习曲线的难度

本质上,这是对最初关注的重新陈述,意味着这只是对具有非传统背景的人是否能在机器学习领域取得成功的关注。如果这篇文章有所成就的话,我希望它至少会打破机器学习完全不可接近的神话,或者只对碰巧拥有计算机科学和应用数学/统计双博士学位的少数幸运者而言。

你低估了学习曲线的难度

我认为这都是可以做到的,而不是简单的*。如果很容易,只要说每个人都会这么做就够了,如果每个人都在这么做,按照逻辑,教育背景不可能是一个相关因素,这意味着本文试图解决的操作性问题将是没有实际意义的。*

简单地说,在前进的道路上会有艰难的坎坷,你如何应对这些坎坷可能会成为你成功的决定性因素。你会开始搜索论坛、邮件列表、Twitter、媒体等吗?直到你得到满意的答案?还是面对不熟悉的素材会心神不定?见上面 【你缺乏耐心和决心】

你打算下周、下个月、今年学习所有的机器学习/人工智能…

在刚刚成为机器学习初学者的过程中,可以学习的材料数量多得令人难以置信。更复杂的是,大量的学术和相关的工作成果正以如此快的速度增长,以至于我们倾向于用一个月或几年来衡量相关性,而不是几十年。

现在或在可预见的未来,技术的发展没有“尽头”,试图找出某个你将知道“关于机器学习的一切”的时间点,是在崇拜一个虚假神的圣坛。慢慢来,一遍又一遍地阅读相关材料,编写更多的代码,构建更多的东西,记录你的学习过程,享受和庆祝个人的小成就。

所以,是的,很明显失败是可能的,而且也不是特别难。但话说回来,避免这些问题也不是特别难。

如何在这方面取得成功

选择一个过程并坚持下去

有大量很好的资源提供了对机器学习概念的全面介绍。一个众所周知的选择是 T2 吴恩达在 Coursera 上的课程。另一种选择是由 fast.ai 提供的。决定没有对错之分——两者都有很好的声誉,每门课程提供的教学风格都与其他课程略有不同。

这里突出的一点是,你应该尽一切努力坚持单一的学习课程。当你面对你不理解的东西时,转换课程在统计学上有意义的一段时间内,一般情况下不太可能产生有意义的进步。解决方案不是“亚马逊的又一本书”或“一个不同的、不太技术性的教程”在某种程度上,你只需要全力以赴,咬紧牙关,努力向上到达学习曲线的右侧。

非常明确地说,我是而不是建议你不要用外部资源补充你自己的学习努力,或者当你有问题时参考第三方资料。我的意思是,在某个时候,随着你越来越深入,你会遇到一些难以理解的概念,因为它们实际上是很难理解的概念。拥抱困难,这是你推动自己超越舒适区的标志,舒适区是这个世界上所有值得讨论的事情发生的地方(根据我的经验)。改变课程、书籍或视频系列并不是一个可行的长期学习策略,而是一种寻找“银弹”的心态如上所述,没有灵丹妙药,没有捷径——有的只是努力工作。

选择一个框架并坚持下去

现在不是拿 TensorFlow 跟 PyTorch 跟 MXNet 等比较对比的时候。作为一个完全的初学者,你没有足够的知识或理解任何这些框架的实现的问题空间,因此任何这样的决定都不是另一个思维过程的回流。

选择一个拥有大型活跃开发社区的主流框架,并坚持下去。在这一点上,专注于学习总体概念,避免兔子洞,即一年后可能相关或不相关的给定框架的细节。

记住“这就像法语”

如果你曾经被要求学习一门外语,很可能你已经遇到了性别名词的概念。非常简单地说,在许多语言中(其中英语不是之一),某些名词不是阳性就是阴性。举例来说,从这篇文章(我的重点是增加的)中摘录。

有一些名词表示具有性别的实体,它们只有一种形式,使用时不考虑实体的实际性别,例如,表示人的单词;personne;永远是女性化的,即使这个人是男性,而老师这个词;教授;即使老师是女的,也永远是男性

关键是,正如试图理解一个人无论性别为何总是女性化的逻辑是一项徒劳的工作(答案不可避免地是“它就是这样——接受它作为一篇真理并继续前进”),试图在第一遍中理解机器学习的一切根本不是一个合理的期望。有些事情你暂时只能相信。

这并不是说你没有注意到这个问题,以便在以后的某个时间点进行进一步的研究,但是每当你遇到你不理解的东西时,试图学习你不理解的所有东西只是上面讨论的*“你打算学习所有的机器学习”*的一个聪明的变体。

不管你更好的天使可能会告诉你什么,你试图钻研细节的动力是而不是帮助你学习。事实上,恰恰相反,因为这些兔子洞只是潜在地拖延时间,直到你对更大的图景有了坚实的理解和基础,为更有意义的探索提供了必要的背景。

建立工具集和可重复的工作流程

对于任何一个工具或工作流的细节,我没有什么特别有趣的(当然也没有什么原创的)可以补充,除了说拥有一套你熟悉的、舒适的、相当可靠的工具是很重要的。

从 Google Cloud 到 AWS 到 Azure 到 Jupyter 笔记本到 Vim、Emacs、VSCode 等的插件,有多种有据可查的解决方案。截至 2019 年下半年,为单个开发人员建立行业级机器学习管道是非常实惠的,也是有据可查的。

找一个像样的笔记软件

我认为这没有得到足够的重视。即使在这个旅程的最初阶段,你也会被信息轰炸,有些你能掌握,有些你不能。如上所述,鉴于我们的知识状况,有些事情你暂时必须相信。但是你绝对应该注意那些你不理解的概念,这样当你有更多的背景知识时,你最终可以做真正需要的深入研究。

我个人使用 Coggle ,但是冒着重复让你厌烦的风险,这并不是关于你选择的工具。文本文件、Markdown 文件、Jupyter 笔记本、OneNote、Evernote 等。都会管用。我个人的偏好源于我更喜欢“思维导图”风格的图表。相对于层次结构的格式(例如在大纲中),我经常发现这与我头脑中的材料的心智模型不一致。思维导图允许我以相当任意的模式将节点连接到其他节点,这允许我以一种对我的大脑更自然的方式记录事情。

学会接受失败是一种正常的休息状态

如果你正在从软件工程以外的东西过渡到机器学习,这可能看起来不直观。简单地说(不仅仅是开玩笑),这项工作的绝大部分可以通俗地描述为“让您的代码编译”,顾名思义,这意味着大部分时间,您的代码处于非工作、失败状态。

当然,作为人类,我们尽我们所能,通过确保错误以粗体、鲜红色显示,并伴有表明你从事不法行为的图标等,来加剧他人和自己的不足感。

事实上,这项工作的一个方面,就像软件工程(在观察了很多数据科学家的工作后,我觉得这样说很舒服),代表了一个有点乏味的实验、错误识别和修复,然后是进一步实验的循环。如果你没有坚韧不拔的精神、建设的动力和天生的好奇心来支撑你度过那些时刻,这可能不适合你。

结束语

成为一个机器学习初学者远不是一件简单的事情,但是,没有什么值得做的事情是简单的。

我给你们留下一个简单的思想实验——如果 (i) 数据科学是美国发展最快的工作 (ii) 只有拥有数据科学背景的人才能胜任那份工作,那么**(I)**怎么可能是真的呢?它怎么可能是发展最快的工作呢?

换句话说,如果第一个(我认为是虚假的)论断是真的,难道不会有很多人因为某种原因,恰好拥有一个十年前并不存在的行业所需的完美技能。这看起来可能吗?

或者更合理的解释是,像你们和我这样有能力的人在这个领域交叉培训和发展新技能,正是因为这些技能实际上是可以获得的?

我把它作为一个练习留给好奇的读者。

脚注

注意:除了我现在的雇主临床数据科学中心之外,我与本文中提到的任何组织都没有关联和/或附属关系。截至本文撰写之时,我没有从任何提及的公司(除了我的雇主)处获得任何折扣或其他优惠,而这些折扣或优惠是任何持有有效信用卡的人无法公开获得的。

[1]为了完全公开,我正在完成 fast.ai 课程。在简要评估了 fast.ai 课程和吴恩达的课程后,我决定 fast.ai 方法会更好地为我服务。我喜欢“自上而下”的方法,一般来说,你从“做”开始,然后到“理解”。

[2]我个人使用谷歌云平台和他们的人工智能笔记本服务,但我也使用过 AWS SageMaker,并对此感到满意。

开始实时复制自然对话

原文:https://towardsdatascience.com/beginning-to-replicate-natural-conversation-in-real-time-d4f6b7f62e08?source=collection_archive---------14-----------------------

进入文学的第一步

为了开始我的新项目,我首先要做的当然是浏览当前的研究和最先进的模型。

最近我接受了采访,在采访中我用 Wallscope 解释了这个新项目,但简而言之(非常短):我的目标是让对话代理人更自然地交谈。

我并没有穷尽这一领域的所有文献,我只是触及了皮毛(如果你知道我必须阅读的相关论文,请在下面链接)。这里是一些研究的概述和走向更自然的对话代理的旅程。在这方面,我将参考以下文件:

[1]

马修·罗迪、加布里埃尔·斯坎茨和娜奥米·哈特利用 LSTMs 研究连续话轮转换预测的语音特征

[2]

由 Divesh Lala、Koji Inoue、Pierrick Milhorat 和 Tatsuya Kawahara 开发的用于识别人机交互参与的社交信号检测

[3]

朱利安·霍夫(Julian Hough)和大卫·施朗根(David Schlangen)利用实时、真实世界的基础策略研究人机交互的流畅性

[4]

Angelika Maier、Julian Hough 和 David Schlangen 的走向情景口语对话系统的深层话轮结束预测

[5]

Gabriel skan tze 的《人机对话中的协调》( 2019 年 3 月 7 日在格拉斯哥的演讲)

内容

简介
转弯结束-转弯预测
接合
实施例
流体增量接地策略
结论

介绍

如果我们想到两个人进行流畅的对话,这与人类与 Siri、谷歌助手、Alexa 或 Cortana 之间的对话非常不同。

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

source

流量损失的一个原因是大量的暂停。对于一个会话代理(CA)来说,如果它检测到你已经说完了你正在说的话(完成了你的话轮),它会等待一段时间的静默。如果它检测到长时间的停顿,它会认为你已经完成了你的话轮,然后处理你的话语。

不同系统之间设置的静默持续时间略有不同。如果它设置得太低,CA 会在中途打断你,因为人类的对话充满了停顿。如果设置的太高,系统会更准确的检测到你的回合结束,但是 CA 会花费很长的时间来响应——扼杀了对话的流畅,让用户感到沮丧。

当两个人说话时,我们倾向于尽量缩小话轮之间的差距,这是跨文化的。在全球范围内,转弯之间的间隔大约为 200 毫秒,接近人类反应时间的极限[1]。因此,在听别人说话时,我们必须预测说话者的话轮结束。

转弯-转弯结束预测

要重现这种流畅的对话,在 CAs 中使用快速切换和轻微重叠,我们必须首先了解我们自己是如何做到的。

不要脸,但略有关联,自我推销。为了研究计算机视觉,我们必须先了解人类视觉

我们下意识地解读话轮转换的暗示来检测什么时候轮到我们说话,那么我们使用什么暗示呢?类似地,我们在听别人说话时不断地这样做,那么我们能重现这种递增的过程吗?

[4]使用声学和语言学特征训练 LSTM 来标记 10ms 窗口。他们的系统的任务是将这些窗口标记为语音、中途停顿(MTP)或 EOT,但主要焦点当然是标记为 EOT 的序列中的第一点。

LSTM 中使用的声学特征是:原始音高、平滑后的 F0、均方根信号能量、对数信号能量、强度、响度以及作为声学特征的每一帧的衍生特征。

除了这些声学特征之外,语言特征由单词和称为加权平均对数三字组概率(WML)的增量句法概率的近似值组成。

许多其他的信号被识别来指示说话者是要继续说话还是已经完成了他们的话轮[5]:

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

[5]

如前所述,等待 10 秒钟的响应就像 CA 不停地在你中途切入一样令人恼火[4]。因此,在 50 毫秒和 6000 毫秒之间定期考虑多个基线,以确保基线中包含多个权衡。

除了一个案例(只有语言特征,500 毫秒沉默阈值),每个模型都超过了基线。仅使用语言或声学特征不会产生太大的差异,但是当模型同时使用两组特征时,性能总是最佳的。最好的整体系统的延迟为 1195 毫秒,切入率仅为 18%。

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

[4]

[1]陈述了我们从多模态信号预测 EOT,多模态信号包括:韵律、语义、句法、手势和眼睛注视。

传统模型不是标记 10ms 窗口(如语音、MTPs 或 EOTs ),而是预测说话者是继续说话(保持)还是完成了他们的话轮(转换),但只有在检测到暂停时才会这样做。这种传统方法的一个主要问题是,反向信道既不是保持也不是转移,而是无论如何都要预测其中之一。

LSTMs 已经被用于以 50 毫秒的间隔连续进行预测,并且当应用于保持/移位预测时,这些模型优于传统的 EOT 模型,甚至优于人类。它们的隐藏层允许它们学习长期相关性,但是不知道哪些特征对性能影响最大。

在[1]中,新系统完成了三个不同的话轮转换预测任务:(1)停顿时的预测,(2)开始时的预测,(3)重叠时的预测。

暂停时的预测是在交互中的短暂暂停时发生的标准预测,用于预测是否会有暂停或转换。本质上,当暂停超过阈值时间时,具有最高平均输出概率(得分)的人被预测为下一个发言。这个分类模型用加权 F 分数进行评估。

开始时的预测对讲话过程中的话语进行分类,而不是在停顿时。然而,该模型略有不同,因为它预测当前正在进行的话语是短还是长。同样,作为一个分类器,这个模型使用加权 F 值进行评估。

首次引入重叠预测。这本质上又是一个保持/移位预测,但是当至少 100 毫秒的重叠周期出现时。当重叠是反向信道时,预测保持(继续讲话)的决定,并且当系统应该停止讲话时,进行转换。这再次使用加权 F 分数进行评估。

下面是一个预测话轮转换的例子:

如上所述,我们并不确切知道我们使用哪些特征来预测何时轮到我们发言。[1]在不同的排列中使用了许多特征来区分哪些是最有用的。所使用的特征如下:

声学特征是低级描述符,包括响度、摆振、音调、抖动、频谱通量和 MFCCs。这些是使用 OpenSmile 工具包提取的。

语言特征从词性(POS)和词两个层面进行考察。文献通常表明,POS 标签擅长预测转弯开关,但是需要单词(来自 ASR 系统)来提取 POS 标签,因此检查是否需要这种额外的处理是有用的。

对于需要实时运行的系统来说,使用单词而不是 POS 将是一个很大的优势。

语音特征从对语音进行分类的深度神经网络(DNN)中输出。

声音活动包含在他们的转录中,因此也被用作一个特征。

那么根据[1],什么特征对 EOT 预测最有用呢?

声学特征对于 EOT 预测非常有用,除了一个实验外,所有实验最佳结果都包括声学特征。对于重叠处的预测尤其如此。

除了开始时的预测,单词的表现大多优于词性标签,所以如果你想预测话语长度(如反向通道),请使用词性标签。

在所有情况下,包括声音活动在内的活动都提高了表现。

在声学特征方面,最重要的特征是响度、F0、低阶 MFCCs 和频谱斜率特征。

总体而言,通过使用声音活动、声学特征和单词获得了最佳性能。

如前所述,使用单词而不是 POS 标签会带来更好的性能,这一事实对于更快的处理来说是非常好的。这当然有利于实时增量预测——就像我们人类所做的那样。

所有这些特征不仅用于检测我们下一次说话的时间,甚至用于指导我们说什么。我们将根据对方对我们所说内容的参与程度,扩展我们所说的内容,跳过细节或改变话题。

因此,为了模拟自然的人类对话,CA 测量参与度是很重要的。

约会

参与度表示对对话的兴趣和关注,因为我们希望用户保持参与,所以会影响 CA 的对话策略。这种用户体验的优化必须实时完成,以保持流畅的对话。

[2]检测以下信号来衡量参与度:点头、笑声、口头暗道和眼睛凝视。这些信号显示注意力和兴趣的事实相对来说是常识,但却是从大量人机交互中习得的。

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

[2]

[2]不仅专注于识别社交信号,还致力于创建参与度识别模型。

这个实验是在日本进行的,在那里点头是非常普遍的。提取了七个特征来检测点头:(每帧)人头部的偏转、滚动和俯仰(每 15 帧)人头部的平均速度、平均速率、平均加速度和范围。

他们的 LSTM 模型在检测点头的所有指标方面都优于其他方法。

微笑经常被用来检测参与度,但为了避免使用相机(他们使用麦克风+ Kinect) 笑声反而被检测到。每个模型的任务是对声音的间歇期单位(IPU)是否包含笑声进行分类。使用韵律和语言特征来训练两层 DNN 执行得最好,但是使用其他频谱特征而不是语言特征(不一定可从 ASR 获得)可以用于改进模型。

与点头类似,口头暗语在日本更为频繁(称为会内)。此外,在日本,口头反馈通常伴随着头部运动,但只有声音提供给模特。类似于笑声检测,该模型对 IPU 是否是一个反向通道或该人是否开始轮到他们进行分类(当闯入时尤其困难)。发现表现最好的模型是随机森林,有 56 个估计器,使用韵律和语言特征。当只给定韵律特征时,该模型仍然合理地执行(再次因为语言特征可能无法从 ASR 获得)。

最后,的眼神俗称订婚的明确信号。根据注释者之间的协议,连续注视 Erica 的头部(本实验中的机器人实施例)10 秒钟被视为参与。因此,少于 10 秒是阴性病例。

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

Erica: source

来自 kinect 传感器的信息用于根据用户的头部方向计算一个向量,如果该向量与 Erica 的头部发生碰撞(加上 30cm 以适应误差),则用户被视为“在看 Erica”。这种基于几何的模型工作得相对较好,但 Erica 的头部位置是估计的,所以这将影响结果。预计当确切的数值已知时,该模型将得到显著改进。

本文的目的不是创建最佳的单个系统,而是假设这些模型结合起来会比单个模型在检测参与度方面表现得更好。

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

[2]

上述模型的集合被用作二元分类器(一个人是否参与)。特别是,他们建立了一个分层贝叶斯二元分类器,从上述 4 个模型的 16 种可能的输出组合中判断听者是否参与。

从注释器中,构建了一个模型来推断在检测参与时哪些特性更重要或更不重要。例如,一些注释者发现笑声是一个特别重要的因素,而其他人则不这么认为。他们发现输入一个包含三种不同字符类型的字符变量可以提高模型的性能。

此外,包括听众的先前参与也改进了模型。这是有道理的,因为目前不感兴趣的人在你下一轮更有可能保持不感兴趣。

衡量参与度只能在体现 CA 时才能真正做到(例如,与 Siri 的眼神交流是不存在的)。社交机器人越来越多地用于教学、公共场所、医疗保健和制造业等领域。这些都可以包含口语对话系统但是为什么一定要具体化呢?

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

[5]

典型,化身

当人们只需打个电话就能进行面对面的交流时,他们会走遍全球。我们不喜欢在看不到对方的情况下互动,因为我们错过了上面谈到的许多信号。在今天的世界里,我们也可以进行视频通话,但出于同样的原因,在可能的情况下还是要避免这样做。电话交谈或面对面交谈的区别类似于与 Siri 和嵌入式对话系统交谈的区别[5]。

目前的语音系统无法显示面部表情,通过眼神交流或移动嘴唇来表示注意。唇读对于听力受损的人来说显然非常有用,但我们在交谈时都会读唇(这就是我们如何知道人们在说什么,即使在非常嘈杂的环境中)。

一张脸不仅可以输出这些信号,它还允许系统检测谁在说话,谁在注意,真实的人是谁(Rory,Jenny 等),并识别他们的面部表情。

然而,机器人的脸有很多种形式,有些更适合在对话中使用。大多数机器人的脸,如 Nao 的脸,都是非常静态的,因此无法像我们一样通过表情来表达广泛的情感。

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

Nao: source

一些更抽象的机器人面部描述,如 Jibo,可以使用形状和颜色来表达情感,但有些表情必须学习。

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

Jibo: source

我们知道如何解读人脸,所以展示人脸是有意义的。超逼真的机器人脸是存在的,但有点令人毛骨悚然,像索菲亚,而且非常昂贵。

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

Sophia: source

他们非常现实,但不完全正确,这使得谈话非常不舒服。为了解决这个问题,虚拟人物被设计成可以在屏幕上对话。

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

source

这些机器人可以相对接近地模仿人类,而不会令人毛骨悚然,因为它不是一个物理机器人。这几乎和 Skype 一样,但是这种方法有“蒙娜丽莎效应”。在多方对话中,屏幕上的头像不可能只看一个人而不看另一个人。这个化身要么是在看所有的聚会,要么是不看任何人。

gabrial skan tze ([ 5]的演示者)是 Furhat robotics 的联合创始人,他认为 Furhat 是所有这些系统之间的最佳平衡。Furhat 已被开发用于对话应用,如接待员、社会培训师、治疗师、采访者等

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

source

Furhat 需要知道它应该看哪里,什么时候应该说话,应该说什么,应该展示什么面部表情[5]。

最后(就目前而言),一旦具体化,与机器人的对话需要与现实世界实时联系。在[3]中,给出的例子是在工业机器中实现的 CA ,[ 5]指出这变得越来越普遍。

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

source

流畅、渐进的接地策略

为了使对话自然,人机对话必须以流畅的方式为基础。

使用非增量接地,用户可以给出积极的反馈并进行修复,但只有在机器人完全理解请求之后。例如,如果你让一个机器人移动一个物体到某个地方,你必须等到这个物体被移动后,才能用类似“不,移动那个红色的”这样的话语来纠正它。没有重叠的语音是可能的,所以如果需要修复,动作必须完全颠倒。

使用增量接地,重叠仍然是不可能的,但是可以以更有规律的间隔给出反馈。反馈可以在子任务间隔给出,而不是在给出反馈之前完成整个任务。“不,移动红色的那个”可以在机器人捡起一个蓝色物体后说,快速修复。在前面的例子中,蓝色物体被放置在一个给定的位置,然后才能进行修复,这导致了整个任务的逆转!这更有效,但仍然不像人与人之间的互动那样流畅。

如果重叠被处理,流体增量接地是可能的。允许并发的言语和动作并进行推理要自然得多。继续我们的修复示例,“不,移动红色的”可以说是机器人一要拿起蓝色物体,就不必完成和反转任何任务,因为并发是允许的。拾取任务可以被中止,红色物体被流畅地拾取,就像你说的那样。

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

[2]

为了实现这种更加流畅的基础,需要进行实时处理。系统不仅需要一个字一个字地处理话语,还需要监控实时上下文,例如机器人的当前状态和计划的动作(这两者都可以在话语或单词的过程中动态变化)。

机器人必须知道什么时候它已经充分展示了它正在做什么来处理修理和确认。机器人需要知道用户在确认什么,更重要的是,需要修复什么。

结论

在这个简短的概述中,我只涉及了当前朝着更自然的对话系统发展的一小部分工作。

即使话轮转换预测、参与度测量、具体化和流体基础都很完善,CAs 也不会像我们人类一样进行对话。我计划在接下来的几年里写更多这样的综述,所以如果感兴趣的话,请留意它们。

与此同时,请对讨论点进行评论,批评我的理解,并提出我(以及任何阅读本文的人)可能会感兴趣的论文。

从 R 开始——未知的领域

原文:https://towardsdatascience.com/beginning-with-r-the-uncharted-territory-d35eaffff3f3?source=collection_archive---------29-----------------------

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

我来自非编程背景,并且 python 是第一次接触编程和数据分析,试图在 R 中动手似乎一开始就相当令人生畏。r 有时会感觉有点奇特和独特,因为它是基于进行数据分析和统计的前提,而不是像 python 那样的软件编程。但是,当我鞭策自己,努力学习 R 相对于 python 的许多特点和优势时,它在某种程度上提供了进行数据分析的不同视角。此外,与 python 相比,使用 R 有一个很强的优势——世界各地的统计学家都在用 R 实现各种统计方法的庞大而现代的库。

除了它的怪癖之外,迄今为止为 R 开发的最有趣的 IDE—R studio让数据分析看起来像是有趣的活动。Rstudio 中的各种其他东西,如使用 LaTex 和 HTML 制作报告,以及使用 HUGO 制作静态网站,都让生活变得非常简单。

但是为了能够做所有这些很酷的事情,我们需要首先掌握 R 的基础知识,这是任何复杂的数据分析管道的构建块。那么我们开始 r 的旅程吧。😃

目录

  • R 简介
  • r 数据类型
  • 处理未定义的值
  • 经营者
  • 逻辑运算符
  • 数据结构—列表、向量、矩阵、数组、因子、数据框

R 简介

r 是一种主要为统计计算和可视化而开发的动态语言。它包括各种统计和机器学习包,易于学习和用于数据分析。

r 数据类型

当在 R workspace 中创建一个变量时,R 会自动将数据类型赋给该变量。

**#***# [1] 4.2***#***# [1] "Hello!"*

要检查变量的类型,使用typeof()

**#***# [1] "double"***#***# [1] "character"*

基本数据类型有

  • 字符串/字符
  • 数字
    整数
    双精度
    复数
  • 布尔/逻辑

无论是整数还是浮点数,都总是用 double 表示。

**#***# [1] "double"*

对于整数的明确要求,添加后缀 L

**#***# [1] "integer"*

处理未定义的值

处理未定义/缺失的值与 python 略有不同。Python 只有NaN 值作为未定义/缺失值。在 R 中,未定义的值基本上用

  • 圆盘烤饼

三者的工作方式不同。

NULL 是一个空对象,在没有值时使用。如果向量或矩阵中存在某个值,并且该值不可用(fill_value),我们使用 NA 或 NaN。

NA 或 NaN 缺少值指示符。

**#***# [1] "NULL"***#***# [1] "logical"***#***# [1] "numeric"*

当没有真或假,即逻辑不确定性时,NA 出现。它也可能是丢失的值。

NaN 表示 0/0

经营者

  • 乘法( ***** )
  • 分部( / )
  • 加法( + )
  • 减法( - )
  • 指数( ^ )
  • 模数( %% )
  • 整数除法( %/% )

逻辑运算符

  • 不()
  • 元素明智与( & )
  • 还有( & & )
  • 元素方面的 OR ( | )
  • 或者( || )
  • 在集合中(%在% )

数据结构

在 R 中有 6 种类型的数据结构

  • 列表
  • 向量(或原子向量)
  • 矩阵
  • 数组
  • 因素
  • 数据帧

列表

R 中的 List 可以保存不同类型的元素。没有强迫。列表可以包含数字、字符、布尔、矩阵、向量、数组、列表等。

要创建列表,请使用list()参数。

**#***# [[1]]*
**#***# [1] "green"*
**#***#* 
**#***# [[2]]*
**#***# [1] "yellow"*
**#***#* 
**#***# [[3]]*
**#***# [1] 1*
**#***#* 
**#***# [[4]]*
**#***# [1] 2*
**#***#* 
**#***# [[5]]*
**#***# [1] 4 5 6*

要给列表中的每个条目命名,使用names()参数。

使用$访问列表中的特定条目

**#***# [1] "green"***#***# [1] "yellow"*
**#***# $A*
**#***# [1] "green"*
**#***# [1] "green"*

要合并两个或多个列表,使用c()

**#***# [[1]]*
**#***# [1] 1*
**#***#* 
**#***# [[2]]*
**#***# [1] 2*
**#***#* 
**#***# [[3]]*
**#***# [1] 3*
**#***#* 
**#***# [[4]]*
**#***# [1] 4*
**#***#* 
**#***# [[5]]*
**#***# [1] 5*
**#***#* 
**#***# [[6]]*
**#***# [1] 6*
**#***#* 
**#***# [[7]]*
**#***# [1] 7*
**#***#* 
**#***# [[8]]*
**#***# [1] 8*

r 中的一些预定义列表。

**##  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"**
**## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z"****##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q"**
**## [18] "R" "S" "T" "U" "V" "W" "X" "Y" "Z"****##  [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov"**
**## [12] "Dec"****##  [1] "January"   "February"  "March"     "April"     "May"** 
**##  [6] "June"      "July"      "August"    "September" "October"** 
**## [11] "November"  "December"**

向量

为了创建一个矢量,我们使用c()函数。它基本上像 python 中的列表一样连接东西。

**## [1] "1"     "2"     "3"     "4"     "5.4"   "hello" "TRUE"  "FALSE"**

正如我们所见,向量可以有任何数据类型,可以是数字、字符或布尔值。但是我们注意到了一些事情。vector 中的所有元素都被强制为字符类型,因为 vector 包含一个字符串"hello"。这就是隐性强制的效果。

对于严格意义上的数字向量,使用vector()功能。

**#***#  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*

我们可以使用这样一个向量来预分配一个向量,该向量可用于从一个for循环中追加值,这比将值追加到一个空向量中要快,因为每次一个值被追加到一个空向量中时,R 都会复制它,从而减慢整个过程。

强制——矢量、数据帧等对象。可以使用as.class功能强制到不同的类别。

**#***# [1] "numeric"***#***# [1] "character"***#***# [1] "logical"*

矩阵

矩阵与向量相同,只是它有一个额外的维度属性。它是一个二维数据结构。

**#***#      [,1] [,2] [,3]*
**#***# [1,]    6    8    6*
**#***# [2,]    2    3    8*
**#***# [3,]    6    2    0***#***# $dim*
**#***# [1] 3 3*

矩阵开始按行填充。而在 python 中,矩阵开始逐列填充。

在 R 中,我们可以传递行和列的名称。

**#***#   x y z*
**#***# a 6 8 6*
**#***# b 2 3 8*
**#***# c 6 2 0*
**## [1] "x" "y" "z"****## [1] "a" "b" "c"**

要访问矩阵的元素,请使用方括号。

**#***# [1] 3***#***#   x y*
**#***# b 2 3*
**#***# c 6 2*

但是a[2,](第二行)或a[,2](第二列)给出了一个向量,即它试图返回最简单的数据结构。为了避免这种情况,即获得一个矩阵,使用drop = FALSE

**#***# x y z* 
**#***# 2 3 8***#***# NULL*
**#***#   x y z*
**#***# b 2 3 8***#***# [1] 1 3*

也可以进行特定的索引。

**#***# [1] 6 2 8 2*

你也可以使用逻辑向量做索引。

**#***#   x y*
**#***# a 6 8*
**#***# c 6 2*

使用t(a)转置矩阵

要组合矢量或矩阵,使用rbindcbind

矩阵维度也可以改变(整形)。

**#***# [1] 1 9*

数组

数组是一个可以保存多维数据的对象。矩阵是数组的子集,因为它们是二维数组。因此,除了维度属性dim之外,数组还具有属性dimnames。数组只是一个多维数据结构。

它的语法是a <- array(data, dim = c(x,y,z,t...))

**#***# , , 1*
**#***#* 
**#***#      [,1] [,2] [,3] [,4]*
**#***# [1,]    1    4    7   10*
**#***# [2,]    2    5    8   11*
**#***# [3,]    3    6    9   12*
**#***#* 
**#***# , , 2*
**#***#* 
**#***#      [,1] [,2] [,3] [,4]*
**#***# [1,]   13   16   19   22*
**#***# [2,]   14   17   20   23*
**#***# [3,]   15   18   21   24*
**#***# , , 1*
**#***#* 
**#***#      [,1] [,2]*
**#***# [1,]   10   30*
**#***# [2,]   20   40*
**#***#* 
**#***# , , 2*
**#***#* 
**#***#      [,1] [,2]*
**#***# [1,]   12   14*
**#***# [2,]   13   15*

要定义不同尺寸的标签,使用dimnames

**#***# , , g*
**#***#* 
**#***#    d  e*
**#***# a 10 30*
**#***# b 20 40*
**#***#* 
**#***# , , h*
**#***#* 
**#***#    d  e*
**#***# a 12 14*
**#***# b 13 15*
**#***# , , 1*
**#***#* 
**#***#      [,1] [,2] [,3]*
**#***# [1,]    1    4    7*
**#***# [2,]    2    5    8*
**#***# [3,]    3    6    9*
**#***#* 
**#***# , , 2*
**#***#* 
**#***#      [,1] [,2] [,3]*
**#***# [1,]   10   13   16*
**#***# [2,]   11   14   17*
**#***# [3,]   12   15   18*
**#***#* 
**#***# , , 3*
**#***#* 
**#***#      [,1] [,2] [,3]*
**#***# [1,]   19   22   25*
**#***# [2,]   20   23   26*
**#***# [3,]   21   24   27*
**#***# $dim*
**#***# [1] 2 2 3***#***# , , 1*
**#***#* 
**#***#      [,1] [,2]*
**#***# [1,]    1    4*
**#***# [2,]    2    5*
**#***#* 
**#***# , , 2*
**#***#* 
**#***#      [,1] [,2]*
**#***# [1,]   10   13*
**#***# [2,]   11   14*
**#***#* 
**#***# , , 3*
**#***#* 
**#***#      [,1] [,2]*
**#***# [1,]   19   22*
**#***# [2,]   20   23*

因素

对于分类数据的表示,R 有称为因子的特定对象。因子基本上是整数,并且有与之相关联的标签。因此,特定数量的因素与特定的标签相关联。这些标签被称为级别。因子看起来像字符,但实际上是整数。因子的其他用途是根据一个分类数据集对所有分类数据集进行排序。

factor()命令用来创建一个因子对象。

**#***# $levels*
**#***# [1] "apple"  "banana" "orange"*
**#***#* 
**#***# $class*
**#***# [1] "factor"*

默认情况下,这些级别是无序的。要订购它们,您可以定义级别。

**#***# $levels*
**#***# [1] "apple"  "orange" "banana"*
**#***#* 
**#***# $class*
**#***# [1] "factor*

数据帧

数据帧用于存储表格数据。长度相等的列表存储在数据帧中。

**#***#     city rank*
**#***# 1 Jaipur    2*
**#***# 2  Jammu    3*

存储的数据可以是不同的类型。一列可能是字符,另一列可能是因子等等。但是每一列必须有相同类型的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值