在整个项目中,我们将分析一些产品类别中几个客户的消费行为。该项目的主要目标是:

将客户分组为具有相近支出特征的集群

描述不同集群内的变化,以便为每个集团找到最佳的交付结构。

解释方差计算公式_解释方差_名词解释方差

要执行此项目,我们将使用可在以下UCI机器学习库中找到的数据集。

我们将重点分析为客户记录的六个产品类别,不包括”渠道”和”区域”字段。

# Import libraries necessary for this project
 import numpy as np
 import pandas as pd
 from IPython.display import display # Allows the use of display() for DataFrames
 
 # Import supplementary visualizations code visuals.py
 import visuals as vs
 
 # Pretty display for notebooks
 %matplotlib inline
 
 # Load the wholesale customers dataset
 try:
 data = pd.read_csv("customers.csv")
 data.drop(['Region', 'Channel'], axis = 1, inplace = True)
 print("Wholesale customers dataset has {} samples with {} features each.".format(*data.shape))
 except:
 print("Dataset could not be loaded. Is the dataset missing?")

解释方差计算公式_名词解释方差_解释方差

解释方差计算公式_解释方差_名词解释方差

数据探索

现在,我们将通过可视化和代码探索数据集,以便了解特征之间的关系。此外,我们将计算数据集的统计描述并考虑每个特征的整体相关性。

# Display a description of the dataset
 display(data.describe())

# Display the head of the dataset
 data.head()

选择样本

为了更好地理解我们的数据集以及如何通过分析转换数据,我们将选择一些样本点并详细探索它们。

# Select three indices to sample from the dataset
 indices = [85,181,338]
 
 # Create a DataFrame of the chosen samples
 samples = pd.DataFrame(data.loc[indices], columns = data.keys()).reset_index(drop = True)
 print("Chosen samples of wholesale customers dataset:")
 display(samples)

注意事项

现在让我们考虑每个产品类别的总购买成本以及我们样本客户的上述数据集的统计描述。如果我们必须预测所选择的三个样本中的每一个代表什么类型的企业:

考虑平均值:

我们可以做出以下预测:

指数85:零售商:

指数181:大市场

指数338:餐厅

特征相关性

我们现在将分析这些特征的相关性解释方差,以了解客户的购买行为。换句话说,确定购买一定数量的一类产品的客户是否必须购买一定比例的另一类产品。

我们将通过在一个数据子集上训练有监督的回归学习器并移除一个特征来研究这一点,然后评估该模型可以预测移除的特征的程度。

# Display the head of the dataset
 data.head(1)

# Make a copy of the DataFrame, using the 'drop' function to drop the given feature
 new_data = data.drop('Grocery', axis=1)
 
 # Split the data into training and testing sets(0.25) using the given feature as the target
 # Set a random state.
 from sklearn.model_selection import train_test_split
 
 X_train, X_test, y_train, y_test = train_test_split(new_data, data.Grocery, test_size=0.25, random_state=42)
 
 # Create a decision tree regressor and fit it to the training set
 from sklearn.tree import DecisionTreeRegressor
 regressor = DecisionTreeRegressor()
 regressor = regressor.fit(X_train, y_train)
 prediction = regressor.predict(X_test)
 
 # Report the score of the prediction using the testing set
 from sklearn.metrics import r2_score
 score = r2_score(y_test, prediction)
 print("Prediction score is: {}".format(score))

解释方差_解释方差计算公式_名词解释方差

可视化特征分布

为了更好地理解我们的数据集,我们将显示每个产品特征的散布矩阵。

显示散点图矩阵相关性的产品特征与预测其他特征相关。

# Produce a scatter matrix for each pair of features in the data
 pd.scatter_matrix(data, alpha = 0.3, figsize = (14,8), diagonal = 'kde');

# Display a correlation matrix
 import seaborn as sns
 sns.heatmap(data.corr())

解释方差_名词解释方差_解释方差计算公式

使用散点矩阵和相关矩阵作为参考,我们可以推断出以下内容:

数据预处理

此步骤对于确保获得的结果具有重要意义。我们将通过缩放数据并检测潜在异常值来预处理数据。

特征缩放

通常中创网,当数据不是正态分布,特别是如果平均数和中位数显著变化,这是最适合施加非线性缩放的,尤其是对财务数据。

实现此缩放的一种方法是使用Box-Cox测试,该测试计算数据的最佳功率变换,从而减少偏斜。在大多数情况下可以使用的更简单的方法是应用自然对数。

# Scale the data using the natural logarithm 
 log_data = np.log(data) 
# Scale the sample data using the natural logarithm 
 log_samples = np.log(samples) 
# Produce a scatter matrix for each pair of newly-transformed features 
 pd.scatter_matrix(log_data, alpha = 0.3, figsize = (14,8), diagonal = 'kde');

解释方差计算公式_解释方差_名词解释方差

总结

在对数据应用自然对数缩放后,每个要素的分布显得更加正常。对于我们之前已经确定为相关的任何特征对,我们在此观察到相关性仍然存在(以及它现在是否比之前更强或更弱)。

显示实际数据:

# Display the log-transformed sample data
 display(log_samples)

解释方差_名词解释方差_解释方差计算公式

异常值检测

在任何分析的数据预处理步骤中检测数据中的异常值都非常重要。异常值的存在通常会使这些数据点的结果产生偏差。

在这里解释方差,我们将使用Tukey的方法来识别异常值:异常步骤计算为四分位数范围(IQR)的1.5倍。具有超出该特征的IQR之外的异常步骤的特征的数据点被认为是异常的。

outliers = []
 
 # For each feature find the data points with extreme high or low values
 for feature in log_data.keys():
 
 # Calculate Q1 (25th percentile of the data) for the given feature
 Q1 = np.percentile(log_data[feature],25)
 
 # Calculate Q3 (75th percentile of the data) for the given feature
 Q3 = np.percentile(log_data[feature],75)
 
 # Use the interquartile range to calculate an outlier step (1.5 times the interquartile range)
 step = 1.5 * (Q3-Q1)
 
 # Display the outliers
 print("Data points considered outliers for the feature '{}':".format(feature))
 display(log_data[~((log_data[feature] >= Q1 - step) & (log_data[feature] = Q1 - step) & (log_data[feature] <= Q3 + step))].index.tolist()
 outliers.append(lista)

名词解释方差_解释方差计算公式_解释方差

outliers

名词解释方差_解释方差计算公式_解释方差

# Detecting outliers that appear in more than one product
 seen = {}
 dupes = []
 
 for lista in outliers:
 for index in lista:
 if index not in seen:
 seen[index] = 1
 else:
 if seen[index] == 1:
 dupes.append(index)
 seen[index] += 1
 dupes = sorted(dupes)
 dupes

解释方差计算公式_解释方差_名词解释方差

# Removing outliers 
 good_data = log_data.drop(dupes, axis=0).reset_index(drop=True)

总结特征转换

现在我们将使用主成分分析来提取有关数据集隐藏结构的结论。PCA用于计算最大化方差的那些维度,因此我们将找到最能描述每个客户的特征组合。

主成分分析(PCA)

一旦数据被缩放到正态分布并且已经去除了必要的异常值,我们就可以应用PCA good_data来发现关于数据的哪些维度最大化所涉及的特征的方差。

除了找到这些维度之外,PCA还将报告每个维度的解释方差比 – 数据中的差异仅由该维度解释。

# Get the shape of the log_samples
 log_samples.shape

解释方差_名词解释方差_解释方差计算公式

# Apply PCA by fitting the good data with the same number of dimensions as features
 from sklearn.decomposition import PCA
 pca = PCA(n_components=good_data.shape[1])
 pca = pca.fit(good_data)
 
 # Transform log_samples using the PCA fit above
 pca_samples = pca.transform(log_samples)
 
 # Generate PCA results plot
 pca_results = vs.pca_results(good_data, pca)

名词解释方差_解释方差_解释方差计算公式

总结尺寸讨论

# Display sample log-data after having a PCA transformation applied
 display(pd.DataFrame(np.round(pca_samples, 4), columns = pca_results.index.values))

解释方差计算公式_解释方差_名词解释方差

降维

使用主成分分析时,主要目标之一是减少数据的维度。

尺寸降低是有代价的:使用的尺寸越少意味着数据中的总方差变化越小。因此,累积解释的方差比对于了解问题需要多少维度非常重要。另外,如果仅通过两维或三维解释显着的方差量,则可以在之后可视化减少的数据。

# Apply PCA by fitting the good data with only two dimensions
 pca = PCA(n_components=2).fit(good_data)
 
 # Transform the good data using the PCA fit above
 reduced_data = pca.transform(good_data)
 
 # Transform log_samples using the PCA fit above
 pca_samples = pca.transform(log_samples)
 
 # Create a DataFrame for the reduced data
 reduced_data = pd.DataFrame(reduced_data, columns = ['Dimension 1', 'Dimension 2'])

下面的单元格显示了仅使用两个维度对PCA转换应用后,对数转换后的样本数据的变化情况。观察与六维中的PCA变换相比,前两个维度的值如何保持不变。

# Display sample log-data after applying PCA transformation in two dimensions
 display(pd.DataFrame(np.round(pca_samples, 4), columns = ['Dimension 1', 'Dimension 2']))

解释方差计算公式_名词解释方差_解释方差

可视化Biplot

双标图是散点图,其中每个数据点由其沿主要分量的分数表示。轴是主要组件。

双标图显示了原始特征沿组件的投影。双标图可以帮助我们解释数据的缩小尺寸,并发现主要组件和原始特征之间的关系。

# Create a biplot
 vs.biplot(good_data, reduced_data, pca)

名词解释方差_解释方差_解释方差计算公式

一旦我们得到原始特征投影(红色),就可以更容易地解释散点图中每个数据点的相对位置。

例如,点图的右下角将有可能对应于花费了大量的客户“牛奶”,“杂货店”和“清洁纸”,但没有这么多的其他产品类别。

聚类

在本节中,我们将选择使用K-Means聚类算法或高斯混合模型(GMM)聚类算法来识别隐藏在数据中的各种客户群。

然后,我们将从群集中恢复特定数据点,以通过将它们转换回原始维度和比例来了解它们的重要性。

K-Means与GMM

使用K-Means作为聚类算法的主要优点是:

使用高斯混合模型作为聚类算法的主要优点是:

选择算法:

创建集群

当先前不知道簇的数量时,不能保证给定数量的簇最好地对数据进行分段,因为不清楚数据中存在什么结构。

但是,我们可以通过计算每个数据点的轮廓系数来量化聚类的”优点” 。数据点的轮廓系数测量它与指定簇的相似程度,从-1(不相似)到1(相似)。计算平均轮廓系数提供了给定聚类的简单评分方法。

# Import the necessary libraries
 from sklearn.mixture import GaussianMixture
 from sklearn.metrics import silhouette_score
 
 scores = {}
 for i in range(2,7):
 
 print('Number of clusters: ' + str(i))
 
 # Apply your clustering algorithm of choice to the reduced data 
 clusterer = GaussianMixture(random_state=42, n_components=i)
 clusterer.fit(reduced_data)
 
 # Predict the cluster for each data point
 preds = clusterer.predict(reduced_data)
 
 # Find the cluster centers
 centers = clusterer.means_
 print('Cluster Center: ' + str(centers))
 
 # Predict the cluster for each transformed sample data point
 sample_preds = clusterer.predict(pca_samples)
 print('Sample predictions: ' + str(sample_preds))
 
 # Calculate the mean silhouette coefficient for the number of clusters chosen
 score = silhouette_score(reduced_data, preds)
 scores[i] = score
 print('Silhouette score is: ' + str(score), 'n')
 
 print('Scores: ' + str(scores))

具有最佳Silhouette Score的群集数为2,得分为0.42。

集群可视化

一旦我们使用上面的评分指标为聚类算法选择了最佳聚类数,我们现在可以在下面的代码块中可视化结果。

# Apply your clustering algorithm of choice to the reduced data 
 clusterer = GaussianMixture(random_state=42, n_components=2)
 clusterer.fit(reduced_data)
 
 # Predict the cluster for each data point
 preds = clusterer.predict(reduced_data)
 
 # Find the cluster centers
 centers = clusterer.means_
 print('Cluster Center: ' + str(centers))
 
 # Predict the cluster for each transformed sample data point
 sample_preds = clusterer.predict(pca_samples)
 print('Sample predictions: ' + str(sample_preds))
 
 # Calculate the mean silhouette coefficient for the number of clusters chosen
 score = silhouette_score(reduced_data, preds)
 scores[i] = score
 print('Silhouette score is: ' + str(score), 'n')

解释方差计算公式_解释方差_名词解释方差

# Display the results of the clustering from implementation
 vs.cluster_results(reduced_data, preds, centers, pca_samples)

解释方差_解释方差计算公式_名词解释方差

数据恢复

上面的可视化中存在的每个群集都有一个中心点。这些中心不是来自数据的特定数据点,而是各个集群中预测的所有数据点的平均值。

对于创建客户群的问题,群集的中心点对应于该段的平均客户。由于数据目前在尺寸上减小并按对数缩放,我们可以通过应用逆变换从这些数据点恢复代表性客户支出。

# Inverse transform the centers
 log_centers = pca.inverse_transform(centers)
 
 # Exponentiate the centers
 true_centers = np.exp(log_centers)
 
 # Display the true centers
 segments = ['Segment {}'.format(i) for i in range(0,len(centers))]
 true_centers = pd.DataFrame(np.round(true_centers), columns = data.keys())
 true_centers.index = segments
 display(true_centers)

解释方差_解释方差计算公式_名词解释方差

下面的代码显示了每个样本点的预测属于哪个ckustr。

# Display the predictions
 for i, pred in enumerate(sample_preds):
 print("Sample point", i, "predicted to be in Cluster", pred)

解释方差计算公式_名词解释方差_解释方差

结论总结

批发经销商如何仅使用其估计的产品支出和客户细分数据来标记新客户?

可以使用监督学习算法,将估计的产品花费作为属性,将客户群作为目标变量,使其成为分类问题。由于客户群与产品支出之间没有明确的数学关系,KNN可能是一个很好的算法。

可视化底层分布

在该项目开始时,讨论了将从数据集中排除’Channel’和’Region’特征,以​​便在分析中强调客户产品类别。通过将’Channel’特征重新引入数据集,当考虑先前应用于原始数据集的相同PCA维数减少时,会出现一个有趣的结构。

下面的代码块显示了每个数据点的标签’HoReCa’(酒店/餐厅/咖啡厅)或’Retail’缩小的空间。

# Display the clustering results based on 'Channel' data vs.channel_results(reduced_data, preds, pca_samples)

解释方差计算公式_名词解释方差_解释方差

我们可以观察到,群集算法可以很好地将数据聚类到底层分布,因为群集0可以与零售商和群集1完美地关联到Ho / Re / Ca(酒店/餐厅/咖啡厅)

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注