TowardsDataScience 博客中文翻译 2020(三百一十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

利用 RoBERTa 模型发现 Reddit 子群的情感

原文:https://towardsdatascience.com/discover-the-sentiment-of-reddit-subgroup-using-roberta-model-10ab9a8271b8?source=collection_archive---------27-----------------------

我们将使用预训练的 RoBERTa 模型来建立情感分析模型,以发现 Reddit 子群的情感。

被困在付费墙后面?点击这里阅读这篇文章和我的朋友链接。

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

资料来源:jeffrey grospe(联合国统计司)

当你登录社交媒体账号,阅读开篇帖子时,你有什么感受?它是让你微笑还是让你悲伤或生气?我有一个复杂的经历。大多数时候,社交媒体上的帖子让我很开心。怎么会?好吧,我们不能控制其他人发布什么,但我们可以控制我们想在自己的社交媒体账户上看到什么。

如果你加入了一个负面评价很高的群体,那么你会更频繁地阅读那些评论。那会让你生气和难过。在它对你精神健康造成损害之前,离开那些有毒的群体。

所以如果我让你找出你社交媒体账户的有毒群体,你能做到吗?

这篇文章将帮助你建立一个模型,帮助你总结所有帖子或评论的观点。所以你可以在他们让你觉得想退出社交媒体之前离开那些群。

我们将在本文中使用 Reddit 社交媒体参考。我将分析我的 Reddit 子群。并且检查这些子群是否具有高数量的负面评论。

为什么是 Reddit?

像 Reddit 和 twitter 这样的社交媒体将允许你通过 API 访问用户的帖子和评论。您可以在 Reddit 数据上测试和实现情感分析模型。

本文分为两部分。在第一部分中,我将建立一个 RoBERTa 模型。在第二部分,我们分析了 Reddit 子群的情感。

罗伯塔模型的建立

我们将使用 twitter 数据集对预训练模型 RoBERTa 进行训练和微调。你可以在这里找到数据。该数据集包含积极和消极情绪的推文。我选择了二元情感数据来提高准确性。二元预测很容易解读。此外,它使决策过程变得容易。

Huggingface 团队变形金刚库将帮助我们访问预训练的罗伯塔模型。RoBERTa 模型在 NLP 基准,通用语言理解评估(GLUE)上表现非常好。RoBERTa 模型的性能与人类水平的性能相匹配。点击了解更多关于罗伯塔的信息。点击了解更多关于变形金刚库的信息。

现在,让我们依次检查代码的不同部分。

第一部分。配置和令牌化

预训练模型具有包含信息片段的配置文件,例如层数和注意力头的数量。RoBERTa 模型配置文件的细节如下所述。

{
    “architectures”: [
    “RobertaForMaskedLM”
    ],
    “attention_probs_dropout_prob”: 0.1,
    “bos_token_id”: 0,
    “eos_token_id”: 2,
    “hidden_act”: “gelu”,
    “hidden_dropout_prob”: 0.1,
    “hidden_size”: 768,
    “initializer_range”: 0.02,
    “intermediate_size”: 3072,
    “layer_norm_eps”: 1e-05,
    “max_position_embeddings”: 514,
    “model_type”: “roberta”,
    “num_attention_heads”: 12,
    “num_hidden_layers”: 12,
    “pad_token_id”: 1,
    “type_vocab_size”: 1,
    “vocab_size”: 50265
}

标记化意味着将 python 字符串或句子转换成整数的数组或张量,这是模型词汇表中的索引。每个模型都有自己的标记器。此外,它还有助于为模型准备数据。

from transformers import RobertaTokenizer
roberta_tokenizer = RobertaTokenizer.from_pretrained(“roberta-base”)

注意:代码的最终版本可以在本文末尾找到。

第二部分。数据预处理

在本节中,我们使用分词器对句子或输入数据进行分词。这种模式需要在序列的开头和结尾添加标记,如[SEP]、[CLS]或或~~。~~

def convert_example_to_feature(review):
  return roberta_tokenizer.encode_plus(review,
                                       add_special_tokens=True,
                                       max_length=max_length,
                                       pad_to_max_length=True,
                                       return_attention_mask=True,
  )def encode_examples(ds, limit=-1):
     # prepare list, so that we can build up final TensorFlow dataset from slices.
  input_ids_list = []
  attention_mask_list = []
  label_list = []
  if (limit > 0):
    ds = ds.take(limit)
  for review, label in tfds.as_numpy(ds):
    bert_input = convert_example_to_feature(review.decode())
    input_ids_list.append(bert_input[‘input_ids’])
    attention_mask_list.append(bert_input[‘attention_mask’])
    label_list.append([label])
  return tf.data.Dataset.from_tensor_slices((input_ids_list,
                                             attention_mask_list,
                              label_list)).map(map_example_to_dict)

max_length:这个变量表示句子允许的最大长度。此变量的最大值不应超过 512。

pad_to_max_length:如果为真,标记器在句尾添加[PAD]。

罗伯塔模型需要 3 个输入。

1.input_ids:数据点的序列或索引。

2.attention_mask:它将原词与特殊记号或填充词区分开来。

3.标签:带标签的数据

第三部分。模型训练和微调

Transformers 库在一行代码中加载预训练的 RoBERTa 模型。权重被下载并缓存在本地机器上。我们根据 NLP 任务微调这些模型。

from transformers import TFRobertaForSequenceClassificationmodel = TFRobertaForSequenceClassification.from_pretrained(“roberta-base”)
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate, epsilon=1e-08)
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
metric = tf.keras.metrics.SparseCategoricalAccuracy(‘accuracy’)
model.compile(optimizer=optimizer, loss=loss, metrics=[metric])
model.fit(ds_train_encoded, 
          epochs=number_of_epochs, 
          validation_data=ds_test_encoded, 
          callbacks=[metrics])

使用以下指针微调模型。

1.1e-05 到 1e-06 之间的 learning_rate 变量的值给出了良好的准确度分数。

2.批量的增加提高了准确性,也增加了训练时间。

3.预训练模型不需要在更多的时期上训练。3 到 10 之间的纪元就可以了。

第四部分。准确性、F1 得分并保存模型

准确性分数有助于您检测模型中的偏差和差异。模型的改进主要取决于准确性得分。在平衡数据中使用准确度分数,在不平衡数据中使用 F1 分数。F1 分数告诉我们模型是否平等地学习了所有数据。我们将使用 Keras 回调函数来计算模型的 F1 分数。

class ModelMetrics(tf.keras.callbacks.Callback): def on_train_begin(self, logs={}):
    self.count_n = 1 def on_epoch_end(self, batch, logs={}):
    os.mkdir(‘/create/folder/’ + str(self.count_n))
    self.model.save_pretrained(‘/folder/to/save/model/’ + str(self.count_n))
    y_val_pred = tf.nn.softmax(self.model.predict(ds_test_encoded))
    y_pred_argmax = tf.math.argmax(y_val_pred, axis=1)
    testing_copy = testing_sentences.copy()
    testing_copy[‘predicted’] = y_pred_argmax
    f1_s = f1_score(testing_sentences[‘label’],
                    testing_copy[‘predicted’])
    print(‘\n f1 score is :’, f1_s)
    self.count_n += 1metrics = ModelMetrics()

我们将使用 save_pretrained 方法来保存模型。您可以保存每个历元的模型。我们将保留具有高准确度的模型,并删除其余的。

分析 Reddit 子群的情绪

一旦你完成了 RoBERTa 模型的构建,我们将检测 Reddit 子群的情绪。这些是你完成任务的步骤。

1\. Fetch the comment of the Reddit subgroup. Learn more about how to fetch comments from Reddit here.2\. Check the sentiment of each comment using your RoBERTa model.3\. Count the positive and negative comments of the Reddit subgroup.4\. Repeat the process for different Reddit subgroup.

你可以在这里找到第 1 步和第 2 步的详细解释。我选择了我最喜欢的五个子网格进行分析。我们分析排名前 10 的每周帖子的评论。由于 Reddit API 请求的限制,我限制了评论。

正面和负面评论的数量会给你 Reddit 子群的整体情绪。我已经在代码中实现了这些步骤。你可以在本文末尾找到这段代码。

我最喜欢的 5 个 Reddit 子群的情感分析图。

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

Reddit 子群被他们的版主高度监管。如果你的评论违反了任何子编辑规则,那么 reddit 机器人将删除你的评论。Reddit 机器人不会根据他们的情绪删除评论。但你可以说,大多数负面评论都打破了 subreddit 规则。

结论

在这篇文章中,你可以学习如何发现社交媒体平台 Reddit 的情绪。本文还介绍了情感分析任务的 RoBERTa 模型的构建。在预先训练好的模型的帮助下,我们可以解决很多 NLP 问题。

NLP 领域中的模型正在变得成熟和强大。Huggingface 变形金刚库使得访问这些模型变得非常容易。用不同的配置和任务尝试这些模型。

作者其他文章

  1. EDA 的第一步:描述性统计分析
  2. 路透社文章的文本数据分析和可视化
  3. 为 Reddit Post: TextBlob 和 VADER 自动化情感分析流程

构建 RoBERTa 分类模型的代码

分析 Reddit 子组的代码

发现你下一个最喜欢的餐馆 Yelp 数据集上的探索和可视化

原文:https://towardsdatascience.com/discover-your-next-favorite-restaurant-exploration-and-visualization-on-yelps-dataset-157d9799123c?source=collection_archive---------30-----------------------

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

我为餐馆 X 生成的单词云(你会在这篇文章的结尾找到 X)

你这辈子第一次来到这个城市。

午餐时间到了。你想找一家好的当地餐馆,但不幸的是,你不知道该地区有谁可以推荐你。你现在做什么?

如果你选择继续 Yelp 寻找答案,你不是唯一的一个。

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

乔纳斯·洛伊普Unsplash 上拍摄的照片

作为一个发布关于企业的众包评论的平台,Yelp 可以帮助用餐者进行决策,提供有价值的功能,如餐厅评级、提示和其他用餐者提供的评论。截至 2020 年 3 月,Yelp [1]上有2.11 亿条累积评论。

有了这些海量数据,Yelp 还发布了他们的业务、评论和用户数据的子集,用于教育和学术目的[2]。它还举办了“Yelp 数据集挑战”,为学生提供了一个通过挖掘这些数据进行研究和分析的机会(查看过去几轮获奖者及其论文此处)。

现在我确信你对这个数据集中有什么和我们能发现什么很好奇。事不宜迟,让我们开始探索之旅吧!

古玩目录

  1. 业务数据中有什么?
  2. 餐厅位于哪里?
  3. 哪些餐厅出现率高?他们的评分有可比性吗?
  4. 我们能在餐厅属性中找到什么?
  5. 如何根据我们的需求找到顶级餐厅?
  6. 我们下一步能做什么?

数据集

在这篇文章中,我将通过 Kaggle 探索 Yelp 数据集(此处链接到数据集)。请注意,数据集是在 2020 年 3 月用更新的数据更新的,我的分析是在更新的数据集(截至 2020 年 7 月)上进行的。

该数据集包含 6 个 JSON 文件:

business.json —位置、评级(星级)和属性等业务数据。
review.json —用户评论包括用户 id、商家 id 等。
user.json —用户数据,比如写的评论数、朋友和一些元数据。
checkin.json —签入数据,包括签入 id 和业务 id。
tip.json —用户写的提示,是比较短的评论(一开始我以为这是客户服务后留下的“提示”。对我们的另一个提醒是确保在分析前充分理解数据。
photo.json —包含标题和标签的照片数据。

有关这些文件和数据格式的完整文档,请查看此链接

值得注意的是,这个数据集是 Yelp 拥有的所有数据的一个子集,所以我们在做出任何大胆的结论之前需要注意。这篇文章使用了 business.jsontip.json 文件,我将在以后的文章中使用其他一些文件( review.json 等)。).

要查看我的完整 Python 代码,请查看我的 Kaggle 内核或我的 Github 页面。这篇文章旨在展示分析结果和发现,而不是详细检查代码。

窥视业务数据

因为每个文件都是 JSON 格式的,所以我们需要先把它加载到 DataFrame 中。然后,让我们看看业务数据的维度:

(209393, 14)

有 209393 个业务,14 个属性。

让我们看看有哪些不同的属性:

Index(['business_id', 'name', 'address', 'city', 'state', 'postal_code', 'latitude', 'longitude', 'stars', 'review_count', 'is_open', 'attributes', 'categories', 'hours'], dtype='object')

由于我们最感兴趣的是餐馆,我们需要使用类别列对其进行子集划分。让我们检查一下这一栏中是否有任何缺失的数据:

0.002502471429321897

在该数据集中的所有企业中,只有大约 0.25%的企业缺少类别数据。我们可以在分析中安全地排除这些。之后,让我们再次检查它的形状:

(208869, 14)

Yelp 上有超过 1200 种不同的商业类别。哪个类别的企业数量最多?我们的直觉可能是餐馆。让我们通过条形图快速确认一下:

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

事实上,“餐馆”拥有最多的业务。请注意,每个企业最多可以分为三类[3]。

现在,我们可以将数据集仅划分为餐馆。一个很自然的问题是这些餐馆在哪里?

地理可视化

由于我们事先不知道这些选定餐馆的位置,我们先把它们标在世界地图上:

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

似乎 Yelp 数据集中的所有餐馆都在北美地区。让我们放大一下:

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

所有餐厅都位于美国或加拿大。

让我们找出在这个数据集中餐馆数量最多的城市:

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

多伦多和拉斯维加斯是餐馆数量最多的两个城市。让我们来看看这两个城市中这些餐厅的位置:

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

该地区越明亮,该地区的餐馆就越多。

出现率高的餐厅&评级对比

在该数据集中的所有餐馆中,哪些餐馆比其他餐馆出现的频率高?我们的直觉可能是快餐连锁店。

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

我们的直觉是正确的。注意“地铁餐厅”是“地铁”被命名为两个不同的餐厅,但它们应该是相同的。让我们来解决它:

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

赛百味和麦当劳在前 2 名。注意,总部位于多伦多的 Tim Hortons 也名列前茅。

由于每个单独的餐厅分店都有一个“星级”栏(评分在 1.0 到 5.0 之间,增量为 0.5),我们可以通过并排的方框图来比较这些受欢迎的连锁餐厅分店的评分:

麦当劳 vs 汉堡王

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

有趣的是,他们的评分似乎一点区别都没有。他们的评级中值是 2.0,利差大致相同。中间的 50%(第 25 百分位—第 75 百分位)分支有 1.5 星— 2.5 星。

必胜客 vs 达美乐比萨

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

两相比较,达美乐比萨的评分略高于必胜客。中间 50%的分店的必胜客星级为 1.5-2.5,达美乐比萨星级为 2.0-3.0。

赛百味 vs 吉米·约翰

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

与之前的对比相似,吉米约翰的评分比赛百味略高。位于中间 50%的分店,赛百味为 2.0-3.0 星,吉米约翰为 2.5-3.5 星。

塔可钟 vs 墨西哥烤肉店

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

最后一对比较显示了有趣的结果。与 Chipotle 相比,Taco Bell 的价差更大,IQR 更高(Q3-Q1)。这可能部分是因为 Taco Bell 在这个数据集中比 Chipotle 多了 100 多家餐厅。此外,也可能是 Chipotle 的食品质量和服务更加均衡。请注意,我们看不到 Chipotle 的中线,因为它与其 Q1 或 Q3 重叠。让我们检查它的中值来确认:

3.0

好吧,和 Q3 重叠了。这种重叠的原因是因为 Chipotle 有大量的“3 星”。

通过这些比较,我们可以看到,对于同一家餐厅,不同分店的评分可能会有很大差异(Chipotle 可能是个例外),而且在我们观察的每个比较对中,评分都没有明显的优势。

评论数量和评级之间的关系

除了“stars”属性,还有一个“review_count”属性,表示 Yelp 用户提交的评论数量。让我们创建一个散点图来直观显示评论数和评分之间的关系:

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

我们可以看到,随着评分从 1.0 增加到 4.0,评论的数量也趋于增加。然而,随着评分的进一步增加,尤其是从 4.5 增加到 5.0,评论的数量会减少。

深入了解餐厅属性

该业务数据集中的一列是“属性”,表示商业设施。让我们来看看它们:

Index(['RestaurantsAttire', 'RestaurantsTakeOut', 'BusinessAcceptsCreditCards', 'NoiseLevel', 'GoodForKids', 'RestaurantsReservations', 'RestaurantsGoodForGroups', 'BusinessParking', 'RestaurantsPriceRange2', 'HasTV', 'Alcohol', 'BikeParking', 'RestaurantsDelivery', 'ByAppointmentOnly', 'OutdoorSeating', 'RestaurantsTableService', 'DogsAllowed', 'WiFi', 'Caters', 'Ambience', 'GoodForMeal', 'HappyHour', 'WheelchairAccessible', 'BYOB', 'Corkage', 'DietaryRestrictions', 'DriveThru', 'BusinessAcceptsBitcoin', 'Music', 'BestNights', 'GoodForDancing', 'Smoking', 'BYOBCorkage', 'CoatCheck', 'AgesAllowed', 'RestaurantsCounterService', 'Open24Hours', 'AcceptsInsurance', 'HairSpecializesIn'], dtype='object')

比特币餐馆

这些属性中的大多数都非常简单。我发现“BusinessAcceptsBitcoin”属性很有趣,所以让我们看看这个数据集中有多少家餐馆接受比特币:

False    4245
True       74
Name: BusinessAcceptsBitcoin, dtype: int64

在包含这一属性的 4319 家餐厅中,有 74 家接受比特币。

大衣格子与价格区间的关系

我的直觉是,随着价格区间的扩大,提供衣帽寄存服务的餐厅比例也会增加。

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

价格范围和是否有大衣格子之间的交叉列表(列出的数字是百分比)

请注意,对于价格范围,“1”表示“ ” , “ 2 ”表示“ ”,“2”表示“ ,“2”表示$”等。查看这里Yelp 美元符号和实际价格范围之间的映射。

我们可以看到,当价格范围在 100 美元到 100 美元之间时,几乎没有一家餐馆提供衣帽寄存服务.然而,当价格范围为$ − - $,近一半的餐厅提供 coatcheck。

餐厅外卖与评分的关系

我的直觉是,随着餐馆评分的增加(1.0-3.0),提供外卖的餐馆的百分比也应该增加,随着餐馆评分从 3.0 增加到 5.0,该百分比可能会略有下降。

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

评分和餐厅是否提供送货服务之间的交叉列表

提供外卖服务的餐馆的比例实际上保持不变,与其评级无关。

请注意,在给定的属性和评级/评论数量之间,我们可以研究更多的二元或多元关系!

根据你的需求发现餐馆

假设您想在多伦多找到一家符合以下条件的餐厅:

  1. 评分> 3.5 星
  2. 100 多篇评论
  3. 打开(重要!)
  4. 价格范围为 11-30 美元
  5. 接受外卖服务(#社交距离)
  6. 接受信用卡

假设我们希望看到按评分(第一)和评论数(第二)排序的前 15 家餐馆:

28918                      Ramen Isshin
46423             Fresco's Fish & Chips
49260                           BarChef
37688    Descendant Detroit Style Pizza
4472                         Hodo Kwaja
49245                      Saigon Lotus
27989                           deKEFIR
60497                      Banh Mi Boys
30969           Manpuku Japanese Eatery
16129                       Le Gourmand
2827                White Brick Kitchen
30799                        La Palette
43941           Aoyama Sushi Restaurant
4794                      Mangia & Bevi
4136                          La Cubana

现在你可能在想拉面伊申,以及人们对这家餐厅有什么建议。为此,我们需要查看提示数据。以下是用户在拉面伊申上给出的五个随机提示:

1\. 'Very small place fits about 30 people. They don't quite have a big sign.'
2\. 'Try the soft tofu appetizer! It's quite light but I find it really tasty!'
3\. 'They have a really cool chart in the front of their menu that breaks down each dish!'
4\. 'Order the white sesame ramen! Quite tasty!'
5\. 'By far, the most spacious ramenya in Toronto.'

单词云是一种有趣的方式来可视化文本组中的流行单词/短语。要创建一个,我们需要首先处理原始文本(删除非字母字符/标点符号/停用词等。).点击阅读关于 NLP 文本处理的更多信息。

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

不太喜欢拉面,你更喜欢“弗雷斯科的鱼和薯条”?当然…这里有一些人们给“弗雷斯科炸鱼薯条”的随机提示:

1\. 'Check in for a free drink!!'
2\. 'Add extra fish for only a few dollars, great for sharing!'
3\. 'Ask to add extra piece of fish to order if you don't want too many chips but want two orders; more fish less chips less money. ;)'
4\. 'Use the free drink checking offer!'
5\. 'Sunday! 3 items for just $5! I like the shrimp!'

我们可以看到“入住免费饮料”和“加额外鱼”在这里都被提到了两次。我知道你现在可能在想什么…你是对的。这篇博文的特色图片确实是“Fresco 的鱼&薯条”。

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

接下来

Yelp 数据集有如此多的文本信息,我们在这篇文章中没有涉及。 review.json 文件包含的用户评论比一般的提示长**。这些数据可用于建立情感分析模型。具体来说,问题如下:有可能预测用户基于他们的文本评论给出的餐馆评级(或总体正面/负面情绪)吗?**

点击这里查看我如何使用逻辑回归创建情感分类模型。

总结

我们研究了 Yelp 数据集中的业务数据,并检查了一些快餐连锁店的餐厅评级。然后我们看了看不同的餐馆属性和它们之间的关系。最后,我们通过一个例子来说明如何找到符合我们需求的顶级餐厅,并使用小费数据来创建可视化效果,以帮助我们理解餐厅小费。

我希望你喜欢这篇文章,并请分享你的想法:)

DS/ML 初学者?查看我的另一篇关于如何使用 Iris 数据集构建第一个 Python 分类器的帖子:

** [## 使用 Python Scikit-learn-Iris 数据集探索分类器

如何用 Python 构建第一个分类器的分步指南。

towardsdatascience.com](/exploring-classifiers-with-python-scikit-learn-iris-dataset-2bcb490d2e1b)**

参考

[1]https://www.yelp-ir.com/overview/default.aspx
【2】https://www.yelp.com/dataset
【3】https://blog.yelp.com/2018/01/yelp_category_list

发现 Python3 字符串格式函数的所有魅力

原文:https://towardsdatascience.com/discovering-all-the-charms-in-python3-string-format-function-af07d609c760?source=collection_archive---------32-----------------------

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

照片由克里斯里德Unsplash 拍摄

一个神奇的函数格式化 Python 字符串,给你更多呈现字符串和数字的想法。

由于 Python3 涉及到了[str.format()](https://docs.python.org/3.8/library/stdtypes.html#str.format)函数,我们有了一种更优雅的方式来定义字符串模板,并将变量值作为参数插入到这个函数中。

本文列出了使用该函数的所有不同方式,并展示了我们可以用它做的事情的潜力。

0x01 按位置传递参数

我们需要使用花括号{}作为占位符,然后将格式函数中的参数传递给字符串模板。有许多使用这种技术的方法,如下所列。

如果我们不指定位置,参数将按默认顺序传递。

>>> '{} {} {}'.format('I', 'love', 'Python')
'I love Python'

我们也可以定义位置,实现同样的事情。

>>> '{0} {1} {2}'.format('I', 'love', 'Python')
'I love Python'

在字符串模板中,我们可以自定义位置。

>>> '{1} {0} {2}'.format('love', 'I', 'Python')
'I love Python'

如果format函数中的参数比字符串模板中定义的多,那么多余的参数将被忽略。

>>> '{0} {1} {2}'.format('I', 'love', 'Python', 'yes')
'I love Python'

我们还可以在字符串模板中的特定位置多次使用该参数。当然,这样使用format功能需要明确指定位置。

>>> '{0} {1} {2}. {3} {1}s {2}, too'.format('I', 'love', 'Python', 'She')
'I love Python. She loves Python, too'

0x02 通过键传递参数

与位置号相比,使用文本定义的键会使代码更具可读性。所以,有时你可能想通过键传递参数。

>>> '{subject} {verb} {object}'.format(subject='I', verb='love', object='Python')
'I love Python'

0x03 传递字典

我们可以直接传入一个字典,而不是在format函数中使用“键=值”对,因为它也是“键:值”格式。

>>> dict = {'subject': 'I', 'verb': 'love', 'object': 'Python'}
>>> '{subject} {verb} {object}'.format(**dict)
'I love Python'

0x04 传递列表

在使用format函数将值传递给字符串模板之前,不必从列表中提取值。

>>> l = ['I', 'love', 'Python']
>>> '{0} {1} {2}'.format(*l)
'I love Python'

还可以通过下标访问列表中的元素。

>>> l = ['I', 'love', 'Python']
>>> '{0[0]} {0[1]} {0[2]}'.format(l)
'I love Python'

高级用法:格式化符号

在花括号{}中,我们不仅可以插入位置指示器,还可以插入格式化符号。下表显示了可用的格式化符号。

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

上表完全是用format函数打印出来的,源代码如下。

def table():
 print('|| {:=^15} || {:=^50} ||'.format(' symbols ', ' meanings '))
 print('|| {:<15} || {:<50} ||'.format(':', 'format indicator'))
 print('|| {:<15} || {:<50} ||'.format('-/=\\#', 'filling characters'))
 print('|| {:<15} || {:<50} ||'.format('<', 'left aligned'))
 print('|| {:<15} || {:<50} ||'.format('>', 'right aligned'))
 print('|| {:<15} || {:<50} ||'.format('^', 'centre aligned'))
 print('|| {:<15} || {:<50} ||'.format('10 (number)', 'width'))
 print('|| {:<15} || {:<50} ||'.format(',', 'formating number'))
 print('|| {:<15} || {:<50} ||'.format('.', 'decimal precision'))
 print('|| {:<15} || {:<50} ||'.format('f', 'floating number indicator'))
 print('|| {:<15} || {:<50} ||'.format('b', 'binary number'))
 print('|| {:<15} || {:<50} ||'.format('d', 'decimal number'))
 print('|| {:<15} || {:<50} ||'.format('o', 'octal number'))
 print('|| {:<15} || {:<50} ||'.format('x', 'hex number'))
 print('|| {0:=^15} || {0:=^50} ||'.format(''))

这些格式化符号将在下一节解释。

0x05 填充、对齐和宽度

对准宽度必须一起使用。前者必须是<左对齐、>右对齐或^居中对齐,后者必须是整数。

>>> print('|{:<15}|'.format('left'))
|left           |
>>> print('|{:^15}|'.format('centre'))
|    centre     |
>>> print('|{:>15}|'.format('right'))
|          right|

如果提供了填充字符,上面字符串中的所有空格都将被给定的字符替换。

>>> print('|{:=<15}|'.format('left'))
|left===========|
>>> print('|{:*^15}|'.format('centre'))
|****centre*****|
>>> print('|{:$>15}|'.format('right'))
|$$$$$$$$$$right|

请注意,填充字符可以是任何字符,但只能是一个字符。

0x06 十进制精度

format功能还允许我们指定十进制数的精度。

>>> print('{:.3f}'.format(3.1415926))
3.142

我们甚至可以通过计算直接显示百分比

>>> print('{:.2%}'.format(7/8))
87.50%

0x07 数字格式

我发现format 功能的数字格式化功能还是挺有用的。它可以很容易地在正确的位置添加逗号。

>>> print('{:,}'.format(123456789))
123,456,789

此外,我们可以控制正数和负数的输出格式,以便有更好的表示。

始终显示标志:

>>> print('{:+f}\n{:+f}'.format(100, -100))
+100.000000
-100.000000

在正数前加一个空格,使数字从负数的相同位置开始:

>>> print('{: f}\n{: f}'.format(100, -100))
 100.000000
-100.000000

0x08 基数转换

我们还可以使用format函数快速转换数字的基数。

十进制到二进制:

>>> print('{:b}'.format(100))
1100100

二进制到十进制

>>> print('{:d}'.format(0b1100100))
100

十进制到八进制

>>> print('{:o}'.format(100))
144

十进制到十六进制

>>> print('{:x}'.format(100))
64

0x09 直接将日期时间转换为字符串

通常我们需要使用strftime函数将一个datetime对象转换成特定格式的string类型。但是,如果你只想打印datetime,你可以不使用该功能。

>>> from datetime import datetime
>>> print('{:%d-%B,%Y %A %H:%M:%S}'.format(datetime.now()))
11-March,2020 Wednesday 22:17:44

摘要

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

尼尔斯·斯塔尔在 Unsplash 上拍摄的照片

下面是 Python 中str.format()函数的全部魔力。我希望这能让你在打印或格式化 Python 字符串和数字时有更多的想法。

[## 通过我的推荐链接加入 Medium 克里斯托弗·陶

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

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

发现数学思维

原文:https://towardsdatascience.com/discovering-mathematical-mindset-d856ec63c21a?source=collection_archive---------40-----------------------

数据科学是如何帮助我养成数学态度的!

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

照片由乔恩·泰森Unsplash 拍摄

或者许多人认为,数学灌输了恐惧、仇恨、厌倦或者至少是某种程度的冷漠。这是一个很难理解的话题。人们很容易联想到诗歌、文学、音乐、法律或历史。但是数学在很大程度上被认为是神秘的,没有灵魂的。上面这张照片抓住了这种感觉:“美术比数学重要”。但是我倾向于不同意因为我相信数学也是一门艺术

这篇文章试图从新的角度来看待数学。

让我们从最基本的开始。

什么是数学?

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

照片由 Antoine DautryUnsplash 上拍摄

有人会说数学是对数字的研究。其他人可能会将其描述为一套用于计数和测量的技术/函数/方程。数学是一门你必须找到解决问题的方法的学科。你被要求解代数方程并计算出 x 的值。你学习处理微分、积分、极限、概率、三角函数、向量微积分等等。我们可以学习如何做到这一点,我们中的许多人甚至在考试中取得好成绩。然而,有很多人对这整个练习感到超脱。做这件事有什么意义?这到底意味着什么?数学方程式或数学公式代表什么?

这些都是重要的问题。要回答这个问题,我们必须深入一点。让我们闭上眼睛, 思考 讲述 学习 ,总的来说。

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

照片由安特·哈默斯特Unsplash 上拍摄

当你观察到一种现象并认识到一种模式时,学习就发生了。你试图通过发现现象中涉及的实体之间是否有任何关系来理解这种模式。

花点时间。你会意识到,对任何事物的任何一种理解或知识,都不过是对模式的识别和解释。想想农业、季节变化、行星运动、生命进化、化学反应、股票市场分析、心理学研究、临床试验、药物开发…几乎每一个对知识的追求都包括对某种模式的识别。(查看此)

如果你同意………请继续阅读。

一旦模式被识别出来,它就必须被表达出来。人类使用“语言”、“符号”和“图画”来表达、描述和交流思想和认识。

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

乔尔·那仁Unsplash 上拍摄的照片

例如,如果我们必须描述“民主”的概念,我们可以用英语来解释。在维基百科上你可以找到如下描述:

D emocracy ( 希腊语 : δημοκρατία, dēmokratiā ,来自dēmos‘人民’和‘统治’)是政府的一种形式,其中人民拥有权力来选择他们的统治立法

如果非要描述如何从一个城市到达另一个城市,可以画一张 地图 来表达。仅使用文本不太适合表达这个想法。

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

来源:谷歌地图

现在,自然界中有许多模式或想法是抽象的。比方说,你有两个橘子放在一个篮子里,三个香蕉放在另一个篮子里。你总共有多少水果?你可以把 2 加 3 得到 5,也可以把 3 加 2 得到 5。顺序不重要。实际上这是 加法交换律 它可以用英语表达为:

当两个数相加时,数字的顺序不起任何作用。

然而,表达上述想法的更有效的方式是:

P + Q = Q + P

关于数学的伟大思想来了

数学是表达“模式”的语言之一。

对于什么样的模式,应该使用数学?

更正式或更抽象的模式,可以用数学语言高效地表达出来。

例如,如果一个人以某个恒定的速度驾驶一辆汽车,在行驶距离、他的速度和驾驶的总时间之间是否存在关系或模式。

是的,有一种模式可以用英语表达如下:

“司机行驶的距离总是等于他的速度乘以他行驶的时间”。

这种解释是正确的,但如果我们用数学符号和运算来表达它,会更有用,如下所示:

距离=速度*时间

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

T

数学上,我们可以说,如果速度不变,距离和时间之间存在线性关系。和学校里教的直线方程比较一下。

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

在我们的例子中,直线穿过原点,因此 b=0。在时间 0,没有距离被覆盖。速度是“斜率”,即我们线的米数)

现在,为什么数学表达式更有用?这是因为它抓住了现象背后的“广义”概念。自然界中任何存在线性关系的现象都可以用直线的形式来表达,我们可以通过遍历这条线来预测未来的值。

[这就是线性回归在很高的水平上]

新的视角

S 顶级思维数学作为一门解决问题的学科。开始把它当成一种语言——一种表达自然界模式的语言。

“数学是上帝书写宇宙的语言”——伽利略·伽利雷

不同类型的模式导致不同的数学分支:

  1. 形状的模式:几何
  2. 运动和变化的模式:微积分
  3. 位置模式:拓扑
  4. 机会模式:概率
  5. 推理模式:逻辑

一旦你开始认为数学是一种模式语言,你就可以开始从不同的思维模式来看待方程。可以把一个等式看作是该模式的表达式。试着想象这个等式想要表达的模式。就当是故事情节,人物之间有关系。

先说一个基本形状:

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

圆心在原点(0,0)的圆的数学公式为:

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

现在想想这个等式表达的模式。

“圆上的每一点离圆心的距离都是一样的”。

实际上,这种模式使它成为一个圆。一个形状的每一点到一个固定点的距离都相等,这个形状就是圆。它不能是矩形或三角形或任何其他形状。只有圆圈遵循这种模式。这是知识或学习,上面的等式是想说!有没有其他的方式,可以表达这种模式?

用世界上任意一个圆的直径除以圆周!你将总是得到一个常数’ 𝜋’(大约 3.14159)

这是描述圆背后图案的另一种方式。任何数学公式中只要有一个圆圈,就会有 𝜋.

**圆的面积,**球体的体积,圆柱体的体积:

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

当然,你可以推导出这些公式的证明,但我试图传达的基本思想是,它们背后有一个共同的模式——“圆形”——因此有了 𝜋

让我们更进一步。以前,我把圆形(或球形)称为基本形状。如果你认为,这是自然界中最丰富的形状(可能不是完美的圆形或球形,但仍然足够接近),像行星和其他天体的形状,气泡,雨滴,原子,行星的旋转和公转,星系的形状等

自然界中存在一种基本模式吗?我认为有。而这个基本模式就是“重复”。有许多重复的自然现象。例如地球(行星)绕轴旋转、行星绕恒星公转、整个星系公转、电子绕原子核运动、季节变化、波浪起伏、光合作用等生物化学循环等等。(人说历史也是重演的。😎)

你看出其中的联系了吗?

这里的想法是,任何遵循重复模式的现象,都可以被认为是一个圆或圆的一部分。因此在其数学形式的某个地方, 𝜋将找到一个位置。

所以现在,每当你看到一个带有 **𝜋的数学公式或方程,**就想到一个圆,然后思考这个方程试图表达的现象中是否有任何重复。您将看到一个连接。

一些例子:

单摆的时间周期:

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

来源:维基百科

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

有“反复”的议案!

开普勒行星运动第三定律:

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

它捕捉了行星离太阳的距离和它们的轨道周期之间的关系。(轨道是“松散的”圆形。行星“反复”围绕太阳转)

库仑电力定律:

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

电荷周围的电场遵循圆形轨迹。

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

来源:维基百科

…….你可以找到更多。当然,所有这些过程背后的实际数学和物理学比这里定义的要复杂得多。但我所建议的是从一个不同的心态来看待这些方程式或公式。哪里有 𝜋,哪里就会有圆圈(重复)的存在

正如 𝜋 对于循环模式,自然界中还有其他模式可以被概括。例如,任何涉及指数增长或下降的现象几乎总是可以用“e”来表示。想想放射性衰变或人口增长,或新冠肺炎感染人数的增加,或你银行的复利。(亲爱的读者,我将把它留在这里让你思考这些模式)

这与机器学习和数据科学有什么关系?

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

照片由亨特·哈里特Unsplash 拍摄

数据科学和机器学习是用来模仿人类学习的领域。目标是自动发现数据中“模式”并建立输出变量和输入变量之间的关系。表达这种关系的最好方式是什么?如前所述,数学是表达这种形式关系的最佳语言。

像线性/逻辑回归或神经网络这样的机器学习算法使用线性代数和概率定理。ML 模型的成本优化采用微积分。单词和句子嵌入使用向量演算。所以,下次你实现任何机器学习算法的时候,想想为什么要使用特定的数学方法或函数,你想找出什么模式?

和所有自然循环一样,我将 重复 (双关语):

数学是表达模式的语言。数学方程式或公式只是该模式的模型或解释。

发现新数据

原文:https://towardsdatascience.com/discovering-new-data-9be5ae5787ca?source=collection_archive---------28-----------------------

使用 Explorium 和 Python 通过几个简单的步骤发现数据。

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

Héizel Vázquez 插图

当你在数据科学领域工作时,最困难的部分之一是发现在试图解决业务问题时使用哪些数据。

请记住,在试图获得数据来解决问题之前,您需要了解业务和项目的背景。我所说的背景是指所有关于公司如何运作其项目、公司如何建立、其竞争对手、有多少部门、他们有不同的目标和目的,以及他们如何衡量成功或失败的细节。

当你拥有了所有这些,你就可以开始考虑获取解决业务问题所需的数据了。在本文中,我不会过多地谈论数据收集,相反,我想讨论并向您展示用新数据丰富您已有数据的过程。

请记住,获取新数据必须以系统的方式进行,而不仅仅是凭空获取数据,我们必须始终如一地做这件事,规划它,创建一个流程来做这件事,这取决于工程、架构师、数据运营以及我将在其他文章中讨论的更多内容。

设置环境

在本文中,我们将使用三种工具:Python、GitHub 和 Explorium。如果你想了解更多关于探索博物馆的信息,请点击这里:

[## 数据在哪里?

或者如何丰富数据集并自动创建新要素。

towardsdatascience.com](/where-is-the-data-798faccb4e29)

让我们从创建一个新的 git repo 开始。我们将在这里存储我们的数据、代码和文档。转到您的终端,创建一个新文件夹并移到那里:

mkdir data_discovery
cd data_discovery

然后初始化 git repo:

git init

现在让我们在 GitHub 上创建一个远程回购:

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

现在转到您的终端并键入(将 URL 改为您的):

git remote add origin [https://github.com/FavioVazquez/data_discovery.git](https://github.com/FavioVazquez/data_discovery.git)

现在让我们检查一下:

git remote -v

您应该看到(当然是您自己的 URL):

origin [https://github.com/FavioVazquez/data_discovery.git](https://github.com/FavioVazquez/data_discovery.git) (fetch)
origin [https://github.com/FavioVazquez/data_discovery.git](https://github.com/FavioVazquez/data_discovery.git) (push)

现在让我们开始一个自述文件(我正在使用 Vim ):

vim Readme.md

你想在里面写什么都行。

现在让我们将文件添加到 git:

git add .

并创建我们的第一个提交:

git commit -m "Add readme file"

最后,让我们把这个推给我们的 GitHub repo:

git push --set-upstream origin master

此时,您的回购应该如下所示:

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

寻找数据

我们来找一些数据。我不打算在这里做理解数据、探索数据、建模或类似事情的整个数据科学过程。我只是去找一些有趣的数据给你做个演示。

对于这个例子,我们将从一些企业的 YELP 评论中探索数据。数据最初在 Kaggle 上:

https://www.yelp.com/dataset/challenge

但是我在这里使用的是来自的 CSV 数据集。我使用的 CSV 文件叫做“yelp_reviews_RV_categories.csv”

让我们将它添加到 git 中:

git add .
git commit -m "Add data"
git push

我们将从加载 Pandas 上的数据并执行基本 EDA 开始:

from pandas_profiling import ProfileReport
profile = ProfileReport(df, title="Pandas Profiling Report")
profile

这将为您提供一份全面的数据报告,如下所示:

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

使用 Explorium 获取更多数据

太好了,现在该去探索博物馆了。要了解更多关于 Explorium 的信息,请点击此处:

[## 增强数据科学平台|探索

自动连接到数以千计的源,并发现 Explorium 正在驱动的精确模型的功能…

hubs.ly](https://hubs.ly/H0r3HMF0)

让我们创建一个新项目:

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

命名项目后,您应该从本地机器添加数据。我们将添加我们的主数据集。你会看到这样的东西:

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

您可以在下面的浏览栏中获得关于 Explorium 上的专栏的更多基本信息:

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

我们拥有的数据包含关于特定企业的信息,比如它的位置(城市、州、邮政编码)、它的名称、类别,以及关于它的评论者的数据。但是我们想知道更多。关于生意的更多信息。我们将首先将所有我们不关心的信息列入黑名单:

  • 用户标识
  • 文本

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

现在,让我们试着获得更多关于这个数据集的信息。Explorium 现在会要求您预测一些能够运行的东西,我们实际上不想预测任何东西,但让我们把一些东西放进去,这样它就能运行(我们将使用“星星”作为目标):

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

以星星为目标

当我们单击“播放”时,系统将开始收集有关数据集的信息。我们必须在这里等。在这一点上,系统不仅从外部来源引入新数据,还基于我们现有的列创建新功能。我们现在不使用它,但是在下一篇关于特性工程的文章中,它将是重要的。

几分钟后,我看到了这个屏幕:

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

这意味着 Explorium 找到了 102 个可以补充我的原始数据的数据集,最终,它从我的数据和外部来源创建/获取了 3791 列。请记住,我们有兴趣找到有关业务的更多信息,所以我将从外部数据集中挑选一些列,并将它们添加到我的原始数据中。

这是丰富数据的实际过程。正如你所看到的,系统可以告诉你前 50 个特征是什么,但是关于什么呢?如果你记得我们试图从其他列中“预测”星星,那么它告诉你的是这 50 或 100 个特征对我们选择的目标有一些预测能力。

您实际上可以获得关于感兴趣的特定列的更多信息。

让我们从最基本的开始。获取企业网站。为此,我将使用数据集:搜索引擎结果:

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

如果你点击箭头,你将下载它。之后,你可以把它装在熊猫身上:

# search engine
search = pd.read_csv("Search  Engine  Results.csv")

正如您将看到的,我们有许多缺失的数据,但这在您进行数据充实时是正常的。太好了,让我们选择公司的网站:

search[["name", "Company Website"]]

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

你看到的是给定名称的最有可能是某个特定企业的网页。很酷吧?

各商家周边的暴力犯罪数量呢?为此,我将使用“美国犯罪统计”数据集:

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

我们将使用不同的方法下载这些数据。我希望直接显示暴力犯罪,因此在我的要素部分,在按犯罪数据集过滤后,我将只选择暴力犯罪:

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

然后单击下载。让我们在 Python 上看看:

crimes[["name","violent_crime"]].dropna().drop_duplicates()

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

就像这样,你知道你有多少具体的商店暴力犯罪。创建这个变量的实际过程相当复杂。要了解更多信息,请访问 Explorium 并在选择变量时单击了解更多:

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

在“要素来源”部分,您可以看到它是如何创建的以及来自哪些数据源:

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

如你所见,这个过程并不那么简单,但是系统已经在为你做了,这太棒了:)

您可以对系统为您收集或创建的每一个变量都这样做,这样,您就可以完全控制整个过程。

更多数据

如果你记得我们把“星星”列为预测。尽管我们对此不感兴趣,但 Explorium 尽了最大努力来获取预测该列的数据。在以后的文章中,我将使用该工具创建整个项目,这样您就可以看到全貌了。

现在,我们可以选择最好的 50 个特征来预测我们选择的“测试”变量。为此,我们转到引擎选项卡并选择功能:

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

我们将仅从系统收集和创建的 3791 个变量中获得最佳的 50 个变量。然后我们会像以前一样下载它们。默认情况下,我们下载的数据集名为“all_features.csv”。让我们将它载入我们的 EDA 笔记本:

data = pd.read_csv("all_features.csv")

这些是我们的栏目:

['name',
 'address',
 'latitude',
 'longitude',
 'categories',
 'review_stars',
 'KNeighbors(latitude, longitude)',
 'review_stars.1',
 '"rv" in categories',
 'KNeighbors(Latitude, Longitude)',
 '"world" in Results Snippets',
 '"camping" in Results Snippets',
 '"camping" in Title of the First Result',
 '"camping" in Results Titles',
 '"world rv" in Results Titles',
 '"motorhomes" in Results Snippets',
 '"campers" in Results Snippets',
 '"accessories" in Results Titles',
 '"rated based" in Results Snippets',
 '"parts accessories" in Results Snippets',
 '"5th wheels" in Results Snippets',
 '"sale" in Results Titles',
 '"based" in Results Snippets',
 '"service center" in Title of the First Result',
 '"rvs" in Results Titles',
 '"buy" in Results Snippets',
 '"dealer" in Results Titles',
 '"inventory" in Results Snippets',
 '"travel" in Results Titles',
 'KNeighbors(LAT, LONG)',
 'Number of Related Links',
 'day(Website Creation Date)',
 'month(Website Creation Date)',
 '"service" in Website Description',
 'year(Website Creation Date)',
 'Percentile',
 'Number of Website Subdomains',
 '"rv" in Website Description',
 'MedianLoadTime',
 '"camping" in Website Description',
 '"buy" in Website Description',
 '"rv dealer" in Title',
 '"dealer" in Title',
 'Number of Connections to Youtube',
 '"trailers" in Website Description',
 'month(Domain Update Date)',
 'Domain Creation Date - Domain Update Date',
 'Domain Creation Date - Domain Expiry Date',
 'Stopword Count(Associated Keywords)',
 '"pinterest instagram" in Social Networks',
 'Number of Social Networks',
 '"facebook" in Social Networks',
 'Year of Establishment',
 'AdultContent->False',
 'AdultContent->empty',
 'Results From Facebook->False',
 'Results From Facebook->True',
 'Url Split(Company Website).company_website_10->empty',
 'Url Split(Company Website).company_website_10->utm_campaign=Yext%20Directory%20Listing',
 'Url Split(Company Website).company_website_10->utm_medium=organic',
 'Url Split(Company Website).company_website_10->utm_source=moz',
 '_TARGET_']

如你所见,我们有非常不同的数据,但当然很有趣。我现在不打算做更多的事情,因为我的想法是向您展示如何为您已经拥有的数据获取更多的数据,但同样,我将创建完整的项目,在其中我将遵循整个数据科学过程。

结论

我们可以看到,这个过程非常简单和直观,如果您不需要建模,您可以保留新数据并自己工作。如果您将这种类型的软件与对业务的良好理解和有效的数据科学方法相结合,您将更快地震撼数据科学世界。

请务必查看他们的网页了解更多信息:

[## 增强数据科学平台|探索

自动连接到数以千计的源,并发现 Explorium 正在驱动的精确模型的功能…

hubs.ly](https://hubs.ly/H0r3HMF0)

感谢阅读:)

通过探索性数据分析发现数据中的模式

原文:https://towardsdatascience.com/discovering-patterns-in-data-with-exploratory-data-analysis-fd07ce1c5efa?source=collection_archive---------34-----------------------

使用 Pandas、Seaborn 和 Plotly 对 SAT 和 ACT 数据的可视化探索

探索性数据分析(EDA)由 John W. Tukey 于 1977 年首次描述,指的是探索数据以了解变量之间的关系、检测异常并了解变量是否满足统计推断的假设的过程。EDA 是一个非常强大的工具,可以发现数据中的模式,并促进新的研究问题的发展。在这篇文章中,我将描述我如何使用 EDA 来揭示数据集中的趋势,以及这些趋势如何帮助我制定和回答一个研究问题。

背景

该项目是作为大会数据科学沉浸式训练营的一部分完成的。这个项目的目标是使用 EDA 来揭示 SAT 和 ACT 数据的趋势,以便为数据科学问题提出建议。对于这个项目,我收到了六个数据集,提供了 2017 年、2018 年和 2019 年各州的 SAT 和 ACT 数据。数据集中的变量包括各州的平均分数和平均参与率。为了准备 EDA,我清理了数据,并将所有六个数据集合并到一个 51 行 23 列的 Pandas 数据框架中。数据帧的部分报头如下所示。

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

显示 2017 年 SAT 和 ACT 数据的标题

探索性数据分析

作为我的 EDA 的一部分,我创建了几个数字来调查 SAT 和 ACT 的参与率趋势。我最感兴趣的是 SAT 和 ACT 参与率如何随时间和地理位置而变化。

为了探索参与率随时间的变化趋势,我使用 Seaborn 和 Matplotlib 为每个测试和年份创建了箱线图。比较参与率的分布让我不仅了解了平均参与率是如何随着时间变化的,还了解了分布的方差是如何变化的。

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

使用 Matplotlib 和 Seaborn 创建的箱线图。从这个图中,我们可以看到,SAT 参与率中位数从 2017 年的 38%上升到 2019 年的 54%。此外,第三个四分位数(第 75 个百分位数)的参与率从 2017 年的 66%上升到 2019 年的 82%。

从上面的图中,我注意到从 2017 年到 2019 年,SAT 参与人数中位数有增加的趋势。

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

使用 Matplotlib 和 Seaborn 创建的箱线图。从这个图中,我们可以看到中位数 ACT 参与率从 2017 年的 69%下降到 2019 年的 54%。此外,第一个四分位数(第 25 个百分位数)的参与率从 2017 年的 31%下降到 2019 年的 25%。

上面的方框图开始说明 2017 年至 2019 年 ACT 和 SAT 参与率的全国趋势。越来越多的州开始增加 SAT 的参与率,而 ACT 的参与率则有所下降。

当我研究这些数据时,我还使用 Plotly 创建了各州 SAT 和 ACT 参与率的 choropleth 图。如下所示,这些图表明,2017 年,除密歇根州和印第安纳州外,沿海各州的 SAT 参与率最高,而 ACT 参与率在中部各州占主导地位。

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

使用 Plotly 创建的 Choropleth 地图。这张地图显示,东部和西部海岸的 SAT 参与率最高。

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

使用 Plotly 创建的 Choropleth 地图。这张地图显示,在美国中部,青蒿素综合疗法的参与率较高。

考虑到我用箱线图揭示的参与率的时间趋势和用 choropleth 图说明的参与的地理差异,形成了一个研究问题。因为大多数中西部州在基线(2017 年)时表现出较低的 s at 参与率,所以我决定探索中西部在 2017 年至 2019 年期间是否也经历了 SAT 参与率中位数的整体增长。

首先,我创建了一个只包含中西部各州(伊利诺伊州、印第安纳州、爱荷华州、堪萨斯州、密歇根州、明尼苏达州、密苏里州、内布拉斯加州、北达科他州、俄亥俄州、南达科他州和威斯康星州)数据的 Pandas 数据框。从那里,我能够使用 Seaborn 和 Matplotlib 创建一个方框图,以查看 2017 年至 2019 年 SAT 参与的分布情况。如下图所示,虽然参与率的差异从 2017 年到 2019 年有所增加,但 SAT 参与率的中位数在三年期间保持相似。对数据的进一步研究显示,2017 年至 2018 年差异的增加主要是由于伊利诺伊州和俄亥俄州 SAT 参与率的增加。

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

使用 Plotly 创建的 Choropleth 地图。从这张地图中,我们可以看到,尽管伊利诺伊州和俄亥俄州的 SAT 参与率在 2017 年至 2019 年期间有所增长,但大多数中西部州的 SAT 参与率并没有增长。

结论

这个项目展示了 EDA 在揭示数据趋势方面的能力,这些数据可以在以后用于产生一个研究问题。通过使用 Matplotlib、Seaborn 和 Plotly 创建的简单图,我能够发现从 2017 年到 2019 年 SAT 参与率的增长趋势以及中西部各州在基线(2017 年)对 ACT 的地理偏好。综合来看,这些见解激励我调查 SAT 参与率的上升趋势是否也在中西部各州出现。仅用六个简单的图表(只有两种类型),我就能确定一个研究问题并寻求答案。想象一下用 EDA 你能发现什么样的洞察力!

使用双深度 Q 学习构建改进的末日智能体

原文:https://towardsdatascience.com/discovering-unconventional-strategies-for-doom-using-double-deep-q-learning-609b365781c4?source=collection_archive---------37-----------------------

Pytorch 中强化学习的实现。

简介

O 在过去的几篇文章中,我们已经讨论了 VizDoom 游戏环境中实现了 深度 Q 学习 (DQN)并测试了它的性能。深度 Q-learning 是一种高度灵活且响应迅速的在线学习方法,它利用场景内的快速更新来估计环境中的状态-动作(Q)值,以便最大化回报。Q-learning 可以被认为是一种策略外的 TD 方法,其中该算法旨在选择独立于当前遵循的策略的最高值的状态-动作对,并且已经与 OpenAI Atari 健身房环境的许多原始突破相关联。

我们的香草 DQN 代理的游戏性,训练超过 500 集。

然而,DQN 倾向于乐观地高估 Q 值,特别是在训练的初始阶段,导致次优动作选择的风险,因此收敛较慢。为了理解这个问题,回想一下 Q 学习更新方程,该方程利用当前状态奖励和最高值的状态-值对来估计当前状态的 Q 值,该 Q 值用于训练 DQN。

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

q-学习更新。

请注意,误差项中存在一个 TD-target,它由当前奖励和最高值的状态-动作对的 Q 值之和组成,与代理的当前策略无关,因此,Q-学习通常被称为非策略 TD 学习。

因此,Q-learning 依赖于为下一个状态选择具有最高值的动作的“远见”。但是我们怎么能确定下一个状态的最佳行动是具有最高 Q 值的行动呢?根据定义,Q 值的准确性取决于我们之前探索过的状态动作。因此,在训练开始时计算的 Q 值的准确性往往是不准确的,因为我们还没有完全探索状态-动作空间。在这种状态下取最大 Q 值可能会选择一个次优的行动,阻碍收敛。由于 TD 目标计算和行动选择是在同一个网络中进行的,这一事实加剧了这一问题,这可能会导致对次优行动选择的强化偏向。

为了解决这个问题,双深度 Q 学习(DDQN)首先由 Van Hasselt 等人引入。a1 通过使用两个网络将动作选择与 Q 值目标计算步骤分离。我们可以通过将 TD 目标的 Q 值部分重写为两个部分来实现这一点,如下所示:

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

在特定的时间步长和状态,我们使用我们的 DQN 网络为我们的下一个状态选择具有最高 Q 值的动作。然后使用目标网络来计算在下一个状态采取该行动的 Q 值,然后将其与当前状态行动的奖励相结合,以形成 TD 目标。网络定期对称更新。

因此,DDQN 可以减少 Q 值高估,从而确保稳定的学习和更快的收敛。

在我们的上一篇文章中,我们探索了如何通过使用开源的 OpenAI gym 包装库 Vizdoomgym ,将深度 Q-learning 应用于训练代理在经典 FPS 游戏 Doom 中扮演一个基本场景。我们将在那篇文章的基础上修改我们的方法,在 Pytorch 中加入 DDQN 架构。

实施

**我们将在与上一篇文章相同的 VizDoomgym 场景中实现我们的方法,*保卫防线,*使用相同的多目标条件。**环境的一些特征包括:

  • 一个 3 的动作空间:开火,左转,右转。不允许扫射。
  • 向玩家发射火球的棕色怪物,命中率为 100%。
  • 试图以之字形靠近来咬玩家的粉红色怪物。
  • 重生的怪物可以承受更多伤害。
  • 杀死一个怪物+1 点。
  • -死了得 1 分。

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

“防线方案”的初始状态

回想一下,在我们最初的 DQN 实现中,我们已经利用了两个并发网络——一个用于行动选择的评估网络,以及一个定期更新的目标网络,以确保生成的 TD 目标是固定的。我们可以利用这个现有的设置来构建我们的 DDQN 架构,而无需初始化更多的网络。

请注意,由于两个网络定期更新彼此的权重,因此这两个模型仍然是部分耦合的,但重要的是,动作选择和 Q 值评估是由在特定时间步长不共享同一组 a 权重的独立网络完成的。

我们的 Google 协作实现是利用 Pytorch 用 Python 编写的,可以在 GradientCrescent Github 上找到。我们的方法基于泰伯优秀强化学习课程中详述的方法。由于我们的 DDQN 实现类似于我们之前的普通 DQN 实现,所以整个高级工作流是共享的,这里不再重复。

让我们从导入所有必需的包开始,包括 OpenAI 和 Vizdoomgym 环境。我们还将安装火炬视觉所需的 AV 包,我们将使用它进行可视化。请注意,安装完成后必须重新启动运行时。

#Visualization cobe for running within Colab
!sudo apt-get update
!sudo apt-get install build-essential zlib1g-dev libsdl2-dev libjpeg-dev nasm tar libbz2-dev libgtk2.0-dev cmake git libfluidsynth-dev libgme-dev libopenal-dev timidity libwildmidi-dev unzip# Boost libraries
!sudo apt-get install libboost-all-dev# Lua binding dependencies
!apt-get install liblua5.1-dev
!sudo apt-get install cmake libboost-all-dev libgtk2.0-dev libsdl2-dev python-numpy git
!git clone [https://github.com/shakenes/vizdoomgym.git](https://github.com/shakenes/vizdoomgym.git)
!python3 -m pip install -e vizdoomgym/!pip install av

接下来,我们初始化我们的环境场景,检查观察空间和动作空间,并可视化我们的环境…

#Check the environment. You'll need to restart the runtime for it to work
import gym
import vizdoomgym

env = gym.make('VizdoomCorridor-v0')# use like a normal Gym environment
state = env.reset()
state, reward, done, info = env.step(env.action_space.sample())
print(state.shape)
# env.render()
env.close()

接下来,我们将定义预处理包装器。这些类继承自 OpenAI gym 基类,覆盖了它们的方法和变量,以便隐式地提供所有必要的预处理。我们将开始定义一个包装器来重复许多帧的每个动作,并执行元素方式的最大值以增加任何动作的强度。您会注意到一些三级参数,如 fire_firstno _ ops——这些是特定于环境的,在 Vizdoomgym 中对我们没有影响。

class RepeatActionAndMaxFrame(gym.Wrapper):
  #input: environment, repeat
  #init frame buffer as an array of zeros in shape 2 x the obs space
    def __init__(self, env=None, repeat=4, clip_reward=False, no_ops=0,
                 fire_first=False):
        super(RepeatActionAndMaxFrame, self).__init__(env)
        self.repeat = repeat
        self.shape = env.observation_space.low.shape
        self.frame_buffer = np.zeros_like((2, self.shape))
        self.clip_reward = clip_reward
        self.no_ops = no_ops
        self.fire_first = fire_first def step(self, action):
        t_reward = 0.0
        done = False
        for i in range(self.repeat):
            obs, reward, done, info = self.env.step(action)
            if self.clip_reward:
                reward = np.clip(np.array([reward]), -1, 1)[0]
            t_reward += reward
            idx = i % 2
            self.frame_buffer[idx] = obs
            if done:
                break max_frame = np.maximum(self.frame_buffer[0], self.frame_buffer[1])
        return max_frame, t_reward, done, info def reset(self):
        obs = self.env.reset()
        no_ops = np.random.randint(self.no_ops)+1 if self.no_ops > 0    else 0
        for _ in range(no_ops):
            _, _, done, _ = self.env.step(0)
            if done:
                self.env.reset()

        if self.fire_first:
            assert self.env.unwrapped.get_action_meanings()[1] == 'FIRE'
            obs, _, _, _ = self.env.step(1) self.frame_buffer = np.zeros_like((2,self.shape))
        self.frame_buffer[0] = obs return obs

接下来,我们为我们的观察定义预处理函数。我们将使我们的环境对称,将它转换到盒子空间,将通道整数交换到张量的前面,并将其从原始(320,480)分辨率调整到(84,84)区域。我们也将我们的环境灰度化,并通过除以一个常数来归一化整个图像。

class PreprocessFrame(gym.ObservationWrapper):
  #set shape by swapping channels axis
 #set observation space to new shape using gym.spaces.Box (0 to 1.0)
    def __init__(self, shape, env=None):
        super(PreprocessFrame, self).__init__(env)
        self.shape = (shape[2], shape[0], shape[1])
        self.observation_space = gym.spaces.Box(low=0.0, high=1.0,
                                    shape=self.shape, dtype=np.float32) def observation(self, obs):
        new_frame = cv2.cvtColor(obs, cv2.COLOR_RGB2GRAY)
        resized_screen = cv2.resize(new_frame, self.shape[1:],
                                    interpolation=cv2.INTER_AREA)
        new_obs = np.array(resized_screen, dtype=np.uint8).reshape(self.shape)
        new_obs = new_obs / 255.0 return new_obs

接下来,我们创建一个包装器来处理帧堆叠。这里的目标是通过将几个帧堆叠在一起作为单个批次,帮助从堆叠帧中捕捉运动和方向。这样,我们可以捕捉环境中元素的位置、平移、速度和加速度。通过堆叠,我们的输入采用(4,84,84,1)的形状。

class StackFrames(gym.ObservationWrapper):
  #init the new obs space (gym.spaces.Box) low & high bounds as repeat of n_steps. These should have been defined for vizdooom

  #Create a return a stack of observations
    def __init__(self, env, repeat):
        super(StackFrames, self).__init__(env)
        self.observation_space = gym.spaces.Box( env.observation_space.low.repeat(repeat, axis=0),
                              env.observation_space.high.repeat(repeat, axis=0),
                            dtype=np.float32)
        self.stack = collections.deque(maxlen=repeat) def reset(self):
        self.stack.clear()
        observation = self.env.reset()
        for _ in range(self.stack.maxlen):
            self.stack.append(observation) return  np.array(self.stack).reshape(self.observation_space.low.shape) def observation(self, observation):
        self.stack.append(observation) return np.array(self.stack).reshape(self.observation_space.low.shape)

最后,在返回最终环境供使用之前,我们将所有的包装器绑定到一个单独的 make_env() 方法中。

def make_env(env_name, shape=(84,84,1), repeat=4, clip_rewards=False,
             no_ops=0, fire_first=False):
    env = gym.make(env_name)
    env = PreprocessFrame(shape, env)
    env = RepeatActionAndMaxFrame(env, repeat, clip_rewards, no_ops, fire_first)

    env = StackFrames(env, repeat) return env

接下来,让我们定义我们的模型,一个深度 Q 网络。这基本上是一个三层卷积网络,它采用预处理的输入观察值,将生成的展平输出馈送到一个全连接层,生成将游戏空间中的每个动作作为输出的概率。请注意,这里没有激活层,因为激活层的存在会导致二进制输出分布。我们的损失是我们当前状态-动作的估计 Q 值和我们预测的状态-动作值的平方差。我们将使用 RMSProp 优化器来最小化我们在训练期间的损失。

import os
import torch as T
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as npclass DeepQNetwork(nn.Module):
    def __init__(self, lr, n_actions, name, input_dims, chkpt_dir):
        super(DeepQNetwork, self).__init__()
        self.checkpoint_dir = chkpt_dir
        self.checkpoint_file = os.path.join(self.checkpoint_dir, name) self.conv1 = nn.Conv2d(input_dims[0], 32, 8, stride=4)
        self.conv2 = nn.Conv2d(32, 64, 4, stride=2)
        self.conv3 = nn.Conv2d(64, 64, 3, stride=1) fc_input_dims = self.calculate_conv_output_dims(input_dims) self.fc1 = nn.Linear(fc_input_dims, 512)
        self.fc2 = nn.Linear(512, n_actions) self.optimizer = optim.RMSprop(self.parameters(), lr=lr) self.loss = nn.MSELoss()
        self.device = T.device('cuda:0' if T.cuda.is_available() else 'cpu')
        self.to(self.device) def calculate_conv_output_dims(self, input_dims):
        state = T.zeros(1, *input_dims)
        dims = self.conv1(state)
        dims = self.conv2(dims)
        dims = self.conv3(dims)
        return int(np.prod(dims.size())) def forward(self, state):
        conv1 = F.relu(self.conv1(state))
        conv2 = F.relu(self.conv2(conv1))
        conv3 = F.relu(self.conv3(conv2))
        # conv3 shape is BS x n_filters x H x W
        conv_state = conv3.view(conv3.size()[0], -1)
        # conv_state shape is BS x (n_filters * H * W)
        flat1 = F.relu(self.fc1(conv_state))
        actions = self.fc2(flat1) return actions def save_checkpoint(self):
        print('... saving checkpoint ...')
        T.save(self.state_dict(), self.checkpoint_file) def load_checkpoint(self):
        print('... loading checkpoint ...')
        self.load_state_dict(T.load(self.checkpoint_file))

回想一下,Q-learning 的更新功能需要:

  • 当前状态 s
  • 当前动作
  • 当前动作后的奖励 r
  • 下一个状态s’
  • 下一个动作a’

为了以有意义的数量提供这些参数,我们需要按照一组参数评估我们当前的策略,并将所有变量存储在一个缓冲区中,我们将在训练期间从该缓冲区中提取迷你批次中的数据。因此,我们需要一个重放内存缓冲区来存储和提取观察值。

import numpy as npclass ReplayBuffer(object):
    def __init__(self, max_size, input_shape, n_actions):
        self.mem_size = max_size
        self.mem_cntr = 0
        self.state_memory = np.zeros((self.mem_size, *input_shape),
                                     dtype=np.float32)
        self.new_state_memory = np.zeros((self.mem_size, *input_shape),
                                         dtype=np.float32) self.action_memory = np.zeros(self.mem_size, dtype=np.int64)
        self.reward_memory = np.zeros(self.mem_size, dtype=np.float32)
        self.terminal_memory = np.zeros(self.mem_size, dtype=np.bool)#Identify index and store  the the current SARSA into batch memory
    def store_transition(self, state, action, reward, state_, done):
        index = self.mem_cntr % self.mem_size
        self.state_memory[index] = state
        self.new_state_memory[index] = state_
        self.action_memory[index] = action
        self.reward_memory[index] = reward
        self.terminal_memory[index] = done
        self.mem_cntr += 1def sample_buffer(self, batch_size):
        max_mem = min(self.mem_cntr, self.mem_size)
        batch = np.random.choice(max_mem, batch_size, replace=False)
        #I believe batch here is creating a list limit that is acquired through max_mem, whihch we use to subselect memory
        states = self.state_memory[batch]
        actions = self.action_memory[batch]
        rewards = self.reward_memory[batch]
        states_ = self.new_state_memory[batch]
        terminal = self.terminal_memory[batch] return states, actions, rewards, states_, terminal

接下来,我们将定义我们的代理,它不同于我们普通的 DQN 实现。我们的代理正在使用一个勘探率递减的ε贪婪策略,以便随着时间的推移最大化开发。为了学会预测使我们的累积奖励最大化的状态-行动-值,我们的代理人将使用通过抽样存储的记忆获得的贴现的未来奖励。

您会注意到,作为代理的一部分,我们初始化了 DQN 的两个副本,并使用方法将原始网络的权重参数复制到目标网络中。虽然我们的常规方法利用这种设置来生成固定的 TD 目标,但我们的 DDQN 方法将扩展到这一范围之外:

  • 从重放存储器中检索状态、动作、奖励和下一状态(sar)。
  • 评估网络用于生成当前状态的所有动作的 Q 值。
  • 评估网络用于创建下一状态的 Q 值,最高 Q 值保存为 max_actions。
  • 目标网络还用于创建下一个状态的 Q 值。
  • 当前状态的 TD-target 通过将当前状态中的奖励与通过评估网络识别的 max_actions 从下一个状态的目标网络导出的 Q 值相结合来计算。
  • 通过将 TD 目标与当前状态 Q 值进行比较来计算损失函数,然后将其用于训练网络。
import numpy as np
import torch as T
#from deep_q_network import DeepQNetwork
#from replay_memory import ReplayBufferclass DDQNAgent(object):
    def __init__(self, gamma, epsilon, lr, n_actions, input_dims,
                 mem_size, batch_size, eps_min=0.01, eps_dec=5e-7,
                 replace=1000, algo=None, env_name=None, chkpt_dir='tmp/dqn'):
        self.gamma = gamma
        self.epsilon = epsilon
        self.lr = lr
        self.n_actions = n_actions
        self.input_dims = input_dims
        self.batch_size = batch_size
        self.eps_min = eps_min
        self.eps_dec = eps_dec
        self.replace_target_cnt = replace
        self.algo = algo
        self.env_name = env_name
        self.chkpt_dir = chkpt_dir
        self.action_space = [i for i in range(n_actions)]
        self.learn_step_counter = 0 self.memory = ReplayBuffer(mem_size, input_dims, n_actions) self.q_eval = DeepQNetwork(self.lr, self.n_actions,
                                    input_dims=self.input_dims,
                                    name=self.env_name+'_'+self.algo+'_q_eval',
                                    chkpt_dir=self.chkpt_dir) self.q_next = DeepQNetwork(self.lr, self.n_actions,
                                    input_dims=self.input_dims,
                                    name=self.env_name+'_'+self.algo+'_q_next',
                                    chkpt_dir=self.chkpt_dir) #Epsilon greedy action selection
    def choose_action(self, observation):
        if np.random.random() > self.epsilon:
          # Add dimension to observation to match input_dims x batch_size by placing in list, then converting to tensor
            state = T.tensor([observation],dtype=T.float).to(self.q_eval.device)
            actions = self.q_eval.forward(state)
            #Return tensor, but use item() to reutnr integer
            action = T.argmax(actions).item()
        else:
            action = np.random.choice(self.action_space) return actiondef store_transition(self, state, action, reward, state_, done):
        self.memory.store_transition(state, action, reward, state_, done) def sample_memory(self):
        state, action, reward, new_state, done = \
                                      self.memory.sample_buffer(self.batch_size) states = T.tensor(state).to(self.q_eval.device)
        rewards = T.tensor(reward).to(self.q_eval.device)
        dones = T.tensor(done).to(self.q_eval.device)
        actions = T.tensor(action).to(self.q_eval.device)
        states_ = T.tensor(new_state).to(self.q_eval.device) return states, actions, rewards, states_, dones def replace_target_network(self):
        if self.learn_step_counter % self.replace_target_cnt == 0:
            self.q_next.load_state_dict(self.q_eval.state_dict()) def decrement_epsilon(self):
        self.epsilon = self.epsilon - self.eps_dec \
                           if self.epsilon > self.eps_min else  self.eps_min def save_models(self):
        self.q_eval.save_checkpoint()
        self.q_next.save_checkpoint() def load_models(self):
        self.q_eval.load_checkpoint()
        self.q_next.load_checkpoint()
    #Main DDQN difference here
    def learn(self): #First check if memory is even big enough
        if self.memory.mem_cntr < self.batch_size:
            return self.q_eval.optimizer.zero_grad() #Replace target network if appropriate
        self.replace_target_network() states, actions, rewards, states_, dones = self.sample_memory()
        #Fetch indices for  matrix multiplication for q_pred
        indices = np.arange(self.batch_size) #Calculate the value of the states taken using the eval network
        # We use the indices here to make sure our output q_pred is of shape batch_size instead of batch_size x action_size 
        q_pred = self.q_eval.forward(states)[indices, actions]
        # calculate the state action value of the next state according to target network
        q_next = self.q_next.forward(states_)
        # calculate the state action value of the next state according to eval network
        q_eval = self.q_eval.forward(states_) #Calculate the maximum action value for the new states according to the eval network
        max_actions = T.argmax(q_eval, dim=1)

        #Set q_next to 0 for terminal states
        q_next[dones] = 0.0
        q_target = rewards + self.gamma*q_next[indices, max_actions] loss = self.q_eval.loss(q_target, q_pred).to(self.q_eval.device)
        loss.backward()
        self.q_eval.optimizer.step()
        self.learn_step_counter += 1 self.decrement_epsilon()

定义了所有支持代码后,让我们运行主训练循环。我们已经在最初的总结中定义了大部分,但是让我们为后代回忆一下。

  • 对于训练集的每一步,在使用ε-贪婪策略选择下一个动作之前,我们将输入图像堆栈输入到我们的网络中,以生成可用动作的概率分布
  • 然后,我们将它输入到网络中,获取下一个状态和相应奖励的信息,并将其存储到我们的缓冲区中。我们更新我们的堆栈,并通过一些预定义的步骤重复这一过程。
  • 在一集的结尾,我们将下一个状态输入到我们的网络中,以便获得下一个动作。我们还通过对当前奖励进行贴现来计算下一个奖励。
  • 我们通过 Q 学习更新函数生成我们的目标 y 值,并训练我们的网络。
  • 通过最小化训练损失,我们更新网络权重参数,以便为下一个策略输出改进的状态-动作值。
  • 我们通过跟踪模型的平均得分(在 100 个训练步骤中测量)来评估模型。
env = make_env('VizdoomCorridor-v0')
best_score = -np.inf
load_checkpoint = False
n_games = 5000
agent = DDQNAgent(gamma=0.99, epsilon=1.0, lr=0.0001,input_dims=(env.observation_space.shape),n_actions=env.action_space.n, mem_size=5000, eps_min=0.1,batch_size=32, replace=1000, eps_dec=1e-5,chkpt_dir='/content/', algo='DDQNAgent',env_name='vizdoogym')if load_checkpoint:
  agent.load_models()fname = agent.algo + '_' + agent.env_name + '_lr' + str(agent.lr) +'_'+ str(n_games) + 'games'
figure_file = 'plots/' + fname + '.png'n_steps = 0
scores, eps_history, steps_array = [], [], []for i in range(n_games):
  done = False
  observation = env.reset()score = 0
  while not done:
    action = agent.choose_action(observation)
    observation_, reward, done, info = env.step(action)
    score += rewardif not load_checkpoint:
      agent.store_transition(observation, action,reward, observation_, int(done))
      agent.learn()
    observation = observation_
    n_steps += 1scores.append(score)
  steps_array.append(n_steps)avg_score = np.mean(scores[-100:])if avg_score > best_score:
    best_score = avg_score

    print('Checkpoint saved at episode ', i)
    agent.save_models()print('Episode: ', i,'Score: ', score,' Average score: %.2f' % avg_score, 'Best average: %.2f' % best_score,'Epsilon: %.2f' % agent.epsilon, 'Steps:', n_steps)eps_history.append(agent.epsilon)
if load_checkpoint and n_steps >= 18000:
    break

我们绘制了 500、1000 和 2000 集的代理商平均得分和 epsilon 比率。

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

500 集后我们经纪人的奖励分配。

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

1000 集后我们经纪人的奖励分配。

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

2000 集后我们经纪人的报酬分配。

查看结果并将其与我们的普通 DQN 实现进行比较,您会立即注意到 500、1000 和 2000 集的评分分布有显著改善。此外,您会注意到振荡是如何被显著抑制的,这表明与普通实现相比,收敛性得到了改善。

我们可以想象我们的代理人在 500 集以下的表现。你可以将它与文章顶部的游戏视频进行比较,视频来自我们在相同的剧集持续时间内训练的香草 DQN 实现。

但是在 1000 集以上,我们开始看到有趣的行为——代理人停止与怪物接触,只是不停地转圈。这一点之前在 2017 Spark AI 峰会的 Vizdoom 环境中已经观察到了。

虽然在峰会演示中,他们通过奖励功能工程解决了这个问题,但理解为什么会出现这种情况很重要。因为每一次重生都被证明可以显著增加怪物的生命值,所以有可能代理人发现棕色怪物的火球的高伤害在每一次重生中都更加可靠。然而,考虑到粉色怪物的移动模式有些随机,在多集游戏中依赖它们并不是一个可靠的策略。

解决这个问题要么需要改变环境(用扫射代替转弯可能是一种选择),要么通过奖励工程——例如,根据生存的持续时间增加奖励。

这就结束了双深度 Q 学习的实现。在我们的下一篇文章中,我们将继续用更高级的 Q-learning 方法来检查我们的代理在这些环境中的性能。

我们希望你喜欢这篇文章,并希望你查看 GradientCrescent 上的许多其他文章,涵盖人工智能的应用和理论方面。为了保持对 GradientCrescent 的最新更新,请考虑关注该出版物并关注我们的 Github 资源库。

来源

萨顿等人。al,“强化学习”

塔博尔,“运动中的强化学习”

西蒙尼尼,“深度 Q 学习的改进*

数据分析的发现

原文:https://towardsdatascience.com/discovery-of-data-analysis-66471b5cab91?source=collection_archive---------42-----------------------

数据不仅对企业或机构很重要,对生活的每个领域也很重要,甚至对一个简单的个人也是如此。甚至我们的记忆也是数据。有了数据,我们对过去感到愤怒,对未来充满希望。

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

穆罕默德·哈桑·pixabay.com

简介

数据和信息是一个组织最具战略性的工具之一。如果一个企业正确理解和处理它的数据,它可以使用它来改进它的流程。数据直接转化为盈利。数据可以用于许多不同的目的;

  • 股票跟踪,
  • 欺诈和诈骗检测,
  • 价格和折扣决策,
  • 购买和品牌忠诚度,
  • 识别和分组用户行为,
  • LFL 金融分析,
  • 趋势分析和预测,

除了将数据转化为有意义的结果之外,数据处理速度提高得越快,企业在决策阶段就越有优势。

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

Stephen Dawson 在 Unsplash 上拍摄的照片

快速准确地获得数据并将其转化为有意义的结果当然很重要,但仅此还不够。数据应该成为企业内部的一种文化。将数据转化为文化;

  • 要知道如何用数据告诉正确的故事
  • 故事将在哪里或在什么样的环境中讲述,这一点应该很清楚。
  • 故事应该传达给正确的人,并采取行动。
  • 能够采取行动并需要数据的人应该能够容易地访问数据或数据衍生分析,并且总是知道如何访问它。
  • 能够从数据中采取行动的人应该很容易理解这个故事,并利用他们从这个故事中获得的东西来引发行动
  • 创建的动作必须不断测试并且过程必须返回到顶部并注入新的故事。

数据分析概述

数据分析过程基于数据清理、建模和可视化

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

JESHOOTS.COMUnsplash 上的照片

  • 数据清理:我们在商业生活中很少遇到干净的数据,通常我们需要移除扰乱分析的数据或者以不扰乱完整性的方式填充
  • 数据建模:按统计区间对数据进行公式化、分组或分组通过对研究的原始数据建立数学函数,将数据带到下一个层次。我们利用它让数据更有价值。
  • 数据可视化:干净且有意义的数据仍然可以处于不必要的细分或细节中。分组和汇总这些数据可以让我们更专注于数据的故事。我们需要用图形和颜色来刺激汇总数据,使人脑更容易感知。

有一些基本组件根据它们的级别来分析数据。分析的类型将改变从数据中获得的内容。例如,看到客户希望从你那里得到的过去情况的后果,正在等待你的解释性分析。

描述性分析

以史料为依据,回答了“发生了什么”的问题。KPI 和绩效指标就属于这一类。此外,监控销售、库存和价格的 LFL 趋势分析也是解释性分析的一部分。

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

M. B. M.Unsplash 上拍摄的照片

诊断分析

再次,基于过去的数据,它是一个回答**“为什么”一个事件发生的问题的分析。当我们想要解释在基于过去几个月的数据的描述性分析中看到的急剧的销售下降时,我们使用它。要解释这种下降的原因,我们必须首先确定异常现象。一旦检测到恶意代码,可能还需要从不同来源收集数据。结合数据后,我们需要找到关系或趋势**来解释这种异常。在这个阶段,它主要受益于统计数据。

预测分析

对于一个企业来说,知道“未来会发生什么”这个问题的答案至关重要。在即将上映的电影中,马蒂·邓泽旭的行动救了他的命,他知道未来会发生什么。这种未来的信息可以挽救一个企业的生命,或者帮助其竞争对手扩大差异。

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

詹·西奥多在 Unsplash 上的照片

但是预测通常是困难的。很难将有意义的数据和关系数据结合在一起,并且需要非常专业的知识。数据必须由合格人员解释和批准。相反,统计操纵的预测可能会产生不良后果。

为了进行预测分析,你可能需要输入机器学习方法,并使用高级算法。最常用的有回归、决策树和神经网络

规定性分析

指导性分析与预测性分析交织在一起。或者预测分析的继承者。在相信我们已经找到了问题"会发生什么"的答案后,如果我们能找到问题"我们将如何做"和"我们应该做什么"的答案,它就能告诉我们对未来的一个事件应该提前采取什么行动。

认知分析

认知分析依赖于机器学习、深度学习和人工智能算法。如果情况发生变化,这有助于探索可能出现的情况。事实上,认知分析是一个循环的表达。它通过在旧数据上添加新数据来创建一个持续的学习循环。

数据处理角色

随着数据的增长,它变得更加复杂;获取和呈现数据所需的主要步骤产生了各自不同的专业。根据业务的规模和业务中的数据,有些职位可能是向内的。

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

https://docs . Microsoft . com/tr-tr/learn/modules/data-analytics-Microsoft/3-roles

商业中最广泛使用的能力分布是业务分析师、数据分析师、数据工程师、数据科学家和数据库经理

  • **业务分析师:**数据分析师和业务分析师在很多业务中是同一个人。将业务分析师与数据分析师区分开来的最大特征是其与流程的接近性,并且擅长解释数据。
  • 数据分析师:他经常使用可视化、报告和数据处理工具。他的主要目的是处理、转换,然后汇总和可视化原始数据。在这样做的时候,他根据业务的需要采取行动。他擅长创造故事,是一个目的性很强的大师。大多数时候,他主导业务流程并提供建议。数据分析师的成功取决于他所能创造的洞察力的质量。数据分析师与数据工程师密切合作。他设计收集数据的过程,工程师和分析数据,并不断生产资源养活自己。
  • 数据工程师:他负责从多个不同来源导入、提取、处理、转换和存储数据。为此,他使用内部环境或云技术。与数据库经理的区别在于,他对操作数据流不感兴趣。因为他可能需要不同的专业知识。数据工程师还需要数据的安全性、数据流的管理以及设计警告机制。他们与数据科学家和数据分析师密切合作,在数据采集阶段设计和实施解决方案。
  • 数据科学家:为了获得比数据更高层次的数据,数据科学家还使用统计方法进行高级分析研究。用描述性分析评估数据,而揭示趋势、模式和异常。确定敏感点。他通过以上这些观点产生洞见。他为这些预测的持续生存建立了灵活的模型。在这样做的过程中,他实施了机器学习、深度学习、人工智能等方法,并使用了先进的工具。他用不变的假设来测试它们。数据分析师和数据科学家的任务在许多方面是相同的。在某些业务中,他们可以是同一个人。在一些业务中,根据数据大小和目的,它们需要密切合作,并且是相同的。
  • 数据库经理:实施和管理业务上的数据库服务、云数据平台和混合解决方案。数据库管理员负责保存数据的环境的性能、速度和连续性。数据工程师负责管理用于分析和可预测性的数据和分析环境,这主要取决于数据科学,而数据库经理更负责运营数据和原始数据的流动。当然,就像数据科学家和数据分析师在某些业务中交织在一起一样,数据库经理和数据工程师的任务和职责也可以交织在一起,并且可以是唯一的。

数据分析师任务的详细概述

如果数据分析师正确管理其数据并保持其连续性,对业务数据和数据分析师工作的信心将会增加。如果数据管理不当,建模不当,或者流很快就容易出错,那么除了他对数据的不信任之外,他还会导致企业做出错误的决策,从而导致比预期更多的问题。

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

穆罕默德·哈桑·pixabay.com

一个数据分析师基本上执行 5 个步骤;

  • 准备:准备数据的过程需要与数据工程师密切合作。增值的分析数据应该从分析数据仓库环境中提供。该数据必须以性能方式进行清理、提取和获取。没有哪个部门会希望在业务中使用整天都不更新的数据。
  • 建模:决定将哪些数据与结果数据组合。通过增加数据的附加值来增加新的项目、类别和计算
  • 可视化:高级数据现在需要进行汇总、着色、分组和交互。可视化不仅仅是用图形来写,还可以用大点来写,用指定的范围来着色和高亮,高亮的数字和文字也是可视化的一部分。
  • **推论:**被形象化和概括的数据必须被解释。根据数据中的模式,可能需要对数据进行多样化处理,或者根据不同的故障进行下降。
  • 共享:组织好的数据应该在企业内部容易访问。此外,并非所有数据在企业中都可见。访问组的管理,相似报告的分组,应用程序接口也包含在共享中。

正确处理数据并使其可食用并不像看起来那么简单,这是一顿美味的大餐。如果一个企业想要获得正确的数据,它必须首先获得数据文化,并使其有价值,根据数据行动。如果这种思维模式一开始就不存在,那么无论输出有多好,建立起来的数据步骤和组织都将保持不活动。此外,处于接触数据位置的人应该密切关注不断发展的技术,跟上创新。今天,许多数据处理、数据存储、数据可视化和机器学习环境要么在两三年前不存在,要么不那么先进和用户友好。

资源;

1-https://docs . Microsoft . com/tr-tr/learn/paths/data-analytics-Microsoft/

2-https://eksisozluk . com/data-analyst-1282941

3-https://towardsdatascience.com/tagged/data-analysis

4-https://en.wikipedia.org/wiki/Data_analysis

5-https://data science . Berkeley . edu/about/what-is-data-science/

我的 Linkedin 个人资料;

https://www.linkedin.com/in/onur-okyol-ba253b72/

价值发现

原文:https://towardsdatascience.com/discovery-of-value-8444ffff3c0c?source=collection_archive---------84-----------------------

机遇、挑战和经验教训

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

Chan2545 在Shutterstock.com拍摄的照片

序言。第四次工业革命已经来临。世界经济论坛将其描述为信息物理系统的出现,涉及人和机器的全新能力,以及技术嵌入我们社会的新方式。数据科学是一个很好的例子,其中全新的社区正在形成,具有非常不同但高效的学习和再学习、创新、信息交流流程,并拥有为有效利用现有和新知识以及创业繁荣提供激励的环境。然而,世界经济论坛抓住了一个重大挑战:

“因此,我们应该记住,所有工业革命最终都是由人们的个人和集体选择推动的。重要的不仅仅是开发底层技术的研究人员、发明家和设计师的选择,更重要的是在日常生活中采用和使用这些技术的投资者、消费者、监管者和公民的选择。”

因此,随着数据科学社区的蓬勃发展,研究人员、发明家和设计师必须意识到共同的挑战,以及将他们有价值的新发现嵌入现有商业领域的机会。更一般地说,这种情况会延伸到其他技术领域,在这些领域,问题往往不在于组织未能理解新技术或新能力,从而导致缺乏资金或支持,而是与文化和创新的一般方法有关。理解这一点是关键。

考虑这个简短的例子。柯达已经在市场上存在了 130 多年,在 2012 年申请破产之前,它被认为是当时最具创新性的公司之一。所有人都知道,他们未能应对从胶片到数码相机的需求转变。但也许不是每个人都知道柯达是第一家在 70 年代末制造出可用数码相机的公司,甚至当苹果在 90 年代发布其第一款数码相机时,它实际上也是由柯达设计的。前副总裁唐·斯特里克兰(Don Strickland)在 90 年代初离开了公司,因为他无法说服公司追求数码相机市场,他说:“我们开发了世界上第一台消费数码相机,但由于担心对电影市场的影响,我们无法获得批准推出或销售它。”正如唐所说,当市场条件被新技术或新能力动摇,企业在捍卫现有地位时,会有一种恐惧。然而,这不是恐惧,而是一系列完全理性的决定,这些决定根植于组织文化和创新的一般方法中。当你读完这篇文章时,回到这一段,并思考一下——柯达就像今天许多其他公司一样,在红海中游泳。数据科学的发现被许多组织接受,就像柯达接受数码相机一样。在本文中,您将了解为什么会发生这种情况,以及如何解决它。

介绍

在的文献中,几乎很难找到关于如何寻找和发现新价值的实用而清晰的指南。在这篇文章的最后,看看我关注的人的名单,他们是世界上在他们的学科中最有影响力的思想家。我已经深入研究了他们的工作,并注意到他们的方法主要是服务于高管或高层管理人员的需求,在这种情况下,学习直接融入到战略中,并清楚地传达了对公司增长的影响。所有的案例研究、理论和观察都是围绕着这种高管文化展开的。这是完全合理的,因为高管设定方向并执行公司增长战略,然后分配资源并批准新项目。然而,一旦项目被批准,或者一个总的方向被设定,更多的决策和优先次序在一个层级中被降低,并且当团队开发技术时几乎每天都是如此。随着我们过渡到知识社会,创新的欲望空前增长,这些技术交付的动力变得更加活跃。为了应对不断增长的创新需求,成熟的组织正在从行动缓慢的层级结构向灵活、更具协作性和敏捷的结构转变。麦肯锡&公司将这种转变定义为从机器般的转变为有机体般的结构,赋予公司在快速变化和模糊的市场环境中更新自我、适应、改变和成功的更大能力。因此,传统上在团队和部门之间划分界限的盒子和线条现在变得不那么重要了,允许跨职能部门进行更少层级的协作,据报道,这将大大提高生产力和创新。因此,在这个动态的环境中,自主性在不断增加,这也是公司实现创新目标的有效性的主要定义。换句话说,更好的效率允许执行更高要求的目标,并允许组织追求更高要求的增长战略。因此,有两个因素有助于组织释放新价值的能力——高管创造并交付的成功战略,以及员工对该战略的交付。虽然我看到的所有实用指南都是针对前者的,但后者往往没有得到应有的重视。想一想亨利·福特(Henry Ford)对他的行业的名言:“如果我问顾客想要什么,他们会说是一匹更快的马”。尽管他的问题是在高管层面发掘新的价值,但同样的推理模式也可以应用于组织层级中其他层面出现的其他问题。虽然当前用于发现价值最大化和风险最小化的解决方案以解决我们在创新中的日常问题的通用方法很麻烦,并且通常缺乏清晰的定义和系统的程序,

我的问题是:如何将世界上最成功的高管发现和执行新市场的战略制定成一个系统框架,使其也适用于层级较低的其他每个人,这些人肩负着实现高管设定的创新目标的重要责任?

在这种情况下,这是一个更广泛的理念——不仅是发现新市场和创造能够带来长期盈利增长的战略,而且更广泛地说,我称之为发现价值,能够更有效地实现创新目标,推动组织对可能性的理解。

我的观点是,不仅是高管,任何级别、任何角色的其他创新人员都应该意识到发现价值和执行战略背后的机遇、挑战和斗争。有趣的是,在创建最成功的公司的过程中,我们可以从世界顶级思想家和企业家身上学到很多东西。无论你是一名渴望开始一个有意义的副业项目的大学生,一名将你的企业带上天空的企业家,一名准备推销的员工,一名追求新研究议程的教授,还是一名寻找新增长机会的知名领导者,这里都有适合每个人的伟大课程。

尽情享受吧!

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

机遇、挑战和经验教训

许多世界顶级思想家为我们提供了清晰理解创新类型之间的根本差异以及所做选择如何影响长期业务增长的方法。这些创新战略以不同的名字被推广,如硅谷的彼得·泰尔的竞争垄断,哈佛的克雷·克里斯滕森的持续颠覆性创新,INSEAD 的 Chan Kim 等人的红海蓝海,或者全球本地化对*。通用电气公司的杰夫·伊梅尔特等人的逆向创新。然而,它们都传递相同的信息。公司有时会陷入竞争的红海中,这种竞争会侵蚀他们的利润,阻止他们创造有意义的差异化,并阻止他们投资可以创造新市场和新价值的颠覆性产品。世界上最成功的公司通过投资于专注的、差异化的、创造新市场的技术,设法逃避竞争,使竞争变得无关紧要。他们设法创造了蓝海和 T21,并利用创新技术来扰乱他们的市场,这导致了强劲和有利可图的增长的新轨迹。*

在他的畅销书《零比一》中,彼得·泰尔写道,“它的竞争[……]就像战争:据称是必要的,据称是勇敢的,但最终是毁灭性的”。发现新市场和创造垄断的公司可以创造压倒性的价值。“我们所说的垄断是指这样一种公司,它在所做的事情上非常出色,没有任何其他公司能够提供与之相当的替代品。[……]垄断拥有自己的市场,所以可以自己定价。由于没有竞争对手,它以最大化利润的数量和价格组合进行生产。”然而,根据 Clay Christensen 的说法,运营良好的公司的经理通常会有意或无意地追求颠覆性创新,Thiel 称之为垄断。这是因为它从根本上挑战了他们的供应链、成本结构、流程、价值观和文化,而这些都是他们在了解和熟知的市场中最强大的客户的需求时发展起来的。需要一种根本不同的战略来应对颠覆性创新,这些创新创造了新的市场、新的竞争、新的需求、新的客户群体,或者以新产品属性和商业模式瞄准现有的既定客户群体。Chan Kim 等人调查了世界上最成功、最持久和最有远见的公司为持续超越市场和反复创造蓝海所遵循的战略的共性。他们发现,发现蓝海的成功战略的基石是价值创新,而不是专注于击败竞争对手,重点应该是通过为客户创造价值的飞跃,让竞争变得无关紧要,从而开辟新的无竞争市场空间。“基于竞争的红海战略假设一个行业的结构条件是给定的,企业被迫在其中竞争。[……]相比之下,价值创新基于这样一种观点,即市场边界和行业结构不是给定的,可以通过行业参与者的行动和信念来重构。”然而,Chan Kim 等人认为,“目前的竞争环境严重失衡,有利于工具和分析框架在红海中取得成功。只要这一点保持不变,红海将继续主导公司的战略议程,即使创造蓝海的业务需求变得更加紧迫。也许这解释了为什么尽管之前呼吁公司超越现有的行业空间,但公司还没有认真对待这些建议。"

通用电气(General Electric)前首席执行官杰夫伊梅尔特(Jeff Immelt)等人已经很好地记录了追求蓝海的影响以及在现有组织内调整其战略的实际挑战。杰夫等人在《哈佛商业评论》上写道,“通用电气迫切需要创新……不仅要扩展到高端市场……还要抢先于其他公司创造类似的产品,然后用它们来瓦解通用电气。坦率地说,如果通用电气的业务要在未来十年生存和繁荣,它们必须变得像在红海中竞争一样擅长(追逐蓝海)。”然而,蓝海战略的发现和执行远非一帆风顺。Jeff 举了一个很好的例子,他描述了通用电气公司在交付的各个阶段带领蓝海所面临的巨大挑战。他写道,作为阿格的领导者,你通常严格负责实现增长计划,满足现有市场中现有客户的需求——换句话说,重点是维持或逐步改善红海。你将很少有时间参加像发现蓝海和创造新策略这样的课外活动。但是,与在内部销售蓝海方案相比,将你的战略写在纸上的这些挑战算不了什么。这样做需要引起公司层级中多个其他领导的注意,例如制造主管、营销主管、财务主管、全球研发主管&,他们都有自己的日程安排,几乎没有时间来说明情况。而且,即使这个提议成功了,你也需要年复一年地与更多短期回报的项目争夺资金。与此同时,你仍然需要担心日常工作的季度数据。杰夫认为,开发全新产品的成功案例少之又少,这不足为奇。

在 Jeff Immelt 等人描述的例子中,组织挑战背后的机制可以用 Christensen 的逻辑很好地解释。问题的核心是普遍接受和实践的衡量增长的方法。当增长是用相对值而不是绝对值来衡量时,比较机会就更容易了。因此,比率被用来衡量和比较提案、项目、投资组合或公司之间的增长。最常用的是资产回报率(ROA)和毛利润。第三个是内部收益率(IRR),它通过评估所有现金流的净现值等于零的贴现率来估计潜在投资的盈利能力,可以理解为一段时间内的投资。优秀的经理会做有意义的事情,而有意义的事情就是关注并投资那些能最大化 ROA、毛利润和 IRR 的项目。这可以通过增加净收入、收入或投资,或者减少资产数量和制造成本,或者投资于为投资者提供更高净现金流的短期项目来实现。前者通常更难实现,因此后者是增长背后最大的意图和焦点。因此,根据这一逻辑,红海文化是一种倾听最强大客户意见的文化,积极投资于近期技术,以满足这些客户的需求,寻求更高的利润,并瞄准足够大的市场以维持增长预期。如果你仔细观察,这里的悖论是,这些是完全理性的行为,但它们与追求蓝海——提供最大价值——背道而驰。这正是杰夫伊梅尔特等人的故事背后的挑战,或许还有更多其他人试图向他们的经理推销想法。作为一名经理,看着蓝海提案,你会得出这样的结论:这些提案通常会被你最强大的客户拒绝,利润较低,表现不如现有技术,投资回报较长,初始市场规模可能微不足道。因此,蓝海的价值不应该用比率来表示和比较,而应该用绝对值来表示和比较。鉴于蓝海在创造无与伦比的价值方面取得的显著成功,我们应该给予它应有的关注和耐心。

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

作者图片

克里斯滕森和泰尔已经很好地研究了聚焦于蓝海的发现和执行的困难背后的原因。它触及了个人和组织行为的核心。组织开发符合其主要业务需求的流程和价值观。这些流程和价值观是构成组织能力的要素,并决定公司成功建立市场领先地位的能力。员工学习什么可以被定义为最佳解决问题的方法和决策标准,当他们成功地使用这些方法并做出决策来解决重复出现的任务时,流程就被定义了。流程可以包括产品开发、采购、市场研究、预算、计划、员工发展和薪酬以及资源分配。做出决策的标准既可以是符合道德的,例如与公司愿景和使命一致,也可以是资源-流程-价值观,这是员工做出优先决策并判断某些行动是否更有吸引力、某些客户是否更重要、或者某些想法是否更有吸引力的标准。组织变得越大越复杂,就越有必要建立适当的流程,并培训员工独立决定优先事项。一旦员工开始通过假设而不是有意识的决定来使用流程和价值观,那么组织文化就建立起来了,这使得员工能够自主一致地行动。通常是文化决定了公司的发展方向,并最终决定了公司的长期发展轨迹。克里斯滕森认为,文化是我们看到经营良好的大公司最终失去市场地位,无法应对竞争基础变化的核心原因。公司没有文化,公司就是文化。文化使员工自主一致地行动,定义员工将做出什么决定,决定资源分配的路径,并决定成本结构。成长文化是由肩负使命的个人建立的,并由他们自己对价值所在的理解所驱动。一些文化重视竞争和满足最强大客户的需求,而另一些文化则通过差异化和创造新市场来推动增长。换句话说,文化将最终决定一个组织脱离竞争并创造新价值的能力。当组织能力已经根植于文化之中时,就像杰夫·伊梅尔特(Jeff Immelt)等人详述的通用电气(GE)的案例那样,变革可能会异常困难。

克服这一困难的一种方法是建立一个独立的增长团队,该团队类似于一个初创环境,拥有决策自主权,并有潜力创造自己的文化,旨在创造新的市场。杰夫·伊梅尔特(Jeff Immelt)等人写道,通用电气通过创建独立的本地增长团队(LGT)来应对他们追求蓝海的组织挑战,他们自己的流程、价值观和文化与业务的其他部分分离,使发现过程比以前更有效,而主流组织的重点是红海。在 2008 年严重的全球经济衰退中,通用电气的一些主要业务增长了 25%,这主要是因为其 LGT 子公司开发的新技术创新为客户创造了价值飞跃,并开辟了新的市场空间。其他人也有类似的战略努力。1998 年至 2007 年间,美国宇航局高级概念研究所(NIAC)每年的预算约为 400 万美元,一个由企业家、研究人员和发明家组成的社区承担了发现蓝海的任务。他们有效地脱离了主流组织强加的障碍。该研究所在其 9 年的生命周期中评估了 10 到 40 年规划范围内的约 1309 项建议,5-10%的选定概念后来被纳入 NASA 的主流长期计划。与此同时,欧洲航天局建立了自己的先进概念小组(ACT ),每年预算 100 万€,任务是监测、执行和促进创新概念和工作方法的进展。NIAC 和 ACT 的成功被评估为采用选定的高风险、高回报的概念、技术、想法和方法,并加以证明,然后转移到主流组织,成功率在 10-30%之间。如果没有他们先进的概念单元,就不可能以如此大的规模和如此高的成功率评估蓝海提案。同样,近年来,在整个航空航天行业,我们可以看到专业业务单位/团体/团队的创建,它们拥有自主权和一套探索先进概念和新市场的策略。例如空客创建了 A3 实验室,R-R 创建了 R2 实验室,GKN 创建了全球技术中心。这是人工智能、区块链、量子计算、物联网、新型推进技术、增材制造等先进概念的地方。被评估为他们的客户创造价值的飞跃,并为新的利润增长设定轨迹。

最后,重申 Chan Kim 等人的观察结果——虽然我们看到一些公司正在采取行动来占领蓝海,但仍有更多的公司尚未采取行动。那些不采取行动的公司,迟早会看到新的陌生竞争的出现,失去市场份额,或者无法留住他们的客户。

底线

努力做到真实和原创,不要将自己的行为与他人进行比较,创造有针对性、差异化的解决方案,为你的目标客户创造价值飞跃。注意你周围文化的特征——这将最终决定你传达和接受对你各种愿景的支持的能力。如果你在挣扎,和那些绝对看到价值的人在一起。然后,当你向在红色海洋中游泳的人推销想法时,要注意你如何接近他们以及信息是如何呈现的。最后,培养你的情感勇气,接受潜在的不适、不确定、拒绝、失败或不安全感。这些是承诺一些更大的和超越常规的事情的风险,如果你想完成任何有价值的事情,这些是你可能不得不感受到的感觉。

无论你如何决定,追求蓝海绝对是值得的!祝你好运,度过一波又一波的挑战,我希望我已经帮助你预见到这些挑战会是什么。

但是如何真正发现价值呢?我有一个好消息,我正在开发一个价值发现的系统框架——敬请关注最新消息!

在我的研究中选择的关键人物

彼得·泰尔是硅谷精英,他共同创立了 PayPal,并成为脸书的风险投资人和早期投资者。他还共同创立了中情局支持的初创企业 Palantir,最近估值约为 260 亿美元。

克莱·克里斯滕森(1952-2020)是哈佛商学院的教授。他被认为是世界上创新和增长方面的顶级专家之一。2011 年,他被评为世界上最具影响力的商业思想家。《经济学人》将他的书创新者的困境命名为有史以来最重要的六本商业书籍之一。

W. Chan Kim 是 INSEAD 蓝海战略研究所的联合主任,也是 INSEAD 大学战略和国际管理的讲座教授。他在世界顶级管理大师中排名前三,并因商业和经济思维领导力获得诺贝尔学术讨论会奖。他与 renée maoborgne 合著的《蓝海战略》一书被认为是有史以来最具标志性和影响力的战略书籍之一。

彼得·布雷格曼是畅销书作家,伯格曼合伙人公司的首席执行官,该公司帮助首席执行官和高级领导人完成困难的事情。

彼得·德鲁克(1909-2005)被认为是管理学的创始人,2002 年他被老布什总统授予总统自由勋章。

丹尼尔·贝尔(1919-2011)可能是我们这个时代最著名的社会学家。他在他的书《后工业社会的到来》(T2,1973)中提出了后工业社会或信息时代的概念。后来,他将这一概念重新命名为信息社会,一般认为他是这一术语的创造者(1979)。

桑尼·贝恩斯是伦敦 UCL 的科学家和记者,也是《解释未来:如何研究、分析和报道新兴技术的作者。

James Surowiecki 是一名报道金融和人类行为的记者。他是研究群体及其集体知识和智力的主要贡献者之一。詹姆斯写了一本畅销书《群体的智慧》。

Richard Peterson 是行为经济学家、精神病学家、作家和 MarketPsych 的创始人,这是汤森路透 MarketPsych 指数(TMRI)背后的一股创新力量。在他的《基于情绪的交易》一书中,理查德展示了管理情绪是如何帮助顶级投资者跑赢大盘的。理查德正在开发突破性的基于预测情绪的模型,分析新闻和社交媒体中的情绪,帮助顶级投资者大幅跑赢大盘。他的团队开发了一个市场中立的基于社交媒体的对冲基金,在 2008 年金融危机期间,该基金的表现超过标准普尔 500 指数 24%。

感谢阅读!如果你觉得这篇文章有用或者有任何问题,请给我留言。同样让我们连线上 LinkedinMedium

Plotly Python 中的离散色阶

原文:https://towardsdatascience.com/discrete-colour-scale-in-plotly-python-26f2d6e21c77?source=collection_archive---------33-----------------------

一个我决定要解决的恼人问题

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

右侧一组离散的颜色条(原始内容)

我喜欢使用 python 库进行 Plotly,但是我注意到,当我试图使用 Graph 对象来做一些事情,比如制作 Choropleth 地图时,我很难为我的数据获取离散的颜色范围。

我喜欢根据类别将我的数据分成不同的区域。例如,如果我试图显示三类数据,我将为第一组使用 0-33 的范围,为第二组使用 34-66 的范围,最后为 67-100。在每一个类别中,我都想展示它自己的一套独立的颜色(见上图)。为了做到这一点,我写了下面的函数,我希望它能帮助那些想做同样事情的人!

该功能

这个函数所做的就是接受一个颜色元素列表。然后,它会想出如何为各种输入制作离散的色块。读一读,看看下面实际怎么叫。

def generateDiscreteColourScale(colour_set):
    **#colour set is a list of lists**
    colour_output = []
    num_colours = len(colour_set)
    divisions = 1./num_colours
    c_index = 0. **# Loop over the colour set**
    for cset in colour_set:
        num_subs = len(cset)
        sub_divisions = divisions/num_subs **# Loop over the sub colours in this set**
        for subcset in cset:
            colour_output.append((c_index,subcset))
            colour_output.append((c_index + sub_divisions-
                .001,subcset))
            c_index = c_index + sub_divisions
    colour_output[-1]=(1,colour_output[-1][1])
    return colour_output

上面是一段很短的代码,但是它为我们做了很多工作。

使用

为了绘制主标题图像,我实际上有 4 个类别(哈利·波特房屋),我不仅想用纯色显示这 4 个类别,还想根据出现的次数(从亮到暗)对它们进行细分。我已经准备好了所有的数据,但需要得到色阶。在下面我们来定义这个方案。每个列表元素对应一个类别(即哈利波特的房子),这个列表元素实际上包含了我想要使用的颜色范围的列表(从最亮的颜色到最暗的颜色)。

**# Harry Potter Houses**
color_schemes = [
    ['#890000','#890000','#5c0000'],
    ['#2a6b28','#0b4c07','#003206'],
    ['#4f5a90','#374798','#30375a'],
    ['#fff4b1','#ffed86','#ffdb00']
]

现在,我可以调用上面的函数来获取适当的格式,并将其传递给 go。Choropleth plotly 对象。

colorscale = generateDiscreteColourScale(color_schemes)

最终增加了我们的情节。

fig.add_trace(go.Choropleth(
    geojson=counties,
    locations=fips,
    z=final['split'].astype(float),
    ***colorscale=colorscale,   <--- THE MONEY***
    marker_line_width=0.0, # line markers between states
    marker_line_color='rgba(0,0,0,0.1)',
    text=final['label'], # hover text
))

就这么简单!你可以用它来制作一堆好看的情节。下面是我使用它的一些例子。

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

使用映射功能的一些示例(原始内容)

当然,这并不局限于地图,在 plotly 中使用 colourscale 输入的任何情况下都可以使用。

希望这有所帮助!如果有任何问题,请随时联系我!

参考

[## 谷歌趋势 DMA

使用 Kaggle 笔记本探索和运行机器学习代码|使用来自 Google Trends County-DMA 映射的数据

www.kaggle.com](https://www.kaggle.com/kapastor/google-trends-dma) [## Choropleth 地图

如何用 Plotly 在 Python 中制作 choropleth 地图?

plotly.com](https://plotly.com/python/choropleth-maps/)

旧金山警察局交通站的歧视

原文:https://towardsdatascience.com/discrimination-in-san-francisco-police-department-traffic-stops-2800bf06895d?source=collection_archive---------50-----------------------

使用假设检验探索旧金山警察局交通检查站种族歧视的证据

安库什·巴拉德瓦伊

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

伊莎贝拉·史密斯Unsplash 上拍摄的照片

介绍

在过去几个月里,针对乔治·弗洛伊德(George Floyd)和冷血杀手布里奥纳·泰勒(Breonna Taylor)被公开处决的和平抗议已经发展成为一场由一代美国年轻人领导的运动,他们已经看够了警察使用不合理的武力摆放黑人尸体。现在,我并不是要让你相信我们的警察系统中存在系统性的种族主义:这里有一篇文章可以帮助你开始。相反,我的目标不是关注整个治安,而是通过数据科学,主要是通过假设检验,调查警察部门进行的交通拦截中的种族歧视。虽然已经有研究充分的证据表明警察交通拦截中存在种族偏见,但我想探究旧金山警察局实施的交通拦截中的种族歧视。我决定研究 SFPD,因为三藩市被认为是一个自由的城市,我想了解“自由”对于一个城市的警察部门的种族主义到底意味着什么。因此,当我开始着手这个项目时,我提出的问题如下:

在旧金山警察局进行的交通拦截的结果方面,是否有歧视黑人的证据?

访问交通站点数据

为了获取交通停车数据,我使用了由斯坦福大学的研究人员和记者团队斯坦福开放警务项目汇编的数据,他们从全国各地的执法部门收集并标准化了车辆和行人停车数据。更多关于他们数据结构的信息可以在这里找到。

将旧金山交通站点的数据导入 Python 后,我开始为下一步的分析清理和准备数据。我首先使用 Seaborn Python 包通过热图(如下所示)可视化了数据集中的 NA 值。

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

可视化 NA 值

在该热图中,红色表示安娜值的存在。由于“违禁品 _ 发现”和“搜索 _ 基础”列有太多的 NA 值需要通过插补来解决,所以我简单地从数据集中删除了这些列。为了处理剩余的 NA 值,任何包含安娜值的行也被从数据集中删除。

最后,准备数据的最后一步是确保每一列都有适当的数据类型。对于这个数据集,我只需要将“date”列更改为 datetime 对象。

探索性数据分析

现在数据已经准备好了,是时候进入探索性的数据分析了。该过程的第一步是使用 Pandas value_counts 函数显示数据集分类列中每个值的计数。在这一步中,我注意到在“reason_for_stop”列中有一个问题,因为一些行被标上了新的原因,尽管已经为该原因建立了一个类别。例如,虽然已经有许多因“酒后驾车检查”而发生的停车,但有几个停车将“违章行驶|酒后驾车检查”列为其“停车理由”。后退一步,我返回到数据清理和准备步骤来修复所有出现的错误。

这种情况说明了数据科学过程的一个关键方面;虽然将数据科学过程视为从数据预处理到 EDA 再到数据分析/建模的一系列线性步骤更容易,但事实是,大多数时候,您必须后退一步来处理数据中以前无法预见的问题。

接下来,我在熊猫的交叉表函数的基础上定义了一个函数,来构建两个因素的比例交叉表。使用这个函数,我生成了一个表,该表比较了由于交通拦截的每个独特原因而被逮捕的人的种族比例。然后将该表可视化为条形图,以便针对每个停车原因,可以比较每个种族群体因交通停车而被捕的比例。

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

黑人被逮捕的比率似乎已经高于其他人群,特别是当逮捕的理由是“违反 MPC”和“BOLO/APB/逮捕证”时。

假设检验

要回答我的问题,我需要一些具体的证据,而不仅仅是条形图。在这种程度上,我将利用假设检验,即当分析师使用样本数据来检验假设,以对样本应该代表的总体做出陈述。在我可以使用的许多具体测试中,我使用了一个双比例 Z 测试,它可以用来确定两个样本比例之间的差异是否显著。

进行假设检验时,陈述你的零假设和你的替代假设是至关重要的,零假设是关于你的总体参数的陈述,替代假设直接与零假设相矛盾。例如,我的无效假设表明,因 SFPD 交通拦截而被捕的黑人比例小于或等于因 SFPD 交通拦截而被捕的所有其他种族的人的比例。另一方面,我的另一个假设认为,由于 SFPD 的交通堵塞而被捕的黑人的比例大于所有其他种族的人由于 SFPD 的交通堵塞而被捕的比例。

下一步是决定重要性水平。进行假设检验允许您使用检验统计量计算 p 值,如果 p 值小于显著性水平,则拒绝零假设,反之亦然。对于我的 Z 检验,我将显著性水平设置为 0.01。

现在,是 Z 测试的时候了。使用stats models proportions _ ztest 函数,我计算了 Z 值和 p 值,比较了因 SFPD 交通拦截而被捕的黑人比例和因 SFPD 交通拦截而被捕的所有其他种族的人的比例。当考虑整个数据集时,通过前面提到的零假设、替代假设和显著性水平,我的 Z 测试的结果使我拒绝了零假设,并得出结论,由于 SFPD 的交通堵塞,黑人比其他种族的人被捕的比率更高。然后,我重复了这个过程,这一次,在进行 Z 测试之前,对每个“停止原因”的数据集进行子集化。这一步的结果如下所示。

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

每个停止原因的 Z 测试结果

因此,尽管在整个数据集中,黑人的被捕率高于其他种族的人,但这种被捕率的差异仅在考虑因“机械或非移动违规(V.C .)”、“BOLO/APB/Warrant”、“移动违规”和“MPC 违规”而导致的交通堵塞时才一致。

中产阶级化和交通堵塞

在摆弄数据集时,我对旧金山县正在进行的中产阶级化和交通站数量之间的关系产生了好奇。因此,我决定将我的项目向前推进一步,看看中产阶级化和交通堵塞之间是否存在关联。

首先,我必须确定我将使用什么指标来定义中产阶级化。受这篇文章的启发,我决定用收入和教育程度来定义中产阶级化。

接下来,我必须弄清楚如何专门为旧金山获取这些数据。幸运的是, CensusData Python 包提供了对美国社区调查数据的访问。随着美国人口普查局的官方文件,我发现了 2009 年至 2015 年旧金山县居民的家庭工资或薪金总收入和最高教育水平。

为了将这些指标与 SFPD 在 2009-2015 年间每年进行的交通拦截次数进行比较,我必须首先将数据重新调整到 0 到 1 之间,以便更好地直观比较这些指标的变化情况:

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

假设由于工资或薪金而增加的家庭总收入和拥有研究生或专业学位的居民比例的增加表明中产阶级化的增加,那么 SFPD 每年进行的交通检查次数似乎会随着中产阶级化而减少(除非从 2014 年到 2015 年交通检查大量增加)。为了找到这种说法的具体证据,我找到了最高教育程度、工资或薪水导致的家庭总收入以及一年中停车次数之间的相关性:

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

教育程度、总收入和交通站点之间的相关性

从上面的热图中,我们可以明确地得出结论,我们的两个中产阶级化指标和每年的交通停车数量之间存在适度的负相关。当然,这个结论应该有所保留,因为中产阶级化比我使用的两个指标要复杂得多。

结论

通过这个项目,我在旧金山警察局进行的交通拦截中发现了种族歧视。具体来说,在旧金山,黑人因交通堵塞而被捕的比率高于其他所有种族。

此外,我发现旧金山的中产阶级化与 SFPD 在 2009 年至 2015 年期间进行的交通拦截数量之间存在适度的负相关。这意味着,随着旧金山日益中产阶级化,交通拦截的数量下降。

用于这个项目的代码可以在这里找到。

作为免责声明,受雇于 SFPD 并不能使个人成为种族主义者 。SFPD 作为一个组织,表现出种族主义的模式,这可能源于各种来源,如警察培训、部门文化等。但这并不能证明 SFPD 官员是种族主义者。

疾病传播预测模型

原文:https://towardsdatascience.com/disease-spread-forecast-modeling-9bbb6ea552ed?source=collection_archive---------42-----------------------

预测器、结果、建模方法

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

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

斯科特·韦伯在 Unsplash 拍摄的照片

我们现在正在新冠肺炎看这出戏。预测疾病传播(尽我们所能)对于如何应对至关重要,例如制定短期策略和长期战略。是否(以及何时)封锁地区或整个国家。是否采取限制较少的措施。预测所需的资源,如急救人员、医生、护士、个人防护设备、医院病床、ICU 病床、呼吸机等,可以确定缺口,并对决定下一步的工作重点至关重要。

先进的预测模型还允许最坏情况和最好情况的预测,以及对各种假设情景的预测,例如当 50%的公众与 90%的公众保持社交距离时的预测。

当疾病发生在像新冠肺炎这样的全球疫情时,传播预测变得尤其重要。在建模方面,它也非常复杂。所以这是一个很好的案例研究。

让我们开始吧。

疾病状态

最简单的区别可能是二元的:个体是否被感染。假设有一个测试可以可靠地揭示一个人的状态。假设群体中的个体每天都被测试。一天内新感染的人正在被统计。

这为我们提供了新感染计数的每日时间序列。我们可以想象这一点,并发现趋势。感染人数呈指数增长吗?变平了?我们甚至可以预测未来几天的价值。

我们可以用各种方式对人口进行分割,重复这一过程:全球的、特定国家的、美国国内的国家。我们甚至可以跨区域比较时间序列,以算法或视觉方式预测下一个热点将在哪里以及何时到来。

好的,所以我们可以根据该人群的历史感染人数,也可能根据其他人群的历史感染人数来预测近期的感染人数。但是有多好呢?这取决于许多因素。

一个潜在的巨大因素是测试的能力或意愿。有些国家(或州)可能会积极地进行测试,有些则不那么积极。这将严重影响他们的感染人数。此外,如果人群中的检测率发生显著变化(这种情况会经常发生),每天的新感染人数也会受到影响。新的感染人数可能会增加,因为我们正在测试更多的人。

到目前为止,我们讨论的二元疾病状态模型没有区分轻度和重度病例。显然这样做是有益的。在我们预测的新感染病例中,有多少可能严重到需要住院治疗?有多少人严重到需要重症监护?我们做出这种精细预测的能力可能是预测我们将需要多少病床的关键;我们需要多少特殊设备,如通风机;等等。

好的,那么让我们把感染分为轻度中度重度。我们需要另一种疾病状态:死亡。显然很重要。我们想知道预计会有多少人死亡。其实还有一个:恢复了

让我们假设我们可以(合理地)准确确定谁在什么时间点处于什么状态,从住院计数,从 ICU 计数,太平间数据等。我们可以用这些数据来估计状态概率和状态转移概率。

轻度对中度对重度感染者的百分比是多少?严重者最终死亡的百分比是多少?恢复的百分比是多少?从轻度中度或者从中度重度有(有时)进展吗?

我们还可以估计发生各种转变所需的时间?最终康复的重症患者的平均康复时间是多少?几天?几周?

所有这些都可以表示为一个马尔可夫模型。节点是疾病状态。弧线携带从一个状态到另一个状态的转移概率。这在下面描述。没有显示所有转换。

healthy → mild, mild → recovered, mild → moderate, severe → recovered, severe → died

https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5871642/中的图 1 描绘了一个疾病进展模型,其主要状态为易感暴露感染痊愈。从结构上看,模型中的主要路径是

susceptible → exposed → infected → recovered

建模延迟

考虑过渡exposed →infected。到目前为止,我们的建模揭示了这种转变的一个可学习参数, P ( 已感染 | 已暴露),它表示暴露个体被感染的概率。如果我们怀疑这个概率随着时间的推移而变化,我们可以尽可能频繁地重新估计这个概率,以保持它是最新的。

到目前为止,该模型没有考虑潜伏期,即暴露者感染所需的时间。潜伏期很大程度上取决于疾病。扩展该模型以包含这一点将让我们预测,除了暴露者中有多少比例会被感染,还有他们什么时候会被感染。这反过来可以对疾病传播做出更准确的预测。

我们如何增强我们的模型以适应潜伏期?一个想法是用特定时间的版本exposed(t)代替exposed。后者代表在时间 t 暴露的个人。虽然可能不知道任何一个人的确切情况,但是可以获得某一天接触到的人数的一个很好的估计。同样,我们可以用infected(t)代替infected。所以现在我们可以获得对任何特定滞后 dP ( 感染(t+d)|暴露 ( t )的估计。这可以利用关于潜伏期的知识。

基本再现号

这是对一个感染者平均感染多少人的估计。准确的估计对预测疾病的传播非常有用。大于 1 的值表示指数增长,而小于 1 的值表示指数收缩。显然,知道我们在哪里是很重要的。

基本再生数对于进行定性预测特别有帮助。新冠肺炎的基本繁殖数大于 1,明显高于季节性流感。所以新冠肺炎以指数速度传播。即使这种预测只是方向性的,它仍然是有用的。尤其是在早期阶段。

出行模式

旅行模式也有助于预测。假设疫情在 A 国爆发。假设从 A 国到 B 国的旅行很多,从 A 国到 c 国的旅行更少。预测 B 国将比 c 国更快开始“感受到疫情”似乎是合理的。

另一种旅行模式是季节性的。旅游季节(比如假期)的疫情可能会比一年中的其他时间传播得更快。

干预

在疫情期间,某些干预措施可能会成为疾病传播的抑制剂。在新冠肺炎,主要原因是社交距离。哪些地理位置在何时以及在何种程度上进行了干预。(我们所说的“程度”是指严重程度,如封锁、旅行建议等。)捕捉这样的数据在建模中非常有用。

干预数据在多大程度上有助于提高预测质量?不好说。在特定的环境中,可能存在多种相互竞争的力量,如疾病传播和干预。如果我们不进行干预,我们可能无法轻易判断情况会有多糟糕。

也就是说,获取和使用干预数据总比没有好。我们总可以在以后整理出它有多有用。如果我们不抓住它,我们甚至没有追索权。

考虑几个月后的全球疫情。假设我们知道哪些地理实体(国家、州、县或城市)在何时以及在何种程度上引入了哪些干预措施。我们还知道哪些还没有。将这些数据与感染前和感染后的计数相关联,在超过 100 个地理实体中进行,可能会开始产生一个明确的图像。

把所有的放在一起

假设我们想要预测某个特定的地理区域(国家、州、县)。或城市)新感染人数在接下来的一周(7 天)内,可能会进一步细分为轻度中度重度痊愈,以及死亡。下面我们盘点了这篇文章中所有可能有助于预测的因素。本质上,这一部分是我们在这篇文章中看到的内容的总结,在这个特定的预测问题的背景下呈现。

预测因素的一个关键组成部分是该地区近期感染计数的时间序列。我们可以将此进一步细分为每日新增的轻度*、中度重度康复,以及死亡。*

这种预测因子的组合可以通过我们前面描述的疾病进展模型的类型来增加。这里有一个场景,描述了这样做的意义。假设昨天我们有一些新的温和的计数。根据我们的疾病状态进展模型,我们可以预测这些计数中有多少将在各种其他状态下结束以及何时结束。显然,这在我们的预测问题中是有用的。此外,请注意,我们的疾病进展模型利用了领域知识,如潜伏期。因此,我们的预测者也可以从这些领域知识中受益。如果该位置处于疾病爆发的早期阶段,这可能特别有用。

我们的预测模型还应该尽可能利用已知的基本再生产数量。这在疫情爆发的早期阶段可能特别有帮助,因为我们可能没有足够的实际新感染天数来进行预测。

如果旅行模式被认为是相关的,我们的预测模型也可能考虑到它们。如果疾病已经在某个地区广泛传播,并且从该地区到我们所在地的旅行很重要,就可能出现这种情况。或者我们的位置是否处于“旅游季节”状态。

我们的预测模型也可能使用我们所在位置的当前干预状态作为预测器。干预是什么时候进行的?它的严重性是什么:锁定?旅游咨询?….在有很多人来往的地方使用干预状态也可能有所帮助。

假情报:如何通过可视化理解假情报网络

原文:https://towardsdatascience.com/disinfovis-how-to-understand-networks-of-disinformation-through-visualization-b4cb0afa0a71?source=collection_archive---------22-----------------------

数据可视化在清晰地表达复杂性方面有着巨大的潜力,但这需要迭代、移情和针对特定数据和领域的定制。

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

图片作者。

假情报行动的网络可视化具有启发的力量。当有效设计时,它们可以表达那些散布假信息的人的微妙策略。这些密集形式的数据可视化受益于贯穿其开发的明智的设计选择,以及改进未来迭代的评估。

去年,我从伦敦大学城市学院的数据科学硕士学位毕业。这个为期一年的特别强化课程教会了我机器学习、神经计算、计算机视觉和视觉分析的基础知识。在我为期三个月的论文项目中,我选择了网络分析作为我研究的领域。特别是,我专注于网络可视化的设计和评估,随着时间的推移,应用于虚假信息领域。

毕业后,我继续研究时间网络及其在虚假信息研究中的应用。2020 年初,我发表了一篇名为“观察六个长达十年的假情报行动在六分钟内展开”的媒体文章,它有点像病毒一样传播开来。我目前在蒙田研究所研究针对法国的虚假信息,并在威尔逊中心通过网络分析研究性别化和性化的虚假信息。我所有的研究都有一个共同的线索,那就是使用网络可视化来理解那些想要在网上影响他人的人的策略是如何随着时间的推移而演变的。

今天我想后退一步,告诉你我的时态网络可视化的设计选择是如何在我的理学硕士论文完成过程中发展的。这项工作得到了伦敦大学城市数据科学研究所的慷慨支持,并得到了我在城市的学术顾问,世界领先的可视化研究小组之一 giCentre 的 Jason Dykes 教授的指导。我们在 EuroVis 2020 上以反病毒的适当标题展示了这篇论文研究的海报。

如果您对数据可视化设计感兴趣,希望您会对我的方法感兴趣。如果你对虚假信息网络感兴趣,希望你会发现可视化信息丰富,可视化方法有用(在各种其他研究报告中有记录)。如果你正在考虑在理学硕士水平上学习数据科学,你可以用这篇文章作为一篇理学硕士论文的例子。

继续我的论文,题目是…

评估信息操作的时间网络可视化表示

这里关键的活动部分是,在这项研究中,我评估了三种时间网络可视化的两种不同表示(静态幻灯片和动态视频)。我使用的数据集是 Twitter 自 2018 年以来一直在识别和发布的中国、俄罗斯和委内瑞拉的信息操作

这篇论文的目标是了解哪种表示类型的假情报实践者认为最有用,以便未来时态网络可视化的设计可以根据他们的需要进行定制。我通过回答两个相关的研究问题实现了这个目标,第一个是数据科学,第二个是社会科学研究问题:

研究问题 1: 时态网络可视化的静态和动态表示有什么好处和挑战?

研究问题 2 :俄罗斯、中国和委内瑞拉国家支持的推特信息运作有哪些独特和共有的方面?

这两个问题是数月思考、编辑、阅读和思考的结果。总的来说,人们好奇的是时间网络可视化是否有助于确定俄罗斯、中国和委内瑞拉等国家在多大程度上拥有其竞选活动的独特在线“指纹”。创建动态和静态可视化的选择随着时间的推移而发展,因为我在思考如何通过时间网络分析的方法最好地贡献在线虚假信息的领域知识。

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

委内瑞拉信息运作随时间演变的例子。图片作者。

这些方法

我的项目包括两个阶段的方法。首先,我在 Twitter 上创建了俄罗斯、中国和委内瑞拉信息运作的时间网络可视化。这是基于我对可视化设计中一些已确立的最佳实践的理解。然后,我通过在结构化采访中向造谣者展示这些网络来评估它们。在采访中,参与者描述了他们如何与网络互动,以及他们在其中看到了什么。

网络可视化本身的数据来自不真实账户(有时被称为机器人、电子人或巨魔)发布的推文,这些账户“可能是 Twitter 上国家支持的信息操作的一部分。自 2018 年以来,Twitter 发布了用户资料和推文的数据集,他们认为这些数据是国家支持的行为者在他们的平台上从事“不真实行为”的更广泛网络的一部分。发布这些数据是为了“研究人员可以调查、学习和建立未来的媒体素养能力”。

Twitter 已经发布了 16 个国家(还在增加)的数据,但在这项研究中,我选择只分析来自中国、委内瑞拉和俄罗斯信息运营部门的英语推文,这些推文都包含大量英语内容。这个决定是为了在三个月的项目时间框架内捕捉英语在线对话中的外国干扰,是一个主观选择,框定了我的整个研究及其结果。在随后的研究中,我扩展到可视化六个国家的所有语言。

为了进一步研究数据,我选择只可视化不真实账户使用的标签。换句话说:我的可视化所需要的只是不真实账户的名称(源)和他们使用的所有标签(目标)。这些源和目标(总是按国家分开)在网络可视化中被连接起来。这些连接线(边缘)是按照虚假账户创建的年份进行颜色编码的,以保留更多的可视化内容。

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

显示连接到目标(标签)的源(非真实帐户)的简化图形。图片作者。

为了让我的参与者(虚假信息从业者)更容易理解时间网络可视化,我制作了这个“网络可视化介绍”视频(以及相同信息的幻灯片)供我的参与者观看:

网络可视化介绍。作者视频。

在将英语委内瑞拉语、俄语和中文的不真实账户分解为标签关系后,它们被分别上传到 Gephi 。Gephi 是一个开源的网络可视化软件,它可以通过时间元素来分解可视化。对于每个国家,由于 Gephi 的内存限制,30 万条推文的随机子集被可视化。

在网络可视化中有许多不同的方式来排列节点(称为布局算法)。我选择使用 ForceAtlas2,因为它吸引密切相关的节点,排斥不相关的节点,并在网络中紧凑地布置“突发”。

在我将一个国家数据集上传到 Gephi 后,我运行了 ForceAtlas2 布局算法,按帐户创建年份进行颜色编码,最后将网络转换为时态网络可视化,以便查看网络不同区域的活动时间。这样做的时候,在软件窗口的底部出现了一个切换栏,允许我挑出在特定时间段发生的非真实用户和标签之间的联系。Gephi 的这种可提供性是这个项目中使用该软件的一个重要原因。下面你可以看到整个中国网络的可视化(左),以及一年的网络切片(右):

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

全中文网络可视化(左),以及 Gephi 软件中显示的 2017 年同一网络可视化中使用的标签(右)。右边的图像是网络的“时间片”,它构成了静态幻灯片中的一张幻灯片。图片作者。

创建静态表示

幻灯片首先显示了整个网络,然后是同一网络的 5-8 个时间片段。这是中国数据集的最终幻灯片:

中文信息操作的静态表示。作者幻灯片。

创建动态表示

为了让这项研究有两个可比较的表示,我还在 Gephi 中记录了网络的发展,并创建了与幻灯片中的文本完全相同的画外音解释。结果是 YouTube 上的这个中国可视化视频:

中文信息操作的动态表示。作者视频。

评估时间网络可视化表示

鉴于对领域专业知识的需求,在这种情况下,根据 Sheelagh Carpendale 关于信息可视化评估的指南进行了一项狭窄而丰富的定性研究:

“使用完整的数据集、领域特定的任务和领域专家作为参与者来运行评估,将有助于为给定信息可视化的有效性开发更加具体和现实的证据。”

一小部分致力于了解、打击或告知公众网上虚假信息的领域专家是通过滚雪球抽样方法发送的电子邮件邀请招募的。这导致了 5 次会议,参与者进行培训,探索可视化,然后通过结构化访谈提供定性反馈。

通过转录响应和进行主题分析(如 Fereday 和 Muir-Cochrane,2006 所述)来分析数据,这些分析总结了参与者对他们在与可视化交互时所面临的好处和挑战的反应,他们对未来可视化的建议,以及他们对网络本身的分析。

通过向领域专家询问他们对可视化的印象和体验,我能够收集到由虚假信息网络知识提供的发现,并围绕可视化的可能最终用户。这似乎很适合数据科学论文,因为任何数据分析过程的最后阶段(与需要分析的利益相关者的沟通)都依赖于数据可视化的有效使用。

结果呢

这项研究的结果可以根据他们回答的研究问题进行细分。对于第一个研究问题,我想知道我的参与者所经历的好处和挑战的答案,以便在虚假信息研究的背景下为未来的网络可视化设计选择提供信息。对于第二个研究问题,我希望进入我的参与者的头脑,了解他们在网络中实际看到的*。*

研究问题 1:时态网络可视化的静态和动态表示有什么好处和挑战?

这个研究问题是在采访中通过询问参与者哪个表征更容易观察或给他们足够的信息,以及每个表征的哪个部分在试图理解他们正在看的东西时更有帮助来解决的。每个问题的不同回答根据被提及的次数进行统计,并整理成表格。

**研究结果:**我发现参与者更喜欢信息操作的复杂时间网络可视化的动态表示,或视频。这在很大程度上是因为每个参与者都认为视频让他们更好地了解了网络随着时间的演变,并评论说视频使他们更容易理解“不同活动时期之间的巨大差异”。虽然参与者喜欢按照自己的节奏浏览静态幻灯片,但五分之四的参与者更喜欢动态或动态和静态相结合的方式来分析网络或向他人解释网络。

**下一步:**这些发现让我们能够为未来的设计提出建议。我们建议使用在关键时刻和更大的上下文信息之间有停顿的交互式动态表示。我们已经制作了这样一个工具的线框——一个通过可视化展示我们建议的概念设计。

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

提议的具有静态和动态元素的时间网络可视化线框(在 EuroVis 2020 上展示)。图片作者。

我从这项研究中学到的关于视觉化设计的一个关键要点也是我在学习专业沟通时学到的:根据你的媒介和受众定制你的信息。使用可视化作为媒介的美妙之处在于,它可以是交互式的、信息丰富的,并且具有无限的设计选择。在我为 Mozilla 做的研究中(我在完成这项研究后进行了这项研究),我决定不实施上面的一些更详细的建议,而是采用一种我认为更适合中型文章的更简单的格式,因为我的目标是解释网络并告知公众,而不是给他们可探索或可调查的可视化。在可视化的目的是允许探索和研究的未来迭代中,更复杂的可视化设计可能是合适的。

研究问题 2:俄罗斯、中国和委内瑞拉国家支持的推特信息运作有什么独特和共同之处?

这个研究问题是在采访中通过询问参与者网络的哪些方面对他们来说是独特的,或者在多个网络之间是共享的来解决的。根据是否需要理解网络结构、hashtag 内容和时态成分,对独特和共享的方面进行了汇总和分析。下图显示了调查结果。

**研究结果:**通过分析时间网络可视化,参与者注意到信息操作是循环的、动态的,并且随着时间的推移而演变。他们还发现,一些行动似乎比其他行动更有组织性和政治性,俄罗斯的活动在其网络结构中独特地表现出两极分化。俄罗斯和中国都被发现使用#followme 等越来越受欢迎的标签,并在 2016 年和 2019 年恢复了早在 2009 年的旧账户。这些行为表明行动是长期战略的一部分。另一方面,委内瑞拉没有表现出这两种行为,并且可能在使用账户角色上有一个不太完善的策略。

下图概述了与会者提到的信息运作的主要方面。有些是个别国家独有的,有些是两个或所有三个国家共有的。

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

俄罗斯、委内瑞拉和中国在推特上的信息运作的异同。结果按照提出要求的参与者人数(“p”)和被提及的总次数(“x”)排序。图片作者。

每个方面右侧的红色字母表示识别它们所需的信息属性。它们是:标签的内容(“C”),交互的结构(“S”),以及操作的时间(“T”)演变。这三个信息属性是在主题分析中导出方面之后开发的。根据识别每个方面所需的数据类型来识别它们。使用两个或三个信息属性的方面可以认为是更健壮的,比如发现所有的信息作战战术都是随时间演化的。hashtag 内容和时间演变等方面可以使用不同的方法来可视化,比如词频表或条形图。内容和时间发现的稳健性以及网络结构发现可以在进一步的研究中探索。

那么,下一步是什么?

在这篇理学硕士论文上的工作经历教会了我通过评估和迭代为设计选择提供信息的价值。它还巩固了为特定领域(如在线虚假信息)定制数据可视化设计的好处。

当我继续在牛津大学攻读社会数据科学的哲学博士学位,研究虚假信息网络时,我将带着我通过这个项目以及通过完成 EuroVis 海报所吸收的设计价值观。通过谨慎而系统地推进这类研究,我们可以对虚假信息、网络可视化以及两者之间的有益关系有更深入的了解。

用 Math 和 Pytorch 分解神经网络以理解其内部运作

原文:https://towardsdatascience.com/dismantling-neural-networks-to-understand-the-inner-workings-with-math-and-pytorch-beac8760b595?source=collection_archive---------21-----------------------

简化的数学与例子和代码,以揭示黑盒内的光

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

弗洛里安·克劳尔在 Unsplash 上拍摄的照片

动机

作为一个孩子,你可能会在狂热的好奇心驱使下拆开一个玩具。你可能被它发出的声音的来源吸引了。或者可能是二极管发出的诱人的彩色光召唤你,让你的手去打开塑料。

有时候,你可能会觉得被欺骗了,因为它的内部与外表的光鲜亮丽让你想象的相去甚远。我希望你足够幸运,打开了正确的玩具。那些充满了足够的错综复杂,值得打开它们。也许你发现了一辆未来外观的 DC 汽车。或者可能是一个奇怪的扬声器,背面有一个强磁铁,你在冰箱上试过。我敢肯定,当你发现是什么让你的控制器振动的时候,感觉就很好。

我们也要做同样的事情。我们正在用数学和 Pytorch 拆除一个神经网络。这将是值得的,我们的玩具甚至不会打破。也许你会感到气馁。这可以理解。在神经网络中有如此多不同而复杂的部分。这是压倒性的。这是通往更明智状态的仪式。

所以为了帮助我们自己,我们需要一个参照物,某种北极星来确保我们在正确的方向上。Pytorch 的预建功能将是我们的北极星。他们会告诉我们必须得到的产量。我们有责任找到将我们引向正确输出的逻辑。如果差异听起来像你曾经熟悉的被遗忘的陌生人,不要烦恼!我们会再做一次介绍,这将是非常愉快的。
我希望你会喜欢。

线性

神经元的价值取决于其输入、权重和偏差。为了计算一层中所有神经元的这个值,我们计算输入矩阵与权重矩阵的点积,并添加偏置向量。当我们写道:

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

一层中所有神经元的值。

然而,数学方程的简洁是通过对内部工作的抽象来实现的。我们为简洁所付出的代价是让理解和在头脑中想象所涉及的步骤变得更加困难。为了能够编码和调试像神经网络这样复杂的结构,我们既需要深刻的理解,也需要清晰的思维可视化。为此,我们倾向于冗长:

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

具有三个输入、三个权重和一个偏差的一个神经元的值。

现在,这个等式的基础是一个特定案例所施加的约束:一个神经元、三个输入、三个权重和一个偏差。我们已经从抽象转向了更具体、更容易实现的东西:

为了计算 z ,我们已经从一层输入前进到下一层神经元。当神经网络一路向前通过其层并获得知识时,它需要知道如何向后调整其先前的层。我们可以通过衍生品实现这种知识的反向传播。简单地说,如果我们对 z 的每个参数(权重和偏差)进行微分,我们可以得到输入层 x 的值。

如果你已经忘记了如何求导,请放心:你不会被告知去温习微积分的整个分支。我们将在需要时回忆差异化规则。 z 对一个参数的偏导数告诉你把那个参数看成一个变量,其他所有参数都看成常数。变量的导数等于它的系数。常数的导数等于零:

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

w0 是变量,其他都是常数。w0 的系数是 x0。

同样,你可以相对于w2b来区分 z (其中 b 的不可见系数为 1)。你会发现 z 的每一个偏导数都等于它所微分的参数的系数。考虑到这一点,我们可以用 Pytorch 亲笔签名来评估我们数学的正确性。**

非线性

我们引入激活函数的非线性。这使得神经网络成为通用函数逼近器。有各种类型的激活,每一种实现不同的目的,产生不同的效果。我们将讨论 ReLU、Sigmoid 和 Softmax 的公式和区别。

热卢

整流线性单位函数将神经元的值与零进行比较,并输出最大值。我们可以认为 ReLU 将所有非阳性神经元标记为同样不活跃。

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

所有非负值保持不变,而负值被零取代。

为了实现我们自己的 ReLU,我们可以将 z 与 0 进行比较,并输出较大的值。但是 Torch 包中提供的 夹钳 方法已经可以为我们做到这一点了。在 Numpy 中,等效的函数叫做 clip 。在使用 Pytorch 的 relu 评估其输出之前,以下代码实现了一个基于 clamp 的 ReLU。

ReLU 的区别很简单:

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

“ReLU”为 1 或 0,取决于 z

  • 对于所有正的 z ,ReLU 的输出为 z 。因此微分就是 z 的系数,等于 1。
  • 对于所有非正的 z ,ReLU 的输出等于零。因此,微分也等于零。

让我们把我们的理解翻译成 Python 代码。我们先实现自己的 ReLU’( z )再和 Pytorch 的 ReLU 自动微分进行对比。

**为什么我们要给 backward() 一个 1 的张量?
backward() 默认在单个标量上被调用的情况,并使用默认参数 *torch.tensor(1。)*这是以前我们调用 z.backward()时的情况。由于 torch_relu 不是单个标量,我们需要明确提供一个与 torch_relu 形状相同的张量。

乙状结肠的

sigmoid 激活函数产生从ℝ到范围[0,1]的映射 z 的效果。当执行二进制分类时,我们通常用值 1 标记属于目标类的实例,用值 0 标记所有其他实例。我们将 sigmoid 的输出解释为一个实例属于目标类的概率。

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

sigmoid 激活函数产生从ℝ到范围[0,1]的映射 z 的效果。

****小测验:神经网络的任务是进行二元分类。该网络的输出层由 sigmoid 激活等于 0.1 的单个神经元组成。在下列解释中,哪一个是正确的?

  1. 该实例属于类 1(目标类)的概率为 0.1。
  2. 该实例属于类 0 的概率为 0.1。
  3. 该实例属于类 0 的概率为 0.9。

****解法:只有 1 和 3 是正确的。重要的是要理解,具有一些输出 p 的乙状结肠激活的神经元,对于非目标类隐含地给出了输出 1-p 。同样需要记住的是 p 是与目标类关联的概率(通常标记为 1),而 1-p 是与非目标类关联的概率(通常标记为 0)。

****观察:认为 p(1-p) 之和等于 1。这在现阶段似乎太明显而无法指出,但当我们讨论 Softmax 时,记住这一点将会很有用。

我们再次用 Python 翻译数学,然后用 sigmoid 的 Pytorch 实现检查我们的结果:

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

乙状结肠分化。

乙状结肠的分化是优雅的。然而,它确实需要一条曲折的道路来达到它的优雅。一旦我们回忆起一些微分规则,我们就有了在蜿蜒的道路上漫步所需的一切。

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

乙状结肠的详细分化。

了解了如何区分 sigmoid,我们现在可以实现数学,并用 Pytorch 的亲笔签名对其进行评估。

注: sigmoid_prime() 依赖于前面实现的同一个 sigmoid()

如今,ReLU 已被广泛用作乙状结肠的替代物。但是 sigmoid 仍然在附近徘徊,隐藏在它的更一般化的形式的名字之下:Softmax。

Softmax

我们想到 sigmoid 用于二分类,softmax 用于多类分类。这种联系虽然是正确的,但却误导我们许多人认为 sigmoid 和 softmax 是两种不同的函数。当我们查看 sigmoid 和 softmax 的方程时,这一点得到了强调,它们之间似乎没有明显的联系。

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

softmax 激活的神经元是其值的指数除以共享同一层的所有其他神经元的指数之和。

再一次,公式的抽象使它乍一看一点也不直观。举个例子会更具体。我们以两个输出神经元为例,第一个 (z0) 输出实例属于标记为 0 的类别的概率,第二个 (z1) 输出实例属于标记为 1 的类别的概率。换句话说,对于 z0 目标类标记为 0,对于 z1 目标类标记为 1。为了用 softmax 激活 z0z1 ,我们计算:

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

Softmax 应用于输出层中的每个神经元。除了将来自ℝ的所有神经元映射到范围[0,1]之外,它还使它们的值相加为 1。

现在,我们可以纠正乙状结肠和 softmax 之间似乎缺乏明显的联系。我们将通过简单地重写 sigmoid 来做到这一点:

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

sigmoid 的另一种写法,显示它实际上是 softmax,有两个类。

第一种形式的乙状结肠比第二种形式的更常见。这是因为后一个版本在计算上更昂贵。然而,它的优势仍然在于帮助我们理解 softmax。

在输出层只有两个神经元,并且给定 softmax 使所有输出神经元总和为 1 的事实:我们总是知道soft max(z0)将等于【1-Softmax(z1) 。因此,对于二进制分类,将视为等于 0 是有意义的,并且使用 sigmoid 仅计算 z1 的激活。**

下面的代码实现了 softmax,并以三个输出神经元为例进行了测试。然后将我们的结果与 Pytorch 的 softmax 的结果进行比较。

我们根据每个神经元区分 softmax 激活。保持具有两个神经元的输出层的相同示例,我们得到四个 softmax 微分:

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

softmax 的雅可比矩阵。

不考虑输出神经元的数量,softmax 微分只有两个公式。当我们对神经元相对于其自身的 softmax 进行微分(雅可比矩阵中左上和右下的微分)时,应用第一个公式。当我们将一个神经元的 softmax 相对于某个其他神经元进行微分(雅可比矩阵中右上和左下的微分)时,应用第二个公式。

为了理解 softmax 的差异化所涉及的步骤,我们需要回忆另一条差异化规则:

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

除法法则。

以下差异包含详细的步骤。虽然它们看起来很密集,看起来令人生畏,但我向你保证,它们比看起来容易得多,我鼓励你在纸上重做它们。

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

softmax 的详细偏微分。

softmax 微分的实现要求我们遍历神经元列表,并对每个神经元进行微分。因此涉及两个循环。请记住,这些实现的目的不是为了提高性能,而是为了显式地翻译数学,并达到 Pytorch 的内置方法所达到的相同结果。

交叉熵损失

在神经网络所涉及的操作序列中,softmax 之后通常是交叉熵损失。事实上,这两个函数联系如此紧密,以至于 Pytorch 中的方法 cross_entropy 将两个函数合二为一。

我记得当我看到交叉熵损失的公式时的第一印象。这是接近欣赏象形文字。解读之后,我希望你能和我一样,对简单的想法有时会有最复杂的表现感到敬畏。

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

交叉熵损失函数。

参与计算交叉熵损失的变量有 pymK 。都以 ik 为计数器,分别从 1 迭代到 mK

  • Z : 是一个数组,其中每一行代表一个实例的输出神经元。 m : 是实例数。
  • K : 是班级人数。
  • p : 是实例 i 属于类 k. 的神经网络的概率,这与从 softmax 计算的概率相同。
  • y : 是实例 i 的标签。根据 y 是否属于类 k 为 1 或 0。
  • log : 为自然对数。

假设我们正在执行一个多类分类任务,其中可能的类的数量是三个( K =3)。每个实例只能属于一个类。因此,每个实例被分配给一个带有两个 0 和一个 1 的标签向量。例如y**=【0,0,1】表示 y 的实例属于类 2。同样,y=【1,0,0】**表示 y 的实例属于 0 类。1 的索引是指实例所属的类。我们说标签是一键编码*。*****

现在我们来举两个实例( m =2)。我们计算它们的 z 值,我们发现: Z = [[0.1,0.4,0.2],[0.3,0.9,0.6]]。然后我们计算他们的 softmax 概率,发现: 激活 = [[0.29,0.39,0.32],[0.24,0.44,0.32]]。我们知道第一个实例属于类 2,第二个实例属于类 0,因为: y = [[0,0,1],[1,0,0]]。

要计算交叉熵:

  1. 我们取 softmax 激活的日志: log(激活 ) = [[-1.24,-0.94,-1.14],[-1.43,-0.83,-1.13]]。
  2. 我们乘以-1 得到负对数:-log(激活)= [[1.24,0.94,1.14],[1.43,0.83,1.13]]。
  3. 将 log(activations)乘以 y 得出:[[0。, 0., 1.14], [1.43, 0., 0.]].
  4. 所有类别的总和给出:[[0。+0.+1.14], [1.43+0.+0.]] = [[1.14], [1.43]]
  5. 所有实例的总和为:[1.14+1.43] = [2.57]
  6. 除以实例数得到:[2.57 / 2] = [1.285]

观察:

  • 步骤 3 和 4 相当于简单地检索目标类的负日志。
  • 第 5 步和第 6 步相当于计算平均值。
  • 当神经网络预测实例以 0.32 的概率属于目标类时,损失等于 1.14。
  • 当神经网络预测实例以 0.24 的概率属于目标类时,损失等于 1.43。
  • 我们可以看到,在这两种情况下,网络未能给正确的类最高的概率。但是与第一个实例相比,网络更确信第二个实例不属于正确的类。因此,它被处以 1.43 英镑的更高损失。

在交叉熵的实现中,我们结合了上述步骤和观察结果。像往常一样,在比较两个输出之前,我们还将经历 Pytorch 等效方法。

注意:**我们不是存储标签的独热编码,而是简单地存储 1 的索引。比如之前的 y 变成了【2,0】。注意,在索引 0 处, y 的值是 2,而在索引 1 处, y 的值是 0。使用索引 y 及其值,我们可以直接检索目标类的负日志。这是通过访问第 0 行第 2 列和第 1 行第 0 列的-log(activations)来完成的。这使得我们可以避免第 3 步和第 4 步中浪费的乘法和零加法。这个技巧叫做整数数组索引,杰瑞米·霍华德在他的《基础深度学习》第 9 讲 34:57 中解释了这个技巧

如果向前穿过神经网络的层可以被看作是获取某种知识的旅程,那么这里就是可以找到知识的地方。使用损失函数的微分可以通知神经网络它在每个实例上有多少误差。把这个误差倒过来看,神经网络可以自我调整。

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

交叉熵微分。

在回忆了几个微分规则后,我们将经历交叉熵的微分步骤:

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

回想一下这两条微分法则。还记得 lnlogbasede**是一样的。 e 贯穿全文。****

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

交叉熵微分步骤。

我们还不能用 Pytorch 的输出来评估下面的实现。原因要追溯到 Pytorch 的 cross_entropy 结合 softmax 和 cross-entropy。因此,使用向后也会涉及链规则中 softmax 的微分。我们将在下一节“反向传播”中讨论和实现这一点。现在,这是我们对交叉熵的实现:

反向传播

对于我们讨论的每一个函数,我们都在神经网络的层中前进了一步,并且我们还利用函数的微分进行了等效的后退。由于神经网络在往回走之前一直向前移动,我们需要讨论如何连接我们的功能。

向前

一路向前,具有一个隐藏层的神经网络从将输入馈送到线性函数开始,然后将其输出馈送到非线性函数,然后将其输出馈送到损失函数。以下是具有实例 x 的示例,其对应的标签 y ,三个线性神经元 z ,每个神经元使用其三个权重 w 和一个偏置b***计算,后跟一个 softmax 激活层和一个交叉熵损失。*****

向后的

一路回溯,同一个神经网络从给予损失函数的相同输入开始,并将其馈送给该损失函数的导数。损失函数的导数的输出就是误差,我们称之为获得的知识。为了调整其参数,神经网络必须将该误差再向后一步带到非线性层,并从那里再向后一步到线性层。

下一步不是简单地将误差反馈给非线性函数的导数。我们需要使用链式法则(我们之前在 sigmoid 的微分中回忆过),我们还需要注意我们应该给每个导数的输入。

前馈和反向传播的关键规则:

  • 函数及其导数接受相同的输入。
  • 函数向前发送它们的输出,作为下一个函数的输入。
  • 导数将其输出向后发送,以乘以前一个导数的输出。

愿你的机器的输出总是与你的数学相一致。

结论

我的印象是,很多来自不同学科背景的人都对机器学习充满好奇和热情。不幸的是,有一种合理的趋势,即在试图远离令人生畏的数学的同时获取知识。我认为这很不幸,因为我相信许多人实际上渴望加深他们的理解;要是他们能找到更多的资源就好了,因为他们来自不同的背景,可能到处都需要一点提醒和一点鼓励。

这篇文章包含了我写读者友好的数学的尝试。我指的是提醒读者需要遵循的规则的数学。我的意思也是数学和方程,避免跳过这么多步骤,让我们思考一行和下一行之间发生了什么。因为有时候我们真的需要有人牵着我们的手,和我们一起走过陌生概念的领域。我真诚地希望我能牵到你的手。

参考

米(meter 的缩写))胺,神经网络的内部运作,我的 Colab 笔记本 (2020)。
M. Amine,神经网络的内部工作原理,我的 Gists ,(2020)。
A. Géron,用 Scikit-Learn、Keras 和 TensorFlow 进行动手机器学习,(2019)。
S. Gugger,numpy中的一个简单神经网络,(2018)。
J. Howard, Fast.ai:从基础开始深度学习第 9 课,(2019)。
py torch 文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值