2017-04-02 2 views
1

에서 노이즈를 제거 DBSCAN는 플롯 DBSCAN을 사용

나는 다음하기 matplotlib를 사용하여 플롯하는 위도와 경도 쌍의 목록을 클러스터 한
(DBSCAN(eps=epsilon, min_samples=10, algorithm='ball_tree', metric='haversine') 

. 플로팅 할 때 생성 된 270 개의 클러스터 중 하나에 할당되지 않은 포인트 인 "노이즈"좌표가 포함됩니다. 음모에서 노이즈를 제거하고, 지정된 요구 사항을 충족하는 클러스터를 플로팅하고 싶습니다. 그러나 그렇게하는 방법을 모르겠습니다. 소음을 제거하는 방법은 무엇입니까 (다시 클러스터에 할당되지 않은 포인트)? 다음은

은 내가 클러스터하기 위해 사용한 코드와 플롯이다 :

df = pd.read_csv('xxx.csv') 

# define the number of kilometers in one radiation 
# which will be used to convert esp from km to radiation 
kms_per_rad = 6371.0088 

# define a function to calculate the geographic coordinate 
# centroid of a cluster of geographic points 
# it will be used later to calculate the centroids of DBSCAN cluster 
# because Scikit-learn DBSCAN cluster class does not come with centroid attribute. 
def get_centroid(cluster): 
"""calculate the centroid of a cluster of geographic coordinate points 
Args: 
    cluster coordinates, nx2 array-like (array, list of lists, etc) 
    n is the number of points(latitude, longitude)in the cluster. 
Return: 
    geometry centroid of the cluster 

""" 
cluster_ary = np.asarray(cluster) 
centroid = cluster_ary.mean(axis=0) 
return centroid 

# convert eps to radians for use by haversine 
epsilon = 0.1/kms_per_rad #1.5=1.5km 1=1km 0.5=500m 0.25=250m 0.1=100m 

# Extract intersection coordinates (latitude, longitude) 
tweet_coords = df.as_matrix(columns=['latitude','longitude']) 

start_time = time.time() 
dbsc = (DBSCAN(eps=epsilon, min_samples=10, algorithm='ball_tree', metric='haversine') 
    .fit(np.radians(tweet_coords))) 

tweet_cluster_labels = dbsc.labels_ 

# get the number of clusters 
num_clusters = len(set(dbsc.labels_)) 

# print the outcome 
message = 'Clustered {:,} points down to {:,} clusters, for {:.1f}% compression in {:,.2f} seconds' 
print(message.format(len(df), num_clusters, 100*(1 - float(num_clusters)/len(df)), time.time()-start_time)) 
print('Silhouette coefficient:  {:0.03f}'.format(metrics.silhouette_score(tweet_coords, tweet_cluster_labels))) 

# Turn the clusters into a pandas series,where each element is a cluster of points 
dbsc_clusters = pd.Series([tweet_coords[tweet_cluster_labels==n] for n in range(num_clusters)]) 

# get centroid of each cluster 
cluster_centroids = dbsc_clusters.map(get_centroid) 
# unzip the list of centroid points (lat, lon) tuples into separate lat and lon lists 
cent_lats, cent_lons = zip(*cluster_centroids) 
# from these lats/lons create a new df of one representative point for eac cluster 
centroids_df = pd.DataFrame({'longitude':cent_lons, 'latitude':cent_lats}) 
#print centroids_df 

# Plot the clusters and cluster centroids 
fig, ax = plt.subplots(figsize=[20, 12]) 
tweet_scatter = ax.scatter(df['longitude'], df['latitude'], c=tweet_cluster_labels, cmap = cm.hot, edgecolor='None', alpha=0.25, s=50) 
centroid_scatter = ax.scatter(centroids_df['longitude'], centroids_df['latitude'], marker='x', linewidths=2, c='k', s=50) 
ax.set_title('Tweet Clusters & Cluser Centroids', fontsize = 30) 
ax.set_xlabel('Longitude', fontsize=24) 
ax.set_ylabel('Latitude', fontsize = 24) 
ax.legend([tweet_scatter, centroid_scatter], ['Tweets', 'Tweets Cluster Centroids'], loc='upper right', fontsize = 20) 
plt.show() 

cluster_small_scale

cluster_large_scale

블랙 포인트가 소음이며, 클러스터에 추가되지 않은이 DBSCAN 입력에 의해 정의 된 , 착색 된 점은 클러스터입니다. 내 목표는 단지 ​​클러스터를 시각화하는 것입니다.

+0

나는 하나의 질문 만 포함하도록 게시물을 편집했습니다. 노이즈는 알고리즘을 사용하여 클러스터에 할당되지 않은 포인트입니다. –

+0

이 최신 편집이 소음에 대한 명확한 설명과 내가 성취하려고 시도한 바를 제공하기를 바랍니다. 내 결과의 스크린 샷을 포함 시키려고했지만 아직 충분히 높은 평판은 아닙니다. –

+1

이미지 ** ** 유용합니다. 당신은 그들을 넣을 수 있습니다, 그들은 링크로 표시됩니다. – ImportanceOfBeingErnest

답변

1

스토어에 원본 DataFrame

df['tweet_cluster_labels'] = tweet_cluster_labels 

필터 DataFrame에서 추가적인 열의 라벨 때문에 단지 (잡음 샘플 라벨 -1 주어진다)

df_filtered = df[df.tweet_cluster_labels>-1] 
비 노이즈 점을 포함

그 점들을 그려보십시오.

tweet_scatter = ax.scatter(df_filtered['longitude'], 
       df_filtered['latitude'], 
       c=df_filtered.tweet_cluster_labels, 
       cmap=cm.hot, edgecolor='None', alpha=0.25, s=50) 
+0

새로운 데이터 프레임이 트릭을 만들었습니다! 도와 주셔서 감사합니다! –