import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.cluster import KMeans
from sklearn import datasets
x1, y1 = datasets.make_circles(n_samples=2000, factor=0.5, noise=0.05)
x2, y2 = datasets.make_blobs(n_samples=1000, centers=[[1.2, 1.2]], cluster_std=[[0.1]])
x = np.concatenate((x1, x2))
model = KMeans(n_clusters=3)
model.fit(x)
y_pred = model.predict(x)
plt.scatter(x[:, 0], x[:, 1], c=y_pred)
model = DBSCAN(eps=0.2, min_samples=50)
model.fit(x)
y_pred = model.fit_predict(x)
plt.figure()
plt.scatter(x[:, 0], x[:, 1], c=y_pred)
plt.show()
k-means聚类方法,它有一个很大的缺陷,就是它对于简单成团的数据样本聚类效果较好,但是对于复杂的样本数据分布就搞不定了,比如环形分布的样本数据。
应用
先放一下直方图,集中在7、8、20、21、22、23。(6类)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn import metrics
def loadData(filePath):
f = open(filePath)
lines = f.readlines()
mac2id=dict()
online_times=[]
for line in lines:
mac=line.split(',' )[2]
online_time=int(line.split(',')[6])
start_time= int(line.split(',')[4].split(' ')[1].split(':')[0])
if mac not in mac2id:
mac2id[mac]= len(online_times)
online_times.append((start_time,online_time/12000))
else:
online_times[mac2id[mac]]=[(start_time,online_time)]
print(online_times)
real_X=np.array(online_times).reshape((-1,2))
return real_X
X=loadData("E:\Desktop\python_code\sklearn\课程数据\聚类\\time2.txt")
db=DBSCAN(eps=0.5 ,min_samples=20,metric='euclidean').fit(X)
labels = db.labels_
print('Labels:',labels)
raito=len(labels[labels[:] == -1]) / len(labels)
print( 'Noise raito: ',format(raito,'.2%'))
n_clusters_= len(set(labels)) - (1 if -1 in labels else 0)
print( ' Est imated number of clusters: %d' % n_clusters_)
print( " Silhouette Coefficient: %0.3f" % metrics.silhouette_score(X, labels))
for i in range(n_clusters_):
print('Cluster',i,':')
print(list(X[labels == i,0].flatten()))
plt.scatter(X[:, 0], X[:, 1],c=labels)
plt.show()
课程中的代码有问题,对应参数是不会得出课程中的结果。 不断调参,尝试。 经过思考,发现了问题,横轴间距太小,如果调大eps,必然会横向误判。 如果纵向缩小一些。。。 于是尝试进行了归一化,结果与课程相符。
不过课程后面提到用对数变换,不过我貌似那是针对第二个例子。应该也可以。
|