# 第一课: 线性回归分析bikes数据
# 读取数据并将日期时间设置为索引
import pandas as pd
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/bikeshare.csv';;
bikes = pd.read_csv(url, index_col='datetime', parse_dates=True)
bikes.head()
# **问题:**
# - 每个观察代表什么?
# - 什么是响应变量(由Kaggle定义)?
# - 有多少功能?
# #“count”是一种方法,所以最好把这个列命名为别的
bikes.rename(columns={'count':'total'}, inplace=True) # ## 可视化数据 import seaborn as sns
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (8, 6)
plt.rcParams['font.size'] = 14
# 大熊猫散点图
bikes.plot(kind='scatter', x='temp', y='total', alpha=0.2)
# Seaborn散点图与回归线
sns.lmplot(x='temp', y='total', data=bikes, aspect=1.5, scatter_kws={'alpha':0.2})
##线性回归的形式:$y = \beta_0 + \beta_1x_1 + \beta_2x_2 + ... + \beta_nx_n$
# - $ y $是回应
# - $ \ beta_0 $是拦截
# - $ \ beta_1 $是$ x_1 $的系数(第一项功能)
# - $ \ beta_n $是$ x_n $的系数(第n个特征)
#$ $ beta $值被称为**模型系数**:
# - 在模型拟合过程中使用**最小平方标准**估计(或“学习”)这些值。
# - 具体来说,我们找到最小化**平方残差**(或“平方误差之和”)的线(数学)。
# - 一旦我们学习了这些系数,我们可以使用模型来预测响应
#创建X和Y.
feature_cols = ['temp']
X = bikes[feature_cols]
y = bikes.total
# 导入,实例化,拟合
from sklearn.linear_model import LinearRegression
linreg = LinearRegression()
linreg.fit(X, y)
#打印系数
print linreg.intercept_
print linreg.coef_
# 解释**拦截**($ \ beta_0 $):
# - 当$ x $ = 0时,它是$ y $的值。
# - 因此,当温度为0摄氏度时,这是预计的租金数量。
# - **注意:**解释截取并不总是有意义的。 (为什么?)
# 解读**“临时”系数**($ \ beta_1 $):
# - $ y $的变化除以$ x $的变化,或“斜率”。
# - 因此,1摄氏度的温度升高**与9.17辆自行车的租金增加相关**。
# - 这不是一个因果关系的陈述。
# - $ \ beta_1 $如果温度上升与租金下降**相关,则**为负**。
# ###使用模型进行预测
# #如果温度是25摄氏度,我们可以预测多少辆自行车出租?
# 手动计算预测
linreg.intercept_ + linreg.coef_*25
# 使用预测方法
linreg.predict(25)
# ##功能的规模是否重要?
# 假设温度是用华氏度来衡量的,而不是摄氏度。 这将如何影响模型?
# 为华氏温度创建一个新的列
bikes['temp_F'] = bikes.temp * 1.8 + 32
bikes.head()
# Seaborn散点图与回归线
sns.lmplot(x='temp_F', y='total', data=bikes, aspect=1.5, scatter_kws={'alpha':0.2})
# 创建X和Y.
feature_cols = ['temp_F']
X = bikes[feature_cols]
y = bikes.total
# 实例化和拟合
linreg = LinearRegression()
linreg.fit(X, y)
# 打印系数
print linreg.intercept_
print linreg.coef_
# 将华氏温度转换成华氏25度
25 * 1.8 + 32
# 预测租金为华氏77度
linreg.predict(77)
# **结论:**线性回归模型的特征尺度是**不相关**。 在改变比例尺的时候,我们只是简单的改变**系数的**解释。
# 删除temp_F列
bikes.drop('temp_F', axis=1, inplace=True)
# 探索更多功能
feature_cols = ['temp', 'season', 'weather', 'humidity']
#在Seaborn多个散点图
sns.pairplot(bikes, x_vars=feature_cols, y_vars='total', kind='reg')
# 熊猫中的多个散点图
fig, axs = plt.subplots(1, len(feature_cols), sharey=True)
for index, feature in enumerate(feature_cols):
bikes.plot(kind='scatter', x=feature, y='total', ax=axs[index], figsize=(16, 3))
# 你有没有看到你没有想到的事情?
# 季节和月份的交叉列表
pd.crosstab(bikes.season, bikes.index.month)
# 方块租金,按季节分组
bikes.boxplot(column='total', by='season')
# 值得注意的是:
# - 行不能捕获非线性关系。
# - 冬天有更多的租金比春天(?)
bikes.total.plot()
# 这告诉我们什么?
# 冬天比春天有更多的租金,但仅仅是因为系统正在经历**整体增长**而冬季月份恰好在春季之后。
# 相关矩阵(范围从1到-1)
bikes.corr()#计算列的成对相关性,不包括NA /空值
# 使用热图可视化Seaborn中的相关矩阵
sns.heatmap(bikes.corr())
# 你注意到了什么关系?
# ##为模型添加更多功能
# 创建一个功能列表
feature_cols = ['temp', 'season', 'weather', 'humidity']
# 创建X和Y.
X = bikes[feature_cols]
y = bikes.total
# 实例化和拟合
linreg = LinearRegression()
linreg.fit(X, y)
# 打印系数
print linreg.intercept_
print linreg.coef_
# 将要素名称与系数配对
zip(feature_cols, linreg.coef_)
# #解读系数:
# - 固定所有其他功能,**温度增加1个单位**与**租赁增加7.86个自行车相关**。
# - 固定所有其他功能,在**季节增加1个单位**与**租赁增加22.5个自行车相关**。
# - 固定所有其他功能,**天气增加1个单位**与**租金增加6.67个自行车相关**。
# - 固定所有其他功能,**湿度增加1个单位**与**减少3.12个自行车** **相关。
# 有什么看起来不正确?
###功能选择
# 我们如何选择模型中包含哪些功能?我们将要使用** train / test split **(最终**交叉验证**)。
# 为什么不使用** p值**或** R平方**来进行特征选择?
# - 线性模型依赖**很多假设**(如特征是独立的),如果违反这些假设,则p值和R平方不太可靠。训练/测试分割依赖于较少的假设。
# - 与响应无关的特征仍然可以具有**显着的p值**。
# - 向你的模型添加与响应无关的特征将总是**增加R平方值**,而调整后的R平方不能充分解释这一点。
# 对于我们的泛化目标,P值和R平方是**代理**,而列车/测试分割和交叉验证尝试**直接估计**模型将如何推广到样本外数据。
# 更普遍:
# - 有不同的方法可以用来解决任何给定的数据科学问题,本课程遵循**机器学习方法**。
# - 本课程重点讨论**通用方法**,可以应用于任何模型,而不是模型特定的方法。
###回归问题的评估指标
# 分类问题的评估指标,如**准确性**,对回归问题没有用处。我们需要评估指标来比较**连续值**。
# 下面是回归问题的三个常见评估指标:
# **平均绝对误差**(MAE)是误差绝对值的平均值:
# $$ \ frac 1n \ sum_ {i = 1} ^ n | y_i- \ hat {y} _i | $$
# **均方误差**(MSE)是平方误差的均值:
# $$ \ frac 1n \ sum_ {i = 1} ^ n(y_i- \ hat {y} _i)^ 2 $$
# **均方根误差**(RMSE)是平方误差平均值的平方根:
# #$$ \ sqrt {\ frac 1n \ sum_ {i = 1} ^ n(y_i- \ hat {y} _i)^ 2} $$
#
# #示例真实和预测的响应值
true = [10, 7, 5, 5]
pred = [8, 6, 5, 10]
# 手工计算这些指标!
from sklearn import metrics
import numpy as np
print 'MAE:', metrics.mean_absolute_error(true, pred)
print 'MSE:', metrics.mean_squared_error(true, pred)
print 'RMSE:', np.sqrt(metrics.mean_squared_error(true, pred))
# 比较这些指标:
# - ** MAE **是最容易理解的,因为这是平均误差。
# - ** MSE **比MAE更受欢迎,因为MSE“惩罚”更大的错误,这在现实世界中往往是有用的。
# - ** RMSE **比MSE更受欢迎,因为RMSE可以用“y”单位来解释。
# 所有这些都是**损失函数**,因为我们想要最小化它们。
# 这是另一个示例,演示MSE / RMSE如何惩罚更大的错误:
# 与上面相同的真值
true = [10, 7, 5, 5]
# 新的一组预测值
pred = [10, 7, 5, 13]
# MAE和以前一样
print 'MAE:', metrics.mean_absolute_error(true, pred)
# MSE和RMSE比以前更大
print 'MSE:', metrics.mean_squared_error(true, pred)
print 'RMSE:', np.sqrt(metrics.mean_squared_error(true, pred))
# ##将模型与训练/测试分离和RMSE进行比较
from sklearn.cross_validation import train_test_split
# 定义一个接受功能列表并返回测试RMSE的函数
def train_test_rmse(feature_cols):
X = bikes[feature_cols]
y = bikes.total
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=123)
linreg = LinearRegression()
linreg.fit(X_train, y_train)
y_pred = linreg.predict(X_test)
return np.sqrt(metrics.mean_squared_error(y_test, y_pred))
# 比较不同的功能集
print train_test_rmse(['temp', 'season', 'weather', 'humidity'])
print train_test_rmse(['temp', 'season', 'weather'])
print train_test_rmse(['temp', 'season', 'humidity'])
# 使用这些功能是不允许的!
print train_test_rmse(['casual', 'registered'])
# ##比较测试RMSE和空RMSE
# 无效RMSE是可以通过总是预测平均响应值**来实现的RMSE。 这是您可能想要衡量您的回归模型的基准。
# 把X和Y分成训练和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=123)
# 创建一个与y_test形状相同的NumPy数组
y_null = np.zeros_like(y_test, dtype=float)
# 用y_test的平均值填充数组
y_null.fill(y_test.mean())
y_null
# 计算空值RMSE
np.sqrt(metrics.mean_squared_error(y_test, y_null))
###处理分类特征
# scikit-learn期望所有功能都是数字。 那么我们如何在模型中包含分类特征呢?
# - **有序类别:**将它们转换为合理的数值(例如:small = 1,medium = 2,large = 3)
# - **无序的类别:**使用虚拟编码(0/1)
#数据集中的分类特征是什么?
# - **有序类别:**天气(已经用合理的数值编码)
# - **无序类别:**季节(需要虚拟编码),节假日(已经虚拟编码),工作日(已经虚拟编码)
# 对于季节,我们不能简单地将编码保留为1 =春天,2 =夏天,3 =秋天,4 =冬天,因为那意味着**有序的关系**。
# 相反,我们创建**多个虚拟变量:**
# 创建虚拟变量
season_dummies = pd.get_dummies(bikes.season, prefix='season')
# 打印5个随机行
season_dummies.sample(n=5, random_state=1)
# 但是,我们实际上只需要**三个虚拟变量(而不是四个)**,因此我们将放弃第一个虚拟变量。
# 为什么? 因为三个假人捕捉了关于季节特征的所有“信息”,并且隐含地将春季(季节1)定义为**基线水平:**
# #放下第一列
season_dummies.drop(season_dummies.columns[0], axis=1, inplace=True)
#打印5个随机行
season_dummies.sample(n=5, random_state=1)
# 一般来说,如果您有** k个可能值**的分类特征,则可以创建** k-1个虚拟变量**。
#如果这是令人困惑的,那么考虑一下为什么我们只需要一个虚拟变量来放假,而不是两个虚拟变量(holiday_yes和holiday_no)。
# #连接原始DataFrame和虚拟DataFrame(axis = 0表示行,axis = 1表示列)
bikes = pd.concat([bikes, season_dummies], axis=1)
# 打印5个随机行
bikes.sample(n=5, random_state=1)
# 在模型中包含季节的虚拟变量
feature_cols = ['temp', 'season_2', 'season_3', 'season_4', 'humidity']
X = bikes[feature_cols]
y = bikes.total
linreg = LinearRegression()
linreg.fit(X, y)
zip(feature_cols, linreg.coef_)
# 我们如何解读季节系数? 他们是**相对于基线(春季)**测量的:
# - 保持所有其他功能固定,**夏季**与**租金减少3.39辆自行车**相比,春天。
# - 保持所有其他功能固定,**下降**与租金减少41.7辆自行车**相比,春天。
# - 保持所有其他功能固定,**冬季**与64.4辆自行车**相比,春季出租增加**。
# 如果我们改变哪个赛季被定义为基线,这会有影响吗?
# - 不,它只会改变我们**系数的解释。
# **重要:**虚拟编码与所有机器学习模型相关,而不仅仅是线性回归模型。
# 比较原始季节变量与虚拟变量
print train_test_rmse(['temp', 'season', 'humidity'])
print train_test_rmse(['temp', 'season_2', 'season_3', 'season_4', 'humidity'])
# ##特征工程
#看看你是否可以创建以下功能:
# - **小时:**作为单个数字功能(0到23)
# - **小时:**作为分类特征(使用23个虚拟变量)
# - **白天:**作为单个分类特征(白天=上午7点到晚上8点,否则白天= 0)
# 然后,尝试使用`train_test_rmse`三个功能中的每一个(用它自己)来看哪一个功能最好!
# 小时作为数字功能
bikes['hour'] = bikes.index.hour
# 小时作为分类特征
hour_dummies = pd.get_dummies(bikes.hour, prefix='hour')
hour_dummies.drop(hour_dummies.columns[0], axis=1, inplace=True)
bikes = pd.concat([bikes, hour_dummies], axis=1)
# 白天作为一个明确的特征
bikes['daytime'] = ((bikes.hour > 6) & (bikes.hour < 21)).astype(int)
print train_test_rmse(['hour'])
print train_test_rmse(bikes.columns[bikes.columns.str.startswith('hour_')])
print train_test_rmse(['daytime'])
# ##比较线性回归与其他模型
# 线性回归的优点:
# - 简单解释
# - 高度可解释的
# - 模型训练和预测是快速的
# - 不需要调整(不包括正规化)
# - 功能不需要缩放
# - 可以在少量的观察中表现良好
# - 完全了解
# 线性回归的缺点:
# - 设定功能和响应之间的线性关系
# - 由于高偏见,表现(通常)与最好的监督式学习方法没有竞争力
# 第二课 用Yelp投票线性回归作业
# 介绍
# 此作业使用Kaggle的[Yelp Business Rating Prediction](https://www.kaggle.com/c/yelp-recsys-2013)竞赛中的一小部分数据。
# - 此数据集中的每个观察结果都是特定用户对特定业务的评论。
# - “星号”列是审阅者分配给企业的星号(1到5)。 (更高的星星更好。)换句话说,这是撰写评论的人的业务评级。
# - “酷”栏是本评论从其他Yelp用户收到的“酷”票数。
# 所有的评论都是从0票“冷静”开始的,评论可以获得多少“酷”的票数是没有限制的。
# 换句话说,这是对评论本身的评价,而不是对评论的评价。
# - “有用”和“有趣”列与“酷”栏相似。
# 将`yelp.csv`读入DataFrame。
# 使用相对路径访问yelp.csv
import pandas as pd
yelp = pd.read_csv('yelp.csv')
yelp.head(1)
###任务1(奖金)
# 忽略`yelp.csv`文件,并从`yelp.json`自己构建这个DataFrame。
# 这包括将数据读入Python,解码JSON,将其转换为DataFrame,并为每个投票类型添加单独的列。
# 从yelp.json读取数据到行列表中
# 使用json.loads()将每行解码成字典
import json
with open('yelp.json', 'rU') as f:
data = [json.loads(row) for row in f]
# 显示第一个评论
data[0]
# 将字典列表转换为DataFrame
yelp = pd.DataFrame(data)
yelp.head(1)
#添加DataFrame列以获得很酷,有用和有趣的内容
yelp['cool'] = [row['votes']['cool'] for row in data]
yelp['useful'] = [row['votes']['useful'] for row in data]
yelp['funny'] = [row['votes']['funny'] for row in data]
#放弃选票栏
yelp.drop('votes', axis=1, inplace=True)
yelp.head(1)
# ###任务2
#探索每种投票类型(酷/有用/有趣)和星星数量之间的关系。
#把星星当成一个分类变量,寻找组间的差异
yelp.groupby('stars').mean()
#相关矩阵
import seaborn as sns
sns.heatmap(yelp.corr())
# 多个散点图
sns.pairplot(yelp, x_vars=['cool', 'useful', 'funny'], y_vars='stars', size=6, aspect=0.7, kind='reg')
# ## Task 3
#
# 定义酷/有用/有趣的功能,明星作为响应。
feature_cols = ['cool', 'useful', 'funny']
X = yelp[feature_cols]
y = yelp.stars
# ## Task 4
#
# 拟合线性回归模型并解释系数。 这些系数对你来说有直觉意义吗? 浏览Yelp网站,查看是否检测到类似的趋势。
from sklearn.linear_model import LinearRegression
linreg = LinearRegression()
linreg.fit(X, y)
zip(feature_cols, linreg.coef_)
# ## Task 5
#
# 通过将模型分解为训练集和测试集并计算RMSE来评估模型。 RMSE是否对你有直觉意义?
from sklearn.cross_validation import train_test_split
from sklearn import metrics
import numpy as np
# 定义一个接受功能列表并返回测试RMSE的函数
# 做回归分析,常用的误差主要有均方误差根(RMSE)和R-平方(R2)。
# RMSE是预测值与真实值的误差平方根的均值
# R2方法是将预测值跟只使用均值的情况下相比,看能好多少
def train_test_rmse(feature_cols):
X = yelp[feature_cols]
y = yelp.stars
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
linreg = LinearRegression()
linreg.fit(X_train, y_train)
y_pred = linreg.predict(X_test)
return np.sqrt(metrics.mean_squared_error(y_test, y_pred))
# 用所有三个特征计算RMSE
train_test_rmse(['cool', 'useful', 'funny'])
# ## Task 6
#
# 尝试删除一些功能,看看RMSE是否改善。
print train_test_rmse(['cool', 'useful'])
print train_test_rmse(['cool', 'funny'])
print train_test_rmse(['useful', 'funny'])
# ## Task 7 (Bonus)
#
# 思考一下可以从现有数据创建的一些新功能,这些功能可以预测响应。
# 找出如何在Pandas中创建这些功能,将它们添加到您的模型中,并查看RMSE是否得到改善。
# 新功能:评论长度(字符数)
yelp['length'] = yelp.text.apply(len)
# 新功能:评论是否包含“爱”或“讨厌”
yelp['love'] = yelp.text.str.contains('love', case=False).astype(int)
yelp['hate'] = yelp.text.str.contains('hate', case=False).astype(int)
# 为模型添加新功能并计算RMSE
train_test_rmse(['cool', 'useful', 'funny', 'length', 'love', 'hate'])
# ## Task 8 (Bonus)
#
# 把你最好的RMSE和测试集合中的RMSE比较为“空模型”,这是忽略所有特征的模型,并简单地预测测试集合中的平均响应值。
#分割数据(在函数之外)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
# 创建一个与y_test形状相同的NumPy数组
y_null = np.zeros_like(y_test, dtype=float)
# 用y_test的均值填充数组
y_null.fill(y_test.mean())
# 计算零均方根误差
print np.sqrt(metrics.mean_squared_error(y_test, y_null))
# ## Task 9 (Bonus)
#
#不要把它看作是一个回归问题,而应该把它看作一个分类问题,看看用KNN可以达到什么样的测试精度。
#导入并实例化KNN
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=50)
# 分类模型将自动将响应值(1/2/3/4/5)视为无序类别knn.fit(X_train, y_train)
knn.fit(X_train, y_train)
y_pred_class = knn.predict(X_test)
print metrics.accuracy_score(y_test, y_pred_class)
# ## Task 10 (Bonus)
# 找出如何使用线性回归进行分类,并将其分类精度与KNN的准确度进行比较。
# 使用线性回归进行连续预测
linreg = LinearRegression()
linreg.fit(X_train, y_train)
y_pred = linreg.predict(X_test)
# 将其预测整理为最接近的整数
y_pred_class = y_pred.round()
# 计算舍入预测的分类准确度
print metrics.accuracy_score(y_test, y_pred_class)
#第三课:指数函数和对数
import math
import numpy as np
# ## 指数函数
# 什么是** e **? 这只是一个数字(被称为欧拉数):
math.e
#** e **是一个重要的数字,因为它是所有持续增长的流程共享的基础增长率。
#例如,如果我有** 10美元**,而且在1年内增长100%(持续复利),我会以** 10 \ * e ^ 1美元结束**:
# 1年增长100%
10 * np.exp(1)
# 100%增长2年
10 * np.exp(2)
#注意:当e上升到一个幂时,它被称为**指数函数**。
# 从技术上讲,任何数字都可以作为基数,它仍然被称为**指数函数**(如2 ^ 5)。
# 但是在我们的情况下,指数函数的基础被假定为e。
#无论如何,如果我只有20%的增长,而不是100%的增长呢?
# 1年增长20%
10 * np.exp(0.20)
# 2年增长20%
10 * np.exp(0.20 * 2)
###对数
#(自然对数)**是什么? 它给你所需的时间达到一定的增长水平。
# 例如,如果我想增长2.718倍,则需要1个单位的时间(假设增长率为100%):
#需要增加1个单位到2.718个单位
np.log(2.718)
#如果我要增长7.389倍,那么我需要2个单位的时间:
# 需要增加1个单位到7.389个单位
np.log(7.389)
# 如果我想要增长1倍,它会花费我0个单位的时间:
# 需要将1个单位增加到1个单位的时间
np.log(1)
#如果我想要增长0.5倍,它将花费我-0.693个单位的时间(这就像是在回顾时间):
#需要增加1个单位到0.5个单位
np.log(0.5)
##连接概念
#正如你所看到的那样,指数函数和自然对数是**反转**:
np.log(np.exp(5))
np.exp(np.log(5))
# 第五课与泰坦尼克号数据进行逻辑回归练习#
# # 用泰坦尼克数据进行逻辑回归练习
# ## Step 1: 将数据读入Pasnda
import pandas as pd
titanic = pd.read_csv('titanic.csv', index_col='PassengerId')
titanic.head()
# ## Step 2: 创建X和Y
#
# 定义** Pclass **和** Parch **作为特征,** Survived **作为响应。
feature_cols = ['Pclass', 'Parch']
X = titanic[feature_cols]
y = titanic.Survived
# ## Step 3: 将数据分解成训练和测试集。
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
# ## Step 4: 拟合逻辑回归模型并检查系数
#
# 确认系数具有直觉意义。
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(C=1e9)
logreg.fit(X_train, y_train)
zip(feature_cols, logreg.coef_[0])
# ## Step 5: 对测试集进行预测并计算精度
# 类预测(不是预测概率)
y_pred_class = logreg.predict(X_test)
# 计算分类精度
from sklearn import metrics
print metrics.accuracy_score(y_test, y_pred_class)
# ## Step 6: 将您的测试准确性与零准确度进行比较
# 这个工程不管类的数量
y_test.value_counts().head(1) / len(y_test)
# 这只适用于编码为0/1的二进制分类问题
max(y_test.mean(), 1 - y_test.mean())
#泰坦尼克号预测的混淆矩阵#
#打印混淆矩阵
print metrics.confusion_matrix(y_test, y_pred_class)
#保存混淆矩阵并切片成四块
confusion = metrics.confusion_matrix(y_test, y_pred_class)
TP = confusion[1][1]
TN = confusion[0][0]
FP = confusion[0][1]
FN = confusion[1][0]
print 'True Positives:', TP
print 'True Negatives:', TN
print 'False Positives:', FP
print 'False Negatives:', FN
# 计算灵敏度
print TP / float(TP + FN)
print 44 / float(44 + 51)
#计算特异性
print TN / float(TN + FP)
print 105 / float(105 + 23)
# 存储预测的概率
y_pred_prob = logreg.predict_proba(X_test)[:, 1]
# 预测概率的直方图
import matplotlib.pyplot as plt
plt.hist(y_pred_prob)
plt.xlim(0, 1)
plt.xlabel('Predicted probability of survival')
plt.ylabel('Frequency')
# 通过降低预测生存的阈值来提高灵敏度
import numpy as np
y_pred_class = np.where(y_pred_prob > 0.3, 1, 0)
# 旧混淆矩阵
print confusion
# 新的混淆矩阵
print metrics.confusion_matrix(y_test, y_pred_class)
#新的灵敏度(比以前更高)
print 63 / float(63 + 32)
# 新的特异性(低于以前)
print 72 / float(72 + 56)
打赏
微信扫一扫,打赏作者吧~