数据专栏

智能大数据搬运工,你想要的我们都有

科技资讯

科技学院

科技百科

科技书籍

网站大全

软件大全

之前我看了一个关于“NLP的实践特性工程”的演讲。主要是关于LIME和SHAP在文本分类可解释性方面是如何工作的。
我决定写一篇关于它们的文章,因为它们很有趣、易于使用,而且视觉上很吸引人。
所有的 机器学习 模型都是在更高的维度上运行的,而不是在人脑可以直接看到的维度上运行的,这些机器学习模型都可以被称为黑盒模型,它可以归结为模型的可解释性。特别是在NLP领域中,特征的维数往往很大,说明特征的重要性变得越来越复杂。
LIME & SHAP不仅帮助我们向最终用户解释NLP模型的工作原理,而且帮助我们自己解释NLP模型是如何工作的。
利用 Stack Overflow 问题标签分类数据集,我们将构建一个多类文本分类模型,然后分别应用LIME和SHAP对模型进行解释。由于我们之前已经做过多次文本分类,所以我们将快速构建NLP模型,并着重于模型的可解释性。
数据预处理、特征工程和逻辑回归 import pandas as pd
import numpy as np
import sklearn
import sklearn.ensemble
import sklearn.metrics
from sklearn.utils import shuffle
from __future__ import print_function
from io import StringIO
import re
from bs4 import BeautifulSoup
from nltk.corpus import stopwords
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score
import lime
from lime import lime_text
from lime.lime_text import LimeTextExplainer
from sklearn.pipeline import make_pipeline
df = pd.read_csv('stack-overflow-data.csv')
df = df[pd.notnull(df['tags'])]
df = df.sample(frac=0.5, random_state=99).reset_index(drop=True)
df = shuffle(df, random_state=22)
df = df.reset_index(drop=True)
df['class_label'] = df['tags'].factorize()[0]
class_label_df = df[['tags', 'class_label']].drop_duplicates().sort_values('class_label')
label_to_id = dict(class_label_df.values)
id_to_label = dict(class_label_df[['class_label', 'tags']].values)
REPLACE_BY_SPACE_RE = re.compile('[/(){}[]|@,;]')
BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')
# STOPWORDS = set(stopwords.words('english'))
def clean_text(text):
"""
text: a string
return: modified initial string
"""
text = BeautifulSoup(text, "lxml").text # HTML decoding. BeautifulSoup's text attribute will return a string stripped of any HTML tags and metadata.
text = text.lower() # lowercase text
text = REPLACE_BY_SPACE_RE.sub(' ', text) # replace REPLACE_BY_SPACE_RE symbols by space in text. substitute the matched string in REPLACE_BY_SPACE_RE with space.
text = BAD_SYMBOLS_RE.sub('', text) # remove symbols which are in BAD_SYMBOLS_RE from text. substitute the matched string in BAD_SYMBOLS_RE with nothing.
# text = ' '.join(word for word in text.split() if word not in STOPWORDS) # remove stopwors from text
return text
df['post'] = df['post'].apply(clean_text)
list_corpus = df["post"].tolist()
list_labels = df["class_label"].tolist()
X_train, X_test, y_train, y_test = train_test_split(list_corpus, list_labels, test_size=0.2, random_state=40)
vectorizer = CountVectorizer(analyzer='word',token_pattern=r'w{1,}', ngram_range=(1, 3), stop_words = 'english', binary=True)
train_vectors = vectorizer.fit_transform(X_train)
test_vectors = vectorizer.transform(X_test)
logreg = LogisticRegression(n_jobs=1, C=1e5)
logreg.fit(train_vectors, y_train)
pred = logreg.predict(test_vectors)
accuracy = accuracy_score(y_test, pred)
precision = precision_score(y_test, pred, average='weighted')
recall = recall_score(y_test, pred, average='weighted')f1 = f1_score(y_test, pred, average='weighted')print("accuracy = %.3f, precision = %.3f, recall = %.3f, f1 = %.3f" % (accuracy, precision, recall, f1))
我们现在目标并不是产生最好的结果。我想尽快进入LIME & SHAP,这就是接下来发生的事情。
用LIME解释文本预测
从现在开始,这是有趣的部分。下面的代码片段主要是从LIME教程中借来的。 c = make_pipeline(vectorizer, logreg)
class_names=list(df.tags.unique())
explainer = LimeTextExplainer(class_names=class_names)
idx = 1877
exp = explainer.explain_instance(X_test[idx], c.predict_proba, num_features=6, labels=[4, 8])
print('Document id: %d' % idx)
print('Predicted class =', class_names[logreg.predict(test_vectors[idx]).reshape(1,-1)[0,0]])
print('True class: %s' % class_names[y_test[idx]])
我们在测试集中随机选择一个文档,它恰好是一个标记为sql的文档,我们的模型也预测它是sql。使用这个文档,我们为标签4 (sql)和标签8 (python)生成解释。 print ('Explanation for class %s' % class_names[4])
print (''.join(map(str, exp.as_list(label=4)))) print ('Explanation for class %s' % class_names[8])
print (''.join(map(str, exp.as_list(label=8))))
很明显,这个文档对标签sql有最高的解释。我们还注意到正负号与特定的标签有关,例如单词”sql”对类sql是正的,而对类python是负的,反之亦然。
我们要为这个文档生成2类标签顶部。 exp = explainer.explain_instance(X_test[idx], c.predict_proba, num_features=6, top_labels=2)
print(exp.available_labels())
它给出了sql和python。 exp.show_in_notebook(text=False)
让我来解释一下这种可视化:
1. 对于本文档,词 “sql”对于类sql具有最高的正分数。
2. 我们的模型预测该文档应该标记为sql,其概率为100%。
3. 如果我们从文档中删除word”sql”,我们期望模型预测label sql的概率为100% – 65% = 35%。
4. 另一方面,单词”sql”对于类python是负面的,我们的模型已经了解到单词”range”对于类python有一个小的正面得分。
我们可能想放大并研究类sql的解释,以及文档本身。 exp.show_in_notebook(text=y_test[idx], labels=(4,))
使用SHAP解释文本预测
以下过程是从本教程中学到的。 「链接」 from sklearn.preprocessing import MultiLabelBinarizer
import tensorflow as tf
from tensorflow.keras.preprocessing import text
import keras.backend.tensorflow_backend as K
K.set_session
import shap
tags_split = [tags.split(',') for tags in df['tags'].values]
tag_encoder = MultiLabelBinarizer()
tags_encoded = tag_encoder.fit_transform(tags_split)
num_tags = len(tags_encoded[0])
train_size = int(len(df) * .8)
y_train = tags_encoded[: train_size]
y_test = tags_encoded[train_size:]
class TextPreprocessor(object):
def __init__(self, vocab_size):
self._vocab_size = vocab_size
self._tokenizer = None
def create_tokenizer(self, text_list):
tokenizer = text.Tokenizer(num_words = self._vocab_size)
tokenizer.fit_on_texts(text_list)
self._tokenizer = tokenizer
def transform_text(self, text_list):
text_matrix = self._tokenizer.texts_to_matrix(text_list)
return text_matrix
VOCAB_SIZE = 500
train_post = df['post'].values[: train_size]
test_post = df['post'].values[train_size: ]
processor = TextPreprocessor(VOCAB_SIZE)
processor.create_tokenizer(train_post)
X_train = processor.transform_text(train_post)
X_test = processor.transform_text(test_post)
def create_model(vocab_size, num_tags):
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(50, input_shape = (VOCAB_SIZE,), activation='relu'))
model.add(tf.keras.layers.Dense(25, activation='relu'))
model.add(tf.keras.layers.Dense(num_tags, activation='sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer='adam', metrics = ['accuracy'])
return model
model = create_model(VOCAB_SIZE, num_tags)
model.fit(X_train, y_train, epochs = 2, batch_size=128, validation_split=0.1)
print('Eval loss/accuracy:{}'.format(model.evaluate(X_test, y_test, batch_size = 128))) 模型训练完成后,我们使用前200个训练文档作为背景数据集进行集成,并创建一个SHAP explainer对象。 我们在测试集的子集上获得各个预测的属性值。 将索引转换为单词。 使用SHAP的summary_plot方法来显示影响模型预测的主要特性。 attrib_data = X_train[:200]
explainer = shap.DeepExplainer(model, attrib_data)
num_explanations = 20
shap_vals = explainer.shap_values(X_test[:num_explanations])
words = processor._tokenizer.word_index
word_lookup = list()
for i in words.keys():
word_lookup.append(i)
word_lookup = [''] + word_lookup
shap.summary_plot(shap_vals, feature_names=word_lookup, class_names=tag_encoder.classes_) 单词”want”是我们模型使用的最大信号词,对类jquery预测贡献最大。 单词”php”是我们模型使用的第四大信号词,当然对PHP类贡献最大。 另一方面,单词”php”可能对另一个类有负面信号,因为它不太可能在python文档中看到单词”php”。
关于LIME & SHAP的机器学习可解释性,还有很多需要学习的地方。我只介绍了一小部分NLP。其余的可以在Github上找到。 NLP-with-Python/LIME_SHAP_StackOverflow.ipynb at master · susanli2016/NLP-with-Python · GitHub
来自:AI中国
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2019-09-24 15:21:00
本文转载自数据派THU
作者:MOHD SANAD ZAKI RIZVI
本文主要介绍了: TensorFlow.js (deeplearn.js)使我们能够在浏览器中构建 机器学习 和 深度学习 模型,而无需任何复杂的安装步骤。 TensorFlow.js的两个组件——Core API和Layer API。 了解如何构建一个很棒的使用Tensorflow.js对网络摄像头中的图像进行分类的模型。
概述
你最喜欢用什么工具来编写机器学习模型?数据科学家们对这个永恒的问题会给出各种不同的答案。一些人喜欢RStudio,另一些人更喜欢Jupyter Notebooks。我绝对属于后者。
所以,当我第一次遇到TensorFlow.js(以前是deeplearn.js)时,我的心都要炸开了。在浏览器中构建机器学习模型?使用JavaScript?听起来好得令人难以置信!
超过43亿人使用网络浏览器——约占世界人口的55%。——维基百科(2019年3月)
谷歌的TensorFlow.js不仅将机器学习引入浏览器中,使机器学习大众化,而且对于经常使用JavaScript的开发人员来说,它也是一个完美的机器学习门户。
我们的网络浏览器是最容易访问的平台之一。这就是为什么构建不仅能够训练机器学习模型而且能够在浏览器本身中“学习”或“迁移学习”的应用程序是有意义的。
在本文中,我们将首先了解使用TensorFlow.js的重要性及其它的不同组件。然后,我们将深入讨论使用TensorFlow.js在浏览器中构建我们自己的机器学习模型。然后我们将构建一个应用程序,来使用计算机的网络摄像头检测你的身体姿势!
如果你是TensorFlow的新手,你可以在下面文章中了解更多: TensorFlow 101: Understanding Tensors and Graphs to get you Started with Deep Learning Introduction to Implementing Neural Networks using TensorFlow
目录
一、为什么你应该使用TensorFlow.js?
1.1 使用网络摄像头在浏览器中进行图像分类
1.2 TensorFlow.js的特征
二、了解浏览器中的机器学习
2.1 Core API:使用Tensors工作
2.2 Layer API:像Keras一样构建模型
三、利用谷歌的预训练模型:PoseNet
为什么要使用TensorFlow.js
我将用一种独特的方法来回答这个问题。我不会深入研究TensorFlow.js的理论方面,也不会列出它为什么是一个如此不可思议的工具。
相反,我将简单地向你展示如果不使用TensorFlow.js将会错过什么。那么,让我们在5分钟内构建一个应用程序,来使用你的网络摄像头对图像进行分类。没错——我们将直接进入代码部分!
这是最好的部分——你不需要安装任何东西来做这个!只要一个文本编辑器和一个网络浏览器即可。下面的动图展示了我们将要构建的应用程序:
这多酷啊!我在浏览器里几分钟就完成了。那么,让我们看一下步骤和代码,以帮助你在Web浏览器中构建自己的图像分类模型。
使用网络摄像头在浏览器中构建图像分类模型
打开你选择的文本编辑器并创建一个文件index.html。将以下代码保存于此文件内: image_classification
接下来,创建另一个文件index.js并在其中编写以下代码: let mobilenet; let video; let label = ”; // when model is ready make predictions function modelReady() { console.log(‘Model is ready!!!’); mobilenet.predict(gotResults); } function gotResults(error, results) { if (error) { console.error(error); } else { label = results[0].className; // loop the inference by calling itself mobilenet.predict(gotResults); } } // setup function function setup() { createCanvas(640, 550); // ml5 to create video capture video = createCapture(VIDEO); video.hide(); background(0); // load the MobileNet and apply it on video feed mobilenet = ml5.imageClassifier(‘MobileNet’, video, modelReady); } function draw() { background(0); // show video image(video, 0, 0); fill(255); textSize(32); // show prediction label text(label, 10, height – 20); }
保存这两个文件,然后在谷歌Chrome或Mozilla Firefox等浏览器中打开index.html文件。就是这样!你现在已经创建了一个可以使用你的网络摄像头在浏览器本身实时分类图像的应用程序!下面是它在我的计算机上的样子:
视频连接:
https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2019/05/mobilenet_demo.mp4_=1
在这个例子中需要注意的要点: 在上面的例子中,我们使用了一个预先训练的图像分类模型MobileNet(https://ai.googleblog.com/2017/06/mobilenets-open-source-models-for.html) 我们使用ml5.js(https://ml5js.org/)一个构建在TensorFlow之上的库。它将MobileNet模型加载到浏览器中,并对视频提要执行推理。 我们还利用P5.js(https://p5js.org/)库来处理视频输入并在视频本身上显示标签。
我不需要在电脑上安装任何东西。这个例子应该适用于任何现代系统,不管它是Linux、Windows还是MacOS——这就是使用JavaScript在web上构建模型的强大功能。
现在,让我们看看TensorFlow.js提供的强大功能,以及如何利用它们在浏览器中部署机器学习模型。
TensorFlow.js的特征
TensorFlow.js是一个库,用于JavaScript开发和训练ML模型,并在浏览器或Node.js上部署。
TensorFlow.js提供了许多的功能来供我们使用。
它是TensorFlow在JavaScript中的扩展,JavaScript是我们在互联网上使用的几乎所有网站、浏览器或应用程序逻辑背后的编程语言。JavaScript和 Python 一样用途广泛,所以使用它来开发机器学习模型给我们带来了很多好处: 如果ML模型是用web语言编写的,则更容易部署。 由于所有主流浏览器都支持JavaScript,所以你可以无处不在地使用它,而不必担心平台类型或其他兼容性问题。对于你的用户也是如此。 TensorFlow.js是一个客户端库,这意味着它可以在用户的浏览器中训练或运行ML模型。这减轻了与数据隐私有关的任何担忧。 在你的客户端上运行实时推断可使你的应用程序更具交互性,因为它们可以立即响应用户输入(例如我们前面构建的webcam应用程序)。
TensorFlow.js以其当前的形式提供了以下主要功能: 浏览器中的机器学习:你可以使用TensorFlow.js在浏览器中创建和训练ML模型。 谷歌的预训练模型:TensorFlow.js配备了一套由谷歌预训练的模型,用于对象检测、图像分割、语音识别、文本毒性分类等任务。 迁移学习:你可以通过对已经训练过的模型的部分进行再训练来执行转移学习,比如TensorFlow.js中的MobileNet。 部署python模型:使用Keras或TensorFlow训练的模型可以很容易地导入浏览器/使用TensorFlow.js的部署。
在本文中,我们将关注前两个功能。在本系列的第二部分(即将推出!)中,我们将讨论如何在Python中转移学习和部署我们的模型。
浏览器中的机器学习
TensorFlow.js提供了两种方法来训练模型(非常类似于TensorFlow): 第一种方法是使用Core API使用低级张量操作来定义模型。 第二种方法是使用Layers API定义模型,类似于Keras。
让我们通过几个例子来理解这两种方法。毕竟,学习一个概念最好的方法就是把它付诸实践!
首先,设置你的HTML文件:
在你的电脑上建立一个新的index.html文件,并在其中编写以下代码:

Tensorflow.js Core API

–>
我们创建了一个基本的HTML页面,并从云URL中加载了Tensorflow.js(第7行)。
关于安装TensorFlow.js(deeplearn.js)的说明:
由于TensorFlow.js是为浏览器而设计的,所以安装和使用TensorFlow.js最简单的方法就是根本不安装它。你可以简单地从HTML中的URL加载它即可。
如果你想在本地工作怎么办呢?实际上,你可以在Jupyter Notebook中使用TensorFlow.js,就像你在Python或R中通常做的那样。这是一个适合每个人的解决方案!
这种本地方法稍微长一些,并且需要一些时间,所以本文不会使用它。如果你确实想学习如何操作,可以从为Jupyter安装ijavascript内核开始。下面是我的Jupyter Notebook的截图:
现在,使用TensorFlow.js的推荐方法是使用库的官方URL直接加载它。你只需将以下行添加到HTML文件中:
完成了!这真的很简单。
Core API:使用Tensors工作
Core API与TensorFlowCore非常相似,我们可以使用低级张量运算和线性代数定义模型。
如果我们想要构建自定义模型或想要从头开始构建神经网络,这非常有用。让我们举一个在浏览器中使用张量的例子。
首先在index.html文件中的

Tensorflow.js Core API

–>
在上面的代码中,我们在两个张量a和b上执行基本的加法和乘法运算,并将结果打印在浏览器中。现在,转到终端,打开项目文件夹,然后使用以下命令启动Python服务器: python3 -m http.server
然后在你的浏览器打开以下地址:
http://localhost:8000/
当你看到一个页面显示“Tensorflow.js Core API”时,使用Ctrl+Shift+I键打开控制台(console)。这应该在Chrome和Firefox都适用。我们在控制台得到上述操作的输出:
如果你想深入阅读有关Core API的更多信息,那么我建议你阅读CoreAPI官方文档。
CoreAPI文档:
https://www.tensorflow.org/js/guide/tensors_operations
Layer API:像Keras一样构建模型
Layers API与Python中的Keras非常相似。就像Keras一样,你可以使用序列的和函数的方法创建模型。
让我们通过一个例子仔细研究序列方法。我们将在这些数据点上训练回归模型:
这里,X和Y有一个线性关系——每个Y对应于X + i(其中i是0、1、2、3……n+1)。让我们在这个数据集上训练一个基本的回归模型。你可以在index.html文件中的标记之间编写以下代码: const callbacks = { onEpochEnd: async (epoch, logs) => { console.log(“epoch: ” + epoch + JSON.stringify(logs)) } };// Generate some synthetic data for training. const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]); const ys = tf.tensor2d([[1], [3], [5], [7]], [4, 1]);// Build and compile model. async function basicRegression(){// Build a sequential model const model = tf.sequential(); model.add(tf.layers.dense({units: 1, inputShape: [1]})); model.add(tf.layers.dense({units: 1, inputShape: [1]})); model.compile({optimizer: ‘sgd’, loss: ‘meanSquaredError’});// Train model with fit(). await model.fit(xs, ys, {epochs: 100, validationSplit: 0.1, callbacks: callbacks});// Run inference with predict(). model.predict(tf.tensor2d([[5]], [1, 1])).print(); }// Create a basic regression model basicRegression();
敏锐的读者一定注意到,上面的语法与用Python构建顺序模型的Keras语法非常相似。我们回到浏览器控制台(console)时会得到预测。
我们的简单回归模型预测7.556,非常接近8的期望值。这是一个基本的例子,但我们可以清楚地看到,在浏览器中直接构建机器学习模型是多么容易和有用。
TensorFlow.js能够在浏览器中构建机器学习和深度学习模型。它还自动利用GPU(s)的强大功能,如果在你的系统模型训练期间可用。
下面是一些使用TensorFlow.js在一些标准数据集上训练的深度学习模型的例子:
你可以在tfjs-examples repository中浏览这些示例。
tfjs-examples repository :
https://github.com/tensorflow/tfjs-examples
利用谷歌的预训练模型:PoseNet
TensorFlow.js提供了大量来自谷歌的预训练模型,用于许多有用的任务,如目标检测、语音识别、图像分割等。预先训练的模型的优点是,我们可以使用它们而不需要任何重大的依赖关系或安装,并且可以开箱即用。
人们普遍预计谷歌将在未来几个月推出更多模型。你可以在下面链接查看可用的预训练模型:
相关链接:
https://www.tensorflow.org/js/models
我们将在本文中使用PoseNet。PoseNet是一种视觉模型,可以通过估计人体关键关节的位置来估计一个人在图像或视频中的姿势。
PoseNet是如何工作的?
这是一个迷人的概念。姿势估计是一种计算机视觉技术,用于检测图像和视频中的人物。例如,这可以帮助我们确定某人的肘部在图像中出现的位置。
只是要清楚-姿势估计不是关于识别谁在一个图像中。该算法只是简单地估计关键身体关节的位置。
检测到的关键点设置为“Part”和“ID”索引,置信度得分在0.0和1.0之间(1.0是最高的)。
以下是PoseNet给出的输出类型的示例:
难以置信,对吧?!我们将使用ml5.js库来使用PoseNet。ml5.js是一个基于TensorFlow.js和p5.js的库。p5.js是另一个库可以使你更容易在浏览器中访问网络摄像头。
ml5.js旨在使机器学习对广大的艺术家,创意编码员和学生来说变得平易近人。该库以TensorFlow.js为基础,通过简单的语法在浏览器中提供对机器学习算法和模型的访问。
例如,你可以使用ml5.js在5行代码中使用MobileNet创建图像分类模型,如下所示:
正是由于Ml5.js的简单性,使得它非常适合在浏览器中快速构建原型,这也是我们在项目中使用它的原因。
让我们回到PoseNet。创建一个新文件index.html并添加以下代码:

PoseNet demo with Ml5.js

Loading Model…


这将创建一个基本的HTML网页并加载必要的文件: ml5.js和p5.js是通过其官方URL加载的。 posenet.js是我们将编写用于使用PoseNet的代码的文件。
现在,我们将编写用于使用PoseNet的JavaScript代码。在与index.html相同的文件夹中创建一个新文件posenet.js。以下是完成此项工作所需的步骤: 加载PoseNet模型并从网络摄像头捕获视频 检测身体关节的关键点 显示检测到的身体关节 绘制估计的身体骨骼
让我们从第一步开始。
步骤1:加载PoseNet模型并从网络摄像头捕获视频
我们将使用ml5.js加载PoseNet。与此同时,p5.js使我们可以用几行代码从网络摄像头捕获视频: let video;let poseNet;let poses = [];function setup() { const canvas = createCanvas(640, 480); canvas.parent(‘videoContainer’);// Video capture video = createCapture(VIDEO); video.size(width, height);// Create a new poseNet method with a single detection poseNet = ml5.poseNet(video, modelReady); // This sets up an event that fills the global variable “poses” // with an array every time new poses are detected poseNet.on(‘pose’, function(results) { poses = results; }); function modelReady(){ select(‘#status’).html(‘model Loaded’)}
以上代码块中最重要的是: createCapture(VIDEO) :它是一个p5.js函数,用于通过摄像头捕获视频来创建视频元素。 ml5.poseNet(video,modelRead) :我们使用ml5.js加载poseNet模式。通过传入视频,我们告诉模型处理视频输入。 PoseNet.on() :每当检测到一个新的姿势时,就执行这个函数。 modelReady() :当PoseNet完成加载时,我们调用这个函数来显示模型的状态。
步骤2:检测身体关节的关键点
下一步是检测姿势。你可能已经注意到,在前面的步骤中,我们通过调用poseNet.on()将每个检测到的位姿保存到pose变量中。这个函数在后台连续运行。无论何时找到一个新的姿势,它都会以以下格式给出身体关节的位置: ‘score’是指模型的置信度 ‘part’表示检测到的身体关节/关键点 ‘position’包含检测到的部分的x和y位置
我们不必为此部分编写代码,因为它是自动生成的。
步骤3:显示检测到的人体关节
我们知道被检测到的人体关节及其x和y位置。现在,我们只需要在视频上画出它们来显示检测到的人体关节。我们已经看到,PoseNet给出了一个检测到的人体关节列表,每个关节及其x和y位置的置信度评分。
我们将使用20%的阈值(keypoint.score > 0.2)置信度得分,以便绘制一个关键点。下面是实现这一操作的代码: // A function to draw ellipses over the detected keypointsfunction drawKeypoints() { // Loop through all the poses detected for (let i = 0; i < poses.length; i++) { // For each pose detected, loop through all the keypoints let pose = poses[i].pose; for (let j = 0; j < pose.keypoints.length; j++) { // A keypoint is an object describing a body part (like rightArm or leftShoulder) let keypoint = pose.keypoints[j]; // Only draw an ellipse is the pose probability is bigger than 0.2 if (keypoint.score > 0.2) { fill(255, 0, 0); noStroke(); ellipse(keypoint.position.x, keypoint.position.y, 10, 10); } } }}
步骤4:绘制估计的身体骨架
除了关键点或身体关节,PoseNet还可以检测估计的身体骨架。我们可以使用pose变量来绘制骨架: // A function to draw the skeletonsfunction drawSkeleton() { // Loop through all the skeletons detected for (let i = 0; i < poses.length; i++) { let skeleton = poses[i].skeleton; // For every skeleton, loop through all body connections for (let j = 0; j < skeleton.length; j++) { let partA = skeleton[j][0]; let partB = skeleton[j][1]; stroke(255, 0, 0); line(partA.position.x, partA.position.y, partB.position.x, partB.position.y); } }}
在这里,我们遍历检测到的骨架并创建连接关键点的线。代码还是相当简单。
现在,最后一步是重复调用drawSkeleton()和drawKeypoints()函数,以及我们从网络摄像头捕获的视频源。我们可以使用p5.js的draw()函数来实现,该函数在setup()之后直接调用,并重复执行: function draw() { image(video, 0, 0, width, height);// We can call both functions to draw all keypoints and the skeletons drawKeypoints(); drawSkeleton();}
接下来,转到终端窗口,进入项目文件夹,然后启动Python服务器: python3 -m http.server
然后转到你的浏览器并打开以下地址:
http://localhost:8000/
瞧!你的PoseNet应该很好地检测到了你的身体姿势(如果你已经正确地遵循了所有步骤)。以下是我的模型的情况:
尾记
你可以看到我为什么喜欢TensorFlow.js。它非常有效率,甚至不需要你在构建模型时担心复杂的安装步骤。
TensorFlow.js展示了通过将机器学习带到浏览器中使机器学习更容易访问的许多前景。同时,它还具有数据隐私、交互性等优点。这种组合使得它成为数据科学家工具箱中的一个非常强大的工具,特别是如果你想部署你的机器学习应用程序的话。
在下一篇文章中,我们将探讨如何在浏览器中应用迁移学习,并使用TensorFlow.js部署机器学习或深度学习模型。
我们用PoseNet做的项目可以更进一步,通过训练另一个分类器来构建一个姿态识别应用程序。我鼓励你去尝试一下!
原文链接: https://www.analyticsvidhya.com/blog/2019/06/build-machine-learning-model-in-your-browser-tensorflow-js-deeplearn-js/
本文为专栏文章,来自:大数据文摘,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/66496.html 。
数据分析
2019-09-24 14:40:00
大数据 文摘出品
编译:Joey、杨威
对乳腺癌的早期筛查一直是机器学习的一个热门研究方向,可是已有的筛查模型大多数依赖于白人女性样本,因此对于非白人女性的筛查准确率令人堪忧。
最近麻省理工开发的新模型不仅很好地解决了这个问题,而且还能够提前五年筛查出乳腺癌病患!
这一项突破性研究,标志着深度学习技术推动下的医学进步,可以提前了解病情,做针对性治疗,这对于病患来说,是一大福祉。
Regina Barzilay和Lehman与CSAIL博士生的主要作者Adam Yala共同撰写了这篇论文。
感兴趣的读者可以查阅下载
https://pubs.rsna.org/doi/pdf/10.1148/radiol.2017170549
已有的筛查模型
之前的疾病筛查模型大多是CNN(卷积神经网络)的改良版本,CNN是前馈神经网络,模拟人的视觉对于图像的理解。网络结构中的卷积核提取图像的边缘、轮廓等信息,Relu等激活函数模拟大脑对于外界信号刺激的应答,对提取到的图像信息做整合,浅层卷积层提取到局部的图像信息,层数越深的卷积层能提取到全局的图像信息,在CV(Computer Version)领域也称为感受野(Receptive Field),CNN网络模型对于图像的分类任务处理十分友好,下图很好地展示了CNN网络的结构和原理:
CNN图像理解示意图
疾病筛查任务也就是二分类任务,对于输入的图像,需要得到是否患病的判断。给医学图片做标签(在计算机科学中标记为0或1,0表示没有患病,1表示患病),在模型中,通过Label(标记)好图片的训练和反向传播的参数调整,使得模型具备一定的学习能力,最终能够对未标记的医学图片做疾病筛查。但是训练的结果依靠 数据集 的好坏,已有的很多乳腺癌预测数据集都偏向于白人女性的研究,鲜少考虑到其他族裔。麻省理工大学研究人员开发的诊断模型考虑到了这一点。
将研究扩展到少数族裔
麻省理工的研究人员在一篇博客中指出,事实上这个看起来不起眼的一个细节是乳腺癌预测的关键:因为黑人女性死于乳腺癌的概率比白人女性高 42%。而正是目前的乳腺癌早期诊断技术中对黑人女性的诊断模型缺失造成了这一巨大差异,因为包括黑人女性在内的少数族裔样本在已有的深度学习模型开发中通常鲜有被考虑进去。
而麻省理工的研究人员表示,他们对乳腺癌预测模型的研究正是为了弥补这一缺陷,他们希望通过这一研究提高对少数族裔健康评估的准确性。针对同一个问题的研究同时也是近期很多业界公司研究和产品开发的重心。
模型结果表明,对于黑人和白人女性的预测效果都相当好。
之所以强调对黑人与白人女性的效果一样好,是因为研究人员在开发过程中发现同类的 人工智能 模型存在大量偏差——因为它们对样本的采集严重地倾向白人女性,黑人女性则很少。因此来自麻省理工的研究团队仔细地设计了他们的模型,使得它对于两种族裔的女性都能够很好地作出预测。
基于风险评估的提前预测
麻省理工学院教授Regina Barzilay本人是一名乳腺癌幸存者,她表示希望这样的系统能让医生在个人层面定制筛查和预防计划,使得晚期诊断成为历史。
所有性别都有患乳腺癌的风险,而大部分人通常认为只影响女性。自1989年第一个乳腺癌风险模型以来,研究者发展患乳腺癌的风险在很大程度上取决于人类的知识和对主要危险因素的直觉,如年龄、乳腺癌和卵巢癌的家族史、激素和生殖因素以及乳房密度。
然而,这些标志物中的大多数仅与乳腺癌微弱相关。因此,这些模型在个人层面上仍然不是很准确,并且鉴于这些限制,许多组织仍然认为基于风险的筛查计划是不可能的。
另一方面,“自20世纪60年代以来,放射科医生已经注意到女性在乳房X线照片上可以看到独特且变化很大的乳房组织模式,”Lehma说。“这些模式可以代表遗传,激素,怀孕,哺乳,饮食,体重减轻和体重增加的影响。我们现在可以在个人层面的风险评估中更准确地利用这些详细信息。”
不同于已有的预测模型,麻省理工计算机与 人工智能 实验室开发出的模型准确地将31%的癌症患者置于风险最高的类别,而传统模型仅为18%,可以至多提前五年预测乳腺癌细胞发展。
数据集来源
MIT / MGH团队不是手动识别乳房X线照片中驱动未来癌症的模式,而是训练深度学习模型直接从数据中诱导模式。麻省理工开发的这一预测模型的开发基于超过六万名来自麻省总医院(Massachusetts General Hospital)的病人样本,其中包括超过九万份乳房X光检查报告和病人们病情发展情况。
这一模型从这些数据出发,通过深度学习甚至能够辨识出一些人类医生都无法辨认出的病情。因为已有的关于乳腺癌的假设和风险因素都充其量是一个指导性的判断框架,而麻省理工的这个模型并不是基于类似的框架,因此模型的准确性在预测性诊断和预筛查方面会更加准确。
总结与展望
总的来说,麻省理工计算机与人工智能实验室的这一项目旨在协助医生们为病人尽早选择正确的治疗方案,而不是像现在的大多数情况下一样,在病人们的病情恶化甚至发展到晚期时才告诉他们这一残酷的事实。
同时,最近在nature中也有报道,对于BRCA1和BRCA2基因的突变检测也能更有效地开展乳腺癌的治疗。
链接如下:
https://www.nature.com/articles/d41586-019-02015-7
展望未来,来自麻省理工的团队希望能够用这一技术来提高其他类似疾病的预测准确性,如通过扫描脑部结构,可以对阿尔茨海默病和多发性硬化症做预测,同理也可以对心血管疾病做预测。只要针对某种疾病的研究已经有成型的风险模型,这一技术就有可能大大提高对它预诊断的准确性。
扫描脑部图片检测疾病
相关报道:
http://news.mit.edu/2019/using-ai-predict-breast-cancer-and-personalize-care-0507 https://techcrunch.com/2018/09/19/ibm-launches-cloud-tool-to-detect-ai-bias-and-explain-automated-decisions/
本文为专栏文章,来自:大数据文摘,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/66519.html 。
数据分析
2019-09-24 14:35:00
大数据 文摘出品
编译:高延、橡树_Hiangsug、宁静
7月6日,这可能是一年中最适合亲吻的日子——国际接吻日(International Kissing Day)。
这个节日最早起源于英国。1991年这个节日得到了联合国的承认,也希望让更多人知道,亲吻的美好,这也是人类表达爱意最自然的一种方式。
那么, 人工智能 可以通过训练了解亲吻吗?
来自 Netflix 的一位高级数据科学家就对“kiss”镜头情有独钟,并且通过上百部电影接吻情节的定位,成功训练出了可以准确识别电影亲吻桥段的AI模型——模型的独创性在于可以区别亲吻与性行为。
大千世界,无所不能,AI也能检测到”kiss”?随文摘菌一探究竟吧。
让AI区别kiss和sex
作为爱情片的代表情节,“亲吻”一直是很多观众最爱反复观看的镜头。不管是《人鬼情未了》中Swayze和Demi Moore的经典接吻桥段,还是《泰坦尼克号》中Rose和Jack的临别一吻,都造就了经典中的经典。
而在电影观看过程中,寻找kiss镜头,就成为了不少娱乐视频场景下的一个真实需求。
这项基于 人工智能 识别接吻的研究由出自Netflix高级数据科学家Amir Ziai之手——此时他正在斯坦福大学攻读人工智能研究生学位。
Ziai在上世纪好莱坞电影中挑选了100部有代表性的作品,并为电影片段手动标注“亲吻”或“非亲吻”标签,用静态画面和声音片段来训练深度学习 算法 ,以实现对亲吻场景的画面和声音的识别。
为了避免任何人得到错误的印象,目前还不能确定亲吻识别算法能否用于性爱场景。Ziai说到,“在我的训练集中,我尽量避免出现性爱场景,这样就能确保我的模型不会混淆接吻和性爱。”
Ziai目前的雇主Netflix并没有参与到斯坦福大学的这个项目上,但该项目在arXiv中有详细记载;另外,即使Ziai还没去调研这项研究在Netflix上的应用,但是不难想象,Netflix或其他公司(如YouTube, Facebook ,Instagram和TikTok等处理大量流媒体或存储视频的公司)可能会对这一技术的商业应用场景感兴趣。
该图是1990年的电影《人鬼情未了》中Swayze和Demi Moore的经典接吻桥段,数据科学家便是用了近百部类似的电影桥段来训练AI模型识别亲吻的行为。
感兴趣的读者可以阅读论文原文,附上地址:
https://arxiv.org/pdf/1906 . 01843.pdf
“双管齐下”:不仅视频识别,还有kiss的音频识别
应用于接吻场景视觉识别最成功的深度学习模型是ResNet-18,这是一种图像分类算法,且该算法经来自ImageNet 数据库 超过一百万张图像的预训练;而为了识别接吻场景的声音,研究人员采用了名为VGGish的深度学习模型,通过每个以秒分段的场景的后960毫秒音频训练。这种双管齐下对接吻的图像和音频同时处理的AI方法使得训练出的模型获得了惊人的F1分(算法精度和准度的加权平均值,度量模型的一种指标)——0.95。
ResNet-18模型结构图
在模型结构中,采用”shortcut connection”方式,也就是上图中的弧线来减少卷积网络传播过程中的计算和参数量,感兴趣的读者可以研究下,VGGish是是产生音频数据集的工具,一般用于音频分类。
github网址如下:
https://github.com/tensorflow/models/tree/master/research/audioset
不过在面对电影场景中一些棘手的片段或某些拍摄机视角时,该模型还是略显吃力。例如,远景或广角的接吻镜头会使算法产生混淆,因为此类视频片段中包含了太多背景画面。此外,一些快节奏的视频片段和不同时包含两个演员的镜头对模型来讲也都是极大的挑战。
电影《Titanic》中Jack和Rose在邮轮甲板上拥吻图片
深度学习是一个“黑盒子”,我们很难弄清楚深度学习模型实现预测时所使用的的具体数据模式。为了尝试理解AI的逻辑,人们通常采用的一种方法是使用显著地形图来可视化分析过程中受到AI关注最多的数据。在好莱坞影片识别接吻场景的项目中,深度学习模型似乎更加关注与演员面部相关的图像像素点。
Ziai表示,即使是在少量有限的实验中也可以看出,人工智能更依赖视觉特征而不是音频特征来识别接吻场景。他发现“精心挑选的数据集”对于训练接吻检测系统有很大帮助,这类数据可以让该系统利用更多的上下文信息来检测接吻,而不仅仅是通过静态图像。
AI“kiss”之原理
AI模型是如何习得这种能力呢?
和初吻尚在的人类学习基本亲吻知识的途径一样,AI模型基于已经成熟的深度学习算法,观看各式各样的好莱坞明星上演的浪漫拥吻片段,通过这种大量的训练来识别影片中人物的面部表情和定位嘴唇,数据科学家说明了AI系统如何能够更深入地了解最亲密的人类活动的原理。
让AI识别kiss有什么用?
早在2019年4月,谷歌宣布其智能手机Pixel已更新其Photobooth功能,这项功能可以在你面部表情发生变化的时候自动拍照,比如说微笑、亲吻、嘟嘴、伸舌头等等,该功能可是使智能手机从手机拍摄的视频中识别出接吻画面。
具体来说,当你按下Photobooth功能的拍摄按键之后,手机的AI就会自动分析你的脸部表情。根据不同状态,手机会自动判定「最佳时刻」,并将这一刻记录下来。同样,Ziai研发的应用端视频接吻识别技术使我们看到了视频内容自动分类,用户个性化视频推荐,甚至视频在线内容审核的未来。
Pixel手机Photobooth功能拍摄的静态图片
OpenAI的策略和传播主管Jack Clark在他的文章《Import AI newsletter》中重点强调了这项研究的意义:“现代计算机视觉技术已经使得开发特定的’感知和响应类’软件变得相当容易,诸如识别定性或非结构化的东西,识别电影中的接吻场景就是一个极佳的例子,但此类AI对个人软件的应用能力明显被低估。”
AI“kiss”之未来
好莱坞影片数据集和计算资源由斯坦福大学计算机科学助理教授Kayvon Fatahalian的实验室提供。
目前,这个用100部好莱坞影片(如《安娜·卡列尼娜》(1935),《人鬼情未了》(1990)和《007:大战皇家赌场》(2006)等)训练的AI模型在面对更大规模的影片时性能尚不清楚。但Ziai表示,在经超过80个影片进行训练后,该模型只看到了“边际改善”。
另一个值得关注的问题是这种AI模型在检测来自社交媒体的不同类型接吻场景视频时否能达到相似的准确度。这是个极大的挑战,可能需要模型对更多的视频数据集进行额外训练,而且训练集中不能仅包含那些出现在电影银幕上诸如Patrick Swayze和Demi Moore的好莱坞明星。尽管如此,从一些非常初步的测试中能看出,这种基于AI的接吻测技术会有很好的的应用前景。
“未来研究将尽量使用更多样化的数据集,以确保模型不会对于某种类型的电影过拟合,”Ziai说道,“不过有趣的是,该模型在我所选的YouTube视频上性能表现得相当好。”
本文为专栏文章,来自:大数据文摘,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/66502.html 。
数据分析
2019-09-24 09:35:00
作者:mylxiaoyi
成为2级新手
我第一次在工作中遇到实际的 机器学习 应用。我们要准备一个识别Zooplus商店中欺诈行为的应用。在经过几个月尝试了不同的解决方案之后:外部提供者,在代码中额外的if语句,灭火脚本等诸如此类,我们最终得到机器学习是最适合该工作的结论。自此以后,我们试着说服周围的人投资我们的教育并继续机器学习之路,但是并没有引人关注的成功。然而偶然的一个机会,我通过尝试Amazon的机器学习功能迈出了我的第一步,因而我认为自己是一个2级新手。在本文中,我会尝试向你 — 1级新手 — 展示如何迈出第一步,并切实地感受什么是机器学习。
什么是机器学习?
在互联网上,也许有成百上千的机器学习的定义。但是,我是初级的傻瓜,我们希望得到一些简单的东西——一些傻瓜式的东西!让我们一起来解决这个问题吧。
术语中的“机器”可能指的是计算机。我们可以想到计算机,无人驾驶飞机和其他东西,但是他们是由计算机控制的,对么?所以,机器学习是关于“计算机学习”的。
学习实际上是指的什么呢?计算机并没有大脑!没有神经元的激活,没有路径的创建。它能做的所有只是存储一些数据和进行一些操作。但是我们知道它是和数据有关的,而且是 大数据 (至少DZone是这么说明的)。所以我们有“关于 大数据 的计算机处理”。
那么,“处理”指的是什么呢?作为2级新手,我可以大概讲解一下(不过我敢打赌,真正的从业人员会认为我说的话一点也不正派)。我所说的,就是利用1级新手和2级新手不想知道的高级 算法 进行统计分析。
我想,这样就足以形成我们在这篇文章中给机器学习定下的最终定义:“电脑对大数据进行统计分析”。够酷吧?
机器学习有什么用?
我懂,我懂。读了这么多,你还是不晓得这一切关于机器学习的知识到底有什么用。作为2级新手,我要再次说一下,我有了一个学习机器学习的机会。
有两种机器学习: 监督 与 非监督 。
监督学习
我非常希望给出监督孩子的类比,但是我并不能够。是谁发明的这个名字?!
监督学习是当你为计算机提供你期望查找的信息时,-还记得我工作识别欺诈行为的例子吗?那就是监督学习。-我告诉计算机:我希望知道这个客户是否是一个欺诈者!而计算机器执行其高级魔法并给出答案:是的,主人!或者,不是,主人!他是一个笨蛋,但是普通的一个。通常,监督学习用于所谓的分类问题中。你为计算机提供大量的数据,而它进行分类:美国人是否会再次投票给 Mr. Trump ?这个人是否得了癌症?你是否会继续阅读这篇长而有趣的文章?
非监督学习
非监督学习是你并不清楚你正在寻找什么时,你毫无思路,你告诉计算机:这里有一堆数据!找出一些有趣的内容来。而它会执行比监督学习中所用的更为高级的算法。
因为我们并不是毫无头绪-我们确切地知道我们需要什么(而且我们对更为高级的算法并不感兴趣),在接下来的部分我们会专注于监督ML。
Amazon ML简介
在不久以前,对于你和我这样的新手接触机器学习非常困难。它是整天思考数字并且认为Scala与Python是好的编程语言的书呆子们的游戏。多亏了Amazon,精于销售的这帮家伙开始卖他们自己的基础设施,并且为我们提供了伟大的工具:Amazon机器学习。
创建数据源
我们拥有超过600个文本单词,所以我们最好直接进入工作。打开你的Amazon Web控制面板并找到“机器学习”按钮。点击!你会看到一些为你提供教程之类内容的屏幕。忽略它!你不需要新手教程,因为你已经在新手教程的中间部分了。你应该看到如下内容:
所以,在大数据上执行计算统计分析的第一步将是提供真正的大数据。使用下面的链接下载文件并将其放入S3桶中: https://s3.amazonaws.com/aml-sample-data/banking.csv
(是的,我们正在使用AWS文档教程所提供的数据。只是这个教程相对更好!)
你一旦完成,你可以返回机器学习屏幕并选择 “Create new…” ,然后选择 “Datasource”. 你应该可以看到如下内容:
Insert the S3 location and choose a Datasource name. 名字无所谓。 (最终我们会将其删除), 所以你可以为其指定任意名字。完成后点击 “Verify” 并选择 “Continue”.
你应该可以看到类似如下的屏幕内容:
正如你看到的,Amazon通过将数据分割为不同的数据类型试图使该数据更为合理。因为这是他们的新手教程数据,所有内容都应该更为平滑。你只需要对列名相关的问题点击 “Yes” ,如果一切顺利,最后一页命名为 “y” 应该是 “Binary” 类型。如果正是这种情况,点击 “Continue”;否则,我不知道 – 我只是一个2级新手。
在第三页,Amazon最终会询问我们真正希望得到什么样的魔法结果。那正是 “Target” 。在如下的屏幕中选择最后一列:
正如你看到的,Amazon将其识别为一个二分类问题,这意味着我们现在是监督者了!点击 “Continue”。
我们的数据并不包含标识符,所以点击 “Review” 并选择 “Create Datasource”。他需要一段时间直到创建完成。一旦完成,你应该看到如下内容:
我们完成了数据源!在系统中我们拥有我们的大数据了!
有了上千的单词,我们已为了最重要的部分做好了准备。我们将会创建实际的统计分析部分。ML模型是我们的超酷的机器学习解决方案的大脑。它是由Amazon基于我们的大数据与设置所创造的神奇生物,可以为所提供的数据预测列 “y” 的值。让我们开始吧!
回到机器学习面板,再一次选择 “Create new…” 然后选择 “ML Model”。选择我们新创建的数据源。我们应该看到类似如下的内容:
点击 “Continue” 然后选择 “Review” 与 “Create ML Model”. 我们并不希望修改任何高级设置。记住,我们仅是1级与2级的新手;我们仅是希望可以看到一切可以正常工作。
一段时间后按F5刷新,我们应该看到成功界面(如下所示)。我们的ML模型已成功创建!
创建预测
如果我们创建了我们解决方案的神奇大脑而不预测任何事情,那我们会感到遗憾。由ML模型成功界面的左边选择 “Try real-time predictions” 。 点击 “Paste a record” 按钮并粘贴如下内容: 32,services,divorced,basic.9y,no,unknown,yes,cellular,dec,mon,110,1,11,0,nonexistent,-1.8,94.465,-36.1,0.883,5228.1
该行与我们的大数据文件具有相同的格式,但是缺少最后一列 – “y” 。这正是我们的神奇ML模型将要预测的内容。如果已为惊奇做好准备,点击 “Create prediction” 。
Yes, yes, yes! 它起作用了!它预测了!如果你正确地做了我告诉你的所有事情,你预测屏幕的右边应是类似如下的内容:
“Predicted label” 是我们预测的结果 – 惊人的 0!正是它!
清理
确保由S3桶中删除数据,从而你不会为存储支付费用。你可以由你的帐户中删除机器学习,这取决于你,因为它不会花费任何费用。
总结
我们由给出一个糟糕的机器学习定义开始。然后,我们学习监督机器学习与非监督机器学习之间的区别。最后,我们通过Amazon机器学习接口创建了一个简单的预测。现在你也许想要知道的是:我们预测了什么?我们在那里放置的是什么数据?如果它没有起作用该怎么办?目前,这些无所谓。它仅是一个例子。现在重要的是,我的2级新手是你希望预测什么?你有什么可以利用的数据?以及为使其起作用你可以做什么?在下面我会为你提供一些资源, 祝你在成长为3级的道路上好运!
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2019-09-23 20:58:00
随着 人工智能 的进步和技术变得越来越复杂,我们希望现有的概念能够接受这种变化或者改变自己。同样,在自然语言的计算机辅助处理领域, 自然语言处理 的概念是否会让位于自然语言理解?或者这两个概念之间的关系是否比仅仅技术的线性进展更微妙和复杂?
在这篇文章中,我们将仔细研究NLP和NLU的概念以及它们在AI相关技术中的优势。
重要的是,虽然有时可以互换使用,但它们是两个有一些重叠的不同概念。首先,他们都处理自然语言和 人工智能 之间的关系。他们都试图理解非结构化数据,如语言,而不是像统计、行动等结构化数据。但是,NLP和NLU是许多其他 数据挖掘 技术的对立面。
自然语言处理
NLP是一个已经建立的,已有数十年历史的领域,在计算机科学、人工智能以及越来越多的 数据挖掘 领域开展业务。 NLP的最终目的是通过机器读取、解读、理解人类语言,将某些任务从人类身上移除并允许机器来处理它们。此类任务的常见实际示例是在线聊天机器人、文本摘要生成器,自动生成的关键字选项卡,以及分析给定文本情绪的工具。
NLP的作用
从广义上讲,NLP可以指代广泛的工具,例如语音识别、自然语言识别和自然语言生成。然而,NLP最常见的任务是历史性的: 符号化 解析 信息提取 相似 语音识别
自然语言和语言世代以及许多其他语言。
在现实生活中,NLP用于文本摘要、情感分析、主题提取、命名实体识别、词性标注、关系提取、词干提取、文本挖掘、机器翻译和自动问答,本体填充、语言建模和我们可以想到的所有与语言相关的任务。 NLP技术NLP的两个支柱是句法分析和语义分析。
总之:NLP依靠机器学习通过分析文本语义和语法从人类语言中获得意义。
自然语言理解
虽然NLP可以追溯到20世纪50年代,当计算机程序员开始尝试简单的语言输入时,NLU在20世纪60年代开始开发,希望让计算机能够理解更复杂的语言输入。它被认为是NLP的一个子主题,自然语言的目的较窄,主要侧重于机器阅读理解:让计算机理解文本的真正含义。
NLU实际上做了什么
与NLP类似,NLU使用 算法 将人类语音降低为结构化本体。然后AI算法检测意图、时间、位置和情绪等事物。但是,当我们查看NLU任务时,我们会惊讶地发现这个概念建立了多少NLP:
NLU任务
自然语言理解是许多过程的第一步,例如分类文本、收集新闻、归档单个文本以及更大规模地分析内容。 NLU的现实世界范例包括小任务,例如基于理解文本发布短命令到一定程度,例如基于基本语法将电子邮件重新路由到合适的人和一个体面大小的词典。更为复杂的努力可能是完全理解新闻文章或诗歌或小说中的含义。
总而言之:最好将NLU视为实现NLP的第一步:在机器处理语言之前,必须首先理解它。
NLP和NLU如何相关联的
从其任务可以看出,NLU是自然语言处理的一个组成部分,它是负责人类理解某个文本所呈现的含义的部分。与NLP最大的区别之一是NLU不仅仅是理解单词,它还试图解释人为常见的错误,如错误发音或字母或单词的位移。
推动NLP的假设是Noam Chomsky在1957年的“句法结构”中所设定的假设:“语言L的语言分析的基本目标是将L的句子的语法序列与不符合语法的序列分开。不是L的句子,而是研究语法序列的结构。“
句法分析确实用于多种任务中,通过将语法规则应用于一组单词,并通过多种技术从中获得意义,从而评估语言如何与愈发规则保持一致: 词形还原:将单词的变形形式简化为单一形式,以便于分析。 词干提取:将变形的词语切割成词根形式。 语素切分:将单词划分为语素。 分词:将连续文本分成不同的单元。 解析:句子的语法分析。 词性标注:为每个单词识别词性。 断句:在连续的文本上设置句子边界。
句法分析技术
但是,语法正确性或不正确性并不总是与短语的有效性相关。想想一个无意义的语法句子的经典例子“无色的绿色思想疯狂地睡觉。”更重要的是,在现实生活中,有意义的句子通常包含小错误,可以归类为不合语法。人工交互允许产生的文本和语音中的错误通过优秀的模式识别和从上下文中获取附加信息来补偿它们。这显示了以语法为中心的分析的不平衡性以及需要更加关注多级语义。
语义分析是NLU的核心,涉及应用计算机算法来理解单词的含义和解释,但尚未完全解决。
以下是语义分析中的一些技巧,仅举几例: 命名实体识别(NER):确定可以识别并分类为预设组的文本部分。 词义消歧:根据语境赋予词语意义。 自然语言生成:使用数据库导出语义意图并将其转换为人类语言。
然而,为了完全理解自然语言,机器不仅需要考虑语义提供的字面意义,还需要考虑预期的信息,或理解文本试图实现的内容。这个级别称为语用分析,它刚刚开始引入NLU / NLP技术。目前,我们可以在一定程度上看到情绪分析:评估文本中包含的消极/积极/中立感受。
NLP的未来
为了实现创建一个能够以人类方式与人类互动的聊天机器人的目标,最后,通过图灵测试,企业和学术界正在投入更多的NLP和NLU技术。他们想到的产品旨在轻松,无人监督,并能够以适当和成功的方式直接与人们互动。
为实现这一目标,该研究分三个层次进行: 语法 – 理解文本的语法。 语义 – 理解文本的字面意义。 语用学 – 理解文本的意图
不幸的是,理解和处理自然语言并不像提供足够大的词汇量和训练机器那么简单。要取得成功,NLP必须融合来自各个领域的技术:语言、语言学、认知科学、数据科学、计算机科学等。只有结合所有可能的观点,我们才能揭开人类语言的神秘面纱。
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2019-09-21 12:08:00
如今互联网大统计数据被应用到诸多领域: AT&T维护着一个311DG的数据库查寻,NSA每天使用3500万Gb的数据,而facebook用户每天分享400亿条动态 。 大数据 中充盈着大价值和大机遇。
我们创造出各种工具来便利、简化我们的工作生活。然而这种工具有时可能比别的系统软件容易欺骗我们。一些数据监控工具可能会被暗箱操作,例如Google的排名系统就能够使用黑帽seo优化来帮助某一网址在谷歌搜索引擎结果中获得更高的排名。
类似地,企业能获取的数据越大,他们越多容易算出他们想要的结果。换句话说,进行大规模的用户调查后,企业非常容易就可以把数据归类,那样方便他们使用这些数据。但是,拥有如此庞大的数据量,也给企业带来另一个难题——要从无穷无尽的原始数据中准确寻找必需的数据可不是一件简单的事。
大数据 不一直参考答案。做为消费者,我们往往偏爱量身订做而不是大批量生产,一刀切不可能对一切都合适。例如,查询路线的手机上aPP可以获得路面布局和道路驾驶证信息内容的数据,并以此为用户整体规划出一条可选择的到达目的地的最优路线。
大数据规定快,持续更新是必要的。再次使用地图软件的例子,为了处理到期信息的问题,这些app需要每秒更新一次公路交通信息。“Waze”允许用户在地图上更新交通事故、交通阻塞或者其他有用的道路信息,这样方便司机们及时了解道路状况。
很明显大数据确实很“大”,习以为常一些大企业也没有能力在日常工作上存储使用如此大量的数据。在你自个的网络服务器上使用所有数据可能会有问题,你可能没法获得足够的计算能力去分析数据,因为那样会占用服务器150%的运行時间与空间。但是如果把你数据储存在云端,数据就可以在异地服务器运行,这些服务器是为解决大数据和快速变化需求而专门设计方案的。这样你的工作服务器就可以得到释放,并给你提供灵活有效的计算能力。
“云计算技术技术非常灵活。”
把数据存储在云端,云计算可以给你提供灵活的计算能力,而你只需要付相应的费用即可。如果你需要分析频繁块的时候,我也可以切实体会到云储存和云计算的优点了。
Amazon是一个成功的案例,在引入云计算技术后,大多数时间他们只需要使用12%的服务器容积,这节省了很多钱。
所以大数据是成功还是不成功?二种观点都有很多事实论据,但是我相信正确使用的大数据必须是赢家。
未来会有更多的企业运用 大数据技术 ,这是一个节奏快的猛兽,我们必须在它摧毁我们以前驾驭它。 英语连接:http://www.smartdatacollective.com/josh-Rose/364503/big-data-winning-or-Some
文中由 数据统计分析网 – 赵焱翻泽,电子信息科学与工程专业大四学生,熟悉一些 数据分析 与挖掘的算法。
本文由 翻译小组 翻译发布,英文链接:http://www.smartdatacollective.com/josh-rose/364503/big-data-winning-or-losing,转载或内容合作请联系我们,未经允许谢绝转载,本文链接:https://www.afenxi.com/23973.html 。
数据分析
2016-08-21 16:32:00
(图片来自:pixabay.com)
现在关于 数据中台 的解释很多了,当然各有道理,但如果我问你数据中台与 数据仓库 、 数据平台 、数据湖等有什么本质区别,你不一定说得清楚。
比如我们引入的某大厂的ETL工具BDI,你认为其是数据中台一部分吗?
我可以明确的告诉你,它刚出来的时候根本不能算是中台的东西,它只是一个偏系统级的应用。
为什么?
今天就再来深入的谈一谈数据中台的本质,本篇文章有5000个字,一定要看完。
在之前,笔者先给大家看一封很久很久以前一位同事的离职信,上面是这么说的:
“非常感谢周五下午您的那次促膝长谈和写给我的两封信(一定花了您不少时间!)。这两天认真考虑了您给我的建议,并与身边好友以及XX的同学交流了看法,特别是征求了家人的建议,最终我还是决定离开。主要基于如下考虑:
工作对于我来说,最大的成就感就在于能发挥自己的专长并因此创造价值,影响决策者,在这点上,XX企业的目前的职位更为明晰一点。在传统行业,还是以业务部门为绝对主导,他们有大量和决策层接触的机会,例如……分析报告,无论是主动还是被动,他们都得到了大量的锻炼机会,并可以自由在报告中表达自己的观点、想法,影响决策者……”
这封信反映了一名数据技术从业者的困惑。
笔者再介绍自己以前写的一篇文章,名字叫 《思考|谈谈数据管理的原则》 :
“一直以来,企业的BI 数据管理 跟IT是紧捆绑的,但跟公司的战略、业务脱节非常厉害,很多企业几乎没有想过企业获取利润跟数据管理有多少直接的关系,反正是大概有关系吧。企业有投资,有费用,反正属于IT要干的事就去干吧,大家都在做,我们当然也要做,在我刚开始做元数据管理的时候,就是这个感觉,从没想到这个东西跟企业的利润有半毛钱关系。”
“做了怎么样?不做了又怎么样?我们甚至连自己都骗不过。直到开始做 大数据 ,当商务、开发必须紧密衔接的时候,当发现某个数据问题已经导致变现困难的时候,才感觉到数据管理的真正价值,才知道自己的数据管理工作该干什么。”
这是我以前的困惑。
自己不止一次的提到过:IT是业务的后端,而数据是后端的后端,数据要往前走面临着巨大挑战。 DT时代 给了我们一次机会,但有了势,没有方法和举措,你也抓不住,还好,我们有数据中台为自己正名。
但十多年前数据仓库如火如荼兴起的时候,为什么它就不能称为数据中台?为什么数据仓库就不能更好的创造价值?
笔者认为数据中台起码有三个特征,是传统的数据平台很难兼顾的: 业务化、服务化及开放化 。 业务是根本,服务是手段,开放是价值,而数据中台把三个都占全了 。
一、业务化
数据仓库是数据中台吗?
不是,因为数据仓库只是实现了数据的平台化,那么,平台化又是什么意思呢?
举个例子,我们拿一个饮料厂的产品线来讲,他可以生产果汁,还可以生产其他的产品,从原材料加工成饮料,它有很多环节,虽然品种不一样,但是它很多环节是类似的,比如装瓶、搅拌。
那么这几个不同的生产流程、生产线,我们可以把那些公共的部分合并起来,更加专业化,然后并且让他们独立去维护,之后把那些不同的产品面向客户,使客户体验不同的产品,使它独立出来,这就是平台化的思路。
所以,平台化的思路很重要的就是把那些有共性的资源,有共性的能力合并在一起,然后把那些面向客户的价值独立出来,这样的话,专业的人做专业的事情,并且对于企业的绩效也非常的有利,不揉在一块了,更加的清晰,这就是平台化的思路。
数据仓库也有一样,各方的数据资源通过E汇聚在一起,然后通过T统一做转化,再通过L统一入库再通过DW分层处理建模,最终实现数据的共享,整个过程就是柔性数据处理”流水线”,从而满足不断丰富、变化的 数据分析 、挖掘类需求,有时我们也把数据仓库叫做数据仓库平台。
但数据仓库也好,传统的数据平台也好,其出发点应该说更是一个支撑性的技术系统,即一定要去考虑我有什么数据,然后我才能干什么,因此特别强调数据质量和元数据管理,而数据中台的第一出发点可不是数据,而是业务,一开始不用看你系统里面有什么数据,而是去解决你的业务问题需要什么样的数据服务?
至于说这些数据服务所依赖的数据有没有,那是我们的实现方式,只要这个服务有价值,那我们就要去想办法去拿到数据,如果没有能力我们去建这个技术能力,去完成数据服务的提供。 (注:以上黑体字观点参考 史凯 BangTalk︱第1期《火热的数据中台对企业的价值是什么?相关论述》)
笔者以下的实践完美的诠释了以上观点。
一般来讲 数据采集 在一个企业是由统一的采集运维团队负责的,但你会发现一些数据的采集和解析方式直接决定了业务的价值,而这对于一般的采集运维团队来说是非常困难的。
比如对于位置数据,笔者就要求打破层级式的数据管理方式,让位置洞察团队直接端到端的完成从业务到数据采集的全过程,位置洞察团队实际承担着位置产品研发、行业模型研发、位置精度算法、位置数据解析和采集等多种职能,因为只有他们才能理解清楚如何根据业务要求来采集全自己所需的数据,从而让上层应用达到业务的要求。
你看,这就叫业务化,用业务驱动数据的建设,这是数据中台希望达到的目标。
我们也可以反思,为什么以前大而全的数据治理项目会经常失败?因为它源于数据,终于数据,它竟然是自我循环的。
为什么公司会限制大数据的投资?因为看不到明显的业务产出,因为没有人为你的数据平台建设背书。
数据中台区别于传统数据平台的在于数据中台的思维是业务化的思维,它从业务问题出发。这也能解释为什么业务部门对数据中台是比较欢迎的,哪怕我的数据只有50%的准确性,只要能产生价值,何必纠结于50%?
最近笔者团队上线了实时数据中台,快速的构建起了校园营销实时应用,虽然业务部门不知道实时数据中台是什么,但一定会为校园实时营销背书,这是有说服力的。
很多数据平台饶了十八个弯才跟业务挂上点关系,就是建设伊始就跟业务离得太远了,谁又能理解你建的这个东西对于业务能产生什么直接的价值。
不管黑猫还是白猫,抓到老鼠的就是好猫,看来是颠扑不磨的真理。
二、服务化
大家在提数据中台的时候,服务化应是提得最多的,因为服务化自带共享,可编排等中台核心的特征。
很多时候我们会发现不同的应用开发项目组,他们都会调用同样的数据模型,同样的数据服务,但是由于不了解数据,并且他们也不知道底层的数据结构,所以不同的项目组可能对同样的数据会用不同的处理方法,自己做自己的,然后出来的结果不一样。有的是错误的,所以开发速度慢,并且数据结果不准确,质量低,这就是过去应用开发和数据开发所面临的矛盾。
但是现在数据中台就要解决这个问题,数据中台要把那些能复用的数据模型,变成一个数据的能力平台,让那些做数据的人专注在做数据,把数据变成一个乐高积木,数据服务提供给应用开发,然后不同的应用开发项目组可以共同的去调用唯一的数据服务,从而保证数据质量和一致性,加速从数据到价值的转换过程。
笔者的企业建设了一个客户经营中心,也就是标签库,沉淀了百万级的标签,对内对外提供统一的洞察服务,对内服务于营业厅、社会渠道、手厅等渠道的个性化推荐,对外服务于智慧精选、验真、洞察、客流等变现产品,每天的调用量超过千万。
你看,通过数据服务我们把对内、对外、各类产品的画像服务全部标准化和统一化了,从而可以最大化数据的价值,但如果没有标签库前期沉淀的这些数据服务,让每个项目或产品团队自建基本是不可能的。
关于服务化的形式,有些人认为只有封装成API才算是,我觉得不是,因为数据跟功能不同,其分析的灵活性和数据维度的无限性决定了你不可能封装出所有的数据服务,因此这里的服务应该是广义的服务,只要我提供的数据能够被共享使用,在前端被业务人员或者其他机器快速方便的使用或调用,这就是数据的服务化。
正如我在 《数据中台到底是什么》 一问中所阐述的一样,广义的数据服务有三种服务的方式:
1、数据模型
数据模型是广义数据服务的基础,按照数据仓库的模型分层概念, 第一种是基础模型 ,主要实现数据的标准化,我们叫作“书同文、车同轨”, 第二种是融合模型 ,主要实现跨越数据的整合,整合的形式可以是汇总、关联,也包括解析, 第三种是挖掘模型 ,虽然是偏应用的,但模型具有共性的话就需要把它归属到中台模型,以便开放给其它人使用,中台模型的中是相对的,没有绝对的标准。
2、数据服务
将数据模型按照应用要求做了服务封装,比如API,所谓的狭义的数据服务,其更多强调的是机器与机器的接口,就是我的数据分析或挖掘出来的结果,不仅仅以报表可视化的形式让人看,而更多的是把这些API数据服务直接地嵌入到生产系统里面产生影响,变成你的价格策略,推荐引擎或者风险管控。
为什么我前面说初期版本的BDI采集工具不是一个数据中台的东西,因为它只提供僵死的界面,不提供API等任何接口,它是一个纯粹的应用。
数据封装比一般的功能封装要难一点,毕竟OLTP功能的变化有限,而数据分析受市场因素的影响很大,变化更快,导致服务封装的难度很大。随着企业大数据运营的深入,各类大数据应用层出不穷,对于数据服务的需求非常迫切,大数据如果不服务化,就很难规模化。
3、数据开发
但有数据模型和数据服务还是远远不够的,因为再好的现成数据和服务也往往无法满足前端个性化的要求,这时候就得授人以鱼不如授人以渔了,广义的数据服务的最后一种服务形式就是数据开发和探索,其按照开发难度也分为三个层次:
最简单的是提供标签库(DMP),用户可以基于标签的组装快速形成客户群,一般面向业务人员。
其次是提供数据开发平台,用户可以基于该平台访问到所有的数据并进行可视化开发,一般面向SQL开发人员。
最后就是提供应用环境和组件,让技术人员可以自主打造个性化数据产品,以上层层递进,满足不同层次人员的要求。
但你也需要知道,光有服务化不能成就数据中台,它只是数据中台的必要条件而已,而业务化是前提。
有人会说那么你的数据仓库基础模型就不能算是数据中台的东西,它可不是业务化的产物?
还真不一定,谁说数据服务就一定要从模型的上层走?比如验真的简单查询服务其数据来源就是基础模型提供的东西,数据仓库的数据所处层次跟其能给业务带来的价值并没有绝对的相关性。
三、开放化
那么有了业务化、服务化特征的数据平台总是数据中台了吧?
概念上讲是,但追求形式没意义,关键还要看数据中台的开放能力,这个决定了它能创造的最终价值。
1、开放意味着知道
数据中台要发挥出价值,光有能力不够,你必须通过各种手段告知别人你有这种能力,2016年我们就完成了大数据平台的建设,该采集的数据也采了,该提供的服务也提供了,但当时最大的挑战是如何让人家知道你有哪些数据,数据怎么访问,有什么价值,直到现在这个问题还存在,即使千人计划已经实施了多年。
对外变现更加是了,浙江移动打造了神灯大数据品牌,开通了微信公众号,在各种展会上展示我们的产品和能力,就是为了让社会知道我们是开放的,希望大家合作共赢。
2、开放意味着好用
数据中台由于直接为前端服务,对于体验的要求特别高,比如你让人家查询到了某个标签,但由于这个标签解释性差就放弃了,最近我们启动的标签治理工作就是要解决好这类问题,数据做到最后都是细微之处见真功夫。
我们提供了不少开放平台,比如数据开发平台、敏捷挖掘平台等等,但以前就是不好用啊,你的数据操作体验不如PL/DEV,人家就不会用,你不支持存储过程,人家也不会用,敏捷挖掘的性能不够,人家也会抱怨,数据开放平台的成长史就是一部项目经理、产品经理的血泪史。
3、开放意味着迭代
你敢于开放数据中台,就意味着要以谦卑的心态去接受批评并不断迭代提升,它不仅仅是说我产生完数据或产品就完事了,而是所有数据或产品的都要持续的去运营,运营的目的就是去看我提供的数据或产品服务是有谁在用,用的情况如何,产生了多少收入,从而给出提升的方法,如此循环,你的数据中台的价值才会越来越大。
迭代还意味着很多数据中台需要结合企业实际进行定制化,因为你没有现成的产品可买,诸如数据管理等大量功能都需要定制化,数据中台定制化的比例估计超过7成,意味着你很少能找到其他行业的最佳实践为你所用。
笔者所以提业务化、服务化、开放化是数据中台的特征,目的还是希望能澄清概念,提供一个较为中肯的衡量数据中台的方法,不是任何一个数据平台或组件都可以称之为数据中台的,在数据中台未达到预期前,先想想有哪些要素我是没做到的。
本文为专栏文章,来自:傅一平,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/74171.html 。
数据分析
2019-09-04 17:48:00
作者:Abhishek Parbhakar 编译:ronghuaiyang
导读 要问 数据科学家 最爱的女人是谁,这个问题很难,大家可能说出无数个答案,但是如果要问数据科学家最爱的男人是谁,那么回答就容易多了,毫无疑问就是高斯(这个答案的分布本身就是个高斯分布哦)!那么高斯分布为什么人见人爱呢?一起来看看!
高斯分布可视化.
对于深度学习和机器学习工程师来说,在世界上所有的概率模型中,高斯分布模型是最突出的。即使你从未参与过AI项目,你也很有可能遇到过高斯模型。
高斯分布模型,通常以其标志性的钟形曲线来识别,也称为正态分布,之所以如此流行,主要有三个原因。
高斯概率分布函数的 数学 公式
自然界中普遍存在的现象 所有的模型都是错的,但是有些是有用的!— George Box
扩散之后的粒子的位置可以用高斯分布来描述
自然界和社会科学中,遵循高斯分布的过程多得令人难以置信。即使没有,高斯函数给出了这些过程的最佳模型近似值。一些例子包括: 我们成年人的身高、血压和智力 扩散之后的粒子的位置 测量误差
数学推理:中心极限定理
二维随机游走,200万步
中心极限定理指出,当我们加入大量的独立随机变量时,不管这些变量的原始分布如何,它们的归一化和都趋向于高斯分布。例如,随机游走所覆盖的总距离的分布趋向于高斯概率分布。
该定理的含义包括,大量专门为高斯模型开发的科学和统计方法也可以应用于可能涉及任何其他类型分布的广泛问题。
这个定理也可以解释为什么许多自然现象遵循高斯分布。
一次高斯,终生高斯!
不像许多其他分布在变换时性质会改变,高斯分布的变换往往仍然是高斯分布。 两个高斯函数的乘积是高斯函数 两个独立高斯随机变量的和是高斯的 高斯函数与另一个高斯函数的卷积是高斯函数 高斯函数的傅里叶变换是高斯函数
简单
奥卡姆剃刀是一个哲学原理,它强调在所有其他事情都相同的情况下,最简单的解决方案是最好的。
对于每一个高斯模型的近似,可能存在一个复杂的多参数分布,可以提供更好的近似。但高斯分布仍然是首选,因为它使数学更简单! 均值、中位数、模型都是相同的 整个分布可以用两个参数指定:均值和方差
高斯分布是以伟大的数学家和物理学家卡尔·弗里德里希·高斯命名的。
英文原文:https://towardsdatascience.com/why-data-scientists-love-gaussian-6e7a7b726859
本文为专栏文章,来自:AI公园,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/73708.html 。
数据分析
2019-09-03 21:35:00
大数据 文摘编辑部出品
Anthony Levandowski是硅谷的一位明星工程师,作为自动驾驶技术的领军人物,他致力于自动驾驶汽车的研发,是谷歌联合创始人Larry Page的心腹。
除了谷歌,为了在自动驾驶领域拥有得力战将,好几家资本都向Anthony Levandowski抛出了橄榄枝,其中就包括他的下一任东家 Uber 。
而就在这周二,这位炙手可热的工程师跌落神坛。
据《纽约时报》报道,联邦检察官指控Anthony Levandowski犯有33项盗窃和企图盗窃商业机密罪。如果他被判有罪,将面临最高10年的监禁和高额罚款。
擅长知识产权保护的科技公起诉前雇员或其他公司并不少,但是,针对一名高级技术人员进行盗窃罪的指控,很不寻常。
此事源于谷歌自动驾驶汽车子公司Waymo在2017年提起的一桩诉讼。Waymo指控这位工程师下载商业机密,并在优步收购奥托(Otto)时将其交给优步。
根据起诉书,Anthony Levandowski在2016年离开谷歌之前下载了逾1.4万份文件,其中包含有关谷歌自动驾驶汽车研究的关键信息。起诉书说,他未经授权将这些文件转移到了自己的笔记本电脑上。在那年的晚些时候,Anthony Levandowski加入了优步,当时优步收购了他的新自动驾驶卡车初创公司奥托(Otto)。
在起诉书中罗列出的33项盗窃内容(部分)
Anthony Levandowski从谷歌获得的一些文件包括专有电路板的私人示意图,以及用于自动驾驶汽车的激光雷达光传感器技术的设计。
旧金山分部的联邦调查局特别探员John Bennett在周二的新闻发布会上说,“湾区有最优秀、最聪明的工程师,他们冒着很大的风险。但硅谷不是蛮荒的西部。快节奏和竞争环境并不意味着联邦法律不适用。”
加州北部地区的联邦检察官David L. Anderson告诉纽约时报,“每个人都有换工作的自由,但是我们不能在走出公司门的时候把自己的口袋塞得满满的”。
Google 起诉,Uber解雇
Anthony Levandowski和他的辩护律师
Anthony Levandowski的辩护律师表示,“十多年来,Anthony Levandowski一直是自动驾驶汽车和卡车技术领域的行业领先创新者。本案的证据将最终证明安东尼没有偷任何东西。不是来自谷歌,不是来自任何人。”
优步计划开发自己的自动驾驶出租车车队,在最初站在支持Anthony Levandowski的一方。但在Anthony Levandowski请求用第五修正案避免在法庭上自证其罪后,Uber于2017年5月解雇了他,并与原告继续谈判达成和解,其中包括将一小部分股份移交给Alphabet、谷歌和Waymo的母公司。
下一次庭审将在9月4日。Uber在一份声明中表示“会配合政府展开调查”,Waymo的发言人Suzanne Philion也表示,“我们一直认为竞争应该由创新来推动,我们对美国检察官办公室和联邦调查局在此案上所做的工作表示感谢。”
跌落神坛的 无人驾驶 元老+技术狂人
Anthony Levandowski一直是自动驾驶领域的“元老级”人物,在无人驾驶发展历史上,有着不可动摇的地位。
熟悉自动驾驶的人对DARPA(美国国防部高级研究计划局)无人驾驶汽车挑战赛一定不会陌生,从2004年起,一群疯狂的家伙聚在一起,完成了一场伟大的挑战赛。业内甚至流传说,没有那场比赛,就没有现在的蒸蒸日上的无人驾驶行业。
在2004年的一个清凉的星期四早上,第一届DARPA在莫哈维沙漠拉开了战幕。一辆来自加州大学伯克利分校的的自动驾驶摩托车毫无疑问成了媒体的宠儿,他的设计者给它安装了陀螺仪,这样可以通过反向旋转来保持平衡。
这辆摩托车有个名字:Ghostrider。然而在赛前的兴奋和欢呼中,它的设计者忘记了把Ghostrider切换到自动驾驶模式,于是在起跑线就一头栽倒了。
那个忘记切换自动驾驶模式的设计者就是1998年进入伯克利学习的Anthony Levandowski。那辆摩托车如今还存放在史密森尼国家美国历史博物馆。
Anthony Levandowski在测试摩托车,为DARPA大挑战赛做准备
2006的DARPA比赛Levandowski还是带着他的摩托车去参加了比赛,而在那次比赛上,他遇到了那次比赛的冠军,来自斯坦福大学的Sebastian Thrun,Thrun邀请Levandowski参加一个名为VueTool的项目,后来Thrun的整个团队被谷歌相中,给每人高达100万美元的奖金来解决街景问题,并将其投入运营。
2007年,Levandowski也跟随Thrun的团队进入了谷歌,当然,也拿到了谷歌的100万美元奖金。
然后在2008年,他创立了Anthony’s Robots,设计了一个名为“Pribot”的丰田普锐斯自动驾驶汽车。根据《卫报》的说法,它是“一辆自动驾驶的丰田普锐斯,配备了第一台旋转式激光雷达激光测距装置,并且是第一辆在公路上行驶的装置。”
Anthony’s Robots后来被收入谷歌,然后Levandowski就一直在谷歌开发自动驾驶汽车,直到2016年1月,他离开谷歌创建了Otto,这家公司生产自动驾驶套件以改装大型钻井平台卡车。根据《纽约时报》报道,Levandowski说他离开谷歌是因为他“渴望尽快将自动驾驶汽车商业化”。
Otto于2016年5月成立,并于2016年7月下旬被Uber收购。作为收购的一部分,Levandowski本人除了在Otto工作外,还担任Uber无人驾驶汽车运营的领导。
Anthony Levandowski是一个把 人工智能 视为人类终极技术的“狂人”,根据2017年9月《连线》杂志报道,Levandowski建立了一个名为“未来之路”的宗教组织,以“发展和促进基于人工智能的神性的实现。”
但是没有想到的是,这位无人驾驶领域的“元老”,认为上帝是机器人的科技崇拜者,如今却因为被指控“窃取技术”要迎来自己的清算日。
频发的无人驾驶公司知识产权盗取事件
这不是无人车领域的第一次知识产权盗窃争端。
近年来,在谷歌、特斯拉、苹果这些大公司的无人驾驶业务中,因为人员流动带来的指控一直没有停止过,包括中国在内的一些无人驾驶公司也牵涉其中。
18年的7月份,FBI曾指控前苹果工程师张晓浪(Xiaolang Zhang)涉嫌窃取有关苹果在自动驾驶汽车项目专有信息,并试图将其带到位于广州的初创公司小鹏汽车。
张晓浪于2015年12参与自动驾驶汽车项目相关软硬件的开发,在休陪产假期间,张晓浪举家回国。休完假期之后,张晓浪告诉苹果自己即将离职,加入总部位于中国广州的小鹏汽车;6月底,张晓浪接受了美国联邦调查局(FBI)质询,承认自己窃取了相关信息;7月7日,张晓浪试图离开美国前往中国时被捕。
当时小鹏汽车发表声明,积极配合调查:称并不了解此事,也没有以任何形式参与此事。小鹏汽车会保持对事的关注和配合,并努力做相关配合工作,目前事件仍在调查中。
今年三月份,海外媒体Verge称特斯拉已经在本周三对一名华裔前雇员发起诉讼,指控他为国内电动车品牌小鹏汽车窃取了机密资料。
同时期的另一个诉讼中,自驾车创业公司Zoox也指控一名员工,涉嫌盗用公司的商业机密。
在硅谷,围绕知识产权的诉讼频发。但在自动驾驶领域,硅谷初创企业正与试图重塑的传统汽车制造商角力,摩擦尤其激烈。Anthony Levandowski可以说是该领域第一个真正引人注目的法律纠纷,但不太可能是最后一起。
自动驾驶相关人才短缺及业务竞争的白热化,也导致了近年来相关人才的频繁流动。知识产权一直受到各大科技巨头的高度重视,而在今天全球化竞争白热化状态下,所有公司都面临如何更好的保护自己研发成果的困境。
而对于公众来说,此事最大的疑问在于: 如果我们不能相信制造自动驾驶汽车的人,我们还能相信他们创造出来的自动驾驶汽车吗?
本文为专栏文章,来自:大数据文摘,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/76242.html 。
数据分析
2019-09-01 20:35:00
作者|黄崇远 (题图:pixabay.com,CCO协议) 公号, 数据虫巢 (ID: blogchong)
01 写在之前
上一篇《 数据与广告系列九:有意思的本地化广告 》时间是7月30号,刚好隔了一个月,哈哈,这不算断更,正常的更新节奏啦(公众号:数据虫巢)。不知不觉中《数据与广告系列》已经更到了第十篇了,以均篇5000的字数来看,也有5万多字了。
在最近的一年多时间里,突然发现散篇写的相对偏少些了,不知不觉中自己也习惯的去从更全局的角度去组织知识结构,然后形成偏系统化的知识结构。除了目前的《数据与广告系列》九篇,还有《推荐系统系列》六篇,《躁动的季节里非典型跳槽指南》四篇,《数据与业务系列》三篇,《读书清单系列》四篇。
而当前《数据与广告系列》从目前的角度来看,还有继续下去的空间。这个情况,或许也是自己对于相关知识结构的一种更体系化的思考,应该算是一个好事吧。以前是个写“短篇小说”的,现在终于开始写“中长篇”了。
02 关于 算法 的执念
在之前的规划里,这个系列应该从广告的起源,到涉及到技术架构,再到推荐系统的交叉结合对比,再到各个不同类型的广告业务场景,这么一个结构逻辑。所以,原定这个系列下一个内容,极有可能是涉及到游戏广告的垂直领域方面,也有计划去做这块的深入探索。
但是,从写完《推荐系统系列》之后,再到写到《数据与广告系列》第九篇,总感觉整个知识结构体系里缺了什么。直到最近才猛然想起来,是的,是算法维度的东西。
以数据为核心,再到业务的应用场景,没有毛病,但是始终是少了最重要的一环,那就是算法。虽然在《推荐系统系列》里,也涉及到了一些常规的推荐算法逻辑,甚至是代码层级的东西,但始终是太过于入门,而非正统的算法以及 机器学习 的陈述逻辑和知识结构,说白了就是,那个逻辑还是以初步架构起推荐系统整体结构为主的知识结构逻辑,而非最终的形态。
换句话说就是,那始终是低level的东西,而我们总是要有更高追求的。
所以,接下来的内容里,将会出现大量算法,或者更严格意义上是机器学习的东西,当然,不会纯粹的理论上的东西(太理论的东西我也不擅长),依然会结合广告的整个机器学习应用场景来看,很多东西我也不会,边走边看。
但我能保证的是,只有我吃透的东西才会抛出来给大家,并且将尽可能的结合广告实际的场景,然后拿更贴合实际的数据(kaggle上的相关数据集),然后一边聊广告,一边来手撕机器学习代码,顺带还可以聊聊人生。
03 广告中的机器学习应用场景
既然这是广告算法相关的延申,当然少不了来看算法,但不是这篇,开篇总不能上来就手撕代码,我们先来看看机器学习在整个广告流程里,到底可以做些什么事,然后才知道后续我们的规划逻辑需要进一步去学习什么,了解什么。
广告的排序
回忆一下第七篇《推荐与广告技术架构》中广告技术的架构图,其中非常重要的一环就是广告的排序。所以,说到算法在广告中的应用,第一个能想到的就是通过机器学习做到广告的最优排序。
再回忆一下广告排序逻辑上会涉及到几个因素:出价,上下文匹配,CTR预估。这本身就是一个多元素组合最优排序的问题,里头CTR预估又是广告领域里头最核心需要解决的问题。
因为很多广告系统里,可能做不到上下文理解,出价逻辑也可以做的稍微粗糙一点,但是对于CTR预估,都是重中之重,首先需要解决的问题。CTR预估本质上就是对于候选曝光用户,针对于每个广告候选池做点击概率的预估计算。所以是一个非常典型的偏回归的问题。
上下文理解
延续上面的话题,上下文理解又或者说上下文的匹配。简单来讲就是,计算环境因素与广告因素的匹配度的问题,或者说相关度的计算。当然,匹配度只是解决上下文理解的一种方式或者说这类机器学习的模型可以解决这个问题。
其实还有其他方式可以去解决的,比如当你样本累计够多的时候,也不单纯计算内容的相关度,也可以从推荐系统的思路去思考,即大量的广告环境与广告曝光关系数据,用户在这个组合下的ctr数据。这不是一个非常典型的关联分析的场景吗!将上下文的环境与广告,通过历史信息,做关联分析,而非基于内容相关性分析。
从目的的角度上来说,最终都是期望用户点击广告,所以不管是关联分析还是相关性分析,都是一种途径。
lookalike人群扩展
人群扩展是广告领域里典型的需求场景,说的更直白点就是,当我要的人,明面上没有这么多的时候怎么办?给我预测一下,扩展一下呗。
所以,lookalike本质上拿到核心用户(所谓核心用户,就是已经验证过的高转化人群),然后计算类似的用户(不是严格意义上的内容相似,而是最终转化目标相似),这样就达到了扩展的目的。
而通常扩展的原始用户则是用户圈选定向的那一拨人,但是显然定向圈定的人群与其实际需求曝光量级有差距。还有一种更常见的扩展场景,就是广告主导入自身积累的高转化核心人群,这就是最精准的定向,然后平台负责帮我找到相同的人。
回归到机器学习,你可以认为这是一个相似用户计算的场景,二值判断,概率计算,最最简单,你用LR就能满足你的需求了。但也不止这么简单,因为很多时候你会发现你的训练样本可能是数百万,甚至是上千万的数据集,然后如果维度不小心做到几十万维,几百万维,甚至是千万级,那么你要解决的问题就多了。
标签定向
我们知道,定向算是广告体系里的人群召回阶段,从基础的男女性别,到更高纬度的商业兴趣,诸如你要不要减肥,是不是要贷款等,而这些最具象化的形态就是用户标签。
每一个成熟的广告平台,都有一个完整且相对精准的标签体系,每个其体系里头的人都或多或少能打上若干个标签。所以,总有某个合适的广告场景中,平台能把你卖出去,卖个好价钱。
回忆一下之前的文章,广告的本质就是卖流量,卖人。虽然有点残酷,但这就是终极的本质。而将人标签化,就是将人分门别类,就跟超市里超市大妈把不同的货品放到不同类目货架上一个理儿,方便顾客“挑选”(太佩服自己了,竟然写的这么有哲理,/捂脸)。
而标签的制造说简单也简单,说难也难。举个简单例子来说,最基础的性别标签,如果有场景可以收集身份证号,自然简单,但是如果没有,你靠猜?所以,这里就是典型的二值分类场景了(也有做三分类的,比如微博里,除了男女,还有诸如大把的机构属性的账号)。
除此之外,还有茫茫多数百个其他标签,各个层次的,各个细分领域的,简单的你可以通过行为规则的方式去打上一些标签。通过行为规则做判断,只要规则合理,准确性固然是可期的。但是,一方面是有显性行为的人量少满足不了你大规模曝光的需求,另一方面召回能力太差,用机器学习的专业术语叫泛化能力太差。
所以,从机器学习的角度来说,这又是典型的判别模型场景,而且是超多分类的场景。当然,你同样可以转化成二值分类,针对于每个标签,都是一个YES OR NO的答案。
当然,在实际的处理中,大部分可能只会计算一个概率值,再来做进一步的计算和判断。而基于用户行为,肯定又会遇到大量的文本,自然语言处理的东西自然是少不了的。
异常分析
所谓异常分析应该属于偏反作弊的范畴了。比如,大规模的机器点击广告,造成假量怎么办,就算不是机器,也总有一些人闲着蛋疼没事干,点着广告玩,更过分的就是那种连接投放收集信息的广告场景中或者二类电商。
填个空号是常态,打个电话过去说非本人也是正常的,二类电商中,地址都到门牌号了,名字写着“周杰伦”,你是不是该犹豫了到底要不要发货呢,万一拒收来回邮费可白搭了。
广告主很忧桑,每个点击都是要扣钱的,每个被拒收的单子不单纯浪费发货精力,更重要的是来回邮费成本,都是小本生意,经不起折腾。
所以,二类电商一定是要控制主脏单率的(所谓脏单就是那种地址找不到,各种拒收的单子),而CPC那层,大量的恶意无效点击也是不可行的,这些压力最终必然会落实到平台上,平台必须要解决这一类人。
把那些有恶意广告行为的人给逮出来(有历史污点的好处理),但是那些有这方面潜力的人也得揪出来,以防后患!
从机器学习和算法的角度来看,这就是一个典型的分类场景,但这真的不是一个典型分类场景。要知道,坏人总是少数的,如果你平台上都是坏人,你的平台也不用玩了。
这是一个“大海捞针”的活计!
即,你要从数千万,甚至是数亿的用户里,捞出寥寥数十万,最多数百万的“可能的坏人”出来。这是一个典型的正负样本极度不均衡的场景,而这可是分类场景里的大忌,简直是灾难,属于非常难以处理的场景之一。
04 想手撕代码吗
如上,那些只是暂时我能想到的机器学习在广告平台上的应用场景,基于我浅薄的学识,一定还有其他更多的场景需要用到机器学习去解决。
说这么多还不如,上个代码,是吧。
莫着急,既然开了机器学习这个头,代码总是有的。在接下来的篇章里,我们将沿着上面我们所说的这些场景,一个一个来了解,立足于真正的广告诉求,用kaggle里的真实数据,结合机器学习的知识来解决这些问题。
又基于我那不算靠谱的机器学习理论,所以,接下来的内容里,将会是两分广告场景,三分机器学习理论,五分手撕代码,这么一个结构,也是一个相对合理的结构,更容易理解和吸收。
本文为专栏文章,来自:数据虫巢,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/73873.html 。
数据分析
2019-08-30 16:35:00
作者:Adam Carrigan
编译:ronghuaiyang
导读 数据科学家 为什么这么贵?这篇文章通过一些统计数据告诉你为什么
当你听到“数据科学家”这个头衔时,你会想到什么?可能不是一个衣衫褴褛、表情严肃的白领,对吧?
也许这就是为什么《哈佛商业评论》(Harvard Business Review)将“数据科学家”称为“21世纪最性感的工作”。他们写道,“如果‘性感’意味着拥有非常抢手的稀有品质,那么数据科学家已经在那里了。”他们很难招到,也很贵,而且由于他们的服务市场竞争非常激烈,很难留住他们。
数据科学家是受过训练的专业技术人员,他们对数据世界的发现充满了好奇心。尽管“数据科学家”一词最近在Linkedin上很流行,但这个领域本身并不新鲜。在《哈佛商业评论》发表这篇文章时,已有数千名数据科学家在初创企业和公司工作。此外,使计算机与人类一样智能的目标已经追求了近四分之一个世纪。数据科学家最近如此受欢迎有多种原因。其一,当收集数据成为时髦依赖,公司多年来一直收集越来越多的数据,由大型技术公司的成功很大程度上是得益于他们收集的数据,其次,技术的进步使得这些数据集合成为资产。
现在有大量现成的数据等待分析:
现在所有行业的大多数大公司都可以获得大量的数据,但是许多公司并没有以一种有效和富有成效的方式使用这些数据。然而,企业现在开始意识到,它们需要利用目前通过企业 数据库 可以访问的大量数据。多少数据?从2013年的4.4万亿gb增加到2020年的44万亿gb。
数据的数量和种类为有能力使用它的人和收集它的企业创造了机会。然而,该行业正面临着技能和专业知识的短缺,而这些技能和专业知识是处理那些寻求利用其丰富数据的公司日益增长的需求所必需的。甚至那些在大学里学习计算机科学和技术的人也被迫在工作场所从事要求很高的 数据分析 工作。
数据科学人才结构性短缺:
根据加州大学河滨分校的统计数据,1/3的美国新闻与世界报道全球100所顶级大学提供数据科学学位。在这29所大学中,只有6所提供本科水平的数据科学课程,其余的是研究生学位。这些数据科学项目的平均班级规模只有23名学生。加州大学(University of California)预测,在已经为数不多的提供数据科学课程的大学中,小班授课不太可能“在缩小全球数据科学人才缺口方面产生有意义的影响”。在简单的经济术语中,需求超过了供给,在这种情况下,远远超过了供给。2017年,IBM预测,到2020年,每年对新数据科学家、数据开发人员和数据工程师的需求将达到近70万个职位空缺。因此,一所大学仅有23个学生班级,而所有提供数据科学课程的大学大约有700名毕业生,将无法满足快速增长的对数据科学人才的需求。
2018年,初级数据科学家的平均工资为11.5万美元,管理10至15人团队的人可以要求高达35万美元的工资。与此同时,数据科学家的平均工作年限从2014年的9年降至2015年的6年。到2019年,全球对数据科学家的需求预计将超过供应的50%。超过40%的公司认为他们招聘数据科学家的无能阻碍了他们的竞争力,难怪超过60%的公司内部培训他们的员工。
Andrew Ng
有两种方法可以填补这一空白:
有两种主要方法可以帮助缓解这种技能短缺。首先, 人工智能 超级明星Andrew NG支持的一种方法是使用非传统的方法来培训更多的数据科学家,比如大规模在线开放课程(MOOCs)。虽然这对于当前的开发人员和其他以数据为中心的员工来说是一种“提高技能”的好方法,但它还不是更大问题的解决方案。我说“还没有”,是因为这从根本上要求改变行为。雇主还没有对这种教育给予足够的重视,许多雇主在招聘时仍然只看名牌大学。虽然这种心态正在缓慢地改变,但它来得不够快,不足以在中短期内解决问题。
第二种方法是让更多没有数据科学技能的人能够轻松地将这些复杂的技术应用到公司数据中。本质上,让 人工智能 和机器学习解决自己的问题。通过使用过去几年开发的技术(包括这里的MindsDB),可以模拟数据科学家,这样即使是非技术人员也可以通过几行代码或几次单击来执行数据分析。
这两种解决方案并不是相互排斥的,它们将协同帮助企业以更有意义的方式使用数据,从而推动成本节约和/或推动增长和收入。为了有效地实现这一目标,企业内部需要进行文化变革,从而制定更好的招聘政策,更好地使用工具和软件,这些工具和软件可以解决企业面临的许多数据问题,而不需要扩大员工数量,也不需要聘请昂贵的数据科学家。
英文原文:https://medium.com/mindsdb/data-scientists-why-are-they-so-expensive-to-hire-7c173bbc1f1a
本文为专栏文章,来自:AI公园,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/73722.html 。
数据分析
2019-08-30 09:17:00
(图片来自:pexels.com)
作为一个受过专业培训的 大数据 工作者,我是早先加入贝尔实验室网络性能组的人员之一。
此后的一两年左右,我开始了数据汇报。我的第一次大型数据汇报是在AT&T(美国电话电报公司)总部。在提前做了充分的准备和细致的演练的情况下,我前去赴会。
我的展示糟糕至极,没有给人留下任何好印象。那时的我年轻气盛,将责任归咎于他人,甚至包括听取汇报的观众。我说:“这里的部门经理甚至看不懂一张饼图。”
一位听取过众多类似汇报的资深人士对我的表现大跌眼镜,他对我如是说,“当然看不懂,汤姆,他们不需要看懂,让他们明白数据的含义是你的工作。”
那是我在展示数据的第一个经验。一 个 数据分析 汇报工作者面临一项艰难的任务,即让他人明白并相信数据的含义,并且要照顾到听众的专业背景 ,以易于听众理解的方式展示汇报数据。 最好的方式就是将数据划分层次,并配上通俗易懂的解释说明。 正如爱德华·塔夫特所建议的, <用生动有力的方式讲解数据>标记轴线,不要曲解数据的含义,同时将非相关信息图表减至最少。
基本的图表分析汇报可以以这样的方式开始, “这是我们的数据质量项目报告,它以时间为序,虽然有听众对这些图表再熟悉不过,但也请确保我们的进度一致。如大家所见,这份汇报是关于客户数据质量的。X轴是时间轴,每个点代表一个月,Y轴是数据分数,与每个点的月份恰好对应。我们以此来衡量精度。这是一个较高的标准,对此我一会儿将详述。” 之后便是为听众解释如何读懂展示的图表。“绿线代表实际结果,蓝线是我们设定的目标值,红线代表限度,在我进一步解释汇报这些数值前,大家对如何读这张图表是否还有疑问?”
记录下你将要给听众详述的部分之前,确保已经给听众解释清楚了如何读图的基本信息,这样听众就可以专注于所见的图表,并专心听你的数据汇报了。
关于这些,要讲的有很多,譬如如何开始项目、开展项目的原因,围绕客户需求条款的乐趣和挑战所在;客户需求的衡量标准,包括Y轴度量选择的逻辑;项目改进;如何确立限度,即红线的本质含义;为听众点明你所进行的每一个环境的意义影响……
听众不同,需求不同,汇报人的阐释要尽可能简明扼要。比如,技术团队希望搞清楚选择度量的细节和制作图标的软件;高层领导想要明白扩展数据对于整个机构的意义。汇报对于每个听众是一样的,但却听众的需求却各有侧重。
要清楚很多人对于 数据分析 ,数据库和统计数据是持怀疑态度的,(你可能会想到那句有名的谚语:“世界上有三种谎言,即谎言,该死的谎言和统计数据。”)不管这样的怀疑是否有道理,它确实使得机构运行好创意的脚步放慢甚至终止。作为一名数据汇报者,肩负着让听众信任数据的神圣使命。汇报人一定要做到:
1、汇报尽可能准确、直白,特别是在汇报成果不利的情况下,更应如此 。此外,如果数据结果显得有点不太明智,一定要简单地陈述事实。
2、如果展示的是一张综合性图表,对于重要信息的遗漏就等于是在说最糟糕的谎言 。
3、提供适当的背景介绍,如数据来源,为确保数据真实有效所做的工作 。(如果对此所做之事甚少,一定要言简意赅地说明“数据来源不明,可能会影响到结果”)
4、总结数据分析,包括汇报结果的不足之处和替代说明。
陈述自己的观点无可厚非(通常也是合理的),但一定要将自己的观点和事实分开。不论分析有多到位,总有言过其实的地方,直觉会混淆事实。要清楚两者之间的界限。
现在更进一步关注听众需求。 成功的汇报案例大多是以让听众明白幻灯片展示内容为基础 。听众在观阅连续播放的幻灯片时,可能无法从你的汇报中有所收获,所以你必须考虑到他们的需求。早先在贝尔实验室时,我曾听说“听众读表的平均时间在15秒,不要让他们花费13秒去搞懂如何读图。尽可能多地在可以标记的地方加上注释,能让图表替你说话更好。”
根据此想法,进行两个步骤。 第一,在幻灯片说明页提供如何读图的解释。第二,如下图所示为图表注解。 注释当然不可能取代汇报,它们只是为听众提供相关信息。
对于大多数听众来说,即便是为微小的洞察做出长篇大论的分析也在所不惜。因此,手边的一张切中问题要害并能引导后续步骤的出色图表要胜过万千无用的图。找到这样出色的图,以此来展示,数据就是力量。
只要你有值得分享的见解和结论,我所建议的方法并不难于实践。领导们,甚至是那些对数据持怀疑态度的人们,迫切期待改善提升部门和公司的方法。作为一名汇报人,你的工作就是以最简明的方式发掘并满足他们的需求。
译者 secretplanet 原文来源:blogs.hbr.org
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2019-08-29 17:25:00
(图片来自: pexels.com )
Kafka 是一个非常流行的分布式消息队列,它可以实时地支持海量的数据,可以支持非常高的吞吐率和低延时,它在 Uber 得到了非常广泛的应用,很多的核心业务都会用到它,比如打车服务和送餐服务。
本文将介绍 Uber 如何搭建一个基于 Kafka 的跨 数据中心 复制平台,除了有关 Kafka 在 Uber 的应用,还有 Uber 的 Kafka Pipeline,以及在哪些应用场景下会用到跨数据中心的复制等等。
本文整理自徐宏亮在 ArchSummit 全球架构师峰会 2019 北京站的演讲。
首先我会介绍一下 Kafka 在 Uber 的应用;然后是 Uber 的 Kafka Pipeline,以及在哪些应用场景下会用到跨数据中心的复制;之后会介绍我们开发的跨数据中心复制平台 uReplicator,最后是我们在复制过程中所做的数据丢失检测。
Apache Kafka at Uber
Kafka 是一个非常流行的分布式消息队列,它可以实时地支持海量的数据,可以支持非常高的吞吐率和低延时,它在 Uber 得到了非常广泛的应用,很多的核心业务都会用到它,比如打车服务和送餐服务。
在使用打车服务时,司机和用户的应用都会将自己当前的信息实时发送到 Kafka,我们在 Kafka 的下游有一个流处理的平台,它从 Kafka 实时读取数据进行计算,得出动态打车的价格。
而送餐服务有一个重要特性,需要计算出实时的预计送达时间,大家打开应用的时候,会看到每一个餐馆后面都会有一个预计的送达时间,我们的后台会有一个机器学习的平台,实时从 Kafka 读取商家、司机和用户三方的数据,用机器学习的方法去动态计算这个送达时间。当然还有很多这样的例子,包括我们对诈骗的实时检测、司机和用户的注册,这些都可以基于 Kafka。
总结来看,Kafka 在 Uber 的应用主要有以下五大类场景:
第一类是将 Kafka 作为最基本的消息队列。各种服务和应用都可以将数据发送到 Kafka,也可以从 Kafka 进行读取,不允许服务之间进行直接的通信,从而避免网状的通信;
第二类是将 Kafka 作为流处理平台数据的来源。在 Uber 我们有一个开源的流处理平台 AthenaX,在这个平台上我们可以运行 Samza 和 Flink 的 job,它们从 Kafka 读取数据进行实时计算,计算完成后也可以将数据发回给 Kafka,再传回到下游;
第三类是将 Kafka 作为数据库。我们的数据库会将自己的变更日志通过 Kafka 传输到下游,也会通过 Kafka 进行跨数据中心的传输;
第四类是将 Kafka 作为批量加载的服务。如果想把数据加载到 HDFS 和 S3,首先需要将数据发送到 Kafka,再由 Kafka 统一加载到 HDFS 和 S3;
第五类是将 Kafka 作为常见服务和应用的日志。所有的服务和应用都可以使用我们提供的库将日志发送到 Kafka,然后用户既可以直接从 Kafka 进行读取来进行调试,也可以通过 Kafka 将日志加载到 Elasticsearch 之类的检索平台进行搜索。
在这五类场景中,Kafka 在 Uber 扮演了一个数据中枢的角色,基本上所有的服务都会将数据发送到 Kafka,而后再进行读取和进一步的操作。
Apache Kafka pipeline & replication
因为对 Kafka 有着非常广泛的应用,所以我们的 Kafka 集群规模也非常大。我们的集群现在有数万个 Topic,每天都会处理超过万亿条的数据,每天的数据量也会达到 PB 的级别。下面我们来看一下 Uber 构建了怎样的 Kafka pipeline,以支持这些应用的场景。
在 Uber 我们有多个数据中心,每个数据中心都会有一个单独的 Kafka pipeline,在每个 pipeline 里会有多个 Regional Kafka 集群,每个集群处理不同类型的数据,比如有的集群处理服务日志相关的数据,有的集群处理核心业务相关的数据,从而做到较好地隔离不同类型的数据。
在每一个 Kafka 的集群前面,我们都会有一个 Kafka REST Proxy 集群,它其实就是一个 REST service,所有应用和服务都会使用所提供的 REST Client 将数据首先发送到 REST Proxy,再由 REST Proxy 统一发送到 Kafka,这样就做到了 Client 和 Kafka broker 之间的隔离。
每一个 Pipeline 最右边都有一个 Aggregate Kafka 集群,它的作用是收集所有数据中心里 Regional Kafka 的数据,相当于它会拥有全局的数据。如果一些服务处理需要全局数据的话,可以从 Aggregate Kafka 读取,再进行进一步的操作。在 Regional Kafka 和 Aggregate Kafka 集群之间,由 uReplicator 跨数据中心、数据平台进行实时复制。
下面,我们来看一下,我们在哪些场景下会需要用到跨数据中心的复制。
第一个应用场景是 Aggregation,很多服务都需要一个 Global view 来处理数据,需要一个复制平台将所有的数据从所有数据中心的 Regional 集群复制到 Aggregate 集群。
第二个应用场景,对于那些需要 Global view 的服务来说,他们通常只运行一个数据中心,当这个数据中心出现问题以后需要切换到另外的数据中心,在切换的过程中,他们需要知道切换之后需要从哪一个 offset 继续开始读取数据,所以复制平台在复制的过程中,还需要做一个额外操作,实时将复制数据的 source 和 Destination 的 offset 的对应关系发送到一个叫 offset Sync 的服务,这个服务可以实时收集所有 Partition offset 的对应关系,计算出从一个数据中心切换到另一个数据中心后需要从哪个 offset 进行读取。这样既可以保证没有数据丢失,还可以保证将重复数据降到最少。
第三个应用场景是批量加载服务,我们需要首先将所有的数据复制到 Aggregate 集群,再统一加载到 HDFS 或 S3,这样可以避免零星加载,也可以使加载过程做到更好的批量化。
最后一个应用场景是,我们可以利用这个复制平台来做 Topic 的迁移,既可以从一个数据中心迁移到另外一个数据中心,也可以在一个数据中心里将一个集群迁移到另外一个集群。Topic 迁移的难点在于通常 Producer 和 Consumer 都不在一个组,也有可能会有多个 Producer 和 Consumer,所以我们很难做到让它们在同一个时间进行切换。
我们的做法是,从新的数据中心往老的数据中心迁移时,先搭建一个复制的集群进行数据的复制。我们可以把 Producer 首先迁移到新的数据中心,因为有了这个复制集群,所以两个数据中心会有相同的数据,这样 Consumer 就可以在 Producer 迁移完之后,再慢慢迁移。如果我们有多个 Consumer,他们也可以按照自己的计划分别进行迁移,当所有的 Consumer 都迁移完以后,我们才可以把这个复制集群移除,至此迁移的过程就算完成了。这么做的好处是,在迁移的过程中可以把对 Consumer 的 down time 降到最低。
uReplicator
那么,我们为什么想要开发一个我们自己的跨数据中心复制平台呢?
2015 年,我们使用的是 Kafka 自带的 MirrorMaker,在使用的过程中碰到了很多的问题。
首先,它使用了 Kafka 的 High-Level Consumer,所以就不可避免地会发生昂贵的、非预期的 Consumer Rebalance,虽然 Rebalance 可以更好地将 Partition 分配到 Worker 上,但 High-Level Consumer Rebalance 有几个缺点。
第一, 不可以控制它什么时候发生,比如增加或减少 Topic 时可能会触发 Rebalance,增加或减少 Worker 时也可能会触发 Rebalance;
第二, Rebalance 的过程中所有复制都会停止,这段时间任何数据都无法流入到下流,这非常不好。另外,在 Rebalance 结束之后,会留下这段时间的 backlog,MirrorMaker 会有一个巨大的 traffic 去 Catch-up 这些 backlog,这样的 spark 对 Destination 的 broker 也有非常大的影响。
第三, 当时 MirrorMaker 使用了一个静态的 Topic List,需要在 MirrorMaker 集群启动的时候读取,想要增加或者减少一个 Topic 时,需要更新这个静态的文件列表,再重启整个 MirrorMaker 集群。每次都要维护静态文件很不方便,而且在重启集群的时候又会导致触发 Rebalance 的问题。
第四, 当时的 MirrorMaker 无法控制 Consumer Commit offset 的时间,经常出现把数据发送到了 Kafka 的 producer 里,但是还没有实际送到 Destination 的情况。这个时候,Consumer 就 Commit 了 offset,在这种情况下,如果这一个 MirrorMaker 的 Worker Crash 了,恢复以后就不会再去重复复制这些信息,那么这些信息就彻底丢失了。
最后,因为 MirrorMaker 使用了一些静态的配置文件,当这些文件没有被同步到所有 Worker 上的机器时,启动时就会发生各种问题。
所以基于以上这些问题,我们决定开发一个自己的复制平台。我们对这个平台提出了五个要求: Stable replication
希望这个平台有稳定复制的能力,如果有 Topic 或者 Worker 在复制过程发生变动,复制行为不应该受到影响,还可以继续稳定复制。 Simple operations
希望可以方便地增加或者删除 Topic,而不需要维护静态文件,不需要在每次改变 Topic 的时候重启整个集群。 High throughput
希望这个平台有非常好的性能,以满足 Uber 数据量的增长。 No data loss
希望在复制的过程中可以保证没有数据丢失。 Auditing
和上一个相关,希望有机制可以检测是否真的发生了数据丢失。
基于这些要求,我们开发了第一代 uReplicator,引入了分布式的任务管理框架 Apache Helix。简单来说,它由 Controller、Participant、Resource 几部分构成。在我们 uReplicator 的具体应用中,Controller 就相当于我们的 uReplicator Controller,可以用来做 Partition 的分配;Participant 相当于实际用来进行复制操作的每个机器;而 Resource 就是每个 Kafka Topic。
Helix 的工作原理是在 Controller 里通过自带的算法或者用户自定义的算法进行一定的计算,把每个 Resource 以 Partition 为单位,分配到 Worker 上,Worker 在收到以后再进行进一步的操作。所以,在引入 Helix 以后,我们相当于取代了 High-Level Consumer 里面的 Consumer Group Coordinato 角色,完全自己控制 Partition 分配的行为。这样我们直接解决了两个问题,第一是稳定复制的能力,当 Topic 或者 Worker 发生变动的时候,可以控制这个变动所带来的影响;第二个好处是,我们在 Controller 里加了一个 End Point,这样我们就可以使用 curl 命令,在运行的时候动态地进行 Topic 的增加和删除,这样就弃掉了静态的 Topic List,不需要再重启整个集群。
我们还对 MirrorMaker 的 Worker 行了一系列的改进,把它演变成了我们的 uReplicator 的 Worker。我们没有改变模式,但将 MirrorMaker Worker 里面 High-Level Consumer 替换成了 SimpleConsumer,这样我们就有了更多底层的控制,可以控制更多 Consumer 的行为,并可以更好发控制 Simple Consumer 的数量,达到更高的并行度,增加吞吐量。另外我们修改了 Commit Offset 的逻辑,可以保证在运行的过程中,只有当 Worker 在 Producer 里的所有数据都被发送到 Destination broker,并且收到了发送成功的返回以后再去 Commit Offset,从而保证数据不会被丢失。如果 Worker crash 了,它就可以从上一个 Commit Offset 进行复制,虽然会有数据重复,但可以避免数据丢失。
Performance Issues
在大概 2017 年初的时候,我们发现随着 Uber 数据量的增长,性能已经不能满足当时 Uber 的吞吐量。当时我们做了很多研究,提出了很多解决方案。在此会介绍其中的 4 个解决方案。
Solution 1: Increase Batch Size
首先我们在改进的过程中发现,在 Catch-up 的过程中分为两个阶段,一个是全速(Full-speed)阶段,另外一个是 Long tail 阶段。全速阶段的定义是在这个过程中,所有的 Worker 上都含有非常高的 Backlog,每个 Worker 都在全速 Catch-up 这些 Backlog。我们在这个阶段观察到的第一个现象,Destination broker 上的 CPU 利用率非常高,从 Kafka 的指标来看,它上面 RequestHandler 的利用率也非常高,这说明每个 broker 都收到了太多发送的请求,由于 CPU 的限制,没办法把每一个发送的请求更快地处理掉,接收更多发送的请求。
对此问题一个最直观的解决方案是,增大每一个发送请求的 Batch Size,从而减少请求的频率或者数目,我们相应地增加了 uReplicator Worker 里一些 Kafka Producer 的参数,比如 batch size 和 linger time,增加这些参数之后效果非常明显,每个 request batch size 增大了将近四到五倍,同时因为 batch size 变大,压缩比例也变得更好了。
Solution 2: 1-1 Partition Mapping
我们发现 Kafka Producer 默认会用 Round robin 的方式,将数据发送到 Destination 的每个 Partition,但这样带来一个问题,假设我们有一个 Topic,它有 N 个 Partition,通常会被分配到 N 个 Worker 上,每一个 Worker 都会往 Destination 的 N 个 Partition 上发送数据,所以一个 Topic 就相当于产生了 N 方个连接。可以想象一下,我们有数万个 Topic,当所有连接都发生的时候,相当于我们的复制平台对我们自己的 Kafka 的集群进行了一个 DDOS 攻击。
我们对于这个问题的解决方案是引入了一个 1-1 Partition Mapping,如果一个 Message 在 Source 是 Partition I,我们把它发送到 Destination 时,也会继续把它发送到 Partition I,这样我们所有连接的数量就和 Partition 的数量成正比,很大地减轻了 Destination Broker 上的压力。在采用了这些改进措施以后,我们每个 Destination Broker 的吞吐量提升了将近 1 倍,并且这个吞吐量是压缩比更高的吞吐量。
Solution 3: Dynamic Workload Balance
下面我们来看一下,对 Long Tail Phase 做了哪些改进。 Long Tail Phase 的定义是一些 Worker 已经 Catch-up 了 backlog,变得比较空闲,但另外一些 Worker 它还在全速进行 Catch-up。
一个非常直观的解决方案是,我们希望将那些还在忙碌的 Worker 上的 Workload 分配到那些已经空闲的 Worker 上,使它们都可以全速地工作。所以我们提出的第一个解决方案是动态 Workload balance,一开始 uReplicator、MirrorMaker 进行 Partition 分配的逻辑,是希望每个 Worker 都有相同数量的 Partition,以求平均。这么做本身并没有问题,但是当数据量特别大的情况下,一些 Workload 比较大的 Partition 可能就会被分配到同一个 Worker 上,导致那个 Worker 被 overload,就不能 Catch-up 所有的 Backlog。
我们的做法不是用 Partition 的数量来进行分配,而是用 Workload 来进行分配,在我们的内部有一个叫 Chaperone 的服务,它可以实时提供每一个 Topic 在 Source Kafka 集群里面的 bytes-in-rate,我们的 Controller 就会从这个服务去实时获取 Workload,根据 Workload 进行 partition 的分配,最终做到每个 Worker 上都有相同数量的 Workload。
Solution 4: Lag-Feedback Rebalance
我们发现在数据中心切换的场景下,很多时候一些 Workload 并不大的 Partition 也可能有比较大的 backlog,如果只按照前面说的 Workload 去做 Balance,就没有办法为它们分配到更多的资源,但其实在 Lag 非常大的情况下,即使这些 Topic 的 Load 不大,每个 Worker 也都需要分配出相当一部分带宽去进行复制。
所以我们引入了一个 Lag-Feedback Rebalance 机制,我们认为在 Lag 非常大的情况下,它相对应的 Workload 也变大了。所以我们在计算 Workload 的时候引入了一个系数,这个系数会随着 Lag 变大,从而将 Lag 和整体的 Workload 统一。
我们采用了动态 Workload Rebalance 后,每隔十分钟会做一次 Rebalance,每做一次 Rebalance 之后,每个 Worker 上 Partition 的数量都会有一些细微的调整,Workload 或者说 Lag 特别大的一些 Worker,它上面有很大的 Backlog,在 Rebalance 之后它的 Backlog 就被挪到了一些空闲的 Worker 上。从而使所有的 Worker 都可以全速地 Catch-up。
至此,我们已经满足了一开始提出的前四项要求,该去实现最后一项要求了。但很不幸的是,在 2017 年年终的时候,我们发现前两个要求又得不到满足了,这是由于多方面的原因。
第一,随着 Uber 数据量的增长,我们每一个 Kafka 集群的规模也在不断增大,每个集群里 Partition 的数量也在增长。在当时,我们 uReplicator 的部署方式是,一个 Source 到 Destination 的 Kafka 的集群由一个 uReplicator 部署来负责,对于最大的那个 Kafka 集群来说,那个 uReplicator 里面需要负责处理非常多的 Partition。所以 Helix 在这个时候就碰到了一个计算上的瓶颈,我们发现在做 rolling restart 的时候,可能需要将近一个小时才能做一次 full Balance,在这一个小时里,很多 Partition 就停止了复制,于是稳定复制的要求就不能得到满足了。
第二,在当时 Uber Kafka 集群的数量也在不断的增长,Kafka 部署的数量通常会跟 Kafka 集群的数量成倍数关系,一旦我们又想要有新的 Kafka 集群的时候,需要去建立更多 uReplicator 的部署。当我们有这么大的部署量时,就很难去维护它们了,很难控制每个部署里面运行的版本号。
第三,因为有那么多的 uReplicator 部署,我们很容易就会引入一些人为产生的错误,比如有一次,我们 whitelist 一个 Topic,不小心在两个 Kafka 集群之间相互 whitelist,就变成了一个死循环。那个 Topic 本身也就 10QPS,最后因为相互的复制,变成了 100KQPS。另外一个可能出现的人为错误是,从一个 Source 到 Destination 可能有不同的路径,可能有时候会错误地将它们在两个不同的路径上对同一个 Topic 进行了 whitelist,这样就会重复复制同一份数据。
基于以上这些问题,我们开发了第二代 uReplicator,我们叫它 Federated uReplicator,它是在第一代 uReplicator 的基础上,加入了一个 Federation 层。
在 Federation 模式下,第一个解决的是 Partition 数量过多的问题。我们的做法是将 Partition 数量非常大的每一个 uReplicator 部署拆分成几个更小的部署,叫做 route。我们在每个 route 里规定了 Partition 数目的上限,有了这个上限,使每个 route 里面的 Helix 计算 Partition 分配时变得非常快。
第二个需要解决的是部署数量过多的问题。在第一代 uReplicator 里,每个部署都需要自己或者用 Script 人为完成,我们为此引入了一个叫做 Deployment Group 的概念,它的思想是把相同类型的部署聚合到一个 Group 里。打个比方,可能我们原来有几十个都是用来做跟 Aggregation 相关的部署,现在我们把它聚合到一个 Aggregation Deployment Group,原来我们可能需要人为地去直接面对几十个 Deployment,现在,我们就只需要面对一个 Deployment Group。这样不管有多少 Kafka 集群,我们只需要面对有限个类型的 Deployment Group。
在每一个 Deployment Group 里,都会有一个叫 uReplicator Manager 的模块来进行每个 route 的创建和维护工作。Manager 的第一个工作是收到一个 Topic whitelist 请求的时候,会决定是把这个 Topic 加入到已有的 route 里面,还是重新建一个新的 route。它创建新 route 的条件是需要保证现有的每一个 route 里 Partition 的数目不会超过我们规定的上限。Manager 的第二个工作是,它也会从 chaperone 服务获取 route 里所有 Topic 的 Workload,然后计算整个 route 有多少 Workload,据此计算出这个 route 需要多少个 Worker 进行复制可以达到一定的吞吐率。它同时可以阶段性的去获取数据,动态进行 Worker 的调整,当 Workload 变少以后就可以自动释放这个 route 里的一些 Worker,可以更好地利用硬件资源,不造成浪费。
在 uReplicator Manager 之前有一个叫做 uReplicator Front 的模块,使用户可以直接做 whitelist/blacklist Topic。在这个模块里有一个功能,会将 whitelist 的信息都存在数据库里,当它收到一个 whitelist 的请求时候,会从数据库或者内存里将这个 Topic 相关的 whitelist 信息都读取出来,我们可以把每一个 whitelist 想象成一个有向图,在收到 whitelist 请求以后,它可以判断在这个有向图里新加入一条边后,会不会造成 Loop 和 Double route 的情况。当所有检查都通过后,它才会将这个 whitelist 请求发送到 Manage,去做实际 whitelist 的操作。
Data loss detection
在我们开发了 Federated uReplicator 之后,终于满足了一开始提出的前四项要求。现在介绍一下,我们是怎么做数据丢失检测的。我们做数据丢失检测的服务,就是刚才提到的 chaperone 服务。它不光可以提供 Workload 信息,还可以做数据丢失的检测。
它的具体做法是,在整个 Kafka pipeline 的每个 tier 上分别 Kafka message 数量的进行统计,汇总到 Cassandra,然后比较 Regional Kafka 和 Aggregate Kafka 中 Message 的数量,从而判断是否有数据的丢失。
最终,我们满足了一开始在开发这个复制平台时提出的所有要求,uReplicator 和 Chaperone 都在我们的生产环境里运行了两年以上,这两个都是我们的开源项目,在 Github 上可以找到它们的源代码。
本文为专栏文章,来自:AI前线,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/66110.html 。
数据分析
2019-08-29 10:25:00
一、 失败 大数据项目 的特征
根据在美国做了15年的 大数据 项目、产品研发和管理,以及其它一些相关的 数据分析 的工作经验,了解到的其它的做的比较成功的和失败的项目,跟大家做一个经验分享。基本上大数据项目失败的特征主要是五个:
1、大数据项目与企业战略脱节
完全是领导或者是不知道那个部门的决策人突然脑子一热,就说别人在用,我们也做一个,根本没有把该做的项目和企业的商业战略、科技战略等各个方面结合起来。在项目无法与战略协调,无法在战略的指导下做一款产品或者是服务项目的时候,失败的可能性会非常大。
2、大数据商业用例不是很明确
商业用例是说大数据项目怎么能够帮助各项业务达成所需要的功能和目标,或者叫目的,这个不是很清楚,怎么帮助我不是很清楚,这样的话,就直接影响到你选什么样的数据,怎么用这些数据,以至于用了以后怎么去支持你的业务,这一点是第二条,也是关键的。
3、无法发掘出大数据特殊价值
如果你没有发掘出特殊价值,其实用小数据也可以做到,这个项目本身就失去了意义。
4、企业内部对大数据项目无共识
财务部门、营销部门、研发部门之间的利益和工作重点是不一样的,没有共识就很难顺利推进一个项目,最后就很有可能是拖延或者是取消,甚至是失败,推出去了内部员工没人买单。
5、缺乏项目所需核心技术
大数据不是谁都能玩儿得起的,如果缺乏核心技术,达不到自己的预期目标,钱也是白花的。
二、成功大数据项目的标志
成功很多时候跟失败是反过来的:
1、项目用例(目标/实用价值)清晰
从上到下,大家都明白这个大数据要做什么,包括企业的财务主管和具体业务部门,比方说营销部门,这个大数据项目是用在营销部门的,他们也很清楚,负责执行的技术部门也很清楚,这个搞清楚了以后,对大家上下一心做好项目是非常重要的。
2、项目规划完善+快速迭代研发试错稳步推进
一个项目规划的时候,不要做成规划三个月、六个月,你用传统的老办法去做,最后发现实际上第一阶段结束了以后,你去做测试完全没有达到你想要的效果。我们做一个大项目要用快速迭代的方法来做,每个星期可以推出一个功能,进行快速测试,内部市场、外部市场都测试成功,下一个星期就可以进行下一个功能的研发、扩展、推广。这样的话,可以通过迅速的试错,比方说第二个星期做的方向不对,或者有些功能没有办法实现,或者跟我设计的不一样,这样的试错代价会比较低,不会等到6个月才发现有重大的错误,调整了以后第三个星期可以接着来,可以换一个方向,可以调整开发的内容,或者是功能,三个月以后,已经经过了四、五个星期的测试和研发了,基本上犯错的可能性就比较低了。
3、所选技术符合大数据项目功能要求
很多人都听说过要上一个大数据项目必须要用一些特殊的技术,大数据项目最重要的不是选高大上的平台,或者是特殊的技术,最重要的是选一款符合最初设计的业务功能的技术,这个技术可能相对来说比较简单,可能是SAS软件,或者是JAVA程序,没必要上高大上的技术,最重要的是符合你的要求。很多企业选了高大上,最后发现,实际上钱花了很多,但是没有达到预期的要求,因为你选了高大上的东西以后,会影响到各个方面的整合和所需要的数据量,预算会很大,成本也会比较高,很难实现盈利的目标。所以最重要的是选一款适合你这个项目目标的技术,这个非常重要。
4、项目团队拥有各方面专业知识技能
大数据技术 就像企业做的任何一款创新产品和项目一样,需要雇佣所有的对这个项目有贡献的,可能会受影响的资源,可能包括人力资源,包括技术资源,包括市场资源,包括运营资源等等各个方面的资源调动,形成这么一个团队,上面有领导的支持,中间有大家的共识,最下面的一线执行人员也很清楚自己要做什么,这方面要协调好,要有专门的技术,这个很重要。
5、项目成果获得业务用例期望成果
这个项目做了三个月、六个月,做出来了,是不是获得了业务用例期望的结果,是一个非常重要的标志。很多时候,很难是百分之百,一般80%的项目达不到完全预期的结果,可能是80%的预期达到了,那已经很好了,可能达到50%,也不错,因为是一个创新的项目,可以根据达到的预期项目进行不停地调整,最差的是只达到了20%,很多企业做的项目结果,这是一个统计的结果,是大家能看得见的。根据业界的标准,到了50%基本上算比较成功了,到了80%就是相当好了。
三、成功大数据项目的衡量标准
成功大数据的横向标准是五点:
1、项目在预定的时间里可以实现或者接近预定的目标;
2、这个项目或者产品实现了传统数据方法没有办法带来的特殊的内部和外部的商业价值;
3、在有限的大数据投资的条件下,给特定的业务带来的好处可以轻松复制到其它的业务领域,比如说营销部门获得的成功会推广到产品的研发部门,或者是推广到业务运营部门,这样会花很小的代价,但是做了更多的事儿。
4、受益的业务部门可以运用 大数据工具 进行高效便捷的工作,这其实是最直接了当的,因为本来我们要做一款大数据的产品,或者是服务项目就是为了提高运营效率和工作效率。
5、通过这个项目实施企业获得了新的商业模式和成长点,这个是最重要的,从战略的角度讲,这个大数据产品和项目成功实现了企业转型和升级。
四、成功大数据项目的路线图
成功大数据的路线图分为六步:
第一步: 确定对企业业务有重大影响的大数据用例和创新方向。
第二步: 我们要制定基于大数据项目的详尽的产品服务创新规划。
第三步: 要详细了解大数据项目所需要的业务功能要求和选择与之相匹配的技术。
第四步: 就大数据项目带来的商业利益在企业内部达成共识。
第五步: 我们要选择容易实现的目标入手,快速迭代研发、试错、稳步推进。也就是说不要刚开始就要搞高大上、大而全的项目,因为失败的几率几乎是百分之百,非常容易失败,因为预算太大,选的工具太复杂,调动的资源很多,很难一下子实现所有的目标,所以通常我们从一个晓得目标,容易实现的目标开始,这样可以鼓励士气,错误犯在研发的初期,而不是在中期和最后,这个最重要。
第六步: 做大数据项目和产品一定要挖掘和实现大数据能给我们带来的特殊价值,这是其它的方法或者是其它类的数据做不到的,只有实现了这种特殊的价值,我们才能实现业务所需要的具体功能,不管是扩展市场的份额,或者是更精准的了解你的客户需求,还是说你要增加边际利润率,或者是提高产品上市的速度,缩短研发周期,这些都是大数据可以做的。另外就是跨界创新,传统企业可以通过大数据这个纽带跟其他企业的业务结合起来。
五、成功大数据项目实战案例
其实有很多精彩的实战案例,我把美国福特公司去年以来做的一个大数据项目跟大家分享一下。我在福特有一个非常熟悉的朋友,我也介入了一点点,我来讲一下,他们基本上是按照我总结的几步来做的。
福特第一步是确定了大数据用例 ,销售部门很想知道我怎么用大数据这个技术来提升汽车销售业绩,这是一个非常简单的业务用例。我们需要界定的是,一切影响销售业务的大数据,一般汽车销售商的普通做法是投放广告,看看影响力怎么样,动辄就是几百万,但是具体很难分清楚到底每一个受众看了这个广告以后会不会产生购买这个汽车的冲动,这个很难看到。大数据技术不太一样,它可以通过对某个地区的房屋市场、新建住宅、库存和销售数据、这个地区的就业率等各种相关的,可能会影响购买汽车意愿的原数据进行分析和收集,还可能会到跟汽车所有相关的网站上搜索,哪一种汽车,哪一种模式,哪一种款式,客户搜索了哪些汽车的价格,车型配置、汽车功能、汽车颜色等等这些客户喜好的数据。
福特汽车用这些方法把所有的数据都界定好了以后, 第二步 是把项目交给了一个差不多200人的大数据分析专业团队,他们获取和搜索所需的外部数据,比方说第三方合同网站,区域经济数据、就业数据等等。
第三步 是他们获得数据以后,就开始对数据进行建模分析、挖掘,为销售和决策部门提供精准可靠的角色选择和效果分析,也就是说,你选这个方法,可能获得的营销效果是怎么样的,他们做了大概几十种可能的分析。
第四步 是营销部门和运营部门根据这些数据策划和实施有针对性的促销计划,比方说在某些区,某些州需求量特别旺盛的地方,他们有专门的促销计划,基本上这些促销计划都是根据某一个个体的需求量身订做的,非常非常精准,所以不需要花五、六百万美金,花出去了以后不知道谁感兴趣,只需要花五、六十万美金,就知道谁对这个汽车感兴趣,这个广告就送到电子邮箱和地区的报纸上了,非常精准。
最后一步 是大数据营销的创新效果衡量,跟传统的广告促销相比,福特花了很少的钱,做了大数据分析产品,我们叫大数据的模型和分析工具,运用这种方法,大幅度的提高了汽车的销售业绩。他们不光在汽车的销售方面运用了大数据,比较成功,还有其它方面的应用,包括汽车的整车质量、保险费用、汽车运输状况、汽车的智能和驾驶模式等等,他们希望用这些数据帮助驾驶员降低保险成本,这样的话可以促进很多销售者对福特这个品牌的认可,扩大市场占有率。
本文由 明悦数据 投稿至 数据分析网 并经编辑发表,内容观点不代表本站立场,如转载请联系原作者,本文链接:https://www.afenxi.com/73394.html 。
数据分析
2019-08-28 08:57:00
作者: 陈肖雅(数据产品经理)
1、主成分降维思想
多元统计 分析处理的是多变量(多指标)问题。由于变量较多,增加了分析问题的复杂性。
但在实际问题中,变量之间可能存在一定的相关性,因此,多变量中可能存在信息的重叠。
人们自然希望通过克服相关性、重叠性,用较少的变量来代替原来较多的变量,而这种代替可以反映原来多个变量的大部分信息.
这实际上是一种 “降维” 的思想。
2、 主成分分析 的几何意义
就像物理中力的分解,将原本相交的两个力分解到垂直的坐标系中,主成分分析是将原本相关的各维变量数值映射到正交的主成分坐标体系中,主成分分析的实质是坐标系的转化。
假设我们要研究的样本对象(n个样本)有X1、X2两个属性变量,如下图所示,X1在各个样本上的观测值向量为(x11, x12,……,x1n), X2在各个样本上的观测值向量为(x21, x22,……,x2n)。假设X1、X2高度相关,存在信息重叠,需要将X1、X2的数值分解到两个正交的向量Z1、Z2中。设θ1、θ2分别是X1、X2在Z1方向的夹角。
Z1、Z2便是从该原始变量向量空间中抽取出来的主成分, 其中样本在Z1方向的方差很大,说明Z1包含了样本的大部分信息量。其中样本在Z2方向的方差很小,只包含样本小部分的信息量。我们称Z1为第一主成分,Z2为第二主成分。如果不介意原始变量信息的略微损失,我们可以只拿第一主成分Z1作为分析的标准,直接舍弃Z2 维度的数据。这样整个模型就变得简单,实际上就起到了降维的作用。
3、主成分提取
通过以上的分析,我们知道主成分的实质是从存在相关的多维度原始变量向量空间中抽取出几个彼此正交的主成分来代表原始数据,从而简化分析模型,这些主成分包含了原始变量大部分的信息。
而这些主成分跟原始变量又存在怎样的关系呢,我们将几何意义中二维空间的分析扩展到多维空间,各个主成分可以表示为原始变量的线性组合。
假定有n个样本,每个样本共有p个变量,构成一个n×p阶的矩阵
主成分与原始变量之间有着如下的线性变换。
这里(Z1,Z2,…,ZP)为主成分变量指标。原变量X到主成分Z的线性组合系数矩阵为A=(ai1,ai2,…,aip),也称为主成分的得分系数矩阵。
通过线性变化,就将原始变量上的样本数据转化到(Z1,Z2,…,ZP)的坐标体系中。
设主成分(Z1,…,Zp)的方差为(λ1,…,λp )。所有主成分的总方差和等于原始变量的总方差和。各个主成分对应的方差越大,表示该主成包含的信息越多,越重要,我们将主成分对应的方差在总方差中的占比成为该主城分的贡献率。
为主成分Zk的贡献率。如果a1使得Z1的贡献率在所有主成分中最大,就称Z1为第一主成分。同理可得第二、三、四…主成分。当提取的前面几个主成分总贡献率达到预定要求,就可以只保留这几个主成分舍弃其它。主成分分析试图在力保数据信息丢失最少的原则下尽可能选择最少的维度。
我们希望找到一组新的变量(Z1,…,Zm)(m≤p) ,这组新的变量充分地反映原变量(X1,…,Xp)的信息,而且相互独立。
先找第一主成分Z1。Z1=a′1X,需要确定a1使得Z1的方差达到最大,一般a1满足以下条件时var(Z1)最大。
如果Z1的贡献率,及var(Z1)在总方差中的占比达到预定要求,只需要提取Z1作为主成分就已经足够。
若不满足代表原变量所包含的信息,再考
虑选取Z2 ,使 满足
称Z2为第二主成分。
类似地,可求第三主成分,第四主成分等等。
4、主成分的性质
(1) 主成分间互不相关
(2) 组合系数ai*a,i=1,主成分提取的方案有多种,满足这个条件,能保证每次提取的主成分方差值最大
(3) 总方差不变
(4) (X1,…,Xp)的相关矩阵为R, (ai1,ai2,…,aip)则是相关矩阵R的第i个特征向量(该特征向量为归一化标准向量)。而且,特征值li就是第i主成分的方差,即 Var(Zi)= λi
5、主成分分析计算步骤
1、 计算相关系数矩阵
rij为原变量xi与xj的相关系数
2、 计算特征值和特征向量
对R求特征值(λ1,…,λp ),并求出特征值分别对应的单位特征(a1,,…ap,)向量,这些特征向量组成的矩阵即为X到Z的相关系数矩阵
3、 各主成分得分
最终的主成分Z可通过原变量X跟相关系数A的线性组合求出。
本文由 陈肖雅 投稿至 数据分析网 并经编辑发表,内容观点不代表本站立场,如转载请联系原作者,本文链接:https://www.afenxi.com/73378.html 。
数据分析
2019-08-27 16:32:00
什么是BI
商业智能 (Business Intelligence,简称:BI),又称商业智慧或 商务智能 ,指用现代数据仓库技术、线上分析处理技术、 数据挖掘 和数据展现技术进行 数据分析 以实现商业价值。
然而,现在大部分人可能对BI有所误解,很多人可能认为BI软件仅仅是一个花架子。在软件的功能使用过程当中,人们总是认为BI软件仅仅是做一个报表,或者说做一个图形可视化的大屏,并不能减少业务人员的工作。
诚然,最基础的BI软件在功能上与一个报表,软件极为相似。但是我理解的BI软件远非如此,而且BI软件应该是在原来的业务系统之上的。
BI的地位
在实际的BI应用过程中,很多企业对数据分析的概念仅为雏形,且业务人员往往难以了解自身数据分析的需求。这就造成很多BI需求调研在和业务人员沟通的环节,业务人员难以明确需求,这使得BI沦为一个报表软件,或者以业务软件的形式来进行实施。
BI软件不是一个业务系统,BI软件应当以一个工具的形式存在。就像Excel,Excel并没有任何业务功能,但是大家可以利用Excel完成业务任务、可以分析数据、可以传递数据。同样,BI软件也应当是这样的地位,而不是沦为一个业务软件。
BI的优势
BI软件的强大,在于其可以快速的拉取数据,并且可以以任何的字段作为维度进行筛选整合数据。BI软件在数据处理的灵活性,是仅次于Excel的,但其又可以处理比Excel更 大数据 量的数据。换句话说,如果一个企业的数量很小,是不建议上BI软件的。用Excel进行数据处理是很好的选择。当然,想要炫酷的可视化除外。
BI与 数据可视化
说到BI软件,大家会想到很炫酷的大屏。如果说哪一款BI软件没法进行数据大屏可视化设计,那是一款功能很少的BI软件。BI软件可以让业务人员快速的展示数据,将原来的数据用图形的形式展现出来。
最开始做数据可视化的是Tableau,其从二战时期便开始了数据可视化的探索,可以说是数据可视化的鼻祖,近年来国内也有各个厂商推出BI软件。此处对于国内数据可视化应用来说,需要说道说道。业务人员有时候会反馈说,数据可视化后,还不如看表来的快。数据可视化在其伊始,就有这样那样的津津乐道的故事,如:南宁格尔玫瑰图的来源(此处不予赘述)。那么为什么我们在实际业务过程中却用起来那么笨拙呢? 图形维度和图形选择处理不当及模型的缺失
图形的选择是在可视化过程中很重要的环节,然而很多实际实施过程中都将其忽略,这就造成图形选择较为随意,看到的维度不够等问题,幸好BI有下钻、联动的功能可以使用,但是却不如表格一目十行来的实在。 中国人很会心算
个人认为这是中国更喜欢表格的重要原因。在BI行业,有一种表格叫做“复杂中国式报表”,可见中国人很喜欢把多个维度叠加在一起,形成一张很大的报表,而对于表格的汇总,完全可以进行心算。业务人员对数据关注,做到“心中有数”,看一眼数据,便知道业务做的好坏,不需要更多的图形展现。对于业务来说,数据可视化更多的是一种炫科技的存在,没有实际用处。
但是,对于长期趋势的对比、查看,甚至更加深入的分析(如:帕累托分析),则不是各个表格一眼看穿的。这就需要BI的帮助了。
总之,BI有其独有的价值,是其他系统的数据分析模块无法替代的。不能因为业务系统中集成了某一个数据分析模型,而否定BI的价值,更不能将BI系统作为一个业务系统来看待。希望企业可以运用好自己的数据,让数据为企业带来价值!
本文由 张文迪 投稿至 数据分析网 并经编辑发表,内容观点不代表本站立场,如转载请联系原作者,本文链接:https://www.afenxi.com/73284.html 。
数据分析
2019-08-27 13:56:00
上周某国内知名生产型企业管理层与我们的首席分析顾问赵兴峰就企业如何进行经营 数据分析 进行了深度的探讨,期间该企业老总道出了现在大多数企业对 数据分析 的强烈需求,以及由于没有数据分析而带来的苦恼。
该企业老总感悟摘选如下:
向我们这样的生产型企业通常用效率表、品质表、客户反馈表这三大表, 来提高员工的生产率或准确率 ,表中员工是不变的,变化的是员工工作的方式,这种改变的作用是非常大的。一般从表面上看人力资源上的成本很高,但其实人力资源上的成本是最低的,如果企业能够运营好的话,由于员工的改变,企业得到的变化会最大。
企业老总想要看见问题,并找到问题,就不能凭感觉,感觉是没有逻辑支持的,是有偏差的, 会造成错误的决策 ,即便认识到了问题也看不到问题的本质。企业老总要想改变,首先要找到核心问题的源点,这些源点肯定是来自于基础的一些东西,如果做数据支撑的人员都凭感觉而来,感觉是不可能给企业造出一个金山来的。
例如企业没有数据敏感度,没有相关的数据以及对数据的分析,即使在与客户的交易中一直损失很多钱,却因为没有精准的数据,没有与客户做这些沟通,使客户一直占了很大便宜,客户已经习惯了这些利益都是属于自己的,企业再想改变的话,是非常苦恼的。
在企业管理中,为了解员工的效率,把员工按在企业的工龄分一下,如十年以上的、六到十年的、一年的。有时会看到在一个表中第一名的和倒数第二名的工龄是相同的,但工作效率却相差两倍多,员工的工龄和效益不成正比,也可能在前期某一个程度是成正比的,但到一定程度就形成一个很大的曲线。如都是六到十年工龄的员工,第一名是6.2工龄的员工,最后一名是8.2工龄的,第一名的效率是最后的一名的三倍,尽管两者的产出相差三倍,企业对他们是投入一样的保险和资源。像这样的情况,如果之前没有数据支持和分析,企业 还会有工龄补贴,企业的成本会越来越高。因此必须通过一定时间来评估和教育效率低的员工,再不行就要淘汰掉。企业如果没有这些数据,都是凭感觉的,就无法真正发现效率高的员工有什么不一样,效率差的又有什么不一样,规律是什么。有了数据支撑,企业可以通过分析,聚焦在某个点上,了解员工的心态、技能、学习情况,管理者做了哪些工作,员工做了哪些工作。同时也可以指导企业组织结构的调整,如果员工本身有问题,要想想组织结构是不是也有问题。例如一个班长管三个人,班长事很多经常不在现场,根本没有时间细管到每一个人的工作,有的在现场也不会管理,只是一个服务员的角色而非指挥官的感觉,这就需要对组织结构进行分析,考察这个班长能不能带队伍,如何通过层级、薪资调整挖掘管理层以下每一位员工的价值,使产出提升。
企业的数据源头有很多,老总的重视是最关键的。有些老总认为数据不够,像财务数据或其它分析不够,这样的问题好解决,企业可以找懂财务的人来做,没有合适的人企业可以增加合适的人,因为牵扯的面不是很大,牵扯的人不多,这些方面都容易完善。但是牵扯面很大的源头数据,牵扯到了很多员工,企业老总却大多不去重视,即使重视了,也缺少下面各个部门的支持。企业愿意推行源头变革,首先是老总认识到了这些问题的重要性,老总亲自推行变革,打通下面的管理层,从管理层打通到班长层,再到员工执行层,以确保第一个源头(执行员工)的数据正确,否则,这所有的数据都是错的。
所以最核心的是企业老总对于企业数据分析的信心、决心和方法。
本文由 明悦数据 投稿至 数据分析网 并经编辑发表,内容观点不代表本站立场,如转载请联系原作者,本文链接:https://www.afenxi.com/73259.html 。
数据分析
2019-08-26 16:27:00
最近阿里巴巴分享了《阿里巴巴 数据中台 实践》这个PPT(自行搜索原始文章),对于数据中台的始作俑者,还是要怀着巨大的敬意去学习的,因此仔细的研读了,希望能发现一些不一样的东西。
读这些专业的PPT,实际是非常耗时的,你需要把这些PPT外表的光鲜扒光,死抠上面的每一个字去理解底下隐藏的含义,然后跟你的已有知识体系去对比,看看是否有助于完善自己的认知,对于自己不理解的,还需要经常去检索相关的文档。
当然,很多写PPT的用词没这么严谨,临时造概念的不少,或者是独特的说法,因此有时候还要做一些揣测,结合自己的实践去理解,这篇PPT的解读有6000多字,因此请做好烧脑的准备,虽然笔者没去现场听演讲,但希望我的“演讲”也能让你学到真功夫。
就让我们开始吧。
1、题目和背景
看到这个片子的出处,阿里云智能事业部,其实是有点奇怪的,记得阿里的中台事业群包括搜索事业部、共享业务平台、数据技术及产品部,阿里云是一个侧重云业务的平台事业部,它来说数据中台合适吗?
有人会问,平台和中台又有什么区别呢?阿里云来讲中台不是很合适吗?
笔者的疑惑是这样:一般意义上的平台具备业务无关性,潜心技术就可以了,而中台是业务的收敛,跟业务的相关性很大,对于数据中台,其核心竞争力不是平台级的技术,而是数据的理解、处理和挖掘。让一个做平台技术的人跑到前端去理解数据诉求沉淀共性是不现实的,而这是当前数据中台创造价值的核心。
当然讲PPT的可以不问出身,能理解阿里的数据中台就可以了。
2、DT派向左,IT派向右
传统的IT是成本中心,而有了数据后,就可能成为价值中心,这个价值体现在:在管理上可以提供决策支持,在生产上可以提供与管理匹配的智能工具,也就是提升生产关系和生产力的适配能力。
这一点提得是不错的,比如浙江移动 大数据中心 就是直接定位为利润中心。
这里的IT和DT的对比就不太合适了,两者不是对立的关系,而是融合的关系,D通过IT形成DT,比如原来IT渠道系统仅受理业务,现在在受理的场景下可以加载基于数据的智能推荐。
DT只是马云提得一个突出数据价值的抽象概念,不能生硬去的理解,现在中国移动提了一个三融概念:融合,融通,融智,我觉得IT和DT就要加强融合融通,融合就是搭在一起卖,融通就是能力共享,IT中有DT能力,DT中也要有IT能力。
片子中提到的DT是问题导向,IT是需求导向,这是一个问题的两面,而不是DT和IT的区别;新抛出的DT的授之以渔,IT的授之以网的区别在于方法的观点倒是有点道理,比如DT的智能推荐就是提供了方法,而以前IT的推荐靠的是人的判断。
3、企业组织对于DT的希望
高管团队 :看指标发现风险这是BI时代的基本诉求,没啥好说的; 大数据 更强大的处理、可视化、实时等技术可以提供更好的看数据体验,这是相对于以前BI提升的地方。
业务团队 :提到三个变化:
一是通过数据发现问题,而不是拍脑袋。
二是业务人员要既懂业务也懂数据,甚至能自己DIY数据和模型。
三是数据要嵌入生产流程中直接发挥作用,比如标签库要成为营销目标用户的发起地,风控模型要嵌入在用户操作流程中等等。
第一点大家都在做,实际还是以经验为主,数据只是参考和佐证,这种模式本质上没有改变。第二点,第三点执行到位对于大多数企业都很难。
技术团队 :提到三个要点:
一是“数据多跑路”是智能平台的核心,浙江的“最多跑一次”就是要靠数据和平台整合实现这个目标。
二是IT人员要有数据化的思维,这个提的很好,缺乏数据思维的人设计IT系统很少考虑智能,现在很多企业的受理系统跟推荐系统是两者皮多少有这个原因。
三是通过 数据分析 发现新的知识,从而赋能业务,这是数据技术团队的使命。
4、大中台、小前台
这张图诠释了阿里的商业操作系统的引擎: 大中台,小前台 ,展示的很清晰了,特别提醒要理解两个重要概念: 业务数据化 和 数据业务化 。
业务数据化 :就是所有的商业活动都应该记录下相关的数据,这是业务中台应该承担的使命。
业务数据化挑战其实很大,以前业务平台在设计的时候,是以功能和流程为核心的,只记录对于要实现功能和流程必需的数据,其他的就可有可无了。
比如运营商的一些信令日志记录不全面导致可能影响后续的网络分析或数据价值变现,这就没有做到业务数据化。
但业务数据化有时意味着巨大的成本投入,说来容易执行难,大多企业的数据不是业务数据化战略执行的结果,而仅仅是顺便摘取的低垂的果实。
数据团队的一个使命就是业务数据化,很多好的数据是你进入前端争取来的,这样才能驱动业务记录数据。
数据业务化 :本质就是从数据中发现价值,反过来赋能业务,这是很好理解的。
数字孪生这个词现在也比较热了,未来万物互联的世界将你所有的行为实时记录下来,形成另一个数字化的你,这就是数字孪生,如果业务中台是你,那数据中台就是你的兄弟。
5、数据中台赋能的四大典型场景
(1) 全局 数据监控 :本质就是指标+报表+可视化,这是给管理者看得,当然业务人员也要看,以下给了双11大屏示例。
(2) 数据化运营 -智能CRM :提到要“基于全链路全渠道数据的建立以“人”为核心的数据连接萃取管理体系,对用户进行全生命周期的精细化管理”,这么多形容词懵不懵逼,到底在说啥?
全链路是指纵向记录跟踪整个商业过程的数据(包括商品企划、售前及售中管理、客服管理、订单处理、仓储物流等等)。
全渠道就是各触点的用户行为数据,比如天猫、淘宝、优酷等等。
因此,通过汇聚全链路全渠道的数据才能形成完整的客户画像,然后用连接萃取的方式方便的获得所需的数据进行分析,从字面意思看跟我们的标签库定位有点像。
(3) 数据植入业务-智能推荐 :这里讲的比较清楚,就是营销闭环管理,从用户细分,千人千面,渠道推荐,再到营销评估,以下是示例。
(4) 数据业务化- 生意参谋 :这个是阿里力推的为数不多的血统纯正的数据产品,是数据业务化和数据直接变现的典型代表,可以为店主提供端到端的分析支撑,网上介绍很多了,下面这张片子着重说明了生意参谋的历史,现在和未来,有点意思。
历史 :百家争鸣,虽然提了数据冗余、体验差等问题,但没有百家争鸣,不可能有生意参谋这个整合产品的出现。
现在 :生意参谋独霸天下,依托的是数据中台体系,包括OneData、OneService、OnePlatForm等,这个后面会解读。
未来 :一个生意参谋还不够,要打造一个产品开发平台,复制出一个个面向不同行业的生意参谋,也就是参谋X,野心很大。
为什么说血统纯正呢?
因为诸如推荐啥的,数据是依附于业务流程上的,你评估数据价值的时候,很难说是业务本身好、流程设计好、还是你数据推荐的好,而纯正的数据产品是数据人员彰显自身价值的更好方式。
6、阿里巴巴做数据中台的缘起
做数据中台的缘起跟一般数据仓库融合模型是一样的,共享复用的需要,比如原来基于淘宝数据的各种业务都自建一套中间层,而这些中间层很多是重复或类似的,比如蚂蚁业务有交易主题,天猫也有交易主题,那能不能抽象出公共的交易主题为两个业务都服务呢?
因此你会看到阿里数据中台抽象出了会员、商品、交易、浏览、广告等公共核心主题层,从而为应用层服务,各个应用层以前要做很多公共层的东西,现在也可以完全复用了,理论上可以提升应用构建的速度。
下面这页片子从数据的依赖关系图比对了前后的变化,一个是网状的,代表了相互之间千丝万缕的关系,冗余肯定是很多的,一个是放射状的,一个节点可以为更多的后端节点服务,代表了共享和简洁。
7、阿里巴巴数据中台全景图
读懂这张图就理解了阿里的数据中台具体到底干了些什么,有五大部分跟数据中台直接相关: 数据中台DaaS 、 数据资产管理 IPaaS 、 数据研发平台IPaaS 及 计算与存储平台IaaS 。
笔者理解 广义的数据中台 其实包括 数据中台DaaS、数据资产管理IPaaS、数据研发平台IPaaS 三部分,如果狭义的理解则仅包括 数据中台DaaS ,数据资产管理IPaaS、数据研发平台IPaaS在笔者的企业叫做能效中台。
(1) 计算与存储平台IaaS
流计算SteamCompute :应该指阿里内部的Flink版本。
离线计算MaxCompute :阿里自研的EB级的数据仓库(原来的ODPS)。
实时计算ADS :AnalyticDB的简称,主要是提供实时在线分析,可以认为是阿里自研的OLAP版本。 
(2) 数据资产管理IPaaS
数据资产管理其实跟元数据管理一回事。
资产地图 :本质上是数据字典的图形化版本,阿里有多少数据、如何存储、数据之间关系如何、如何找、如何用都可以从资产地图找到答案,蛮形象的,从网上资料看,其设计还是值得借鉴,以下是一些界面截图。
资产分析 :你可以理解为针对元数据的BI分析,什么结构分析,趋势分析什么的,万变不离其宗,你希望通过元数据分析理解现状,发现异常,从而指导数据资产的治理,比如支付类别的数据增长情况如何。
资产应用 :你可以理解为利用元数据信息来提升数据资产的利用效率,比如通过影响分析挖掘出无效的数据资产,从而降低数据冗余,这个工作做好,价值是很大的。
资产运营 :运营这个词被用烂了,运营其实不是一个功能,而是一个动作,希望通过各种举措来让数据被更多的人使用,从而产生更多的价值,比如新增数据资产的推荐等等。
数据资产使用的二八定律是非常明显的,大多数据其实是没人访问或使用的,而存储的成本可是很高的,只有通过运营才能让沉默的数据被更多的人使用,无效的数据得到清除,从而实现降本增效。
(3) 数据研发平台IPaaS
这个平台跟笔者以前文章中提到的DACP是一个东西,就是负责数据的加工,需要一系列配套功能,包括数据规划、交换、处理、开发、调度及监控等等。
(4) 数据中台DaaS
垂直数据中心 (OneClick):就是传统数据架构中的ETL,通过离线、实时等方式将各渠道的数据采集过来。
公共数据中心 (OneData):就是数据仓库建模需要达到的目的,保证数据口径的规范和统一,沉淀共性的数据,阿里采用的是维度建模,通过分析业务过程抽象出维度和指标,最后汇总成所需要的仓库模型。
萃取数据中心 (OneID):笔者的理解是阿里为了方便对外提供数据,形成了一套以各种ID(业务核心对象)为唯一标识的宽表,就好比运营商需要形成一套以用户ID(手机号码)、客户ID、账户ID、家庭ID为核心的宽表体系一样。
统一 数据服务 中间件 (OneService):以数据仓库整合计算好的数据作为数据源,对外通过接口的方式提供数据服务。
8、阿里巴巴数据中台的沉淀与积累
(1)OneData
数据标准化 :实现数据资产各域、主题、模型、字段、指标命名等的统一规范,笔者一直强调数据标准化一定要在源头解决,如果阿里的业务系统数据资产都遵循这个原则,那是厉害的很。
技术内核工具化 :我的理解是规范的落地必须依托工具来强制控制,比如你只能按照规范模板的要求来建表,否则就执行不了,阿里在这方面的管控据说是比较给力的。
元数据驱动智能化 :有了元数据分析就能科学的计算出对于资源的诉求,而且可以做得非常快速和灵活,摈弃每次规划扩容到处找依据的窘境,这跟前面的元数据应用是类似的。
OneData 是阿里数据中台非常核心的内容,其有一个 Dataphin引擎 ,可以实现 数据标准规范定义、数据模型的自动化开发、主题式数据服务即时生成 等功能。
具体如下面这个片子所示,其包括数据引入-规范定义-数据建模-数据外部关联-数据资产沉淀-数据服务生成整个闭环链条,通过这一链条把数据管理的大多要素都实现了。
这种强规范性的开发模式在一定程度上也降低了灵活性,但其规模效益是非常好的,否则阿里这么庞大的数据资产是根本无法很好管理的,这个笔者深有体会,正如我们运营的DACP一样,我们遭遇到的,他们也一定遭遇到了。 指标标准化 是笔者尝试过的事情,因为当初深感重复开发的报表太多了,而通过指标标准化可以解决这类问题,这是报表做到一定程度后自然而然产生的想法,以下阿里的做法跟自己当初做的如出一辙,所谓殊途同归。
(2) OneID
假设有一位用户张三,在第一个手机上使用百度地图, 在ipad上观看百度爱奇艺视频,在第二个手机上使用手机百度app, 在pc电脑上使用百度搜索,如何将同一个用户在这些不同端的用户信息聚合起来呢? 
跟运营商的天然的以手机号码为唯一标识不同,互联网公司的各类账号ID要打通的挑战是非常高的,ID-MAPPING是互联网公司的一个核心技术,其需要确保各个领域搜集的数据是可以集成和关联分析的,没有统一ID的支持,多样化的数据集中起来分析是没有意义的,这是另一种形式的数据孤岛。
比如下面的四条用户记录实际上表明的是同一个人。
(3) OneMeta
这里的“数据资产分析”和“数据血缘跟踪”在前面的“数据资产管理IPaaS”都已经提及,是数据管理里非常基本的东西,特别提下 数据综合治理 。
安全 :指的是诸如敏感数据分级和访问控制定义。
质量 :指的是数据的质量规则定义。
成本 :指基于数据资产的调用情况和处理成本给出一个综合评估。
人员 :大概是数据资产指归属组织和个人的定义吧,比如我们的数据字典里就有一个属性,必须标识出这个资产的创建人、修改人以便跟踪追责。
(4)OneService
主题式数据服务 :应该是基于元数据构建的简单数据服务查询引擎,面向业务统一数据出口与数据查询逻辑,屏蔽多数据源与多物理表,就是搞一套业务化的伪SQL方便取数。
统一而多样化的服务 :一般查询指普通SQL查询,OLAP就是多维分析,在线服务比较抽象,笔者猜测是诸如数据推送、定时任务等定制化服务形式。
跨源数据服务 :大数据由于技术组件非常多,不同的数据往往存储在不同的数据库内,比如hadoop,gbase,oracle等等,如果要进行跨异构数据库的即席查询一般就要做先做数据汇聚,但一些轻量级的取数希望能直接进行关联分析得到结果,因此出现了这种服务诉求。
PPT就解读到这里,笔者最大的感受就是阿里的数据中台技术体系很庞大,但又非常关注细节,几个字看着简单,但落地则需要付出巨大的代价,而且是个渐进的过程,比如Dataphin。如要要了解阿里数据中台的更多技术细节,推荐一本书《阿里巴巴大数据实践》。
其实数据中台要搞好不是简单的引进几个工具就可以了,技术仅仅是技术,你能COPY技术但COPY不了管理和文化,而这恰恰是数据中台成功的关键。
数据中台的更大挑战是: 你的企业对于数据的理解是否已经达到了一定的阶段,你是否能够驱动公司去建立一套适合自己企业的数据管理机制和流程,而这个是最难的,你得走出自己的路 。
本文为专栏文章,来自:傅一平,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/73236.html 。
数据分析
2019-08-26 10:12:00
本文整理自百度李俊卿在QCon上的演讲:《 流式数据 处理在百度数据工厂的应用与实践》。
作者:李俊卿,百度高级研发工程师,数据工厂流式数据处理负责人。
百度数据工厂最原先用Hive引擎,进行离线批量 数据分析 和PB级别的查询,处理一些核心报表数据。但是在我们推广过程中发现,用户其实还是有复杂分析、实时处理、 数据挖掘 的请求,我们在Spark1.0推出的时候,就开始跟进Spark。在Spark1.6时候彻底在团队中推广起来,当时是SparkStreaming。当时Spark1.6的API基于RDD,它和Spark批式处理的API并不同步。后来在Spark2.2、2.3发布的时候,Spark推出了StructStreaming,它的API和批处理API已经完全一致,这时候我们迎来一次完整的架构升级,基于Spark做了一次更强大的封装;以Spark为基础,加上其他的CRM,PFS等各种模块来做统一元数据处理;统一的资源调度;以Spark为基础做了统一的一个计算引擎,以前Hive的一套也有完全融入到Spark里来;包括多种提交方式;安全管理等等。最后形成一套完整的成品。
这就是我们目前的一个整体的技术架构。左下角是统一元数据处理,包括文件类的元数据处理和结构类数据,比如说Hive,或者MySQL的元数据处理,这都是作为统一的处理层的。还有就是统一调度引擎处理,我们会有统一的调度引擎,由用户注册队列,执行的时候只需要显示队列,去执行具体的资源。目前也支持K8S等。再往上一层是统一的Spark引擎。Spark引擎里面我们现在目前支持了SQL、DatasetAPI,可在上面跑各种复杂的处理。
再往上一层就是由Jupyter提供的工作空间,还有由我们自研提供的调度,自研的一套流式计算作业处理,整个一套就构成了现在完整的数据工厂。
流式数据处理在百度数据工厂的应用
接下来是比较最核心的部分,百度在Spark流批处理上做的哪些内容,主要是Spark流式SQL问题、实时转离线问题、实时转大屏展示问题。
首先Spark本身有一套完整的API的,有专门的引擎用来分析,所有的流、Batch分析,信息都会经过这套API进行一系列的处理,包括语义分析、语法分析、一些优化等。大家可以注意到,右下角是空缺的,Spark目前是没有提供这部分内容的。而用户转型过程中很多用户都是由Hive过来的,是熟悉应用SQL的用户,他们要处理流式数据,就会迫切的需要有一个SQL的引擎,来帮他将Hive的SQL转型成一个流式的SQL。
我们针对这个问题进行了一些开发。首先大家看一下,上面是SparkAPI层,Spark在流批处理上的API已经做得很完善了,是通过read和readStream来进行区分的。批到SQL处理,其实就是,可以完全看到它是首先是Sparkread一个Source,而它会映射成一个FromTable,具体的处理会映射成select、join、union等各种操作。然后WriteTable这种,在最后映射成了kafka_Table。我们流式SQL也可以映射这种类型的。
比如说这个例子,它从Kafka读取,输出到HDFS,映射的流式SQL的就是Kafka_Table。我们可以专门定义一个KafkaTable。用户的处理,我们会变成 。。大家注意,我中间加了一个stream关键字。Spark在处理的时候,做了统一引擎的处理。只有API层用户写readStream的时候,它才是一个流式的处理,如果它用户写一个Read,它就是一个批处理。相对来说,SQL层我们也做了相应的处理,跑的同样的SQL,用户如果没加Stream关键字,它就是批处理的一个SQL,如果加Stream关键字,它就变成一个流式处理。但里面处理的引擎是完全一致的,只不过最后转换Plan的时候,将最后原Plan的部分转换成了流的plan。
这里也涉及了Table是怎么存储的。Table存储,如图所示,一个批量的Table存储的时候,无非就是Tablename、Schema、Properties,还有一些定义,比如说location等一些配置的信息。同样可以把我们创建的KafkaTable也可以映射进去,比如说我创建的Table名称可以映射TableName等,和Meta这边进行一一对应,这样我们在Hive那一侧,已经有了完善的一套Table的存储信息。它会生成一个虚拟的路径,其实并不会真正去创建,并不会真正去对它执行的。在数据工厂中,我们是这样定义一个Table的。一个Table定义出来以后为要能被多个人使用,但临时Table除外,你能够授权给其他人去读,也能够去进行列裁减,能够对它进行一些如数脱敏的数据分析,这时候就需要考虑Table的通用性。
首先第一点,我们创建的Table不能存放多个数据源。比如说存放三个数据源,这时完全可以定义三个Table,不同的数据源做Join,做Unit分析等,这在Spark里面都是OK的。
第二点只能定义通用配置。给别人使用,授权,计算的时候,肯定会需要考虑他自己的应用场景,这里面不能去搀杂何与应用场景相关信息,比如说watermark配置,这就是属于与应用场景相关的信息,这部分信息都是不能存放于Table里面的。
另外就是Spark原生是支持Kafka,流式的Table。它要既能够去流式的去读,也能够批量的去读,既然定义了Table我们怎么去读呢?这就是我们在Spark里面的改进,主要改动的部分就是改动了语义分析层的一个逻辑。大家可以看一下右侧整个逻辑框架。
我们主要改动就改动在语义层分析上。在这个规则上增加一个语义分析FindDataSouce,完成流式表解析,和增加了一个专门的可执行类SQLStreamingSink,用来专门读取。比如说读取Watermark或各种的配置,最终产生一个流式的Plan去执行。最后经过语义层分析之后,就变成了一个SQLStreamingSink。到这一步,一旦执行起来,它和正常API调度是一样的,这样API和SQL在语义层之后已经达到完整一致了。整体只在语义层这个地方做了一些区别而已。
总结来说,首先我们提供了一个统一的Hive元数据存储,我们所有的Table都是基于Hive的,当然Hive只是一种方案,主要是用数据仓库的形式来对数据进行统一管理。我们升级了FindDataSource,用来处理Table到Source一个定义。比如说用户的groupby,filter,sum等操作都会通过语义解析的时候,会对它进行分析。现在这套方案,我们已经提供给社区。如果大家有兴趣的可以一块看看有什么更好的方案解决StreamingJoinBach的处理,在Spark的Patch中搜SQLStreaming可以看到目前正在讨论的链接,欢迎一起讨论相关方案。
实时转离线问题
很多人会说实时转离线用的场景多吗?其实在百度内的场景用的不少的,因为比如说用户的点击日志数据,大部分都是实时存放在日志中的,他会进行流式处理时候会全部打到Kafka消息队列里面,它还是有些需求,对数据进行一些比如说天级别,月级别,甚至年级别的数据分析。这时候应该怎么办呢?于是我们就提供了实时转离线的功能,其实Spark本身已经提供了一个实时转离线的,就是右侧的这个代码。
比如说定义了一个CSV,定义一下它的分区路径,定义partition、location等,去执行写的操作时是有问题的。首先它输出信息完全是由人为去记在如一个卡片里,记在一个统一的文档里,下游去用的时候,问上游询要。一旦上游改变了,里面信息肯定就完全不对称了。
另外一个就是迁移升级问题。在百度内部存在集群迁移的问题,一个机房一般用几年之后,都会下线,这时候就会存在机型迁移。在输出路径上,或者在输出格式上,需要做出改变。而现在,一般来说,就是很多数据开发的人员,更期望的是开发的代码,能长时间运行。如果我用当前的实时转离线方案的话,肯定需要拿到原生的代码进行修改,再搭架构,再执行,这也是现实场景中用户吐槽最多的。
另外就是一个拓展文件格式,比如说甲方要求输出sequenceFile,并指定了格式。但下游需要的sequenceFile格式是不同,怎么去拓展?这样开发代价很大,很多用户是比较抵制的,我们提供的方案是什么呢?就是实时转数仓的方案。
大家知道Hive保存了很多信息,里面这些元数据信息,比如说有统一的管理员进行管理之后,这些信息都可以很明晰,很明了的被其他人看到。但输出升级或迁移了,这时候修改location就可以了,代码比较好改。具体代码是什么样呢?就是右下角的这行代码。
这个方案具体实现是这样的,原生有一个FileSink,读取CSV的数据,然后对数据进行处理之后,进行流式输出。只不过我们改动变成了Hive的FileFormat,以批量的形式进行写入,然后输出出去。我们在创建FileSink的时候,我们会读一下用户填入的Table,拿到它的信息,注入进去,进行一个写操作。大家可以注意到有一个分析监听器 ,在运行完每一个批量,都有一个信息反馈,如到底输出了哪些partition,能拿到相应的分区信息。拿到这个分区信息之后,可以对它进行一些处理,最后注入到Hive中,这样的话到底生产了哪些partition,完全可以在Hive里面可以去查到的。
基本上这就是这完整的一套实时转数仓方案。我们基于这一套方案,在百度内部已经推广到了很多业务上。在百度内部还有很多细粒度的权限处理使用实时转数仓方案。一旦写入数仓,下游在订阅的时候会有一些数据脱敏,或者是读写权限控制,或者列权限控制,都能用这套方案进行控制,所以实时转数仓方案在百度内部还是比较受欢迎的。
实时转大屏展示
我们在推广过程中,用户是也些大屏展示的使用场景的。
这页显示的这是一个通用的用户使用场景,比如说将Streaming实时的数据输出到一个OLAP里面,最终展示给大屏。但是这个场景有什么问题呢?这里需要额外使用其他的系统,比如Kafka系统、OLAP系统,最后再接入到大屏展示里面。每个系统,都需要找不同的负责人去处理,中间一旦出问题,需要反复去找负责人,与他们相互协调。中间会很复杂,一旦有一个网络出现故障,数据就会延时,负责人都需要处理自己的业务瓶颈。处理瓶颈是在用户使用场景中比较难办的问题。
我们是如何处理呢?现有的一套解决方案提供了一套原生的基于SparkSQL,Sparkshell的系统。我们自研了一套就是交互式的分析,可以在本地,通过LivyJBDCAPI,当用户select*或者什么的时候,它完全可以交互式的提交到集群上处理,然后反馈给用户。这时候结合SparkMemorySink去处理,将数据进行一些复杂的分析,具体的业务逻辑处理之后,它会将数据写入到集群内存里面。前端通过LivyJDBCAPI去交互式的去查询Spark集群内存的数据。这样数据是直接落到集群内存的,没有任何产出,是保存在内存里面的。Livy去查的时候直接从里面去拿出来,相当于直接走内存,不会走经过落盘,网络等。这套方案就在实时处理和部署上,比较受欢迎。
然后这就是,我们整个的流批的处理,用户通过各种方式传输数据,我们经过流到流,或者是流到批,或者是批到批的处理,当然中间我们可以完全映射成Table,就是流式的Table到批的Table,再到具体的业务输出方。或者流式的Table到流式的Table,或者是批的Table的到批的Table,这完全是OK的。
流式数据处理在百度数据工厂的实践
基于这套数据处理,我给大家简单介绍一下百度内部的一些实践。下图是流式的第一版本的产品化界面。我们已经在设计第三版了。左边是一个流式SQL的一个提交界面,用户可以在里面添加SQL,右边是流式监控。和现在Spark比较,和Spark监控页面比较类似的,监控当天有什么数据,显示实际处理量、数据时延等。
广告物料分析实践案例是我们一个比较典型的流批处理的使用场景。在实际的产品运维过程中,存在广告主投放广告的场景。广告主投放广告付钱是要看真实的点击率、曝光率和转化率的,而且很多广告主是根据曝光量、点击量、转化量来付钱的。
这种情况下,我们就需要专门针对广告物料进行分析,根据点击、曝光日志和转化数据生成广告的pv、uv、点击率和转化率,并根据计费数据生成广告收益。
可以看到我们会通过Streaming直接输出到大屏展示。广告主会直接看到实时的用户量、当前的产出、收益。另外一部分数据产出到离线里面,通过实时转离线输出出来,进行一个日级别,天级别的分析,生成一些天级别,还有月级别的一些PV量,供后台做策略人员分析,以调整广告的投放策略。
本文为专栏文章,来自:AI前线,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/66094.html 。
数据分析
2019-08-26 09:53:00
Dragon 是一种创新和实用的通用语言。所支持的编程范例是命令式的、过程式的、面向对象的、使用嵌套结构的声明式的。该语言是可移植的(Windows、Linux、macOS、Android等),可用于创建控制台、GUI和移动应用程序。该语言被设计为简单、小巧、灵活和快速。
它由Aavesh Jilani设计,于2018年首次出现,也被称为多范式语言。 该语言是可移植的,适用于所有操作系统。使用动态类型系统,它也被用来创建GUI,控制台。
而这种语言以创新的方法而闻名。
创新
有各种各样的Dragon库,比如GUI、DB和图形库,它们对于编写完整的程序非常有用。它的实用特性有助于提高开发人员的工作效率,并且可以轻松使用。
实用
许多Dragon模块(GUI、图形、db、文件等)。Dragon已经准备好在生产中使用,并提高了开发人员的生产力。
为什么使用Dragon 编程语言
语言简单、自然。它具有紧凑的语法和一组特性,使程序员能够在很短的时间内创建自然接口和声明性领域特定语言。它很小、很快。它提供了有用和实用的库。该语言是为提高生产力和开发可扩展的高质量解决方案而设计的。
专为明确目标而设计
1. 应用编程语言。
2. 生产力和开发可扩展的高质量解决方案。
3. 短小精悍的语言。
4. 可用于教育的简单语言。
简单的
Dragon是一种非常简单的语言,具有非常直观的语法。它鼓励程序员在没有样板代码的情况下编程。要使用标准输出输出内容,可以使用”show”命令。以及’showln’用于换行输出。
对于输入,我们可以使用”prompt()”方法,它位于”graphic”库中。
试着变得自然
定义前调用函数
赋值操作符使用深层副本(此操作中没有引用)
通过参数传递值。
来自: AI中国
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2019-08-21 18:47:00
英国一家网络安全创业公司,曾获Autonomy创始人Mike Lynch投资的 Darktrace ,7月6日宣布完成新一轮6400万美元的C轮融资。
新一轮融资由全球投资公司KKR领投,其他参投的还包括现有投资方Summit Partners和新投资方TenEleven以及SoftBank。
新的投资让这家成立于2013年的公司估值上升到4亿多美元,不过在一次电话中,Lynch表示,新的融资是一次典型的发展轮融资,日后将用以进一步国际扩展和产品开发。
他还特别强调,Darktrace正在开发一项技术,不仅能够帮助企业识别并应对人为制造的网络攻击,同时还能预防基于机器学习的网络攻击,比如,在传统的科幻小说里我们经常可以看到,分别代表了正义与邪恶的AI激烈对抗。
不过这都是后话了,重要的是现在Darktrace能为用户提供些什么。这家创业公司开发的“企业免疫系统”有一个放在公司网络上的盒子,结合公司开发的软件可以监听流量。
当可疑行为发生时,系统会向IT经理发送警告,或者如果必要的话,系统会采取即时措施阻止或减慢攻击,比如通过限制网速为人们争取更多时间解决黑客攻击问题。
更广泛地,Lynch解释说,Darktrace的运行基于一种特殊的假设,即所有公司的网络都可能已经受损,或者非常容易遭到攻击。这种网络环境对我们的系统来说非常普遍,因为公司必须得跟供应商和消费者交互,还有自己的庞大员工群体需要使用网络。
因此,与其假设网络攻击可以被强大的“防火墙”阻挡,Darktrace则选择模仿人类的免疫系统,病毒入侵到网络内部时,通过公司提供的“高级算法和机器学习技术”,把危害扼杀在摇篮里。
从基础层面上讲,这就意味着Darktrace不仅要有监听所有通过公司网络的流量的能力,还必须能够区别正常和恶意的行为。
Lynch说,快速的攻击很容易识别,它们的本质就说明了一切,但是抵御这类攻击,系统的反应机制就必须特别地迅速,因此Darktrace的盒子才需要具备一定程度的自主性。不过,隐藏或暂时休眠的恶意行为就相对难处理,但是公司的机器学习技术表示可以解决。
另外,让我们这种普通的科技记者去判断网络安全创业公司的技术声明到底有多真实可靠,似乎有点强人所难,不过其他事实可以说明些许——Darktrace的发展速度让人震惊。Lynch说,Darktrace可能是他创办或投资过的公司中发展最快的一个。公司其他几个早期投资者,比如Hoxton Venture的Hussein Kanji也看到了Darktrace的潜力。
具体来说,Darktrace宣称已有超过1000多用户部署了公司的系统,其中包括全球“金融机构、通讯网络公司、法律公司、零售商、技术公司、政府机构以及国家重要的基础设施等。”说到收益,公司表示相比去年增长了600%以上。换句话说,也就是每月收益大概在百万美元以上。
根据Lynch的说法,公司成长如此迅速的一个原因,可能是,一方面近年来媒体报道的网络攻击越来越频繁,另一方面很多公司也逐渐接受在他们的网络系统中安装一个来自第三方的设备,尤其是当他们可以马上看到这样做的好处之后。
最后当被问及这个系统有时候会不会让IT经理或者公司的首席技术官感到尴尬时,Lynch表示,在某些情况下确实会。但是,他还强调,我们的文化在改变,公司管理层应该开始接受新的现实:网络攻击会不断发生,战争已经开始。 作者:月半白
来源:猎云网
链接:http://www.lieyunwang.com/archives/190560
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2016-07-06 19:20:00
在今天, 大数据 不仅仅是一个概念、一个话题,而正在成为生活中的一部分,Google用 大数据 预测流感趋势、政府用大数据构建智慧城市、银行用大数据构建用户画像分析客户心理……随着大数据在多个领域的应用“落地”,越来越多的企业已经清晰地认识到企业大数据已经成为企业的核心资产和重要组成部分,都希望能够从数据获取更多的价值并且快速指导商业决策。
但在大数据带来巨大的价值的同时,也给企业的数据安全带来了挑战。企业大数据可能包含了大量的客户隐私信息、员工基础信息、销售订单信息、企业运营信息和各种行为的细节记录, 数据分析 系统如何对这些私密信息进行恰当的数据安全保护,将是企业大数据发展中需要亟待解决的难题。
老丁的担忧
老丁是一家公司IT部门的主管,随着公司内部信息化系统建设的逐步完善,企业内部的数据量正快速地增长,公司为了将数据价值最大化,斥资购置并搭建了一套数据分析系统,并将分散在财务、OA、ERP和CRM等系统的数据做了数据整合存储,为企业提供跨业务场景的数据分析支持,提升决策的准确度。
在系统正式上线运行后,跨业务的数据分析功能得到了业务部门用户的好评,纷纷表示获取数据更加方便快捷了,而且还解决了之前各业务系统由于统计口径不一致导致数据偏差的问题。虽然业务用户反馈良好,但此时的老丁心里是喜忧参半,因为数据分析系统中汇集了全公司的业务数据,其中不乏许多敏感私密的商业信息,这些数据的集中存储增加的数据泄露的风险。一旦分析系统的数据管控不当,造成的后果相比单个业务系统的数据泄露要严重很多。目前已经陆陆续续有好几个业务部门的主管给他反馈了一些数据管控存在缺陷的问题: 业务部门的某个普通员工能够对部门的报表模板做更改保存,影响了其他员工的报表查阅和数据分析工作; 一线销售人员通过商品销售报表的不仅可以看到销售额和销量指标,甚至连商品销售成本和利润等敏感信息都能够查看。 某个门店的店长竟然能够查看到整个销售大区的订单数据;
针对以上发现的问题,引起了公司高层领导的重视,大老板向老丁下达了做好企业数据权限管控,以防内部数据大量泄漏的任务。其实在上面的案例中,老丁在建设数据分析系统时所遇到的数据管控问题,是大多数企业在建设大数据分析平台时都将存在的普遍问题,也是企业内部IT部门面临着急需解决的问题。
数据管控
如果我们想要保护企业内部数据的安全,可以从以下几个方面来打造企业级数据权限管控体系:
1. 功能权限
功能权限限制了用户在系统中的具备的操作能力,合理地为用户账号划分功能权限,是数据报告和后台数据保持稳定性的有力保障。一般可按照组织架构(集团、区域、子公司、分中心、事业部、部门等层级)、角色(超级管理员、部门管理员、普通用户)和用户等方式对功能权限进行划分,通过严格控制不同组织、不同角色及特定用户在功能模块访问权限、数据模型读写权限和数据报告读写权限三个方面具备的操作,来实现功能权限的管理。
2. 数据权限
数据权限限制了即用户在系统中所能查阅的数据范围,合理地为用户账号分配数据权限,能够有效地降低敏感数据大范围泄露的风险。在数据权限管理中一般利用行权限和列权限两种方式来限制数据的访问。行权限可根据自定义的规则来对每行数据访问的权限进行控制,主要用于按组织架构(集团、区域、子公司、分中心、事业部、部门等层级)的维度对数据访问的范围做限制。列权限则是对每列数据项的访问权限做控制,主要用于按角色(超级管理员、部门管理员、普通用户)的维度对敏感字段的访问权限做限制。
通过对用户数据权限的管理可严格控制企业内部各个部门间数据的独立性,实现不同组织/区域/部门/层级、不同角色的用户在查看同一张数据报告时只能看到对应的数据表及数据字段。举个例子,用户A是华南区域的销售主管,用户B是华北区域的普通销售员,在实现了数据权限管控前提下,当他们在查阅同一张“销售分析报告”时,用户A只能查看到华南区域的销售数据,用户B也只能查看到华北区域的销售数据,由于商品成本和利润是企业敏感数据,不允许对普通销售员开放,因此在用户B查看销售明细表时仅仅只是查看到商品的销售额和销量,但用户A是销售主管的角色,因此他在销售明细表中还能够获取到商品成本和利润两项数据字段的信息。
3. 企业权限集成管控
每个业务系统都具备单独的权限管理体系,随着企业内部建设的业务系统越来越多,所需维护管理的账户权限也将越来越复杂,这是许多企业IT部门都头疼的问题。为了彻底解决这个难题,需要在企业内部以LDAP或AD域的方式搭建一套统一的权限管控系统,并要求业务系统和数据分析平台需具备与第三方权限系统集成的能力,可通过接口的方式与统一权限管控系统对接,保证系统之间组织架构和用户账号的一致,最终实现企业级权限的统一管控。
随着企业内部大数据分析平台的逐步建立,大家开始意识到数据保护和安全的重要性,如何在保证大数据分析能力的前提下做好数据管控,是越来越多公司在对大数据分析平台选型和建设时提出的核心诉求。
永洪的努力
对致力于“以卓越的数据技术为客户创造价值,实现客户成功”的永洪科技来说,如何帮助企业客户保护数据安全,打造企业级数据管控体系一直是永洪关注的重点。永洪科技在2017年4月最新推出的一站式大数据分析平台Yonghong Z-Suite V7.1中,为企业客户提供了更加强大的企业级管理和数据管控能力。主要的能力包括:
1. 更细粒度的权限管理:
更细粒度的操作权限配置,便于用户更有效地管理数据权限,满足自助分析的需要。管理员可以通过界面灵活地对添加数据源、创建数据集、仪表盘、以及单个数据集类型等分别设置不同组、不同角色及不同用户的读写权限。支持功能级别权限管控和数据级别权限管控。在功能级别上,永洪权限支持到按钮级别,比如导入导出,支持关键字段脱敏;在数据层面上支持行列级别单元格权限管控,比如让各个不同部门看到不同的数据,部门中的人也按照角色看到不同的数据。

Yonghong Z-Suite的数据操作权限管理功能
2. 可定制化的权限管理系统
永洪的权限管理系统除了能够使用自带的权限管理系统,还预留了与第三方权限管理系统集成的标准API接口,让永洪平台能够快速地实现与企业统一权限管理系统的集成。
Yonghong Z-Suite的定制化权限管理功能
3. 良好的管理机制
通过提供多级权限管理,导入导出功能,任务调度功能等等,支撑一个企业级管理的需求。
4. 良好的监控机制
提供用户登录情况监控,被访问报表的监控,被调用查询的监控,执行的数据的监控,机器状态的监控等等,对系统各方面进行良好的监控。

Yonghong Z-Suite系统监控界面
5. 加密存储的数据文件
所有存储在永洪平台中的数据文件都是以永洪独创的加密形式保存,即使外部人员通过非法手段得到相关数据文件,也无法成功破解及查看相关其中的数据内容。
6. 可靠的防暴力破解技术与密码找回机制
防止他人非法破解您的密码,保护数据安全。同一账户,在短时间内连续登陆错误次数超出限制后,再次登陆将会得到锁定提示。
借助永洪的企业级数据管控功能,老丁重新设置了不同角色用户对数据报表模板的访问权限,避免了普通员工对报表模板的随意更改;同时加强了不同地区、不同角色用户对敏感数据读取写入的权限控制,防止了敏感数据的任意读取和泄露,及时解决了公司数据管控存在的问题,为数据安全与业务发展提供了更多保障。
简洁高效的数据管控不仅能够避免数据缺乏管理可能导致的风险,更能够解放IT瓶颈束缚的企业驱动力,从整体上提升数据分析与IT管理的效率与价值,从而解除“老丁”们的后顾之忧。 本文作者Jayson,永洪科技高级咨询顾问
本文由 永洪科技 投稿至 数据分析网 并经编辑发表,内容观点不代表本站立场,如转载请联系原作者,本文链接:https://www.afenxi.com/44662.html 。
数据分析
2017-06-15 05:36:00
本文是学习大型分布式网站架构的技术总结。对架构一个高性能、高可用、可伸缩及可扩展的分布式网站进行了概要性描述,并给出一个架构参考。文中一部分为读书笔记,一部分是个人经验总结,对大型分布式网站架构有较好的参考价值。
一、大型分布式网站架构技术
1、大型网站的特点 用户多,分布广泛 大流量,高并发 海量数据,服务高可用 安全环境恶劣,易受网络攻击 功能多,变更快,频繁发布 从小到大,渐进发展 以用户为中心 免费服务,付费体验
2、大型网站架构目标 高性能:提供快速的访问体验。 高可用:网站服务一直可以正常访问。 可伸缩:通过硬件增加/减少,提高/降低处理能力。 安全性:提供网站安全访问和数据加密、安全存储等策略。 扩展性:方便地通过新增/移除方式,增加/减少新的功能/模块。 敏捷性:随需应变,快速响应;
3、大型网站架构模式
分层:一般可分为应用层、服务层、数据层、管理层与分析层; 分割:一般按照业务/模块/功能特点进行划分,比如应用层分为首页、用户中心。 分布式:将应用分开部署(比如多台物理机),通过远程调用协同工作。 集群:一个应用/模块/功能部署多份(如:多台物理机),通过负载均衡共同提供对外访问。 缓存:将数据放在距离应用或用户最近的位置,加快访问速度。 异步:将同步的操作异步化。客户端发出请求,不等待服务端响应,等服务端处理完毕后,使用通知或轮询的方式告知请求方。一般指:请求——响应——通知模式。 冗余:增加副本,提高可用性、安全性与性能。 安全:对已知问题有有效的解决方案,对未知/潜在问题建立发现和防御机制。 自动化:将重复的、不需要人工参与的事情,通过工具的方式,使用机器完成。 敏捷性:积极接受需求变更,快速响应业务发展需求。
4、高性能架构
以用户为中心,提供快速的网页访问体验。主要参数有 较短的响应时间、较大的并发处理能力、较高的吞吐量与稳定的性能参数 。
可分为前端优化、应用层优化、代码层优化与存储层优化。 前端优化 :网站业务逻辑之前的部分; 浏览器优化 :减少HTTP请求数,使用浏览器缓存,启用压缩,CSS JS位置,JS异步,减少Cookie传输;CDN加速,反向代理; 应用层优化 :处理网站业务的服务器。使用缓存,异步,集群 代码优化 :合理的架构,多线程,资源复用(对象池,线程池等),良好的数据结构,JVM调优,单例,Cache等; 存储优化 :缓存、固态硬盘、光纤传输、优化读写、磁盘冗余、分布式存储(HDFS)、 NoSQL 等。
5、高可用架构
大型网站应该在任何时候都可以正常访问,正常提供对外服务。因为大型网站的复杂性,分布式,廉价服务器,开源数据库,操作系统等特点,要保证高可用是很困难的,也就是说网站的故障是不可避免的。
如何提高可用性,就是需要迫切解决的问题。首先,需要从架构级别考虑,在规划的时候,就考虑可用性。行业内一般用几个9表示可用性指标,比如四个9(99.99),一年内允许的不可用时间是53分钟。
不同层级使用的策略不同,一般采用冗余备份和失效转移解决高可用问题。 应用层 :一般设计为无状态的,对于每次请求,使用哪一台服务器处理是没有影响的。一般使用负载均衡技术(需要解决Session同步问题)实现高可用。 服务层 :负载均衡,分级管理,快速失败(超时设置),异步调用,服务降级,幂等设计等。 数据层 :冗余备份(冷,热备[同步,异步],温备),失效转移(确认,转移,恢复)。数据高可用方面著名的理论基础是CAP理论(持久性,可用性,数据一致性[强一致,用户一致,最终一致])
6、可伸缩架构
伸缩性是指在不改变原有架构设计的基础上,通过添加/减少硬件(服务器)的方式,提高/降低系统的处理能力。 应用层: 对应用进行垂直或水平切分。然后针对单一功能进行负载均衡(DNS、HTTP[反向代理]、IP、链路层)。 服务层 :与应用层类似; 数据层 :分库、分表、NoSQL等;常用算法Hash,一致性Hash。
7、可扩展架构
可以方便地进行功能模块的新增/移除,提供代码/模块级别良好的可扩展性。 模块化,组件化 :高内聚,低耦合,提高复用性,扩展性。 稳定接口 :定义稳定的接口,在接口不变的情况下,内部结构可以“随意”变化。 设计模式 :应用面向对象思想,原则,使用设计模式,进行代码层面的设计。 消息队列 :模块化的系统,通过消息队列进行交互,使模块之间的依赖解耦。 分布式服务 :公用模块服务化,提供其他系统使用,提高可重用性,扩展性。
8、安全架构
对已知问题有有效的解决方案,对未知/潜在问题建立发现和防御机制。对于安全问题,首先要提高 安全意识 ,建立一个安全的有效机制,从政策层面,组织层面进行保障,比如服务器密码不能泄露,密码每月更新,并且三次内不能重复;每周安全扫描等。以制度化的方式,加强安全体系的建设。同时,需要注意与安全有关的各个环节。安全问题不容忽视,包括基础设施安全,应用系统安全,数据保密安全等。 基础设施安全 :硬件采购,操作系统,网络环境方面的安全。一般采用正规渠道购买高质量的产品,选择安全的操作系统,及时修补漏洞,安装杀毒软件防火墙。防范病毒,后门。设置防火墙策略,建立DDOS防御系统,使用攻击检测系统,进行子网隔离等手段。 应用系统安全 :在程序开发时,对已知常用问题,使用正确的方式,在代码层面解决掉。防止跨站脚本攻击(XSS),注入攻击,跨站请求伪造(CSRF),错误信息,HTML注释,文件上传,路径遍历等。还可以使用Web应用防火墙(比如:ModSecurity),进行安全漏洞扫描等措施,加强应用级别的安全。 数据保密安全 :存储安全(存储在可靠的设备,实时,定时备份),保存安全(重要的信息加密保存,选择合适的人员复杂保存和检测等),传输安全(防止数据窃取和数据篡改);
常用的加解密算法(单项散列加密[MD5、SHA],对称加密[DES、3DES、RC]),非对称加密[RSA]等。
9、敏捷性
网站的架构设计,运维管理要适应变化,提供高伸缩性,高扩展性。方便的应对快速的业务发展,突增高流量访问等要求。
除上面介绍的架构要素外,还需要引入敏捷管理,敏捷开发的思想。使业务,产品,技术,运维统一起来,随需应变,快速响应。
10、大型架构举例
以上采用七层逻辑架构,第一层客户层,第二层前端优化层,第三层应用层,第四层服务层,第五层数据存储层,第六层 大数据 存储层,第七层 大数据 处理层。 客户层 :支持PC浏览器和手机APP。差别是手机APP可以直接通过IP访问,反向代理服务器。 前端层 :使用DNS负载均衡,CDN本地加速以及反向代理服务; 应用层 :网站应用集群;按照业务进行垂直拆分,比如商品应用,会员中心等; 服务层 :提供公用服务,比如用户服务,订单服务,支付服务等; 数据层 :支持关系型数据库集群(支持读写分离),NOSQL集群,分布式文件系统集群;以及分布式Cache; 大数据存储层 :支持应用层和服务层的日志数据收集,关系数据库和NOSQL数据库的结构化和半结构化数据收集; 大数据处理层 :通过Mapreduce进行离线 数据分析 或Storm实时数据分析,并将处理后的数据存入关系型数据库。(实际使用中,离线数据和实时数据会按照业务要求进行分类处理,并存入不同的数据库中,供应用层或服务层使用)。
二、大型电商网站系统架构演变过程
一个成熟的大型网站(如淘宝、天猫、腾讯等)的系统架构并不是一开始设计时就具备完整的高性能、高可用、高伸缩等特性的,它是随着用户量的增加,业务功能的扩展逐渐演变完善的,在这个过程中,开发模式、技术架构、设计思想也发生了很大的变化,就连技术人员也从几个人发展到一个部门甚至一条产品线。
所以成熟的系统架构是随着业务的扩展而逐步完善的,并不是一蹴而就;不同业务特征的系统,会有各自的侧重点,例如淘宝,要解决海量的商品信息的搜索、下单、支付;例如腾讯,要解决数亿用户的实时消息传输;百度它要处理海量的搜索请求。
他们都有各自的业务特性,系统架构也有所不同。尽管如此我们也可以从这些不同的网站背景中,找出其中共用的技术,这些技术和手段广泛运用在大型网站系统的架构中,下面就通过介绍大型网站系统的演化过程,来认识这些技术和手段。
1、最开始的网站架构
最初的架构,应用程序、数据库、文件都部署在一台服务器上,如图:
2、应用、数据、文件分离
随着业务的扩展,一台服务器已经不能满足性能需求,故将应用程序、数据库、文件各自部署在独立的服务器上,并且根据服务器的用途配置不同的硬件,达到最佳的性能效果。
3、利用缓存改善网站性能
在硬件优化性能的同时,同时也通过软件进行性能优化,在大部分的网站系统中,都会利用缓存技术改善系统的性能,使用缓存主要源于热点数据的存在,大部分网站访问都遵循28原则(即80%的访问请求,最终落在20%的数据上),所以我们可以对热点数据进行缓存,减少这些数据的访问路径,提高用户体验。
缓存实现常见的方式是本地缓存、分布式缓存。当然还有CDN、反向代理等,这个后面再讲。本地缓存,顾名思义是将数据缓存在应用服务器本地,可以存在内存中,也可以存在文件,OSCache就是常用的本地缓存组件。本地缓存的特点是速度快,但因为本地空间有限所以缓存数据量也有限。分布式缓存的特点是,可
以缓存海量的数据,并且扩展非常容易,在门户类网站中常常被使用,速度按理没有本地缓存快,常用的分布式缓存是Memcached、Redis。
4、使用集群改善应用服务器性能
应用服务器作为网站的入口,会承担大量的请求,我们往往通过应用服务器集群来分担请求数。应用服务器前面部署负载均衡服务器调度用户请求,根据分发策略将请求分发到多个应用服务器节点。
常用的负载均衡技术硬件的有F5,价格比较贵,软件的有LVS、Nginx、HAProxy。LVS是四层负载均衡,根据目标地址和端口选择内部服务器,Nginx和HAProxy是七层负载均衡,可以根据报文内容选择内部服务器,因此LVS分发路径优于Nginx和HAProxy,性能要高些,而Nginx和HAProxy则更具配置性,如可以用来做动静分离(根据请求报文特征,选择静态资源服务器还是应用服务器)。
5、数据库读写分离和分库分表
随着用户量的增加,数据库成为最大的瓶颈,改善数据库性能常用的手段是进行读写分离以及分库分表,读写分离顾名思义就是将数据库分为读库和写库,通过主备功能实现数据同步。分库分表则分为水平切分和垂直切分,水平切分则是对一个数据库特大的表进行拆分,例如用户表。垂直切分则是根据业务的不同来切分,如用户业务、商品业务相关的表放在不同的数据库中。
6、使用CDN和反向代理提高网站性能
假如我们的服务器都部署在成都的机房,对于四川的用户来说访问是较快的,而对于北京的用户访问是较慢的,这是由于四川和北京分别属于电信和联通的不同发达地区,北京用户访问需要通过互联路由器经过较长的路径才能访问到成都的服务器,返回路径也一样,所以数据传输时间比较长。对于这种情况,常常使用CDN解决,CDN将数据内容缓存到运营商的机房,用户访问时先从最近的运营商获取数据,这样大大减少了网络访问的路径。比较专业的CDN运营商有蓝汛、网宿。
而反向代理,则是部署在网站的机房,当用户请求达到时首先访问反向代理服务器,反向代理服务器将缓存的数据返回给用户,如果没有缓存数据才会继续访问应用服务器获取,这样做减少了获取数据的成本。反向代理有Squid、Nginx。
7、使用分布式文件系统
用户一天天增加,业务量越来越大,产生的文件越来越多,单台的文件服务器已经不能满足需求,这时就需要分布式文件系统的支撑。常用的分布式文件系统有GFS、HDFS、TFS。
8、使用NoSQL和搜索引擎
对于海量数据的查询和分析,我们使用NoSQL数据库加上搜索引擎可以达到更好的性能。并不是所有的数据都要放在关系型数据中。常用的NoSQL有MongoDB、HBase、Redis,搜索引擎有Lucene、Solr、Elasticsearch。
9、将应用服务器进行业务拆分
随着业务进一步扩展,应用程序变得非常臃肿,这时我们需要将应用程序进行业务拆分,如百度分为新闻、网页、图片等业务。每个业务应用负责相对独立的业务运作。业务之间通过消息进行通信或者共享数据库来实现。
10、搭建分布式服务
这时我们发现各个业务应用都会使用到一些基本的业务服务,例如用户服务、订单服务、支付服务、安全服务,这些服务是支撑各业务应用的基本要素。我们将这些服务抽取出来利用分部式服务框架搭建分布式服务。阿里的Dubbo是一个不错的选择。
三、一张图说明电商架构
四、大型电商网站架构案例
1、电商案例的原因
分布式大型网站,目前看主要有几类: 大型门户, 比如网易,新浪等; SNS网站, 比如校内,开心网等; 电商网站, 比如阿里巴巴,京东商城,国美在线,汽车之家等。
大型门户一般是新闻类信息,可以使用CDN,静态化等方式优化,开心网等交互性比较多,可能会引入更多的NoSQL,分布式缓存,使用高性能的通信框架等。电商网站具备以上两类的特点,比如产品详情可以采用CDN,静态化,交互性高的需要采用NoSQL等技术。因此,我们采用电商网站作为案例,进行分析。
2、电商网站需求
客户需求: 建立一个全品类的 电子商务 网站(B2C),用户可以在线购买商品,可以在线支付,也可以货到付款; 用户购买时可以在线与客服沟通; 用户收到商品后,可以给商品打分,评价; 目前有成熟的进销存系统;需要与网站对接; 希望能够支持3~5年,业务的发展; 预计3~5年用户数达到1000万; 定期举办双11、双12、三八男人节等活动; 其他的功能参考京东或国美在线等网站。
客户就是客户,不会告诉你具体要什么,只会告诉你他想要什么,我们很多时候要引导,挖掘客户的需求。好在提供了明确的参考网站。因此,下一步要进行大量的分析,结合行业,以及参考网站,给客户提供方案。
需求功能矩阵
需求管理传统的做法,会使用用例图或模块图(需求列表)进行需求的描述。这样做常常忽视掉一个很重要的需求(非功能需求),因此推荐大家使用需求功能矩阵,进行需求描述。
本电商网站的需求矩阵如下:
3、网站初级架构
一般网站,刚开始的做法,是三台服务器,一台部署应用,一台部署数据库,一台部署NFS文件系统。
这是前几年比较传统的做法,之前见到一个网站10万多会员,垂直服装设计门户,N多图片。使用了一台服务器部署了应用,数据库以及图片存储。出现了很多性能问题。
如下图:
但是,目前主流的网站架构已经发生了翻天覆地的变化。一般都会采用集群的方式,进行高可用设计。至少是下面这个样子:
使用集群对应用服务器进行冗余,实现高可用;(负载均衡设备可与应用一块部署) 使用数据库主备模式,实现数据备份和高可用;
4、系统容量预估
预估步骤: 注册用户数-日均UV量-每日的PV量-每天的并发量; 峰值预估:平常量的2~3倍; 根据并发量(并发,事务数),存储容量计算系统容量。
根据客户需求:3~5年用户数达到1000万注册用户,可以做每秒并发数预估: 每天的UV为200万(二八原则); 每日每天点击浏览30次; PV量:200*30=6000万; 集中访问量:24*0.2=4.8小时会有6000万*0.8=4800万(二八原则); 每分并发量:4.8*60=288分钟,每分钟访问4800/288=16.7万(约等于); 每秒并发量:16.7万/60=2780(约等于); 假设:高峰期为平常值的三倍,则每秒的并发数可以达到8340次。 1毫秒=1.3次访问;
没好好学数学后悔了吧?!(不知道以上算是否有错误,呵呵~~)
服务器预估:(以tomcat服务器举例)
按一台web服务器,支持每秒300个并发计算。平常需要10台服务器(约等于);[tomcat默认配置是150],高峰期需要30台服务器;
容量预估:70/90原则
系统CPU一般维持在70%左右的水平,高峰期达到90%的水平,是不浪费资源,并比较稳定的。内存,IO类似。
以上预估仅供参考,因为服务器配置,业务逻辑复杂度等都有影响。在此CPU,硬盘,网络等不再进行评估。
5、网站架构分析
根据以上预估,有几个问题: 需要部署大量的服务器,高峰期计算,可能要部署30台Web服务器。并且这三十台服务器,只有秒杀,活动时才会用到,存在大量的浪费。 所有的应用部署在同一台服务器,应用之间耦合严重。需要进行垂直切分和水平切分。 大量应用存在冗余代码 服务器Session同步耗费大量内存和网络带宽 数据需要频繁访问数据库,数据库访问压力巨大。
大型网站一般需要做以下架构优化(优化是架构设计时,就要考虑的,一般从架构/代码级别解决,调优主要是简单参数的调整,比如JVM调优;如果调优涉及大量代码改造,就不是调优了,属于重构): 业务拆分 应用集群部署(分布式部署,集群部署和负载均衡) 多级缓存 单点登录(分布式Session) 数据库集群(读写分离,分库分表) 服务化 消息队列 其他技术
6、网站架构优化
6.1业务拆分
根据业务属性进行垂直切分,划分为产品子系统,购物子系统,支付子系统,评论子系统,客服子系统,接口子系统(对接如进销存,短信等外部系统)。
根据业务子系统进行等级定义,可分为核心系统和非核心系统。核心系统:产品子系统,购物子系统,支付子系统;非核心:评论子系统,客服子系统,接口子系统。 业务拆分作用:提升为子系统可由专门的团队和部门负责,专业的人做专业的事,解决模块之间耦合以及扩展性问题;每个子系统单独部署,避免集中部署导致一个应用挂了,全部应用不可用的问题。 等级定义作用:用于流量突发时,对关键应用进行保护,实现优雅降级;保护关键应用不受到影响。
拆分后的架构图:
参考部署方案2
如上图每个应用单独部署,核心系统和非核心系统组合部署
6.2应用集群部署(分布式,集群,负载均衡) 分布式部署:将业务拆分后的应用单独部署,应用直接通过RPC进行远程通信; 集群部署:电商网站的高可用要求,每个应用至少部署两台服务器进行集群部署; 负载均衡:是高可用系统必须的,一般应用通过负载均衡实现高可用,分布式服务通过内置的负载均衡实现高可用,关系型数据库通过主备方式实现高可用。
集群部署后架构图:
6.3 多级缓存
缓存按照存放的位置一般可分为两类本地缓存和分布式缓存。本案例采用二级缓存的方式,进行缓存的设计。一级缓存为本地缓存,二级缓存为分布式缓存。(还有页面缓存,片段缓存等,那是更细粒度的划分)
一级缓存,缓存数据字典,和常用热点数据等基本不可变/有规则变化的信息,二级缓存缓存需要的所有缓存。当一级缓存过期或不可用时,访问二级缓存的数据。如果二级缓存也没有,则访问数据库。
缓存的比例,一般1:4,即可考虑使用缓存。(理论上是1:2即可)。
根据业务特性可使用以下缓存过期策略: 缓存自动过期; 缓存触发过期;
6.4单点登录(分布式Session)
系统分割为多个子系统,独立部署后,不可避免的会遇到会话管理的问题。一般可采用Session同步,Cookies,分布式Session方式。电商网站一般采用分布式Session实现。
再进一步可以根据分布式Session,建立完善的单点登录或账户管理系统。
流程说明 用户第一次登录时,将会话信息(用户Id和用户信息),比如以用户Id为Key,写入分布式Session; 用户再次登录时,获取分布式Session,是否有会话信息,如果没有则调到登录页; 一般采用Cache中间件实现,建议使用Redis,因此它有持久化功能,方便分布式Session宕机后,可以从持久化存储中加载会话信息; 存入会话时,可以设置会话保持的时间,比如15分钟,超过后自动超时;
结合Cache中间件,实现的分布式Session,可以很好的模拟Session会话。
6.5数据库集群(读写分离,分库分表)
大型网站需要存储海量的数据,为达到海量数据存储,高可用,高性能一般采用冗余的方式进行系统设计。一般有两种方式读写分离和分库分表。
读写分离:一般解决读比例远大于写比例的场景,可采用一主一备,一主多备或多主多备方式。
本案例在业务拆分的基础上,结合分库分表和读写分离。如下图:
业务拆分后:每个子系统需要单独的库; 如果单独的库太大,可以根据业务特性,进行再次分库,比如商品分类库,产品库; 分库后,如果表中有数据量很大的,则进行分表,一般可以按照Id,时间等进行分表;(高级的用法是一致性Hash) 在分库、分表的基础上,进行读写分离;
相关中间件可参考Cobar(阿里,目前已不在维护),TDDL(阿里),Atlas(奇虎360),MyCat。
分库分表后序列的问题,JOIN,事务的问题,会在分库分表主题分享中,介绍。
6.6服务化
将多个子系统公用的功能/模块,进行抽取,作为公用服务使用。比如本案例的会员子系统就可以抽取为公用的服务。
6.7消息队列
消息队列可以解决子系统/模块之间的耦合,实现异步,高可用,高性能的系统。是分布式系统的标准配置。本案例中,消息队列主要应用在购物,配送环节。 用户下单后,写入消息队列,后直接返回客户端; 库存子系统:读取消息队列信息,完成减库存; 配送子系统:读取消息队列信息,进行配送;
目前使用较多的MQ有Active MQ、Rabbit MQ、Zero MQ、MS MQ等,需要根据具体的业务场景进行选择。建议可以研究下Rabbit MQ。
6.8其他架构(技术)
除了以上介绍的业务拆分,应用集群,多级缓存,单点登录,数据库集群,服务化,消息队列外。还有CDN,反向代理,分布式文件系统,大数据处理等系统。
此处不详细介绍,大家可以问度娘/Google,有机会的话也可以分享给大家。
7、架构汇总
大型网站的架构是根据业务需求不断完善的,根据不同的业务特征会做特定的设计和考虑,本文只是讲述一个常规大型网站会涉及的一些技术和手段,希望能给大家带来启发。
作者介绍
烂猪皮,十余年工作经验,曾在 Google 等外企工作过几年,精通 Java、分布式架构、微服务架构以及数据库,最近正在研究大数据以及区块链,希望能突破到更高的境界
原文链接:https://my.oschina.net/editorial-story/blog/1808757
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2018-07-20 01:46:00
用户在社交网络中留下了海量信息,为企业进行消费者和市场研究提供了宝贵的数据资源,Social Listening(社群聆听)已经成为品牌市场部门的必修技能。长期以来,互联网数据的应用局限于文本数据,消费者与品牌的大部分对话场景——图片,成为Social Listening的巨大盲区。
Social Listening 2.0时代,已经到来
据统计,每天有 32亿 张图片被分享到社交媒体上,50%以上的社交内容包含图片,85%的视觉信息没有文字提及。图片已经成为信息传播、品牌曝光的主要形式。对于企业而言,看不见海量的彩色数据,无异于睁眼的瞎子,不仅会导致数据研究的失真和失实,也将丧失洞察消费者的最佳机会。随着近年来AI领域的飞速发展,基于深度学习的图像识别技术,为图片数据的理解和挖掘打开了大门。与文本数据相比,图片数据更完整、更真实、更丰富、更可靠。具备读图能力的Social Listening 2.0时代,已经到来。
更完整:图片声量–Social Listening 不可或缺的指标
社交网络的“声量”和“互动量”,是评估品牌资产、线上营销活动效果和媒介投放的重要指标。当前的监测系统,这两个指标都是通过文本关键词来计算的。比如,提及“可口可乐”关键词的内容数量,以及参与“转/评/赞”的数量,分别是“可口可乐”品牌的声量和互动量。读图时代,越来越多的用户选择用图片传播信息、表达情感。消费者在很多场景下 不会直接提及品牌的名字 ,而是通过发布包含品牌或产品的图片,并加以评论。由于图片比文字具备更强的表达能力,也往往会吸引更多的互动量。据图片 大数据 应用公司ImageDT统计, 超过50%的品牌声量有图片数据产生,有些品牌甚至超过80% ,图片数据是Social Listening不可或缺的监测和评估指标。
更真实:更加贴近真实的消费场景
消费者提及品牌,可以通过文字提及品牌的名字(文字声量),也可以通过发表包含品牌或产品的图片(图片声量),而两者所表达的内容却有不同。 文字声量 要求直接提及品牌名,大部分 受品牌主营销活动的影响,反应了消费者的直接品牌认知 。比如,文字声量的高频词可能是品牌代言人、品牌赞助综艺节目、线上推广活动、产品的参数属性等。
与之相比, 图片声量 往往是用户在真实消费场景下产生的,消费者在体验产品的时候,拍照上传,并表达他们的感受, 更加贴近用户的生活场景和感受 。
更丰富:文本数据从未拥有的洞察维度
Social Listening需要通过文本语义分析技术,对社交网络中的海量语料数据进行分析和挖掘,从而进行消费者和市场洞察。文本语料,需要用户在语言上经过雕琢才发布出来,往往反映了用户感知最强烈的一部分。比如,对品牌的印象、或者对产品体验的评价。然而,用户通常不会完整的表达, Who、When、Where、What ,而这恰恰是品牌主很希望知道的。通过图片数据的分析,对 图片内容进行结构化 ,能够还原图片中的上下文信息,比如,在什么时间、什么地点、跟谁在一起、正在做什么事情。对于消费品,通过图片数据可以研究消费场景、购物篮、伴随消费品等;对于网络游戏,通过玩家截图,可以研究战绩、对战、海报、角色等不同画面最吸引玩家的地方。
更可靠:解决数据清洗的世纪难题
在海量非结构化的社交数据中,存在着大量的“脏”数据,一直以来是Social Listening准确性的巨大障碍。1)文本数据存在 大量的歧义 ,例如“统一”、“亲亲”、“尖叫”,这些品牌名都存在着大量的歧义数据,即使运用最先进的语义消歧技术,往往也难以得到非常满意的结果;
2)消费者提及品牌名时,很容易出现 错别字 ,如”安(幕)希→安(慕)希“,通过文本关键词监测很难识别这部分数据;
3)社交网络上存在着大量的 “僵尸”和“水军” ,制造大量的垃圾信息,也使数据价值大打折扣。
图片数据天生具备消歧的能力,通过Logo识别就能够准确定位品牌图片声量;而且,由于图片垃圾信息的制造成本高,对于需要批量重复操作的水军,发图操作更复杂,一般的黑市会选择性价比更高的纯文字模式,使得图片数据的可靠性远高于文字数据。
Social Listening 2.0时代,图片数据必将扮演重要角色。今年,ImageDT已经将图片数据应用于品牌资产评估、产品口碑分析、产品包装创新、山寨品跟踪、公关舆情监测、用户画像等多个研究场景。“图片必将成为商业 大数据 的标配,所有的互联网数据监测、舆情、洞察和分析产品,都将具备读图的能力。ImageDT正在加速这一天的到来。” 本文来源:ImageDT
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2017-06-10 15:48:00
随着机器学习的兴起, Python 逐步成为了「最受欢迎」的语言。它简单易用、逻辑明确并拥有海量的扩展包,因此其不仅成为机器学习与数据科学的首选语言,同时在网页、数据爬取可科学研究等方面成为不二选择。此外,很多入门级的机器学习开发者都是跟随大流选择 Python,但到底为什么要选择 Python 就是本文的核心内容。
本教程的目的是让你相信两件事:首先,Python 是一种非常棒的 编程语言 ;其次,如果你是一名科学家,Python 很可能值得你去学习。本教程并非想要说明 Python 是一种万能的语言;相反,作者明确讨论了在几种情况下,Python 并不是一种明智的选择。本教程的目的只是提供对 Python 一些核心特征的评论,并阐述作为一种通用的科学计算语言,它比其他常用的替代方案(最著名的是 R 和 Matlab)更有优势。
本教程的其余部分假定你已经有了一些编程经验,如果你非常精通其他以数据为中心的语言(如 R 或 Matlab),理解本教程就会非常容易。本教程不能算作一份关于 Python 的介绍,且文章重点在于为什么应该学习 Python 而不是怎样写 Python 代码(尽管其他地方有大量的优秀教程)。
概述
Python 是一种广泛使用、易于学习、高级、通用的动态编程语言。这很令人满意,所以接下来分开讨论一些特征。
Python(相对来说)易于学习
编程很难,因此从绝对意义上来说,除非你已经拥有编程经验,否则编程语言难以学习。但是,相对而言,Python 的高级属性(见下一节)、语法可读性和语义直白性使得它比其他语言更容易学习。例如,这是一个简单 Python 函数的定义(故意未注释),它将一串英语单词转换为(crummy)Pig Latin:
def pig_latin(text):
”’ Takes in a sequence of words and converts it to (imperfect) pig latin. ”’
word_list = text.split(‘ ‘)
output_list = []
for word in word_list:
word = word.lower()
if word.isalpha():
first_char = word[0]
if first_char in ‘aeiou’:
word = word + ‘ay’
else:
word = word[1:] + first_char + ‘yay’
output_list.append(word)
pygged = ‘ ‘.join(output_list)
return pygged
以上函数事实上无法生成完全有效的 Pig Latin(假设存在「有效 Pig Latin」),但这没有关系。有些情况下它是可行的:
test1 = pig_latin(“let us see if this works”)
print(test1)
抛开 Pig Latin 不说,这里的重点只是,出于几个原因,代码是很容易阅读的。首先,代码是在高级抽象中编写的(下面将详细介绍),因此每行代码都会映射到一个相当直观的操作。这些操作可以是「取这个单词的第一个字符」,而不是映射到一个没那么直观的低级操作,例如「为一个字符预留一个字节的内存,稍后我会传入一个字符」。其次,控制结构(如,for—loops,if—then 条件等)使用诸如「in」,「and」和「not」的简单单词,其语义相对接近其自然英语含义。第三,Python 对缩进的严格控制强加了一种使代码可读的规范,同时防止了某些常见的错误。第四,Python 社区非常强调遵循样式规定和编写「Python 式的」代码,这意味着相比使用其他语言的程序员而言,Python 程序员更倾向于使用一致的命名规定、行的长度、编程习惯和其他许多类似特征,它们共同使别人的代码更易阅读(尽管这可以说是社区的一个特征而不是语言本身)。
Python 是一种高级语言
与其他许多语言相比,Python 是一种相对「高级」的语言:它不需要(并且在许多情况下,不允许)用户担心太多底层细节,而这是其他许多语言需要去处理的。例如,假设我们想创建一个名为「my_box_of_things」的变量当作我们所用东西的容器。我们事先不知道我们想在盒子中保留多少对象,同时我们希望在添加或删除对象时,对象数量可以自动增减。所以这个盒子需要占据一个可变的空间:在某个时间点,它可能包含 8 个对象(或「元素」),而在另一个时间点,它可能包含 257 个对象。在像 C 这样的底层语言中,这个简单的要求就已经给我们的程序带来了一些复杂性,因为我们需要提前声明盒子需要占据多少空间,然后每次我们想要增加盒子需要的空间时,我么需要明确创建一个占据更多空间的全新的盒子,然后将所有东西拷贝到其中。
相比之下,在 Python 中,尽管在底层这些过程或多或少会发生(效率较低),但我们在使用高级语言编写时并不需要担心这一部分。从我们的角度来看,我们可以创建自己的盒子并根据喜好添加或删除对象:
# Create a box (really, a ‘list’) with 5 things# Create
my_box_of_things = [‘Davenport’, ‘kettle drum’, ‘swallow-tail coat’, ‘table cloth’, ‘patent leather shoes’]
print(my_box_of_things)
[‘Davenport’, ‘kettle drum’, ‘swallow-tail coat’, ‘table cloth’, ‘patent leather shoes’]
# Add a few more things
my_box_of_things += [‘bathing suit’, ‘bowling ball’, ‘clarinet’, ‘ring’]
# Maybe add one last thing
my_box_of_things.append(‘radio that only needs a fuse’)
# Let’s see what we have…
print(my_box_of_things)
更一般来说,Python(以及根据定义的其他所有高级语言)倾向于隐藏需要在底层语言中明确表达的各种死记硬背的声明。这使得我们可以编写非常紧凑、清晰的代码(尽管它通常以降低性能为代价,因为内部不再可访问,因此优化变得更加困难)。
例如,考虑从文件中读取纯文本这样看似简单的行为。对于与文件系统直接接触而伤痕累累的开发者来说,从概念上看似乎只需要两个简单的操作就可以完成:首先打开一个文件,然后从其中读取。实际过程远不止这些,并且比 Python 更底层的语言通常强制(或至少是鼓励)我们去承认这一点。例如,这是在 Java 中从文件中读取内容的规范(尽管肯定不是最简洁的)方法:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile {
public static void main(String[] args) throws IOException{
String fileContents = readEntireFile(“./foo.txt”);
}
private static String readEntireFile(String filename) throws IOException {
FileReader in = new FileReader(filename);
StringBuilder contents = new StringBuilder();
char[] buffer = new char[4096];
int read = 0;
do {
contents.append(buffer, 0, read);
read = in.read(buffer);
} while (read >= 0);
return contents.toString();
}
}
你可以看到我们不得不做一些令人苦恼的事,例如导入文件读取器、为文件中的内容创建一个缓存,以块的形式读取文件块并将它们分配到缓存中等等。相比之下,在 Python 中,读取文件中的全部内容只需要如下代码:
# Read the contents of “hello_world.txt”
text = open(“hello_world.txt”).read()
当然,这种简洁性并不是 Python 独有的;还有其他许多高级语言同样隐藏了简单请求所暗含的大部分令人讨厌的内部过程(如,Ruby,R,Haskell 等)。但是,相对来说比较少有其他语言能与接下来探讨的 Python 特征相媲美。
Python 是一种通用语言
根据设计,Python 是一种通用的语言。也就是说,它旨在允许程序员在任何领域编写几乎所有类型的应用,而不是专注于一类特定的问题。在这方面,Python 可以与(相对)特定领域的语言进行对比,如 R 或 PHP。这些语言原则上可用于很多情形,但仍针对特定用例进行了明确优化(在这两个示例中,分别用于统计和网络后端开发)。
Python 通常被亲切地成为「所有事物的第二个最好的语言」,它很好地捕捉到了这样的情绪,尽管在很多情况下 Python 并不是用于特定问题的最佳语言,但它通常具有足够的灵活性和良好的支持性,使得人们仍然可以相对有效地解决问题。事实上,Python 可以有效地应用于许多不同的应用中,这使得学习 Python 成为一件相当有价值的事。因为作为一个软件开发人员,能够使用单一语言实现所有事情,而不是必须根据所执行的项目在不同语言和环境间进行切换,是一件非常棒的事。
标准库
通过浏览标准库中可用的众多模块列表,即 Python 解释器自带的工具集(没有安装第三方软件包),这可能是最容易理解 Python 通用性的方式。若考虑以下几个示例: os: 系统操作工具 re:正则表达 collections:有用的数据结构 multiprocessing:简单的并行化工具 pickle:简单的序列化 json:读和写 JSON argparse:命令行参数解析 functools:函数化编程工具 datetime:日期和时间函数 cProfile:分析代码的基本工具
这张列表乍一看并不令人印象深刻,但对于 Python 开发者来说,使用它们是一个相对常见的经历。很多时候用谷歌搜索一个看似重要甚至有点深奥的问题,我们很可能找到隐藏在标准库模块内的内置解决方案。
JSON,简单的方法
例如,假设你想从 web.JSON 中读取一些 JSON 数据,如下所示:
data_string = ”’
[
{
“_id”: “59ad8f86450c9ec2a4760fae”,
“name”: “Dyer Kirby”,
“registered”: “2016-11-28T03:41:29 +08:00”,
“latitude”: -67.170365,
“longitude”: 130.932548,
“favoriteFruit”: “durian”
},
{
“_id”: “59ad8f8670df8b164021818d”,
“name”: “Kelly Dean”,
“registered”: “2016-12-01T09:39:35 +08:00”,
“latitude”: -82.227537,
“longitude”: -175.053135,
“favoriteFruit”: “durian”
}
]
”’
我们可以花一些时间自己编写 json 解析器,或试着去找一个有效读取 json 的第三方包。但我们很可能是在浪费时间,因为 Python 内置的 json 模块已经能完全满足我们的需要:
import json
data = json.loads(data_string)
print(data)
”’
[{‘_id’: ’59ad8f86450c9ec2a4760fae’, ‘name’: ‘Dyer Kirby’, ‘registered’: ‘2016-11-28T03:41:29 +08:00’, ‘latitude’: -67.170365, ‘longitude’: 130.932548, ‘favoriteFruit’: ‘durian’}, {‘_id’: ’59ad8f8670df8b164021818d’, ‘name’: ‘Kelly Dean’, ‘registered’: ‘2016-12-01T09:39:35 +08:00’, ‘latitude’: -82.227537, ‘longitude’: -175.053135, ‘favoriteFruit’: ‘durian’}]
请注意,在我们能于 json 模块内使用 loads 函数前,我们必须导入 json 模块。这种必须将几乎所有功能模块明确地导入命名空间的模式在 Python 中相当重要,且基本命名空间中可用的内置函数列表非常有限。许多用过 R 或 Matlab 的开发者会在刚接触时感到恼火,因为这两个包的全局命名空间包含数百甚至上千的内置函数。但是,一旦你习惯于输入一些额外字符,它就会使代码更易于读取和管理,同时命名冲突的风险(R 语言中经常出现)被大大降低。
优异的外部支持
当然,Python 提供大量内置工具来执行大量操作并不意味着总需要去使用这些工具。可以说比 Python 丰富的标准库更大的卖点是庞大的 Python 开发者社区。多年来,Python 一直是世界上最流行的动态编程语言,开发者社区也贡献了众多高质量的安装包。
如下 Python 软件包在不同领域内提供了被广泛使用的解决方案(这个列表在你阅读本文的时候可能已经过时了!): Web 和 API 开发:flask,Django,Falcon,hug 爬取数据和解析文本/标记: requests,beautifulsoup,scrapy 自然语言处理(NLP):nltk,gensim,textblob 数值计算和 数据分析 :numpy,scipy,pandas,xarray 机器学习:scikit-learn,Theano,Tensorflow,keras 图像处理:pillow,scikit-image,OpenCV 作图:matplotlib,seaborn,ggplot,Bokeh 等等
Python 的一个优点是有出色的软件包管理生态系统。虽然在 Python 中安装包通常比在 R 或 Matlab 中更难,这主要是因为 Python 包往往具有高度的模块化和/或更多依赖于系统库。但原则上至少大多数 Python 的包可以使用 pip 包管理器通过命令提示符安装。更复杂的安装程序和包管理器,如 Anaconda 也大大减少了配置新 Python 环境时产生的痛苦。
Python 是一种(相对)快速的语言
这可能令人有点惊讶:从表面上看,Python 是一种快速语言的说法看起来很愚蠢。因为在标准测试时,和 C 或 Java 这样的编译语言相比,Python 通常会卡顿。毫无疑问,如果速度至关重要(例如,你正在编写 3D 图形引擎或运行大规模的流体动力学模拟实验),Python 可能不会成为你最优选择的语言,甚至不会是第二好的语言。但在实际中,许多科学家工作流程中的限制因素不是运行时间而是开发时间。一个花费一个小时运行但只需要 5 分钟编写的脚本通常比一个花费 5 秒钟运行但是需要一个礼拜编写和调试的脚本更合意。此外,正如我们将在下面看到的,即使我们所用的代码都用 Python 编写,一些优化操作通常可以使其运行速度几乎与基于 C 的解决方案一样快。实际上,对大多数科学家家来说,基于 Python 的解决方案不够快的情况并不是很多,而且随着工具的改进,这种情况的数量正在急剧减少。
不要重复做功
软件开发的一般原则是应该尽可能避免做重复工作。当然,有时候是没法避免的,并且在很多情况下,为问题编写自己的解决方案或创建一个全新的工具是有意义的。但一般来说,你自己编写的 Python 代码越少,性能就越好。有以下几个原因: Python 是一种成熟的语言,所以许多现有的包有大量的用户基础并且经过大量优化。例如,对 Python 中大多数核心科学库(numpy,scipy,pandas 等)来说都是如此。 大多数 Python 包实际上是用 C 语言编写的,而不是用 Python 编写的。对于大多数标准库,当你调用一个 Python 函数时,实际上很大可能你是在运行具有 Python 接口的 C 代码。这意味着无论你解决问题的算法有多精妙,如果你完全用 Python 编写,而内置的解决方案是用 C 语言编写的,那你的性能可能不如内置的方案。例如,以下是运行内置的 sum 函数(用 C 编写):
# Create a list of random floats
import random
my_list = [random.random() for i in range(10000)]
# Python’s built-in sum() function is pretty fast
%timeit sum(my_list)
47.7 µs ± 4.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
从算法上来说,你没有太多办法来加速任意数值列表的加和计算。所以你可能会想这是什么鬼,你也许可以用 Python 自己写加和函数,也许这样可以封装内置 sum 函数的开销,以防它进行任何内部验证。嗯……并非如此。
def ill_write_my_own_sum_thank_you_very_much(l):
s = 0
for elem in my_list:
s += elem
return s
%timeit ill_write_my_own_sum_thank_you_very_much(my_list)
331 µs ± 50.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
至少在这个例子中,运行你自己简单的代码很可能不是一个好的解决方案。但这不意味着你必须使用内置 sum 函数作为 Python 中的性能上限!由于 Python 没有针对涉及大型输入的数值运算进行优化,因此内置方法在加和大型列表时是表现次优。在这种情况下我们应该做的是提问:「是否有其他一些 Python 库可用于对潜在的大型输入进行数值分析?」正如你可能想的那样,答案是肯定的:NumPy 包是 Python 的科学生态系统中的主要成分,Python 中的绝大多数科学计算包都以某种方式构建在 NumPy 上,它包含各种能帮助我们的计算函数。
在这种情况下,新的解决方案是非常简单的:如果我们将纯 Python 列表转化为 NumPy 数组,我们就可以立即调用 NumPy 的 sum 方法,我们可能期望它应该比核心的 Python 实现更快(技术上讲,我们可以传入一个 Python 列表到 numpy.sum 中,它会隐式地将其转换为数组,但如果我们打算复用该 NumPy 数组,最好明确地转化它)。
import numpy as np
my_arr = np.array(my_list)
%timeit np.sum(my_arr)
7.92 µs ± 1.15 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
因此简单地切换到 NumPy 可加快一个数量级的列表加和速度,而不需要自己去实现任何东西。
需要更快的速度?
当然,有时候即使使用所有基于 C 的扩展包和高度优化的实现,你现有的 Python 代码也无法快速削减时间。在这种情况下,你的下意识反应可能是放弃并转化到一个「真正」的语言。并且通常,这是一种完全合理的本能。但是在你开始使用 C 或 Java 移植代码前,你需要考虑一些不那么费力的方法。
使用 Python 编写 C 代码
首先,你可以尝试编写 Cython 代码。Cython 是 Python 的一个超集(superset),它允许你将(某些)C 代码直接嵌入到 Python 代码中。Cython 不以编译的方式运行,相反你的 Python 文件(或其中特定的某部分)将在运行前被编译为 C 代码。实际的结果是你可以继续编写看起来几乎完全和 Python 一样的代码,但仍然可以从 C 代码的合理引入中获得性能提升。特别是简单地提供 C 类型的声明通常可以显著提高性能。
以下是我们简单加和代码的 Cython 版本:
# Jupyter extension that allows us to run Cython cell magics
%load_ext Cython
The Cython extension is already loaded. To reload it, use:
%reload_ext Cython
%%%%cythoncython
defdef ill_write_my_own_cython_sum_thank_you_very_muchill_write (list arr):
cdef int N = len(arr)
cdef float x = arr[0]
cdef int i
for i in range(1 ,N):
x += arr[i]
return x
%timeit ill_write_my_own_cython_sum_thank_you_very_much(my_list)
227 µs ± 48.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
关于 Cython 版本有几点需要注意一下。首先,在你第一次执行定义该方法的单元时,需要很少的(但值得注意的)时间来编译。那是因为,与纯粹的 Python 不同,代码在执行时不是逐行解译的;相反,Cython 式的函数必须先编译成 C 代码才能调用。
其次,虽然 Cython 式的加和函数比我们上面写的简单的 Python 加和函数要快,但仍然比内置求和方法和 NumPy 实现慢得多。然而,这个结果更有力地说明了我们特定的实现过程和问题的本质,而不是 Cython 的一般好处;在许多情况下,一个有效的 Cython 实现可以轻易地将运行时间提升一到两个数量级。
使用 NUMBA 进行清理
Cython 并不是提升 Python 内部性能的唯一方法。从开发的角度来看,另一种更简单的方法是依赖于即时编译,其中一段 Python 代码在第一次调用时被编译成优化的 C 代码。近年来,在 Python 即时编译器上取得了很大进展。也许最成熟的实现可以在 numba 包中找到,它提供了一个简单的 jit 修饰器,可以轻易地结合其他任何方法。
我们之前的示例并没有强调 JITs 可以产生多大的影响,所以我们转向一个稍微复杂点的问题。这里我们定义一个被称为 multiply_randomly 的新函数,它将一个一维浮点数数组作为输入,并将数组中的每个元素与其他任意一个随机选择的元素相乘。然后它返回所有随机相乘的元素和。
让我们从定义一个简单的实现开始,我们甚至都不采用向量化来代替随机相乘操作。相反,我们简单地遍历数组中的每个元素,从中随机挑选一个其他元素,将两个元素相乘并将结果分配给一个特定的索引。如果我们用基准问题测试这个函数,我们会发现它运行得相当慢。
import numpy as np
def multiply_randomly_naive(l):
n = l.shape[0]
result = np.zeros(shape=n)
for i in range(n):
ind = np.random.randint(0, n)
result[i] = l[i] * l[ind]
return np.sum(result)
%timeit multiply_randomly_naive(my_arr)
25.7 ms ± 4.61 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
在我们即时编译之前,我们应该首先自问是否上述函数可以用更加符合 NumPy 形式的方法编写。NumPy 针对基于数组的操作进行了优化,因此应该不惜一切代价地避免使用循环操作,因为它们会非常慢。幸运的是,我们的代码非常容易向量化(并且易于阅读):
def multiply_randomly_vectorized(l):
n = len(l)
inds = np.random.randint(0, n, size=n)
result = l * l[inds]
return np.sum(result)
%timeit multiply_randomly_vectorized(my_arr)
234 µs ± 50.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
在作者的机器上,向量化版本的运行速度比循环版本的代码快大约 100 倍。循环和数组操作之间的这种性能差异对于 NumPy 来说是非常典型的,因此我们要在算法上思考你所做的事的重要性。
假设我们不是花时间重构我们朴素的、缓慢的实现,而是简单地在我们的函数上加一个修饰器去告诉 numba 库我们要在第一次调用它时将函数编译为 C。字面上,下面的函数 multiply_randomly_naive_jit 与上面定义的函数 multiply_randomly_naive 之间的唯一区别是 @jit 修饰器。当然,4 个小字符是没法造成那么大的差异的。对吧?
import numpy as np
from numba import jit
@jit
def multiply_randomly_naive_jit(l):
n = l.shape[0]
result = np.zeros(shape=n)
for i in range(n):
ind = np.random.randint(0, n)
result[i] = l[i] * l[ind]
return np.sum(result)
%timeit multiply_randomly_naive_jit(my_arr)
135 µs ± 22.4 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
令人惊讶的是,JIT 编译版本的朴素函数事实上比向量化的版本跑得更快。
有趣的是,将 @jit 修饰器应用于函数的向量化版本(将其作为联系留给读者)并不能提供更多帮助。在 numba JIT 编译器用于我们的代码之后,Python 实现的两个版本都以同样的速度运行。因此,至少在这个例子中,即时编译不仅可以毫不费力地为我们提供类似 C 的速度,而且可以避免以 Python 式地去优化代码。
这可能是一个相当有力的结论,因为(a)现在 numba 的 JIT 编译器只覆盖了 NumPy 特征的一部分,(b)不能保证编译的代码一定比解译的代码运行地更快(尽管这通常是一个有效的假设)。这个例子真正的目的是提醒你,在你宣称它慢到无法去实现你想要做的事之前,其实你在 Python 中有许多可用的选择。值得注意的是,如 C 集成和即时编译,这些性能特征都不是 Python 独有的。Matlab 最近的版本自动使用即时编译,同时 R 支持 JIT 编译(通过外部库)和 C ++ 集成(Rcpp)。
Python 是天生面向对象的
即使你正在做的只是编写一些简短的脚本去解析文本或挖掘一些数据,Python 的许多好处也很容易领会到。在你开始编写相对大型的代码片段前,Python 的最佳功能之一可能并不明显:Python 具有设计非常优雅的基于对象的数据模型。事实上,如果你查看底层,你会发现 Python 中的一切都是对象。甚至函数也是对象。当你调用一个函数的时候,你事实上正在调用 Python 中每个对象都运行的, age=”62″, status=”hanging out in a jar”)
print(brain.owner)
—————————————————————————
sue
print(brain.gender)
—————————————————————————
AttributeError Traceback (most recent call last)
in ()
—-> 1 print(brain.gender)
in __getattr__(self, attr)
12 if hasattr(self, attr_name):
13 return lambda: getattr(self, attr_name)
—> 14 raise AttributeError
AttributeError:
重要的是,我们不用忍受这种行为。假设我们想创建一个替代接口用于通过以「get」开头的 getter 方法从 Brain 类的内部检索数据(这是许多其他语言中的常见做法),我们当然可以通过名字(如 get_owner、get_age 等)显式地实现 getter 方法。但假设我们很懒,并且不想为每个属性编写一个显式的 getter。此外,我们可能想要为已经创建的 Brains 类添加新的属性(如,brain.foo = 4),在这种情况下,我们不需要提前为那些未知属性创建 getter 方法(请注意,在现实世界中,这些是为什么我们接下来要这么做的可怕理由;当然这里完全是为了举例说明)。我们可以做的是,当用户请求任意属性时,通过指示 Brain 类的操作去改变它的行为。
在上面的代码片段中,我们的 __getattr__ 实现首先检查了传入属性的名称。如果名称以 get_ 开头,我们将检查对象内是否存在期望属性的名称。如果确实存在,则返回该对象。否则,我们会引发错误的默认操作。这让我们可以做一些看似疯狂的事,比如:
print(brain.get_owner())
其他不可思议的方法允许你动态地控制对象行为的其他各种方面,而这在其他许多语言中你没法做到。事实上,因为 Python 中的一切都是对象,甚至数学运算符实际上也是对对象的秘密方法调用。例如,当你用 Python 编写表达式 4 + 5 时,你实际上是在整数对象 4 上调用 __add__,其参数为 5。如果我们愿意(并且我们应该小心谨慎地行使这项权利!),我们能做的是创建新的特定领域的「迷你语言」,为通用运算符注入全新的语义。
举个简单的例子,我们来实现一个表示单一 Nifti 容积的新类。我们将依靠继承来实现大部分工作;只需从 nibabel 包中继承 NiftierImage 类。我们要做的就是定义 __and__ 和 __or__ 方法,它们分别映射到 & 和 | 运算符。看看在执行以下几个单元前你是否搞懂了这段代码的作用(可能你需要安装一些包,如 nibabel 和 nilearn)。
from nibabel import Nifti1Image
from nilearn.image import new_img_like
from nilearn.plotting import plot_stat_map
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
class LazyMask(Nifti1Image):
”’ A wrapper for the Nifti1Image class that overloads the & and | operators
to do logical conjunction and disjunction on the image data. ”’
def __and__(self, other):
if self.shape != other.shape:
raise ValueError(“Mismatch in image dimensions: %s vs. %s” % (self.shape, other.shape))
data = np.logical_and(self.get_data(), other.get_data())
return new_img_like(self, data, self.affine)
def __or__(self, other):
if self.shape != other.shape:
raise ValueError(“Mismatch in image dimensions: %s vs. %s” % (self.shape, other.shape))
data = np.logical_or(self.get_data(), other.get_data())
return new_img_like(self, data, self.affine)
img1 = LazyMask.load(‘image1.nii.gz’)
img2 = LazyMask.load(‘image2.nii.gz’)
result = img1 & img2
fig, axes = plt.subplots(3, 1, figsize=(15, 6))
p = plot_stat_map(img1, cut_coords=12, display_mode=’z’, title=’Image 1′, axes=axes[0], vmax=3)
plot_stat_map(img2, cut_coords=p.cut_coords, display_mode=’z’, title=’Image 2′, axes=axes[1], vmax=3)
p = plot_stat_map(result, cut_coords=p.cut_coords, display_mode=’z’, title=’Result’, axes=axes[2], vmax=3)
Python 社区
我在这里提到的 Python 的最后一个特征就是它优秀的社区。当然,每种主要的编程语言都有一个大型的社区致力于该语言的开发、应用和推广;关键是社区内的人是谁。一般来说,围绕编程语言的社区更能反映用户的兴趣和专业基础。对于像 R 和 Matlab 这样相对特定领域的语言来说,这意味着为语言贡献新工具的人中很大一部分不是软件开发人员,更可能是统计学家、工程师和科学家等等。当然,统计学家和工程师没什么不好。例如,与其他语言相比,统计学家较多的 R 生态系统的优势之一就是 R 具有一系列统计软件包。
然而,由统计或科学背景用户所主导的社区存在缺点,即这些用户通常未受过软件开发方面的训练。因此,他们编写的代码质量往往比较低(从软件的角度看)。专业的软件工程师普遍采用的最佳实践和习惯在这种未经培训的社区中并不出众。例如,CRAN 提供的许多 R 包缺少类似自动化测试的东西——除了最小的 Python 软件包之外,这几乎是闻所未闻的。另外在风格上,R 和 Matlab 程序员编写的代码往往在人与人之间的一致性方面要低一些。结果是,在其他条件相同的情况下,用 Python 编写软件往往比用 R 编写的代码具备更高的稳健性。虽然 Python 的这种优势无疑与语言本身的内在特征无关(一个人可以使用任何语言(包括 R、Matlab 等)编写出极高质量的代码),但仍然存在这样的情况,强调共同惯例和最佳实践规范的开发人员社区往往会使大家编写出更清晰、更规范、更高质量的代码。
结论
Python 太棒了。 出处:机器之心 链接:https://www.toutiao.com/item/6586551141515919885/
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2018-08-05 21:29:00
如果你发觉自己在编程时一次又一次地查找相同的问题、概念或是语法,你不是一个人!
虽然我们在StackOverflow或其他网站上查找答案是很正常的事情,但这样做确实比较花时间,也让人怀疑你是否完全理解了这门编程语言。
我们现在生活的世界里,似乎有着无限的免费资源,而你只需要一次搜索即可获得。然而,这既是这个时代的幸事,也是一种诅咒。如果没能有效利用资源,而是对它们过度依赖,你就会养成不良的习惯,长期处于不利境地。
当我谷歌一个问题,发现有人提了同样问题,但下面只有一个回答,而且2003年以后就再也没有新的答案的时候,我真是和那个提问者同病相怜!弱小,可怜又无助!
“你是谁!你在哪儿!最后你发现了啥!”
就个人而言,我发现自己也是多次从类似的技术问答中找代码(见上文插图漫画);而不是花时间学习和巩固概念,以便下次可以自己把代码写出来。
网上搜索答案是一种懒惰的行为,虽然在短期内它可能是最简便的途径,但它终究不利于你的成长,并且会降低工作效率和对语法的熟知能力(咳咳,面试的时候这些知识很重要)。
目标
最近,我一直在Udemy学习名为 Python for Data Science and Machine Learning 的 数据科学 在线课程。在该系列课程的早期课件中,我想起了用Python做 数据分析 时一直被我忽略的一些概念和语法。
为了一劳永逸地巩固我对这些概念的理解,并为大家免去一些StackOverflow的搜索,我在文章中整理了自己在使用Python,NumPy和Pandas时总是忘记的东西。
我为每个要点提供了简短的描述和示例。为了给读者带来福利,我还添加了视频和其他资源的链接,以便大家更深入地了解各个概念。
单行List Comprehension
每次需要定义某种列表时都要写for循环是很乏味的,好在Python有一种内置的方法可以用一行代码解决这个问题。该语法可能有点难以理解,但是一旦熟悉了这种技巧,你就会经常使用它。
* Line 8是对for loop的单行简化
请参阅上图和下文的示例,比较一下在创建列表时,你通常使用的for循环样板和以单行代码创建这二者之间的差别。
x = [1,2,3,4] out = [] for item in x:    out.append(item**2) print(out) [1, 4, 9, 16] # vs. x = [1,2,3,4] out = [item**2 for item in x] print(out) [1, 4, 9, 16]
Lambda 函数
编程的过程中经常为了实现最后的功能,创建一个又一个阶段性的函数,这些函数往往就只用一两次。这个过程很烦人。这时候Lambda函数来搭救你了!
Lambda函数用于在Python中创建小型的,一次性的和匿名的函数对象。基本上,它们可以让你“在不创建新函数的情况下”创建一个函数。
lambda函数的基本语法如下:
lambda arguments: expression
所以,只要给它一个表达式,lambda函数可以执行所有常规函数可执行的操作。请看下面的简单示例和后文中的视频,以更好地感受lambda函数强大的功能。
double = lambda x: x * 2 print(double(5)) 10
Map和Filter
一旦掌握了lambda函数,并学会将它们与map和filter函数配合使用,你将拥有一个强大的工具。
具体来说,map函数接受一个列表并通过对每个元素执行某种操作来将其转换为新列表。在下面的示例中,它遍历每个元素并将其乘以2的结果 映射 到新列表。请注意,这里的list函数只是将输出转换为列表类型。
# Map seq = [1, 2, 3, 4, 5] result = list(map(lambda var: var*2, seq)) print(result) [2, 4, 6, 8, 10]
filter函数需要的输入是列表和规则,非常类似于map,但它通过将每个元素与布尔过滤规则进行比较来返回原始列表的子集。
# Filter seq = [1, 2, 3, 4, 5] result = list(filter(lambda x: x > 2, seq)) print(result) [3, 4, 5]
Arange和Linspace
要创建快速简单的NumPy数组,可以查看arange和linspace函数。它们都有特定的用途,但在这里我们看中的是它们都输出Numpy数组(而非其使用范围),这通常更容易用于数据科学。
Arange在给定的范围内返回间隔均匀的值。除了起始值和终止值,你还可以根据需要定义步长或数据类型。请注意,终止值是一个“截止”值,因此它不会被包含在数组输出中。
# np.arange(start, stop, step) np.arange(3, 7, 2) array([3, 5])
Linspace与Arange非常相似,但略有不同。Linspace是在指定的范围内返回指定个数的间隔均匀的数字。所以给定一个起始值和终止值,并指定返回值的个数,linspace将根据你指定的个数在NumPy数组中划好等分。这对于 数据可视化 和在定义图表坐标轴时特别有用。
# np.linspace(start, stop, num) np.linspace(2.0, 3.0, num=5) array([ 2.0,  2.25,  2.5,  2.75, 3.0])
Axis的真正意义
在Pandas中删除列或在NumPy矩阵中对值进行求和时,可能会遇到这问题。即使没有,那么你也肯定会在将来的某个时候碰到。我们现在来看看删除列的示例:
df.drop(‘Row A’, axis=0) df.drop(‘Column A’, axis=1)
在我知道自己为什么要这样定义坐标轴之前,我不知道我写了多少次这行代码。你可以从上面看出,如果要处理列,就将axis设为1,如果要处理行,则将其设为0。
但为什么会这样呢?我记得我最喜欢的解释是这个:
df.shape (# of Rows, # of Columns)
从Pandas的dataframe调用shape属性时会返回一个元组,其中第一个值表示行数,第二个值表示列数。如果你想想在Python中是如何建立索引的,即行为0,列为1,会发现这与我们定义坐标轴值的方式非常相似。很有趣吧!
Concat, Merge, 和Join
如果你熟悉SQL,那么这些概念对你来说可能会更容易。无论如何,这些功能基本上就是以特定方式组合dataframe的方法。可能很难评判在什么时候使用哪个最好,所以让我们都回顾一下。
Concat允许用户在其下方或旁边附加一个或多个dataframe(取决于你如何定义轴)。
Merge可以基于特定的、共有的主键(Primary Key)组合多个dataframe。
Join,就像merge一样,可以组合两个dataframe。但是,它根据它们的索引进行组合,而不是某些特定的主键。
大家可以查看很有帮助的Pandas文档,了解语法和具体示例和你可能会遇到的特殊情况。
Pandas Apply
apply类似于map函数,不过它是用于Pandas DataFrames的,或者更具体地说是用于Series的。如果你不熟悉也没关系,Series在很大程度上与NumPy中的阵列(array)非常相似。
Apply会根据你指定的内容向列或行中的每个元素发送一个函数。你可以想象这是多么有用,特别是在对整个DataFrame的列处理格式或运算数值的时候,可以省去循环。
透视表
最后要说到的是透视表。如果你熟悉Microsoft Excel,那么你可能已经听说过数据透视表。Pandas内置的pivot_table函数将电子表格样式的数据透视表创建为DataFrame。请注意,透视表中的维度存储在MultiIndex对象中,用来声明DataFrame的index和columns。
结语
我的这些Python编程小贴士就到此为止啦。我希望我介绍的这些在使用Python做数据科学时经常遇到的重要但又有点棘手的方法、函数和概念能给你带来帮助。
而我自己在整理这些内容并试图用简单的术语来阐述它们的过程中也受益良多。
相关报道:
https://towardsdatascience.com/python-for-data-science-8-concepts-you-may-have-forgotten-i-did-825966908393
本文为专栏文章,来自:大数据文摘,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/58922.html 。
数据分析
2018-08-04 21:11:00
在数据科学与网络技术的各项技能中,大家对 爬虫 的兴趣要大于其他技能。无论学术研究还是 商业分析 ,数据搜集永远是第一个需要解决的问题。通常来说,一般的数据可以从国家和地方统计局、统计年鉴、单位年报中找到,但对于特定领域的 数据分析 与挖掘工作,所需要的数据可能并不是简单的搜索就可以获取的。这时就需要学习网络数据采集技术了,也就是网络爬虫。很多读者已经习惯使用R作为数据分析工具了,如果 R语言 能够像Python一样具备强大的爬虫生态,那就完美了。
尽管R具有开源、扩展包丰富、好学易上手等特点,但R的爬虫生态不如Python却是不争的事实。Python中的scrapy框架就足以让人满心欢喜,但R还没有比较流行的爬虫框架。尽管如此,如果结合R现有的爬虫条件,多加探索,还是可以解决当前大部分的爬虫需求的。
下面介绍爬虫技术的第一个基础知识: HTML 。作为网络前端技术最核心的三大技术之一(HTML、CSS和JavaScript),HTML的重要性不言而喻。如果说前端开发过程是一个造房子的过程,那么HTML就是这所房子的骨架结构,从地基到天花板都需要结构明晰;而房子造好后的装修则是CSS,比如说给地板贴瓷砖、给墙壁贴墙纸等。进一步,给房子加上更多的动态以及视觉效果,比如灯照变化、音乐渲染等功能,这主要就是JavaScript做的事情。
图1 前端技术三驾马车
那么到底什么是HTML呢?它跟R语言爬虫又有什么关系呢?HTML的全称是 超文本标记语言 (Hyper Text Markup Language),是一种用于在网页上展示内容的语言。HTML并不是一种编程语言,而是一种 描述内容并定义其表征的标记语言 。HTML只规定了网页的结构,让网页在哪里显示标题和内容,显示什么内容,至于怎么显示,就不是HTML管辖的范围了。
HTML的语法规则
1
在爬取数据之前,需要先了解HTML的语法规则,才能够“对症下药”。在任意一款浏览器中,随手打开一个网页,单击鼠标右键查看源文件或者审查元素,当前网页的HTML代码就出现了。下面以电影《芳华》为例,展示一下HTML的基本原理。
图2 《芳华》海报
在豆瓣电影上查看《芳华》页面的HTML源码,对比网页页面元素和HTML源码的对应关系。图3展示的是芳华在豆瓣电影上介绍的HTML代码一部分。
图3 豆瓣电影关于《芳华》介绍的HTML源码
图3就是单击鼠标右键审查元素之后的界面,可以看到在网页端显示的“冯小刚”在HTML中对应的位置,嵌套在层层在HTML代码之中(此处结果使用谷歌chrome浏览器展示)。
所以一个专门抓取导演信息的爬虫要做的事情很简单,就是找到“冯小刚”所嵌套的位置,然后把他请出来。下面来简单学习HTML的语法结构。
相较于编程语言的语法,HTML的语法堪称简单易懂又好学。简单而言,从内容上看,HTML是标签、元素和属性的组合;从结构上看,HTML是一个树形组织结构。了解了这些,再稍微注意一下HTML的注释方式、保留字符和文档定义,就掌握了HTML的知识概貌。下面从内容和结构上分别具体说明一下。
1.标签、元素和属性
HTML中的标签可以理解为一种标题,在实际语法中标签通常以一对“< >”符号包括起来,起始标签、内容和终止标签组合起来则成为元素,如图4所示的代码。
图4 HTML元素
起始标签和终止标签都用“< >”符号包裹,以便和内容进行区分,不同的是终止标签会有一个“/”符号以示区别。大部分标签都成对出现,但也有例外,比如说
标签表示换行,它就不需要一个
标签来表示终止。
常用的HTML标签如表1所示(更多标签请参考HTML手册http://www.w3school.com.cn/tags/)。
表1 常用HTML标签
标签最重要的一个特性是属性。继续看图4所示的代码:标签能够把相关的文本(这里是“冯小刚”)和一个指向另一个地址的超链接关联起来。href=”/celebrity/1274255/”这个属性指定链接,浏览器会自动把这类元素转化为带有下划线并且可以点击的样式,而rel=”v:directedBy”这个属性则是用于指定当前文档与被链接文档的关系。总而言之,属性就是让标签能够描述其内容处理方式的选项。具体属性的作用则根据相应的标签来定。
属性总是处于起始标签的内部、标签名的右侧。一个标签拥有多个属性也是常见操作,多个属性之间用空格分开(见图5)。
图5 标签的属性
2. 树形结构
就像文档结构图(图6)一样,HTML最大的特点就是呈现为树形结构。
图6 文档结构图
一个简单的HTML结构示例如图7所示。
图7 HTML的树形结构
图7中,第一个元素是
元素,在这个元素的起始和终止标签内,又有几个标签分别起始和终止:
标签作为同级标签都被包含在
元素内,标签则包含在
标签内。一个典型的树形结构就这样被描述出来了。
在结构良好并且合法的HTML文件中,所有元素相互之间必须是严格嵌套的,即一对起始标签和终止标签必须完全包含在另一对起始和终止标签内,像数学算式中的层层括号一样。
HTML除了以上这些基本知识,还有一些包括注释、保留字符和特殊字符、文档定义类型等其他细节知识值得注意,这里不再一一罗列。
R语言中HTML的解析
2
熟悉了基本的HTML结构之后,下面来看在R语言中HTML该如何解析。对于HTML,R语言无法直接分析,而是需要通过转化,这个过程就是HTML解析。具体而言,为了将HTML文件转为结构化数据,需运用一个能够理解HTML结构含义的程序,并重建HTML文件隐含的层次结构,使得HTML内容转化为R语言可以分析的形式。在R语言中,通常使用XML包中的htmlParse()函数来解析一个HTML文件,XML有着以C语言为基础的libxml2库的接口,功能十分强大。下面展示一个简单的R代码示例:
通过以上代码,一个完整的HTML文档就被解析到R中了。解析后,HTML文件被转化为R语言中的一个对象。 HTML作为所有网络爬虫的起步知识,对于后面的爬虫理解和操作具有基础性的意义。虽然数据科学不是前端开发,但是掌握基本的网页知识是非常有必要的。
本文由 狗熊会 投稿至 数据分析网 并经编辑发表,内容观点不代表本站立场,如转载请联系原作者,本文链接:https://www.afenxi.com/58509.html 。
首先,什么是 Python ?根据 Python 创建者 Guido van Rossum 所言,Python 是一个:高级 编程语言 ,其设计的核心理念是代码的易读性,以及允许编程者通过若干行代码轻松表达想法创意。实际上,我选择学习 Python 的首要原因是其编程的优美性,用它编码和表达想法非常自然。
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。
另一个原因是 Python 的编写使用方式有多种,数据科学、网页开发、 机器学习 皆可使用 Python。Quora、Pinterest 和 Spotify 都使用 Python 作为其后端开发语言。
基础篇
变量
简单来讲,我们可以把变量看作是存储一个值的词。
在 Python 中定义一个变量并为其赋值非常简单。想象一下你在变量「one」中存储 1,即是: one = 1
这是多么简单,我们只要把 1 赋值给变量「one」。 two = 2some_number = 10000
并且你可以把任意值赋给任意变量。如上所见,把整数 2 赋值给变量「two」,把 10,000 赋值给变量「some_number」。除了整数,我们也可以赋值布尔运算、字符串、浮点数以及其他数据形式。 # booleanstrue_boolean = Truefalse_boolean = False # stringmy_name = "Leandro Tk" # floatbook_price = 15.80
控制流:条件语句
「If」语句通过表达式评估一个语句是真或假。如果是真,则向下执行「If」条件中的子语句。比如: if True: print("Hello Python If")if 2 > 1: print("2 is greater than 1")
2 比 1 大,因此「print」代码被执行。如果「If」表达式是假的,则「else」下的子语句将被执行。 if 1 > 2: print("1 is greater than 2")else: print("1 is not greater than 2")
你也可以使用一个「elif」语句以添加一个执行条件。 if 1 > 2: print("1 is greater than 2")elif 2 > 1: print("1 is not greater than 2")else: print("1 is equal to 2")
循环/迭代器
在 Python 中,我们可有不同形式的迭代。我将讨论两个:while 与 for。
While 循环:当该语句为真,以下代码将被执行,并打印从 1 到 10 的数字。 num = 1 while num <= 10: print(num) num += 1
While 循环需要一个「循环条件」。如果它为真,则继续迭代。在以上实例中,当 num 为 11,则循环条件为假,我们结束循环。
以下代码有助于更好地理解它: loop_condition = True while loop_condition: print("Loop Condition keeps: %s" %(loop_condition)) loop_condition = False
循环条件为真,则继续迭代,直到它为假。对于 For 循环:你可以把变量「num」应用需要循环的代码块中,而「for」语句会为你迭代它。该代码的打印与 while 代码相同:从 1 到 10。 for i in range(1, 11): print(i)
看,如此简单。范围从 1 直到第 11 个元素(10 是第 10 个元素)。此外,如果我们直接确定一个数,那么 For 循环将从零开始一直迭代到该数字(不包括)。例如以下 For 循环将输出 0 到 9:
for i in range(10):
print(i)
列表:数组数据结构
列表是一个数组或集合,它可用于存储一系列值(比如那些你想要的整数)。因此让我们用一下它: my_integers = [1, 2, 3, 4, 5]
如上我们创建了一个数组并赋值到 my_integers 变量中。而我们可以通过索引取该数组中的值,如下所示,数组第一个元素的索引为 0,第二个元素的索引为 1,依次类推。
使用以下语句可能更好理解: my_integers = [5, 7, 1, 3, 4]print(my_integers[0]) # 5print(my_integers[1]) # 7print(my_integers[4]) # 4
同样我们列表元素的类型也可以是字符型,如下我们创建了一个元素为字符的列表: relatives_names = [ "Toshiaki", "Juliana", "Yuji", "Bruno", "Kaio"]print(relatives_names[4]) # Kaio
以上我们了解了列表的定义和索引使用方法,以下我们将了解如何添加一个元素到列表数据结构中。添加元素到列表最常见的方法是 append: bookshelf = []bookshelf.append("The Effective Engineer")bookshelf.append("The 4 Hour Work Week")print(bookshelf[0]) # The Effective Engineerprint(bookshelf[1]) # The 4 Hour Work Week
append 方法非常简单,我们只需要对需要添加的元素应用该方法就能将其添加到列表的末尾。
字典:键-值数据结构
我们已经知道列表是通过整数索引来获取某个元素,而若我们不希望使用整数作为索引,那么就可以使用字典数据结构。通过这种数据结构,我们可以使用数值型、字符型或其它类型的索引。字典的每个键值 (key=>value) 对用冒号 (**:**) 分割,每个对之间用逗号 (**,**) 分割,整个字典包括在花括号 (**{})**中。如下,字典(Dictionary)是键(Key)与值(Value)的集合: dictionary_example = { "key1": "value1", "key2": "value2", "key3": "value3"}
其中键是指向对应值的索引,我们需要使用键而访问对应的元素值: dictionary_tk = { "name": "Leandro", "nickname": "Tk", "nationality": "Brazilian"} print("My name is %s" %(dictionary_tk["name"])) # My name is Leandroprint("But you can call me %s" %(dictionary_tk["nickname"])) # But you can call me Tkprint("And by the way I'm %s" %(dictionary_tk["nationality"])) # And by the way I'm Brazilian
以上创建了一个字典,其中定义了四个键与对应的值,print 函数内使用了字典的键以获取对应的值。此外,字典的值可以使用任何类型的数据,如下我们添加了一个键为字符型,值为数值型的键-值对。 dictionary_tk = { "name": "Leandro", "nickname": "Tk", "nationality": "Brazilian", "age": 24} print("My name is %s" %(dictionary_tk["name"])) # My name is Leandroprint("But you can call me %s" %(dictionary_tk["nickname"])) # But you can call me Tkprint("And by the way I'm %i and %s" %(dictionary_tk["age"], dictionary_tk["nationality"])) # And by the way I'm Brazilian
下面我们需要了解如何添加元素到字典中,其实字典的本质就是指向特定值的关键字的集合。因此我们可以直接将某个值赋予到字典某个关键字(可以不存在)中而修改或添加键值对。 dictionary_tk = { "name": "Leandro", "nickname": "Tk", "nationality": "Brazilian"} dictionary_tk['age'] = 24 print(dictionary_tk) # {'nationality': 'Brazilian', 'age': 24, 'nickname': 'Tk', 'name': 'Leandro'}
迭代:数据结构中的循环
列表循环同样十分简单,我们可以循环地修改或输出某个列表。如下,我们常用 For 循环依次提取列表中的元素: bookshelf = [ "The Effective Engineer", "The 4 hours work week", "Zero to One", "Lean Startup", "Hooked"] for book in bookshelf: print(book)
对于哈希数据结构,我们同样可以使用字典中的键和 For 循环依次读取键与对应的值: dictionary = { "some_key": "some_value" } for key in dictionary: print("%s --> %s" %(key, dictionary[key])) # some_key --> some_value
使用 iteritems 方法同样可以实现相同的效果: dictionary = { "some_key": "some_value" } for key, value in dictionary.items(): print("%s --> %s" %(key, value)) # some_key --> some_value
我们命名了两个参数 key 和 value,但我们同样可以命名为其它的,如下我们使用 attribute 和 value 作为字典键值的参数,它同样有效: dictionary_tk = { "name": "Leandro", "nickname": "Tk", "nationality": "Brazilian", "age": 24} for attribute, value in dictionary_tk.items(): print("My %s is %s" %(attribute, value)) # My name is Leandro# My nickname is Tk# My nationality is Brazilian# My age is 24
进阶篇
类与对象
对象(Object)表征的是真实世界中的目标,如狗、猫和自行车等,一般对象有两个特征,即数据(Data)与行为(Behavior)。对象「车辆」有一些数据,如车轮的数量、车门的数量与作为容量等,它同样还有一些行为,例如车辆可以加速、刹车、展示燃油使用量等。
在面向对象的编程中,我们将数据表示为属性,将行为表示为方法。
类(Class)是创建独立对象的蓝图。在现实世界中,我们经常发现很多相同类型的对象。例如车辆,同型号的车辆都有引擎、车轮、座位等组件,而每一辆车都是根据相同的设计图构建且有相同的组件。
因此,对象是对客观事物的抽象,类是对对象的抽象。对象是类的实例,类是对象的模板。
Python 是一种面向对象的程序语言,因此它也有类(Class)与对象(Object)这两个概念。在了解 Python 面向对象编程的案例前,我们需要先熟悉面向对象编程的一些基本概念: 类 (Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。 实例变量:定义在方法中的变量,只作用于当前实例的类。 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,一个「狗」类的对象派生自「动物」类,这是模拟”是一个(is-a)”关系(狗是一种动物)。 实例化:创建一个类的实例,类的具体对象。 方法:类中定义的函数。 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
下面首先查看通过声明定义类的语句: class Vehicle:pass
目标是类的实例,我们可以使用类的名称创建一个实例: car = Vehicle()print(car) # <__main__.Vehicle instance at 0x7fb1de6c2638>
如上,car 为 Vehicle 类的一个对象或实例。
若我们的 vehicle 类有四个属性,即车轮数、储能类型、座位容量和最大时速,那么我们在创建 vehicle 类时可以设置这些属性。下面,我们定义了初始化类时所接受的数据。self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。 class Vehicle: def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity): self.number_of_wheels = number_of_wheels self.type_of_tank = type_of_tank self.seating_capacity = seating_capacity self.maximum_velocity = maximum_velocity
__init__() 方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建 vehicle 类的实例时就会调用该方法来定义这些属性。若我们希望能创建 Tesla Model S 这一个对象,根据其有四个车轮、电力驱动、四座容量和最大时速为 250km/hour 的特征,我们能创建对象: tesla_model_s = Vehicle(4, 'electric', 5, 250)
现在所有的属性已经设定了,那么我们该如何访问这些属性值?我们将发送信息到对象的过程称为方法,即对象的行为: class Vehicle: def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity): self.number_of_wheels = number_of_wheels self.type_of_tank = type_of_tank self.seating_capacity = seating_capacity self.maximum_velocity = maximum_velocity def number_of_wheels(self): return self.number_of_wheels def set_number_of_wheels(self, number): self.number_of_wheels = number
以上语句实现了两个方法,number_of_wheels 和 set_number_of_wheels。我们可以称为 getter & setter,因为第一个方法获取了属性值,而第二个方法将为该属性设置一个新的值。在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数。
在 Python 中,我们能使用 @property (decorators) 定义 getter & setter: class Vehicle: def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity): self.number_of_wheels = number_of_wheels self.type_of_tank = type_of_tank self.seating_capacity = seating_capacity self.maximum_velocity = maximum_velocity @property def number_of_wheels(self): return self.number_of_wheels @number_of_wheels.setter def number_of_wheels(self, number): self.number_of_wheels = number
同样我们能使用这些方法作为属性: tesla_model_s = Vehicle(4, 'electric', 5, 250)print(tesla_model_s.number_of_wheels) # 4tesla_model_s.number_of_wheels = 2 # setting number of wheels to 2print(tesla_model_s.number_of_wheels) # 2
这和定义方法有一些不同,这些方法作为了一种属性。如上当我们设定新的车轮数量,我们不需要将「2」作为参数设定,而是将 number_of_wheels 数值设定为 2。
我们还能使用方法做一些其他的操作,例如方法「make_noise」可以设置为: class Vehicle: def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity): self.number_of_wheels = number_of_wheels self.type_of_tank = type_of_tank self.seating_capacity = seating_capacity self.maximum_velocity = maximum_velocity def make_noise(self): print('VRUUUUUUUM')
当我们调用该方法时,它将返回字符串「VRRRRUUUUM」。 tesla_model_s = Vehicle(4, 'electric', 5, 250)tesla_model_s.make_noise() # VRUUUUUUUM
封装:隐藏信息
封装是一种限制直接访问目标属性和方法的机制,但同时它又有利于对数据(对象的方法)进行操作。
封装是一种将抽象性函数接口的实现细节部分包装、隐藏起来的方法。同时,它也是一种防止外界调用端,去访问对象内部实现细节的手段,这个手段是由编程语言本身来提供的。
对象所有的内部表征对于外部来说都是隐藏的,只有对象能直接与内部数据交互。首先,我们需要理解公开(public)和私有(non-public)实例变量和方法。
公开实例变量
对于 Python 的类,我们可以使用 constructor 方法初始化公开实例变量: class Person: def __init__(self, first_name): self.first_name = first_name
下面我们应用 first_name 的值作为公开实例变量的变元。 tk = Person('TK')print(tk.first_name) # => TK
在类别内: class Person: first_name = 'TK'
现在我们不需要再对 first_name 赋值,所有赋值到 tk 的目标都将有类的属性: tk = Person()print(tk.first_name) # => TK
现在我们已经学会如何使用公开实例变量和类属性。除此之外,我们还能管理公开部分的变量值,即对象可以管理其变量的值:Get 和 Set 变量值。保留 Person 类,我们希望能给 first_name 变量赋另外一个值: tk = Person('TK')tk.first_name = 'Kaio'print(tk.first_name) # => Kaio
如上我们将另外一个值(kaio)赋予了 first_name 实例变量,因为它又是一个公开变量,所以会更新变量值。
私有实例变量
和公开实例变量一样,我们可以使用 constructor 方法或在类的内部声明而定义一个私有实例变量。语法上的不同在于私有实例变量在变量名前面加一个下划线: class Person: def __init__(self, first_name, email): self.first_name = first_name self._email = email
上述定义的 email 变量就是私有变量。 tk = Person('TK', 'tk@mail.com')print(tk._email) # tk@mail.com
我们可以访问并且更新它,私有变量仅是一个约定,即他们需要被视为 API 非公开的部分。所以我们可以使用方法在类的定义中完成操作,例如使用两种方法展示私有实例的值与更新实例的值: class Person: def __init__(self, first_name, email): self.first_name = first_name self._email = email def update_email(self, new_email): self._email = new_email def email(self): return self._email
现在我们可以使用方法更新或访问私有变量。 tk = Person('TK', 'tk@mail.com')print(tk.email()) # => tk@mail.comtk._email = 'new_tk@mail.com'print(tk.email()) # => tk@mail.comtk.update_email('new_tk@mail.com')print(tk.email()) # => new_tk@mail.com
我们先初始化 Person 类并赋值,然后通过定义的方法访问并打印私有变量的值。如我们直接赋值给私有变量新的值,那么打印出来还是原有的值,我们只能通过在类里面定义的方法进行操作而更新私有变量。
公开方法
对于公开方法(public methods),我们同样能在类以外的地方调用,以下定义了一个类与方法: class Person: def __init__(self, first_name, age): self.first_name = first_name self._age = age def show_age(self): return self._age
让我们测试一下该方法: tk = Person('TK', 25)print(tk.show_age()) # => 25
私有方法
但是对于私有方法来说,并不能这样操作。若我们定义相同的类,且使用下划线定义 show_age 为私有方法: class Person: def __init__(self, first_name, age): self.first_name = first_name self._age = age def _show_age(self): return self._age
我们同样能调用对象的私有方法: tk = Person('TK', 25)print(tk._show_age()) # => 25
我们也能访问并更新它,私有方法应该要看作 API 的私有部分。下面的案例可以展示了如何使用它: class Person: def __init__(self, first_name, age): self.first_name = first_name self._age = age def show_age(self): return self._get_age() def _get_age(self): return self._agetk = Person('TK', 25)print(tk.show_age()) # => 25
如上我们声明了私有方法_get_age 和公开方法 show_age。show_age 方法可以在类的外部调用,而_get_age 只能在类内部使用。
封装小结
通过程序封装,我们确保了对象的内部表征对外是隐藏的。而面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。
若我们有一辆车,且知道车轮数、座位容量和最大时速,那么一辆电动车类就继承常规汽车类中的相同属性。 class Car: def __init__(self, number_of_wheels, seating_capacity, maximum_velocity): self.number_of_wheels = number_of_wheels self.seating_capacity = seating_capacity self.maximum_velocity = maximum_velocity
更新类中的一个对象: my_car = Car(4, 5, 250)print(my_car.number_of_wheels)print(my_car.seating_capacity)print(my_car.maximum_velocity)
初始化对象后,Python 可以将父类(parent class)作为参数应用到子类(child class)中。因此电动车类可以从汽车类继承对象。 class ElectricCar(Car): def __init__(self, number_of_wheels, seating_capacity, maximum_velocity): Car.__init__(self, number_of_wheels, seating_capacity, maximum_velocity)
我们不需要实现其他方法,因为电动汽车类已经从汽车类继承了对象: my_electric_car = ElectricCar(4, 5, 250)print(my_electric_car.number_of_wheels) # => 4print(my_electric_car.seating_capacity) # => 5print(my_electric_car.maximum_velocity) # => 250
End.
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「 我们 」留言处理。
数据分析
2018-07-23 08:14:00
毫不夸张地说,99%天天和Excel打交道的人,他们所掌握的Excel知识量不到总体的5%,也就是说还有95%的知识点并没有掌握。这不是危言耸听,这是我这几年 数据分析 培训中观察的结果。大部分的Excel使用者,每天在用最低级的知识处理着各种复杂的数据分析问题,分析要有效率只是一种传说。
不信我们就来测试一下,用一个最大众化的函数Vlookup来做测试,别瞧不起这个初阶函数,国外有个小哥还专门给这个函数写了一本书,可见这个函数简约而不简单。
于是我就琢磨了个题考考大家函数水平,看你在几段:
一段 :会简单的 vlookup 函数的使用
二段 :会vlookup+column函数的嵌套使用
三段 :会vlookup+ match 函数的嵌套使用
四段 :会vlookup的模糊匹配使用
五段 :会vlookup+offset+match的高阶嵌套使用
相信大部分人在一段或者段外徘徊,vlookup函数基本上是使用频率最高的一个函数,这个函数不会使用的话,基本上就算是不会函数了。只会sum或count这种函数的朋友自动面壁去,下面的描述你基本看不懂哈。
很多表哥表妹常说这些函数都会,但是组合在一起就不会了。确实,函数的嵌套是最难的,不光难在技术,最关键是逻辑,很多时候是我们自己想不到这样取巧的使用而自己打败了自己。
别慌,今天我给大家上堂干货课程,分享给你办公室的每个表哥表姐表弟表妹们,让他们都学会。谦虚的说,这样你们的办公效率至少会提高一倍吧。 一段:vlookup的基本用法
vlookup是一个纵向查找函数(从左往右查),官方的语法规则是这样的:VLOOKUP(lookup_value,table_array,col_index_num,range_lookup)。翻译成中文就是:查找(一个值,这个值所在的区间,它位于第几列,精准匹配还是模糊匹配)
图1
lookup_value :可以是一个值、日期或文本等。如你查询上图中的“城市”
table_array :查询值所处的区域,对于上图就是A1:H11这个范围,强烈推荐区域改成A:H这种写法,好处是当添加新数据源时不用更改公式。
col_index_num :查询的数据处于第几列,比如要查“完成率”这个值就是4,查“销售数量”就是6。
range_lookup :0为精准匹配,就是查询对象必须长得一模一样,少根汗毛都不行。一般情况都要求精准匹配,如果这个值省略这是模糊匹配(见vlookup四段的用法)
举例说明:
公式=VLOOKUP(“上海”,A:H,5,0)
查找“上海”所在的第五列数据,要求精准匹配。这个公式生成的结果是718。
注 :“上海”可以是查询值所处的单元格,如果“上海”在K2单元格,则公式可以改成:
公式=VLOOKUP(K2,A:H,5,0)
K2中如果是“成都”,结果则是659,如果是“雄安”,结果则是668。
Vlookup是非常好的数据查找函数,很方便的把处于不同地方的数据匹配到指定的地方,其中关键点就是数据查询的区域,这个区域可以是不同的区域,不同的工作簿,不同的工作表。
拓展知识点:
Vlookup家族还有Hlookup,Lookup。 二段:Vlookup+Column
当我们需要用Vlookup匹配多列数据的时候,往往需要手动去更改公式中的第3个值(就是col_index_num),但是匹配对象太多的情况下,手动修改其实是非常没有效率并且非常苦逼的一件事,这个时候column函数可以解放你们。
相信大部分会vlookup的人,现在还是傻傻的手动在改这个参数,说的就是你。
COLUMN(reference)
返回reference所在单元格所处的列号,如果A1就是1(第1列),B25就是2(第2列),H2就是8(第8列),这三个公式分别为COLUMN(A1),COLUMN(B25),COLUMN(H2)。如果reference为空则返回当前单元格的列号。
图2
上图就是在L2单元格写好公式后直接往后拉这个公式就可以直接匹配出其它6个值,不用手动将第3个参数分别改成3,4,5……,因为第三个值自动复制成COLUMN(C1),COLUMN(D1),COLUMN(E1)……
高效不?就是这么简单,小函数有大用途。
拓展知识点:
与column(reference)函数对应的是row(reference),试试看。 三段:Vlookup+match
Vlookup和match函数组合是V函数的标准用法,与column函数一样的功效,match函数的作用也是用来改变第三个参数值。
MATCH(lookup_value, lookup_array, match_type)
M函数是返回指定数值在指定数组区域中的位置,生成的是位置而不是V函数中位置所处的值,这是二者的区别。match_type如果是0则为精准匹配,省略则为模糊匹配,一般都是用0进行精准匹配。
例如我们使用上面图1中的数据源,公司如下:
公司=MATCH(“完成率”,B1:H1,0)
返回值为3,因为“完成率”这个指标是在B1:H1这个区域的第3个值,如果查询“进店顾客数”则返回7。所以M函数可以用来查询指定对象所处的位置,和V函数组合威力巨大,基本上可以两个查询值的无死角匹配。
图3
图3中嵌套公式写在了V2单元格,U2和V1单元格是可以修改“城市”和“查询指标”的地方,V2单元格将生成对应的查询值,修改U2和V1的值即可以查到对应的数据。
V+M函数组合是非常灵活的查询函数,是E界必备之效率嵌套用法。 四段:Vlookup的模糊匹配
从技术层面来讲,这个V函数的用法大概处于二段水平,但是从数据分析业务场景来说,我更愿意把它放在四段,因为这种应用解决了好几个业务场景的实际使用。
比如将商品价格分成低中高三段,将员工年龄分成青年、中年、老年等,将员工工龄分成4段等等场景。
如下图,通过每个商品的价格,自动匹配出来它处于的”价格段”和”价格描述”两个字段,有了这两个字段后,再用数据透视表做分析就so easy了。
图4
要实现这样的功能,首先需要建立一个自定义的分段标准,没有标准鬼才知道你应该归位到哪儿。知识点来了:
图5
这里的价格节点可以自定义修改,修改后在图4的对应位置就可以自动生成对应的价格段。自定义的知识点其实比较简单,真正的知识点是图4、图5的数据该如何关联在一起?
图6
单元格C2和D2中的公式就是答案,它利用了vlookup函数的模糊匹配功能,你可以看到公式中第四个参数是缺失的。
本文为专栏文章,来自:数据化管理,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/56826.html 。
数据分析
2018-07-01 11:23:00
通常,分类变量y可以采用不同的值。在最简单的情况下,y是二进制的,意味着它可以假设值为1或0.机器学习中使用的经典示例是电子邮件分类:给定每个电子邮件的一组属性,如单词数量,链接和图片,算法应该决定电子邮件是否为垃圾邮件(1)或不(0)。在这篇文章中,我们将模型称为“二项 逻辑回归 ”,因为要预测的变量是二元的,然而,逻辑回归也可以用来预测一个可以假设多于2个值的因变量。在第二种情况下,我们称之为“多项逻辑回归”模型。例如,一个典型的例子就是将电影在“娱乐”,“边缘”或“无聊”之间进行分类。
R中的逻辑回归实现
R可以很容易地拟合逻辑回归模型。 被调用的函数是glm(),拟合过程与线性回归中使用的不同。 在这篇文章中,我将拟合一个二元逻辑回归模型并解释每一步。
数据集
我们将研究泰坦尼克号数据集。 这个数据集有不同版本可以在线免费获得,但我建议使用Kaggle提供的数据集,因为它几乎可以使用(为了下载它,你需要注册Kaggle)。数据集(训练)是关于一些乘客的数据集合(准确地说是889),并且竞赛的目标是预测生存(如果乘客幸存,则为1,否则为0)基于某些 诸如服务等级,性别,年龄等特征。正如您所看到的,我们将使用分类变量和连续变量。
数据清理过程
在处理真实数据集时,我们需要考虑到某些数据可能丢失或损坏的事实,因此我们需要为我们的分析准备数据集。 作为第一步,我们使用read.csv()函数加载csv数据。确保参数na.strings等于c(“”),以便将每个 缺失值 编码为NA。 这将帮助我们接下来的步骤。 training.data.raw <- read.csv( ‘train.csv’, header = TRUE, na.strings = c(“”)
现在我们需要检查缺失的值,并使用sapply()函数查看每个变量有多少个唯一值,该函数将作为参数传递的函数应用于数据帧的每一列。 sapply( training.data.raw, function(x) sum(is.na(x)) )
sapply( training.data.raw, function(x) length(unique(x)) )
对缺失值进行可视化处理可能会有所帮助:Amelia包具有特殊的绘图函数missmap(),它将绘制数据集并突出显示缺失值:
变量carbin有太多的缺失值,我们不会使用它。 我们也会放弃PassengerId,因为它只是一个索引和Ticket。使用subset()函数,我们将原始数据集进行子集化,只选择相关列。 data <- subset(training.data.raw,select=c(2, 3, 5, 6, 7, 8, 10, 12))
处理缺失值
现在我们需要解释其他缺失的值。 通过在拟合函数内设置参数来拟合广义线性模型时,R可以很容易地处理它们。 但是,我个人更倾向于在可能的情况下“手动”处理缺失值。 有不同的方法可以做到这一点,一种典型的方法是用现有的平均值,中位数或模式代替缺失值。 我将使用平均值。 data$Age[is.na(data$Age)] <- mean(data$Age,na.rm=T)
就分类变量而言,默认情况下使用read.table()或read.csv()会将分类变量编码为因子。 一个factor是R如何处理分类变量。
我们可以使用以下代码行来检查编码 is.factor(data$Sex) is.factor(data$Embarked)
为了更好地理解R如何处理分类变量,我们可以使用contrasts()函数。 这个函数将向我们展示变量如何被R虚拟化,以及如何在模型中解释它们。 contrasts(data$Sex) contrasts(data$Embarked)
例如,你可以看到变量sex时,女性将被用作参考。 至于Embark中的缺失值,由于只有两个值,我们将丢弃这两行(我们也可以用模式替换缺失的值并保留数据点)。 data <- data[!is.na(data$Embarked),] rownames(data) <- NULL
在进行拟合过程之前,让我提醒您清洁和格式化数据的重要性。 这个预处理步骤对于获得模型的良好拟合和更好的预测能力通常是至关重要的。
模型拟合
我们将数据分成两部分: 训练和测试集 。 训练集将用于拟合我们将在测试集上进行测试的模型。 train <- data[1: 800,] test <- data[801: 889,]
现在,我们来拟合模型。 一定要在glm()函数中指定参数family = binomial。 model <- glm(Survived ~.,family=binomial(link=’logit’),data=train)
通过使用函数summary(),我们获得了我们模型的结果: summary(model)
部分结果如下图:
解释我们的逻辑回归模型的结果
现在我们可以分析拟合并解释模型告诉我们什么。
首先,我们可以看到SibSp,Fare和Embarked没有统计学意义。 至于统计上显着的变量,性别具有最低的p值,这表明乘客的性别与存活的可能性有很强的关联。 该预测因子的负系数表明所有其他变量相同,男性乘客不太可能存活下来。 请记住,在Logit模型中,响应变量是对数可能性:ln(odds)= ln(p /(1-p))= a  x1 + b  x2 + … + z * xn。 由于男性是虚拟变量,因此男性将对数赔率降低2.75,而单位年龄增加则将对数赔率降低0.037。
现在我们可以在模型上运行anova()函数来分析偏差表 anova(model, test=”Chisq”)
零偏差和残差偏差之间的差异显示了我们的模型如何对付零模型(仅包含截距的模型)。 这个差距越大越好。 通过分析表格,我们可以看到每次添加一个变量时偏差下降的情况。 同样,增加Pclass,Sex and Age可以显着减少残余偏差。 尽管SibSp具有较低的p值,但其他变量似乎可以改进模型。 这里的大p值表示没有变量的模型差不多也能解释相同的变化量。 最终你想看到的是偏差和AIC的显着下降。
尽管不存在与线性回归R2的精确等价,但McFadden R2指数可用于评估模型拟合。 library(pscl) pR2(model)
评估模型的预测能力
在上面的步骤中,我们简要地评估了模型的拟合,现在我们想看看模型在预测新的一组数据时是如何进行的。 通过设置参数type =’response’,R将以P(y = 1 | X)的形式输出概率。 我们的决策边界将是0.5。 如果P(y = 1 | X)> 0.5,则y = 1,否则y = 0。 请注意,对于某些应用程序,不同的阈值可能是更好的选择。 fitted.results <- predict(model,newdata=subset(test,select=c(2, 3, 4, 5, 6, 7, 8)),type=’response’) fitted.results <- ifelse(fitted.results > 0.5, 1, 0) misClasificError <- mean(fitted.results != test$Survived) print(paste(‘Accuracy’,1-misClasificError))
“准确性0.842696629213483”
测试集上的0.84精度是相当不错的结果。 但是,请记住,这个结果有点依赖于我之前做的数据的手动分割,因此如果您希望得到更精确的分数,最好运行某种交叉验证,如k折交叉验证。
作为最后一步,我们将绘制ROC曲线并计算二元分类器典型性能测量的AUC(曲线下面积)。
ROC是通过在各种阈值设置下绘制真阳性率(TPR)与假阳性率(FPR)而产生的曲线,而AUC是ROC曲线下的面积。 作为一个经验法则,具有良好预测能力的模型应该具有接近于1(1是理想的)的AUC。 library(ROCR) p <- predict(model, newdata=subset(test,select=c(2, 3, 4, 5, 6, 7, 8)), type=”response”) pr <- prediction(p, test$Survived) prf <- performance(pr, measure = “tpr”, x.measure = “fpr”) plot(prf) auc <- performance(pr, measure = “auc”) auc <- auc@y.values[[1]] auc
0.8647186
ROC如下图所示:
完整代码 # 任务描述 # R执行逻辑回归算法 training.data.raw <- read.csv( ‘train.csv’, header = TRUE, na.strings = c(“”) sapply( training.data.raw, function(x) sum(is.na(x)) sapply( training.data.raw, function(x) length(unique(x)) library(Amelia) missmap(training.data.raw, main = “Missing values vs observed”) data <- subset(training.data.raw,select=c(2, 3, 5, 6, 7, 8, 10, 12)) data$Age[is.na(data$Age)] <- mean(data$Age,na.rm=T) is.factor(data$Sex) is.factor(data$Embarked) contrasts(data$Sex) contrasts(data$Embarked) data <- data[!is.na(data$Embarked),] rownames(data) <- NULL train <- data[1: 800,] test <- data[801: 889,] model <- glm(Survived ~.,family=binomial(link=’logit’),data=train) summary(model) anova(model, test=”Chisq”) library(pscl) pR2(model) fitted.results <- predict(model,newdata=subset(test,select=c(2, 3, 4, 5, 6, 7, 8)),type=’response’) fitted.results <- ifelse(fitted.results > 0.5, 1, 0) misClasificError <- mean(fitted.results != test$Survived) print(paste(‘Accuracy’,1-misClasificError)) library(ROCR) p <- predict(model, newdata=subset(test,select=c(2, 3, 4, 5, 6, 7, 8)), type=”response”) pr <- prediction(p, test$Survived) prf <- performance(pr, measure = “tpr”, x.measure = “fpr”) plot(prf) auc <- performance(pr, measure = “auc”) auc <- auc@y.values[[1]] auc
编译 :数据人网 陆勤
出处 :http://shujuren.org/article/620.html
英文作者 :Michy Alice
英文链接 :https://www.r-bloggers.com/how-to-perform-a-logistic-regression-in-r/
本文为专栏文章,来自:数据人网,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/56409.html 。
数据分析
2018-06-23 22:50:00
作者 Igor Bobriakov 编译  Mika
在解决数据科学任务和挑战方面, Python 继续处于领先地位。去年,我对当时热门的Python库进行了总结。今年,我在当中加入新的库,重新对2018年热门Python库进行全面盘点。
其实入选的库远不止20个,但由于一些库针对相同问题是可以相互替代的,因此没有纳入其中。
核心库和统计
1. NumPy(提交:17911,贡献者:641)
首先介绍科学应用方面的库,其中NumPy是不可忽视的选择。NumPy用于处理大型多维数组和矩阵,并通过大量的高级数学函数和实现方法进行各种操作。
在过去一年里,NumPy进行了大量改进。除了bug修复和兼容性问题之外,还涉及到样式可能性,即NumPy对象的格式化打印。
2. SciPy(提交:19150,贡献者:608)
科学计算方面的另一个核心库是SciPy。SciPy基于NumPy,因此扩展了NumPy的功能。SciPy的主要数据结构是由Numpy实现的多维数组。当中包括许多解决线性代数、概率论、积分等任务的工具。
SciPy的主要改进包括,持续集成到不同操作系统,以及添加的新功能和新方法。此外,还封装了许多新的BLAS和LAPACK函数。
3. Pandas(提交:17144,贡献者:1165)
Pandas是一个Python库,提供高级数据结构和各种分析工具。主要特点是能够将相当复杂的数据操作转换为一两条命令。Pandas包含许多用于分组、过滤和组合数据的内置方法,以及时间序列功能。
Pandas库已推出多个新版本,其中包括数百个新功能、增强功能、bug修复和API改进。这些改进包括分类和排序数据方面,更适合应用方法的输出,以及执行自定义操作。
4. StatsModels(提交:10067,贡献者:153)
Statsmodels是一个Python模块,用于统计模型估计、执行统计测试等统计 数据分析 。在它的帮助下,你可以使用 机器学习 方法进行各种绘图尝试。
Statsmodels在不断改进。今年加入了时间序列方面的改进和新的计数模型,即广义泊松、零膨胀模型和负二项。还包括新的多变量方法 ——因子分析、多元方差分析和方差分析中的重复测量。
可视化
5. Matplotlib(提交:25747,贡献者:725)
Matplotlib是用于创建二维图表和图形的低级库。使用Matplotlib,你可以构建直方图、散点图、非笛卡尔坐标图等图表。此外,许多热门的绘图库都能与Matplotlib结合使用。
Matplotlib在颜色、尺寸、字体、图例等方面都有一定改进。外观方面包括坐标轴图例的自动对齐;色彩方面也做出改进,对色盲更加友好。
6. Seaborn(提交:2044,贡献者:83)
Seaborn是基于matplotlib库更高级别的API。它包含更适合处理图表的默认设置。此外,还包括时间序列等丰富的可视化图库。
Seaborn的更新包括bug修复。同时,还包括FacetGrid与PairGrid的兼容性,增强了matplotlib后端交互,并在可视化中添加了参数和选项。
7. Plotly(提交:2906,贡献者:48)
Plotly能够让你轻松构建复杂的图形。Plotly适用于交互式Web应用程序。可视化方面包括等高线图、三元图和三维图。
Plotly不断增加新的图像和功能,对动画等方面也提供了支持。
8. Bokeh(提交:16983,贡献者:294)
Bokeh库使用JavaScript小部件,在浏览器中创建交互式和可缩放的可视化。Bokeh提供了多种图形集合、样式,并通过链接图、添加小部件和定义回调等形式增强互动性。
Bokeh在交互式功能的进行了改进,比如旋转分类标签、小型缩放工具和自定义工具提示字段的增强。
9. Pydot(提交:169,贡献者:12)
Pydot用于生成复杂的定向图和非定向图。它是用Python编写的Graphviz接口。使用Pydot能够显示图形结构,这经常用于构建神经网络和基于决策树的算法。
机器学习
10. Scikit-learn(提交:22753,贡献者:1084)
Scikit-learn是基于NumPy和SciPy的Python模块,并且是处理数据方面的不错选择。Scikit-learn为许多机器学习和 数据挖掘 任务提供算法,比如聚类、回归、分类、降维和模型选择。
Scikit-learn已做出了许多改进。改进包括交叉验证、使用多个指标,近邻取样和逻辑回归等训练方法也有小的改进。主要更新还包括完善常用术语和API元素的术语表,这能帮助用户熟悉Scikit-learn中的术语和规则。
11. XGBoost / LightGBM / CatBoost(提交:3277/1083/1509,贡献者:280/79/61)
梯度提升(gradient boosting)是最流行的机器学习算法之一,这在决策树模型中是至关重要的。因此我们需要重视XGBoost、LightGBM和CatBoost。这几个库都用相同的方式解决常见问题。这些库能够更优化、扩展且快速地实现梯度提升,从而它们在数据科学家和Kaggle竞争中备受追捧,其中许多人在这些算法的帮助下赢得了比赛。
12. Eli5(提交:922,贡献者:6)
通常机器学习模型预测的结果并不特别清晰,这时就需要用到eli5了。它可以用于可视化和调试机器学习模型,并逐步跟踪算法运行情况。同时eli5能为scikit-learn,XGBoost,LightGBM,lightning和sklearn-crfsuite库提供支持。
深度学习
13. TensorFlow(提交:33339,贡献者:1469)
TensorFlow是用于深度学习和机器学习的热门框架,由谷歌大脑开发。TensorFlow能够用于多个数据集的人工神经网络。TensorFlow的主要应用包括对象识别、语音识别等等。
新版本中加入了新的功能。最新的改进包括修复安全漏洞,以及改进TensorFlow和GPU集成,比如能在一台机器上的多个GPU上运行评估器模型。
14. PyTorch(提交:11306,贡献者:635)
PyTorch是一个大型框架,能通过GPU加速执行tensor计算,创建动态计算图并自动计算梯度。此外,PyTorch为解决神经网络相关的应用提供了丰富的API。
PyTorch基于Torch,它是用C语言实现的开源的深度学习库。Python API于2017年推出,从此之后该框架越来越受欢迎,并吸引了大量数据科学家。
15. Keras(提交:4539,贡献者:671)
Keras是用于神经网络的高级库,可运行与TensorFlow和Theano。现在由于推出新版本,还可以使用CNTK和MxNet作为后端。它简化了许多任务,并大大减少了代码数量。但缺点是不适合处理复杂任务。
Keras在性能、可用性、文档即API方面都有改进。新功能包括Conv3DTranspose层、新的MobileNet应用等。
分布式深度学习
16. Dist-keras / elephas / spark-deep-learning(提交:1125/170/67,贡献者:5/13/11)
由于越来越多的用例需要大量的精力和时间,深度学习问题变得更为重要。但是,使用Apache Spark之类的分布式计算系统能够更容易处理大量数据,这又扩展了深度学习的可能性。
因此dist-keras、elephas、和spark-deep-learning变得更为普及,由于它们有能用于解决相同任务,因此很难从中取舍。这些包能够让你在Apache Spark的帮助下,直接通过Keras库训练神经网络。Spark-deep-learning还提供了使用Python神经网络创建管道的工具。
自然语言处理
17. NLTK(提交:13041,贡献者:236)
NLTK是一组库,是进行自然语言处理的平台。在NLTK的帮助下,你可以通过多种方式处理和分析文本,对其进行标记和提取信息。NLTK还可用于原型设计和构建研究系统。
NLTK的改进包括API和兼容性的小改动,以及CoreNLP的新接口。
18. SpaCy(提交:8623,贡献者:215)
SpaCy是自然语言处理库,具有出色的示例、API文档和演示应用。该库用Cython编写,Cython是C语言在Python的扩展。它支持将近30种语言,提供简单的深度学习集成,并能确保稳定性和高准确性。SpaCy的另一个强大功能是无需将文档分解,整体处理整个文档。
19. Gensim(提交:3603,贡献者:273)
Gensim是Python库,用于语义分析、主题建模和矢量空间建模,建立在Numpy和Scipy之上。它提供了word2vec等NLP算法实现。尽管gensim拥有自己的models.wrappers.fasttext实现,但fasttext库也可用于词语表示的高效学习。
数据抓取
20. Scrapy(提交:6625,贡献者:281)
Scrapy可用于创建扫描页面和收集结构化数据。另外,Scrapy还可以从API中提取数据。由于其可扩展性和便携性,Scrapy非常好用。
今年Scrapy的更新包括代理服务器升级,以及错误通知和问题识别系统。这也为使用scrapy解析机械能元数据设置提供了新的方法。
结语
以上就是2018年数据科学方面的Python库的整理。与去年相比,一些新的库越来越受欢迎,数据科学方面常用的库也在不断改进。
以下的表格显示了github上各个库的统计数据。
尽管今年我们扩大了列表,但仍然可能有一些库没有包含在内,欢迎留言补充。
原文链接:
https://medium.com/activewizards-machine-learning-company/top-20-python-libraries-for-data-science-in-2018-2ae7d1db8049
本文为专栏文章,来自:CDA数据分析师,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/56185.html 。
数据分析
2018-06-20 09:03:00
大数据 文摘出品
编译:睡不着的iris、陈同学、YYY
不知道如何在地图上可视化网络图?下面这篇博客将使用R中的igraph、ggplot2或ggraph包来介绍三种在地图上可视化网络图的方法。在对地理位置以及位置的连接关系进行可视化时,还可以在图中展示一些属性。
当我们对节点(nodes)为地理位置的网络图进行可视化时,比较有效的做法是将这些节点绘制在地图上并画出它们之间的连接关系,因为这样我们可以直接看到网络图中节点的地理分布及其连接关系。
但这与传统的网络图是 不同 的。在传统的网络图中,节点的分布取决于使用何种布局算法(layout algorithm),有一些算法可能会使紧密联系的那些节点聚成集群。
下面将介绍三种可视化的方法。
准备工作
首先,我们需要加载下面的库:
library(assertthat)
library(dplyr)
library(purrr)
library(igraph)
library(ggplot2)
library(ggraph)
library(ggmap)
现在,让我们加载一些样本节点。我随机选取了几个国家的地理坐标。
country_coords_txt <- ”
1     3.00000  28.00000       Algeria
2    54.00000  24.00000           UAE
3   139.75309  35.68536         Japan
4    45.00000  25.00000 ‘Saudi Arabia’
5     9.00000  34.00000       Tunisia
6     5.75000  52.50000   Netherlands
7   103.80000   1.36667     Singapore
8   124.10000  -8.36667         Korea
9    -2.69531  54.75844            UK
10    34.91155  39.05901        Turkey
11  -113.64258  60.10867        Canada
12    77.00000  20.00000         India
13    25.00000  46.00000       Romania
14   135.00000 -25.00000     Australia
15    10.00000  62.00000        Norway”
# nodes come from the above table and contain geo-coordinates for some
# randomly picked countries
nodes <- read.delim(text = country_coords_txt, header = FALSE,
quote = “‘”, sep = “”,
col.names = c(‘id’, ‘lon’, ‘lat’, ‘name’))
我们选取了15个国家作为网络图的节点,每个节点的信息包括国名、地理坐标(经度和纬度)和一个ID。现在,我将随机生成这些节点之间的连接关系:
set.seed(123)  # set random generator state for the same output
N_EDGES_PER_NODE_MIN <- 1
N_EDGES_PER_NODE_MAX <- 4
N_CATEGORIES <- 4
# edges: create random connections between countries (nodes)
edges <- map_dfr(nodes$id, function(id) {
n <- floor(runif(1, N_EDGES_PER_NODE_MIN, N_EDGES_PER_NODE_MAX+1))
to <- sample(1:max(nodes$id), n, replace = FALSE)
to <- to[to != id]
categories <- sample(1:N_CATEGORIES, length(to), replace = TRUE)
weights <- runif(length(to))
data_frame(from = id, to = to, weight = weights, category = categories)
})
edges <- edges %>% mutate(category = as.factor(category))
这里每条边均通过from列和to列里的节点ID来确定节点之间的连接关系。此外,我们生成随机连接关系的类型和强度。这些属性通常用于图表分析,之后也可以被可视化。
这样我们的节点和边就充分表现了图的内容。现在我们可以用igraph库生成一个图结构g,这对于以后快速计算每个节点的等级或其他属性尤为必要。
g <- graph_from_data_frame(edges, directed = FALSE, vertices = nodes)
我们现在创建一些数据结构,这些数据结构将用于我们将要生成的所有的图。首先,我们创建一个 数据框 来绘制边。这个数据框将与edges数据框类似,但是有额外四列数据来定义每条边的开始点和结束点(x, y 和 xend, yend):
edges_for_plot <- edges %>%
inner_join(nodes %>% select(id, lon, lat), by = c(‘from’ = ‘id’)) %>%
rename(x = lon, y = lat) %>%
inner_join(nodes %>% select(id, lon, lat), by = c(‘to’ = ‘id’)) %>%
rename(xend = lon, yend = lat)
assert_that(nrow(edges_for_plot) == nrow(edges))
现在我们给每个节点赋予一个权重,并使用等级作为指标。在地图上这个指标表现为节点的大小。
nodes$weight = degree(g)
现在我们定义一个通用的ggplot2 的主题(在ggplot中设置及美化图形的一个工具)来展示地图 (无坐标轴和网格线):
maptheme <- theme(panel.grid = element_blank()) +
theme(axis.text = element_blank()) +
theme(axis.ticks = element_blank()) +
theme(axis.title = element_blank()) +
theme(legend.position = “bottom”) +
theme(panel.grid = element_blank()) +
theme(panel.background = element_rect(fill = “#596673”)) +
theme(plot.margin = unit(c(0, 0, 0.5, 0), ‘cm’))
所有的图将会应用同一个主题,并使用相同的世界地图作为“背景”(用map_data(‘world’)实现),采取同一个固定比例的坐标系来限定经度和纬度。
country_shapes <- geom_polygon(aes(x = long, y = lat, group = group),
data = map_data(‘world’),
fill = “#CECECE”, color = “#515151”,
size = 0.15)
mapcoords <- coord_fixed(xlim = c(-150, 180), ylim = c(-55, 80))
图1:仅ggplot2
让我们从ggplot2开始入门吧!
除了世界地图(country_shapes)中的国家多边形以外,我们还需创建 三个几何对象 :使用geom_point将节点绘制为点,使用geom_text为节点添加标签;使用geom_curve将节点之间的边绘制成曲线。
在图中,我们需要为每个几何对象定义 图形属性映射 (aesthetic mappings,也称为美学映射,用以“描述数据中的变量如何映射到视觉属性”)。
图形属性映射链接:
http://ggplot2.tidyverse.org/reference/aes.html
对于节点,我们将它们的地理坐标映射到图中的x和y位置,并且由其权重所决定节点的大小(aes(x = lon,y = lat,size = weight))。对于边,我们传递edges_for_plot数据框架并使用x, y 和 xend, yend 作为曲线的起点和终点。
此外,每条边的颜色都取决于它的类别(category),而它的“尺寸”(指它的线宽)取决于边的权重(一会儿我们会发现后面这一条没有实现)。
请注意, 几何对象的顺序非常重要 ,因为它决定了哪个对象先被绘制,并可能会被随后在下一个几何对象层中绘制的对象所遮挡。因此,我们首先绘制边,然后节点,最后才是顶部的标签:
ggplot(nodes) + country_shapes +
geom_curve(aes(x = x, y = y, xend = xend, yend = yend,     # draw edges as arcs
color = category, size = weight),
data = edges_for_plot, curvature = 0.33,
alpha = 0.5) +
scale_size_continuous(guide = FALSE, range = c(0.25, 2)) + # scale for edge widths
geom_point(aes(x = lon, y = lat, size = weight),           # draw nodes
shape = 21, fill = ‘white’,
color = ‘black’, stroke = 0.5) +
scale_size_continuous(guide = FALSE, range = c(1, 6)) +    # scale for node size
geom_text(aes(x = lon, y = lat, label = name),             # draw text labels
hjust = 0, nudge_x = 1, nudge_y = 4,
size = 3, color = “white”, fontface = “bold”) +
mapcoords + maptheme
这时候代码界面中的控制台中会显示一条警告,提示“已显示‘尺寸’标度,添加其他的标度‘尺寸‘将替换现有的标度。”这是因为我们两次使用了“尺寸”的图形属性及其标度,一次用于节点大小,一次用于曲线的宽度。
比较麻烦的是,我们不能在同一个图形属性上定义两种不同的标度,即使这个图形属性要用于不同的几何对象(比如在我们这个例子里:“尺寸”这个图形属性被同时用于节点的大小和边的线宽)。据我所知在ggplot2中控制线宽只能通过“size“来实现。
使用ggplot2,我们只需决定要调整哪一个几何对象的大小。此处,我选择使用静态节点大小和动态线宽:
ggplot(nodes) + country_shapes +
geom_curve(aes(x = x, y = y, xend = xend, yend = yend,     # draw edges as arcs
color = category, size = weight),
data = edges_for_plot, curvature = 0.33,
alpha = 0.5) +
scale_size_continuous(guide = FALSE, range = c(0.25, 2)) + # scale for edge widths
geom_point(aes(x = lon, y = lat),                          # draw nodes
shape = 21, size = 3, fill = ‘white’,
color = ‘black’, stroke = 0.5) +
geom_text(aes(x = lon, y = lat, label = name),             # draw text labels
hjust = 0, nudge_x = 1, nudge_y = 4,
size = 3, color = “white”, fontface = “bold”) +
mapcoords + maptheme
图2:ggplot2+ggraph
幸运的是,ggplot2有一个名为ggraph的扩展包,里面包含专门用于绘制网络图的几何对象和图形属性。这样我们就可以对节点和边使用不同的标度了。默认情况下,ggraph将根据你指定的布局算法放置节点。但是我们还可以使用地理坐标作为节点位置来自定义布局:
node_pos <- nodes %>%
select(lon, lat) %>%
rename(x = lon, y = lat)   # node positions must be called x, y
lay <- create_layout(g, ‘manual’,
node.positions = node_pos)
assert_that(nrow(lay) == nrow(nodes))
# add node degree for scaling the node sizes
lay$weight <- degree(g)
我们使用先前定义的布局lay和拓展包ggraph中的几何对象geom_edge_arc及geom_node_point来作图:
ggraph(lay) + country_shapes +
geom_edge_arc(aes(color = category, edge_width = weight,   # draw edges as arcs
circular = FALSE),
data = edges_for_plot, curvature = 0.33,
alpha = 0.5) +
scale_edge_width_continuous(range = c(0.5, 2),             # scale for edge widths
guide = FALSE) +
geom_node_point(aes(size = weight), shape = 21,            # draw nodes
fill = “white”, color = “black”,
stroke = 0.5) +
scale_size_continuous(range = c(1, 6), guide = FALSE) +    # scale for node sizes
geom_node_text(aes(label = name), repel = TRUE, size = 3,
color = “white”, fontface = “bold”) +
mapcoords + maptheme
边的宽度可以通过edge_width的图形属性及其标度函数scale_edge_width进行控制。节点则沿用之前的size来控制大小。另一个不错的功能是,geom_node_text可以通过repel = TRUE 来分布节点标签,这样它们就不会互相遮挡太多。
请注意,图的边与之前ggplot2的图 采用了不同的绘制方式。由于 ggraph采用了不同的布局算法,连接关系仍然相同,只是布局变了。例如,加拿大和日本之间的绿松石色边线已经从最北部转移至南部,并穿过了非洲中心。
图3:拙劣的方法(叠加数个ggplot2“plot grobs”)
我不想隐瞒另一个可能被认为是拙劣的方法:通过将它们标注为“grobs”(graphical objects的简称),你可以叠加几个单独创建的图(透明背景)。这可能不是图形对象标注功能本来的目的,但总之,当你真的需要克服上面图1中所描述的 ggplot2图形属性限制 时,它随时可以派上用场。
图形对象标注链接:
http://ggplot2.tidyverse.org/reference/annotation_custom.html
如上所述,我们将制作独立的图并“堆叠”它们。第一个图就是之前以世界地图为“背景”的图。第二个图是一个只显示边的叠加层。最后,第三个叠加层图仅显示带有节点及其标签的点。这样设置后,我们便可以分别控制边线的线宽和节点的大小,因为它们是在图中各自单独生成。
这两次叠加需要有一个透明的背景,所以我们用一个主题来定义它:
theme_transp_overlay <- theme(
panel.background = element_rect(fill = “transparent”, color = NA),
plot.background = element_rect(fill = “transparent”, color = NA)
)
底图或“背景”图制作十分方便,且仅显示地图:
p_base <- ggplot() + country_shapes + mapcoords + maptheme
现在,我们创建第一个叠加层的边,线宽的大小由边的权重所决定:
p_edges <- ggplot(edges_for_plot) +
geom_curve(aes(x = x, y = y, xend = xend, yend = yend,     # draw edges as arcs
color = category, size = weight),
curvature = 0.33, alpha = 0.5) +
scale_size_continuous(guide = FALSE, range = c(0.5, 2)) +  # scale for edge widths
mapcoords + maptheme + theme_transp_overlay +
theme(legend.position = c(0.5, -0.1),
legend.direction = “horizontal”)
第二个叠加层显示节点和标签:
p_nodes <- ggplot(nodes) +
geom_point(aes(x = lon, y = lat, size = weight),
shape = 21, fill = “white”, color = “black”,    # draw nodes
stroke = 0.5) +
scale_size_continuous(guide = FALSE, range = c(1, 6)) +    # scale for node size
geom_text(aes(x = lon, y = lat, label = name),             # draw text labels
hjust = 0, nudge_x = 1, nudge_y = 4,
size = 3, color = “white”, fontface = “bold”) +
mapcoords + maptheme + theme_transp_overlay
最后,我们使用图形对象标注组合叠加层。请注意, 准确定位图形对象的工作十分繁琐 。我发现使用ymin可以做得很好,但似乎必须手动调整参数。
p <- p_base +
annotation_custom(ggplotGrob(p_edges), ymin = -74) +
annotation_custom(ggplotGrob(p_nodes), ymin = -74)
print(p)
正如前面所述,这是一个拙劣的解决方案,应谨慎使用。但在有些情况下,它还是有用的。例如,当你需要在线图中使用不同标度的点尺寸和线宽时,或者需要在单个绘图中使用不同的色彩标度时,可以考虑采用这种方法。
总而言之,基于地图的网络图对于 显示节点之间的地理尺度上的连接关系 十分有用。缺点是,当有很多地理位置接近的点和许多重叠的连接时,它会 看起来非常混乱 。在仅显示地图的某些细节,或者对边的定位点添加一些抖动时,这种方法可能会很有用。
完整的R脚本可参阅github上的gist。
相关报道:
https://www.r-bloggers.com/three-ways-of-visualizing-a-graph-on-a-map/
本文为专栏文章,来自:大数据文摘,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/56193.html 。
数据分析
2018-06-18 09:08:00
关于黑客马拉松最有趣和最具挑战性的事情之一是在公共和私人排行榜上获得高分。 我密切关注了Data Hackathons系列,并发现了一个有趣的趋势。 这一趋势是基于参与者在公共和私人排行榜上的排名。
有一点非常突出,那就是在排行榜在私人排行榜上得到验证后,在排行榜上排名较高的参与者就会失去自己的位置。 有些人甚至未能在私人排行榜前20名中获得排名(图片见下图)。
最终,我发现这种现象在排行榜上带来了这样的涟漪。
 1、为什么模型会失去稳定性?
让我们使用下面的快照来了解这一点,说明各种型号的适用性:
在这里,我们试图找到尺寸和价格之间的关系。为了达到这个目的,我们采取了以下步骤:
我们已经使用线性方程建立了关系,图中显示了这个关系。从训练数据点来看,第一个曲线有很高的误差。因此,这在公共或私人排行榜上都不会表现出色。这是“Underfit”的一个例子。在这种情况下,我们的模型未能捕捉到数据的基本趋势
在第二个情节中,我们找到了价格和规模之间的正确关系,即低的训练错误和关系的普遍化
在第三个情节中,我们发现了一个几乎没有训练错误的关系。这是因为通过考虑数据点(包括噪声)中的每个偏差来开发关系,即,模型过于敏感并且捕获仅存在于当前数据集中的随机模式。这是“过度配合”的一个例子。在这种关系中,公共和私人排行榜之间的偏差可能会很大
数据科学竞赛中的一种常见做法是迭代各种模型以找到更好的表现模型。然而,由于我们更好地捕捉了关系,或者我们只是过度拟合了数据,所以很难区分这种分数的提高是否会到来。为了找到这个问题的正确答案,我们使用验证技术。这种方法有助于我们实现更普遍的关系。
2、什么是 交叉验证 ?
交叉验证是一种技术,它涉及到预留一个数据集的特定样本,在该样本上不训练模型。 稍后,您在完成该测试之前测试您的模型。
以下是交叉验证所涉及的步骤:
您保留一个样本数据集
使用数据集的其余部分训练模型
使用测试(验证)集的备用样本。 这将有助于您衡量模型性能的有效性。 如果您的模型对验证数据提供了正面结果,请继续使用当前模型。 它岩石!
一些常用的方法用于交叉验证
有多种方法可用于执行交叉验证。 我在本节中讨论了其中的一些。
验证集方法
在这种方法中,我们保留50%的数据集用于验证,其余50%用于模型训练。 然而,这种方法的一个主要缺点是,由于我们只对50%的数据集进行模型训练,所以我们很可能会错过一些有关数据的有趣信息,这会导致更高的偏差。
Python 代码: train, validation = train_test_split(data, test_size=0.50, random_state = 5)
R 代码: set.seed(101) # Set Seed so that same sample can be reproduced in future also
# Now Selecting 50% of data as sample from total ‘n’ rows of the data
sample <- sample.int(n = nrow(data), size = floor(.50*nrow(data)), replace = F)
train <- data[sample, ]
test <- data[-sample, ]
3、留下一个交叉验证(LOOCV)
在这种方法中,我们只从可用数据集中预留一个数据点,并在其余数据上训练模型。 该过程针对每个数据点进行迭代。 这也有其自身的优点和缺点。 让我们看看他们:
我们利用所有的数据点,因此偏见会很低
我们重复交叉验证过程n次(其中n是数据点的数量),这会导致更高的执行时间
这种方法导致测试模型有效性的变化更大,因为我们针对一个数据点进行测试。 所以,我们的估计会受到数据点的高度影响。 如果数据点变成异常值,则可能导致更高的变化
Python 代码: from sklearn.model_selection import LeaveOneOut
X = np.array([[1, 2], [3, 4]])
y = np.array([1, 2])
loo = LeaveOneOut()
loo.get_n_splits(X)
for train_index, test_index in loo.split(X):
print(“train:”, train_index, “validation:”, test_index)
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
R 代码: score = list()
LOOCV_function = function(x,label){
for(i in 1:nrow(x)){
training = x[-i,]
model = #… train model on training
validation = x[i,]
pred = predict(model, validation[,setdiff(names(validation),label)])
score[[i]] = rmse(pred, validation[[label]]) # score/error of ith fold
}
return(unlist(score)) # returns a vector
}
LOOCV留下一个数据点。 同样,您可以将p个训练样例留给每个迭代具有大小p的验证集。 这称为LPOCV(保留P Out交叉验证)
k-fold交叉验证
从以上两种验证方法中,我们了解到:
我们应该在大部分数据集上训练模型。否则,我们将无法阅读并识别数据中的潜在趋势。这最终会导致更高的偏见
我们还需要很好的测试数据点比例。正如我们上面所看到的,在测试模型的有效性时,少量的数据点可能会导致方差错误
我们应该多次迭代训练和测试过程。我们应该改变火车和测试数据集的分布。这有助于正确验证模型的有效性
我们是否有一种方法来处理所有这3项要求?
是!该方法被称为“k倍交叉验证”。这很容易遵循和实施。下面是它的步骤:
将整个数据集随机分成k个“折叠”
对于数据集中的每个k-fold,在k-1折叠的数据集上构建模型。然后,测试模型以检查第k次折叠的有效性
记录您在每个预测中看到的错误
重复此操作,直到每个k-折叠都充当测试集
记录的k个错误的平均值称为交叉验证错误,并将作为模型的性能指标
以下是当k = 10时的k倍验证的可视化。
现在,最常见的问题之一是,“如何选择正确的k值?”。
请记住,k值越低越有偏见,因此是不可取的。 另一方面,较高的K值偏差较小,但可能会有较大的变化。 重要的是要知道,较小的kalways值将我们带向验证集方法,而较高的k值导致LOOCV方法。
准确地说,LOOCV相当于n倍交叉验证,其中n是训练样本的数量。
Python 代码: from sklearn.model_selection import KFold
kf = RepeatedKFold(n_splits=5, n_repeats=10, random_state=None)
for train_index, test_index in kf.split(X):
print(“Train:”, train_index, “Validation:”,test_index)
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
R 代码: library(caret) data(iris) # Define train control for k fold cross validation train_control <- trainControl(method="cv", number=10) # Fit Naive Bayes Model model <- train(Species~., data=iris, trControl=train_control, method="nb") # Summarise Results print(model)
4、分层k折交叉验证
分层是重新整理数据的过程,以确保每一次折叠都是整体的良好代表。 例如,在二元分类问题中,每个类别包含50%的数据,最好安排数据,以便在每一个类别中,每个类别包含大约一半的实例。
处理偏差和方差时通常是更好的方法。 随机选择的折叠可能不足以代表小类,尤其是在类别失衡严重的情况下。
用于分层k折交叉验证的Python代码片段: from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5, random_state=None)
# X is the feature set and y is the target
for train_index, test_index in skf.split(X,y):
print(“Train:”, train_index, “Validation:”, val_index)
X_train, X_test = X[train_index], X[val_index]
y_train, y_test = y[train_index], y[val_index]
R 代码: library(caret)
# Folds are created on the basis of target variable
folds <- createFolds(factor(data$target), k = 10, list = FALSE)
话虽如此,如果火车集没有充分代表整个人口,那么使用分层k倍可能不是最好的主意。 在这种情况下,应该使用简单的k-fold交叉验证和重复。
在重复交叉验证中,交叉验证程序重复n次,得到原始样本的n个随机分区。 n次结果再次被平均(或以其他方式组合)以产生单一估计。
用于重复k-fold交叉验证的Python代码: from sklearn.model_selection import RepeatedKFold
rkf = RepeatedKFold(n_splits=5, n_repeats=10, random_state=None)
# X is the feature set and y is the target
for train_index, test_index in rkf.split(X):
print(“Train:”, train_index, “Validation:”, val_index)
X_train, X_test = X[train_index], X[val_index]
y_train, y_test = y[train_index], y[val_index]
5、敌对验证
在处理真实的数据集时,经常会遇到测试和训练集非常不同的情况。 因此,内部交叉验证技术可能给出的分数甚至不在测试分数的大部分范围内。 在这种情况下,对抗性验证提供了一个有趣的解决方案。
总体思路是根据特征分布检查训练和测试之间的相似程度。 如果似乎并非如此,我们可以怀疑它们是完全不同的。 这种直觉可以通过组合训练和测试集,分配0/1标签(0训练,1测试)和评估二元分类任务来量化。
让我们了解一下,如何在以下步骤中实现这一点:
1、从火车组中移除目标变量 train.drop([‘target’], axis = 1, inplace = True)
2、为列组中的每一行创建一个新的目标变量,对于测试集中的每一行创建一个新的目标变量 train[‘is_train’] = 1 test[‘is_train’] = 0
3、组合火车和测试数据集
df = pd.concat([train, test], axis = 0)
4、使用上面新创建的目标变量,拟合一个分类模型并预测测试集中每行的概率 y = df[‘is_train’]; df.drop(‘is_train’, axis = 1, inplace = True)
# Xgboost parameters
xgb_params = {‘learning_rate’: 0.05,
‘max_depth’: 4,
‘subsample’: 0.9,
‘colsample_bytree’: 0.9,
‘objective’: ‘binary:logistic’,
‘silent’: 1,
‘n_estimators’:100,
‘gamma’:1,
‘min_child_weight’:4}
clf = xgb.XGBClassifier(**xgb_params, seed = 10)
5、在步骤4中使用计算的概率对列车组进行排序,并将n%样本/行作为验证集(n%是要保留在验证集中的列车组的一部分) probs = clf.predict_proba(x1)[:,1]
new_df = pd.DataFrame({‘id’:train.id, ‘probs’:probs})
new_df = new_df.sort_values(by = ‘probs’, ascending=False) # 30% validation set
val_set_ids = new_df.iloc[1:np.int(new_df.shape[0]*0.3),1]
val_set_ids将为您提供来自列车集的id,它们将构成与测试集最相似的验证集。 这将使您的验证策略在火车和测试集高度不相似的情况下更加稳健。
但是,使用这种类型的验证技术时必须小心。 一旦测试集的分布发生变化,验证集可能不再是评估模型的好子集。
6、时间序列的交叉验证
随机分割时间序列数据集不起作用,因为您的数据的时间部分将会混乱。 对于时间序列预测问题,我们按照以下方式进行交叉验证。
时间序列交叉倾斜的折叠以前向链式创建
假设我们有一个时间序列,用于n年期间产品的年度消费者需求。 折叠将创建如下: fold 1: training [1], test [2]
fold 2: training [1 2], test [3]
fold 3: training [1 2 3], test [4]
fold 4: training [1 2 3 4], test [5]
fold 5: training [1 2 3 4 5], test [6]
.
.
.
fold n: training [1 2 3 ….. n-1], test [n]
我们逐步选择一个新的火车和测试集。 我们从一个训练集开始,该训练集具有拟合模型所需的最少观察次数。 逐步地,我们每次都要更换我们的火车和测试台。 在大多数情况下,1步预测可能并不重要。 在这种情况下,可以将预测原点转换为允许使用多步错误。 例如,在回归问题中,以下代码可用于执行交叉验证。
Python 代码: from sklearn.model_selection import TimeSeriesSplit
X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
y = np.array([1, 2, 3, 4])
tscv = TimeSeriesSplit(n_splits=3)
for train_index, test_index in tscv.split(X):
print(“Train:”, train_index, “Validation:”, val_index)
X_train, X_test = X[train_index], X[val_index]
y_train, y_test = y[train_index], y[val_index]
TRAIN: [0] TEST: [1]
TRAIN: [0 1] TEST: [2]
TRAIN: [0 1 2] TEST: [3]
R 代码: library(fpp)
library(forecast)
e <- tsCV(ts, Arima(x, order=c(2,0,0), h=1) #CV for arima model
sqrt(mean(e^2, na.rm=TRUE)) # RMSE
h = 1意味着我们仅仅为了提前1步预测而采取错误。
(h = 4)前面的4步错误如下图所示。 如果您想评估您的模型以进行多步骤预测,可以使用此方法。
7、自定义交叉验证技术
不幸的是,没有一种方法最适合于各种问题陈述。 通常,可以创建基于特征或特征组合的自定义交叉验证技术,如果该特征在用户在黑客马拉松中提交提交内容时给予用户稳定的交叉验证分数。
例如,在最近完成的由Analytics Vidhya完成的“机器之王”竞赛中,顶尖选手使用的最稳定的验证技术是使用campaign id变量。
请查看本主题参与者讨论的问题陈述和一些方法。
如何衡量模型的偏差 – 方差?
k次交叉验证后,我们将得到k个不同的模型估计误差(e1,e2 … ..ek)。 在理想情况下,这些误差值应该总计为零。 要返回模型的偏差,我们取所有错误的平均值。 降低平均值,更好的模型。
类似地,为了计算模型方差,我们取所有错误的标准偏差。 标准偏差的较低值表明我们的模型在训练数据的不同子集上变化不大。
我们应该把重点放在实现偏差和方差之间的平衡上。 这可以通过在一定程度上减少方差和控制偏差来完成。 这将导致更好的预测模型。 这种折衷通常会导致构建不太复杂的预测模型。 为了更深入地理解偏差 – 方差权衡,请参阅本文的第9节。
结束笔记
在本文中,我们讨论了过度拟合和交叉验证等方法以避免过度拟合。 我们还研究了不同的交叉验证方法,如验证集方法,LOOCV,k-fold交叉验证,分层k-fold等等,然后是在Iris数据集上执行的每种方法在Python和R中的实现。
您是否觉得这篇文章有帮助? 请在下面的评论部分分享您的意见/想法。 不要忘了在AV黑客马拉松中测试这些技术。 英文作者:MUTHUPANDI
英文链接:https://www.analyticsvidhya.com/blog/2018/05/improve-model-performance-cross-validation-in-python-r/
本文由 翻译小组 翻译发布,英文链接:,转载或内容合作请联系我们,未经允许谢绝转载,本文链接:https://www.afenxi.com/55906.html 。
数据分析
2018-06-16 01:53:00
大数据 文摘出品
编译:Fei、倪倪、什锦甜、钱天培
未来AI的主要应用是在建立能够学习数据然后生成原创内容的网络。这个想法已经充分应用于在自然语言处理(NLP)领域,这也是AI社区能够搭建出所谓语言模型的原因:语言模型的前提是学习句子在文章段落中的组成结构,从而生成新的内容。
在这篇文章中,我想尝试生成与很受欢迎的加拿大说唱歌手Drake(a.k.a. #6god)风格类似的说唱歌词,这肯定是件很有趣的事儿。
另外,我还想分享一下常规的 机器学习 项目渠道,因为我发现很多同学想做一些小项目,但不知道该从何处入手。
1.获取数据
首先,我们开始搜集Drake的曲库,为了节省时间我直接写了个爬虫,从网页metrolyrics.com抓取歌词。
import urllib.request as urllib2
from bs4 import BeautifulSoup
import pandas as pd
import re
from unidecode import unidecode
quote_page = ‘http://metrolyrics.com/{}-lyrics-drake.html’
filename = ‘drake-songs.csv’
songs = pd.read_csv(filename)
for index, row in songs.iterrows():
page = urllib2.urlopen(quote_page.format(row[ ‘song’ ]))
soup = BeautifulSoup(page, ‘html.parser’ )
verses = soup.find_all( ‘p’ , attrs={ ‘class’ : ‘verse’ })
lyrics = ”
for verse in verses:
text = verse.text.strip()
text = re.sub(r”\[.*\]\n”, “”, unidecode(text))
if lyrics == ”:
lyrics = lyrics + text.replace(‘ \n’, ‘|-|’ )
else :
lyrics = lyrics + ‘|-|’ + text.replace( ‘\n’ , ‘|-|’ )
songs.at[index, ‘lyrics’ ] = lyrics
print( ‘saving {}’ .format(row[ ‘song’ ]))
songs.head()
print( ‘writing to .csv’ )
songs.to_csv(filename, sep= ‘,’ , encoding= ‘utf-8’ )
我用了一个大家都很熟悉的 Python 包BeautifulSoup来抓取网页,这里参考了一位大牛Justin Yek的教程,我只花了五分钟就学会了使用。说明一下,上面的代码中我在循环里使用了songs这一数据格式,是因为我事先定义了想获得的歌曲。
教程:
https://medium.freecodecamp.org/how-to-scrape-websites-with-python-and-beautifulsoup-5946935d93fe
用DataFrame存储了所有的歌曲歌词
运行爬虫之后,我就得到了以合适的结构存储歌词的csv文件,下一步开始对数据进行预处理并且搭建模型。
2.模型介绍
现在我们来看看模型是如何生成文本的,这部分你要着重理解,因为这是真正的干货。我将先从模型设计和生成歌词模型中的关键组成部分讲起,然后,我们就可以直接进入实施阶段。
搭建语言模型主要有两种方法:
1.字符级(Character-leve)模型,
2.词汇级(Word-level)模型。
这两者的主要区别在于模型的输入和输出,接下来就具体讲解一下两个模型的工作原理。
字符级模型
在字符级模型中,输入是一连串的字符seed(种子),模型负责预测下一个字符,然后用seed + new_char组合来生成再下一个字符,以此类推。注意,因为我们每次输入的长度应保持一致,所以实际上在每次迭代输入时都要丢掉一个字符。我们可以看一个简单的直观的例子:
字符级模型生成词的迭代过程
每次迭代时,模型都是在给定种子字符的基础上预测下一个最可能生成的字符,或者利用条件概率,即找到概率P(new_char|seed)的最大值,其中new_char是字母表中的任一字母。
在此例中,字符表指所有英文字母和间隔符号的集合。(说明,字母表可以根据你的需要包含不同的字母,主要取决于你生成的语言种类)。
词汇级模型
词汇级模型和字符级模型非常相似,但是它用来生成下一个单词而非字符。这里举一个简单的例子来说明这一点:
图3. 词汇级模型生成词汇的迭代过程
现在在这个模型中,我们以一个词汇为单位向前寻找下一个词汇,而非字符。因此,我们想找到概率P(new_word|seed)的最大值,其中new_word是任一词汇。
这里要注意的是,这里我们搜索的范围比字符级要大得多。字符集模型中,我们只需从字符表中查找大概30个字符,但词汇级中每次迭代搜索的范围远远大于这个数量,因此每次迭代的运行速度更慢,但既然我们生成的是一整个词而不只是一个字符,所以也不算太糟糕。
关于词汇级模型,我最后想说明一点,我们可以通过在数据集中搜索独特的词汇来生成更加多样的词汇(这一步通常在数据预处理阶段进行)。由于词汇量可以无限大,我们其实有很多提高生成词汇性能的算法,比如词嵌入,不过关于这个问题可以再写一篇文章了。
这篇文章主要关注字符级模型,因为它更易于实施和理解,也更容易转化为复杂的词汇级模型。
数据预处理
针对字符级模型,我们将按照以下步骤进行数据预处理:
1.标记字符
对字符级模型而言,输入应该是基于字符而非字符串的形式。所以,我们首先要将歌词的每一行转变成字符的集合。
2.定义字符表
上一步,我们获得了歌词中所有可能出现的字符,接下来需要找出所有独特的字符。由于整个数据集并不大(只有140首歌),简单起见,我只保留所有英文字母以及一些特殊符号(比如空格),而忽略数字和其他的信息(因为数据集很小,我宁愿让模型少预测一些字符)。
3.创建训练序列
这里我们会用到滑动窗口的概念。通过沿着句子拖动一个固定长度的窗口,我们将建立用于训练的数据序列。下面的这张图很好地展示了滑动窗口的操作:
图4. 用滑动窗口获得输入/输出
我们通过每次平移一个字符,得到相应长度为20个字符的模型输入和长度为1个字符的模型输出。每次只平移一格的额外好处就是大大扩展了数据集的大小。
4.标注编码训练序列
最后,我们不想直接处理原始字符(尽管理论上讲每个字符都是一个数字,所以你也可以说ASCII码已经帮我们为每个字符完成了编码)。我们要做的是用唯一的数字和每个字符一一对应,这一步就是所谓的标签编码。同时,我们要建立两个非常重要的映射:character-to-index (字符到索引)和index-to-character(索引到字符)。有了这两个映射,我们就能将字母表中任意的字符编码成对应的数字,同理,也能将模型输出的数字索引解码获得相应的字符。
5.数据集的独热编码
因为我们用的是分类数据,就是说所有字符都可以被归为某个类别,所以我们要将字符编码成输入列的形式。
当我们完成以上五个步骤以后,基本就大功告成了,接下来只需要搭建和训练模型。如果你想深入更多细节,以下是五个步骤的代码供参考。
3.建立模型
我们将用循环神经网络(RNN),更具体的说是长短期记忆网络(LSTM),基于前面出现的字符集来预测下一个字符。如果这两个概念都听着陌生的话,我也提供了相关概念的快速复习:
RNN快速复习
通常,你看到的网络就是一个网状,从很多点汇聚到一个单点输出。如下图所示:
图5. 神经网络示意图
这里的神经网络是单点输入,单点输出。它适用于输入是不连续的情况,因为输入的顺序不会影响到输出结果。但是在我们的案例中,输入字符的顺序是非常重要的,因为顺序决定了对应的单词。
而RNN可以接收连续的输入,同时将前一个节点的输出作为参数输入下一个节点,从而解决输入顺序的问题。
图6. 简易RNN示意图
例如,基于序列Tryna_keep_it_simple,提取的下一个字符就应该是>
LSTM快速复习
简单的RNN网络仍存在一些问题,它不善于将非常前端的元胞信息传递到后端元胞。例如,句子Tryna keep it simple is a struggle for me中最后一个词me,如果不往回看前面出现了什么单词,那么这个单词是很难预测准确的(很可能就被预测成了Baka,cat,potato之类)。
而LSTM能够很好地解决这个问题,它在每个元胞中存储部分前面发生的事件信息(即前面出现的单词)。如下图所示:
图7. LSTM示意图,摘自Andrew Ng的深度学习课程
不仅传递前一个元胞的输出a ,同时包含之前元胞输入信息的c 也作为了下一个元胞的输入的一部分。这使得LSTM能够更好地保留上下文的信息,并适用于语言建模的预测。
编程建模
我之前学过一点Keras,所以这次就以Keras为框架编程搭建模型。其实也可以选择自己搭建模型框架,但这样会花费更多的时间。
# create sequential network, because we are passing activations
# down the network
model = Sequential()
# add LSTM layer
model.add(LSTM( 128 , input_shape=(maxlen, len(chars))))
# add Softmax layer to output one character
model.add(Dense(len(chars)))
model.add(Activation( ‘softmax’ ))
# compile the model and pick the loss and optimizer
model.compile(loss= ‘categorical_crossentropy’ , optimizer=RMSprop(lr= 0.01 ))
# train the model
model.fit(x, y, batch_size= 128 , epochs= 30 )
以上可见,我们搭建了LSTM模型并且使用了批处理,利用数据子集分批进行训练而不是一次输入所有的数据,这样可以稍微提高一点训练的速度。
4、生成歌词
训练完模型,接下来介绍如何生成下一个字符。我们首先要用用户输入的简单字符串作为随机种子。接着,我们把种子作为网络的输入来预测下一个字符,重复这个过程直到我们生成了一些新的歌词,类似于图2中所示。
以下是一些生成的歌词的例子。
注意:这些歌词都没被审核过,阅读时请自行甄别。


你可能会注意到,生成的单词有的是没有意义的,这是字符级模型的一个常见问题。这是因为输入序列经常在单词的中间被切断,使得神经网络模型学习并生成对其输入而言是有意义,但是我们看来很奇怪的新单词。
这也是在词汇级模型中可以解决的问题,但是对于仅以200行代码建立的模型来说,字符级模型所达到的效果仍然令人印象深刻。
其他应用
在这里演示的字符级模型的歌词预测功能可以被扩展到其他更有用的应用上。
例如,可以利用相同的原理对iPhone键盘上要输入的下一个单词进行预测。
图8. 键盘输入预测下一个单词
想象假如你建立一个高准确度的Python语言模型,不但能够自动填充关键词或者变量名,还可以填充大段的代码,这将帮助码农们节省多少时间啊!
你可能也注意到了文中的代码并不完整,遗漏了一些片段。请到我的Github获取更多的细节,学习搭建你自己的项目模型。
Github链接:
https://github.com/nikolaevra/drake-lyric-generator
相关报道:
https://towardsdatascience.com/generating-drake-rap-lyrics-using-language-models-and-lstms-8725d71b1b12
本文为专栏文章,来自:大数据文摘,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/55856.html 。
数据分析
2018-06-15 06:02:00
第一次接触 R语言 是我读研的时候,算到现在有5年多了。R语言可以算得上是我进入编程世界的启蒙语言,尽管在大学期间为了考试而被迫学习过计算机二级,但那真心是没有一丁点的兴趣可言。进入R的世界后,真的越来越喜欢,可以帮助我解决学术研究过程中的很多探索,最起码读研期间的所有小论文和毕业论文的案例分析都是通过R语言完成的。工作后, 数据分析 、可视化和 数据挖掘 的落地更是通过R语言帮我实现的,她对我的学习和工作起到了很大的帮助。
2015年2月份毕业开始了一份正式的工作,半年多后突然产生一个想法,就是把自己在工作中的所学所用通过公众微信号(lsxxx2011)记录下来,并给自己的公众号起名“每天进步一点点2015”。到今天已维护了近2年半的时间,积累了近160篇文章,也结识了很多对数据分析、挖掘感兴趣的朋友。曾经有好多朋友都向我问起过一个类似的问题:“我是***,对数据分析很感兴趣,但目前是R语言的小白,也自学了一段时间,但总感觉使不上力,有没有比较好的学习方法?”那就抽空来讲一讲我学习R语言的过程,希望对处于迷茫或困惑的朋友起到一点帮助。接下来,我就从以下几个方面来讲讲我学习R语言的经历:
基础篇
我接触R语言的第一本书是薛毅老师的《统计建模与R软件》,这本书个人感觉非常棒,至少有这三方面的优点:首先,该书将统计学里面的基础知识和理论都作了比较详细的剖析;其次,也详细介绍了R软件本身的基础知识,如语法、数据结构、数据读取、控制流等;最后但也是最重要的,运用R软件(很多情况都不是直接调包)将统计学模型的原理作了相应的代码实现,包括统计检验、线性回归、方差分析等。这本书我看了至少2遍,但对于R语言的初学者并不建议将这本书当作学习的第一本书。
《R语言实战》,这是一本非常好的初学R语言的资料,而且该书在今年也更新到了中文版的第二版。之所以首推这本书作为初学教程,是因为这本书偏实战,而非理论,你可以通过这本书提高R软件的使用技能,该书包括R软件编程基础、可视化作图和统计建模等内容。这本书我至少也看了2遍,书中包含了各式各样的R软件包和函数的使用,要想记住这些内容还不得不多敲代码。
《R语言数据操作》,是一本页数非常少的书籍,但都是精华。书中没有任何关于统计学相关的内容,都是在讨论数据集的管理,如缺失值处理、数据读取、日期数据的处理、正则表达式、数据汇总等。通过阅读和学习这本书,相信在数据预处理这块会对你有很大的提升,我曾经针对这本书的每一章内容作了整理,并分享到公众号中,对我本身而言,也是一个提升的过程。
当然,网上也有很多其他初学者资料,如《153分钟学会R》、《R语言经典入门_2012》、《R语言初学者指南》、《RCookbook》等。
可视化篇
在学习R软件的同时,你肯定会碰到关于使用R软件来完成数据的可视化操作,确实,R软件也是一款非常棒的可视化工具,包含了各种各样的可视化包,如graphics、lattice、plotrix、plotly、ggplot2等等。关于这一块内容的学习,你可以根据上面提到的书籍《统计建模与R软件》、《R语言实战》、《R Cookbook》等初识一下可视化,了解R软件基础包中是如何实现 数据可视化 (尽管每一个绘图函数都包含很多参数),这样会对你的绘图思维带来好处。如果要推荐几本 数据可视化 的书,我会强烈推荐《ggplot2:数据分析与图形艺术》和《R数据可视化手册》。
第一本书是ggplot2包的开发作者所编著的,在R中ggplot2也是非常火爆的可视化包,书中详细介绍了如何利用图层的思想绘制完美的统计图形,有系统的绘图组件,如geom_*函数、stat_*函数、sacle_*函数及theme类函数。这本书更多的是从绘图思想和理论出发,介绍ggplot2包的庞大功能(当然也有很多绘图案例)。
第二本书则弥补了第一本书的轻松感,说实话,我读《R数据可视化手册》的次数要比《ggplot2:数据分析与图形艺术》多一些,因为该书通过非常多的例子来对比基础包与ggplot2包在绘图方面的差异,既让我巩固了基础包的绘图方法,也提升了我对ggplot2包的浓厚兴趣,目前工作中涉及到基本统计图形(如条形图、直方图、折线图、散点图等)的绘制,我都是优选ggplot2包来完成。当然,我也把ggplot2包中常见的绘图功能作了整理,并以系列的形式分享在了公众号中。
谢益辉整理的《现代统计绘图》、肖凯的PPT《30分钟学会ggplot2》及英文版的《R语言之多变量数据可视化–Lattice》都是比较好的可视化学习材料。
数据挖掘篇
上面介绍的这些书更多的都是从数据分析角度,如果你想提升自己,研究一些目前比较火的数据挖掘知识,R语言同样提供了出路。这里介绍几本我看过的相关书籍,它们是《数据挖掘:R语言实战》、《机器学习与R语言》、《 R语言数据分析 与挖掘实战》、《数据挖掘概念与技术》和《统计学习方法》。
前面三本书都是基于R语言工具的数据挖掘实战,内容包含了常见的数据挖掘方法,如Knn、Logistic回归、决策树、朴素贝叶斯、神经网络、SVM、随机森林、Bagging、Adboosting、K均值聚类、密度聚类、EM聚类、关联规则等,每一种挖掘方法都配备了详细的数据案例,甚至也会解释挖掘函数中重要参数的含义和使用方法。当你读完这几本实战类的书,你就会发现通过R语言的调包来完成数据挖掘是特别简单的。此时,我相信你一定会对数据挖掘的理论感兴趣(最起码,你在实战数据挖掘的过程中你会反问自己为什么这个参数这样调整会更好?),因为你或多或少的感觉到你遇到了瓶颈,你想更往上走一步,但又力不从心。此时,你需要的是数据挖掘理论方面的材料来给充实自己,给自己补充能量。那这就是我接下来要跟你介绍的另两本理论书籍。
《数据挖掘概念与技术》这本书虽说是理论方面的书籍,但读起来还是蛮轻松的。书籍中的挖掘部分,首先介绍挖掘方法的概念和理论知识,然后通过某些数据集来完成手工计算的过程,对于读者来说,具有代入感,学习起来也会比较有劲。这本书相对于《数据挖掘导论》来说会稍微难一点,如果你对自己没有信心,可以先看看《数据挖掘导论》这本书。
《统计学习方法》是一本完全偏理论的书籍,包含了很多算法的推理过程,如knn算法、贝叶斯算法、决策树算法、支持向量机算法等,这些推理对读者的数学知识要求比较高,如线性代数、微积分、概率论等。如果你能够静下心来对整本书的推理进行一遍梳理(哪怕是抄一遍),我相信你一定会受益匪浅,对数据挖掘的理解会更加深刻。
其他学习资源
除了上面所提及的书本(几乎每本书我都看了至少两遍),网络上还有更多的习资源,如视频网站、论坛、博客、社区等。接下来我跟大家介绍几个我常去的免费资源:
统计之都:https://cosx.org/,里面有非常丰富的高质量文章,包含数据挖掘、可视化、统计学、分析报告等;
统计之都论坛:https://d.cosx.org/,如果你有学习上的疑问,你可以在论坛上提问,热心的网友也会给出他们的答案;同样,你也可以看别人提出的问题,尝试回答或查看别人的回复,进一步提高自己的R语言技能;
R语言官网:https://www.r-project.org/,官网中有一些不错的学习手册,同时也会定期更新R语言包,截止到写稿目前已有11,899个第三方包,使用R真的就是站在巨人的肩膀上;
经管之家:http://bbs.pinggu.org/,网站中有专门R语言论坛,其性质跟统计之都论坛相似,可以互动,相互学习;当然该网站还有其他学习资源,如SAS、计量经济论坛、Python论坛等;
数据分析网:https://www.afenxi.com/,国内数据分析第一门户,提供 大数据 新闻资讯、前沿技术、业界观点的信息平台,有数据学院、R语言、Python等学习资源;
中国统计网:http://www.itongji.cn/,网站中有非常多的好文,包含数据运营、数据分析、数据挖掘、干货分享等栏目;
Github官网:https://github.com/,在这个网站上你可以查到很多别人做过的项目案例,含有R语言代码,通过一步步学习,能够提高R语言编程技能 ;
Kaggle官网:https://www.kaggle.com/,这是一个提供数据挖掘比赛的网站,你既可以查看别人提交的作页,也可以通过报名比赛来提高自己的实战能力;
尽管有如此多的优秀学习资料,但不要贪杯,在学习过程中一定要各个击破(一本一本的用心看,用心记,用心敲代码),系统学习。如果你想学好R语言这个工具,千万不要着急,基础很重要,否则基础刚学一半就去看高级的或看别人的比赛代码,我相信你还会被打回原形。而且学习还是一个坚持的过程,坚持记得学习;坚持写写心得;坚持将每一个知识点串起来尝试替代你最拿手的工具(如Excel,SPSS等)。加油!“革命尚未成功,同志仍需努力!”
OK,到此就分享的差不多了,我在学习R语言的过程中,看书是一方面,另一方面要通过书籍中的知识点去想想我会在哪些场景下去使用,怎样使用;同时,通过查看大量的文章(论坛,博客)来学习别人所分享内容的思想、步骤和结论。作为数据分析或挖掘工作者,技能是一方面,另一方面是关于如何培养好自己的分析思维,毕竟技术这个东西是很容易替代的,而思维才是属于自己的,才是自己有别于其他人的地方。
原文作者介绍:刘顺祥( 个人公众号:数据分析1480),著名电商行业资深数据分析师,热爱数据分析与挖掘工作,擅长使用R和Python语言。
本文由 三数学院 投稿至 数据分析网 并经编辑发表,内容观点不代表本站立场,如转载请联系原作者,本文链接:https://www.afenxi.com/55258.html 。
数据分析
2018-06-08 07:37:00
作者 | 田晓旭
编辑 | 陈思
导读: 十年前,出世两年的 Hadoop 顺利通过孵化器成为了 Apache 顶级项目,同年,第一个 Hadoop 商业化公司 Cloudera 成立;五六年前,简直就是 Hadoop 的主场,社区不断建立的新组件来扩展 Hadoop 的应用场景和可用性,其中有很多组件都成功脱离 Hadoop 成为了 Apache 顶级项目,例如 HBase、Hive、ZooKeeper 等。
但是最近剧情反转的有点让人猝不及防,上上周,美股开盘之后,Cloudera 股价暴跌 43%,曾经 41 亿美元的估值缩水为 14 亿美元;上上上周,外媒爆料曾经估值 10 亿美元的 MapR 向加州就业发展局提交文件,称如果找不到新的投资人,公司将裁员 122 人。
抱团取暖,裁员闭店,Hadoop 三大发行商遭“团灭”
在 Hadoop 的发展史上,有三家公司不得不提,分别是 Cloudera、Hortonworks 和 MapR。
Cloudera 是第一家 Hadoop 商业化公司,成立于 2008 年 8 月,创始人来自 Google、FaceBook 和 Yahoo!,其首席架构师 Doug Cutting 也是 Hadoop 的第一位作者;Hortonworks 成立于 2011 年,是由 Yahoo! 的 Hadoop 团队拆分而成;MapR 成立于 2009 年,创始人 M.C.Srivas 来自于 Google。
这三家公司同属于 Hadoop 发行版提供商。所谓的“发行版”,其实是开源文化特有的,虽然在很多外行眼中,发行版只是将开源代码打包,然后在添加一些自己独创的边角料。但其实发行版真正比拼的是对海量生态系统组件的价值筛选、兼容和集成保证以及支撑服务。
同样是提供发行版,这三家公司的商业模式可以说是完全不同。Cloudera 主要是发布 Hadoop 商业版和商用工具,其核心组件 CDH 开源免费,与 Apache 社区同步;而数据治理和系统管理组件闭源,用户需要获得商业许可,除了之外,商业组件也会提供企业生产环境中必需的运维功能。
Hortonworks 的商业模式是 100% 完全开源的策略,所有产品开源,用户可免费使用。真正用来盈利的是技术服务支持。
MapR 的商业模式遵循了传统软件厂商的模式,采用私有化实现,用户通过购买软件许可来使用。
虽然三家公司的商业模式不尽相同,但是都曾从 Hadoop 中获得了红利,Cloudera 的估值在顶峰时高达 41 亿美元,而 Hortonworks 和 MapR 的估值也曾超过 10 亿美元。
不过,最近剧情急转直下,2018 年 10 月,Cloudera 和 Hortonworks 宣布合并,Cloudera 的股东将拥有新公司 60% 的股权,Hortonworks 的股东持有 40% 的股权。合并时,双方对于未来的盈利能力信心十足,“到 2020 年预计每年收入有望超过 10 亿美元。”但是,事情发展并不如预期,合并半年多后,2019 年 6 月 6 日美股开盘,Cloudera 股价暴跌 43%,曾经 41 亿美元的估值缩水为 14 亿美元。
相比于抱团取暖的 Cloudera 和 Hortonworks,MapR 的处境更为艰难了,甚至走到了“闭店裁员”的窘境,“如果再获得新的资金注入,MapR 可能会裁员 122 人,并关闭位于 Santa Clara 的总部。”据外媒报道,MapR 裁员将于 6 月 14 日生效,但是就在前几日,有消息称 MapR 将寻找新资金的最后期限延长到了 7 月 9 日。
眼看 Hadoop 三大商业公司起高楼,为何忽然之间楼斜了呢?众说纷纭,有人说是因为数据库的发展,有人说是因为云计算的崛起,还有人说是自身模式有问题?…… 为了弄清楚原因,我们采访了多位各领域的技术专家。
MongoDB 和 Elasticsearch 会是 Hadoop 的竞争对手吗?
在一篇外媒的 分析文章 中,提出了这样一个观点:在受欢迎指数、收益等方面, 大数据 其他开源供应商(如 Elastic 和 MongoDB 公司)和 Hadoop 三大商业公司呈现出了此消彼长的态势,之前没有人认为 MongoDB 和 Elasticsearch 这样的技术以及它们背后的公司能够挑战 Hadoop 及相关产品,但是现在它们做到了。
事实真如这篇文章分析的那样吗?MongoDB、Elasticsearch 和 Hadoop 真的已经成为了竞争关系吗?
针对此,我们采访多位 MongoDB 和 Elasticsearch 的技术专家,大家的观点出奇的一致,那就是从目前来看, MongoDB 和 Elasticsearch 与 Hadoop 并不构成竞争关系,甚至连重合点都很少。
“MongoDB 和 Elasticsearch 与 Hadoop 在本质上是离线处理和在线处理两个完全不同的方向,”MongoDB 中文社区主席唐建法这样认为:“Hadoop 的底层存储是基于无索引的 HDFS ,核心应用场景是对海量结构化、非结构化数据的永久存储和离线分析,例如客户肖像、流失度分析、日志分析、 商业智能 等。而 MongoDB 和 Elasticsearch 的核心场景是实时交互,通常用于人机交互场景,例如电商移动应用,其特征是响应时间一般是毫秒级到秒级。”
当然,它们之间也不是完全没有竞争的地方,但 MongoDB 、Elasticsearch 真正竞争的是 Hadoop 内的生态组件,例如 HBase、Hive、Impala 等。以 Elasticsearch 为例,它满足了比较基础的即席查询需求、在线业务检索需求,甚至是轻量的 BI 需求,这些在功能上与 Hadoop 会有所重合。
除了竞争关系,这篇外媒评论文中还提到了一个重要观点,那就是 Hadoop 使用繁琐,用户体验糟糕,MongoDB 和 Elasticsearch 使用方便,而这也导致了 Hadoop 的“衰败”。
“Hadoop 使用繁琐”的观点得到了众多技术专家的赞同。Hadoop 的本质其实就是 HDFS 存储 +MapReduce 计算框架,但是 Hadoop 发行商为了提高自己的商业竞争力,在 Hadoop 技术上增加了各种组件。Elastic 社区首席架构师吴斌称,“假设你发现了一个符合需求的组件,那么在部署使用它之前,可能还需要部署它的存储和配置管理组件,这时就不得不把精力放在诸如 HDFS、Zookeeper 等组件之上。在真正使用服务之前,用户就在 HDFS 和 Zookeeper 上付出了不少代价,这个过程往往会让入门级选手心灰意冷,进而追求门槛更低的服务,例如 Elasticsearch 或者 MongoDB。”
即使成功迈过了入门的门槛, 很多企业也会因为复杂性难以充分利用 Hadoop 。MongoDB 中文社区主席唐建法曾在两间银行看到过这样的情况,他们一家使用 MapR,一家使用 Cloudera,在系统上线 2 年后的今天,只完成了一个最简单的业务场景,行内一部分业务数据的归档功能。他们提到了一个共同的问题就是,如果说写进数据湖(Hadoop) 还算可以做得到, 把数据从里面读出来使用是更加困难的!
公有云会给 Hadoop 致命一击吗?
在很多分析文章中,都把 Hadoop 近日来的“颓势”归因为公有云的发展,Hadoop 的出现代表了当时革命性的技术,而云计算代表了数据处理的新方法,解决了与 Hadoop 相同的问题。Hadoop 主要是应用了比之前廉价的存储,但是云计算的出现,让存储变得更加廉价,且用户体验也获得了成倍提升。
云计算厂商打造了完全集成的一站式云原生服务,并且在云上提供了很多组件来替代原有的 Hadoop 组件,例如 AWS 的 S3 替代了 HDFS,K8S 替代了 Yarn。而 Hadoop 因其庞然的架构,本身并不适合以弹性灵活快速扩展的公用云环境。
公有云的出现给了 Hadoop 一定的压力,但会成为 Hadoop 的致命一击吗?
综合多位技术专家的意见,答案是否定的。
本地化部署的 Hadoop 颓势确实和公有云产品有关。 吴斌认为:“云计算厂商提供的托管服务在部署和运维上给予了用户太多便利,且从计算资源角度来看,云厂商大大降低了用户的成本,尤其是竞价实例,在给终端用户节省成本的同时,也做到了资源的合理利用和自身利益的最大化。”
在采访中,唐建法还提到了另外一种情况:“支撑大部分实体经济的企业,例如制造业、金融业、政府等强监管行业,还远远没有达到把企业全量数据存放到公有云的阶段,甚至会出于数据安全的考虑,永远不放在公有云上。”也就是说,公有云也不是银弹,即使发展得更好,也不可能完全侵占 Hadoop 的应用场景。
在很多分析文章都把云公司和 Hadoop 发行版公司放在了对立的两端, 事实上它们并不是天然的对手 ,Hadoop 发行版公司也在积极的向云端转型,甚至 Cloudera 原本的初衷就是提供云服务。Cloudera 创始人在某次访谈中提到:“Cloudera 在创建时原本打算做的服务是类似于现在 AWS 的 Elastic MapReduce 那样的云上服务。但很快发现这个模式太超前,所以转向了做 Hadoop 发行商的角色。”
云会威胁 Cloudera 吗?Cloudera 创始人 Mike Olson 在 2018 年接受采访时,是这样回答的:“如果五年后我们只是一个本地部署供应商,我们将成为一个注脚。我们的大好机会是帮助客户迁移到云,并提供云和本地部署之间的可移植性。由于我们在早期所做的赌注,我们可以让用户在不编码到专有 API 的情况下进行迁移。我们与所有的超大规模云提供商都有良好的合作关系。当然,他们在某种程度上与我们竞争,但我的机会不是击败 Redshift 。Redshift 的目的是帮助那些希望训练机器学习模型的客户在所有云提供商中提供这种能力。而我们的目标是将客户想要的所有可移植性与他们需要的法规和遵从性功能集成并提供给他们。”
Hadoop 三大发行商的衰落是否代表了 Hadoop 的衰败?
“Hadoop 三大发行商的衰落是否代表了 Hadoop 的衰败?”这是很多人关心的问题,也是技术人在热情讨论的问题。首先,需要明确的是 Hadoop 三大发行商无法全权代表 Hadoop,其次,与前几年相比,Hadoop 的热度确实在下降。
与其说 Hadoop 衰败,倒不如说是 Hadoop 走下了神坛。 早些年前,Hadoop 是与大数据划等号的存在,但是现在,大家对于大数据产品的需求更丰富了,眼光也更挑剔了。最早大家只要求能够处理海量数据,后来追求高效实时,而现在大家还要求经济便宜,功能丰富。
唐建法认为 Hadoop 生态的衰败并非是指技术,而是市场炒作的一种理性回归。 因为低成本、海量扩展能力,以及对半结构化、非结构化数据的支持,Hadoop 在大 数据分析 、历史数据归档方面是有独特地位的。如果 Hadoop 能够专注于擅长的离线场景,并提升用户使用体验,那么基于 Hadoop 的技术方案在未来还是很有前景的。
Hadoop 真正面临的竞争态势是什么?
既然 Hadoop 真正的竞争对手不是 MongoDB、Elasticsearch 等其它开源产品,也不是公有云,那么真正的对手是谁?
首先,我们不能简单的把 Hadoop 理解成一款产品,它是一种生态。所以,Hadoop 真正面临的其实是生态之争,而不是某款产品之争。
Elasticsearch 技术专家表示:“与 Elasticsearch 生态相比, Hadoop 的产品功能相对比较分散。Elastic Stack 的整合程度则非常高, 且 Elasticsearch 的分析速度更快更实时,从数据接入到前端分析展现都有完整的产品,打通了整条数据分析的链路,开箱即用,用户体验要好的多。”
而云计算厂商通常会选择更多的生态伙伴来一起合作,例如 Google 宣布将 MongoDB 纳入 Market Place 产品目录,AWS 与 MongoDB 签署全球金牌合作伙伴,腾讯云和 Elastic 达成合作。
与单个产品或环节的竞争不同,生态之间的竞争更加复杂多样,既包括了产业链上的生态,也包括了跨行业的生态,所以竞争结果不只是简单的争长竞短、你死我活,也有可能是互相融合、共同繁荣。Hadoop 生态与其它大数据生态各自有自己的使用场景和成熟的生态链,它们之间不只有竞争,更有互补的地方,从这个角度来看,Hadoop 未来的机会不是打败对手,而是做好自己。
本文为专栏文章,来自:AI前线,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/66122.html 。
数据分析
2019-07-04 11:34:00
担任过3家创业公司的创始人&CEO、3家企业的市场VP、5家企业的增长顾问、创造超过10亿美元的价值,并推动其中两家成功IPO…… 这是一种怎样的体验?
彪悍的人生不需要解释,本文的主人公 ––– Sean Ellis(肖恩·艾利斯) ––– 的经历用『传奇』来形容都不为过。更让人印象深刻的是,Sean Ellis 还是第一个提出 Growth Hacker( 增长黑客 )概念的人;在资本寒冬的今天,他的增长理论被众多创业者视为宝典。
图1:Sean Ellis (左)和 GrowingIO CEO 张溪梦(右)合照
这样一位大牛,到底有着怎样的经历 他对增长有何洞见?在流量红利逐渐褪去的今天,他的增长理论能给我们带来怎样的启发?
一、对增长极致的追求
在硅谷,像 Airbnb、Dropbox 和 Slack 这样独角兽的出现,标志着互联网发展的重要转变!这些公司可以在很短时间内吸引数以百万的用户、达到数十亿美元的估值,但是在传统营销上的花费几乎为零。
为什么会有这样的变化呢?
Sean Ellis 在十多年前就发现了这个问题的苗头:随着风险投资资金的减少,幸存下来的企业必须创新,把钱花到刀刃上,实现高效的增长。
(一)职场传奇经历
在1996年担任 Uproar (一家欧洲在线游戏企业)市场VP的时候,他就开始利用病毒传播让这款游戏软件传播到了40000+网站上。 在2000年所有的IPO的互联网企业中,Uproar 的获客成本是最低的。
从2003年担任 LogMeln(一家协作、远程连接软件服务商)市场VP开始,他就推行免费增值模式,同时不断打磨转化漏斗,提高付费转化率。在他的努力下,当时 LogMeln 的安装量超过3000万,2008年 LogMeln 顺利在纳斯达克IPO。
图2:Sean Ellis 职场传奇经历
因为之前在营销领域的惊艳表现,Sean Ellis 担任多家创业公司的 Head of Growth (增长负责人 或 增长顾问),其中就包括现在风靡硅谷的 Dropbox 。Sean Ellis 是在 DropBox 负责增长的,他在 DropBox 工作时间很短,不到 2 年,但是这期间每年 DropBox 的增长率在 500% 到 700% 之间(一年 5 倍到 7 倍)大约在2008-2012年间,他先后为5家创业公司提供增长咨询服务。在这个过程中,他和受雇公司的CEO一起工作,梳理公司的产品和市场逻辑,搭建完整的 数据分析 和增长框架。
图3:Sean Ellis 对 『Growth Hacker』的定义
2010年他在自己的博客上,第一次提出了『Growth Hacker』的概念。2012年 Uber 的增长负责人Andrew Chen 发表了《Growth Hacker is the new VP Marketing》一文,将『Growth Hacker』这个概念推到了大众面前。Sean Ellis 应该没想到,他提出的这个概念会对硅谷、乃至整个互联网领域产生如此深远的影响。
(二)Growth 不等于 Marketing
很多人会将 Growth 等同于 Marketing ,认为获取更多的新用户就是增长,Sean Ellis 认为这两者需要被严格区分。
从产品内部找到增长的机会,这并不是传统市场营销所需要的技能。大多数的营销人员还是在花费更多时间在外部渠道上,也包括很多品牌和活动,但是这些都离产品很远。
Growth 更加关注可以直接对增长有影响的因素,Growth Hacker 都会深入探索产品本身,提升用户参与度、留存度和病毒传播系数。在硅谷,发展很快的企业通常都有营销团队和增长团队,而增长团队倾向于向产品负责人报告。
图4:Growth 团队由多角色组成
增长团队一般通过深入了解产品以推动增长,他们往往是由技术和数据驱动的多学科团队。团队由负责增长的 产品经理 负责,包含开发者、设计师、分析师、营销人员等在内。
增长的理论博大精深,并非一个名词或者一个模型就能概括。市场VP和增长顾问的角色并不能满足Sean Ellis 对增长极致的追求,他决定把他的 Growth 理论做成产品、帮助更多的企业。
二、如何让Growth Hacker价值落地
(一)创业的三个阶段
Sean Ellis 提出了著名的『Startup Pyramid』模型,这个模型将创业公司的发展过程分为3段:Product/Market Fit、Transition to Growth 和 Growth。
图5:创业金字塔
第一阶段: Product/Market Fit(产品和市场匹配,简称PMF)。创业的初期,打造一款适合目标市场的产品至关重要。PMF是一个非常抽象的概念,很难衡量,有时候就算达到了你自己也不知道。
为此 Sean Ellis 设计了一份问卷,问正在使用产品的用户:『如果你不能再使用这个产品和服务,你的感受是什么?』Sean Ellis 提供了参考答案,如果40%及以上的人回答『非常失望』,那就说明你已经达到了产品和市场匹配状态,现在这个问题已经成为定位创业所处阶段的标杆问题。
第二阶段: Transition to Growth,过渡阶段。是不是达到PMF阶段,你就可以大力踩油门了呢?肯定不是的!在发力之前,你需要搞清楚这几个问题:你产品的核心优势是什么?用户能从你的产品中得到什么好处?如何描述你产品的价值?
Sean Ellis 认为这个过渡阶段总结起来就是两点:1)从最活跃用户那里提取产品的核心价值;2)将用户对核心价值的看法打造成吸引新用户的方法。
第三阶段: Growth,增长。如果你完成了前面两个阶段,那就开始加大油门踩下去吧。
(二)一款获得了750万美元融资的营销工具
那么,怎样才能搞清楚用户对我们产品的反馈呢?问卷调查,线下访谈,抑或是群发邮件…… 然而仔细思考下来,每种方法都有不足之处。
最后 Sean Ellis 决定做一款产品,非常方便地收集访问用户对产品的反馈, 这就是 Qualaroo!Sean Ellis 把 Qualaroo 定位为一款营销工具,只需要在网站内植入一段代码,企业就可以方便地和访问者展开交流、影响用户的特定行为,从而提高转化。
这款工具在内嵌到用户网站或博客上的同时,用户可以将调研问卷放在网站的指定页面上,例如,在页面右下角设置一个弹出问题对话框。用户增长工程师能够利用客户洞察设计出更符合用户需求的产品。
Qualaroo 获得了包括 Uber,Starbucks,Spotify和Intuit在内的众多客户,它所进行的各项调查的查阅量高达45亿人次。Qualaroo很轻松获得了750万美元的融资,Sean Ellis 在自己Growth实践的路上又前进了一步。然而他并没有止步于此,早已开启一段新的征程,并在2016年的时候卖掉了 Qualaroo。
(三)建立增长黑客社区
其实在2015年的时候,Sean Ellis 就已经建立了一个全新的网站 GrowthHackers.com (增长黑客网)。
这是一个非常垂直的交流社区,汇集了200,000多位增长领域的专家(包括市场营销,产品经理,设计师,增长工程师等),你几乎能知道硅谷圈里每一个跟增长相关的负责人或团队,Sean Ellis 简直就是硅谷的“增长人脉王”。
并且这还是一个关于增长idea收集、讨论、跟进的协作平台,用户可以在这个平台上将自己的想法不断实践。
图6:Simon作为嘉宾出席网站增长活动
表面上看只是一个简单的社区网站和协作工具,背后却是 Sean Ellis 对『增长黑客』本质的深入理解。在全新的经济形势下,充分利用互联网的网络化、 大数据 的特征,通过快速试验和迭代,不断提高产品的增长能力。
产品的增长和优化,涉及到用户体验中的每个变量以及最佳组合,比如注册步骤、产品文案、设计元素等等。如果你想知道自己的想法可不可行,唯一的方式就是测试它。测试的越多、测试的越快,你的产品优化的越快、增长得越快。
在互联网时代,曾经硅谷独享的优势现在已经能遍及世界任何一家创业公司了。对企业家们、网络市场营销和增长黑客来说,现在是增长最好的时代。 本文作者: GrowingIO 增长团队,集工程、产品、市场、分析多重角色于一身,负责拉新和用户活跃,用数据驱动业务增长。原文发于 GrowingIO 博客 和公众号,授权发布。
本文为专栏文章,来自:数据驱动增长,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/39105.html 。
数据分析
2016-11-29 08:00:00
电力 大数据公司 “行知聚能”完成千万元级天使轮融资
电力 大数据 公司“行知聚能”已完成千万元级天使轮融资,投资方为可可资本。行知聚能成立于2017年6月,通过非侵入式电力大数据进行异常诊断,为生产制造型企业提供能耗监控与设备维护管理解决方案。目前主营产品为数聚盒+数聚云,已服务于株洲湘火炬火花塞有限责任公司、千金药业、中信戴卡等区域性重点行业的标杆客户。
视比特 机器人 获数千万天使轮融资
7月10日消息:视比特机器人完成数千万元天使轮融资,图灵创投领投,道生资本、小智投资跟投。本轮融资将用于3D视觉技术研发、团队扩建、市场推广等方向。视比特机器人定位为面向物流、智能制造、新零售、大健康等领域。
Jeff Dean回应 AI 专利争议:谷歌不打算靠专利牟利
针对备受争议的AI专利争议,谷歌AI负责人Jeff Dean表示,希望开发者不必为此担心,谷歌这样做更多还是出于防御,而非进攻。谷歌并不打算靠专利牟利,但出于当前市场环境谷歌选择了先申请成专利,防止可能的碰瓷或不必要的麻烦。Jeff Dean明确,专利即便申请成功,也永远不会被当做武器,用来攻击别人或牟利工具。
阿里公布新语音合成技术KAN-TTS
昨日,阿里发布新一代语音合成技术KAN-TTS,该技术由达摩院机器智能实验室自主研发,融合了目前主流的端到端TTS技术和传统TTS技术,从多个方面改进了语音合成,可大幅提高合成语音与真人发声的相似度,并将语音合成定制成本降低10倍以上。
首个5G+AI无人机防灾及救援应用亮相成都
近日,在美丽的西岭雪山,中国电信与大邑公安局携手打造的5G+AI无人机防灾及救援应用,成功完成大邑县应急救援演练,充分展示了5G应用在山区日常巡检和野外救援中的积极作用。这是继年春运首日发布全国首个5G智慧交通管理示范应用后,中国电信成都分公司在推动5G在城市智慧管理中实际运用的又一创新实践。(四川新闻网)
谷歌收购 云存储 服务商Elastifile公司
据外媒报道,7月9日,谷歌宣布将收购云存储服务商Elastifile公司。谷歌在官方新闻稿中并未对这笔交易给出具体价格,但表示预计将在今年晚些时候完成交易。此次收购Elastifile的交易为谷歌云计算提供了更多的技术支持。谷歌表示,Elastifile将与谷歌文件存储服务集成,支持更广泛的计算和存储能力。(腾讯科技)
本文由 数据分析网 编辑发布,内容观点不代表本站立场,转载或内容合作请联系我们,本文链接:https://www.afenxi.com/66775.html 。
数据分析
2019-07-11 00:35:00
大数据 和分析法的质量,不如分析的目的来得重要。最有趣的紧张态势和争论,始终围绕着组织是否会因使用分析法而获得最大报酬,以使既有的流程行为(process behavior)更完善,或者改变公司人员的行为。
许多企业投下数百万美元用于 大数据、 大数据分析 ,并雇用 数据分析 家,但却感到很受挫。无可否认,他们现在得到了更多、更好的数据。他们的分析师和分析法也是一流的。但经理人对业务的想法和争论,似乎与过去的类型仍一样,只是他们使用的数据与分析法都比以前好得多。最终的决定可能是更加由数据驱动(data-driven),但组织文化给人的感觉仍然相同。正如一位CIO最近告诉我的,“我们现在可以做实时的分析,那是我在五年前根本无法想象的,但这么所带来的影响力,仍与我的预期差距很远。”
怎么回事?《财富》杂志1000大企业举办了几场大数据与大数据分析会议,并花费大量时间协助一些似乎对投资在分析法上的回报感到很满意的组织,结果一个明确的“数据启发法”(data heuristic)出现了。分析成果为平庸到中等的企业,用大数据和分析法来支持决策;而“分析报酬率”(Return on Analytics,简称ROA)良好的企业,使用大数据和分析法来推动并维持行为的改变。较好的数据驱动分析不仅仅是纳入既有的流程和检讨会,它们还被用来创造及鼓励不同类型的对话和互动。
“要等到管理阶层确认想要改变、并清楚知道影响的行为是什么之后,我们才会去做分析或商业情报的工作,”一位金融服务公司的CIO说。“提高合乎法规的情况和改善财务报告,是很容易获得的成果。但是,这只意味着我们使用分析法去做我们已经做得比以前好的事情。”
真正的挑战是洞察,利用 大数据和分析法,以改善解决问题和决策的方式,会掩盖组织里一个现实情况,那就是新的分析法往往需要新的行为。公司人员可能需要做更多分享和协力合作;各部门可能需要设置不同的或互补的业务流程;经理人和高级主管可能需要确保,现有的激励措施不会破坏分析带来的成长机会和效率。
例如,一家医疗用品供货商整合有关“能带来最多利润的客户”和“最赚钱产品”的分析,必须对业务人员与技术支持团队进行完整的再教育,两者都是为了“打扰”并“教育”客户有关附加价值较高的产品。这家公司了解,这些分析法不应该只是被用来支持现有的销售和服务实务,而应该被视为一种契机,可推动新型的促进式(facilitative)和顾问式(consultative)销售及支持组织。
讽刺的是,大数据和分析法的质量,不如分析的目的来得重要。最有趣的紧张态势和争论,始终围绕着组织是否会因使用分析法而获得最大报酬,以使既有的流程行为(process behavior)更完善,或者改变公司人员的行为。但大致的共识是,最有成效的对话聚焦于分析如何改变行为,而非解决问题。
“我们组织内的大多数人,历史课的表现优于数学课,”一位消费性产品分析主管告诉我。“要让公司人员了解新信息和指标可能会如何改变他们的做事方式,是比较容易的,要让他们了解根本的算法则比较困难……我们好不容易才学到,‘翻墙’(over-the-wall)数据和分析法,不是让我们的内部客户从工作中获得价值的好办法。”
得到正确的答案,甚至是问正确的问题,原来不是拥有高ROA企业的主要关切点。无可否认,数据与分析法的问题、答案,都是重要的。但更重要的是,这些问题、答案及分析法,如何与个人与机构的行为协调一致(或彼此冲突)。有时候,即使是最好的分析法也可能引发适得其反的行为。
本文由 明悦数据 投稿至 数据分析网 并经编辑发表,内容观点不代表本站立场,如转载请联系原作者,本文链接:https://www.afenxi.com/70150.html 。
数据分析
2019-08-02 17:40:00