#https://zhuanlan.zhihu.com/p/36834302
#1 导入有序字典函数
from collections import OrderedDict
#导入pandas包
import pandas as pd
#把数据集以字典的方式导入
examDict={"学习时间":[0.50,0.75,1.00,1.25,1.50,1.75,1.75,2.00,2.25,2.50,2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],"通过考试":[0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]}
#排序为有序字典
examOrderDict=OrderedDict(examDict)
#把有序字典转换成数据框
examDf=pd.DataFrame(examOrderDict)
examDf.head()

#print(examDf)


#特征 feature
exam_X=examDf.loc[:,"学习时间"]
#标签labels
exam_y=examDf.loc[:,"通过考试"]

#导入绘图包
import matplotlib.pyplot as plt
#散点图
plt.scatter(exam_X,exam_y,color="b",label="exam data")
#添加图标标签
plt.xlabel("hours")
plt.ylabel("pass")
#显示图像
plt.show()

#由图知:学习时间小于1的考试都没通过,学习时间在1~2的,通过了1个,在2~4之间的通过了3个。学习时间大于4 的都通过。

#train_test_split是交叉验证中常用的函数,功能是从样本中随机的按比例选取训练数据(train)和测试数据(test)
#从 sklearn包中导入train_test_split函数
from sklearn.model_selection import train_test_split, KFold
#建立训练数据和测试数据
X_train , X_test , y_train , y_test = train_test_split(exam_X ,
exam_y ,
train_size = 0.8)
#分别查看特征和标签的训练数据、测试数据大小
print("时间特征",exam_X.shape,X_train.shape,X_test.shape)
print("标签",exam_y.shape,y_train.shape,y_test.shape)
#时间特征 (20,) (16,) (4,)
#标签 (20,) (16,) (4,)

import matplotlib.pyplot as plt
#散点图
plt.scatter(X_train, y_train, color="blue", label="train data")
plt.scatter(X_test, y_test, color="red", label="test data")
#添加图标标签
plt.legend(loc=2)
plt.xlabel("Hours")
plt.ylabel("Pass")
#显示图像
plt.show()

#如果你输入的数据只有1个特征,需要用array.reshape(-1, 1)来改变数组的形状
#numpy的reshape就是指改变数组的形状
#reshape行的参数是-1,表示根据所给的列数,自动按照原始数组的大小形成一个新的数组
#原始数组总共是2行*3列=6个数,那么这里就会形成6行*1列的数组
#sklearn要求输入的特征必须是二维数组的类型,但是因为我们目前只有1个特征,所以用reshape转行成二维数组的类型。
X_train=X_train.values.reshape(-1,1)
#将测试数据特征转换成二维数组行数*1列
X_test=X_test.values.reshape(-1,1)


# 3 逻辑回归预测

#导入逻辑回归包
from sklearn.linear_model import LogisticRegression
# 创建模型:逻辑回归
model = LogisticRegression()
#训练模型
model.fit(X_train , y_train)

#输出结果为
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,penalty='l2', random_state=None, solver='liblinear', tol=0.0001,verbose=0, warm_start=False)

#4 模型评估(使用测试数据)
#评估模型使用测试数据,这里得到的是准确率
model.score(X_test , y_test)

#输出结果为
#1.0
#测试结果为1,即100%,说明预测还可以,但因为数据量太小了,是一个非常小的数据集,
#如果大的数据集仍然能保持这么高的预测正确率的话,就说明这个模型是非常有效的。

#求3个小时能否通过考试

#使用模型的predict方法可以进行预测。这里我们输入学生的特征学习时间3小时,模型返回结果标签是1,就代表预测该学生未通过考试。
pred=model.predict([[3]])
print(pred)