数据预处理概述:特征浓缩、自动特征选择
实践教程
在一个视图中使用 python 实现的有用的要素工程方法
数据集应该适用于机器学习中训练的数据和算法做出的预测,以产生更成功的结果。查看数据集,可以发现有些要素比其他要素更重要,也就是说,它们对输出的影响更大。例如,当用数据集的对数值或其他数学运算(如平方根、指数运算)进行替换时,可以获得更好的结果。这里要区分的是选择适合模型和项目的数据预处理方法。这篇文章包含了不同的角度来看待数据集,以使算法更容易学习数据集。使用 python 应用程序,所有研究都变得更容易理解。
Table of Contents (TOC)
1\. Binning
2\. Polynomial & Interaction Features
3\. Non-Linear Transform
3.1\. Log Transform
3.2\. Square Root Transform
3.3\. Exponential Transform
3.4\. Box-cox Transform
3.5\. Reciprocal Transform
4\. Automatic Feature Selection
4.1\. Analysis of Variance (ANOVA)
4.2\. Model-Based Feature Selection
4.3\. Iterative Feature Selection
1.扔掉
在上一篇文章中,解释了以算法可以处理的方式对分类数据进行数字化的方法。宁滨用于将数值数据转换为分类数据,从而使模型更加灵活。考虑到数字数据,创建了由用户确定的箱数。所有数据都被填入这些范围并被重命名。现在让我们将宁滨应用于数据集中的年龄列。
import numpy as np
import pandas as pd
import matplotlib.pyplot as pltIN[1]
data=pd.read_csv('toy_dataset.csv')
data[['Age']].describe()
**OUT[2]**
**count 150000.000000
mean 44.950200
std 11.572486
min 25.000000
25% 35.000000
50% 45.000000
75% 55.000000
max 65.000000**IN[2]
def binnings(col, number_of_bins,labels):
min_val = col.min()
max_val = col.max()
space = (max_val-min_val)/number_of_bins
bin_borders=[]
for i in range(number_of_bins+1):
bin_values = min_val+space*i
bin_borders.append(bin_values)
bin_borderss = pd.cut(col, bins=bin_borders,labels=labels,include_lowest=True)
return bin_borders,bin_borderss
IN[3]
labels=["young_1","young_2","young_3","young_4","young_5","young_6","young_7","young_8","young_9","young_10"]
binnings(data['Age'],10,labels)
**OUT[3]
([25.0, 29.0, 33.0, 37.0, 41.0, 45.0, 49.0, 53.0, 57.0, 61.0, 65.0],
0 young_4
1 young_8
2 young_5
3 young_4
4 young_6
...
149995 young_6
149996 young_1
149997 young_1
149998 young_1
149999 young_3
Name: Age, Length: 150000, dtype: category**
通过将数据集中的年龄范围等间隔分成 11 个部分,创建了 10 个箱。每个范围都被赋予选定的标签(young_1……young_10)并作为列添加到数据集中。现在,如果我们想向数据集添加一个新列:
IN[4]
data['binned_age']= binnings(data['Age'],10,labels)
data
图一。OUT[4],图片由作者提供
现在让我们看看算法精度对我们创建的数据集的影响。
IN[5]
x = np.random.rand(100, 1)
y = 100 + 5 * x + np.random.randn(100, 1)
plt.scatter(x,y)
plt.xlabel('input')
plt.ylabel('output')
图二。OUT[5],图片由作者提供
IN[6] *without bin*
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=2021)
lr = LinearRegression()
lr.fit(x_train,y_train)
print("score=",lr.score(x_test,y_test))
**OUT[6]
score= 0.7120200116547827**
现在,让我们创建条块,并用条块测试新数据集。
IN[7] *create bins*
bins=np.linspace(x.min()-0.01,x.max()+0.01,9)
print(bins)
datas_to_bins = np.digitize(x, bins=bins,right=False)
np.unique(datas_to_bins)
**OUT[7]
[-0.00374919 0.12264801 0.24904522 0.37544243 0.50183963 0.62823684 0.75463404 0.88103125 1.00742846]
array([1, 2, 3, 4, 5, 6, 7, 8], dtype=int64)**IN[8] *with bins*
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(sparse=False)
x_binned=encoder.fit_transform(datas_to_bins)
x_binned_train,x_binned_test,y_binned_train,y_binned_test=train_test_split(x_binned,y,test_size=0.2,random_state=2021)
lr.fit(x_binned_train,y_binned_train)
print("score=",lr.score(x_binned_test,y_binned_test))
**OUT[8]
score= 0.7433952534198586**
可以看出,当分成 9 个部分并分组为 8 个箱时,测试数据集中的成功率从 71 增加到 74。
宁滨不会影响基于树的算法,因为它们使用拆分日期来训练模型。另一方面,它对于线性模型相当有效。
2.多项式和交互特征
可以对数据集进行的另一项改进是添加交互要素和多项式要素。如果我们考虑上一节中创建的数据集和宁滨运算,可以创建各种数学配置来增强这一点。例如,让我们以宁滨数据为例,该数据从数值变量转换为分类变量,然后用 OneHotEncoder 转换回数值变量。我们使用宁滨对通过添加 0 和 1 之间的 100 个随机数据而创建的数据集进行了分组,现在让我们将入库数据集与正常数据集合并并创建一个新数据集,或将入库数据集与正常数据集相乘并将其添加到入库数据集,或将入库数据集划分为正常数据集并将其添加到入库数据集。让我们看看所有这些配置的线性回归和得分。
IN[9]
x_combined=np.hstack([x_binned,x*x_binned])
print(x_binned.shape)
print(x.shape)
print(x_combined.shape)
x_combined_train,x_combined_test,y_combined_train,y_combined_test=train_test_split(x_combined,y,test_size=0.2,random_state=2021)
lr.fit(x_combined_train,y_combined_train)
print("score=",lr.score(x_combined_test,y_combined_test))
**OUT[9]
(100, 3)
(100, 1)
(100, 6)
score= 0.7910475179261578**IN[10]
x_combined2=np.hstack([x_binned,x])
x_combined2_train,x_combined2_test,y_combined2_train,y_combined2_test=train_test_split(x_combined2,y,test_size=0.2,random_state=2021)
lr.fit(x_combined2_train,y_combined2_train)
print("score=",lr.score(x_combined2_test,y_combined2_test))
**OUT[10]
score= 0.7203969392138159**IN[11]
x_combined3=np.hstack([x_binned,x_binned/x])
x_combined3_train,x_combined3_test,y_combined3_train,y_combined3_test=train_test_split(x_combined3,y,test_size=0.2,random_state=2021)
lr.fit(x_combined3_train,y_combined3_train)
print("score=",lr.score(x_combined3_test,y_combined3_test))
**OUT[11]
score= 0.7019604516773869**
丰富数据集的另一种方法是使用多项式要素。通过对多项式要素列中的数据进行指定次数的幂运算来扩展数据集。例如,当在多边形特征预处理中设置 4 度时,它很容易与 sklearn 库一起使用,4 个新特征将被添加为 x,x,x,x⁴.现在,让我们通过在同一数据集中添加多项式要素来观察结果。
IN[12]
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=4, include_bias=False)
x_poly=poly.fit_transform(x)
poly.get_feature_names()
**OUT[12]
['x0', 'x0^2', 'x0^3', 'x0^4']**IN[13]
x_poly_train,x_poly_test,y_poly_train,y_poly_test=train_test_split(x_poly,y,test_size=0.2,random_state=2021)
lr.fit(x_poly_train,y_poly_train)
print("score=",lr.score(x_poly_test,y_poly_test))
**OUT[13]
score= 0.7459793178415801**
使用多项式和交互功能无法获得良好结果的原因是,数据集是随机创建的。这些方法在实际项目中经常使用,效率很高。
3.非线性变换
数据集中的数值呈高斯分布这一事实非常有利于模型学习和进行预测。它可以通过一些数学运算将数据集转换为高斯分布。这就像从另一个角度看同一数据集,就像在同一信号的频率分析中使用傅立叶变换一样。相同的 mat 操作应用于该列中的所有数据。现在,在我们看一下这些方法之前,让我们准备一下我们将使用的列和 qq_plot。
IN[14]
data=pd.read_csv('CarPrice_Assignment.csv')
data.columns
**OUT[14]
Index(['car_ID', 'symboling', 'CarName', 'fueltype', 'aspiration',
'doornumber', 'carbody', 'drivewheel', 'enginelocation', 'wheelbase', 'carlength', 'carwidth', 'carheight', 'curbweight', 'enginetype', 'cylindernumber', 'enginesize', 'fuelsystem', 'boreratio', 'stroke','compressionratio', 'horsepower', 'peakrpm', 'citympg', 'highwaympg', 'price'],
dtype='object')**IN[15] *column we will use*
data['price'].describe()
**OUT[15]
count 205.000000
mean 13276.710571
std 7988.852332
min 5118.000000
25% 7788.000000
50% 10295.000000
75% 16503.000000
max 45400.000000
Name: price, dtype: float64**IN[16] *create histogram and qq plot*
import scipy.stats as stat
import pylab
def qq_plot(data,feature):
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
data[feature].hist()
plt.title('histogram')
plt.subplot(1,2,2)
stat.probplot(data[feature],dist='norm',plot=pylab)
plt.show()IN[17]
qq_plot(data,'price')
图 3。输出[17],直方图(左)和概率图(右),图片由作者提供
3.1.对数变换
列中所有数据的对数。
IN[18]
data['log'] = np.log(data['price'])
qq_plot(data,'log')
OUT[18]
图 4。输出[18],对数变换,直方图(左)和概率图(右),作者图片
3.2.平方根变换
列中所有数据的平方根。
IN[19]
data['squareroot'] = data.price**(1/2)
qq_plot(data,'squareroot')
图 5。输出[19],平方根变换,直方图(左)和概率图(右),图片作者
3.3.指数变换
列中所有数据的用户选择的指数。
IN[20]
data['exp'] = data.price**(1/1.5)
qq_plot(data,'exp')
图 6。OUT[20],指数变换,直方图(左)和概率图(右),作者图片
3.4.Boxcox 变换
它根据等式应用于列。
Box-cox 方程,来源
IN[21]
data['boxcox'],parameters = stat.boxcox(data['price'])
print(parameters)
qq_plot(data,'price')
图 7。OUT[21],box-cox 变换,直方图(左)和概率图(右),图片由作者提供
3.5.互易变换
列中的所有数据除以 1。
IN[22]
data['reciprocal'] = 1/data.price
qq_plot(data,'reciprocal')
图 8。OUT[22],倒数变换,直方图(左)和概率图(右),作者图片
4.自动特征选择
在上一节中,我们丰富了我们的特征并扩展了我们的数据集,但是由于这个操作将创建一个复杂的数据集,它可能会导致过度拟合。现在,让我们研究一下根据高维数据集或复杂数据集的要素重要性减少要素的方法。
4.1.方差分析——ANOVA
每个特征与目标的关系被单独分析,并且以用户选择的速率与目标具有较少关系的特征被排除。这种特征-目标关系是根据 p 值确定的。首先消除具有高 p 值的要素。现在让我们导入乳腺癌数据集,然后应用线性回归和决策树算法。
IN[22]
from sklearn.datasets import load_breast_cancer
data=load_breast_cancer()
x=data.data
y=data.targetIN[23]
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=2021)
lr = LinearRegression()
lr.fit(x_train,y_train)
print("score=",lr.score(x_test,y_test))
**OUT[23]
score= 0.7494572559981934**IN[24]
from sklearn.tree import DecisionTreeRegressor
dt = DecisionTreeRegressor(random_state=42)
dt.fit(x_train, y_train)
print("score on test set: ", dt.score(x_test, y_test))
**OUT[24]
score on test set: 0.8115079365079365**
添加决策树回归器是为了查看特征的重要性:
IN[25]
print(dt.feature_importances_)
**OUT[25]
[0\. 0.01755418 0\. 0\. 0.01690402 0.00845201
0.01173891 0\. 0\. 0.00375645 0.00725021 0.01126935
0.00907901 0.00991574 0.00223873 0\. 0\. 0.
0\. 0\. 0.00782594 0.0397066 0\. 0.71559469
0\. 0\. 0.01979559 0.11891856 0\. 0\. ]**IN[26]
np.argsort(dt.feature_importances_)
**OUT[26]
array([ 0, 25, 24, 22, 19, 18, 17, 16, 15, 28, 29, 2, 3, 8, 7, 14, 9, 10, 20, 5, 12, 13, 11, 6, 4, 1, 26, 21, 27, 23], dtype=int64)**
现在让我们应用方差分析:
IN[27]
from sklearn.feature_selection import SelectPercentile
select = SelectPercentile(percentile=30)
select.fit(x_train, y_train)
# transform training set
x_train_selected = select.transform(x_train)
print("X_train.shape: {}".format(x_train.shape))
print("X_train_selected.shape: {}".format(x_train_selected.shape))
**OUT[27]
X_train.shape: (455, 30)
X_train_selected.shape: (455, 9)**
百分比设置为 30,以便选择 30%的特征(9)。
具有选定特征的线性回归:
IN[28]
x_test_selected = select.transform(x_test)
lr.fit(x_train_selected, y_train)
print("Score with only selected features: {:.3f}".format(
lr.score(x_test_selected, y_test)))
**OUT[28]
Score with only selected features: 0.712**
仅用 9 个特征获得 0.712,而用 30 个特征获得 0.749。现在让我们看看 SelectPercentile 选择了哪些功能:
IN[29]
mask = select.get_support()
print(mask)
**OUT[29]
[ True False True True False False True True False False False False False False False False False False False False True False True True False False False True False False]**
4.2.基于模型的特征选择
它一次评估所有特性,并根据它们的相互作用选择特性。它根据用户设置的阈值选择重要性较高的内容。例如,如果选择阈值=中等,则选择 50%的特征。Sklearn 中阈值的默认值是均值。
IN[30]
from sklearn.feature_selection import SelectFromModel
selection = SelectFromModel(LinearRegression(), threshold="median")
selection.fit(x_train, y_train)
x_train_select = selection.transform(x_train)
print("X_train.shape:",x_train.shape)
print("X_train_l1.shape:",x_train_select.shape)
**OUT[30]
X_train.shape: (455, 30)
X_train_l1.shape: (455, 15)**IN[31]
mask = select.get_support()
print(mask)
**OUT[31]
[False False False False True True True True False True False False False False True True True True True True False False False False True False False True True True]**
具有选定特征的线性回归:
IN[32]
x_test_select = selection.transform(x_test)
print(lr.fit(x_train_select, y_train).score(x_test_select, y_test))
**OUT[32]
0.6919232554797755**
4.3.迭代特征选择
它根据某个阈值以 2 种方式工作:第一种从 0 个特征开始,根据其重要性继续添加特征,直到达到阈值。第二个选择所有特征并逐个消除它们,直到阈值。顾名思义,递归特征消除(RFE) 选择所有特征,消除特征,直到指定条件。
IN[33]
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
select = RFE(LogisticRegression(),
n_features_to_select=20)
select.fit(x_train, y_train)
# visualize the selected features:
mask = select.get_support()
print(mask)
**OUT[33]
[ True True False False True True True True True False True True True True False False False False False False True True True False True True True True True True]**
条件设置为 20 个特征,从 30 个特征开始,一个接一个地消除特征,直到剩下 20 个特征。
IN[34]
x_train_rfe= select.transform(x_train)
x_test_rfe= select.transform(x_test)
lr.fit(x_train_rfe, y_train)
print("score:",lr.score(x_test_rfe, y_test))
**OUT[34]
score: 0.7140632795679898**
回到指引点击这里。
https://ibrahimkovan.medium.com/machine-learning-guideline-959da5c6f73d
深度学习概述——从历史到基础
世贸中心遗址
一本学习深度学习本质的剧本,重点是卷积神经网络
我最近为那些想成为数据科学家的人教授了一门关于机器学习 101 的迷你课程。其中一个模块是关于深度学习的。我发现许多新手对这个话题感到困惑,主要是因为它经常被教授许多复杂的内容。在这篇文章中,我的目标是描述它足够简单,但不要太简单。希望有帮助!
本文分为以下四个部分:
- 什么是神经网络?
- 什么是深度学习?
- 如何搭建一个简单的深度学习架构?
- 如何训练一个深度学习模型?
什么是神经网络?
神经网络是一种受生物神经网络启发的计算模型,它在人脑中处理信息。神经网络由一组按层(输入、隐藏和输出)组织的人工神经元组成。这些人工神经元由突触连接,这些突触只是加权值。
—构建模块是什么?
人工神经元是具有特定数学运算的计算元件。一个神经元接受它的输入(布尔或实数),并在对输入应用预定义的操作后,通过激活函数将结果传递给其他神经元。激活函数是每个节点的一部分,它将线性函数转换为非线性函数。基本上,它决定了一个神经元是否应该放电。激活函数可以是不同的数学函数,例如 Step、Sigmoid 和 ReLU。
图 1:生物神经元(上)和人工神经元(下)。该图像已获得 Shutterstock 的许可。
一个普通的神经元(也称为感知器神经元)接受包括偏差在内的输入,并将其乘以相关的权重,然后将总和传递给阶跃函数。
—如何训练一个神经网络?
训练神经网络是指计算(或找到)网络中的权重以最小化目标函数(或损失函数)的过程。您可以将神经网络中的权重视为多项式函数(如ax^2+b*x+c
)中的参数,其中有两个主要区别。神经网络是具有高度和潜在非线性性能的多项式函数。在这里,高度意味着需要时参数的数量可以超过数百万。
有各种算法来训练神经网络,反向传播(backpropagation)是其中之一。简而言之,反向传播是一种在训练阶段使用梯度下降技术来计算神经网络中的权重的算法。在这种方法中,计算输出与期望值相比的误差,并成比例地(即,基于当前权重)反向传播以更新网络权重。网络权重基于学习速率迭代更新,直到收敛。
推荐看视频了解更多这种方法。YouTube 频道有一个描述这个话题的最好的可视化工具。
反向传播到底在做什么?—3 蓝色 1 棕色
要训练神经网络,您必须知道以下问题的答案。在开始实现一个示例项目之前,您可能不会理解它们的重要性。
- 如何初始化权重?
- 停止的标准是什么?
- 算法不收敛怎么办?
- 增加网络的复杂性有帮助吗?
**最后一件事。**如果你想了解学习率、激活函数或架构等配置参数如何影响神经网络的结果,我强烈建议查看 TensorFlow 创建的名为 Playground 的交互式演示。太美了,太有见地了!
什么是深度学习?
深度学习是一系列基于深度神经网络(具有许多隐藏层的神经网络)的特殊架构的机器学习方法,这些深度神经网络可以同时进行特征提取和分类,并且只需很少的人力。这种特殊的结构比简单完全连接的神经网络中的层更高级。这些特殊的架构大多建立在一个名为“胶囊的概念之上。胶囊是每一层中的一组神经元,它们进行大量内部计算,并输出表示数据属性(如卷积)的压缩结果。你可以阅读更多关于卷积神经网络的内容
—一个成功的故事:AlphaGo
由 Deepmind 创建的 AlphaGo 项目是深度学习的成功案例之一。正如 Deepmind 所说:“AlphaGo 是第一个打败围棋世界冠军的计算机程序”。首先,我来描述一下围棋为什么特别。
围棋是人工智能瞄准的最具挑战性的经典游戏。为什么?主要是因为玩家可以选择的移动数量。按此篇、T3 在前 2 步棋后,围棋中大概有 13 万步棋。这个数字是国际象棋中 400 种可能的走法。你可以看到 Go 中的搜索空间是无可争议的广阔。当搜索空间极其广阔时,深度学习可能是一个不错的选择。
深度学习是瞄准围棋的正确方法的另一个原因是植根于围棋的玩法。如果你问围棋手他们是如何决定一步棋的,他们通常会告诉你感觉很对。在这些你不能定义特征的场景中,你不能使用经典的机器学习算法。当确定有用的特征集不可行时,深度学习可能是一个不错的选择。
什么是卷积神经网络?
卷积神经网络(或 CNN)是一类深度学习架构,通常用于分析图像,如图像分类、对象检测和视频动作识别。一般来说,卷积神经网络被设计用于任何在其结构中具有某种空间不变性的数据,例如人脸或语音识别。空间不变性意味着,例如,图像左上角的猫耳与图像右下角的猫耳具有相同的特征。CNN 建立在下面描述的两个主要构件上。
- 卷积 —细胞神经网络是空间不变的,因为它们建立在卷积算子之上。卷积是一种数学运算,它对两个函数(信号)的乘积进行积分,其中一个信号被翻转(如果需要)。例如,在过去,卷积运算符被用于计算两个信号之间的相关性或寻找信号中的模式。该操作符对于视觉数据中的特征提取非常有效。过去几年里,计算机视觉领域取得的许多进步,部分归功于卷积神经网络。
- 池化—CNN 中的另一个构件是池化层。它的功能是逐渐减小数据的空间大小,以减小网络大小和算法对输入中要素精确位置的敏感度。网络规模转化为在训练阶段必须计算的权重数量。
有时,您还需要在输入图像的边界周围添加带有pixel_intensity=0
的额外像素,以增加有效尺寸。这有助于在应用卷积层后保持图像大小固定。这个过程叫做填充。
图 2:Alex net——图片获得了 Shutterstock 的许可。
有哪些特殊的架构?
- AlexNet — AlexNet 是卷积神经网络的成功实现,在 2012 年赢得了 ImageNet 大规模视觉识别挑战赛( ILSVRC )。该架构已由 Alex Krizhevsky、Ilya Sutskever、Geoffrey Hinton 在 NeurIPS 2012 上发表(图 2)。在这种架构中,输入是大小为 256×256 的 RGB 图像,这些图像被随机裁剪成大小为 224×224 的图像。该架构包含 65 万个神经元和 6000 万个参数。此外,在两个 GTX 580 3GB GPU 上训练需要 5-6 天。它由 5 个卷积层和 3 个全连接层组成。他们首次使用整流线性单元(ReLUs)作为激活函数。
- VGG16 — 提高深度神经网络性能的标准方法是增加深度。VGG-16 是由牛津大学视觉几何小组的人发明的。该架构有 13 个卷积层和 3 个全连接层。他们还使用 ReLU 激活功能作为 AlexNet 的传统。与 AlexNet 相比,该网络堆叠了更多层,并使用了更小尺寸的过滤器(2×2 和 3×3)。它由 138M 参数组成。
- ResNet50 — 随着网络深度的增加,精度会饱和,然后迅速下降,这主要是因为我们无法对其进行适当的训练。微软研究院用 ResNet50 解决了这个问题——使用跳过(或快捷方式)连接,同时构建更深层次的模型。更深的 CNN(高达 152 层)而不影响模型的泛化。这是一个好主意…
如何构建一个简单的深度学习架构
— Keras
Keras 是一个带有 Python 接口的高级神经网络库,可以在主要的科学计算框架上运行,如 TensorFlow(由 Google 创建)或 CNTK(由微软创建)。与 Pytorch 相比,工程师通常更喜欢提供快速开发的 Keras。您可以使用下面的 Kears 找到如何建立一个类似 VGG 的卷积神经网络。要了解更多关于如何使用 Keras 建立深度学习模型的信息,可以查看原始的文档。
**from** keras.models **import** Sequential
**from** keras.layers **import** Dense, Dropout, Flatten
**from** keras.layers **import** Conv2D, MaxPooling2D
**from** keras.optimizers **import** SGDmodel = **Sequential**()
model.add(**Conv2D**(32, (3, 3), **activation**='relu', **input_shape**=(100, 100, 3)))
model.add(**Conv2D**(32, (3, 3), **activation**='relu'))
model.add(**MaxPooling2D**(**pool_size**=(2, 2)))
model.add(**Dropout**(0.25))model.add(**Conv2D**(64, (3, 3), **activation**='relu'))
model.add(**Conv2D**(64, (3, 3), **activation**='relu'))
model.add(**MaxPooling2D**(**pool_size**=(2, 2)))
model.add(**Dropout**(0.25))model.add(**Flatten**())
model.add(**Dense**(256, **activation**='relu'))
model.add(**Dropout**(0.5))
model.add(**Dense**(10, **activation**='softmax'))**sgd** = **SGD**(**lr**=0.01, **decay**=1e-6, **momentum**=0.9, **nesterov**=True)
model.compile(**loss**='categorical_crossentropy', **optimizer**=sgd)model.fit(x_train, y_train, batch_size=32, epochs=10)
— PyTorch
PyTorch 是一个基于 python 的低级神经网络库,构建于脸书科学计算框架(Torch)之上。其工作流程类似于 Python 科学计算库(Numpy)。Pytorch 具有高度可配置性,与不需要复杂架构或特殊图层操作的开发者相比,更受研究人员的欢迎。您可以在下面找到如何使用 PyTorch 构建卷积神经网络。要了解更多关于如何使用 PyTorch 构建深度学习模型的信息,可以查看原始的文档。
**import** torch.nn **as** nn
**import** torch.nn.functional **as** F
**class** **Net(nn.Module):**
**def** __init__**(**self**):**
super**().**__init__**()**
self**.conv1** **=** **nn.Conv2d(**3**,** 6**,** 5**)**
self**.pool** **=** **nn.MaxPool2d(**2**,** 2**)**
self**.conv2** **=** **nn.Conv2d(**6**,** 16**,** 5**)**
self**.fc1** **=** **nn.Linear(**16 ***** 5 ***** 5**,** 120**)**
self**.fc2** **=** **nn.Linear(**120**,** 84**)**
self**.fc3** **=** **nn.Linear(**84**,** 10**)**
**def** **forward(**self**,** **x):**
**x** **=** self**.pool(F.relu(**self**.conv1(x)))**
**x** **=** self**.pool(F.relu(**self**.conv2(x)))**
**x** **=** **torch.flatten(x,** 1**)**
**x** **=** **F.relu(**self**.fc1(x))**
**x** **=** **F.relu(**self**.fc2(x))**
**x** **=** self**.fc3(x)**
**return** **x**
**net** **=** **Net()**
如何训练一个深度学习模型?
在本文中不可能解释关于训练神经网络的所有内容。在这里,我想阐明一些最重要的话题。
—定义
如上所述,训练神经网络是指计算网络中的权重以最小化目标函数的过程。这是一个经典的优化问题,你必须搜索使损失函数最小化的最优权重(或参数)集。搜索方法的功效决定了训练过程的速度和结果。
思考的食粮— 在机器学习算法中,我们选择一个度量(例如,准确性)来评估模型;然而,我们优化了一个不同的目标函数,并“希望”最小化它的值将改进我们关心的度量。那么,我们能做些什么来确保达到预期的要求呢?
—实施
一般来说,要实现一个搜索方法,必须对以下问题有答案:(1)“如何确定搜索方向?”以及(2)“如何确定搜索步骤?”。
如上所述,梯度下降技术已被用于训练神经网络以指导搜索过程。搜索方向由梯度算子决定,搜索步长由超参数𝝺决定,也称为学习率。简而言之,梯度下降技术中的更新机制如下:xₘ=xₙ -𝝺* ∇ f(xₙ).经典的梯度下降技术不能简单地用于深度学习技术,在深度学习技术中通常存在大量的权重(参数)和大量的数据点。⛔
🚀随机梯度下降 (SGD)是梯度下降技术的一种变体,对深度学习模型更有效。与使用批数据计算误差相反,该方法计算误差并更新训练数据集中每个数据点的模型。SGD 的搜索速度更快**,并且提供更频繁的型号更新。另一方面,每次运行的 SGD 结果不同,与标准技术相比,它的收敛更慢。**
除了只使用当前步骤的梯度来指导搜索,我们可以使用过去步骤的梯度知道最近的步骤更重要。这在优化上下文中被称为动量。因此,我们可以,例如,使用梯度步骤的指数平均值来进行更有效的搜索过程。查看下面的文章,了解更多关于动量的信息。
https://distill.pub/2017/momentum/
SGD 不管用怎么办?
我们有其他技术来解决优化问题,如 AdaGrad 或 Adam (自适应矩估计)。这些方法是梯度下降优化的变体,其自适应地改变学习速率以确保具有更有效的搜索过程。简而言之,对于搜索空间中的每个方向以及在时间中的每个时刻,学习率或搜索步长可以不同。这里可以阅读更多。如果你想学习如何在现实世界中使用这些技术,可以看看 Keras 官方文档。
感谢阅读!
如果你喜欢这个帖子,想支持我…
https://pedram-ataee.medium.com/membership
Julia 算子概述
快速浏览 Julia 编程语言中的所有操作符及其用法
https://unsplash.com/photos/Mmk63saBhDM
介绍
对于那些对朱丽亚感兴趣的人来说,进入朱丽亚的世界可能会感到困惑和恐惧。这不仅适用于 Julia 通常使用的方法,利用不同的编程概念,如多重分派,而且适用于更基本的数学函数,如加法或减法。
当学习一门新的编程语言时,最重要的事情之一就是学习这门语言中的操作符。Julia 有一些非常独特的操作符,它们不一定在整个计算机编程范围内都是标准化的。记住这一点,让我们看看这些操作符,以及它们在语言中的作用。
算术运算符
Julia 中最重要和最基本的操作符是算术操作符。这些运算符用于 Julia 中的断言和数学表达式,执行与用于表示 Julia 中运算符的字符相关的精确运算。
断言操作符
断言操作符是大多数程序员可能都熟悉的一种操作符。这由=符号表示,通常用于将变量别名设置为某种类型。
一元加号
一元加号是加法运算符的典型用法,只放在一个变量上。这将执行标识操作。恒等运算是表示给定数量和另一数量的组合的运算,其中该数量保持不变。例如,加法恒等式是 0,因为 x + 0 = 0 + x = x。这在 Julia 中表示为一元运算符,这意味着它只用于一个参数。我们可以在变量调用之前使用+ char 来调用它,就像这样:
+x
一元减操作
一元减号运算符的表示方式与一元加号运算符相同。然而,这个操作符执行的是完全不同的运算。该运算符用于将值映射到它们的加法逆运算。这基本上意味着它否定了这个数。换句话说,在《朱莉娅》中,我们可以用一元减号来表示否定——我认为这很自然也很酷。这真的符合他们“就像在报纸上一样”的方法论,我认为这很酷。
-x
二进制加号
二进制加法执行普通加法。
x + y
二进制减
二进制减执行正常的减法。
x - y
时间运算符
乘以运算符用于执行普通乘法。
x * y
除法算符
谁能想到呢?除法运算符是用来执行除法的!
x / y
整数除法运算符
该运算符将执行除法,但将始终返回一个四舍五入的整数:
x ÷ y
我认为这个很没用,因为我不知道按什么 numpad 键来创建这个符号,你可以简单地使用 round()方法来将一个浮点数转换成一个整数。
反向除法
反向除法运算符将第二个参数除以第一个参数,而不是相反。
x \ y
力量
Julia 中的幂运算符是^,每当我使用 Python 并试图调用 Xor 运算符^,以为它会给我一个指数时,这总是让我感到困惑。
x ^ 2
剩余物
余数运算符将返回两个参数相除的余数。
x % y
布尔运算符
虽然不是很令人兴奋,布尔运算符也很重要。正如所料,这些操作符专门用于 bool 类型。坦率地说,我知道最有可能知道我们到目前为止所看到的所有运算符,但是要获得朱利安运算符的真正内容,我们必须首先通过相对基本的东西。
否认
否定运算符是另一个一元运算符,它将给定的布尔值改为相反的值。用一个解释点来表示。
!x
和
布尔 and 操作符是直接从 Julia 的 Bash 中提取出来的。它被表示为&&。
x && y
或者
另一个连接操作符是 or 操作符,用||表示。
按位运算符
在计算机程序设计中,按位操作是在位串、位数组或二进制数的单个位的层次上进行操作。这通常意味着操作符用于改变操作符中的单个位。
按位非
按位 not 运算符用~表示,是一元运算符。
~100
按位 and
按位 and 运算符用“与”符号表示,是一种二元运算符。
x & y
按位或
按位“或”运算符用一个管道表示,也是一个二元运算符。
x | y
按位异或
按位异或用⊻表示,但是你也可以使用 xor()方法,这是我通常做的。
x ⊻ y
逻辑右移
逻辑右移运算符用三个向右箭头表示,是一个二元运算符。
x >>> y
算术右移
算术右移只用两个右箭头表示,也是一个二元运算符。
x >> y
逻辑或算术左移
逻辑和算术左移组合成两个向左的箭头。这当然也是一个二元运算符。
x << y
更新运算符
Julia 语言中的每个二进制位或算术运算符都有一个更新的对应部分。这些运算符用于用新类型更新变量别名。我们刚刚讨论的操作符的更新版本是
+= -= *= /= \= ÷= %= ^= &= |= ⊻= >>>= >>= <<=
矢量化运算符
基本运算符的最后一种形式是任何二进制算术运算的矢量化版本。这由操作符前面的点表示。这些当然意味着用在可迭代的向量或数组上。这些运算符的矢量化版本如下:
.+ .- .* ./ .\ .% .^
比较运算符
比较运算符用于根据某种条件从两个参数返回布尔类型。这个条件可以是数字、等式,甚至更多。
等式运算符
如果值相等,相等运算符返回 true。
x == y
不等式算子
如果值不相等,不等式运算符返回 true。
x != y
小于运算符
如果第一个参数小于第二个参数,则小于运算符返回 true。
x < y
大于运算符
如果第二个参数小于第一个参数,则大于运算符返回 true。
x > y
或等于运算符
我们可以通过简单地在运算符后添加一个等号,使小于和大于运算符都变成小于或等于和大于或等于运算符。
x >= y
y <= x
子类型运算符
不幸的是,这个列表中最令人兴奋的是子类型操作符。子类型运算符有两种用途。它是一个接受类型的二元运算符。该运算符用<:/>
abstract type AbstractTuber end
struct Potato <: AbstractTuber data::Array end
该运算符也可用于返回用于比较的布尔值,这也是它出现在本节中的原因:
x <: y
我们可以假设这个操作符的意思是“是的子类型。”如果您想了解更多关于 Julia 中子类型的一般概念,以及这个操作符在 Julia 类型层次结构中的用法,我写了一整篇文章,您可以在这里查看:
结论
我决定写这篇文章,因为 Julia 语言在它的领域中与许多其他竞争语言有一些显著的不同。当从一种语言切换到另一种语言并使用不同的操作符时,经常会感到困惑,此外,对于新程序员来说,了解他们语言中的所有操作符可能是件好事。虽然写起来很无聊,但我确实认为它可能对任何打算学习这门语言的人有所帮助。非常感谢你阅读我的文章,我很感激!
AWS 上的 ML 概述
从自动人工智能服务到构建定制深度学习模型的全面的 ML 产品资源集
图片来自 Unsplash
当你开始在本地笔记本或环境之外看待 ML 时,你就开始进入云计算的世界。像 AWS、Azure 和 GCP 这样的提供商正在他们各自的云中提供一套令人难以置信的 ML 服务,可以帮助你将 ML 带到生产级规模。更令人难以置信的是,对于所有程序员来说,ML 正在慢慢地民主化。随着人工智能的发展,算法背后的许多理论和知识都被抽象成了 AutoML 服务,使得没有人工智能经验的开发人员能够启动由尖端人工智能驱动的应用程序。这些 Auto-AI 服务涵盖了不同 ML 领域的种类**,例如 NLP 、计算机视觉、时间序列预测、等等。尽管如此,仍然需要使用 TensorFlow、PyTorch、SKLearn 等框架的定制模型。AWS 提供各种各样的服务,这些服务都属于建筑风格。在本文中,我们将探索 AWS 中这两个不同领域提供的大量服务。我还将附上这些服务的所有的代码样本**、文档和其他资源
目录
1.基于 AutoML/API 的 ML(需要较低的 ML 理论知识)
2.AWS SageMaker(更适合数据科学家/定制模型构建)
3.结论
1.基于自动人工智能/API 的 ML(需要较低的 ML 理论知识)
以下服务属于基于 AWS ML API 的服务。在这里,您不必像我们传统的做法那样构建定制的 ML 模型,而是可以通过一个 AWS SDK 如bot O3(Python SDK)以编程方式访问这些服务,以调用这些高级 API 的,并将它们集成到您的应用程序中。
包含
理解是亚马逊的主要自然语言处理服务,它自动化了许多流行的自然语言处理任务,如情感分析、命名实体识别和主题建模。understand 还在自定义分类中增加了另一层,您可以通过 ML powering understand 提供数据来训练自定义模型。理解医疗是理解的扩展,但是是为处理临床文本而定制的,例如医生笔记和测试结果。
资源:
重新认识
Rekognition 是亚马逊的主要自动计算机视觉服务。Rekognition 具有多种任务功能,例如:人脸检测、文本检测、自定义标签等。定制标签特别允许您为您正在尝试识别的特定用例/对象或项目提供/训练定制数据集。
资源:
使个性化
亚马逊个性化帮助用户建立实时个性化推荐。个性化使您可以带来一个自定义数据集,您可以像传统方式一样对其进行预处理和处理。您以个性化可以理解的特定格式提供模式和数据,它创建一个配方:个性化算法,提供基于常见用例的训练模型。创建配方后,Personalize 会创建一个解决方案,让您定制培训。在此之后部署您的个性化模型,您使用该解决方案创建一个称为个性化活动的东西,用于实时推荐。这些步骤被清晰地抽象出来,在构建模型之前,理解个性化的一般流程和术语是非常重要的。
资源:
翻译
亚马逊翻译是一款支持 71 种语言进行翻译的神经机器翻译工具。翻译还支持基于您的用例的实时和批量翻译。Translate 的另一个巧妙之处是可以附加的自定义术语。如果您需要翻译硬编码的特定单词或实体,您可以将它们插入一个自定义词典(例如:csv 文件), Translate 会将其添加到模型翻译中。
资源:
转录
Amazon Transcribe 使用自动语音识别(ASR)为他们的应用程序添加了语音到文本的功能。转录支持异步和实时转录。与“理解”类似,还有一个被称为亚马逊转录医疗的医疗扩展。转录医学符合 HIPAA 标准,您可以通过提供自定义医学词汇来提高转录准确性。
资源:
预报
Amazon Forecast 使用 ML 来处理时间序列数据和其他功能来建立预测模型。您可以将任何历史数据与您拥有的其他相关数据集结合起来,并上传到 Forecast,Forecast 将自动分析这些数据以识别重要的属性,并选择合适的预测算法(也可以由您选择),它可以为您创建预测文件以集成到您的应用程序中。为了比较预测提供的算法,请点击这里查看文档。
资源:
其他人
总结一下自动人工智能的部分,有很多其他的自动人工智能服务,你也可以在你的空闲时间探索。我已经列出了 AWS 的一些其他产品以及它们的基本功能。
- Amazon Textract :处理基于大量文本的文档数据以提取洞察力(例如:OCR)
- 亚马逊肯德拉:搜索服务
- 亚马逊波利:文本到语音服务
- 亚马逊 Lex :聊天机器人服务(对话界面)
- 其他服务
2.AWS SageMaker
介绍
SageMaker 是一个覆盖整个 ML 生命周期的巨大服务,所以在未来我会看到更多的文章和资源来深入研究它的每一个功能。在这篇文章中,我们将探索它对构建 ML 管道的特性的介绍,它涵盖了 SageMaker 的 MLOps 部分。我们将介绍提供的内置算法/模型,以及关于如何将定制模型引入框架(如 TensorFlow)的资源,涉及 SageMaker 的培训/托管部分。 SageMaker 在核心上工作的方式是通过 笔记本实例 ,它们是计算实例,让你在实例上的传统 Jupyter 笔记本/实验室设置中构建、训练和部署 ML 模型。
SageMaker 管道公司
ML 生命周期的很大一部分是创建和自动化端到端的管道。SageMaker Pipelines 是一个 CI/CD 服务,帮助创建和自动化 ML 工作流程从预处理到培训等等。在 Pipelines 中,您可以使用 SageMaker Python SDK 来定义您的工作流,以定义各个步骤。下面显示了一个来自管道示例的示例工作流。
管道示例工作流程(截图来自文档
在 Pipeline 中,您可以与各种其他 SageMaker 功能进行交互,例如功能存储、模型注册、培训和部署,从而帮助您完成 ML 端到端生命周期。
资源:
亚马逊算法
对于实际的模型训练和部署,SageMaker 提供了一套自己开发的内置算法。这些内置算法虽然类似于我们讨论的 Auto-AI 服务,但为我们添加预处理代码或在您正在构建的整体模型中引入更多库/包提供了更多的灵活性。关于这些内置算法或您带来的任何自定义算法,需要注意的一个关键特性是,SageMaker 上的所有东西都是通过 Docker 容器化的 。为了访问这些内置算法,你需要提取它们的图像**,如果是定制模型,你需要提供一个 Docker 图像。对于参考资料,我附上了内置算法及其功能的列表,以及 SageMaker 上的容器入门,以了解不同的部署选项。**
资源
SageMaker 上的定制模型
SageMaker 提供的最大灵活性是在你选择的框架** 中带来你自己的模型/容器。SageMaker 提供了内置的 Docker 图像,您可以为 TensorFlow、PyTorch 和 SkLearn 等流行的框架提取这些图像。您可以通过提供自己的定制训练/推理模型代码来构建这些图像。这种方法被称为自带模型/脚本模式。为了获得训练/推理的最大灵活性,有一种称为自带容器 的东西,如果您正在使用 AWS 不提供的框架,您可以在其中提供一个定制的 Docker 容器,其中包含您的模型的所有依赖项。SageMaker 中有各种不同的培训/托管选项,您可以根据自己的计算/模型需求进行选择。**
资源:
结论
本文概述了 AWS 提供的一些 ML 功能。每个服务都有自己的大量资源和主题来帮助优化和构建令人难以置信的 ML 应用程序。您可以将其中许多与其他 AWS 服务结合使用,以复杂的方式解决极其复杂的问题。
我希望这篇文章对 AWS 必须提供的 ML 功能/服务的介绍和概述有所帮助。我计划在未来撰写并提供更多关于这些服务和 SageMaker 功能的深入/具体的例子,所以请确保继续关注媒体以跟上我的工作。如果你对 ML & AWS 感兴趣,请随时在评论中留下任何反馈或通过 Linkedln 与我联系。感谢您的阅读!
自然语言处理应用综述
用深度学习处理文本的实用方法,已解释
自然语言处理(NLP)是人工智能的一个分支,包括一个广泛的软件领域,旨在推理和处理文本数据。NLP 技术正在快速发展,很难找出哪种 NLP 技术对行业影响最大。
在本帖中,我们将介绍和讨论自然语言处理技术,这种技术已经在现实生活中广泛采用和使用。
让我们开始吧。
自然语言处理简史
自然语言处理领域可以追溯到艾伦·图灵(Alan Turing)和图灵测试——能够如此有效地教会计算机用自然语言对话,以至于它会被误认为是人类吗?因此,NLP(以及计算机视觉)是现代人工智能研究的核心。
基于规则的自然语言处理
NLP 经历了两个不同的阶段。第一种通常被称为“优秀的老式人工智能”,其中算法被编写为使用逻辑规则解析语言。这些技术导致了 80 年代、90 年代和 2000 年代的一系列 NLP 技术,包括知识库、基于规则的推理机和语法分析器。
机器学习
最近,机器学习技术在 NLP 中的引入导致了新技术的寒武纪大爆发,其中使用大型训练语料库来监督深度学习模型,以创建围绕语言的灵活算法。本文将关注自然语言处理中的机器学习方法,包括:
- 文本分类
- 槽提取
- 对话系统
- 文本翻译
可以构建不属于这些更完善的技术的自定义 NLP 模型,但是考虑您的任务是否适合这些类别之一或者这些 NLP 技术的集合总是有用的,因为这将允许您为您的项目利用大量开源工作。
文本分类
自然语言处理中的许多任务归结为对文本进行分类的任务。在文本分类中,给机器学习算法一个类别选择,它可以放置一段给定的文本。
文本分类示例
一个示例文本分类预测
例如,如果我们正在训练一个机器人来对旅行社的用户请求进行分类,我们可以让机器人将短语“请为我在台北预订两晚的酒店住宿”放入“新预订”类别中。文本分类算法的任务是决定该分类优于其他可能的类别。
文本分类训练
为了训练一个文本分类器,你需要收集一个相似例子的数据集来展示你的机器学习算法。这个数据集将通过一个训练循环,反复通知模型它应该做出的决定。
文本分类知识库
我们最喜欢的文本分类库包括:
- 用于分类的文本转换器的高级实现。
- fastai.text — fastai 很好地实现了各种文本分类器。
槽提取
自然语言处理问题的另一个大子集属于槽提取(也称为信息提取或槽填充)的管辖范围。Slot extraction 查看一个句子并提取相关的信息,将它们传递到 Slot 类别中。
插槽提取示例
示例时隙提取预测
例如,在我们的 travel agent bot 示例中,我们可能需要文本分类所提供的额外信息,并且我们可能希望训练一个槽提取模型来提取相关细节以完成用户的请求,而不是必须通过算法来请求额外信息。
插槽提取训练
为了训练槽提取模型,您将需要收集训练数据集,就像分类一样。在这个数据集中,要提取的句子中的跨度应该突出显示,并用它们特定的槽标签进行标记。
插槽提取存储库
我们最喜欢的一些槽提取库包括:
对话系统
对话系统位于分类和填充槽的交叉点。在对话系统中,用户输入通过一个分类模型被分组为“意图”,然后通过一个槽填充模型进行调查,以寻找与用户请求相关的信息。对话系统可以在同一个模型中进行多次对话。
对话系统资源
你可以使用像 JointBert 这样的开源技术,或者使用 Rasa 或 Google 的 DialogueFlow 这样的聊天机器人服务来构建自己的对话系统。
文本翻译
文本翻译是 NLP 技术产生重大影响的另一个领域。文本翻译接受一种语言的文本输入,并依次预测目标语言的翻译序列。
文本翻译的一个例子
在我们的酒店预订示例中,我们可能希望将文本翻译成给定的目标语言,比如西班牙语。
与文本分类和槽填充不同,文本翻译不太具有可定制性,通常您将使用现成的模型,该模型已经过培训,可以在您选择的语言之间进行翻译。
结论
从事涉及自然语言处理的项目是一个令人兴奋的时刻,因为由机器学习驱动的自然语言处理技术正在迅速发展,并在行业中产生真正的影响。
在这篇文章中,我们回顾了自然语言处理中常用的一些关键技术,包括文本分类、槽提取、对话系统和文本翻译。
一如既往,快乐训练!
原载于 2021 年 1 月 6 日https://blog . apex advisors . ai。
用 5 分钟概述熊猫系列
Python 熊猫教程—第 1 部分
掌握数据科学家最流行的 Python 数据结构之一
图一。还有什么图标可以更好地代表熊猫的数据帧?(照片由弗莱彻·普莱德在 Unsplash 上拍摄)
熊猫是我们一直认为理所当然的图书馆之一。当我们从事数据项目时,我们总是专注于使用最新、最酷的深度学习框架(如 TensorFlow 或 PyTorch)来构建最佳模型。Pandas 是我们每次都不可避免地在预处理中使用的库,并且很快就忘记了它。嗯,熊猫的力量恰恰来源于此:它的方便。在本帖中,我们将介绍我们在 pandas 库中看到的主要数据结构之一:Series
让我们简单介绍一下
熊猫是什么?
Pandas 是一个 Python 库,它提供了灵活且富于表现力的数据结构,适合执行快速数学运算。它是一个全面易用的数据分析库,旨在成为领先的开源语言中立的数据分析工具。你没听错:Pandas 开发团队的目标是将其功能扩展到 Python 之外。
由于 Pandas 扩展了 NumPy 的功能,并且是在 NumPy 的基础上构建的,所以它几乎是作为 NumPy 的扩展来运行的。Pandas 还提供了几种数据可视化方法,这对于从数据集中获得洞察力非常有用。在进入高级部分之前,在这篇文章中,我们将只关注两个主要对象类型中的第一个:熊猫系列对象。
熊猫系列
一维序列和二维数据帧是 pandas 中的两种主要数据结构。尽管您可以创建更高维度的数据帧,但熊猫数据帧对象通常是二维的。另一方面,熊猫系列总是一维的。以下是系列对象的基本可视化:
图二。熊猫系列物品的可视化
进口熊猫
因为我们将在这篇文章中编码,所以请确保用下面的代码行导入 Pandas 库(也请导入 NumPy 库):
import pandas as pd
import numpy as np
熊猫系列
Series 是一维数组,能够保存任何数据类型,如整数、字符串、NumPy 对象和其他 Python 对象。它们也被标记,这是相对于 NumPy 数组的一个扩展。这些标签在熊猫 API 中被称为index
。
创建系列对象
创作一个熊猫系列相当容易。你可以使用主熊猫 API 中的pandas.Series()
函数,并将你想要转换的数据传递给熊猫系列对象,如下所示:
# The data and index variables must be defined # see below
s = pd.Series(data, index=index)
好吧,你能传递的数据可以很不一样。可以传递的一些合适的数据类型有:
- 一只熊猫
dict
或list
; - Numpy 数组;
- 像单个整数一样的标量值;
- 甚至是一串。
为了充分利用这个系列,最好传递一个带有索引值的类似列表的对象。然而,正如你在上面看到的,熊猫 API 在创建一个系列对象时非常灵活。以下是熊猫系列对象的一个示例:
data = [1,2,3,4,5]
index = ["a","b","c","d","e"]s = pd.Series(data=data, index=index, name='series 1')
print(s)
图 3。由 1 到 5 的数字组成的 Series 对象示例(作者提供的数字)
属性
一旦创建了Series
对象,就可以使用属性来查看关于系列对象的信息:
print("Index:", s.index)
print("Values:", s.values)
print("Data Type:", s.dtype)
print("Name of the Series:", s.name)
print("Length of the Series", len(s))
print("Descriptive statistics about the Series\n", s.describe())
print("Shape of the Series", s.shape)
图 4。可通过系列对象属性查看的信息(按作者分类)
您也可以使用Series.rename()
功能重命名系列对象:
s = s.rename(“new name”)
print(“Name of the Series:”, s.name)
图 5。重命名系列对象(作者图)
随机访问值和设置新值
series 对象的行为类似于 dictionary 对象;因此,也可以通过索引标签访问随机值。此外,您还可以将索引值用作属性:
# Access a random value like in dictionary objects
print("The val. at 'a' is", s['a'])# Use index values as an attribute
print("The val. at 'b' is", s.b)# get() function for random access
print("The val. at 'c' is", s.get("c"))# get() function for missing valuesprint("The val. at 'f'", s.get("f", "does not exist"))
图 6。随机访问系列对象值(图由作者提供)
此外,您可以使用我们用于 list 对象和 NumPy 数组的相同方法来访问 Series 对象的切片:
print('The first two elements of the Series object are:\n', s[:2])
但是,这还不是全部!pandas API 还提供特定的属性来访问特定的值。我们有四个具体选项:Series.at
、Series.iat
、Series.loc
和Series.iloc
。简而言之,下面是它们在一个句子中的作用:
**Series.iat**
→使用索引位置访问单个值;**Series.at**
→使用索引名称访问单个值;**Series.loc**
→按索引名访问一组值(一个切片)。**Series.iloc**
→通过索引位置访问一组值(切片)。
因此,Series.loc
和Series.iloc
属性也可以用于一组值,而Series.at
和Series.iat
属性用于单值访问。
让我们用一个例子来看看它们:
print(‘Output of s.at[“a”]’)
print(s.at[“a”])print(‘Output of s.loc[“a”:”b”]’)
print(s.loc[“a”:”b”])print(‘Output of s.iat[0]’)
print(s.iat[0])print(‘Output of s.iloc[0:2]’)
print(s.iloc[0:2])
图 7 和图 8。访问系列对象的切片和单个值(作者图)
最后,我们可以使用所有这些属性为给定的片或单个元素设置新值,如下所示:
print(“Before\n”, s)# Setting values by label:
s.at[“a”] = 100# Setting values by position
s.iat[3] = 500# Setting by assigning with a list object:
s.loc[“b”:”c”] = [33, 44]# Setting by assigning with a NumPy array:
s.iloc[4:5] = np.array([111])print(“After\n”, print(s))
图 9 和图 10。为系列对象设置新值之前和之后(作者提供的图表)
矢量化运算
对序列执行矢量化运算也非常容易,几乎与对整数值执行操作一样容易。以下是我们进行加法、除法和指数运算的一些例子:
s + 3
s / 5
s * s
图 11。加法运算(图由作者提供)|图 12。除法运算(作者图)|图 13。指数运算(图由作者提供)
但是,你并不局限于这些基本操作。您可以使用Series.apply()
函数来传递自定义函数或 lambda 函数。例如,我们可以用下面的代码将 Series 对象的值乘以 2:
s.apply(lambda x: x* 2)
图 14。Lambda 函数在系列对象中的应用(作者提供的图片)
由于这是一个介绍性的帖子,我将在这里完成它。现在你对熊猫系列物品有了更多的了解。在下一篇文章中,我们将深入研究 DataFrame 对象,这种二维数据结构对于数据科学任务非常有用。
订阅邮件列表获取完整代码
如果你喜欢这篇文章,想在 Google Colab 上获得我的教程文章的代码,并尽早获得我的最新内容,考虑订阅:✉️的邮件列表
如果你对深度学习感兴趣,也可以看看我的人工智能内容指南:
https://oyalcin.medium.com/a-guide-to-my-content-on-artificial-intelligence-c70c9b4a3b17
既然您正在阅读这篇文章,我相信我们有着相似的兴趣,并且现在/将来会从事相似的行业。那么我们就通过Linkedin来连线吧!请不要犹豫发送联系请求!Orhan g . Yal n—Linkedin
Python 中机器学习(分类)算法的性能评价指标综述
使用 Python 函数开发分类模型并计算所有流行的性能评估指标
在我看来,性能评估是机器学习中最重要的部分。因为机器学习本身已经变得相当容易,因为有了所有的库和包。任何人都可以在不太了解幕后发生的事情的情况下开发机器学习。那么绩效评估可能是一个挑战。你如何评价那个机器学习模型的性能?
像 Weka 这样的软件会在你建立模型的时候自动提供大量的性能评估参数。但是在 sklearn 或 R packages 等其他工具中,性能评估参数不会随模型自动提供。您必须选择评估模型性能的参数。
因此,我决定撰写这篇文章,总结分类模型的所有流行的性能评估指标。所以,它为你节省了一些时间。
在本文中,我将尝试使用公式、简单的解释以及使用实际示例的计算来简要解释分类模型的性能评估度量。我不会深入探究它们,因为这是一个概述或备忘单。
我们需要一个机器学习模型,在这个模型上我们将尝试所有的性能评估指标。因此,首先,我们将开发一个模型,然后逐个研究绩效评估指标。
这篇文章表现:
- 特征的选择
- 模型开发
- 绩效评估方法
我将使用这个关于关节炎的数据集。该数据集包含其他参数,我们将使用这些参数来预测一个人是否患有关节炎。请随意从以下链接下载数据集:
https://github.com/rashida048/Machine-Learning-BU/blob/main/arthritis.csv
让我们把重点放在模型开发上。但在此之前,我们需要选择功能。
特征选择
以下是该项目的数据集:
import pandas as pd
import numpy as npdf = pd.read_csv('arthritis.csv')
这个数据框太大了,我无法在这里显示截图。它总共有 108 列。这些是列:
df.columns
输出:
Index(['x.aidtst3', 'employ1', 'income2', 'weight2', 'height3', 'children', 'veteran3', 'blind', 'renthom1', 'sex1',
...
'x.denvst3', 'x.prace1', 'x.mrace1', 'x.exteth3', 'x.asthms1',
'x.michd', 'x.ltasth1', 'x.casthm1', 'x.state', 'havarth3'],
dtype='object', length=108)
最后一列“havarth3”是我们希望使用分类器预测的目标变量。这一栏告诉我们一个人是否有关节炎。它有两个价值。值 1 表示该人患有关节炎,值 2 表示该人没有关节炎。
其余的特征是输入参数。
X= df.drop(columns=["havarth3"])
y= df['havarth3']
使用 scikit-learn 库中的 train_test_split 方法,将数据集拆分为训练集和测试集:
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.34, random_state = 35)
我们现在有了培训和测试集。但是我们需要所有的 108 个训练特征吗?也许不是。
我使用 sklearn 库中可用的 SelectKBest 函数从中选择了 9 个特性。
我没有随意选择 9 这个数字。我检查了不同的其他功能选择方法,并尝试了不同的数字,即使使用这种功能选择方法,最终选择了数字 9。
请随时查看我关于特性选择的文章。我在最后提供了链接。
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classifuni = SelectKBest(score_func = f_classif, k = 9)
fit = uni.fit(X, y)reduced_training = fit.transform(x_train)
reduced_test = uni.transform(x_test)
这些是通过上述特征选择方法选择的列:
x_train.columns[fit.get_support(indices=True)].tolist()
输出:
['employ1',
'rmvteth4',
'genhlth',
'x.age.g',
'x.age80',
'x.ageg5yr',
'x.age65yr',
'x.phys14d',
'x.hcvu651']
这 9 个特征将用于分类器。
模型开发
有这么多可用的分类器。我在这里选择一个随机的森林分类器。如果您使用 sklearn 库,这相当简单。只需导入分类器,传递超参数并使训练数据适合它。
from sklearn.ensemble import RandomForestClassifierclf = RandomForestClassifier(max_depth=6, random_state=0).fit(reduced_training, y_train)
分类器完成了!现在我们将转向我们做这一切的主要目的。那就是学习所有的绩效评估指标。
机器学习的性能评估指标
精度
任何人都很容易想到的第一个是准确率。对于这个特定的项目,我们想知道准确预测了多少有关节炎和没有关节炎的人。让我们先检查一下训练集。
clf.score(reduced_test, y_test)
输出:
0.7417447018235584
是 74.17%。还不错!我们保留测试集来测试模型。让我们来测试一下:
clf.score(reduced_training, y_train)
输出:
0.7466666666666667
74.67%的训练集和测试集的准确率非常接近。所以这里不存在过度拟合的问题。
困惑 _ 矩阵
很多时候我们需要处理非常敏感的数据。例如,如果我们正在处理一个诊断癌症患者的数据集。正确诊断非常重要。
请记住,在这些情况下,准确性度量可能具有欺骗性。因为数据集可能会非常倾斜。也许 98%或更多的数据是负面的。意味着 98%或更多的情况下,患者没有癌症并且是阴性的。只有少量的数据是肯定的。在这种情况下,如果我们的分类器准确率是 98%,这意味着什么?
这可能意味着它只能正确分类癌症阴性患者,而不能诊断任何癌症阳性患者。但准确率仍高达 98%。但是在这种情况下分类器有效吗?一点也不。
因此,知道正确分类的癌症阳性患者的百分比和正确分类的癌症阴性患者的百分比是重要的。
混淆矩阵是一个由四个数字组成的 2x2 矩阵,将结果细分为真阳性、假阳性、真阴性和假阴性。定义如下:
真阳性:真阳性是被正确预测为阳性的阳性数据的数量。
假阳性:假阳性显示实际上是阴性的数据量,但分类器将其归类为阳性。
**真阴性:**被正确预测为阴性的阴性数据的数量。
**假阴性:**假阴性是被分类器错误地预测为阴性的阳性数据的数量。
您可以比较实际标签和预测标签来找出所有这些。但是这里我将导入并使用 confuion_matrix 函数。
下面是使用混淆矩阵函数的函数,并使用字典将输出标记为 tp(真阳性)、“fp”(假阳性)、fn(假阴性)和“tn”(真阴性)。
def confusion_matrix_score(clf, X, y):
y_pred = clf.predict(X)
cm = confusion_matrix(y, y_pred)
return {'tp': cm[0, 0], 'fn': cm[0, 1],
'fp': cm[1, 0], 'tn': cm[1, 1]}
接下来,只需导入混淆矩阵函数并使用上面的函数:
from sklearn.metrics import confusion_matrix
cm = confusion_matrix_score(clf, reduced_test, y_test)
cm
输出:
{'tp': 692, 'fn': 651, 'fp': 397, 'tn': 2318}
这四个参数将用于查找其他几个绩效评估指标。
真阳性率(TPR)和假阳性率(FPR)
真阳性率是真阳性(TP)除以总阳性§。如果我们看混淆矩阵,真正已经在那里了。但是总的积极因素是什么呢?总阳性是真阳性和假阴性的总和。
真阳性率(TPR) =真阳性/(真阳性+假阴性)
真实阳性率也称为敏感度。
同样,假阳性率是假阳性除以假阳性和真阴性之和。
假阳性率(FPR) =假阳性/(假阳性+真阴性)
TPR 和 FPR 都是非常重要的指标。如果我们看这个项目,我们可以发现有多少关节炎的人被正确检测出来,有多少没有关节炎的人被错误地检测为关节炎患者。为了计算它们,让我们从上面计算的混淆矩阵‘cm’中提取 tn、fp、fn 和 tp。
tn, fp, fn, tp = cm['tn'], cm['fp'], cm['fn'], cm['tp']tpr = tn/(tn+fn)
fpr = fn/(fn+tp)(tpr, fpr)
输出:
(0.7807342539575615, 0.4847356664184661)
真阳性率为 78.07%,假阳性率为 48.47%。
ROC 曲线和曲线下面积(AUC)
ROC 曲线(受试者工作特征曲线)显示了真阳性率(TPR)和假阳性率(FPR)之间的权衡。针对不同的阈值计算 TRP 和 FPR。然后将这一系列的 TPR 和 FPR 绘制成 ROC 曲线。如果曲线下面积(AUC)更接近 1,则认为该模型是有技巧的。
所以,这里是如何找到 ROC 曲线和曲线下的面积
from sklearn import metrics
metrics.plot_roc_curve(clf, reduced_test, y_test)
该图显示曲线下面积(AUC)为 0.8。
精度和校准
如果我们考虑这个项目,precision 将计算分类器正确预测关节炎患者的比例。这个公式可以写成:
从公式中可以看出,精度越高意味着真阳性越高,假阳性越低。
另一方面,回忆代表所有关节炎患者中被检测为关节炎患者的比例。如果你是第一次看到这个,这个定义可能看起来很混乱。公式如下:
所以,更高的回忆意味着更高的真阳性和更低的假阴性。回忆也叫敏感。
让我们计算一下精度和回忆:
precision = tn/(tn+fn)
recall = tn/(tn+fp)(precision, recall)
输出:
(0.7807342539575615, 0.8537753222836095)
f 分数
如您所见,精确度意味着更低的误报率,召回意味着更低的误报率。当你将要优化一个机器学习模型的时候,你需要选择你想往哪个方向走:更低的误报率还是更低的漏报率?这取决于项目要求。
F1 分数是精确度和召回率的调和平均值。该公式如下所示:
注意公式。当精确度和召回率都达到完美时,f 值为 1。
f 分数的一个更通用的公式是:
当精确度或召回率需要比另一个更重要时,使用这个公式。β的三个常用值是 1、2 或 0.5。当精度和召回权重相同时使用 1,当召回权重高于精度时使用 2,当召回权重低于精度时使用 0.5。
在本次演示中,我将使用 1 和 2 的β值,并计算 f 1 和 f2 值:
f1_score = 2*precision*recall/(precision + recall)
f2_score = 5*precision*recall/(4*precision + recall)
(f1_score, f2_score)
输出:
(0.8156228008444757, 0.8380938607274568)
精确召回曲线
精确-召回曲线显示了精确和召回之间的权衡。精确度-召回率曲线下的高区域意味着高精确度和高召回率。为此,使用不同的阈值来计算精确度和召回率。
但是没问题。我们不必手动计算不同阈值的精度和召回率。我们可以简单地使用 sklearn 库中可用的函数,该函数将为我们提供曲线以及曲线下的面积。
from sklearn.metrics import auc, plot_precision_recall_curve
plot_precision_recall_curve(clf, reduced_test, y_test)
输出:
曲线显示平均精度(AP)为 0.89。
这是中国曲线下的面积:
auc(recall, precision)
输出:
0.6555667752074759
马修斯相关系数
MCC 是二进制分类的另一个很好的性能评估指标。它考虑了真阳性、假阳性和假阴性。它返回一个介于-1 和 1 之间的值。值 1 表示完美的分类器,0 表示不比随机猜测好,而-1 表示原始标签和预测标签之间完全不一致。公式如下:
使用 python 对本项目进行计算:
mcc = (tn*tp - fn*fp)/np.sqrt((tn+fn)*(tn+fp)*(tp+fn)*(tp+fp))
mcc
输出:
0.3919014959349731
也可以使用以下函数进行计算,该函数将预测 y 和原始 y 作为参数:
**from ** **sklearn.metrics ** **import** matthews_corrcoef
matthews_corrcoef (y_test, y_pred)
输出:
0.3919014959349731
结论
所有指标都显示为二进制分类设置。但是相同的度量也可以用于多类分类问题。这种方法被称为一对一。说,你在计算精度。您将其中一个类设置为正类,将其余的类设置为负类。这样问题就变成二元的了。
希望这个关于绩效评估的讨论有所帮助。请随时在 Twitter 上关注我。
更多阅读
[## 文本数据的探索性数据分析,包括可视化和情感分析
towardsdatascience.com](/exploratory-data-analysis-of-text-data-including-visualization-and-sentiment-analysis-e46dda3dd260) https://pub.towardsai.net/dissecting-1-way-anova-and-ancova-with-examples-in-r-a3a7da83d742
文本挖掘软件选项概述
这些定性定量的软件工具需要在你的雷达上
介绍
在我的数据科学工作中,我经常向客户和合作伙伴推荐一系列软件,它们在定性和定量分析之间架起了一座桥梁。
https://adamrossnelson.medium.com/membership
我们有时将这些软件包称为定性数据分析软件(QDAS)。他们人数众多。在我看来,定性这个名称是用词不当。对于许多这样的软件包来说,其内部都有一套强大的定量算法和功能。
我也是一个文字游戏爱好者,这些包很多都是用来给自己命名的!
如果没有这个软件家族,数据科学或分析社区将很难有效地处理像 Boswell 照片中显示的文本。
本文将确定其中的许多包,在哪里可以找到它们,并给出它们的优缺点。在适用的地方,我会提到关于它们与其他包的互操作性的信息。
按字母顺序。
ATLAS.ti
这个 QDAS 软件是可用时间最长的软件之一。该平台提供了可以与 SPSS(或任何其他可以读取 SPSS 的平台,如 R、Stata 和 Python 的 Pandas)一起工作的导出。你可以在 http://atlasti.com 找到更多——指定为商业和/或非开源。
AnSWR
AQUAD
有多种语言版本。主网站是德语的。下拉菜单提供英语和其他语言的访问。你可以在https://www.aquad.de/找到更多——这个工具值得了解,因为作者在他们的网站上维护了参考书目。
卡珊德拉
这个包的大部分文档都是法语的。对于那些寻求能够在所有主流操作系统(Mac、Windows 和 Linus)上运行良好的软件的人来说,这是值得一看的。更多在线尽在http://cassandre.ulg.ac.be/。
计算机辅助文本标记分析(CATMA)
现在,在其第六个主要版本中,该软件拥有高度的稳定性和成熟性,受到用户群的高度赞赏。适用于 Windows、Mac OS 和 Linus。汉堡大学的研究人员为人文学科的研究人员开发了这个平台。更多在线尽在https://catma.de/。
下一代纲要
原名纲要(现已退休)。该软件可通过其 GitHub repo 获得。它将自己描述为对“对话映射和思维映射”有用,并继续解释“但它的用途几乎是无限的。”遗留产品信息在线存档。更新后的下一代包在:【https://github.com/CompendiumNG/CompendiumNG】T4。
Dedoose
喜欢这个的拼写!Dedoose 提供了一个基于 web 的用户界面。加州大学洛杉矶分校的学者最初在威廉·格兰特基金会的支持下开发了这个平台。导致该平台流行的许多额外待遇和功能包括低成本、基于云的基础设施和有益的技术支持。更多在线尽在https://www.dedoose.com/。
发现文本
以前称为,编码分析工具包(CAT)。该软件提供了一个基于网络的用户界面。以前这个工具是免费和/或开源的。然而,情况不再如此。Discover Text 通过他们在 https://discovertext.com/的网站提供免费试用。
F4 分析
该平台提供了一系列与文本分析相关的服务和解决方案,而不仅仅是分析。例如,在与音频转录相关的特性和能力上与该平台相结合。该平台还支持多种语言。更多在线尽在https://www.audiotranskription.de/en/。
自由 QDA
这个项目的状况还不清楚。虽然它最后一次更新是在 2015 年,但它的代码仍然可以在:https://sourceforge.net/projects/freeqda/找到。
超研究
最初发布于 1991 年。该软件为研究人员和科学家提供了免费的有限试用版,他们可能会在您购买之前尝试一下。这个软件的一个优点是他们提供先进的技术支持。更多在线信息请访问 http://www.researchware.com/company.html。
夸利坦
这个软件的大部分文档都是德语的,有着聪明的文字游戏名称。更多在线尽在https://kwalitan.nl/。
libreQDA
这个工具来自乌拉圭,为说西班牙语的人提供了一个平台。现在由 https://tryolabs.com/的赞助和维护,关于这个包的更多信息在 Tryo 的博客上。作为 Tryo 实验室的一个项目,该项目为包括或将涉及机器学习和人工智能的项目提供支持。
语言民族志
这个包提供了对特定用例的支持。在它的网站上,这个包“表演语言民族志”。也就是说,给定代表某一现象的文档集合(例如,快乐博客;谎言;妇女撰写的文本;等等。),这些工具可以帮助分析集合并发现潜在的有趣模式。”更多在线信息,请访问 https://web . eecs . umich . edu/~ mihalcea/downloads . html # linge thn
MAXQDA
这个包的一些优点是对统计分析和数据可视化有强大的支持。这个软件包还提供了一个免费试用版。有三个级别,包括“标准”、“高级”和“专业分析”该软件包的网站提供了广泛的教育资源,对研究人员、科学家、分析师以及其他处于学习定性数据分析软件初级阶段的人非常有用。更多在线尽在https://www.maxqda.com/。
NVivo
QSR 国际公司维护和分发这一受欢迎的软件包。作为定性数据分析软件中的知名产品,该软件通常通过网站许可协议提供给许多基于大学的研究人员和科学家。此外,与 MAXQDA 类似,NVivo 网站提供广泛的教育资源,包括点播培训网络研讨会。更多在线信息请访问https://www . qsrinternational . com/nvivo-qualitative-data-analysis-software/home/。
QDA 矿工队(QDA 矿工队)
根据 Provalis 的研究,该软件可以很好地与其他软件包集成。Provalis 的这套软件的一个优点是高度模块化。配套软件包包括 WordStat 和 SimStat。从网站上看,“这些工具的互操作性允许研究人员将数字和文本数据集成到单个项目文件中,并在定量和定性数据分析之间无缝地来回移动。”更多在线尽在https://provalisresearch.com/。
夸鲁斯
又一个有趣的文字游戏。这个包赢得了荣誉,因为它最近退休了。更多在线信息请访问 http://www.ideaworks.com/qualrus/index.html(通过 Wayback 机器)。
奎尔科斯
最初由爱丁堡大学开发的基于英国的软件。许多领域的许多组织都使用这种软件,它主要支持那些对文本数据的定性分析感兴趣的人,通常是社会科学。这个软件包的特性列表包括许多有用的插图,包括展示其许多用途的动画。更多信息请访问 https://www.quirkos.com/index.html 的。
RQDA
对于流行的统计和数据科学编程语言 R 的用户来说,这个包值得一读。这个软件作为一个 R 包免费发布,带有 BSD 许可证。更多信息请访问 http://rqda.r-forge.r-project.org/的。
https://adamrossnelson.medium.com/membership
结论
本文列出了定性数据分析软件(QDAS)包以及在哪里可以找到它们。在适用的情况下,本文也给出了关于软件包优点和缺点的注释。
对于全方位服务的研究和分析工作,数据科学家和相关专业人员将从了解这些软件包中受益。我经常向客户和合作伙伴推荐这个连接定性和定量分析的软件家族。
感谢阅读
感谢阅读。把你的想法和主意发给我。你可以写信只是为了说声嗨。我期待着尽快聊天。推特:@ adamrossnelsonLinkedIn:亚当·罗斯·尼尔森在推特和脸书:亚当·罗斯·尼尔森在脸书。
scikit-learn 集群包概述
机器学习
scikit-learn 系列的第二集,解释了用于机器学习的著名 Python 库
作者图片
聚类是一种无监督的机器学习技术,其中既没有训练集,也没有预定义的类。当有许多记录时使用聚类,这些记录应该根据相似性标准(如距离)进行分组。
聚类算法将数据集作为输入,并返回标签列表作为输出,这些标签对应于相关的聚类。
聚类分析是一个迭代过程,其中,在每一步,当前迭代被评估,并被用于反馈到下一次迭代中对算法的改变,直到获得期望的结果。
scikit-learn 库提供了一个名为[sklearn.cluster](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.cluster)
的子包,它提供了最常见的聚类算法。
在这篇文章中,我描述了:
sklearn.cluster
提供的类和功能- 调谐参数
- 聚类算法的评价指标
1 类和功能
sklearn.cluster
子包定义了两种应用聚类算法的方式:类和函数。
1.1 类别
在类策略中,您应该通过指定类参数来创建所需聚类类算法的实例。然后用数据拟合算法,最后,可以使用拟合的模型来预测分类:
**from** **sklearn.cluster** **import** AffinityPropagationmodel = AffinityPropagation()
model.fit(X)
labels = model.predict(X)
1.2 功能
除了类定义之外,Scikit-learn 还提供了执行模型拟合的函数。关于类,当只有一个数据集时,可以使用函数,该数据集必须在一个点上只分析一次。
在这种情况下,调用函数就足够了,以便获得集群化的数据:
**from** **sklearn.cluster** **import** affinity_propagationresult = affinity_propagatiom(X)
2 个调谐参数
根据要调整的主要参数,聚类算法可以分为两大类:
- 要在数据中发现的聚类数
- 观测值之间的最小距离。
2.1 要发现的集群数量
通常,在这组聚类算法中,你至少要调优最大数量的聚类才能找到。在scikit-learn
中,通常这个参数被称为n_clusters
。
sklearn.cluster
包提供了以下属于该类别的聚类算法(为每个提供的算法显示了类和函数):
[**AgglomerativeClustering**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html#sklearn.cluster.AgglomerativeClustering)
[**Birch**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.Birch.html#sklearn.cluster.Birch)
[**FeatureAgglomeration**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.FeatureAgglomeration.html#sklearn.cluster.FeatureAgglomeration)
[**KMeans**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans)
/[**MiniBatchKMeans**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.MiniBatchKMeans.html#sklearn.cluster.MiniBatchKMeans)
[**SpectralClustering**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.SpectralClustering.html#sklearn.cluster.SpectralClustering)
/[**SpectralBiclustering**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.SpectralBiclustering.html#sklearn.cluster.SpectralBiclustering)
[**SpectralCoclustering**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.SpectralCoclustering.html#sklearn.cluster.SpectralCoclustering)
对于这类算法,主要的问题是找到最佳的聚类数。可以使用不同的方法,例如弯头法。
在肘形法中,计算并绘制出数量不断增加的聚类的平方和(例如从 1 到 20)。最佳的聚类数对应于斜率像弯头一样变化的点。
存在许多其他技术来计算最佳聚类数。 Matt.0 在他的一篇非常有趣的文章中阐述了它们,这篇文章名为选择最佳聚类数的 10 个技巧。
2.2 观测值之间的最小距离
在这类聚类算法中,最重要的调整参数是**距离。**在 scikit-learn 中,与距离相关的参数名称取决于算法。因此,我建议阅读与所选算法相关的文档,以发现距离参数的确切名称。
sklearn.cluster
包提供了以下属于这个类别的聚类算法(括号中是距离参数的名称):
[**AffinityPropagation**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AffinityPropagation.html#sklearn.cluster.AffinityPropagation)**(damping)**
/[**DBSCAN**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN)**(eps)**
/[**MeanShift**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.MeanShift.html#sklearn.cluster.MeanShift)**(bandwidth)**
/**mean_shift()**
[**OPTICS**](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.OPTICS.html#sklearn.cluster.OPTICS)**(max_eps)**
/**cluster_optics_xi()**
——**cluster_optics_dbscan()**
这类聚类算法的主要挑战是找到最佳距离值。一种可能的解决方案是用不同的距离值测试算法,并选择与最佳性能相关联的值。
3 项评估指标
[sklearn.metrics.cluster](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.metrics.cluster)
子包包含了用于评估聚类分析的指标。
评估聚类算法的性能并不是一件容易的事情,因为它应该验证每条记录都被分配了正确的聚类 r,即每条记录与属于其聚类的记录的相似度要比与属于其他聚类的记录的相似度高得多。
关于集群评估的更多细节可以在这篇有趣的文章中找到。
有两种评价:
- 基于监督的评估
- 基于无监督的评估
3.1 基于监督的评估
基于监督的方法(也称为外在方法)利用基础事实来执行评估。其思想是将基本事实与聚类算法的结果进行比较,以计算得分。
Scikit-learn 提供以下基于监督的方法:
[**adjusted_mutual_info_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.adjusted_mutual_info_score.html#sklearn.metrics.adjusted_mutual_info_score)
[**adjusted_rand_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.adjusted_rand_score.html#sklearn.metrics.adjusted_rand_score)
[**completeness_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.completeness_score.html#sklearn.metrics.completeness_score)
[**fowlkes_mallows_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.fowlkes_mallows_score.html#sklearn.metrics.fowlkes_mallows_score)
[**homogeneity_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.homogeneity_score.html#sklearn.metrics.homogeneity_score)
[**mutual_info_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mutual_info_score.html#sklearn.metrics.mutual_info_score)
[**normalized_mutual_info_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.normalized_mutual_info_score.html#sklearn.metrics.normalized_mutual_info_score)
[**rand_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.rand_score.html#sklearn.metrics.rand_score)
对于所有前面的函数,您应该至少提供两个参数:labels_true
(地面真实类标签)和labels_pred
(要评估的聚类标签)。
3.2 基于无监督的评估
基于非监督的方法(也称为内在方法)通过分析分类的分离程度和分类的紧密程度来评估聚类算法。
Scikit-learn 为聚类评估提供了以下固有方法:
[**calinski_harabasz_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.calinski_harabasz_score.html#sklearn.metrics.calinski_harabasz_score)
[**davies_bouldin_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.davies_bouldin_score.html#sklearn.metrics.davies_bouldin_score)
[**silhouette_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.silhouette_score.html#sklearn.metrics.silhouette_score)
[**v_measure_score**](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.v_measure_score.html#sklearn.metrics.v_measure_score)
这类函数至少接受两个参数作为输入:X
(样本之间成对距离的数组)和labels
(每个样本的标签值)。
摘要
在本文中,我描述了由 Scikit-learn 库提供的 sklearn.cluster 子包,以及用于评估集群算法质量的评估指标。
有关集群的更多信息,您可以阅读 Scikit-learn 官方文档。
如果你想发现 Scikit-learn 提供的其他类和函数,你可以关注我、订阅我的邮件列表,敬请关注。
如果你已经走了这么远来阅读,对我来说今天已经很多了。谢谢!你可以在这篇文章里读到更多关于我的内容。
相关文章
Scikit-learn 库概述—第 1 集预处理
机器学习
著名的用于机器学习的 Python 库的剧集中的描述。第一集处理预处理子包。
作者图片
Scikit-learn 是一个非常流行的用于机器学习的 Python 库。最初由 David Cournapeau 于 2007 年开发,2010 年,当法国计算机科学和自动化研究所 INRIA 参与该项目时,它开始成长。2021 年 9 月,Scikit-learn 最新版本发布,即 1.0。
Scikit-learn 提供了机器学习过程中涉及的所有步骤,包括数据预处理、特征提取、模型选择、模型训练、模型评估和模型部署。
在这篇文章中,我开始了一系列的情节,每一集都描述了 Scikit-learn 提供的一个单独的子包。Scikit-learn 被组织成一个名为sklearn
的主模块,这个主模块又被分成许多子模块。在本文中,我关注数据预处理。
用于数据预处理的所有类和函数都包含在子模块sklearn.preprocessing
中,该子模块提供以下操作:
- 特征缩放
- 特征二值化
- 特征编码
- 非线性变换
- 其他的
1 特征缩放
特征缩放涉及数据规范化和标准化。在这篇由 Baijayanta Roy 撰写的名为关于特性缩放的有趣文章中,你可以理解规范化和标准化之间的区别。
Scikit-learn 为功能缩放提供了许多类:
MaxAbsScaler()
—给定一个特征值列表,将列表中的每个值转换为 0 到 1 之间的数字。新值的计算方法是当前值除以列的最大值。MinMaxScaler()
—新值计算为当前值和最小值之差除以特征值列表的范围。RobustScaler()
—移除中间值,并根据四分位范围缩放数据。该定标器对异常值具有鲁棒性。StandardScaler()
—移除平均值并缩放至方差。这个定标器对应于经典的标准化过程。Normalizer()
—将每个值标准化为单位定额。
为了使用 whatever scaler,您应该首先实例化一个对象,例如:
scaler = StandardScaler()
然后你必须用所有可用的数据来拟合它:
scaler.fit(data)
最后,您可以将缩放器仅应用于感兴趣的数据(也可能包括所有数据)。数据集):
scaled_data = scaler.transform(subset_of_data)
或者,您可以用一个函数同时应用拟合和变换:
scaled_data = scaler.fit_transform(data)
你可以在我之前的文章中读到一个关于MinMaxScaler()
和MaxAbsScaler
的实际例子,标题是使用 Python scikit 进行数据规范化-学习。
除了所描述的类之外,Scikit-learn 还提供了一些用于特征缩放的函数,这些函数可以直接在固定数组上使用,而无需拟合过程:
maxabs_scale()
[minmax_scale](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.minmax_scale.html#sklearn.preprocessing.minmax_scale)()
normalize()
robust_scale()
scale()
2 特征二值化
特征二值化阈值数字特征获取布尔值,存储为 0 或 1。
Scikit-learn 为二进制化提供了许多类:
Binarizer()
—根据阈值将特征值设置为 0 或 1。大于阈值的值设置为 1,小于或等于阈值的值设置为 0。LabelBinarizer()
—对于每个输出标签,构建一个向量,其中元素的数量等于唯一标签的数量,然后根据向量的每个元素在哪个标签中,为其分配 1 或 0。这个类与OneHotEncoder()
非常相似,区别在于LabelBinarizer()
用于输出类,而 OneHotEncoder 用于输入特性。更多细节,你可以在 Stackoverflow 上阅读这个线程。MultilabelBinarizer()
—LabelBinarizer()
的扩展,支持多标签。
类似于缩放器,二进制化器也应该首先被实例化,然后被拟合,最后被应用于数据:
binarizer = Binarizer()
binarizer.fit(data)
binarized_data = binarizer.transform(new_data)
或者:
binarizer = Binarizer()
data = binarizer.fit_transform(data)
Scikit-learn 还为二进制化提供了有用的函数,当元素数量固定时可以使用:
binarize()
label_binarize()
正如已经说过的特征缩放,请提醒保存安装的二进制化器,因为它将在模型部署期间使用。
3 特征编码
在模型能够被拟合和评估之前,分类特征必须被转换成数字。特征编码就是这种转换。
Scikit-learn 为特征编码提供了不同的类:
LabelEncoder()
—用介于 0 和类别总数减 1 之间的值对输出标签进行编码。OneHotEncoder()
-对于每个输入分类特征,构建一个向量,其中元素的数量等于唯一标签的数量,然后根据向量的每个元素在哪个标签中,为其分配 1 或 0。OrdinalEncoder()
—每个唯一的类别值被分配一个整数值。然后,每个输入分类特征值被转换成一个数字,对应于相对类别。比如,“苹果”是 1,“橘子”是 2,“甜瓜”是 3。
每个编码的使用与前面的操作非常相似。因此,实例化所选的编码器,然后用分类数据对其进行拟合和转换就足够了。
4 非线性变换
Scikit-learn 还为非线性转换提供了一些有趣的类:
PowerTransformer()
—应用幂变换使特征更像高斯。这对于建模需要数据正态性的情况很有用。QuantileTransformer()
-变换特征以遵循均匀分布或正态分布。这是通过利用分位数信息来实现的。SplineTransformer()
—基于单变量 B 样条函数生成新的特征矩阵。FunctionTransformer()
—应用自定义变换。
每个转换器必须首先被实例化,然后用数据拟合,最后通过transform()
函数使用。
如果元素的数量是固定的,也可以直接通过以下函数进行变换,而无需任何拟合:
quantile_transform()
power_transform()
5 其他
preprocessing
包还包括以下类:
KBinsDiscretizer()
—将连续数据归入区间。KernelCenterer()
—将内核矩阵居中。PolynomialFeatures()
—生成一个新的特征矩阵,该矩阵包含所有次数小于或等于指定次数的特征的多项式组合。
还有一个有趣的功能:
add_dummy_feature()
-用虚拟输入特征扩充数据集。
摘要
在本文中,我描述了 Scikit-learn preprocessing
包的概述。许多操作和变换可应用于数据集,包括输入要素和输出类,包括要素缩放、要素二值化、要素编码、非线性变换和其他操作。要了解更多信息,你可以阅读预处理包上的官方 Scikit-learn 文档。
如果你想发现 Scikit-learn 提供的其他类和函数,可以关注我,订阅我的邮件列表敬请关注。
如果你已经走了这么远来阅读,对我来说今天已经很多了。谢谢!你可以在这篇文章里读到更多关于我的内容。
你愿意支持我的研究吗?
你可以每月订阅几美元,解锁无限的文章。
奖金
提醒将拟合的预处理操作保存到一个外部文件,因为当您部署模型时,您需要将处理过程中使用的同一 scaler 应用到新数据:
from sklearn.externals import joblibjoblib.dump(prep, 'prep.pkl')
然后,要从文件中打开 scaler,您可以执行以下代码:
prep = joblib.load('prep.pkl')
相关文章
多功能数据工具包概述
数据工程
开始使用多功能数据工具包,这是一个使数据工程师工作更高效的框架
作者图片
数据工程师的工作需要多种技能,包括构建数据管道、评估数据库、设计模式和管理模式。简而言之,数据工程师加载、提取、操作和管理数据。这项工作通常需要大量的技能,如果流程没有实现自动化,数据工程师就有可能犯很多错误,并在解决意外事件时浪费大量时间。
最近,我测试了一个非常有趣的框架,它方便了数据工程师的工作:由 VMware 在 Github 上开源发布的通用数据工具包。
多功能数据工具包允许数据工程师半自动执行任务。实际上,他们只需要关注数据和框架的一般配置,比如数据库设置和 cron 任务调度,而不用担心手动部署、版本控制和类似的事情。
换句话说,多功能数据套件简化了数据工程师的生活,因为它允许以简单快速的方式管理数据,以及快速处理意外事件。
数据工程师只需三个步骤就可以构建完整的数据处理工作负载(数据作业,在通用数据工具包语言中):
- 摄取数据
- 过程数据
- 发布数据
在本文中,我给出了通用数据工具包的概述,以及一个实际的用例,展示了它的潜力。欲了解更多信息,您可以阅读多功能数据套件完整文档。
1 概述
通用数据工具包是一个框架,使数据工程师能够开发、部署、运行和管理数据作业。一个数据作业就是数据处理工作量。
多功能数据套件由两个主要组件组成:
- 一个**数据 SDK,**提供了所有用于数据提取、转换和加载的工具,以及一个插件框架,允许根据数据应用的特定需求扩展框架。
- 一个控制服务,它允许在 Kubernetes 运行时环境中创建、部署、管理和执行数据作业。
多功能数据工具包管理三种类型的数据作业,如下图中的浅绿色所示:
作者图片
1.1 摄入工作
摄取作业包括将不同来源的数据推送到数据湖,这是原始数据的基本容器。数据可能以不同的格式提供,如 CSV、JSON、SQL 等。
摄取可以通过不同的步骤来定义,包括但不限于创建数据模式和将数据加载到表中的过程。所有这些步骤都可以通过编写数据作业(通常用 Python 或 SQL)或通过插件来指定。通用数据工具包提供了一些预打包的插件,例如用于 CSV 和 SQL 摄取,但是您可以实现自己的插件。
1.2 加工作业
处理作业允许从数据湖中包含的数据集创建精选数据集。通常,这些工作涉及数据操作,例如数据清理和数据聚合。产生的数据集存储在数据仓库中,这在概念上不同于数据湖,但在物理上可能与之一致。由于其高度可配置性,处理作业也可以与高级分析用例相关联。
通常处理作业是用 SQL 编写的,但是 Python 也可以用来实现这种类型的作业。
1.3 发布工作
发布作业包括即席查询或视图,可用于不同的目的,例如使用标准商业智能工具构建交互式仪表板,向其他应用程序发送通知或警报等。
发布作业依赖于特定的数据集,因此目前它们尚未包含在当前版本的通用数据工具包中。
2 用法示例
例如,我将开发一个本地数据湖,在这里我将摄取一个 CSV 文件,该文件包含世界城市数据库的基本版本,包含大约 41k 个位置:
作者图片
我将遵循以下步骤:
- 多功能数据套件安装
- 数据作业创建
- 摄取作业
- 加工作业
2.1 多功能数据套件安装
多功能数据套件可通过pip
轻松安装,如下所示:
pip install -U pip setuptools wheel
pip install quickstart-vdk
由于我在本地部署了所有数据作业,因此不需要安装控制服务。但是,如果您想在 Kubernetes 运行时环境上部署数据作业,您可以遵循本指南。
2.2 数据工作创建
一旦安装完毕,我就可以使用vdk
命令与多功能数据工具包进行交互。我可以通过以下命令创建新的数据作业:
vdk create -n world-cities-vdk -t my-team
其中-n
指定数据作业名称,-t
指定团队名称。关于每个vdk
命令的更多细节,我可以运行以下命令:
vdk [command-name] --help
例如:
vdk create --help
作为create
命令的结果,vdk
创建了一个新目录,其中包含一些示例文件,每个文件对应于数据作业的一个步骤。
作者图片
步骤按字母顺序执行,因此,为了便于阅读,可以从 1 开始编号。关于数据作业目录结构的更多细节,可以查看官方文档。
2.3 环境设置
在开始使用多功能数据工具包之前,需要进行初步配置。这是通过配置两个文件实现的:
requirements.txt
—该文件包含项目中开发的库的列表,每行一个;config.ini
—该文件允许配置一些基本信息,如团队名称和 cron 运行任务。
现在,我可以配置一些环境变量,包括数据库类型(在我的例子中是 sqlite)和名称(在我的例子中是vdk-cities.db
)。我可以直接从我的终端配置这些变量:
export VDK_DB_DEFAULT_TYPE=SQLITE
export VDK_INGEST_METHOD_DEFAULT=sqlite
export VDK_INGEST_TARGET_DEFAULT=vdk-cities.db
export VDK_SQLITE_FILE=vdk-cities.db
这个vdk-cities.db
文件将成为我的数据湖。
2.4 摄入工作
我已经准备好接收数据湖中的数据。首先,我在本地下载数据集,并将其放入名为source
的目录中,该目录位于数据作业父目录中。
想法是将数据集摄取到名为cities
的表中。这可以通过两种方式实现:
- 编写数据作业
- 使用
vdk-csv
插件。
2.4.1 写入数据作业
我定义了一个初步的数据作业步骤,它删除表cities
,如果它存在的话,以确保总是有一个新版本的表:
DROP TABLE IF EXISTS cities;
我在数据作业目录中将这一步保存为10_drop_cities_table.sql
。名称开头的10
将确保首先执行该步骤。
现在我定义第二个数据作业步骤,它定义了表模式,数据集将被导入到这个表模式中。数据作业步骤对应于以下简单的 SQL 代码:
CREATE TABLE cities (city NVARCHAR,
city_ascii NVARCHAR,
lat REAL,
lng REAL,
country NVARCHAR,
iso2 NVARCHAR,
iso3 NVARCHAR,
admin_name NVARCHAR,
capital NVARCHAR,
population INTEGER,
id INTEGER
);
我将此步骤保存为20_create_cities_table.sql
。
最后,我可以将数据集上传到cities
表中。我可以编写以下 Python 脚本,它将数据集作为 Pandas dataframe 加载,将其转换为 dict,然后通过多功能数据工具包提供的job_input.send_object_for_ingestion()
函数将 dict 的每一项发送到数据湖:
import logging
from vdk.api.job_input import IJobInput
import pandas as pdlog = logging.getLogger(__name__)def run(job_input: IJobInput):
log.info(f"Starting job step {__name__}")
df = pd.read_csv('source/worldcities.csv') df_dict = df.to_dict(orient='records')
for row in range(0, len(df_dict)):
job_input.send_object_for_ingestion(
payload=df_dict[row], destination_table="cities")
请注意,为了将 Python 脚本识别为数据作业 Python 步骤,需要使用run()
函数。
现在,我已经准备好运行数据作业步骤了。我移动到数据作业父目录,并运行以下命令:
vdk run world-cities-vdk
数据库vdk-cities.db
在当前目录中创建,并使用cities
表填充。我可以通过vdk query
命令或传统的sqlite
命令查询数据库:
vdk sqlite-query -q 'SELECT * FROM cities'
2.4.2 使用 **vdk-csv**
插件
将数据集加载到数据湖的另一种方法是使用插件。在我的例子中,我将使用vdk-csv
插件。我可以通过pip
轻松安装:
pip install quickstart-vdk vdk-csv
然后,我可以通过以下命令接收数据集:
vdk ingest-csv -f source/worldcities.csv -t cities
2.5 加工作业
作为一项处理工作,我创建了一个只包含美国城市的cities
表的视图。为此,我定义了两个处理作业:
- 删除视图(如果存在)
- 创建视图并将其保存在默认的数据湖中。
首先,我编写了另一个数据作业步骤,名为40_drop_usa_cities_view.sql
:
DROP VIEW IF EXISTS usa_cities;
然后我创建了另一个数据作业步骤,它创建了视图:
CREATE VIEW usa_cities
AS
SELECT *
FROM cities
WHERE country = 'United States';
我又运行了一遍所有的数据作业:
vdk run world-cities-vdk
视图被添加到数据湖中。
摘要
在这篇文章中,我描述了通用数据工具包的概述,这是一个非常强大的框架,允许以有效的方式管理数据。
此外,我还展示了该框架的一个初始用例,包括数据作业接收和处理。有关更多详细信息,您可以阅读通用数据工具包用户指南。
本教程的完整代码可以从我的 Github 资源库下载。
对于多功能数据工具包的问题或疑问,你可以直接加入他们的公共 slack 工作区或他们的邮件列表或在 Twitter 上关注他们。
如果你读到这里,对我来说,今天已经很多了。谢谢!你可以在这篇文章中读到更多关于我的内容。
你愿意支持我的研究吗?
你可以每月订阅几美元,并解锁无限的文章。
相关文章
免责声明 :此文非赞助文章。我与通用数据工具包或其作者没有任何关系。这篇文章展示了该工具包的一个公正的概述,旨在让更多的人可以使用数据科学工具。
用 Python 进行 RFM 分析
以及如何从 it 中快速释放洞察力和商业价值
Dilyara Garifullina 在 Unsplash 上拍摄的照片
是时候重温一下我的 Python 技能了!👩🏻💻
本周,我想走技术路线,分享一个最近使用 RFM 框架的 Python 练习。这是一种通过三个方面来确定客户价值的方法:
- 最近:用户最后一次采取行动(例如登录、下订单)是什么时候?
- 频率:用户采取这个动作多少次?
- 货币价值:这个用户一生的货币价值总和是多少?
我的工作受到了同一个数据集上许多有用帖子的极大启发,比如这个。在这篇文章中,我想分享我的 RFM 细分分析,并重点关注我发现的一些有用的提示,以快速从模型输出中带来商业价值。
- 将绝对最近值、频率值和货币值转换为相对值,以减少与实际客户生命周期相关的偏差。
- 生成简单、启发式的业务逻辑,以快速的方式交付业务价值。
- 将这些细分市场与其他数据集结合起来,以更深入地了解您的客户群。
数据集描述和问题陈述
在我们深入细节之前,我想快速浏览一下我们的数据集是什么样子,以及我们的目标是解决什么问题。
我们的原始数据是包含以下字段的交易记录表:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 406829 entries, 0 to 541908
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 InvoiceNo 406829 non-null object
1 StockCode 406829 non-null object
2 Description 406829 non-null object
3 Quantity 406829 non-null int64
4 InvoiceDate 406829 non-null object
5 UnitPrice 406829 non-null float64
6 CustomerID 406829 non-null float64
7 Country 406829 non-null object
dtypes: float64(2), int64(1), object(5)
memory usage: 27.9+ MB
通常,我们会在客户层面上汇总数据。
作者图片
我们希望将 RFM 框架应用于该聚合数据集,并回答以下问题:
- 新近性、频率和货币价值之间有关联吗?
- 我们应该如何定义我们最有价值的客户(MVC)?我们的客户中有百分之多少是最有价值的客户?
- 我们是否能够创造独特的细分市场并据此设计 CRM 活动来提高客户参与度和/或盈利能力?
将绝对值转换为相对值,以减少客户寿命的偏差。
我在许多教程中注意到的一点是,计算中使用了绝对数字。换句话说,我们有以下内容:
- 最近=最近一次操作和今天之间的时间间隔
- 频率=从用户注册日期到今天的操作次数
- 货币价值=用户一生中的总收入
在这一步之后,一个典型的方法是通过基于每个单独列的四分位数创建存储桶来计算最近/频率/货币得分。例如,在“频率”列上,我们执行以下操作:
customer_data["FrequencyScore"] = pd.cut(customer_data["Frequency"],
bins=[-1,
np.percentile(customer_data["Frequency"], 25),
np.percentile(customer_data["Frequency"], 50),
np.percentile(customer_data["Frequency"], 75),
customer_data["Frequency"].max()],
labels=[1, 2, 3, 4]).astype("int")
请注意,对于最近得分,我们需要给出相反的标签,因为客户越活跃,最近值就越低。😃
一旦我们获得了每个维度的分数,我们就可以通过将这三个分数相加来计算 RFM 的总分数。总体 RFM 得分越高(从 3 到 12),客户越有价值。
customer_data["RFM"] = customer_data["RecencyScore"] + customer_data["FrequencyScore"] + customer_data["MonetaryScore"]
这种方法很容易实现,但它容易与实际的客户生命周期产生偏差。例如,与过去 6 个月内注册的客户相比,12 个月前注册的客户自然具有更低的新近度(假设用户参与度在整个生命周期内普遍下降)、更高的频率和更高的货币价值(假设在用户活动和货币化方面同类)。因此,签约 12 个月的客户的 RFM 分数可能被高估了。
为了解释这种偏差,在计算个人得分之前,我会先将最近发生的事、发生的频率和货币价值标准化。例如,我会做相对频率=最近/一生。
customer_data["RelFrequency"] = customer_data["Frequency"] / customer_data["Lifetime"]
然后我会根据相对频率计算频率得分:
customer_data["FrequencyScore"] = pd.cut(customer_data["RelFrequency"],
bins=[-1,
np.percentile(customer_data["RelFrequency"], 25),
np.percentile(customer_data["RelFrequency"], 50),
np.percentile(customer_data["RelFrequency"], 75),
customer_data["RelFrequency"].max()],
labels=[1, 2, 3, 4]).astype("int")
在我的笔记本上,你可以找到使用绝对值的rfm_abs
RFM 分割和使用相对值的rfm_rel
。在这里,我只附上在这两种方法下每个 RFM 细分市场的中值客户生命周期。正如我们所看到的,使用绝对值的 RFM 细分市场的客户生命周期有较大的差异,而使用相对值的 RFM 细分市场的客户生命周期相当稳定。更具体地说,对于第一种方法,我们看到那些 RFM 分数为 5 和 6(因此处于活动的下限)的人具有明显更短的寿命(因此是更近期的客户)。这种方法似乎“惩罚”了最近的客户,因为他们的频率和金额较低。
另一方面,我们的方法设法减少了 RFM 细分中与客户寿命相关的偏差!
作者图片
生成简单、启发式的业务逻辑,以快速的方式交付业务价值。
到目前为止一切顺利!
许多教程都以生成 RFM 分段标签(3–12)结束,包含以下汇总统计数据:
RFM 分割结果
这张表回答了我们的前两个问题:
- 在最近、频率和货币价值之间确实存在正相关关系。
- 我们的 MVC 是那些总 RFM 分数为 11 和 12 的人,即他们平均有 7 次以上的交易,在其一生中产生超过 2K 的交易,并且他们的最后一次交易是在过去 2 周内。这类客户约占我们总客户群的 16%。
然而,在现实生活中,这种输出可能不足以快速创造商业价值。一方面,我们得到的桶彼此差别不大,我们有机会合并一些部分。另一方面,逻辑本身相当复杂-如果我们想要严格遵循逻辑,我们需要将笔记本电脑部署到生产中,这需要大量的工程工作,并且产生大量商业价值的不确定性很高。
我们想快速行动。因此,我想根据上面的 RFM 分割结果生成一些简单的启发式逻辑,并将它们应用到生产中进行分析和操作。请注意,没有完美的逻辑——这里我只分享一组我认为最有区别的标准。
customer_data["last_order_within_l60d"] = customer_data["Recency"]<60 # Had transactions in the last 60 dayscustomer_data["more_than_two_orders"] = customer_data["Frequency"]>2 # Logged in more than twicecustomer_data["value_higher_than_2k"] = customer_data["MonetaryValue"]>2000 # Sum of value higher than 2Kcustomer_data.groupby(["last_order_within_l60d", "more_than_two_orders", "value_higher_than_2k"]).count()["Lifetime"]
作者图片
基于上面的分支,我定义了五个最终段(在括号中,您可以找到段的大小):
- 高参与度&高价值 (523)是最近 2 个月有最后一笔交易,成交 2 笔以上,平均贡献 2K 以上的人。
- 高参与度&低值 (876)是和 Group1 一样活跃,但贡献不到 2K 的人。
- 近期活动&低频 (811)是指最近 2 个月内有最后一笔交易但交易不超过 2 笔的人。这些客户的货币价值也较低。显然,这个群体中的大多数客户是最近获得的客户(他们的平均寿命只有 45 天)。
- 【老】活动&高频 (523)是最近 2 个月没有任何交易的人。然而,他们平均有 2 笔以上的交易。这些客户在旅程开始时非常活跃,但最近不那么活跃了。我们需要想办法让他们重新参与进来。
- 低参与度&低值 (1426)是最近 2 个月没有任何交易,交易不超过 2 笔,贡献收入最低的人。
作者图片
与其他数据集结合,释放更多洞察力和价值。
基于我们在上面获得的知识,有许多使用案例。这里我想详细阐述一下我在工作中用过的两个用例。
一种方法是将这个客户价值分数作为一个新的维度附加到 BI 数据集(用户资料、跟踪事件、购买记录等)。结合现有的指标和仪表板,这可以帮助您回答以下问题:
- 我们的 MVC 的社会经济特征(收入、职业等)和人口统计学特征(年龄、性别、婚姻状况等)是什么?这为我们如何瞄准并获得更多这样的客户提供了启示。
- 与其他群体相比,我们的 MVC 有明显不同的用户旅程吗?我们如何优化 MVC 的旅程体验?
- 与其他集团相比,我们的 MVC 是否拥有重要的市场份额?这可能会给我们一些启发,以改善对他们的推荐。
另一个用例是将此标签发送到 CRM 工具,并将其用于定制的互动交流。以我上面生成的最终细分为例:对于第 2 组高参与度&低价值和第 3 组近期活动&低频率,我们应该通过个性化推荐关注货币化(例如订单数量、平均订单价值),而对于第 4 组老活动&高频率,我们应该尝试重新吸引他们,并让他们回到我们的网站/应用程序。结合其他数据集的特征,我们能够设计有针对性的内容和媒体,以接触到个人客户并最大限度地提高转化率。
就是这样。让我知道你的想法和反馈!