第八课、决策树
# 决策树(Decision Tree)是在已知各种情况发生概率的基础上,
# 通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,
# 判断其可行性的决策分析方法,是直观运用概率分析的一种图解法
# ### Demo: 选择给定功能的理想切点
# 车辆数据
import pandas as pd
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/vehicles_train.csv';;
train = pd.read_csv(url)
# 在分割任何东西之前,只需预测整个数据集的平均值即可
train['prediction'] = train.price.mean()
train
#计算这些预测的RMSE(它的计算方法是先平方、再平均、然后开方)说明样本的离散程度。
from sklearn import metrics
import numpy as np
np.sqrt(metrics.mean_squared_error(train.price, train.prediction))
# 定义一个函数来计算一个给定的英里数的RMSE
def mileage_split(miles):
lower_mileage_price = train[train.miles < miles].price.mean()
higher_mileage_price = train[train.miles >= miles].price.mean()
train['prediction'] = np.where(train.miles < miles, lower_mileage_price, higher_mileage_price)
return np.sqrt(metrics.mean_squared_error(train.price, train.prediction))
# 计算分裂在英里数<50000的树的RMSE
print 'RMSE:', mileage_split(50000)
train
# 计算分裂在英里数<100000的树的RMSE
print 'RMSE:', mileage_split(100000)
train
# 检查所有可能的里程分割
mileage_range = range(train.miles.min(), train.miles.max(), 1000)
RMSE = [mileage_split(miles) for miles in mileage_range]
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (6, 4)
plt.rcParams['font.size'] = 14
# 绘制里程分界点(x轴)与RMSE(y轴)
plt.plot(mileage_range, RMSE)
plt.xlabel('Mileage cutpoint')
plt.ylabel('RMSE (lower is better)')
#**总结:**在每次分割之前,对每个特征重复该过程,并选择产生最低MSE的特征和分割点。
###在scikit-learn中构建一个回归树
#编码为0,卡车为1
train['vtype'] = train.vtype.map({'car':0, 'truck':1})
# define X and y
feature_cols = ['year', 'miles', 'doors', 'vtype']
X = train[feature_cols]
y = train.price
# 实例化一个DecisionTreeRegressor(random_state = 1)
from sklearn.tree import DecisionTreeRegressor
treereg = DecisionTreeRegressor(random_state=1)
treereg
# 使用leave-one-out交叉验证(LOOCV)来估计此模型的RMSE
from sklearn.cross_validation import cross_val_score
scores = cross_val_score(treereg, X, y, cv=14, scoring='neg_mean_squared_error')
np.mean(np.sqrt(-scores))
###调整回归树
#我们试着通过调整** max_depth **参数来减少RMSE:
#尝试不同的值一个接一个
treereg = DecisionTreeRegressor(max_depth=1, random_state=1)
scores = cross_val_score(treereg, X, y, cv=14, scoring='neg_mean_squared_error')
np.mean(np.sqrt(-scores))
#或者,我们可以写一个循环来尝试一系列值:
#要尝试的值列表
max_depth_range = range(1, 8)
# 列表来存储每个max_depth值的平均RMSE
RMSE_scores = []
# 使用每个值为max_depth的LOOCV
for depth in max_depth_range:
treereg = DecisionTreeRegressor(max_depth=depth, random_state=1)
MSE_scores = cross_val_score(treereg, X, y, cv=14, scoring='neg_mean_squared_error')
RMSE_scores.append(np.mean(np.sqrt(-MSE_scores)))
# plot max_depth(x轴)对RMSE(y轴)
plt.plot(max_depth_range, RMSE_scores)
plt.xlabel('max_depth')
plt.ylabel('RMSE (lower is better)')
# max_depth = 3是最好的,所以适合使用该参数的树
treereg = DecisionTreeRegressor(max_depth=3, random_state=1)
treereg.fit(X, y)
# 每个特征的“基尼重要性”:该特征带来的(归一化)总误差减少
pd.DataFrame({'feature':feature_cols, 'importance':treereg.feature_importances_})
###创建一个树形图
#创建一个Graphviz文件
from sklearn.tree import export_graphviz
export_graphviz(treereg, out_file='tree_vehicles.dot', feature_names=feature_cols)
# ## 预测测试数据
# 阅读测试数据
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/vehicles_test.csv'
test = pd.read_csv(url)
test['vtype'] = test.vtype.map({'car':0, 'truck':1})
test
#**问题:**使用上面的树形图,模型对每个观测值做出什么样的预测?
#使用拟合的模型来预测测试数据
X_test = test[feature_cols]
y_test = test.price
y_pred = treereg.predict(X_test)
y_pred
# 计算RMSE
np.sqrt(metrics.mean_squared_error(y_test, y_pred))
# 为你自己的树计算RMSE!
y_test = [3000, 6000, 12000]
y_pred = [0, 0, 0]
from sklearn import metrics
np.sqrt(metrics.mean_squared_error(y_test, y_pred))
###第2部分:分类树
# 读取数据
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/titanic.csv';;
titanic = pd.read_csv(url)
# 将女性编码为0,男性编码为1
titanic['Sex'] = titanic.Sex.map({'female':0, 'male':1})
# 用年龄中位数填写年龄缺失值
titanic.Age.fillna(titanic.Age.median(), inplace=True)
# 创建一个虚拟变量的数据框
embarked_dummies = pd.get_dummies(titanic.Embarked, prefix='Embarked')
embarked_dummies.drop(embarked_dummies.columns[0], axis=1, inplace=True)
# 连接原始DataFrame和虚拟DataFrame
titanic = pd.concat([titanic, embarked_dummies], axis=1)
# 打印更新的DataFrame
titanic.head()
# - **存活:** 0 =死亡,1 =存活(反应变量)
# - ** Pclass:** 1 =一等,2 =二等,3 =三等
# - 如果树在这个特性上分裂会发生什么?
# - **性别:** 0 =女性,1 =男性
# - **年龄:**数值
# - **进入:** C或Q或S
# define X and y
feature_cols = ['Pclass', 'Sex', 'Age', 'Embarked_Q', 'Embarked_S']
X = titanic[feature_cols]
y = titanic.Survived
# 在所有数据上都适合一个max_depth = 3的分类树
from sklearn.tree import DecisionTreeClassifier
treeclf = DecisionTreeClassifier(max_depth=3, random_state=1)
treeclf.fit(X, y)
#创建一个Graphviz文件
export_graphviz(treeclf, out_file='tree_titanic.dot', feature_names=feature_cols)
# 计算特征的重要性
pd.DataFrame({'feature':feature_cols, 'importance':treeclf.feature_importances_})
##第3部分:将决策树与其他模型进行比较
# **决策树的优势:**
# - 可以用于回归或分类
# - 可以用图形显示
# - 高度可解释的
# - 可以指定为一系列规则,并且比其他模型更接近于人类决策
# - 预测很快
# - 功能不需要缩放
# - 自动学习功能交互
# - 倾向于忽略不相关的功能
# - 非参数(如果特征和响应之间的关系非常非线性,将优于线性模型)
# #**决策树的缺点:**
# #
# - 表现(通常)与最好的监督式学习方法没有竞争力
# - 可以轻松过度训练数据(需要调整)
# - 数据的小变化可能导致完全不同的树(高变化)
# 递归二进制分裂使得“局部最优”决策可能不会导致全局最优树
# - 如果课程非常不平衡,则不会趋于良好
# - 对于非常小的数据集不适合
第九课、集合
# 为什么我们学习集合?
# - 提高机器学习模型预测性能的非常流行的方法
# - 为理解更复杂的模型奠定了基础
# 第一部分:简介
import numpy as np
# 为可再现性设置种子
np.random.seed(1234)
#为每个模型生成1000个随机数(0到1之间),代表1000个观察值
mod1 = np.random.rand(1000)
mod2 = np.random.rand(1000)
mod3 = np.random.rand(1000)
mod4 = np.random.rand(1000)
mod5 = np.random.rand(1000)
# 如果随机数至少为0.3,则每个模型独立预测1(“正确响应”)
preds1 = np.where(mod1 > 0.3, 1, 0)
preds2 = np.where(mod2 > 0.3, 1, 0)
preds3 = np.where(mod3 > 0.3, 1, 0)
preds4 = np.where(mod4 > 0.3, 1, 0)
preds5 = np.where(mod5 > 0.3, 1, 0)
# 打印每个模型的前20个预测
print preds1[:20]
print preds2[:20]
print preds3[:20]
print preds4[:20]
print preds5[:20]
# 平均预测,然后轮到0或1
ensemble_preds = np.round((preds1 + preds2 + preds3 + preds4 + preds5)/5.0).astype(int)
#打印合奏的前20个预测
print ensemble_preds[:20]
#每个模型有多精确?
print preds1.mean()
print preds2.mean()
print preds3.mean()
print preds4.mean()
print preds5.mean()
#合奏有多精确?
print ensemble_preds.mean()
###什么是合成?
#**集合学习(或“集合”)**是将多个预测模型组合在一起以生成比任何单个模型更精确的组合模型的过程。
# 第2部分:手动合成
# 什么使得一个好的手工合奏?
# - 不同类型的**模型**
# - **功能的不同组合
# - 不同的**调整参数**
# ##第三部分:装袋
#
# **决策树**的主要弱点是它们往往不具有最好的预测准确性。 这部分是由于**高方差**,
# 这意味着训练数据中的不同分裂可能导致非常不同的树。
# #** Bagging **是减少机器学习方法方差的通用程序,但对决策树特别有用。
# Bagging是** bootstrap聚合**的缩写,意思是bootstrap样本的聚合。
# 为可再现性设置种子
np.random.seed(1)
# 创建一个1到20的数组
nums = np.arange(1, 21)
print nums
# 样本数组替换20次
print np.random.choice(a=nums, size=20, replace=True)
# #**装袋工作(对于决策树)如何工作?**
# #1.使用训练数据中的B bootstrap样本生成B树。
# #2.训练每个树的自举样本并做出预测。
# #3.结合预测:
# # - 平均**回归树的预测**
# # - 为**分类树**投票
# #注意:
# - **每个引导样本**应该与原始训练集大小相同。
# - ** B **应该是一个足够大的值,这个错误似乎已经“稳定”了。
# - 树木长得很深,所以它们的偏差很小/偏差很大。
# Bagging通过**降低方差来提高预测精度**,类似于交叉验证如何通过分割多次平均结果来减少与列车/测试分割相关联的方差(用于估计样本外误差)。
# ##手工实现袋装决策树(B = 10)
# 阅读并准备车辆训练数据
import pandas as pd
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/vehicles_train.csv';;
train = pd.read_csv(url)
train['vtype'] = train.vtype.map({'car':0, 'truck':1})
train
#为可再现性设置种子
np.random.seed(123)
# 创建10个引导样本(将用于从DataFrame中选择行)
samples = [np.random.choice(a=14, size=14, replace=True) for _ in range(1, 11)]
samples
# 显示第一个决策树的行
train.iloc[samples[0], :]
#阅读并准备车辆测试数据
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/vehicles_test.csv';;
test = pd.read_csv(url)
test['vtype'] = test.vtype.map({'car':0, 'truck':1})
test
from sklearn.tree import DecisionTreeRegressor
#长出每棵树
treereg = DecisionTreeRegressor(max_depth=None, random_state=123)
# 列表中存储每棵树的预测价格
predictions = []
# 定义测试数据
X_test = test.iloc[:, 1:]
y_test = test.iloc[:, 0]
# 为每个bootstrap样本生成一棵树,并对测试数据进行预测
for sample in samples:
X_train = train.iloc[sample, 1:]
y_train = train.iloc[sample, 0]
treereg.fit(X_train, y_train)
y_pred = treereg.predict(X_test)
predictions.append(y_pred)
# 将预测从列表转换为NumPy数组
predictions = np.array(predictions)
predictions
# 平均预测
np.mean(predictions, axis=0)
# 计算RMSE
from sklearn import metrics
y_pred = np.mean(predictions, axis=0)
np.sqrt(metrics.mean_squared_error(y_test, y_pred))
# ## 用scikit-learn(B = 500)
# 定义培训和测试集
X_train = train.iloc[:, 1:]
y_train = train.iloc[:, 0]
X_test = test.iloc[:, 1:]
y_test = test.iloc[:, 0]
# 指示BaggingRegressor使用DecisionTreeRegressor作为“基本估计器”
from sklearn.ensemble import BaggingRegressor
bagreg = BaggingRegressor(DecisionTreeRegressor(), n_estimators=500, bootstrap=True, oob_score=True, random_state=1)
# 适合和预测
bagreg.fit(X_train, y_train)
y_pred = bagreg.predict(X_test)
y_pred
# 计算RMSE
np.sqrt(metrics.mean_squared_error(y_test, y_pred))
# ##估计样本外错误
# 对于袋装模型,可以不使用**火车/测试分割**或**交叉验证**来估计样本外错误!
# 平均而言,每个袋装树使用大约三分之二**的观察值。 对于每一棵树,其余的**观测**被称为“外包”观测。
# 显示第一个bootstrap示例
samples[0]
# 显示每个样品的“袋内”观察结果
for sample in samples:
print set(sample)
# 显示每个样本的“外包”观察结果
for sample in samples:
print sorted(set(range(14)) - set(sample))
# 如何计算**“外包错误”:**
# 1.对于训练数据中的每一个观测值,只使用**来预测其观测值在树袋外的树的响应值。 平均那些预测(回归)或投票(分类)。
# 2.将所有的预测与实际响应值进行比较,以便计算出袋外误差。
# 当B足够大时,**出包错误**是对样本外错误**的准确估计。
# 计算B = 500的袋外R平方得分(不幸的是,不是MSE)
bagreg.oob_score_
# ##估计特征重要性
# 套袋增加**预测的准确性**,但减少**模型的解释性**,因为不再可能将树形象化以理解每个特征的重要性。
# #第5部分:构建和调整决策树和随机森林
# - 每个观察代表一个球员
# - **进球:**预测球员薪水
###准备数据
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/hitters.csv';;
hitters = pd.read_csv(url)
# 删除缺少值的行
hitters.dropna(inplace=True)
hitters.head()
# 将分类变量编码为整数
hitters['League'] = pd.factorize(hitters.League)[0]
hitters['Division'] = pd.factorize(hitters.Division)[0]
hitters['NewLeague'] = pd.factorize(hitters.NewLeague)[0]
hitters.head()
# 让情节出现在笔记本中
import matplotlib.pyplot as plt
#“年薪”与“工资”着色点之间的散点图
hitters.plot(kind='scatter', x='Years', y='Hits', c='Salary', colormap='jet', xlim=(0, 25), ylim=(0, 250))
#定义特征:排除职业统计(以“C”开头)和回应(薪水)
feature_cols = hitters.columns[hitters.columns.str.startswith('C') == False].drop('Salary')
feature_cols
# 定义X和y
X = hitters[feature_cols]
y = hitters.Salary
###用决策树预测工资
#使用交叉验证为决策树找到最好的** max_depth **:
#为max_depth尝试的值列表
max_depth_range = range(1, 21)
# 列表来存储每个max_depth值的平均RMSE
RMSE_scores = []
# 对每个max_depth值使用10次交叉验证
from sklearn.cross_validation import cross_val_score
for depth in max_depth_range:
treereg = DecisionTreeRegressor(max_depth=depth, random_state=1)
MSE_scores = cross_val_score(treereg, X, y, cv=10, scoring='neg_mean_squared_error')
RMSE_scores.append(np.mean(np.sqrt(-MSE_scores)))
# plot max_depth(x轴)对RMSE(y轴)
plt.plot(max_depth_range, RMSE_scores)
plt.xlabel('max_depth')
plt.ylabel('RMSE (lower is better)')
# 显示最好的RMSE和相应的max_depth
sorted(zip(RMSE_scores, max_depth_range))[0]
# max_depth = 2是最好的,所以适合使用该参数的树
treereg = DecisionTreeRegressor(max_depth=2, random_state=1)
treereg.fit(X, y)
#计算功能重要性
pd.DataFrame({'feature':feature_cols, 'importance':treereg.feature_importances_}).sort_values('importance')
# ## 用随机森林预测工资
from sklearn.ensemble import RandomForestRegressor
rfreg = RandomForestRegressor()
rfreg
####调整n_estimators
#一个重要的调整参数是** n_estimators **,这是应该增长的树的数量。 它应该是一个足够大的值,这个错误似乎已经“稳定”了。
#为n_estimators尝试的值列表
estimator_range = range(10, 310, 10)
# 列表来存储每个n_estimators值的平均RMSE
RMSE_scores = []
# 对n_estimators的每个值使用5-fold交叉验证(WARNING:SLOW!)
for estimator in estimator_range:
rfreg = RandomForestRegressor(n_estimators=estimator, random_state=1)
MSE_scores = cross_val_score(rfreg, X, y, cv=5, scoring='neg_mean_squared_error')
RMSE_scores.append(np.mean(np.sqrt(-MSE_scores)))
# 绘制n_estimators(x轴)与RMSE(y轴)
plt.plot(estimator_range, RMSE_scores)
plt.xlabel('n_estimators')
plt.ylabel('RMSE (lower is better)')
####调整max_features
#另一个重要的调整参数是** max_features **,这是在每个split应该考虑的功能的数量。
#为max_features尝试的值列表
feature_range = range(1, len(feature_cols)+1)
# 列表来存储每个max_features值的平均RMSE
RMSE_scores = []
# 对每个max_features值使用10次交叉验证(警告:慢!)
for feature in feature_range:
rfreg = RandomForestRegressor(n_estimators=150, max_features=feature, random_state=1)
MSE_scores = cross_val_score(rfreg, X, y, cv=10, scoring='neg_mean_squared_error')
RMSE_scores.append(np.mean(np.sqrt(-MSE_scores)))
# 绘图max_features(x轴)与RMSE(y轴)
plt.plot(feature_range, RMSE_scores)
plt.xlabel('max_features')
plt.ylabel('RMSE (lower is better)')
#显示最好的RMSE和相应的max_features
sorted(zip(RMSE_scores, feature_range))[0]
####用最好的参数拟合随机森林
#max_features = 8是最好的,n_estimators = 150是足够大的
rfreg = RandomForestRegressor(n_estimators=150, max_features=8, oob_score=True, random_state=1)
rfreg.fit(X, y)
#计算功能重要性
pd.DataFrame({'feature':feature_cols, 'importance':rfreg.feature_importances_}).sort_values('importance')
# 计算出袋外R平方得分
rfreg.oob_score_
####减少X的最重要的功能
#检查X的形状
X.shape
第十课、高级scikit-learn
# 假数据
import pandas as pd
train = pd.DataFrame({'id':[0,1,2], 'length':[0.9,0.3,0.6], 'mass':[0.1,0.2,0.8], 'rings':[40,50,60]})
test = pd.DataFrame({'length':[0.59], 'mass':[0.79], 'rings':[54]})
# 训练数据
train
# 测试数据
test
# 定义X和y
feature_cols = ['length', 'mass', 'rings']
X = train[feature_cols]
y = train.id
# KN = K = 1
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X, y)
# 它预测什么“应该”?
knn.predict(test)
# 让情节出现在笔记本中
import matplotlib.pyplot as plt
plt.rcParams['font.size'] = 14
plt.rcParams['figure.figsize'] = (5, 5)
# 为绘图创建一个“颜色”数组
import numpy as np
colors = np.array(['red', 'green', 'blue'])
# 训练数据的散点图,由id着色(0 =红色,1 =绿色,2 =蓝色)
plt.scatter(train.mass, train.rings, c=colors[train.id], s=50)
# 测试数据
plt.scatter(test.mass, test.rings, c='white', s=50)
# 添加标签
plt.xlabel('mass')
plt.ylabel('rings')
plt.title('How we interpret the data')
# 调整x限制
plt.scatter(train.mass, train.rings, c=colors[train.id], s=50)
plt.scatter(test.mass, test.rings, c='white', s=50)
plt.xlabel('mass')
plt.ylabel('rings')
plt.title('How KNN interprets the data')
plt.xlim(0, 30)
### StandardScaler如何解决问题?
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
# 原始值
X.values
# 标准化价值
X_scaled
# 弄清楚它是如何标准化的
print scaler.mean_
print scaler.scale_
#手动标准化
(X.values - scaler.mean_) / scaler.scale_
###将StandardScaler应用于真实的数据集
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data';;
col_names = ['label', 'color', 'proline']
wine = pd.read_csv(url, header=None, names=col_names, usecols=[0, 10, 13])
wine.head()
wine.describe()
# define X and y
feature_cols = ['color', 'proline']
X = wine[feature_cols]
y = wine.label
# 分成训练和测试集
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
# 标准化X_train
scaler.fit(X_train)
X_train_scaled = scaler.transform(X_train)
# 检查它是否正确标准化
print X_train_scaled[:, 0].mean()
print X_train_scaled[:, 0].std()
print X_train_scaled[:, 1].mean()
print X_train_scaled[:, 1].std()
#规范X_test
X_test_scaled = scaler.transform(X_test)
# 这是正确的吗?
print X_test_scaled[:, 0].mean()
print X_test_scaled[:, 0].std()
print X_test_scaled[:, 1].mean()
print X_test_scaled[:, 1].std()
# KNN对原始数据的准确性
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)
y_pred_class = knn.predict(X_test)
from sklearn import metrics
print metrics.accuracy_score(y_test, y_pred_class)
# KNN在缩放数据上的准确性
knn.fit(X_train_scaled, y_train)
y_pred_class = knn.predict(X_test_scaled)
print metrics.accuracy_score(y_test, y_pred_class)
# define X and y
feature_cols = ['color', 'proline']
X = wine[feature_cols]
y = wine.label
#对原始(未缩放的)数据进行适当的交叉验证
knn = KNeighborsClassifier(n_neighbors=3)
from sklearn.cross_validation import cross_val_score
cross_val_score(knn, X, y, cv=5, scoring='accuracy').mean()
# 为什么在缩放的数据上这个不正确的交叉验证?
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
cross_val_score(knn, X_scaled, y, cv=5, scoring='accuracy').mean()
#使用管道修复交叉验证过程
from sklearn.pipeline import make_pipeline
pipe = make_pipeline(StandardScaler(), KNeighborsClassifier(n_neighbors=3))
cross_val_score(pipe, X, y, cv=5, scoring='accuracy').mean()
#使用GridSearchCV搜索最佳的n_neighbors值
neighbors_range = range(1, 21)
param_grid = dict(kneighborsclassifier__n_neighbors=neighbors_range)
from sklearn.grid_search import GridSearchCV
grid = GridSearchCV(pipe, param_grid, cv=5, scoring='accuracy')
grid.fit(X, y)
print grid.best_score_
print grid.best_params_
第十一课、集群
#1. K-均值聚类
#2.集群评估
#3. DBSCAN集群
# 啤酒数据集
import pandas as pd
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/beer.txt';;
beer = pd.read_csv(url, sep=' ')
beer
# 你将如何聚集这些啤酒?
# define X
X = beer.drop('name', axis=1)
##第一部分:K均值聚类
#有3个集群的K-means
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, random_state=1)
km.fit(X)
# 查看集群标签
km.labels_
# 保存群集标签并按群集排序
beer['cluster'] = km.labels_
beer.sort_values('cluster')
# 审查集群中心
km.cluster_centers_
# 计算每个群集的每个特征的平均值
beer.groupby('cluster').mean()
# 保存集群中心的DataFrame
centers = beer.groupby('cluster').mean()
import matplotlib.pyplot as plt
plt.rcParams['font.size'] = 14
#为绘图创建一个“颜色”数组
import numpy as np
colors = np.array(['red', 'green', 'blue', 'yellow'])
#卡路里与酒精的散点图,由簇着色(0 =红色,1 =绿色,2 =蓝色)
plt.scatter(beer.calories, beer.alcohol, c=colors[beer.cluster], s=50)
# 由“+”标记的聚类中心
plt.scatter(centers.calories, centers.alcohol, linewidths=3, marker='+', s=300, c='black')
# 添加标签
plt.xlabel('calories')
plt.ylabel('alcohol')
# 散点图矩阵(0 =红色,1 =绿色,2 =蓝色)
pd.scatter_matrix(X, c=colors[beer.cluster], figsize=(10,10), s=100)
# ### 重复缩放数据
# 中心和缩放数据
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# K-means在缩放数据上具有3个群集
km = KMeans(n_clusters=3, random_state=1)
km.fit(X_scaled)
# 保存群集标签并按群集排序
beer['cluster'] = km.labels_
beer.sort_values('cluster')
# 审查集群中心
beer.groupby('cluster').mean()
# (0 =红色,1 =绿色,2 =蓝色)的散点图矩阵
pd.scatter_matrix(X, c=colors[beer.cluster], figsize=(10,10), s=100)
##第二部分:聚类评估
# 计算SC为K = 3
from sklearn import metrics
metrics.silhouette_score(X_scaled, km.labels_)
# 计算K = 2到K = 19的SC
k_range = range(2, 20)
scores = []
for k in k_range:
km = KMeans(n_clusters=k, random_state=1)
km.fit(X_scaled)
scores.append(metrics.silhouette_score(X_scaled, km.labels_))
#绘制结果
plt.plot(k_range, scores)
plt.xlabel('Number of clusters')
plt.ylabel('Silhouette Coefficient')
plt.grid(True)
# K-means在缩放数据上具有4个群集
km = KMeans(n_clusters=4, random_state=1)
km.fit(X_scaled)
beer['cluster'] = km.labels_
beer.sort_values('cluster')
##第3部分:DBSCAN聚类
#DBSCAN,eps = 1和min_samples = 3
from sklearn.cluster import DBSCAN
db = DBSCAN(eps=1, min_samples=3)
db.fit(X_scaled)
# 查看集群标签
db.labels_
# 保存群集标签并按群集排序
beer['cluster'] = db.labels_
beer.sort_values('cluster')
# 审查集群中心
beer.groupby('cluster').mean()
# DBSCAN聚类分配的散点图矩阵(0 =红色,1 =绿色,2 =蓝色,-1 =黄色)
pd.scatter_matrix(X, c=colors[beer.cluster], figsize=(10,10), s=100)
第十二课、正则化线性模型
# 正则化
# 1.过度配合(复习)
# 2.过度拟合线性模型
# 3.线性模型的正则化
# 4.在scikit-learn中正则化回归
# 5. scikit-learn中的规范化分类
# 6.将正则化的线性模型与非正则化的线性模型进行比较
# ###加载并准备犯罪数据集
import pandas as pd
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/communities/communities.data';;
crime = pd.read_csv(url, header=None, na_values=['?'])
crime.head()
# 检查响应变量
crime[127].describe()
# 删除分类功能
crime.drop([0, 1, 2, 3, 4], axis=1, inplace=True)
# 删除任何缺少值的行
crime.dropna(inplace=True)
# 检查形状
crime.shape
# 定义X和y
X = crime.drop(127, axis=1)
y = crime[127]
# 分成训练和测试集
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
####线性回归
#建立一个线性回归模型
from sklearn.linear_model import LinearRegression
linreg = LinearRegression()
linreg.fit(X_train, y_train)
# 检查系数
print linreg.coef_
#作出预测
y_pred = linreg.predict(X_test)
# 计算RMSE
from sklearn import metrics
import numpy as np
print np.sqrt(metrics.mean_squared_error(y_test, y_pred))
###岭回归
from sklearn.linear_model import Ridge
ridgereg = Ridge(alpha=0, normalize=True)
ridgereg.fit(X_train, y_train)
y_pred = ridgereg.predict(X_test)
print np.sqrt(metrics.mean_squared_error(y_test, y_pred))
# try alpha=0.1
ridgereg = Ridge(alpha=0.1, normalize=True)
ridgereg.fit(X_train, y_train)
y_pred = ridgereg.predict(X_test)
print np.sqrt(metrics.mean_squared_error(y_test, y_pred))
# 检查系数
print ridgereg.coef_
# 创建一个alpha值的数组
alpha_range = 10.**np.arange(-2, 3)
alpha_range
# 用RidgeCV选择最好的alpha
from sklearn.linear_model import RidgeCV
ridgeregcv = RidgeCV(alphas=alpha_range, normalize=True, scoring='mean_squared_error')
ridgeregcv.fit(X_train, y_train)
ridgeregcv.alpha_
# 预测方法使用最佳的alpha值
y_pred = ridgeregcv.predict(X_test)
print np.sqrt(metrics.mean_squared_error(y_test, y_pred))
### Lasso回归
# try alpha=0.001 and examine coefficients
from sklearn.linear_model import Lasso
lassoreg = Lasso(alpha=0.001, normalize=True)
lassoreg.fit(X_train, y_train)
print lassoreg.coef_
# 尝试α= 0.01并检查系数
lassoreg = Lasso(alpha=0.01, normalize=True)
lassoreg.fit(X_train, y_train)
print lassoreg.coef_
# 计算RMSE(对于α= 0.01)
y_pred = lassoreg.predict(X_test)
print np.sqrt(metrics.mean_squared_error(y_test, y_pred))
# 用LassoCV选择最好的alpha
from sklearn.linear_model import LassoCV
lassoregcv = LassoCV(n_alphas=100, normalize=True, random_state=1)
lassoregcv.fit(X_train, y_train)
lassoregcv.alpha_
# 检查系数
print lassoregcv.coef_
# 预测方法使用最佳的alpha值
y_pred = lassoregcv.predict(X_test)
print np.sqrt(metrics.mean_squared_error(y_test, y_pred))
##第五部分:scikit-learn中的规范化分类
# read in the dataset
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data';;
wine = pd.read_csv(url, header=None)
wine.head()
#检查响应变量
wine[0].value_counts()
# define X and y
X = wine.drop(0, axis=1)
y = wine[0]
#分成训练和测试集
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
###逻辑回归(非正规化)
# 建立逻辑回归模型
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(C=1e9)
logreg.fit(X_train, y_train)
# 检查系数
print logreg.coef_
# 生成预测概率
y_pred_prob = logreg.predict_proba(X_test)
print y_pred_prob
# 计算对数损失
print metrics.log_loss(y_test, y_pred_prob)
# ###逻辑回归(正则化)
# 标准化X_train和X_test
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 尝试C = 0.1与L1罚款
logreg = LogisticRegression(C=0.1, penalty='l1')
logreg.fit(X_train_scaled, y_train)
print logreg.coef_
# 生成预测概率并计算对数损失
y_pred_prob = logreg.predict_proba(X_test_scaled)
print metrics.log_loss(y_test, y_pred_prob)
# 尝试C = 0.1与二级惩罚
logreg = LogisticRegression(C=0.1, penalty='l2')
logreg.fit(X_train_scaled, y_train)
print logreg.coef_
# 生成预测概率并计算对数损失
y_pred_prob = logreg.predict_proba(X_test_scaled)
print metrics.log_loss(y_test, y_pred_prob)
#StandardScaler和LogisticRegression的管道
from sklearn.pipeline import make_pipeline
pipe = make_pipeline(StandardScaler(), LogisticRegression())
# 网格搜索C和惩罚的最佳组合
from sklearn.grid_search import GridSearchCV
C_range = 10.**np.arange(-2, 3)
penalty_options = ['l1', 'l2']
param_grid = dict(logisticregression__C=C_range, logisticregression__penalty=penalty_options)
grid = GridSearchCV(pipe, param_grid, cv=10, scoring='neg_log_loss')
grid.fit(X, y)
# 打印所有日志丢失分数
grid.grid_scores_
# 检查最好的模型
print grid.best_score_
print grid.best_params_
###第6部分:比较正规化的线性模型与未经调整的线性模型
# **正则化线性模型的优点:**
# - 更好的性能
# L1正则化执行自动特征选择
# - 用于高维问题(p> n)
# **正则化线性模型的缺点:**
# - 调整是必需的
# - 推荐功能缩放
# - 较少可解释(由于功能缩放)