import pandas as pd import numpy as np from sklearn.cluster import DBSCAN from sklearn import metrics from sklearn.cluster import KMeans import os def dbscan(input_file): ## 纬度在前,经度在后 [latitude, longitude] columns = ['lat', 'lon'] in_df = pd.read_csv(input_file, sep=',', header=None, names=columns) # represent GPS points as (lat, lon) coords = in_df.as_matrix(columns=['lat', 'lon']) # earth's radius in km kms_per_radian = 6371.0086 # define epsilon as 0.5 kilometers, converted to radians for use by haversine # This uses the 'haversine' formula to calculate the great-circle distance between two points # that is, the shortest distance over the earth's surface # http://www.movable-type.co.uk/scripts/latlong.html epsilon = 0.5 / kms_per_radian # radians() Convert angles from degrees to radians db = DBSCAN(eps=epsilon, min_samples=15, algorithm='ball_tree', metric='haversine').fit(np.radians(coords)) cluster_labels = db.labels_ # get the number of clusters (ignore noisy samples which are given the label -1) num_clusters = len(set(cluster_labels) - set([-1])) print('Clustered ' + str(len(in_df)) + ' points to ' + str(num_clusters) + ' clusters') # turn the clusters in to a pandas series # clusters = pd.Series([coords[cluster_labels == n] for n in range(num_clusters)]) # print(clusters) kmeans = KMeans(n_clusters=1, n_init=1, max_iter=20, random_state=20) for n in range(num_clusters): # print('Cluster ', n, ' all samples:') one_cluster = coords[cluster_labels == n] # print(one_cluster[:1]) # clist = one_cluster.tolist() # print(clist[0]) kk = kmeans.fit(one_cluster) print(kk.cluster_centers_) def main(): path = './datas' filelist = os.listdir(path) for f in filelist: datafile = os.path.join(path, f) print(datafile) dbscan(datafile) if __name__ == '__main__': main()
时间: 2024-03-11 09:43:59 浏览: 108
这是一个 Python 代码,主要使用了 Pandas、NumPy、sklearn.cluster 等库实现了 DBSCAN 和 KMeans 聚类算法。代码读入了一个文件夹中的多个文件,每个文件都是 GPS 坐标点的经纬度信息,然后使用 DBSCAN 算法进行聚类,并且输出了聚类的个数。接着使用 KMeans 算法对每个聚类进行细分,最后输出每个聚类的中心点坐标。
相关问题
如何对比dbscan与kmeans聚类结果好坏
对比 DBSCAN 和 KMeans 的聚类结果好坏,可以使用同一种评价指标来进行对比。以下是一个计算轮廓系数来对比两种聚类算法结果好坏的示例代码:
```python
import numpy as np
import pandas as pd
from sklearn.manifold import TSNE
from sklearn.cluster import KMeans, DBSCAN
from sklearn.metrics import silhouette_score
# 读取csv文件
data = pd.read_csv('data.csv', header=0)
# 提取数据
X = data.iloc[:, :60].values
# 使用TSNE进行降维,降到2维
tsne = TSNE(n_components=2)
X_tsne = tsne.fit_transform(X)
# 使用KMeans进行聚类
kmeans = KMeans(n_clusters=5)
kmeans.fit(X_tsne)
# 使用DBSCAN进行聚类
dbscan = DBSCAN(eps=0.5, min_samples=5)
dbscan.fit(X_tsne)
# 计算轮廓系数
kmeans_score = silhouette_score(X_tsne, kmeans.labels_, metric='euclidean')
dbscan_score = silhouette_score(X_tsne, dbscan.labels_, metric='euclidean')
print('KMeans 轮廓系数为:', kmeans_score)
print('DBSCAN 轮廓系数为:', dbscan_score)
```
在上述代码中,计算轮廓系数分别对 KMeans 和 DBSCAN 的聚类结果进行了评价,并输出了两种算法的轮廓系数。可以通过比较两种算法的轮廓系数来判断两种算法的聚类结果好坏,值越大表示聚类结果越好。需要注意的是,轮廓系数只是评价聚类结果的一种指标,不一定适用于所有聚类算法和数据集,因此需要根据具体情况进行选择和综合考虑。
请编写代码实现鸢尾花数据DBSCAN聚类,鸢尾花数据保存在iris_pca_self.csv文件中(设 eps=0.5, min_samples=5)(注意:不得直接调用 sklearn 或其他库中的 Kmeans 或类似函 数),并输出聚类结果(簇总数,各样本的所属簇编号)。调用 matplotlib 的 scatter 函数将聚类后各样本可视化输出(不同簇内 的样本用不同的颜色表示)。调用 sklearn 库中函数,计算得到外部指标(RI、FMI)和内部指标 (DBI)。
好的,我会为你解答这个问题。
首先,我们需要读取鸢尾花数据集,这里使用 pandas 库来读取数据:
```python
import pandas as pd
data = pd.read_csv('iris_pca_self.csv')
```
接着,我们需要实现 DBSCAN 聚类算法,这里我们可以参考 DBSCAN 的伪代码来实现:
```python
def dbscan(data, eps, min_samples):
# 初始化所有点为未访问状态
visited = [False] * len(data)
# 初始化所有点的簇编号为 -1,表示未分类
clusters = [-1] * len(data)
# 初始化簇编号为 0
cluster_index = 0
# 遍历每个点
for i in range(len(data)):
# 如果该点已经访问过,跳过
if visited[i]:
continue
# 标记该点为已访问状态
visited[i] = True
# 找到该点的所有邻居点
neighbors = find_neighbors(data, i, eps)
# 如果邻居点数量小于 min_samples,该点为噪声点
if len(neighbors) < min_samples:
clusters[i] = -1
# 否则,扩展聚类
else:
expand_cluster(data, visited, clusters, i, neighbors, cluster_index, eps, min_samples)
cluster_index += 1
return clusters
def find_neighbors(data, center, eps):
neighbors = []
# 计算该点与其他所有点的距离
for i in range(len(data)):
if i == center:
continue
dist = np.linalg.norm(data[i] - data[center])
if dist < eps:
neighbors.append(i)
return neighbors
def expand_cluster(data, visited, clusters, center, neighbors, cluster_index, eps, min_samples):
# 将该点加入当前聚类
clusters[center] = cluster_index
# 遍历邻居点
for i in neighbors:
# 如果该点未访问过,标记为已访问
if not visited[i]:
visited[i] = True
# 找到该点的邻居点
new_neighbors = find_neighbors(data, i, eps)
# 如果邻居点数量大于等于 min_samples,将其加入当前聚类
if len(new_neighbors) >= min_samples:
neighbors += new_neighbors
# 如果该点还未分类,将其加入当前聚类
if clusters[i] == -1:
clusters[i] = cluster_index
```
这个算法用到了两个辅助函数 `find_neighbors` 和 `expand_cluster`,前者用于找到某个点的邻居点,后者用于扩展聚类。这两个函数的实现都比较简单,这里就不赘述了。
接下来,我们可以使用上述函数进行聚类:
```python
import numpy as np
# 调用 dbscan 函数进行聚类
clusters = dbscan(data.values, eps=0.5, min_samples=5)
# 输出簇总数和各样本的所属簇编号
print('Total clusters:', len(np.unique(clusters)))
print('Cluster labels:', clusters)
```
最后,我们可以使用 matplotlib 库将聚类结果可视化输出:
```python
import matplotlib.pyplot as plt
# 绘制散点图
colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k']
for i in range(len(data)):
plt.scatter(data.iloc[i, 0], data.iloc[i, 1], c=colors[clusters[i]])
plt.show()
```
至此,我们已经成功实现了鸢尾花数据集的 DBSCAN 聚类,并将聚类结果可视化输出。
最后,我们可以使用 sklearn 库中的函数计算得到外部指标(RI、FMI)和内部指标(DBI):
```python
from sklearn import metrics
# 计算外部指标
labels_true = data['label'].values
print('RI:', metrics.adjusted_rand_score(labels_true, clusters))
print('FMI:', metrics.fowlkes_mallows_score(labels_true, clusters))
# 计算内部指标
print('DBI:', metrics.davies_bouldin_score(data.values, clusters))
```
好了,以上就是完整的代码实现。
阅读全文