机器学习之朴素贝叶斯、聚类算法
摘要:本文介绍了朴素贝叶斯算法和聚类算法的原理与应用。朴素贝叶斯是一种基于概率的分类算法,假设特征相互独立,适用于文本分类等场景。聚类算法则是一种无监督学习方法,通过样本相似性进行分组,包括K-means、层次聚类等。K-means算法流程包括初始化聚类中心、计算距离、重新计算中心点等步骤,评估指标有SSE、轮廓系数等。文章还提供了商品评论情感分析和客户聚类两个实际案例,展示了算法在文本处理和商业
朴素贝叶斯算法
朴素贝叶斯介绍:
概述:
贝叶斯: 仅仅依赖 概率 就可以进行分类的 一种机器学习算法.
朴素: 不考虑特征之间的关联性, 即: 特征间都是相互独立的.
原始: P(AB) = P(A) * P(B|A) = P(B) * P(A|B)
加入朴素后: P(AB) = P(A) * P(B
api
from sklearn.naive_bayes import MultinomialNB # 朴素贝叶斯对象
朴素贝叶斯demo:
"""
案例:
演示通过 朴素贝叶斯算法 实现 商品评论情感分析, 即: 好评, 差评...
朴素贝叶斯介绍:
概述:
贝叶斯: 仅仅依赖 概率 就可以进行分类的 一种机器学习算法.
朴素: 不考虑特征之间的关联性, 即: 特征间都是相互独立的.
原始: P(AB) = P(A) * P(B|A) = P(B) * P(A|B)
加入朴素后: P(AB) = P(A) * P(B)
细节:
因为我们分词要用到 jieba分词器, 记得先装一下, 例如: pip install jieba
"""
# 导包
import numpy as np # 数学计算包
import pandas as pd # 数据处理包
import matplotlib.pyplot as plt # 画图包
import jieba # 分词包
from sklearn.feature_extraction.text import CountVectorizer # 词频统计包, 把评论内容 转成 词频矩阵.
from sklearn.metrics import accuracy_score
from sklearn.naive_bayes import MultinomialNB # 朴素贝叶斯对象
# 1. 读取文件, 获取到原始数据.
df = pd.read_csv('./data/书籍评价.csv', encoding='gbk')
# df.info()
# 2. 数据预处理.
# 2.1 添加labels列, 充当: 标签列. 好评 -> 1, 差评 -> 0
df['labels'] = np.where(df['评价'] == '好评', 1, 0)
# df.info()
# print(df)
# 2.2 抽取 labels列, 作为: 标签.
y = df['labels']
# 2.3 演示 jieba 分词
# print(jieba.lcut('好好学习, 天天向上! 我爱你你爱我, 蜜雪冰城甜蜜蜜! 小明骑车, 一把把把把住了.'))
# 2.4 对用户的评论信息, 做切词.
# 数据格式: [[第1条评论切词1, 切词2, 切词3...], [第2条评论切词1, 切词2, 切词3...], ...]
comment_list = [','.join(jieba.lcut(line)) for line in df['内容']]
# 数据格式: ['第1条评论切词1, 切词2, 切词3...', '第2条评论切词1, 切词2, 切词3...', ...]
print(comment_list)
# 演示字符串的 join()函数用法.
# my_list = ['aa', 'bb', 'cc']
# print(','.join(my_list))
# 2.5 加载 停用词列表, 即: 里边记录的词, 不需要参与模型训练, 预测, 要被删除的词, 例如: 的, 啊, 哈, 从, 都...
with open('./data/stopwords.txt', 'r', encoding='utf-8') as src_f:
# 2.5.1 一次读取所有的行
stopwords_list = src_f.readlines()
# 2.5.2 删除最后的 '\n'
stopwords_list = [line.strip() for line in stopwords_list]
# 2.5.3 对 停用词列表去重.
stopwords_list = list(set(stopwords_list))
print(stopwords_list)
# 2.6 创建向量化对象, 从 评论切词列表(comment_list) 中 删除 停用词, 并且统计词频(单词矩阵).
transfer = CountVectorizer(stop_words=stopwords_list) # 参数: 停用词列表.
# 2.7 统计词频矩阵, 先训练, 后转换, 在转数组.
# transfer.fit(comment_list)
# x的格式: [[第1条评论的切词分布, 有就是1, 没有就是0], [第2条评论的切词分布, 有就是1, 没有就是0], ...]
# x = transfer.transform(comment_list).toarray()
x = transfer.fit_transform(comment_list).toarray()
print(x)
# 2.8 看一下 我们13条评论, 切词, 且删除 停用词后, 一共剩下多少个词了.
print(transfer.get_feature_names_out())
print(len(transfer.get_feature_names_out())) # 37个词, 即: 13条评论, 切词, 且删除 停用词后, 一共剩下多少个词了.
# 2.9 因为就 13条数据, 我们把前10条当训练集, 后三条当测试集.
x_train = x[:10]
y_train = y[:10]
x_test = x[10:]
y_test = y[10:]
# 3. 特征工程, 此处略.
# 4. 模型训练.
estimator = MultinomialNB() # 创建 朴素贝叶斯模型对象.
estimator.fit(x_train, y_train)
# 5. 模型预测.
y_pred = estimator.predict(x_test)
print(f'模型预测结果: {y_pred}')
# 6. 模型评估.
print(f'准确率: {accuracy_score(y_test, y_pred)}')
聚类算法
一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。
在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,对于不同的相似度计算方法,会得到不同的聚类结果,常用的相似度计算方法有欧式距离法。
关于距离计算主要分为以下几个大类:
欧氏距离
样本间所有 纬度差 的平方相加,再开方 (类似勾股定理)
曼哈顿距离(城市街区距离)
样本间所有纬度差的绝对值相加
切比雪夫距离
样本间所有纬度差的最大值
闵氏距离
样本间所有纬度差的p次方相加再开p次方
p=1 曼哈顿距离
p=2 欧氏距离
p=无穷 切比雪夫距离
聚类算法在现实中的应用
-
用户画像,广告推荐,Data Segmentation,搜索引擎的流量推荐,恶意流量识别
-
基于位置信息的商业推送,新闻聚类,筛选排序
-
图像分割,降维,识别;离群点检测;信用卡异常消费;发掘相同功能的基因片段

聚类算法的分类

聚类算法API之K-means
K-means简介: 它属于 无监督学习, 即: 有特征, 无标签, 根据样本间的相似性进行划分.
所谓的相似性 可以理解为 就是 距离,
例如: 欧式距离, 曼哈顿(城市街区)距离, 切比雪夫距离, 闵式距离...
sklearn.cluster.KMeans(n_clusters=8)
-
参数:
-
n_clusters:开始的聚类中心数量
-
整型,缺省值=8,生成的聚类数,即产生的质心(centroids)数。
-
-
-
方法:
-
estimator.fit(x)
-
estimator.predict(x)
-
estimator.fit_predict(x)
-
计算聚类中心并预测每个样本属于哪个类别,相当于先调用fit(x),然后再调用predict(x)
-
-
demo:
随机创建不同二维数据集作为训练集,并结合k-means算法将其聚类,可以尝试分别聚类不同数量的簇,并观察聚类效果:
# 1.创建数据集
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import calinski_harabaz_score
# 创建数据集
# X为样本特征,Y为样本簇类别, 共1000个样本,每个样本2个特征,共4个簇,
# 簇中心在[-1,-1], [0,0],[1,1], [2,2], 簇方差分别为[0.4, 0.2, 0.2, 0.2]
X, y = make_blobs(n_samples=1000, n_features=2, centers=[[-1, -1], [0, 0], [1, 1], [2, 2]],
cluster_std=[0.4, 0.2, 0.2, 0.2],
random_state=9)
# 数据集可视化
plt.scatter(X[:, 0], X[:, 1], marker='o')
plt.show()
# 2.使用k-means进行聚类,并使用CH方法评估
y_pred = KMeans(n_clusters=2, random_state=9).fit_predict(X)
# 分别尝试n_cluses=2\3\4,然后查看聚类效果
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
# 用Calinski-Harabasz Index评估的聚类分数
print(calinski_harabasz_score(X, y_pred))
K-means算法流程
1.事先确定常数 K (聚成几类),常数K意味着最终的聚类类别数,
随机选择 K 个样本点作为初始聚类中心
2.计算每个样本到 K 个中心的距离,选择最近的聚类中心点作为标记类别
3.根据每个类别中的样本点,重新计算出新的聚类中心点(该类中所有样本点的 x,y 平均值),
如果计算得出的新的中心点与原中心点一样,认为算法收敛,聚类完成,
否则重新计算新的聚类中心点,直到聚类中心不再变化或者达到最大迭代次数.
通过下图解释实现流程:

评价指标

-
K 表示聚类中心的个数
-
Ci 表示簇
-
p 表示样本
-
mi 表示簇的质心

SSE 越小,表示数据点越接近它们的中心,聚类效果越好。

结合了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果。
其计算过程如下:
-
计算每一个样本 i 到同簇内其他样本的平均距离 ai,该值越小,说明簇内的相似程度越大
-
计算每一个样本 i 到最近簇 j 内的所有样本的平均距离 bij,该值越大,说明该样本越不属于其他簇 j
-
计算所有样本的平均轮廓系数
-
轮廓系数的范围为:[-1, 1],值越大聚类效果越好

肘部法可以用来确定 K 值.
-
对于n个点的数据集,迭代计算 k from 1 to n,每次聚类完成后计算 SSE
-
SSE 是会逐渐变小的,因为每个点都是它所在的簇中心本身。
-
SSE 变化过程中会出现一个拐点,下降率突然变缓时即认为是最佳 n_clusters 值。
-
在决定什么时候停止训练时,肘形判据同样有效,数据通常有更多的噪音,在增加分类无法带来更多回报时,我们停止增加类别。

上述CH系数就是我们的calinski_harabaz_score
from sklearn.metrics import calinski_harabaz_score
# 用Calinski-Harabasz Index评估的聚类分数
print(calinski_harabasz_score(X, y_pred))
SSW 的含义:
-
Cpi 表示质心
-
xi 表示某个样本
-
SSW 值是计算每个样本点到质心的距离,并累加起来
-
SSW 表示表示簇内的内聚程度,越小越好
-
m 表示样本数量
-
k 表示质心个数
SSB 的含义:
-
Cj 表示质心,X 表示质心与质心之间的中心点,nj 表示样本的个数
-
SSB 表示簇与簇之间的分离度,SSB 越大越好
聚类评估demo:
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.metrics import silhouette_score
from sklearn.metrics import calinski_harabasz_score
if __name__ == '__main__':
x, y = make_blobs(n_samples=1000,
n_features=2,
centers=[[-1, -1], [0, 0], [1, 1], [2, 2]],
cluster_std=[0.4, 0.2, 0.2, 0.2],
random_state=9)
plt.figure(figsize=(18, 8), dpi=80)
plt.scatter(x[:, 0], x[:, 1], c=y)
plt.show()
estimator = KMeans(n_clusters=4, random_state=0)
estimator.fit(x)
y_pred = estimator.predict(x)
# 1. 计算 SSE 值
print('SSE:', estimator.inertia_)
# 2. 计算 SC 系数
print('SC:', silhouette_score(x, y_pred))
# 3. 计算 CH 系数
print('CH:', calinski_harabasz_score(x, y_pred))
聚类案例
已知:客户性别、年龄、年收入、消费指数
需求:对客户进行分析,找到业务突破口,寻找黄金客户

# 导包
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import pandas as pd
from sklearn.preprocessing import StandardScaler
if __name__ == '__main__':
# 1. 读取顾客数据
data = pd.read_csv('data/customers.csv')
data.columns = ['CustomerID', 'Gender', 'Age', 'Annual Income', 'Spending Score']
# print(data.head())
# 2. 对 Gender 特征进行独热编码
data = pd.get_dummies(data, columns=['Gender'])
# print(data.head())
# 3. 数据标准化
scaler = StandardScaler()
data = scaler.fit_transform(data)
print(data)
# 4. 选择最后两列(高收入\高支出),作为关键特征列,进行聚类分析
X = data.iloc[:, 3:]
# print(data[:5])
# 5. 肘部法寻找质心个数
sse = []
for k in range(1, 20):
estimator = KMeans(n_clusters=k, random_state=0)
estimator.fit(data)
sse.append(estimator.inertia_)
plt.plot(range(1, 20), sse)
plt.show()
# 6. 确定质心的个数
estimator = KMeans(n_clusters=10, n_init=10, random_state=0)
# n_init 算法会使用不同的随机初始中心点,独立运行 10 次,每次运行都会计算最终的簇内误差平方和(inertia),最后选择误差最小的那次结果作为最终模型
y_pred = estimator.fit_predict(data)
# 7. 聚类结果可视化
plt.scatter(X.values[y_pred == 0, 0], X.values[y_pred == 0, 1], s=100, c='red', label='Standard')
# 在 plt.scatter() 函数中,s=100 参数的意思是:设置散点图中点的大小为 100
plt.scatter(X.values[y_pred == 1, 0], X.values[y_pred == 1, 1], s=100, c='blue', label='Traditional')
plt.scatter(X.values[y_pred == 2, 0], X.values[y_pred == 2, 1], s=100, c='green', label='Normal')
plt.scatter(X.values[y_pred == 3, 0], X.values[y_pred == 3, 1], s=100, c='cyan', label='Youth')
plt.scatter(X.values[y_pred == 4, 0], X.values[y_pred == 4, 1], s=100, c='magenta', label='TA')
plt.scatter(estimator.cluster_centers_[:, 0], estimator.cluster_centers_[:, 1], s=300, c='black', label='Centroids’)
plt.title('Clusters of customers')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.legend()
plt.show()
效果如图所示:

聚类算法总结
什么是聚类
一种无监督学习算法,根据样本间的相似性,将样本划分到不同的类别中
聚类算法分类
Kmeans\层次聚类\DBSCAN聚类\谱聚类
Kmeans算法原理
k的含义:聚成几类
k的选择方法:肘部法则
SSE 变化过程中会出现一个拐点,下降率突然变缓时即认为是最佳 n_clusters 值
Kmeans实现流程:
1.事先确定常数 K (聚成几类),常数K意味着最终的聚类类别数,
随机选择 K 个样本点作为初始聚类中心
2.计算每个样本到 K 个中心的距离,选择最近的聚类中心点作为标记类别
3.根据每个类别中的样本点,重新计算出新的聚类中心点(该类中所有样本点的 x,y 平均值),
如果计算得出的新的中心点与原中心点一样,认为算法收敛,聚类完成,
否则重新计算新的聚类中心点,直到聚类中心不再变化或者达到最大迭代次数.
API:klearn.cluster.KMeans(n_clusters=8)
聚类评估方法
SSE
簇内误差的平方和
SSE越小,聚类效果越好
SC轮廓系数
综合考虑簇内的内聚程度与簇间的分离程度
SC越大,聚类效果越好
CH轮廓系数
综合考虑簇内的内聚程度、簇间的分离程度、质心的个数
CH越大,聚类效果越好
以上观点仅供参考学习,欢迎评区域留言~~~
更多推荐






所有评论(0)