前言在机器学习的世界里有监督学习与无监督学习如同“两条腿”并驾齐驱。而朴素贝叶斯Naïve Bayes 和K-Means聚类分别是这两大分支中最为经典、应用广泛的入门级算法。朴素贝叶斯基于贝叶斯定理借助“特征条件独立”这一强力假设将复杂的联合概率计算大大简化在文本分类、垃圾邮件过滤、情感分析等任务中表现高效且稳健。K-Means聚类则是一种典型的无监督学习算法通过迭代寻找最优的聚类中心将相似的样本自动归为一类在用户画像、图像分割、异常检测等场景中扮演重要角色。朴素贝叶斯朴素贝叶斯介绍常见的概率公式条件概率表示事件A在另外一个事件B已经发生条件下的发生概率P(A|B)在女神喜欢的条件下职业是程序员的概率女神喜欢条件下有 2、3、4、7 共 4 个样本4 个样本中有程序员 3、4 共 2 个样本则 P(程序员|喜欢) 2/4 0.5联合概率表示多个条件同时成立的概率P(AB) P(A) P(B|A)特征条件独立性假设P(AB) P(A) P(B)职业是程序员并且体型匀称的概率数据集中共有 7 个样本职业是程序员有 1、3、4 共 3 个样本则其概率为3/7在职业是程序员体型是匀称有 3 共 1 个样本则其概率为1/3则即是程序员又体型匀称的概率为3/7 * 1/3 1/7联合概率 条件概率在女神喜欢的条件下职业是程序员、体重超重的概率 P(AB|C) P(A|C) P(B|AC)在女神喜欢的条件下有 2、3、4、7 共 4 个样本在这 4 个样本中职业是程序员有 3、4 共 2 个样本则其概率为2/40.5在在 2 个样本中体型超重的有 4 共 1 个样本则其概率为1/2 0.5则 P(程序员, 超重|喜欢) 0.5 * 0.5 0.25简言之条件概率在去掉部分样本的情况下计算某些样本的出现的概率表示为P(B|A)联合概率多个事件同时发生的概率是多少表示为P(AB) P(B)*P(A|B)贝叶斯公式P© 表示 C 出现的概率P(W|C) 表示 C 条件 W 出现的概率P(W) 表示 W 出现的概率P(C|W) P(喜欢|程序员超重)P(W|C) P(程序员超重|喜欢)P© P(喜欢)P(W) P(程序员超重)根据训练样本估计先验概率P©P(喜欢) 4/7根据条件概率P(W|C)调整先验概率P(程序员,超重|喜欢) 1/4此时我们的后验概率P(C|W)为P(程序员,超重|喜欢) * P(喜欢) 4/7 * 1/4 1/7那么该部分数据占所有既为程序员又超重的人中的比例是多少呢P(程序员,超重) P(程序员) * P(超重|程序员) 3/7 * 2/3 2/7P(喜欢|程序员, 超重) 1/7 ➗ 2/7 0.5朴素贝叶斯贝叶斯概率计算过程中需要计算 P(程序员,超重|喜欢) 和 P(程序员, 超重) 等联合概率为了简化联合概率的计算朴素贝叶斯在贝叶斯基础上增加特征条件独立假设即特征之间是互为独立的。此时联合概率的计算即可简化为P(程序员,超重|喜欢) P(程序员|喜欢) * P(超重|喜欢)P(程序员,超重) P(程序员) * P(超重)拉普拉斯平滑系数α 是拉普拉斯平滑系数一般指定为 1Ni是 F1 中符合条件 C 的样本数量N 是在条件 C 下所有样本的总数m 表示所有独立样本的总数为了避免概率值为 0在分子和分母分别加上一个数值这就是拉普拉斯平滑系数的作用。情感分析案例api介绍sklearn.naive_bayes.MultinomialNB(alpha 1.0)朴素贝叶斯分类alpha拉普拉斯平滑系数商品评论情感分析已知商品评论数据根据数据进行情感分类好评、差评步骤分析1获取数据2数据基本处理2.1 取出内容列对数据进行分析2.2 判定评判标准2.3 选择停用词2.4 把内容处理转化成标准格式2.5 统计词的个数2.6准备训练集和测试集3模型训练4模型评估代码实现importpandasaspdimportnumpyasnpimportjiebaimportmatplotlib.pyplotaspltfromsklearn.feature_extraction.textimportCountVectorizerfromsklearn.naive_bayesimportMultinomialNBdatapd.read_csv(../data/书籍评价.csv,encodinggbk)# 数据预处理# 添加labels列充当标签列 1:好评 0差评data[labels]np.where(data[评价]好评,1,0)# 抽取labels列作为标签ydata[labels]# 对用户的评价内容做分词comment_list[,.join(jieba.lcut(comment))forcommentindata[内容]]# 加载停用词列表即里面记录的词不需要参与模型训练预测要被删除的词例如的啊哈从都withopen(../data/stopwords.txt,r,encodingutf-8)asf:# 一次性读取所有行stopwords_listf.readlines()# 删除最后的\nstopwords_list[stopword.strip()forstopwordinstopwords_list]# 对停用词列表进行去重stopwords_listlist(set(stopwords_list))# 创建向量化对象从评论切词列表中删除停用词并且统计词频transferCountVectorizer(stop_wordsstopwords_list)# 参数停用词列表# 统计词频矩阵xtransfer.fit_transform(comment_list).toarray()print(x)x_trainx[:10]y_trainy[:10]x_testx[10:]y_testy[10:]# 特征工程# 模型训练estimatorMultinomialNB()# 创建朴素贝叶斯对象estimator.fit(x_train,y_train)# 模型预测y_preestimator.predict(x_test)print(f模型预测结果{y_pre})# 模型评估print(f准确率{accuracy_score(y_test,y_pre)})[[0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0] [0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 1] [0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0] [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0]] 模型预测结果[0 0 0] 准确率1.0聚类算法聚类算法简介聚类算法介绍一种典型的无监督学习算法主要用于将相似的样本自动归到一个类别中。在聚类算法中根据样本之间的相似性将样本划分到不同的类别中对于不同的相似度计算方法会得到不同的聚类结果常用的相似度计算方法有欧式距离法。聚类算法在现实中的应用用户画像广告推荐Data Segmentation搜索引擎的流量推荐恶意流量识别基于位置信息的商业推送新闻聚类筛选排序图像分割降维识别离群点检测信用卡异常消费发掘相同功能的基因片段分类聚类API的初步使用api介绍sklearn.cluster.KMeans(n_clusters8)参数:n_clusters:开始的聚类中心数量整型缺省值8生成的聚类数即产生的质心centroids数。方法:estimator.fit(x)estimator.predict(x)estimator.fit_predict(x)计算聚类中心并预测每个样本属于哪个类别,相当于先调用fit(x),然后再调用predict(x)案例随机创建不同二维数据集作为训练集并结合k-means算法将其聚类你可以尝试分别聚类不同数量的簇并观察聚类效果importmatplotlib.pyplotaspltfromsklearn.datasetsimportmake_blobs# 默认会按照高斯分布生成数据集只需要指定均值标准差fromsklearn.clusterimportKMeans# 聚类的API采用指定质心来分簇fromsklearn.metricsimportcalinski_harabasz_score# 评价指标值越大聚类效果越好# 准备数据集#参1样本数量 参2样本特征数量 参3样本标签数量 参4标准差 参5随机种子x,ymake_blobs(n_samples1000,n_features2,centers[[-1,-1],[0,0],[1,1],[2,2]],cluster_std[0.4,0.2,0.2,0.2],random_state23)# 绘制上述的图形# 参1横坐标 参2纵坐标 参3颜色plt.scatter(x[:,0],x[:,1])plt.show()# 创建KMeans对象estimatorKMeans(n_clusters4,random_state23)# 模型训练和预测y_preestimator.fit_predict(x)# 预测值# 绘制预测结果plt.scatter(x[:,0],x[:,1],cy_pre)plt.show()# 评价指标print(f评价指标{calinski_harabasz_score(x,y_pre)})# 越大越好Kmeans算法流程k-means聚类流程1、随机设置K个特征空间内的点作为初始的聚类中心2、对于其他每个点计算到K个中心的距离未知的点选择最近的一个聚类中心点作为标记类别3、接着对着标记的聚类中心之后重新计算出每个聚类的新中心点平均值4、如果计算得出的新中心点与原中心点一样质心不再移动那么结束否则重新进行第二步过程通过下图解释实现流程k-means聚类动态效果图案例练习1、随机设置K个特征空间内的点作为初始的聚类中心本案例中设置p1和p22、对于其他每个点计算到K个中心的距离未知的点选择最近的一个聚类中心点作为标记类别3、接着对着标记的聚类中心之后重新计算出每个聚类的新中心点平均值注意这里P2′(2.3,3.3)下同。4、如果计算得出的新中心点与原中心点一样质心不再移动那么结束否则重新进行第二步过程【经过判断需要重复上述步骤开始新一轮迭代】5、当每次迭代结果不变时认为算法收敛聚类完成K-Means一定会停下不可能陷入一直选质心的过程。评价指标SSE-误差平方和K 表示聚类中心的个数Ci表示簇p 表示样本mi表示簇的质心SSE 越小表示数据点越接近它们的中心聚类效果越好。SC 系数结合了聚类的凝聚度Cohesion和分离度Separation用于评估聚类的效果。其计算过程如下计算每一个样本 i 到同簇内其他样本的平均距离 ai该值越小说明簇内的相似程度越大计算每一个样本 i 到最近簇 j 内的所有样本的平均距离 bij该值越大说明该样本越不属于其他簇 j计算所有样本的平均轮廓系数轮廓系数的范围为[-1, 1]值越大聚类效果越好肘部法肘部法可以用来确定 K 值.对于n个点的数据集迭代计算 k from 1 to n每次聚类完成后计算 SSESSE 是会逐渐变小的因为每个点都是它所在的簇中心本身。SSE 变化过程中会出现一个拐点下降率突然变缓时即认为是最佳 n_clusters 值。在决定什么时候停止训练时肘形判据同样有效数据通常有更多的噪音在增加分类无法带来更多回报时我们停止增加类别。CH 系数CH 系数结合了聚类的凝聚度Cohesion和分离度Separation、质心的个数希望用最少的簇进行聚类。SSW 的含义Cpi表示质心xi表示某个样本SSW 值是计算每个样本点到质心的距离并累加起来SSW 表示表示簇内的内聚程度越小越好m 表示样本数量k 表示质心个数SSB 的含义Cj表示质心X 表示质心与质心之间的中心点nj表示样本的个数SSB 表示簇与簇之间的分离度SSB 越大越好聚类评估的使用# 定义函数演示SSE 肘部法defdm01_sse():# 定义sse列表记录每个k值的SSE值sse_list[]# 生成数据集 参1样本数量 参2样本特征数量 参3样本标签数量 参4标准差 参5随机种子x,ymake_blobs(n_samples1000,n_features2,centers[[-1,-1],[0,0],[1,1],[2,2]],cluster_std[0.4,0.2,0.2,0.2],random_state23)# for循环遍历获取每个k值计算其对应的sse值并添加到sseforkinrange(1,100):# 创建KMeans对象指定 k值迭代次数随机种子estimatorKMeans(n_clustersk,max_iter100,random_state23)# 训练模型estimator.fit(x)# 模型预测y_predestimator.predict(x)# 获取每个簇的sse值sse_valueestimator.inertia_# 将每个k值对应的sse值添加到sse_list列表中sse_list.append(sse_value)# 绘制SSE曲线-数据可视化plt.figure(figsize(20,10))plt.title(SSE value)plt.xticks(range(0,100,3))plt.xlabel(k)plt.ylabel(sse)plt.grid()# 参1k值 参2该k值对应的SSE值plt.plot(range(1,100),sse_list)plt.show()fromsklearn.datasetsimportmake_blobsfromsklearn.clusterimportKMeansimportmatplotlib.pyplotaspltfromsklearn.metricsimportsilhouette_scorefromsklearn.metricsimportcalinski_harabasz_scoreif__name____main__:x,ymake_blobs(n_samples1000,n_features2,centers[[-1,-1],[0,0],[1,1],[2,2]],cluster_std[0.4,0.2,0.2,0.2],random_state9)plt.figure(figsize(18,8),dpi80)plt.scatter(x[:,0],x[:,1],cy)plt.show()estimatorKMeans(n_clusters4,random_state0)estimator.fit(x)y_predestimator.predict(x)# 1. 计算 SSE 值print(SSE:,estimator.inertia_)# 2. 计算 SC 系数print(SC:,silhouette_score(x,y_pred))# 3. 计算 CH 系数案例案例介绍已知客户性别、年龄、年收入、消费指数需求对客户进行分析找到业务突破口寻找黄金客户数据集共包含顾客的数据, 数据共有 4 个特征, 数据共有 200 条。接下来使用聚类算法对具有相似特征的的顾客进行聚类并可视化聚类结果。案例实现# 定义函数 找聚类的质心数K值defdm01_find_k():# 加载数据集dataps.read_csv(../data/customers.csv)# 定义sse_listsc_list记录不同k值的评估效果sse_list[]#sse 只考虑簇内越小越好sc_list[]# sc考虑簇内和簇间越大越好# 抽取特征xdata.iloc[:,3:5]# 定义for训练测试不同k值的评估效果forkinrange(2,20):# 创建KMeans对象指定 k值迭代次数随机种子estimatorKMeans(n_clustersk,max_iter100,random_state23)# 训练模型estimator.fit(x)# 模型预测y_predestimator.predict(x)# 获取每个簇的sse值sse_valueestimator.inertia_# 将每个k值对应的sse值添加到sse_list列表中sse_list.append(sse_value)sc_valuesilhouette_score(x,y_pred)# 将每个k值对应的sc值添加到sc_list列表中sc_list.append(sc_value)# 绘制折线图看看k值哪个最好plt.figure(figsize(20,10))plt.plot(range(2,20),sse_list,labelSSE)plt.legend()plt.show()plt.figure(figsize(20,10))plt.plot(range(2,20),sc_list,labelSC)plt.legend()plt.show()# 结论k5的时候效果最好# 定义函数实现模型训练模型预测、模型评估defdm02():dataps.read_csv(../data/customers.csv)xdata.iloc[:,3:5]# k5是之前通过上面方法获取到的estimatorKMeans(n_clusters5,max_iter100,random_state23)estimator.fit(x)# 模型预测y_preestimator.predict(x)# 绘制5个簇的样本点 -散点图plt.scatter(x.values[y_pre0,0],x.values[y_pre0,1],s100,cred,labelStandard)# [[15,39],[15, 81]...] 0号簇plt.scatter(x.values[y_pre1,0],x.values[y_pre1,1],s100,cblue,labelTraditional)# 1号簇plt.scatter(x.values[y_pre2,0],x.values[y_pre2,1],s100,cgreen,labelNormal)# 2号簇plt.scatter(x.values[y_pre3,0],x.values[y_pre3,1],s100,ccyan,labelYouth)# 3号簇plt.scatter(x.values[y_pre4,0],x.values[y_pre4,1],s100,cmagenta,labelTA)# 4号簇# 绘制5个簇的质心 - 散点图plt.scatter(estimator.cluster_centers_[:,0],estimator.cluster_centers_[:,1])plt.title(Clusters of Customers)plt.xlabel(Annual Income (k$))plt.ylabel(Spending Score (1-100))plt.legend()plt.show()x.values[y_pre 0, 0]x.values因为 x 是 Pandas 的 DataFrame带表头而 plt.scatter 只认 Numpy 数组所以用 .values 把它变成纯粹的二维数组200行2列。第 0 列是“年收入”第 1 列是“消费指数”。y_pre 0y_pre 里存的是每个客户的组别0,1,2,3,4。y_pre 0 会生成一个布尔掩码Boolean Mask比如 [True, False, True, …]长度为200。相当于一个“筛选器”告诉程序“只要属于 0 号簇的行”。合在一起 x.values[布尔掩码, 0]在 Numpy 中逗号前面管“行”逗号后面管“列”。它先根据布尔掩码把属于 0 号簇的那些行挑出来然后 , 0 表示只取这些行的第 0 列年收入作为散点图的 X 轴数据。同理x.values[y_pre 0, 1] 就是取这些行的第 1 列消费指数作为 Y 轴。总结机器学习不仅在于“调包”更在于理解算法背后的数学逻辑与适用边界。希望本文能帮助你建立起从理论到实践的桥梁在未来面对分类或聚类任务时能够从容选择、高效实现。欢迎在评论区交流你的实战心得或疑问让我们共同进步