基本上把一些点都注释了,使用的原始数据是在网上找的
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import operator
from os import listdir
# 设置在图像中可以使用中文
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r'simsun.ttc', size=15)
def file_matrix(filename):
"""处理文件内容,输出处理成矩阵和类标签向量"""
fr = open(filename)
fr1 = np.genfromtxt(filename, delimiter='\t', dtype=str, skip_header=0)
# 每一行对象
# print(fr1)
array_lines = fr.readlines()
# 总行数
number_oflines = len(array_lines)
# print(arrayOlines)
# print(number_oflines)
# 返回一个给定形状和类型的用0填充的数组
# 参数:shape:形状,dtype:可选参数,默认numpy.float64
# order:可选,c代表行优先,f代表列优先
return_mat = np.zeros((number_oflines, 3))
class_label_vector = []
index = 0
for line in array_lines:
# 移除每行开头结尾的空格
line = line.strip()
# 切割字符串
list_fromline = line.split('\t')
# print(list_fromline)
# 替换掉为0的数据
return_mat[index, :] = list_fromline[0:3]
# print(return_mat[index,:])
# 将航班号存储到列表中
class_label_vector.append(int(list_fromline[-1]))
index += 1
return return_mat, class_label_vector
def matplotlib_(data):
# 利用原始数据制作散点图
# 创建一个名为figure的画图窗口
fig = plt.figure()
# 添加子图,111是默认参数,用来设定大小
ax = fig.add_subplot(111)
# 在子图中画scatter散点图
ax.scatter(data[:, 0], data[:, 1])
# 设置可以显示中文字体
ax.set_ylabel(u'看电影的次数', fontproperties=font_set)
ax.set_xlabel(u'玩视频游戏所耗的时间百分比', fontproperties=font_set)
plt.show()
def auto_norm(dataset):
"""在原始数据的继承上归一化数据"""
# 取出矩阵中最小的数,参数0使得取得的从列中取出最小值
min_vals = dataset.min(0)
# print(min_vals)
# 取出矩阵中最大的数
max_vals = dataset.max(0)
ranges = max_vals - min_vals
# 用0来填充矩阵
norm_dataset = np.zeros(np.shape(dataset))
# print(norm_dataset)
# 取出行数
m = dataset.shape[0]
# print(m)
# 归一化公式:n e w V a l u e = {o l d V a l u e - m i n ) / (max-min)
# np.tile将min_vals 这个矩阵的列复制m次
norm_dataset = dataset - np.tile(min_vals, (m, 1))
norm_dataset = norm_dataset / np.tile(ranges, (m, 1))
return norm_dataset, ranges, min_vals
def classify0(inX, dataSet, labels, k):
# 用来测试的行数,inx 当前一行矩阵,dataset用来测试的数据(后500行),labels分类结果,k是取前几个值来预判
dataSetSize = dataSet.shape[0]
# 复制当前行数,在减去以前求得的最小值
diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
# 平方
sqDiffMat = diffMat ** 2
# 求和
sqDistances = sqDiffMat.sum(axis=1)
# 根号处理
distances = sqDistances ** 0.5
# y|{0 - 67)2 + (20 000 - 32 000)2 + (1 • 1 — 0.1)2
# argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引),然后输出到sortedDistIndicies
sortedDistIndicies = distances.argsort()
classCount = {}
for i in range(k):
# 取出与当前值误差最小的3个值,来作为预测的结果
voteIlabel = labels[sortedDistIndicies[i]]
# 生成字典键,默认值为0
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
# py2和py3中字典的处理方式不同,3中是items(),reverse,默认是flase,由小到大,True由大大小,
# key是选取value来判断,写成lambda item:item[0]结果一样,可以接受的是一个函数
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
# 返回结果中出现次数多的那个当结果
return sortedClassCount[0][0]
def dating_classtest():
# 分类器测试
# 用来预测的原始数据
horario = 0.5
# 初始化数据
data, data_list = file_matrix('datingTestSet2.txt')
norm_dataset, ranges, min_vals = auto_norm(data)
# 取行
m = norm_dataset.shape[0]
num_test_vecs = int(m * horario)
# 初始化错误次数
error_count = 0.0
for i in range(num_test_vecs):
# 调用classify0判断预测结果
class_ifier_result = classify0(norm_dataset[i, :], norm_dataset[num_test_vecs:m, :], data_list[num_test_vecs:m],
3)
print('正确结果是%d,预测的是%d' % (class_ifier_result, data_list[i]))
if (class_ifier_result != data_list[i]):
error_count += 1
print("这次预测的正确率是%.2f%%" % ((1-(error_count) / float(num_test_vecs))*100))
data,list1 = file_matrix('datingTestSet2.txt')
matplotlib_(data)
# norm_dataset,ranges,c = auto_norm(data)
# print(a)
# dating_classtest()
def classify_person():
result_list = ['一点点','很喜欢','爱']
ff_miles = float(input("请输入一年的出差里数:"))
peroent_tabs = float(input("玩视频游戏所耗的时间百分比:"))
ice_creame = float(input("请输入两个人一起看电影的次数:"))
data, data_list = file_matrix('datingTestSet2.txt')
norm_dataset, ranges, min_vals = auto_norm(data)
in_arr = np.array([ff_miles,peroent_tabs,ice_creame])
# print(in_arr)
# print(type(peroent_tabs))
# print(type(min_vals))
# print(type(ranges))
data1 = (in_arr-min_vals)/ranges
classifier_result = classify0(data1,norm_dataset,data_list,3)
print("喜欢的程度:",result_list[classifier_result-1])
# classify_person()

