西瓜数据集(watermelon.txt)各个特征的含义如下: 数据集的每一行由3个数值组成,前2个数字用\t分隔,后2个数字用空格分隔。 对于数据集文件watermelon.txt,请编写MapReduce程序,同时采用密度和含糖率数据作为特征,设类别数为2,利用 K-Means 聚类方法通过多次迭代对数据进行聚类。使用Python将聚类结果表示在二维平面上。完整代码
时间: 2023-11-22 11:52:35 浏览: 110
西瓜数据集,用于判断西瓜好坏
由于题目要求使用MapReduce进行聚类,我这里提供的是Hadoop Streaming的代码实现。
1. 准备数据
将数据集文件watermelon.txt上传到HDFS中,并创建一个输入目录input,将数据集文件放入该目录中。
2. 编写Mapper和Reducer代码
Mapper代码:
```python
#!/usr/bin/env python
import sys
import numpy as np
# 读取聚类中心坐标
centers = np.loadtxt(sys.argv[1], delimiter=',')
# 定义计算欧几里得距离的函数
def euclidean_distance(x, y):
return np.sqrt(np.sum((x - y) ** 2))
# Mapper
for line in sys.stdin:
# 将每行数据转化为numpy数组形式
data = np.array([float(i) for i in line.strip().split()])
# 计算数据点到每个聚类中心的距离
distances = [euclidean_distance(data[:2], center) for center in centers]
# 选取距离最近的聚类中心,并输出
cluster = np.argmin(distances)
print(f"{cluster}\t{data[0]},{data[1]}")
```
Reducer代码:
```python
#!/usr/bin/env python
import sys
import numpy as np
# 读取聚类中心坐标
centers = np.loadtxt(sys.argv[1], delimiter=',')
# 初始化每个聚类的数据点
clusters = [[] for i in range(len(centers))]
# Reducer
for line in sys.stdin:
cluster, point = line.strip().split('\t')
x, y = map(float, point.split(','))
clusters[int(cluster)].append([x, y])
# 计算新的聚类中心
new_centers = []
for i in range(len(clusters)):
if len(clusters[i]) == 0:
new_centers.append(centers[i])
else:
new_centers.append(np.mean(clusters[i], axis=0))
# 输出新的聚类中心
print(','.join([f"{x},{y}" for x, y in new_centers]))
```
3. 执行MapReduce任务
使用以下命令执行MapReduce任务:
```bash
hadoop jar /path/to/hadoop-streaming.jar \
-file /path/to/mapper.py -mapper "python3 mapper.py /path/to/centers.txt" \
-file /path/to/reducer.py -reducer "python3 reducer.py /path/to/centers.txt" \
-input /path/to/input/* -output /path/to/output
```
其中,/path/to/hadoop-streaming.jar是Hadoop Streaming的jar包路径,/path/to/mapper.py和/path/to/reducer.py是上述编写的Mapper和Reducer代码的路径,/path/to/centers.txt是初始聚类中心的坐标文件路径,/path/to/input是输入目录路径,/path/to/output是输出目录路径。
4. 生成聚类结果图像
在MapReduce任务执行完成后,可以将聚类结果定义为一个二维坐标系,将每个数据点按照其所属的聚类标记(0或1)进行着色。使用Python绘制该二维坐标系即可得到聚类结果图像。
```python
import numpy as np
import matplotlib.pyplot as plt
# 读取聚类结果
results = np.loadtxt('/path/to/output/part-00000', delimiter=',')
# 绘制聚类结果图像
fig, ax = plt.subplots()
ax.scatter(results[:,0], results[:,1], c=results[:,2])
ax.set_xlabel('Density')
ax.set_ylabel('Sugar content')
plt.show()
```
其中,/path/to/output/part-00000是MapReduce任务的输出结果文件路径,需要根据实际情况进行修改。
阅读全文