一、游戏介绍
玩家从1数到100,如果碰到能被3和5整除的数字,那么喊'fizzbuzz',如果碰到能被3整除的数字就喊'fizz',如果碰到能被5整除的数就喊'buzz',如果碰到的数字不满足上述任何一条件,则直接喊出该数字。
二、传统方式实现
对于传统编程来说,实现这个游戏非常简单,只需要简单的代码即可实现其逻辑。
参考代码
#根据数字,按照游戏规则进行输出
def fizz_or_buzz(num):
if num % 15 == 0:
return 'fizzbuzz'
elif num % 3 == 0:
return 'fizz'
elif num % 5 == 0:
return 'buzz'
else:
return str(num)
#开始游戏
ret = [] # 用于存储输出结果
for i in range(1, 101):
output = fizz_or_buzz(i)
ret.append(output)
print(ret)
输出如下
['1', '2', 'fizz', '4', 'buzz', 'fizz', '7', '8', 'fizz', 'buzz', '11', 'fizz', '13', '14', 'fizzbuzz', '16', '17', 'fizz', '19', 'buzz', 'fizz', '22', '23', 'fizz', 'buzz', '26', 'fizz', '28', '29', 'fizzbuzz', '31', '32', 'fizz', '34', 'buzz', 'fizz', '37', '38', 'fizz', 'buzz', '41', 'fizz', '43', '44', 'fizzbuzz', '46', '47', 'fizz', '49', 'buzz', 'fizz', '52', '53', 'fizz', 'buzz', '56', 'fizz', '58', '59', 'fizzbuzz', '61', '62', 'fizz', '64', 'buzz', 'fizz', '67', '68', 'fizz', 'buzz', '71', 'fizz', '73', '74', 'fizzbuzz', '76', '77', 'fizz', '79', 'buzz', 'fizz', '82', '83', 'fizz', 'buzz', '86',
'fizz', '88', '89', 'fizzbuzz', '91', '92', 'fizz', '94', 'buzz', 'fizz', '97', '98', 'fizz', 'buzz']
看上去一切正常,非常简单。然而传统编程方式实现的局限在于,代码中对规则进行了硬编码,每次修改规则,都要重新编码实现。另外,如果碰到了程序未曾触及到的逻辑,可能会有不可预料的输出。那么接下来,看看机器学习如何完成这个简单的逻辑。
三、机器学习实现之 K-近邻算法
K-近邻算法的核心思想是,通过对已知样本的建模,选择前若干个离新样本最近的已知样本,通过选择得到的已知样本投票决定未知样本的分类。
示例代码并没有真正实现k-近邻算法,而是通过scikit-learn包已经实现好的训练器进行训练与预测,具体代码如下
#引入必要的包
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
# 构建特征值
def build_feature(num):
return np.array([num % 3, num % 5, num % 15])
# 将需要预测的指标转换为数字方法:number, "fizz", "buzz", "fizzbuzz"
# 将数据的真实值(预测结果)分别对应转换为数字
# 映射关系 number -> 0, "fizz" -> 1, "buzz" -> 2, "fizzbuzz" -> 3
def make_lable(i):
if i % 15 == 0:
return np.array([3])
elif i % 5 == 0:
return np.array([2])
elif i % 3 == 0:
return np.array([1])
else:
return np.array([0])
#将结果映射成输出
def output_mapping(i, num):
if i == 1:
return 'fizz'
elif i == 2:
return 'buzz'
elif i == 3:
return 'fizzbuzz'
return str(num)
#构建训练集数据
x_train = np.array([build_feature(i) for i in range(101, 200)])
y_train = np.array([make_lable(i) for i in range(101, 200)])
#测试集
x_test = np.array([build_feature(i) for i in range(1, 101)])
y_test = np.array([make_lable(i) for i in range(1, 101)])
#KNN分类器训练
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(x_train, y_train)
# #打印预测结果
result = knn.predict(x_test)
# print(result)
print([output_mapping(num, idx+1) for idx, num in enumerate(result)])
#预测效果评分
print('train score:{}'.format(knn.score(x_train, y_train)))
print('test score:{}'.format(knn.score(x_test, y_test)))
输出
['1', '2', 'fizz', '4', 'buzz', 'fizz', '7', '8', 'fizz', 'buzz', '11', 'fizz', '13', '14', 'fizzbuzz', '16', '17', 'fizz', '19', 'buzz', 'fizz', '22', '23', 'fizz', 'buzz', '26', 'fizz', '28', '29', 'fizzbuzz', '31', '32', 'fizz', '34', 'buzz', 'fizz', '37', '38', 'fizz', 'buzz', '41', 'fizz', '43', '44', 'fizzbuzz', '46', '47', 'fizz', '49', 'buzz', 'fizz', '52', '53', 'fizz', 'buzz', '56', 'fizz', '58', '59', 'fizzbuzz', '61', '62', 'fizz', '64', 'buzz', 'fizz', '67', '68', 'fizz', 'buzz', '71', 'fizz', '73', '74', 'fizzbuzz', '76', '77', 'fizz', '79', 'buzz', 'fizz', '82', '83', 'fizz', 'buzz', '86',
'fizz', '88', '89', 'fizzbuzz', '91', '92', 'fizz', '94', 'buzz', 'fizz', '97', '98', 'fizz', 'buzz']
train score:1.0
test score:1.0
四、机器学习实现之 logistic回归算法
不同于k-近邻算法直接对新样本进行预测分类。logistic回归算法是通过已知样本得到算法模型中的参数,从而用训练好的模型对新样本进行预测。
示例代码同样使用scikit-learn包下已经实现的算法实现
#引入必要的包
import numpy as np
from sklearn import linear_model
# 构建特征值
def build_feature(num):
return np.array([num % 3, num % 5, num % 15])
# 将需要预测的指标转换为数字方法:number, "fizz", "buzz", "fizzbuzz"
# 将数据的真实值(预测结果)分别对应转换为数字
# 映射关系 number -> 0, "fizz" -> 1, "buzz" -> 2, "fizzbuzz" -> 3
def make_lable(i):
if i % 15 == 0:
return np.array([3])
elif i % 5 == 0:
return np.array([2])
elif i % 3 == 0:
return np.array([1])
else:
return np.array([0])
#将结果映射成输出
def output_mapping(i, num):
if i == 1:
return 'fizz'
elif i == 2:
return 'buzz'
elif i == 3:
return 'fizzbuzz'
return str(num)
#构建训练集数据
x_train = np.array([build_feature(i) for i in range(101, 200)])
y_train = np.array([make_lable(i) for i in range(101, 200)])
#测试集
x_test = np.array([build_feature(i) for i in range(1, 101)])
y_test = np.array([make_lable(i) for i in range(1, 101)])
#Logistic回归训练
logistic=linear_model.LogisticRegression()
logistic.fit(x_train, y_train)
# #打印预测结果
result = logistic.predict(x_test)
# print(result)
print([output_mapping(num, idx+1) for idx, num in enumerate(result)])
#预测效果评分
print('train score:{}'.format(logistic.score(x_train, y_train)))
print('test score:{}'.format(logistic.score(x_test, y_test)))
输出
['1', '2', 'fizz', '4', '5', 'fizz', '7', '8', 'fizz', 'buzz', '11', 'fizz', '13', '14', 'fizzbuzz', '16', '17', 'fizz', '19', '20', 'fizz', '22', '23', 'fizz', 'buzz', '26', 'fizz', '28', '29', 'fizzbuzz', '31', '32', 'fizz', '34', '35', 'fizz', '37', '38', 'fizz', 'buzz', '41', 'fizz', '43', '44', 'fizzbuzz', '46', '47', 'fizz', '49', '50', 'fizz', '52', '53', 'fizz', 'buzz', '56', 'fizz', '58', '59', 'fizzbuzz', '61', '62', 'fizz', '64', '65', 'fizz', '67', '68', 'fizz', 'buzz', '71', 'fizz', '73', '74', 'fizzbuzz', '76', '77', 'fizz', '79', '80', 'fizz', '82', '83', 'fizz', 'buzz', '86', 'fizz', '88', '89', 'fizzbuzz', '91', '92', 'fizz', '94', '95', 'fizz', '97', '98', 'fizz', 'buzz']
train score:0.9393939393939394
test score:0.93
五、总结
至此,已经对fizz buzz游戏通过三种不同的方式进行了编码实现,其中有两种是通过机器学习的方式实现。主要为了了解传统编程方式和机器学习编程方式在解决问题上的区别。在面对简单问题的时候,传统的编程手段,更加快捷方便,而且几乎不会出现错误。而在面对一些无法通过硬编码实现逻辑,或者对于输入数据无法预知的问题时,通过机器学习的方式解决问题,可能会更加容易。
网友评论