数据挖掘|数据集成|基于Python的数据集成关键问题处理
-
- [1. 实体识别](#1. 实体识别)
- [2. 数据冗余与相关性分析](#2. 数据冗余与相关性分析)
- [3. 去除重复记录](#3. 去除重复记录)
- [4. 数据值冲突的检测与处理](#4. 数据值冲突的检测与处理)
- [5. 基于Python的数据集成](#5. 基于Python的数据集成)
-
- [5.1 merge()方法](#5.1 merge()方法)
- [5.2 Concat()方法](#5.2 Concat()方法)
数据集成是把来自多个数据库或文件等不同数据源的数据整合成一致的数据存储。其中关键问题有:实体识别、数据冗余与相关性分析、记录重复、数据值冲突的检测与处理。
1. 实体识别
实体识别主要涉及同名异义、异名同义、单位统一以及ID-Mapping等方面。
2. 数据冗余与相关性分析
为了提高数据挖掘的精度和减少数据挖掘使用的时间,对多个数据源进行集成时,减少数据集中的冗余和不一致是十分必要的。
如果一个属性可以由另外一个或一组属性值推导出来,则这个属性可能是冗余的。
冗余是数据集成的一个重要问题,有些冗余可以通过相关性分析检测出来。
对于标称数据,两个属性A和B之间的相关关系可以通过 χ 2 \chi^2 χ2(卡方)检验发现,这里不做详细介绍。
对于数值数据,可以通过计算属性A和B的相关系数(又称 Pearson积矩系数)来分析其相关性。
用Python求相关系数的方法有三种:
- 用numpy模块中的corrcoef()函数计算相关系数矩阵。
- 用pandas模块中DataFrame对象自带相关性计算方法corr(),可以求出所有列之间的相关系数。
- 自己编写Python程序计算相关系数。
对于数值属性,可以使用协方差来评估一个属性值如何随另一个属性值变化。在概率论和统计学中,协方差(Covariance)是用于衡量两个变量的总体误差。而方差是协方差的一种特殊情况,即为两个变量相同时的协方差。它们都是评估两个属性如何一起变化。
使用Python求协方差示例:
python
import numpy as np
from sklearn import datasets
iris = datasets.load_iris() #装载鸢尾花数据
A= iris.data[:,0]
B= iris.data[:,1]
result=np.cov(A,B)
print(result)
[[ 0.68569351 -0.042434 ]
[-0.042434 0.18997942]]
3. 去除重复记录
除了检查属性的冗余之外,还要检测重复的记录,所谓重复记录是指给定唯一的数据实体,存在两个或多个相同的记录。
Python的模块Numpy中unique()函数可以去除一维数组或者列表中的重复元素;对于多维数组,如果指定 axis=0 , 可以把冗余的行去掉,若指定 axis=1 ,可以把冗余的列去掉。
例:去掉多维数组的重复行。
python
import numpy as np
data=np.array([['S1','张三','女',21],['S4','李四','女',22],['S1','张三','女',21],['S5','王五','男',20]])
print("去除重复前:\n",data)
result=np.unique(data,axis=0)
print("去除重复后:\n",result)
去除重复前:
[['S1' '张三' '女' '21']
['S4' '李四' '女' '22']
['S1' '张三' '女' '21']
['S5' '王五' '男' '20']]
去除重复后:
[['S1' '张三' '女' '21']
['S4' '李四' '女' '22']
['S5' '王五' '男' '20']]
4. 数据值冲突的检测与处理
数据集成还涉及数据值冲突的检测与处理,如:
- 对于现实世界的同一实体,来自不同的数据源的属性值可能不同。
- 相同属性的单位可能不同,如公斤和磅;学生成绩有百分制也有五级制等。
- 模式不同,如某大学的学生成绩数据库表中的每一行是成绩类型和相应的成绩,而另一所大学学生成绩数据库表中的每一行是基本课程成绩和平时成绩,还有大学的学生成绩数据库用两个表来存储学生的成绩,第一个表专门存储学生的基本课程成绩,第二个表专门存储学生的平时成绩。
数据值冲突的处理方法是按照一定规则建立起底层关系数据库模式的语义模型,然后利用建立好的语义冲突本体来扩展关系数据库模式的语义,最后再给出基于本体和数据库语义模型解决冲突的具体方法。
5. 基于Python的数据集成
针对可能来自于不同的数据源,可以使用Python对数据子集进行集成处理。Pandas模块中的merge()、concat()方法可以完成数据的集成。
5.1 merge()方法
merge()方法主要是基于两个DataFrame对象的共同列进行连接。
merge()函数常用形式为:
merge(left,right,how='inner',on=None,left_on=None,right_on= None, sort=True)
例:merge()函数数据集成示例。
python
import pandas as pd
S_info=pd.DataFrame({'学号':['S1','S2','S3','S4','S5'],
'姓名':['许文','刘德','刘世','于金','周新']})
course=pd.DataFrame({'学号':['S1','S2','S1','S4','S1'],
'课程':['C2','C1','C3','C2','C4']})
df=pd.merge(S_info,course)
print(df)
学号 姓名 课程
0 S1 许文 C2
1 S1 许文 C3
2 S1 许文 C4
3 S2 刘德 C1
4 S4 于金 C2
python
#当遇到两个数据集的关键字不同时,可以分别指定联结关键字:
import pandas as pd
S_info=pd.DataFrame({'学号':['S1','S2','S3','S4','S5'],
'姓名':['许文','刘德','刘世','于金','周新']})
course=pd.DataFrame({'编号':['S1','S2','S1','S4','S1'],
'课程':['C2','C1','C3','C2','C4']})
df=pd.merge(S_info,course,left_on='学号',right_on='编号')
print("左、右数据子集关键字不同的merge()函数数据集成:\n",df)
左、右数据子集关键字不同的merge()函数数据集成:
学号 姓名 编号 课程
0 S1 许文 S1 C2
1 S1 许文 S1 C3
2 S1 许文 S1 C4
3 S2 刘德 S2 C1
4 S4 于金 S4 C2
python
#当how='outer'时,函数merge()的数据集成示例。
import pandas as pd
grade1=pd.DataFrame({'学号':['S1','S2','S3','S4','S5'],
'姓名':['许文','刘德','刘世','于金','周新'],
'高数':[67,92,67,58,78],
'英语':[82,88,96,90,87]})
grade2=pd.DataFrame({'学号':['S1','S2','S4','S5','S6'],
'数据库技术':[89,34,74,90,83]})
df=pd.merge(grade1,grade2,how='outer')
print(df)
学号 姓名 高数 英语 数据库技术
0 S1 许文 67.0 82.0 89.0
1 S2 刘德 92.0 88.0 34.0
2 S3 刘世 67.0 96.0 NaN
3 S4 于金 58.0 90.0 74.0
4 S5 周新 78.0 87.0 90.0
5 S6 NaN NaN NaN 83.0
python
# merge()函数通过多个键的数据集成示例。
import pandas as pd
info_s=pd.DataFrame({'学号':['S1','S2','S3','S4','S5'],
'姓名':['许文','刘德','刘世','于金','周新'],
'性别':['女','男','男','女','女']})
course=pd.DataFrame({'学号':['S1','S2','S1','S3','S5','S2', 'S1'],
'姓名':['许文','刘德','许文','刘世','周新','刘德','许文'],
'课程':['C1','C1','C3','C2','C2','C3','C4'],
'成绩':[78,82,67,92,89,77,68]})
df=pd.merge(info_s,course,on=['学号','姓名'])
print(df)
学号 姓名 性别 课程 成绩
0 S1 许文 女 C1 78
1 S1 许文 女 C3 67
2 S1 许文 女 C4 68
3 S2 刘德 男 C1 82
4 S2 刘德 男 C3 77
5 S3 刘世 男 C2 92
6 S5 周新 女 C2 89
5.2 Concat()方法
Concat()方法是对Series对象或DataFrame对象的数据集进行连接,可以指定按某个轴进行(行或列)连接,也可以指定连接方式:outer和inner。与SQL不同的是concat()不会去重,要达到去重的效果可以使用drop_duplicates()方法。常用形式为:
concat(objs,axis=0,join='outer')
参数说明:
(1) objs:Series对象、DataFrame对象或list对象。
(2) axis:需要连接的轴,axis=0是行连接,axis=1是列连接。
(3) join:连接的方式,inner或outer。
python
#Concat()方法连接示例
import pandas as pd
data1=[['S1','许文','女'],['S2','刘德','男'],
['S3','刘世','男'],['S4','于金','女'],
['S5','周新','女']]
df1=pd.DataFrame(data1,columns=['学号','姓名','性别'])
data2=[[78,89,80,61],[77,83,78,66],[90,54,68,78],[76,66,80,82]]
df2=pd.DataFrame(data2,columns=['高数','英语','数据库技术','数据挖掘'])
df=pd.concat([df1,df2],axis=1,join='outer')
print(df)
学号 姓名 性别 高数 英语 数据库技术 数据挖掘
0 S1 许文 女 78.0 89.0 80.0 61.0
1 S2 刘德 男 77.0 83.0 78.0 66.0
2 S3 刘世 男 90.0 54.0 68.0 78.0
3 S4 于金 女 76.0 66.0 80.0 82.0
4 S5 周新 女 NaN NaN NaN NaN