数据挖掘 = 算法 + 领域知识(domain knowledge)
一 数据收集
行:数据对象 & 列:数据属性
1.1 数据
1. 记录型数据
两类数据:
Categorical(描述性数据,无比较含义)
Nominal:名义型数据
Ordinal:序数型 (eg:RGB编码不可以0,1,2;可以使用one-hot编码)
Numerical(数字性数据,有比较含义)
Interval:区间型 calendar dates (只可以加减计算)
Ratio:比例型 length、time
属性:
离散属性 Discrete Attribute
连续属性 Continuous Attribute
2. 文本类数据
文本数据进行向量化,记录词频。或者进行token化处理。
3. 图结构数据
将图数据转换为table结构,行列都是节点,值为0-1表示是否有边
1.2 数据质量
- 错误数据
- 数据噪声:噪声是指对原始值的修改;离群点等。
- 数据缺失:部分缺失可以使用众数填充、平滑填充等方法。
- 重复数据
二 数据预处理
对脏数据进行清洗。
2.1 采样
主要原则:
- 良好的采样是可以代表总体的数据分布
- 良好的采样可以代表
2.2 维度&特征
当数据维度较多的时候,可以对有用的维度进行筛选。
当数据维度较少的时候,可以对特征进行创造。常用方法:映射
2.3 离散化
将数值类的数据转换为分类类别的数据,例如将0-100的数值,可以划分为及格&不及格(<60)
2.4 pandas数据相关操作demo
# 导入所需的库 import pandas as pd import matplotlib.pyplot as plt # 读取iris数据集 data = pd.read_csv('/Users/dongjiawei/Documents/buaa/数据挖掘/iris.csv') # 显示数据集的基本信息 data.info() # 显示sepal_length和species列的前10行 data[['sepal_length', 'species']].head(10) # 筛选出sepal_length大于7且petal_length大于6的数据 data[(data['sepal_length'] > 7) & (data['petal_length'] > 6)] # 选择第100行到第110行,第4列和第3列的数据 data.iloc[100:110, [4, 3]] # 计算petal_length和petal_width的和,并将结果存储在新的列petal_sum中 data['petal_sum'] = data['petal_length'] + data['petal_width'] # 显示数据集的统计信息 data.describe() # 显示species列的统计信息 data['species'].describe() # 计算第1列和第2列的平均值 data.iloc[:, [1, 2]].mean() # 按species分组,计算每组的sepal_length的平均值 data.groupby('species')["sepal_length"].mean() # 绘制sepal_length的直方图,展示其分布情况 data.plot(kind='hist', y='sepal_length', bins=30, title='Sepal Length Distribution') plt.show() # 绘制sepal_length和sepal_width的散点图,展示两者的关系 data.plot(kind='scatter', x='sepal_length', y='sepal_width', title='Sepal Length vs Width') plt.show() # 创建一个字典,将species的每个唯一值映射到一个整数 cdict = dict(zip(data['species'].unique(), range(data['species'].nunique()))) print(cdict) # 绘制sepal_length和sepal_width的散点图,颜色由species决定,展示两者的关系以及species的分布 data.plot(kind='scatter', x='sepal_length', y='sepal_width', c=data['species'].apply(lambda x: cdict[x]), colormap='viridis', colorbar=True, title='Sepal Length vs Width') plt.show()
三 数据挖掘模型
3.1 关联性分析
计算数据的共同出现和相关性。
类似与超市购物记录,会记录同一批购物的商品类型,去计算购买物品A后购买物品B的可能性。
How to do:
频繁模式
项集:(哪些商品总是一起出现),包含了一个或者多个产品的集合。
k-项集:包含了k个产品的项集
支持度
一个项集出现的频率。在总样本中,指定k项集出现的比值。
阈值
minSupp:最小的支持度
关联规则
{A,B}→{C}:在AB出现的前提下,C出现的概率
置信度:Y在包含了X的项集中出现的概率,Supp(XY)/Supp(X)
核心方法
如果是蛮力计算,在数据量太大时不可行。常用Apriori算法。
Apriori算法
超集的支持度小于等于子集的支持度
所以如果子集的支持度已经小于了最小阈值,那么超集的支持度一定小于最小阈值。可以将其剪枝。
3.2 回归分析-线性回归
1. 线性回归
通过残差平方和最小化实现最小拟合。去通过
回归本质是去做数据拟合
2. 线性回归的正则化
为了防止模型的过拟合,在建立线性模型的时候,需要对要模拟参数加入正则化,防止出现异常的w值。
3. 实操
使用sklearn包进行模型调用试验
regmodel = LinearRegression()
一元线性回归
# %% # 一元线性回归 # 导入pandas库 import pandas as pd # 使用pandas的read_csv函数读取insurance.txt文件,文件中的数据以制表符('\t')分隔 data = pd.read_csv('/Users/dongjiawei/Documents/buaa/数据挖掘/insurance.txt', sep='\t') # 显示数据的基本信息 data.info() # 从数据中提取'X'列作为特征,'Y'列作为目标,使用reshape(-1, 1)将其转换为二维数组 X = data['X'].values.reshape(-1, 1) Y = data['Y'].values.reshape(-1, 1) # 导入sklearn库的线性回归模型 from sklearn.linear_model import LinearRegression # 创建线性回归模型实例 regmodel = LinearRegression() # 使用X和Y训练线性回归模型 regmodel.fit(X, Y) print(regmodel.coef_) // w值 print(regmodel.intercept_) // b值 print(regmodel.score(X, Y)) // 异常值^2 # 使用训练好的模型对X进行预测 predict_y = regmodel.predict(X) # 打印预测结果 print(predict_y) # 导入matplotlib库的pyplot模块 import matplotlib.pyplot as plt # 绘制原始数据的散点图,颜色为蓝色 plt.scatter(X, Y, color='blue') # 绘制预测结果的线图,颜色为红色 plt.plot(X, predict_y, color='red') # 显示图像 plt.show()
多元分析
# %% # 多元线性回归 from sklearn.datasets import load_diabetes data = load_diabetes() X = data.data Y = data.target from sklearn.linear_model import LinearRegression regmodel = LinearRegression() regmodel.fit(X,Y) print(regmodel.coef_) print(regmodel.intercept_) predict_y = regmodel.predict(X) # 导入matplotlib库的pyplot模块 import matplotlib.pyplot as plt # 绘制预测结果的线图,颜色为红色 plt.scatter(Y, predict_y) plt.xlabel('True Value') plt.ylabel('Predict Value') # 显示图像 plt.show()
3.3 回归分析-逻辑回归
本质:将回归模型预测出的Y(数值型),转换为分类型数据。
逻辑回归函数:
就是将预测出的Y值,带入该函数的x值,即可求得分类数据。
LogisticRegression(solver=”lbfgs”,class_weight=’balanced’)
3.4 分类分析
类别标签。构建一个以属性为自变量,类别标签为因变量的函数。例如银行的风险评级模型。
给定训练集:
每条记录(x,y)组成,其中x代表属性集合,y代表类别标签。
x: attribute
y: class
Task: 训练一个模型,将x可以映射到标签集合Y中。
1. 决策树 (Decision Tree)
尽量用一棵树去拟合训练数据。
对一个数据集可能有多种不同的构建树的方式,一般不能百分百拟合。
Q:分裂的过程何时停止
不一定要求所有的数据都符合要求,可以按比例进行提前停止。
Q:分类的测试条件
针对类别型数据,尽量进行二分类别。针对类别较多的label,可以进行合并。
eg:衣服尺码,可以将xs s分为一类,l xl分为一类
针对连续性数据,可以进行二值划分(>60),或者按区间进行多划分。即对连续的属性进行离散化处理。
Q:如何选择分裂的最佳属性
分裂后target label尽量集中 & 分裂的分支尽量少
贪婪法:
选择能够产生更纯的分裂结果的属性。
纯度指标:
基尼系数 :
eg:
C1:0 C2:6
P(c1) = 0/6 = 0; P(c2) = 6/6 = 1
Gini = 1- P(c1)^2 - P(c2)^2 = 1-0-1 = 0
基尼系数越小,说明指标纯度越高
Q:寻找最佳的分裂属性
- 计算分裂前的不纯度指标P
- 计算分裂后的不纯度指标M1 和 M2(如果是分成两个类别)
- 选择该分裂的最高收益为: P-M(M1,M2加权平均,以数据量为权重)
Q:模型过拟合是什么
在训练中,过渡拟合训练集的结果,使得泛化能力降低,对训练集外的数据预测能力下降。
eg:在训练预测用户信息时,分类节点为用户ID,这种情况训练的准确率100%,但是在训练集外表现很差。
过拟合(overfitting):当模型太复杂(为了拟合数据而造了更复杂的模型),训练集错误很低,但是验证集错误率很高。
欠拟合(underfitting):当模型太简单,训练集和验证集的错误率都很高。
2. 分类的评价方法
Q:如何划分数据为训练集和验证集
- Holdout: 按比例划分训练集和验证集
- Random subsampling:随机分配
- Cross validation:交叉验证,一部分数据即为训练集,也是验证集
- 将数据分为k个部分,将k-1个数据做为训练集,k个数据做为验证集
- 循环k次,每次的验证集均不同
Q:如何评价分类模型(二分类)
混淆矩阵 confusion matrix
准确度指标:
准确度是模型正确预测的样本数与总样本数的比例。
但是这个指标针对数据有偏的情况存在问题,如正常指标C1: 9990个,错误指标C2: 10个,将所有指标都预测为C1, 准确率为99.9%,但是无实际含义。
精确度:
精确度是模型预测为正类并实际为正类的样本数与模型预测为正类的样本数的比例。
召回率:
召回率是模型预测为正类并实际为正类的样本数与实际为正类的样本数的比例。
准确率和召回率有一定的制约关系,很难同时提高。
F1分数:
F1分数是精确度和召回率的调和平均数,用于在一个单一的指标中平衡这两者。
3. 实操
# 该文件用于实现分类器的训练和预测,用于预测鸢尾花的种类 # %% import pandas as pd from matplotlib import pyplot as plt from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier iris = pd.read_csv('/Users/dongjiawei/Documents/buaa/数据挖掘/iris.csv') # 将数据集分为特征和目标 X = iris.iloc[:, 0:4] Y = iris['species'] # 将数据集分为训练集和测试集 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2) # 创建决策树分类器 clf = DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=4) clf.fit(X_train, Y_train) # 使用分类器对测试集进行预测 pred_labels = clf.predict(X_test) # 输出分类器的预测结果评分,包括准确率、召回率、F1值等 from sklearn.metrics import classification_report print(classification_report(Y_test, pred_labels)) # 输出混淆矩阵 from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay cm = confusion_matrix(Y_test, pred_labels) disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=clf.classes_) disp.plot() plt.show() # 画出决策树 from sklearn import tree plt.rcParams['figure.dpi'] = 400 tree.plot_tree(clf, filled=True) plt.show()
准确率、召回率、F1值
混淆矩阵:
决策树:
3.5 支持向量机SVM
SVM本质:找一个分界面将两类数据分开,并且使该分界面上下浮动的空间最大。
1. 训练数据线性不可分,如何处理
- 加入松弛变量,使分类具有一定容错性。
- 添加维度,使其在高维空间中使用分界面可分。
2. 核函数(kernel)
核函数可以将线性平面映射为非线性平面。
将数据稍微,通过分界面划分后,将分界面降维后即为非线性。
在使用SVM模型时,kernel的正确选用是影响模型表现的重要元素。
3. 实操
# %% from sklearn import svm from sklearn import datasets from sklearn.metrics import classification_report from sklearn.model_selection import train_test_split # 加载红酒数据集 wine = datasets.load_wine(as_frame=True) x_train, x_test, y_train, y_test = train_test_split(wine.data, wine.target, test_size=0.2) # 创建支持向量机分类器 clf = svm.SVC(kernel='poly', C=100) clf.fit(x_train, y_train) # 使用分类器对测试集进行预测 pred_labels = clf.predict(x_test) # 输出分类器的预测结果评分,包括准确率、召回率、F1值等 print(classification_report(y_test, pred_labels))
3.5 聚类分析
对数据对象进行分组,组内的数据之间相似或者相关,组间数据足够不同或者不相关。这里的组就是类。
示例:文档分组、基因序列模式发现
属于无监督学习。
3.6 异常检测
异常点与数据噪声不同,是有意义的。
- 基于模型的方法,数据不平衡问题
- 无监督的的方法:没有类别标签
- 有监督的方法
- 基于距离的方法
- 基于密度的方法
3.7 文本挖掘
现在数据80%以上都是非结构性的数据。
