西瓜书第三章课后答案—3.3、3.5


1、3.3编程实现对率回归

  • 1、数据集
    西瓜书89页数据集3.0a
    在这里插入图片描述
  • 2、代码
1
2
3
4
5
6
7
8
9
10
11
12
13
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression #对率回归
from sklearn import metrics
dataset = pd.read_csv('watermelon3a.csv',encoding='utf-8')
#数据预处理
X = dataset[['密度','含糖率']]
Y = dataset['好瓜']
good_melon = dataset[dataset['好瓜'] == 1]
bad_melon = dataset[dataset['好瓜'] == 0]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#绘制图片
f1 = plt.figure(1)
plt.title('watermelon_3a')
plt.xlabel('density') #x轴坐标密度
plt.ylabel('radio_sugar') #y轴坐标含糖率
plt.xlim(0,1) #范围0-1
plt.ylim(0,1) #范围0-1
plt.scatter(bad_melon['密度'],bad_melon['含糖率'],marker='*',color='r',s=50,label='bad') #散点图
plt.scatter(good_melon['密度'],good_melon['含糖率'],marker='*',color='b',s=50,label='good')
plt.legend(loc='upper right')
#分割训练集和验证集
X_train,X_test,Y_train,Y_test = model_selection.train_test_split(X,Y,test_size=0.3,random_state=0) #选择30%为测试集
#训练
log_model = LogisticRegression() #封装好的对率函数
log_model.fit(X_train,Y_train)
#验证
Y_pred = log_model.predict(X_test)
#汇总结果
print(metrics.confusion_matrix(Y_test, Y_pred))  #该模块均为sklearn中,计算预测中正确的个数和错误的个数
print(metrics.classification_report(Y_test, Y_pred, target_names=['Bad','Good']))#可以得到准确率、查全率、F1值等
#从上面可以看出好瓜正确率为0,坏瓜准确率为0.67,3个中对了2个
print(log_model.coef_) #w1,w2的值
print(log_model.intercept_) #b
theta1, theta2 = log_model.coef_[0][0], log_model.coef_[0][1]
X_pred = np.linspace(0,1,100)
line_pred = theta1 + theta2 * X_pred
plt.plot(X_pred, line_pred)
plt.show()
  • 3、输出结果
    预测中正确的个数和错误的个数
    准确率、查全率、F1值
    系数值与最终的图形
    在这里插入图片描述
    在这里插入图片描述

2、3.5线性判别分析

  • 1、数据集
    西瓜书89页数据集3.0a
  • 2、理论
    在这里插入图片描述
  • 3、代码复现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#1、输出查全率、f1值等
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis #线性判别分析
from sklearn import model_selection
from sklearn import metrics

dataset = pd.read_csv('watermelon3a.csv',encoding='utf-8')
#数据预处理
X = dataset[['密度','含糖率']]
Y = dataset['好瓜']
#分割训练集和验证集
X_train,X_test,Y_train,Y_test = model_selection.train_test_split(X,Y,test_size=0.3,random_state=0)#仍选取30%作为测试集
#训练
LDA_model = LinearDiscriminantAnalysis()
LDA_model.fit(X_train,Y_train)
#验证
Y_pred = LDA_model.predict(X_test) #同之前的方法类似
#汇总结果
print(metrics.confusion_matrix(Y_test, Y_pred))
print(metrics.classification_report(Y_test, Y_pred, target_names=['Bad','Good']))
print(LDA_model.coef_)
#画图
good_melon = dataset[dataset['好瓜'] == 1]
bad_melon = dataset[dataset['好瓜'] == 0]
plt.scatter(good_melon['密度'],good_melon['含糖率'],marker='*',color='r',s=50,label='good')#注意此处与3.3的颜色有所调换
plt.scatter(bad_melon['密度'],bad_melon['含糖率'],marker='*',color='b',s=50,label='bad')
plt.legend(loc='upper right') #标签
plt.show()
  • 输出结果
    预测中正确的个数和错误的个数
    准确率、查全率、F1值
    系数值与最终的图形
    在这里插入图片描述
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#2、线性判别分析(二分类问题),求解w,并绘制相应图片
import numpy as np
import matplotlib.pyplot as plt
data = [[0.697, 0.460, 1],
        [0.774, 0.376, 1],
        [0.634, 0.264, 1],
        [0.608, 0.318, 1],
        [0.556, 0.215, 1],
        [0.403, 0.237, 1],
        [0.481, 0.149, 1],
        [0.437, 0.211, 1],
        [0.666, 0.091, 0],
        [0.243, 0.267, 0],
        [0.245, 0.057, 0],
        [0.343, 0.099, 0],
        [0.639, 0.161, 0],
        [0.657, 0.198, 0],
        [0.360, 0.370, 0],
        [0.593, 0.042, 0],
        [0.719, 0.103, 0]]
#数据集按瓜好坏分类
data = np.array([i[:-1] for i in data])
X0 = np.array(data[:8]) #好瓜
X1 = np.array(data[8:]) #坏瓜
#求正反例均值
miu0 = np.mean(X0, axis=0).reshape((-1, 1))
miu1 = np.mean(X1, axis=0).reshape((-1, 1))
#求协方差
cov0 = np.cov(X0, rowvar=False)
cov1 = np.cov(X1, rowvar=False)
#求出w
S_w = np.mat(cov0 + cov1) #类内散度矩阵
Omiga = S_w.I * (miu0 - miu1) #求逆在与均值差相乘
#画出点、直线
plt.scatter(X0[:, 0], X0[:, 1], marker='+',color='r',s=50,label='good')
plt.scatter(X1[:, 0], X1[:, 1], marker='_',color='b',s=50,label='bad')
plt.plot([0, 1], [0, Omiga[0] / Omiga[1]], label='y')
plt.xlabel('密度', fontproperties='SimHei', fontsize=15, color='green');
plt.ylabel('含糖率', fontproperties='SimHei', fontsize=15, color='green');
plt.title(r'LinearDiscriminantAnalysis', fontproperties='SimHei', fontsize=25);
plt.legend()
plt.show()

  • 结果为:
    在这里插入图片描述
    在这里插入图片描述
    从这两种方法可以看出,线性判别方法比对率回归准确率稍高一些,效果较好,但由于数据量较少的原因,最终的效果并不是特别理想。