机器学习
pytorch
import torch.nn as nn
import numpy as np
import time
starttime = time.time()
x_values = [i for i in range(11000000)]
x_train = np.array(x_values, dtype=np.float32)
x_train = x_train.reshape(-1, 1)
y_values = [2 * i + 1 for i in x_values]
y_train = np.array(y_values, dtype=np.float32)
y_train = y_train.reshape(-1, 1)
class LinearRegressionModel(nn.Module):
def __init__(self, input_dim, output_dim):
super(LinearRegressionModel, self).__init__()
self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x):
out = self.linear(x)
return out
input_dim = 1
output_dim = 1
model = LinearRegressionModel(input_dim, output_dim)
print(model)
epochs = 1000
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# device = "cpu"
print(device)
model.to(device)
criterion = nn.MSELoss()
for epoch in range(epochs):
epoch += 1
inputs = torch.from_numpy(x_train).to(device)
labels = torch.from_numpy(y_train).to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if epoch % 50 == 0:
print("epoch{},loss{}".format(epoch, loss.item()))
endtime = time.time()
estime = endtime - starttime
print(estime)
# predicted = model(torch.from_numpy(x_train).requires_grad_()).data.numpy()
# print(predicted)
# 模型存储和读取
# torch.save(model.state_dict(),'model.pkl')
#
# model.load_state_dict(torch.load('model.pkl'))
sklearn
分类树
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
import pandas as pd
import graphviz
import os
os.environ['PATH'] = os.pathsep + r'D:\Program Files\Graphviz\bin'
# sklearn 不接受任何一维矩阵作为特征矩阵被输入,如果你的数据确实只有一个特征,那就必须用reshape(-1,1)来给矩阵增维。
wine = load_wine()
# cc = pd.concat([pd.DataFrame(wine.data), pd.DataFrame(wine.target)], axis=1)
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data
, wine.target
, test_size=0.3
, shuffle=False
)
# 分类树
clf = tree.DecisionTreeClassifier(
# 用来决定不纯度的计算方法的,sk提供两个选择,entropy(信息熵)和gini(基尼系数),如果不填,默认gini,信息熵对不纯度更敏感,所以生长出来的树更精细,对于高维数据或者噪音很多的数据,信息熵很容易过拟合,这时要选择gini,当决策树拟合度不够的时候,要选择信息熵entropy。
criterion="entropy"
# 用来设置分枝中的随机模式的参数,默认是None,在高维度时随机性会表现更明显,低维度数据随机性几乎不会显现。
, random_state=0
# 用来控制决策树中的随机选项,有两种输入值best和random。best在决策树分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝,random分枝时更加随机,树会更深,对训练集的拟合将会降低。也是防止过拟合的一种方式。
, splitter="random"
# 限制树的最大深度,超过设定深度的树枝全部减掉。
, max_depth=3
# 跟max_depth异曲同工,限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。方法比较暴力,一般不推荐使用,因为在不了解决策树中的各个特征的重要性的情况下,强行设定这个参数可能会导致模型学习不足。如果希望通过降维方式防止过拟合,建议使用PCA,ICA或者特征模块中的降维算法。
, max_features=5
# 限制信息增益的大小,信息增益就是父节点和子节点信息熵的差,信息增益小于设定数值的分枝不会发生。
, min_impurity_decrease=0.001
# 一个节点在分枝后的每个子节点都必须包含至少这么多个训练样本,否则就不会发生,或者,分枝会朝着满足每个子节点都包含这么多个样本的方向去发生。
, min_samples_leaf=10
# 一个节点必须要包含至少这么多个训练样本,这个节点才允许被分枝,否则分枝就不会发生。
, min_samples_split=50
# 完成样本标签平衡的参数。在我们需要有偏向的研究某个事物,比如1%信用卡会违约的人群,可以给少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。默认是None,可以自己给少数分配更多的权重
# , class_weight=None
# 设置了上述权重属性后,样本量就不再单纯地记录数目,而是受输入的权重的影响,此时剪枝就需要搭配这个基于权重的剪枝参数来使用。基于权重的剪枝参数将比不知道样本权重的标准(min_samples_leaf)更少偏向主导类。如果样本是加权的,则使用基于权重的预修剪标准来更容易优化树结构,这确保叶节点至少包含样本权重的总和的一小部分。
# , min_weight_fraction_leaf=1
)
# 训练
clf = clf.fit(Xtrain, Ytrain)
# 打分
scoret = clf.score(Xtest, Ytest)
scoretr = clf.score(Xtrain, Ytrain)
dot_data = tree.export_graphviz(clf, feature_names=wine.feature_names, class_names=wine.target_names, filled=True,
rounded=True)
graph = graphviz.Source(dot_data)
# fi = clf.feature_importances_
# print(fi)
print(scoret)
print(scoretr)
graph.view()
# graph.render('_tree')
# apply返回每个测试样本所在的叶子节点的索引
clf.apply(Xtest)
# 返回每个测试样本的分类/回归结果
clf.predict(Xtest)
回归树
from sklearn.datasets import load_wine
from sklearn.model_selection import cross_val_score
from sklearn.tree import DecisionTreeRegressor
boston = load_wine()
"""
criterion回归树衡量分支质量的指标,有三种标准,mse使用均方误差,父节点和叶子节点之间的均方误差的差额来选择标准,这种方法通过使用叶子节点的均值来最小化L2损失。
friedman_mse使用费尔德曼均方误差,这种指标使用弗里德曼针对潜在分枝中的问题改进后的均方误差
mae使用绝对平均误差使用叶节点的中值来最小化L1损失。
"""
regressor = DecisionTreeRegressor(random_state=0)
"""
regressor可以是任何实例化后的模型,如向量机,随机森林等
data为完整数据,不需要划分训练集和测试集,函数会自动把数据划分为cv份,然后用1/cv作为测试集,最后返回一个交叉验证后的结果
"""
cvs = cross_val_score(regressor, boston.data, boston.target, cv=10
# 使用(负)均方误差来评判模型,结果越接近0越好,如果不加这个参数,则用R方来衡量结果。R方=1-残差平方和/总平方和,R方可正可负,接近1最好,最小负无穷
, scoring="neg_mean_squared_error"
)
# 以上为回归树的参数解释,其余没写的跟分类树一样,还有一个交叉验证的写法
# 以下是一个正弦函数的回归拟合验证的例子,(节点深度太大容易过拟合)
import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
# 随机数种子
rng = np.random.RandomState(1)
# 生成0-5的随机数,排序方向是0
X = np.sort(5 * rng.rand(80, 1), axis=0)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - rng.rand(16))
plt.figure()
plt.scatter(X, y, s=20, edgecolors="black", c="darkorange", label="data")
plt.show()
# np.random.rand()生成随机数组的函数
# 了解降维函数ravel()的用法。
# np.random.random((2,1))
# np.random.random((2,1)).ravel()
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)
from sklearn import tree
import graphviz
import os
os.environ['PATH'] = os.pathsep + r'D:\Program Files\Graphviz\bin'
dot_data = tree.export_graphviz(regr_2, feature_names=["Xvalue"], class_names=["Xv"], filled=True,
rounded=True)
graph = graphviz.Source(dot_data)
graph.view()
# 生成序列,然后升维
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
plt.figure()
plt.scatter(X, y, s=20, edgecolors="black", c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue", label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()
随机森林分类器
# %matplotlib inline
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
wine = load_wine()
Xtrain,Xtest,Ytrain,Ytest = train_test_split(wine.data,wine.target,test_size=0.3)
rfc = RandomForestClassifier(
# n_estimators森林中树木的数量,即基评估器的数量。
n_estimators=25
, random_state=0
# bootstrap 有放回的随机抽样技术,默认是True,通常我们不会把他设置成False
, bootstrap=True
# 自助集通常只包含63%的原始数据,有37%的数据没有被取到,所以,可以直接用袋外数据进行测试,在实际操作中,可以不用分训练集和测试集,然后把所有完整数据传入训练,在训练完成后,调用rfc.oob_score_来获取袋外数据的分数
, oob_score=True
)
rfc = rfc.fit(Xtrain,Ytrain)
score_r = rfc.score(Xtest,Ytest)
print(score_r)
# 查看森林中的所有树
print(rfc.estimators_)
# 袋外数据的分数
print(rfc.oob_score_)
# 返回特征重要性数值,数值越大,越重要
print(rfc.feature_importances_)
# apply返回每个测试样本在每一棵树中所在的叶子节点的索引
print(rfc.apply(Xtest))
print(len(Xtest))
# 返回每个测试样本的分类/回归结果
print(len(rfc.predict(Xtest)))
# 返回每个测试样本对应的被分到每一类标签的概率,标签有几个就返回价格概率。
# sklearn中的随机森林每个样本对应的predict_proba返回的概率得到一个平均概率,从而决定测试样本的分类,而不是传统决策树的平均和众数方法决定分类
rfc.predict_proba(Xtest)
随机森林回归器
import pandas as pd
from sklearn.datasets import load_wine
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestRegressor
import sklearn
boston = load_wine()
regressor = RandomForestRegressor(n_estimators=100, random_state=0)
cvs = cross_val_score(regressor, boston.data, boston.target, cv=10
# 使用(负)均方误差来评判模型,结果越接近0越好,如果不加这个参数,则用R方来衡量结果。R方=1-残差平方和/总平方和,R方可正可负,接近1最好,最小负无穷
, scoring="neg_mean_squared_error"
)
# sklearn 当中的模型评估指标(打分)列表
sorted(sklearn.metrics.SCORERS.keys())
# 用来填补缺失值的方法
sklearn.impute.SimpleImputer
from sklearn.impute import SimpleImputer
import numpy as np
imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean')
# imp_0 = SimpleImputer(missing_values=np.nan, strategy="constant", fill_value=0)
X_missing_mean = imp_mean.fit_transform(boston.data)
res = pd.DataFrame(X_missing_mean).isnull().sum()
print(res)
参数调整
import numpy as np
from sklearn.tree import DecisionTreeClassifier
# 网格搜索
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.datasets import load_wine
wine = load_wine()
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data
, wine.target
, test_size=0.3
, shuffle=False
)
gini_threholds = np.linspace(0, 0.5, 50)
entropy_threholds = np.linspace(0, 1, 50)
# 网格搜索
parameters = {
"criterion": ("gini", "entropy")
, "splitter": ("best", "random")
, "max_depth": [*range(1, 10)]
, "min_samples_leaf": [*range(1, 50, 5)]
, "min_impurity_decrease": [*np.linspace(0, 0.5, 50)]
}
########网格搜索需要时打开###################
# clf = DecisionTreeClassifier(random_state=0)
# GS = GridSearchCV(clf, parameters, cv=10)
# GS = GS.fit(Xtrain, Ytrain)
############################
# 从我们输入的参数和参数取值的列表中,返回最佳组合
# GS.best_params_
# 网格搜索后的模型的评判标准
# GS.best_score_
"""
# 随机森林调参影响程度
n_estimators 提升至平稳,不影响单个模型的复杂度 4星
max_depth 有增有减,默认最大深度,向复杂度降低的方向调参 3星
min_samples_leaf 有增有减,默认最小限制1,向复杂度降低的方向调参 2星
min_samples_split 有增有减,默认最小限制2,向复杂度降低的方向调参 2星
max_features 有增有减,默认auto,用最大特征量的开平方,位于中间复杂度,既可以向复杂度升高的方向,也可以向复杂度降低的方向调参,调参时注意方向 1星
criterion 有增有减,一般使用gini,看具体情况。
"""
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
data = load_breast_cancer()
rfc = RandomForestClassifier(n_estimators=100, random_state=20)
score_pre = cross_val_score(rfc, data.data, data.target, cv=10).mean() # , scoring="accuracy"
print(score_pre)