跳转至

机器学习

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)