当前位置:   article > 正文

数据挖掘与机器学习 实验:分类算法_数据挖掘分类实验原理

数据挖掘分类实验原理

数据挖掘与机器学习

实验:分类算法

一、实验名称

实验:分类算法

二、实验目的

1.了解分类算法理论基础

2.平台实现算法

3.编程实现分类算法

三、实验原理

分类(Categorization or Classification)就是按照某种标准给对象贴标签(label),再根据标签来区分归类。

四、实验步骤

1、adult.data.txt数据集,该数据集由多组个人信息构成,其中信息包含年龄、工作、婚姻等属性,以及类别收入,根据这些已有数据建立模型,推测出未知收入群体的收入情况。

2、加载数据并查看数据,需注意数据的分隔符为', '即',空格',并且没有表头。

  1. # 引包
  2. import numpy as np
  3. import pandas as pd
  4. # 读取数据
  5. # 分隔符为', '即',空格' , header=None表示在读取数据时不将第一行作为列名
  6. data = pd.read_csv('D:/数据挖掘/实验/adult.data.txt', sep=', ', header=None)
  7. data
  8. # 查看数据的基本信息
  9. data.info()

3、由于数据中含有异常值,需将异常值替换成缺失值pd.NaT,再将数据中包含缺失值的行删除掉。

  1. # 将异常值替换成缺失值pd.NaT
  2. # .replace()函数将数据中的'?'替换成pd.NaT
  3. # inplace=True表示在原始数据上进行替换操作,而不是创建一个新的
  4. data.replace('?', pd.NaT, inplace=True)
  5. # 删除数据中包含缺失值的行
  6. # .dropna()删除数据中包含缺失值的行,inplace=True表示在原始数据上进行操作
  7. data.dropna(inplace=True)
  8. data

4、筛选收入<=50K和>50K的数据,发现收入<=50K的数据有22654条,而收入>50K的数据只有7508条,由于不同的类别的数据体量相差很大会造成分类器向大数据体量一方倾斜,因此我们需依据不同的类别收入加载相同数量的数据。

  1. # 筛选出收入<=50K的数据
  2. data[data[14]=='<=50K']
  3. # 筛选出收入>50K的数据
  4. data[data[14]=='>50K']

5、随机选取收入<=50K和收入>50K的数据各3000条,并将选取出的收入<=50K和收入>50K的数据进行合并。

  1. # 选取收入50K上下的同等数据量进行数据分析
  2. # 筛选出收入<=50K的数据,结果返回一个由布尔值组成的Series对象,其中每个元素的值为True或False
  3. t1 = (data[14] == '<=50K')
  4. # data1
  5. # 随机选择3000条收入<=50K的数据
  6. data1 = data[t1].sample(3000)
  7. data1
  8. # 筛选出收入>50K的数据
  9. t2 = (data[14] == '>50K')
  10. # 随机选择3000条收入>50K的数据
  11. data2= data[t2].sample(3000)
  12. data2
  13. # 将选取的收入<=50K和收入>50K的数据进行合并
  14. # 使用pd.concat()函数将数据进行纵向合并
  15. data3 = pd.concat([data1,data2])
  16. data3

6、转换数据的属性编码,由于原数据中的属性是包含英文字符的,无法进行数学运算,需将其转换为数值型数据。由于对新的数据集进行编码转换时,需要使用相同的编码方式,即使用相同的 LabelEncoder() 对象,所以需要将所有的 LabelEncoder() 对象保存下来,以便在对新数据集进行编码时使用。

  1. # 转换数据的属性编码
  2. # 原数据中含有英文字符,使用preprocessing.LabelEncoder()函数将英文转换成数值型
  3. from sklearn.preprocessing import LabelEncoder
  4. # 对新的数据集进行编码转换时,需要使用相同的编码方式,即使用相同的 LabelEncoder() 对象。
  5. # 因此需要将所有的 LabelEncoder() 对象保存下来,以便在对新数据集进行编码时使用。
  6. # 创建一个空列表 le1 用于存储所有的 LabelEncoder() 对象
  7. le1 = []
  8. # 创建一个副本保留原始数据
  9. data4 = data3.copy()
  10. # 使用循环对每一列的数据进行属性编码
  11. for column in data3.columns:
  12. # 判断每列的数据类型是否为object(即非数值型数据)
  13. if data3[column].dtype == 'object':
  14. # 创建一个LabelEncoder对象
  15. le = LabelEncoder()
  16. # 如果是非数值型数据,就使用LabelEncoder对象le对该列进行编码
  17. data4[column] = le.fit_transform(data3[column])
  18. # 保存LabelEncoder对象,将le对象添加到le1列表中
  19. le1.append(le)
  20. # print(le1)
  21. data4

7、获取数据的属性和标签,先对数据集进行划分,模型选择朴素贝叶斯算法,再依次进行模型的训练、预测、测评,测评使用交叉验证,交叉验证是将数据分成n等份,每次取其中1份作为测试集,其余作为训练集进行评测,重复n次,取n次的平均值作为结果。将结果转换成百分比的形式,并保留两位小数。

  1. # 获取数据属性
  2. X = data4.iloc[:, :-1].values
  3. # 获取数据标签
  4. y = data4.iloc[:, -1].values
  5. X
  6. y
  7. from sklearn.model_selection import train_test_split
  8. # 划分数据集
  9. # test_size:测试集大小,random_state:随机种子
  10. X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.25,random_state=5)
  11. # 模型的选择,朴素贝叶斯算法
  12. from sklearn.naive_bayes import GaussianNB
  13. classifier_gaussiannb = GaussianNB()
  14. # 模型的训练
  15. classifier_gaussiannb.fit(X_train, y_train)
  16. # 模型的预测
  17. y_test_pred = classifier_gaussiannb.predict(X_test)
  18. # 模型的测评
  19. # 交叉验证:将数据分成n等份,每次取其中1份作为测试集,其余作为训练集进行评测,重复n次,取n次的平均值作为结果
  20. from sklearn.model_selection import cross_val_score
  21. # cv每种情况训练的次数,scoring='f1_weighted' 表示使用加权的F1得分作为评价指标
  22. scores = cross_val_score(classifier_gaussiannb,X,y,scoring='f1_weighted',cv=5)
  23. # 得分取平均值,转换成百分比形式,保留两位小数
  24. print("scores:" + str(round(100*scores.mean(),2)) + "%")

8、选取一个新的个体样本,采用相同的编码规则进行处理,并进行预测其收入类别,注意得到的结果是数值型的标签,需将数值型标签转换成非数值型的标签。

  1. # 选取个例进行预测
  2. # 创建一个新样本,使用训练好的模型对其进行预测,预测该样本的收入类别
  3. input_data = ['39', 'State-gov', '77516', 'Bachelors', '13', 'Never-married', 'Adm-clerical', 'Not-in-family', 'White',
  4. 'Male', '2174', '0', '40', 'United-States']
  5. # 创建一个与 input_data 长度相同的列表,并将初始值设置为 -1,将编码后的结果存储到对应的位置上
  6. # 创建一个列表,用于存放新样本数据编码后的结果
  7. input_data_encoder = [-1] * len(input_data)
  8. # 对新样本的数据进行编码
  9. # count表示新样本数据中非数字的列的顺序
  10. # 在上面有一个训练好的编码器列表,通过count使用非数值的列对应的编码器对新样本数据进行编码
  11. count = 0
  12. # 使用 enumerate() 函数遍历输入数据,index 表示当前元素的索引,item 表示当前元素的值
  13. for index, item in enumerate(input_data):
  14. # 判断当前元素是否为数值型数据,如果是,则将其转换为整数并存储到 input_data_encoder 的相应位置上
  15. if item.isdigit():
  16. input_data_encoder[index] = int(item)
  17. # 如果当前元素不是数值型数据,则需要进行编码转换
  18. else:
  19. # tranform()对数据进行编码,参数是一个 numpy 的 ndarray,所以需要使用 np.array() 构建一个ndarray
  20. temp = le1[count].transform(np.array([item]))
  21. # 将编码后的结果转换为整数,并存储到 input_data_encoder 的相应位置上
  22. input_data_encoder[index] = int(temp)
  23. count += 1
  24. # 查看一下编码后的样本数据
  25. print(input_data_encoder)
  26. # 使用 np.array()函数将数据转换为 numpy 数组对象
  27. out = np.array(input_data_encoder)
  28. out
  29. # 进行预测
  30. # .reshape(1,-1):对数据进行转换,将其转换为一个只有一行的二维数组
  31. result=classifier_gaussiannb.predict(out.reshape(1,-1))
  32. result
  33. # 将编码后的数值型标签转换成非数值型的标签
  34. print(le.inverse_transform(result)[0])

五、完整代码

  1. # 引包
  2. import numpy as np
  3. import pandas as pd
  4. # 读取数据
  5. # 分隔符为', '即',空格' , header=None表示在读取数据时不将第一行作为列名
  6. data = pd.read_csv('D:/数据挖掘/实验/adult.data.txt', sep=', ', header=None)
  7. data
  8. # 查看数据的基本信息
  9. data.info()
  10. # 将异常值替换成缺失值pd.NaT
  11. # .replace()函数将数据中的'?'替换成pd.NaT
  12. # inplace=True表示在原始数据上进行替换操作,而不是创建一个新的
  13. data.replace('?', pd.NaT, inplace=True)
  14. # 删除数据中包含缺失值的行
  15. # .dropna()删除数据中包含缺失值的行,inplace=True表示在原始数据上进行操作
  16. data.dropna(inplace=True)
  17. data
  18. # 筛选出收入<=50K的数据
  19. data[data[14]=='<=50K']
  20. # 筛选出收入>50K的数据
  21. data[data[14]=='>50K']
  22. # 选取收入50K上下的同等数据量进行数据分析
  23. # 筛选出收入<=50K的数据,结果返回一个由布尔值组成的Series对象,其中每个元素的值为True或False
  24. t1 = (data[14] == '<=50K')
  25. # data1
  26. # 随机选择3000条收入<=50K的数据
  27. data1 = data[t1].sample(3000)
  28. data1
  29. # 筛选出收入>50K的数据
  30. t2 = (data[14] == '>50K')
  31. # 随机选择3000条收入>50K的数据
  32. data2= data[t2].sample(3000)
  33. data2
  34. # 将选取的收入<=50K和收入>50K的数据进行合并
  35. # 使用pd.concat()函数将数据进行纵向合并
  36. data3 = pd.concat([data1,data2])
  37. data3
  38. # 转换数据的属性编码
  39. # 原数据中含有英文字符,使用preprocessing.LabelEncoder()函数将英文转换成数值型
  40. from sklearn.preprocessing import LabelEncoder
  41. # 对新的数据集进行编码转换时,需要使用相同的编码方式,即使用相同的 LabelEncoder() 对象。
  42. # 因此需要将所有的 LabelEncoder() 对象保存下来,以便在对新数据集进行编码时使用。
  43. # 创建一个空列表 le1 用于存储所有的 LabelEncoder() 对象
  44. le1 = []
  45. # 创建一个副本保留原始数据
  46. data4 = data3.copy()
  47. # 使用循环对每一列的数据进行属性编码
  48. for column in data3.columns:
  49. # 判断每列的数据类型是否为object(即非数值型数据)
  50. if data3[column].dtype == 'object':
  51. # 创建一个LabelEncoder对象
  52. le = LabelEncoder()
  53. # 如果是非数值型数据,就使用LabelEncoder对象le对该列进行编码
  54. data4[column] = le.fit_transform(data3[column])
  55. # 保存LabelEncoder对象,将le对象添加到le1列表中
  56. le1.append(le)
  57. # print(le1)
  58. data4
  59. # 获取数据属性
  60. X = data4.iloc[:, :-1].values
  61. # 获取数据标签
  62. y = data4.iloc[:, -1].values
  63. X
  64. y
  65. from sklearn.model_selection import train_test_split
  66. # 划分数据集
  67. # test_size:测试集大小,random_state:随机种子
  68. X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.25,random_state=5)
  69. # 模型的选择,朴素贝叶斯算法
  70. from sklearn.naive_bayes import GaussianNB
  71. classifier_gaussiannb = GaussianNB()
  72. # 模型的训练
  73. classifier_gaussiannb.fit(X_train, y_train)
  74. # 模型的预测
  75. y_test_pred = classifier_gaussiannb.predict(X_test)
  76. # 模型的测评
  77. # 交叉验证:将数据分成n等份,每次取其中1份作为测试集,其余作为训练集进行评测,重复n次,取n次的平均值作为结果
  78. from sklearn.model_selection import cross_val_score
  79. # cv每种情况训练的次数,scoring='f1_weighted' 表示使用加权的F1得分作为评价指标
  80. scores = cross_val_score(classifier_gaussiannb,X,y,scoring='f1_weighted',cv=5)
  81. # 得分取平均值,转换成百分比形式,保留两位小数
  82. print("scores:" + str(round(100*scores.mean(),2)) + "%")
  83. # 选取个例进行预测
  84. # 创建一个新样本,使用训练好的模型对其进行预测,预测该样本的收入类别
  85. input_data = ['39', 'State-gov', '77516', 'Bachelors', '13', 'Never-married', 'Adm-clerical', 'Not-in-family', 'White',
  86. 'Male', '2174', '0', '40', 'United-States']
  87. # 创建一个与 input_data 长度相同的列表,并将初始值设置为 -1,将编码后的结果存储到对应的位置上
  88. # 创建一个列表,用于存放新样本数据编码后的结果
  89. input_data_encoder = [-1] * len(input_data)
  90. # 对新样本的数据进行编码
  91. # count表示新样本数据中非数字的列的顺序
  92. # 在上面有一个训练好的编码器列表,通过count使用非数值的列对应的编码器对新样本数据进行编码
  93. count = 0
  94. # 使用 enumerate() 函数遍历输入数据,index 表示当前元素的索引,item 表示当前元素的值
  95. for index, item in enumerate(input_data):
  96. # 判断当前元素是否为数值型数据,如果是,则将其转换为整数并存储到 input_data_encoder 的相应位置上
  97. if item.isdigit():
  98. input_data_encoder[index] = int(item)
  99. # 如果当前元素不是数值型数据,则需要进行编码转换
  100. else:
  101. # tranform()对数据进行编码,参数是一个 numpy 的 ndarray,所以需要使用 np.array() 构建一个ndarray
  102. temp = le1[count].transform(np.array([item]))
  103. # 将编码后的结果转换为整数,并存储到 input_data_encoder 的相应位置上
  104. input_data_encoder[index] = int(temp)
  105. count += 1
  106. # 查看一下编码后的样本数据
  107. print(input_data_encoder)
  108. # 使用 np.array()函数将数据转换为 numpy 数组对象
  109. out = np.array(input_data_encoder)
  110. out
  111. # 进行预测
  112. # .reshape(1,-1):对数据进行转换,将其转换为一个只有一行的二维数组
  113. result=classifier_gaussiannb.predict(out.reshape(1,-1))
  114. result
  115. # 将编码后的数值型标签转换成非数值型的标签
  116. print(le.inverse_transform(result)[0])

六、实验总结

本实验对分类算法的原理做了基本的了解,并通过Python代码的形式进行真实的算法实现,构建了一个分类器实现对未知收入群体的收入情况的预测。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/140892
推荐阅读
  

闽ICP备14008679号