DBSCAN聚类算法概述
DBSCAN聚类算法(Density-Based Spatial Clustering of Applications with Noise,DBSCAN)是一个比较有代表性的基于密度的聚类算法。所谓密度,就是说样本的紧密程度对应其类别,属于同一个类别的样本是紧密相连的。算法通过将密度相连的样本划为一类,这样就得到了一个聚类类别。再将所有样本划为多个密度相连的不同类别,就得到了最终的聚类结果。
DBSCAN聚类算法可以在噪声空间数据库中发现任意形状的聚类。
class sklearn.cluster.DBSCAN(eps=0.5, *, min_samples=5, metric='euclidean', metric_params=None, algorithm='auto', leaf_size=30, p=None, n_jobs=None)
参数 | 说明 |
---|---|
eps | float, default=0.5 输入数据。两个样本之间的最大距离,其中一个被视为另一个样本的邻域内。这并不是一个簇内点之间距离的最大界限。。这是为数据集和距离函数适当选择的最重要的dbscan参数。 |
min_samples | int, default=5 一个点被视为核心点的邻域内的样本数(或总权重)。这包括要该点本身 |
metric | string, or callable, default=’euclidean’ 在计算特征数组中实例之间的距离时使用的度量。如果度量是字符串或可调用的,则它必须是 sklearn.metrics.pairwise_distances 为其度量参数所允许的选项之一。如果度量是“precomputed”,则假定X是距离矩阵,并且必须是平方的。X可能是Glossary,在这种情况下,只有“非零”元素可以被视为DBSCAN的邻居。新版本0.17中:度量预计算以接受预先计算的稀疏矩阵。 |
metric_params | dict, default=None 度量函数的附加关键字参数 新版本0.19中 |
algorithm | {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, default=’auto’ NearestNeighbors模块用于计算点态距离和寻找最近邻的算法。有关详细信息,请参阅NearestNeighbors模块文档。 |
p | float, default=None 用于计算点间距离的Minkowski度量的幂。 |
n_jobs | int, default=None 要运行的并行数。 None意 味 1, 除非在joblib.parallel_backend 环境中。-1 指使用所有处理器。有关详细信息,请参Glossary。 |
汽车评论数据聚类分析
利用DBSCAN算法可以方便地对批量交易、团伙作案加以挖掘,结合文本特征提取,可以对淘宝、京东、大众点评、汽车论坛等平台上面海量的评论进行聚类,挖掘刷评论用户、发现商品评价的典型意见……
-
对评论数据进行分词处理、向量转化
# 加载所需要的包
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
import os
import jieba
os.chdir(r'C:\baidupan')
train_car = pd.read_excel('car_comments_sub.xlsx')
# c=[' '.join(i) for i in [jieba.lcut(i) for i in train_car['content'].tolist()]]
#进行分字处理 用结巴分词
data_car = train_car['content'].apply(lambda x:' '.join(jieba.lcut(x)) )
data_car
# 看看分词的结果
for i in data_car.head():
print(i)
# 进行向量转化
vectorizer_word = TfidfVectorizer(max_features=10000,
token_pattern=r"(?u)\b\w+\b",
min_df = 3,
max_df=0.1,
analyzer='word',
ngram_range=(1,2)
)
vectorizer_word_car = vectorizer_word.fit(data_car)
vectorizer_word_car
# 获取tfidf矩阵
tfidf_matrix_car = vectorizer_word_car.transform(data_car)
tfidf_matrix_car.shape
#查看矩阵内容:
print(tfidf_matrix_car)
2. DBSCAN模型训练
# 进行模型训练
from sklearn.cluster import DBSCAN
clustering_car = DBSCAN(eps=0.95, min_samples=6).fit(tfidf_matrix_car)
pd.Series(clustering_car.labels_).value_counts()
查看聚类结果:
#新建列,将聚类标签打回给原始数据:
train_car['labels_'] = clustering_car.labels_
查看标签为3的聚类结果:
train_car[train_car.labels_==3]
3.调参
DBSCAN参数主要是对eps和min_samples进行调整,以获得更好的聚类表现。调参是个耗时的活儿,可以去喝个咖啡先。
import warnings
warnings.filterwarnings("ignore")
from sklearn import metrics
result = []
# 迭代eps
for eps in np.arange(0.001,1,0.05):
# 迭代min_samples
for min_samples in range(2,10):
dbscan = DBSCAN(eps = eps, min_samples = min_samples)
# 模型训练
dbscan.fit(tfidf_matrix_car)
# 统计各参数组合下的簇个数(-1表示异常点)
n_clusters = len([i for i in set(dbscan.labels_) if i != -1])
# 异常点的个数
outliners = np.sum(np.where(dbscan.labels_ == -1, 1,0))
# 统计每个簇的样本个数
stats = str(pd.Series([i for i in dbscan.labels_ if i != -1]).value_counts().values)
res.append({'eps':eps,'min_samples':min_samples,'n_clusters':n_clusters,'outliners':outliners,'stats':stats})
# 将迭代后的结果存储到DF中
df_car = pd.DataFrame(result)
df_car.rename(columns={'n_clusters':'簇个数','outliners':'异常点个数','stats':'各簇数量'}).sort_values(by=['异常点个数','簇个数'],ascending=[True,False])
4.聚类分析
以eps=0.951, min_samples=4为例,得到的簇为76个,而再往上为304个簇,结合总量情况,选取它进行下一步分析。
#将聚类标签打回给原始数据:
train_car['labels_'] = clustering_car.labels_
# 查看标签为3的聚类结果:
train_car[train_car.labels_==3]
for x in range(76):
for i in train_car[train_car.labels_==x]['content']:
print(i)
con_times=train_car.groupby(['content_id','labels_']).agg(**{'各类标签评论次数':pd.NamedAgg(column='labels_',aggfunc='count')}).unstack()
con_times=con_times.iloc[:,1:]
con_times
con_times.loc[:,('小计',"")]=con_times.sum(1,numeric_only=True)
con_times[con_times[('小计',"")]>1].fillna("")
以上已经得到各个用户在不同聚类标签下的评论次数,再结合所评价商品、商家、经销商的分布情况,即可发现背后刷评论的嫌疑犯。
文章出处登录后可见!
已经登录?立即刷新