我有一组文档,我从中创建了一个特征矩阵。然后计算文档之间的余弦相似度。将余弦距离矩阵输入到dBSCAN算法中。我的代码如下。
import pandas as pd
import numpy as np
from sklearn.metrics import pairwise_distances
from scipy.spatial.distance import cosine
from sklearn.cluster import DBSCAN
# Initialize some documents
doc1 = {'Science':0.8, 'History':0.05, 'Politics':0.15, 'Sports':0.1}
doc2 = {'News':0.2, 'Art':0.8, 'Politics':0.1, 'Sports':0.1}
doc3 = {'Science':0.8, 'History':0.1, 'Politics':0.05, 'News':0.1}
doc4 = {'Science':0.1, 'Weather':0.2, 'Art':0.7, 'Sports':0.1}
doc5 = {'Science':0.2, 'Weather':0.7, 'Art':0.8, 'Sports':0.9}
doc6 = {'Science':0.2, 'Weather':0.8, 'Art':0.8, 'Sports':1.0}
collection = [doc1, doc2, doc3, doc4, doc5, doc6]
df = pd.DataFrame(collection)
# Fill missing values with zeros
df.fillna(0, inplace=True)
# Get Feature Vectors
feature_matrix = df.as_matrix()
print(feature_matrix.tolist())
# Get cosine distance between pairs
sims = pairwise_distances(feature_matrix, metric='cosine')
# Fit DBSCAN
db = DBSCAN(min_samples=1, metric='precomputed').fit(sims)
现在,如SkSee中的dBSCAN demo所示,我绘制了簇。也就是说,代替
X
我插入sims
,这是余弦距离矩阵。labels = db.labels_
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
print('Estimated number of clusters: %d' % n_clusters_)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
#print(labels)
# Plot result
import matplotlib.pyplot as plt
# Black removed and is used for noise instead.
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
for each in np.linspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):
if k == -1:
# Black used for noise.
col = [0, 0, 0, 1]
class_member_mask = (labels == k)
xy = sims[class_member_mask & core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
markeredgecolor='k', markersize=14)
xy = sims[class_member_mask & ~core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
markeredgecolor='k', markersize=6)
plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()
我的第一个问题是,更改
sims
而不是X
是否正确,因为X
表示坐标值in the demo of sklearn而sims
表示余弦距离值?我的第二个问题是,是否可以将给定的点变成红色?例如,我想将
[0.8, 0.0, 0.0, 0.0, 0.2, 0.9, 0.7]
的reprsentsfeature_matrix
改为red? 最佳答案
首先是对术语的评论:
有两种类型的矩阵可以测量数据集中对象的接近度:
距离矩阵描述数据集中对象之间的成对距离。
相似矩阵描述数据集中对象之间的成对相似性。
一般来说,当两个物体彼此接近时,它们之间的距离很小,但它们的相似性很大。所以距离矩阵和相似矩阵在某种意义上是对立的。例如,对于余弦度量,距离矩阵D
和相似矩阵S
之间的关系可以写成D = 1 - S
。
由于上面示例中的sims
数组包含成对距离,因此将其称为dists
数组可能更为合适。
我的第一个问题是,用sims代替x是否正确,
因为X代表SKEXCEL的演示中的坐标值
sims表示余弦距离值?
不。如果要在二维平面上绘制数据,则绘图功能需要二维坐标数组作为输入。距离矩阵是不够的。
如果您的数据具有两个以上的维度,则可以通过一些维度缩减技术来获得它的二维表示。SKEXE在sklearn.manifold
和sklearn.decomposition
模块中包含了许多有用的降维算法。算法的选择通常取决于数据的性质,并且可能需要一些实验。
在SKEXLY中,大多数维数约简方法接受特征(或坐标)向量作为输入。有些还接受距离或相似矩阵(这需要从文档中检查;一个好的提示是关键字[cc]在某个地方被提到)。在需要距离矩阵的情况下,也应注意不要使用相似矩阵,反之亦然。
我的第二个问题是,是否可以将给定的点
红色?例如,我想改变reprsents[0.8,
特征矩阵的0.0、0.0、0.0、0.2、0.9、0.7]变为红色?
问题2有点不同,主要涉及precomputed
。
我想人们事先知道哪些点会被涂成红色。下面的代码中有一个名为matplotlib
的数组,它应该包含红色点的索引。例如,如果red_points
和doc2
应该涂成红色,则可以设置doc5
(索引从零开始)。
对于聚类的可视化,采用主成分分析(PCA)进行降维,这是这类任务最直接的方法之一。注意,我根本不计算距离矩阵,而是直接在red_points = [1, 4]
上应用dbscan和pca。
import pandas as pd
import numpy as np
from sklearn.metrics import pairwise_distances
from scipy.spatial.distance import cosine
from sklearn.cluster import DBSCAN
# Initialize some documents
doc1 = {'Science':0.8, 'History':0.05, 'Politics':0.15, 'Sports':0.1}
doc2 = {'News':0.2, 'Art':0.8, 'Politics':0.1, 'Sports':0.1}
doc3 = {'Science':0.8, 'History':0.1, 'Politics':0.05, 'News':0.1}
doc4 = {'Science':0.1, 'Weather':0.2, 'Art':0.7, 'Sports':0.1}
doc5 = {'Science':0.2, 'Weather':0.7, 'Art':0.8, 'Sports':0.9}
doc6 = {'Science':0.2, 'Weather':0.8, 'Art':0.8, 'Sports':1.0}
collection = [doc1, doc2, doc3, doc4, doc5, doc6]
df = pd.DataFrame(collection)
# Fill missing values with zeros
df.fillna(0, inplace=True)
# Get Feature Vectors
feature_matrix = df.as_matrix()
# Fit DBSCAN
db = DBSCAN(min_samples=1).fit(feature_matrix)
labels = db.labels_
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
print('Estimated number of clusters: %d' % n_clusters_)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
# Plot result
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
# Perform dimensional reduction of the feature matrix with PCA
X = PCA(n_components=2).fit_transform(feature_matrix)
# Select which points will be painted red
red_points = [1, 4]
for i in red_points:
labels[i] = -2
# Black removed and is used for noise instead.
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
for each in np.linspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):
if k == -1:
# Black used for noise.
col = [0, 0, 0, 1]
if k == -2:
# Red for selected points
col = [1, 0, 0, 1]
class_member_mask = (labels == k)
xy = X[class_member_mask & core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
markeredgecolor='k', markersize=14)
xy = X[class_member_mask & ~core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
markeredgecolor='k', markersize=6)
plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()
左图适用于
feature_matrix
为空的情况,右图适用于red_points
。