Python数据挖掘算法入门与实践

共 21709字,需浏览 44分钟

 ·

2024-04-10 16:09

一、数据挖掘简介

数据挖掘是一个通过对大量数据进行清理和处理,以发现其中隐藏的信息和模式的过程。简单来说,它是从大量数据中提取或“挖掘”知识的过程,也称为知识发现。




随着互联网和移动工具的发展,我们每天产生的数据量非常庞大,这些数据通常被收集并存储在大型数据库中。数据挖掘技术提供了一种有效的方法,可以从这些海量数据中提取有价值的信息,从而为决策提供重要依据 。这个过程在许多领域都有广泛的应用,如新闻 分类、推荐系统等。




数据挖掘一般的流程如下:




d44cd7ac82e6885d79e777ebf9c50a7e.webp



  1. 首先,进行数据挖掘的第一步是数据选择。在明确了业务需求后,我们需要从各种来源中选择与需求相关的数据。这些数据可能来自业务原始数据、公开的数据集,或者通过爬虫从网站上抓取的结构化数据。选择合适的数据是进行数据挖掘的基础。


  2. 接下来是数据预处理阶段。在这个阶段,我们需要对选定的数据进行清洗和处理,以消除其中的噪音和不完整信息。


  3. 完成数据预处理后,我们进入特征工程或数据转换阶段。这个阶段的目标是根据所选择的算法,从预处理好的数据中提取出有意义的特征,并将其转换为适合特定数据挖掘算法的分析模型。


  4. 然后是数据挖掘阶段。在这个阶段,我们将使用选定的数据挖掘算法对处理过的数据进行深入分析,以发现其中的模式和关联。


  5. 最后是解释与评价阶段。在这个阶段,我们将对数据挖掘的结果进行解释和评价,以便将其应用于实际的工作领域。







二、数据挖掘算法简介




044b00c13f46bbea501cd9bfa145c865.webp


2.1 关联分析
关联规则分析的目标是发现数据集中不同属性之间的关联。为了达到这个目标,关联规则算法设置了最小支持度阈值和最小置信度阈值。这些算法致力于在尽可能高效的方式下完成这个任务。


常见的关联规则算法包括Apriori算法、AprioriTid算法和FP-growth算法。


315bc378aa684976ae7b7a7f4d77ff66.webp


2.2 分类算法
分类算法的目标是将数据集中的对象分配到预定义的类别中。以下是几种经典的分类算法:


6fa0b840fddd07fe46978c446c7916b0.webp



  • 决策树算法:使用树形结构表示分类或决策集合,从而产生规则或发现规律。主要的算法包括ID3、C4.5、SLIQ、SPRING和RainForest。


  • 朴素贝叶斯分类算法:基于贝叶斯定理,通过计算每个类别的概率来选择概率最大的类别进行分类。


  • KNN分类算法:基于最近邻原理,将距离相近的归为同一类。


  • CBA(基于关联规则的分类算法):利用关联规则进行分类。


  • MIND(在数据库中挖掘)算法:使用用户定义的函数(UDF)在数据库中实现分类的算法。


  • 神经网络分类算法:利用训练集对多层的神经网络进行训练,然后用训练好的模型对样本进行分类。


  • 粗集理论:一种不需要预先给出特征或属性数量描述的分类方法,直接从问题出发,通过不可分辨关系和不可分辨类确定近似域,找出问题的内在规律。


  • 遗传算法:模拟生物进化过程的优化求解技术,利用选择、交叉和变异三个基本方法进行优化。



2.3 回归分析


回归分析主要研究因变量(目标)和自变量(预测器)之间的关系。在大数据分析中,回归分析是一种预测性的建模技术,它通过研究因变量和影响它的自变量之间的回归模型,来预测因变量的发展趋势。当有多个自变量时,可以研究每个自变量对因变量的影响强度。


466ec4bc4455f5a3ac7bbe896b61e50f.webp


回归分析的分类如下:



  • 按自变量的多少分为:一元回归分析和多元回归分析。


  • 按因变量的多少分为:简单回归分析和多重回归分析。


  • 按自变量和因变量之间的相关关系不同分为:线性回归分析和非线性回归分析。



2.4 聚类算法
聚类分析处理的对象集合中,对象的类是未知的。它的目标是将对象集合分组为多个由类似对象组成的簇。聚类分析的方法可以分为以下三类:


8991c7532a71d9ba6c2fad7ba9c03805.webp



  • 分区方法:给定一个包含N个对象或元组的数据库,分区方法构建数据的K个划分,每个划分表示一个聚簇,且K < N。经典算法是K-MEAN(K平均值)算法。


  • 层次方法:对给定的数据对象集合进行层次的分解。经典算法是BIRCH(平衡迭代减少和聚类使用层次结构)算法。


  • 基于网格的方法:采用多分辨率的网格数据结构,将空间量化为有限数目的单元,形成网格结构,所有的聚类分析都在网格上进行。常用的算法有STING(统计信息网格)、CLIQUE(基于网格的聚类)和SKWAVECLUSTER(声波聚类)等。




三、相关预备知识




3.1 距离(相似度)度量


距离度量可用于在数据挖掘中明确样本数据相似度,通常可以计算样本间的距离,如下为常用距离度量的介绍。


样本数据以如下三个人的身高体重示例:6090d5de833da3d3ebec986d35d3b727.webp展示到坐标图中是这样的:


938173dcc0da58b51c3cb59b17d6d071.webp

曼哈顿距离: 也称曼哈顿街区距离,就如从街区的一个十字路口点到另一个十字路口点的距离, 二维空间(多维空间按同理扩展)用公式表示为




a8fb0e75ea985475d01588203df60058.webp





861894aeb3a5a1debb0d67665bdf862b.webp





欧氏距离:表示为点到点的距离。二维空间(多维空间按同理扩展)的公式表示为




d6f2def758c9b14834a092cce9b1b297.webp





1fcda95b70290c64d19d0f93de0d6dc7.webp





闵可夫斯基距离:其实就是距离方法的通用概括,当 p=1 既是曼哈顿距离,当 p=2 既是欧氏距离。当p越大,单一维度的差值对整体的影响就越大。




e8119e59d3312dda4415ccfb833934f1.webp



余弦相关系数


样本数据视为向量,通过两向量间的夹角余弦值确认相关性,数值范围[-1,1]。-1表示负相关,0表示无关,1表示正相关。


09480f5cfbad4ed809139b8c3449d0f2.webp余弦相关系数的优缺点:


优点:余弦相似度与向量的幅值无关,只与向量的方向相关,在文档相似度(TF-IDF)和图片相似性(histogram)计算上都有它的身影;而且在样本数值稀疏的时候仍可以使用。


缺点:余弦相似度受到向量的平移影响,上式如果将 x 平移到 x+1, 余弦值就会改变。(可以理解为受样本的起始标准的影响,接下来介绍的皮尔逊相关系数可以消除这个影响)


皮尔逊相关系数


计算出了样本向量间的相关性,数值范围[-1,1]。 f40215a1d52f19a46f992fd9829f5b47.webp


考虑计算的遍历的次数,有一个替代公式可以近似计算皮尔逊相关系数:


d2dd426637b9872c905e332803593c3d.webp

皮尔逊相关系数优点:可消除每个分量标准不同(分数膨胀)的影响,具有平移不变性和尺度不变性




3.2 数据标准化


数据中如果各分量的单位尺度差异很大,可以使用数据标准化消除不同分量间单位尺度的影响,,加速模型收敛的效率,常用的方法有三种:


min-max 标准化:将数值范围缩放到(0,1),但没有改变数据分布。max为样本最大值,min为样本最小值。


a378ceb4b3a71a0596ba4489ce2477f8.webp

z-score 标准化:将数值范围缩放到0附近, 经过处理的数据符合标准正态分布。u是平均值,σ是标准差。




59d9e0ca8e3055470c2819d866b7ecb9.webp

修正的标准z-score:修正后可以减少样本数据异常值的影响。将z-score标准化公式中的均值改为中位数,将标准差改为绝对偏差。


33c03eddd2d78ed0a2103a326f6f1fa0.webp


其中asd绝对偏差:u为中位数,card(x)为样本个数


dda52ea2b32075cb385fc23e01d2fc38.webp





3.3 算法的效果评估方法



  • 十折交叉验证:将数据集随机分成十份,每次使用九份进行训练,剩余一份进行测试,这个过程重复十次,确保每份数据都至少被使用过一次作为测试集。关键在于保证数据集被均匀地分成十份。


  • N折交叉验证:又称为留一法,它利用几乎所有的数据来进行训练,然后留出一份数据进行测试。这个过程会迭代进行,确保每一份数据都被用作过测试集。


  • 训练-测试划分验证:随机将数据集划分为训练集和验证集,用于评估模型的性能。





四、数据挖掘算法原理及实践





  1. 4.1 Apriori关联分析算法



模型原理:Apriori算法是一种用于频繁项集挖掘和关联规则学习的算法。其主要思想是通过候选生成和剪枝策略发现频繁项集。它利用了数据集中的项集(items)的先验知识,通过减少不必要的搜索来提高效率。a195632f1027d4f5b15f01ee39baf155.webp


使用场景:常用于市场篮子分析,如超市购物篮分析,以发现商品之间的关联关系。


Python示例代码:


        



from mlxtend.frequent_patterns import apriori


from mlxtend.frequent_patterns import association_rules








# 假设df是包含交易数据的DataFrame,'item'是商品列



frequent_itemsets = apriori(df, min_support=0.05, use_colnames=True)


rules = association_rules(frequent_itemsets, metric="confidence",min_threshold=0.7)

 

4.2 协同过滤推荐算法


基于用户的协同过滤是通过计算用户之间的距离找出最相似的用户(需要将所有的评价数据在读取在内存中处理进行推荐),并将相似用户评价过的物品推荐给目标用户。


7dda768066a452f3dfe7b447e684bfaf.webp


而基于物品的协同过滤则是找出最相似的物品(通过构建一个物品的相似度模型来做推荐),再结合用户的评价来给出推荐结果。算法常用有 修正余弦相似度算法:以物品的评分作为物品的属性值,通过对比物品i,j的共有的用户相对评分的计算相关性s(i,j)。


d584db4c83af56f553ebb50a6666f1b7.webp


Python示例代码:


          
import numpy as np








# 用户-物品评分矩阵



ratings = np.array([[5, 3, 0, 1],


[4, 0, 0, 0],


[0, 5, 3, 0],


[0, 4, 5, 5]])








# 计算用户之间的相似度




def similarity(ratings):



n = ratings.shape[0]


sim = np.zeros((n, n))


for i in range(n):


for j in range(n):


if i != j:


sim[i][j] = np.corrcoef(ratings[i], ratings[j])[0, 1]


return sim








# 基于用户的协同过滤推荐算法




def user_based_collaborative_filtering(ratings, threshold=0.6):



n = ratings.shape[0]


sim = similarity(ratings)


rec_list = {}


for i in range(n):


for j in range(n):


if i != j and sim[i][j] > threshold:


for k in range(len(ratings[j])):


if ratings[j][k] == 0 and ratings[i][k] != 0:


rec_list[k] = ratings[i][k]


return rec_list








# 获取推荐结果



rec_list = user_based_collaborative_filtering(ratings)


print(rec_list)


4.3 分类算法


(1)基于物品特征值的KNN分类算法




代码实现:iris鸢尾花KNN分类算法


          
...







# KNN核心逻辑手写


def knn(self, oj_list):


weight_dict = {"Iris-setosa":0.0, "Iris-versicolor":0.0, "Iris-virginica":0.0}


for atuple in oj_list:


weight_dict[atuple[1]] += (1.0 / atuple[0])


rel_class = [(key, value) for key, value in weight_dict.items()]


#print(sorted(rel_class, key=lambda x:x[1], reverse=True))


rel_class = sorted(rel_class, key=lambda x:x[1], reverse=True)[0][0]


return rel_class







...


# 调用sklearn直接实现


from sklearn.datasets import load_iris


from sklearn.model_selection import train_test_split


from sklearn.neighbors import KNeighborsClassifier


from sklearn.metrics import classification_report, confusion_matrix







# 加载鸢尾花数据集


iris = load_iris()


X = iris.data


y = iris.target







# 划分数据集为训练集和测试集


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)







# 创建KNN分类器,并设置邻居数量为3


knn = KNeighborsClassifier(n_neighbors=3)







# 使用训练数据训练KNN分类器


knn.fit(X_train, y_train)







# 使用测试数据进行预测


y_pred = knn.predict(X_test)







# 输出分类器的评估结果


print("Classification Report:\n", classification_report(y_test, y_pred))


print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred))


前面我们讨论的协同推荐算法,需要在用户生成的各种数据上进行深入分析,因此也被称为社会化过滤算法。然而,这种算法存在一些明显的问题,如数据的稀疏性、算法的可扩展性,以及过度依赖用户数据。为了解决这些问题,我们可以采用基于物品特征值分类的算法。

这个算法主要分为两个步骤: 第一步是特征值的选取。这一步是至关重要的,因为它决定了算法的准确性和效率。我们需要挑选出具有代表性且能提供区分度的特征值。以Iris花为例,我们可以选取花萼长度、花萼宽度、花瓣长度和花瓣宽度作为特征值。
a969bcaccc96c519cadb67e424ea7c6b.webp第二步是计算距离。在这一步中,我们将测试集与训练集的特征值进行比较,计算它们之间的曼哈顿距离。通过这种方式,我们可以找到与测试集最相似的k个训练样本。然后,我们使用加权后的结果来预测分类。
然而,KNN分类算法也存在一些缺点。首先,它无法对分类结果的置信度进行量化,这意味着我们无法确定分类的准确性。其次,它是一种被动学习的算法,这意味着每次进行测试时都需要遍历所有的训练集,这可能导致算法的效率较低。



(2)贝叶斯分类算法




代码实现:


          
...



# bayes 核心逻辑手写




def bayes(self):




#训练组的条件概率



for word in self.vocabulary:


for category,value in self.prob.items():


if word not in self.prob[category]:


count = 0


else :


count = self.prob[category][word]



#优化条件概率公式



self.prob[category][word] = (count + 1) / (self.total[category] + len(self.vocabulary))







...



# 调用sklearn实现



from sklearn.feature_extraction.text import CountVectorizer


from sklearn.naive_bayes import MultinomialNB


from sklearn.model_selection import train_test_split


from sklearn.metrics import accuracy_score


import pandas as pd








# 假设你有一个文本数据集,存储在CSV文件中,有两列:'text'和'label'



data = pd.read_csv('text_data.csv')








# 提取特征和标签



X = data['text'].values


y = data['label'].values








# 切分数据集为训练集和测试集



X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)








# 使用CountVectorizer将文本转换为向量



vectorizer = CountVectorizer()


X_train_transformed = vectorizer.fit_transform(X_train)


X_test_transformed = vectorizer.transform(X_test)








# 使用朴素贝叶斯分类器进行训练



classifier = MultinomialNB()


classifier.fit(X_train_transformed, y_train)








# 对测试集进行预测



y_pred = classifier.predict(X_test_transformed)








# 计算准确率



accuracy = accuracy_score(y_test, y_pred)


print(f"Accuracy: {accuracy}")







贝叶斯分类算法是基于概率的分类算法。相比于KNN分类算法,它是主动学习的算法,它会根据训练集建立一个模型,并用这个模型对新样本进行分类,速度也会快很多。




贝叶斯分类算法的理论基础是基于条件概率的公式(应用于现实中P(X|Y&Z)不直观得出,而P(Y|X)*P(Z|X)比较直观得出),并假设已存在的子事件(y,z...实际应用中会有多个)间是相互独立的(因此也称为朴素贝叶斯),当y,z事件假设为独立便有:






ee1b5e7c2ebe38178975094a98003d41.webp

如下举例推测买牛奶和有机食品,再会买绿茶的概率:




442326c013f6518bf42c4d485b28a56c.webp





第一步:计算先验概率及条件概率


先验概率:为单独事件发生的概率,如P(买绿茶),P(有机食品)


条件概率(后验概率):y事件已经发生,观察y数据集后得出x发生的概率。如P(买有机食品|买绿茶),通过以下公式计算(nc表示y数据集下x的发生频数,n为y数据集的总数):






91605a2a19a2eb748515ceae96e73491.webp

上式存在一个缺陷,当一个条件概率 P(y|x)为0时,整体的预测结果P(x) * P(y|x) * P(z|x)只能为0,这样便不能更全面地预测。






修正后的条件概率:(公式摘自Tom Mitchell《机器学习》。m是一个常数,表示等效样本大小。决定常数m的方法有很多,我们这里可以使用预测结果的类别来作为m,比如投票有赞成和否决两种类别,所以m就为2。p则是相应的先验概率,比如说赞成概率是0.5,那p(赞成)就是0.5。):






d6ab8692cdb7f5d21734ccce0e2c9279.webp





第二歩:根据贝叶斯公式做出预测






ee1b5e7c2ebe38178975094a98003d41.webp





由公式计算比较y&z事件发生下,不同x事件发生的概率差异,如得出P(x=喜欢),P(x=不喜欢) 的概率大小,预测为概率比较大的事件。因为P(y)*p(z)在上式都一样,因此公式可以简化为计算概率最大项而预测分类:




6024bae9d029d21bcaaa487d8348de50.webp





贝叶斯算法的优点:能够给出分类结果的置信度;它是一种主动学习算法,速度更快。


贝叶斯算法的缺点:需要特定格式;数值型数据需要转换为类别计算概率或用高斯分布计算概率;




(3)神经网络(DNN)分类算法




代码实现 :


          

import tensorflow as tf




from tensorflow.keras import layers, models




import numpy as np




import matplotlib.pyplot as plt




import cv2









# 加载数据集,这里我们使用的是MNIST数据集,你可以替换成自己的数据集




(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()









# 对数据进行归一化处理




train_images = train_images / 255.0




test_images = test_images / 255.0









# 构建DNN模型




model = models.Sequential()




model.add(layers.Dense(512, activation='sigmoid', input_shape=(28, 28))) # 输入层,28x28是MNIST图片的大小




model.add(layers.Dense(512, activation='sigmoid')) # 隐藏层




model.add(layers.Dense(10, activation='softmax')) # 输出层,10个类别,使用softmax激活函数进行多分类









# 编译模型,设置损失函数、优化器和评估指标




model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])









# 训练模型




model.fit(train_images, train_labels, epochs=5)









# 在测试集上评估模型性能




test_loss, test_acc = model.evaluate(test_images, test_labels)




print('\nTest accuracy:', test_acc)









# 使用模型进行预测并可视化结果




predictions = model.predict(test_images)




predicted_class = np.argmax(predictions, axis=1) # 获取预测类别




true_class = np.argmax(test_labels, axis=1) # 获取真实类别




plt.figure(figsize=(10, 5))




for i in range(len(test_images)):




plt.subplot(1, 2, i+1)




plt.imshow(test_images[i].reshape(28, 28), cmap='gray')




plt.title('Predicted: ' + str(predicted_class[i]) + ', True: ' + str(true_class[i]))




plt.show()



DNN分类算法实现了输入图片特征向量X,输出Y(范围0~1)预测X的分类。


第一步,得到关于X线性回归函数


可以通过线性回归得到WX + b,其中W是权重,b是偏差值。但不能用本式表述预测的值,因为输出Y的值需要在(0~1)区间;


第二歩,通过激活函数转换


激活函数的特点是可以将线性函数转换为非线性函数,并且有输出值有限,可微分,单调性的特点。本例使用sigmoid,使输出为预测值Y=sigmoid(WX+b);


多个神经网络层,也就是重复第一、二步,类似sigmoid(sigmoid(WX+b))..的复合函数。


第三歩,构建Cost函数


训练W,b更好的预测真实的类别需要构建Cost代价函数,y^为sigmoid(WX+b)的预测分类值,y为实际分类值(0或者1):


52812566d17381942420bb238c406983.webp

其中L(y^,y)称为损失函数 e5d35e6dcf9b1049cc13397a5b9976e3.webp训练的目的就是为了让L(y^,y)足够小,也就是当y实际分类值为1时,y^要尽量偏向1。y实际分类值为0时,y^尽量小接近0。


第四步,梯度下降得到Cost函数的极小值


d3948dc5d54530cad6adb4adab91f7dd.webp通过对W,b两个参数求偏导,不断迭代往下坡的的位置移动(对w,b值往极小值方向做优化,其中α为学习率控制下降的幅度),全局最优解也就是代价函数(成本函数)J (w,b)这个凸函数的极小值点。 36726e03a38a789e656b84e33c43115f.webp第五步、通过训练好的W,b预测分类。 508c65dec9f9a113dddd037602be48de.webp





4.4 聚类算法


(1)层次聚类


层次聚类将每条数据都 当作是一个分类,每次迭代的时候合并距离最近的两个分类,直到剩下一个分类为止。


代码实现:


          
from sklearn.cluster import AgglomerativeClustering


from sklearn.datasets import make_blobs


import matplotlib.pyplot as plt








# 生成样本数据



X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)








# 实例化层次聚类模型,n_clusters为聚类数



cluster = AgglomerativeClustering(n_clusters=4)








# 拟合数据



cluster.fit(X)








# 获取聚类标签



labels = cluster.labels_








# 绘制结果



plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')


plt.show()




(2)K-means++聚类




8aab069a49a1d55b22051d3b251504a6.webp


注:Kmean算法与Kmean++区别在于初始的中心点是直接随机选取k各点。


代码实现:



          
from sklearn.cluster import KMeans


from sklearn import datasets


import matplotlib.pyplot as plt








# 加载Iris数据集



iris = datasets.load_iris()


X = iris.data


y = iris.target








# 创建KMeans实例并拟合数据



kmeans = KMeans(n_clusters=3)


kmeans.fit(X)








# 获取聚类标签和聚类中心点



labels = kmeans.labels_


centroids = kmeans.cluster_centers_








# 绘制聚类结果




plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')




plt.scatter(centroids[:, 0], centroids[:, 1], c='red', s=300) # 绘制聚类中心点



plt.show()







k-means++算法可概括为:


(1)基于各点到中心点得距离分量,依次随机选取到k个元素作为中心点:先随机选择一个点。重复以下步骤,直到选完k个点。


计算每个数据点dp(n)到各个中心点的距离(D),选取最小的值D(dp); f43f4333c84ac66ebe85289bdff6a620.webp根据D(dp)距离所占的份量来随机选取下一个点作为中心点。 e77e3622194c4120c0901e27ebdf0348.webp


(2)根据各点到中心点的距离分类;


(3)计算各个分类新的中心点。重复(2、3),直至满足条件。


浏览 36
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报