背景
海伦女士一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但她并不是喜欢每一个人。经过一番总结,她发现自己交往过的人可以进行如下分类:
- 不喜欢的人
- 魅力一般的人
- 极具魅力的人
海伦收集的样本数据主要包含以下3种特征:
- 每年获得的飞行常客里程数
- 玩视频游戏所消耗时间百分比
- 每周消费的冰淇淋公升数
现在就通过这3中特征来对样本进行分类
代码
读取数据
下载数据后,将数据集读取到numpy中,并分成特征值和结果
def file2matrix(filename):
fr = open(filename)
numberOfLines = len(fr.readlines())
returnMat = zeros((numberOfLines, 3))
classLabelVector = []
fr = open(filename)
index = 0
for line in fr.readlines():
line = line.strip()
listFromLine = line.split('\t')
returnMat[index, :] = listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat, classLabelVector
分析数据(使用Matplotlib创建散点图)
def canvas(datingDataMat, dataingLabels):
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(datingDataMat[:, 0], datingDataMat[:, 1], 15.0 * array(dataingLabels), 15.0 * array(dataingLabels))
plt.show()
准备数据(数值归一化)
在这个实例中,如果使用欧氏距离公式计算距离,飞行里程的特征值比较大,因此为了让3种特征对结果做出的贡献相同,就需要进行归一化处理。关于归一化的详细解释可以看这里
# 归一化数值
def autoNorm(dataSet):
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
ranges = maxVals - minVals
m = dataSet.shape[0]
normDataSet = dataSet - tile(minVals, (m, 1))
normDataSet = normDataSet / tile(ranges, (m, 1))
return normDataSet, ranges, minVals
测试算法
在数据集中随机取10%的数据作为测试集,并预测结果,计算错误率。如果错误率超出预期,那就要再缕一缕了~·
# 验证分类器,使用10%的数据作为测试集
def datingClassTest():
# 测试集的比例10%
hoRatio = 0.1
datingDataMat, datingLabels = file2matrix("datingTestSet2.txt")
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m * hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
inX = normMat[i, :]
dataSet = normMat[numTestVecs:m, :]
labels = datingLabels[numTestVecs:m]
k = 3
classifierResult = classify0(inX, dataSet, labels, k)
print("分类器预测结果:%d,正确结果是:%d" % (classifierResult, datingLabels[i]))
if (classifierResult != datingLabels[i]): errorCount += 1.0
print("错误率%f" % (errorCount / float(numTestVecs)))
使用算法进行预测
原理和上面一样
# 任意给出一个人的三种特征信息
def classifyPerson(flight, playing, iceCream):
resultList = ['不喜欢的人', '魅力一般的人', '极具魅力的人']
datingDataMat, datingLabels = file2matrix("datingTestSet2.txt")
normMat, ranges, minVals = autoNorm(datingDataMat)
isArr = array([flight, playing, iceCream])
# 将预测值归一化
isArr = (isArr - minVals) / ranges
classifierResult = classify0(isArr, normMat, datingLabels, 3)
print("结果:", resultList[classifierResult - 1])
classifyPerson(33338, 10, 0.5)
——————————————————————————————————————————————————————————————————————————————
输出: 结果: 极具魅力的人