二叉树的博客

Python加速科学运算的一些小技巧

原地操作

使用

1
2
3
4
a = 1
b = 1
a += b
print(a) # 结果是2

而不是使用

1
a = a + b

好处是内存不会复制扩展,只使用a和b的内存运算

1
2
3
4
import numpy as np
X = np.arange(12).reshape(3, 4)
Y = np.array([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
np.concatenate([X, Y], axis=0), np.concatenate([X, Y], axis=1)

检测内存是否一致,在下面的例子中,用Python的id()函数演示了这一点,它提供了内存中引用对象的确切地址。运行Y = Y + X后,会发现id(Y)指向另一个位置。这是因为Python首先计算Y + X,为结果分配新的内存,然后使Y指向内存中的这个新位置。

通过GCN生成概率图引导树搜索解决图的组合优化问题

前言

老板下指示复现两篇文章,这是其中一篇

https://arxiv.org/pdf/1810.10659.pdf

文章的原理什么的已经大致明白了但仍然有小部分不懂,故而做下记录,以备后续复现或深入了解

原始数据

Training Data

https://www.cs.ubc.ca/~hoos/SATLIB/benchm.html

Testing Data

SAT Competition 2017

https://helda.helsinki.fi/bitstream/handle/10138/224324/sc2017-proceedings.pdf

深度学习环境安装(李沐老师相关)

由于之前有写过一键安装jupyter的shell脚本,所以这里只需要找一个服务器就够了

https://github.com/spiritLHLS/one-click-installation-script#%E4%B8%80%E9%94%AE%E5%AE%89%E8%A3%85jupyter%E7%8E%AF%E5%A2%83

1
curl -L https://raw.githubusercontent.com/spiritLHLS/one-click-installation-script/main/install_scripts/jupyter.sh -o jupyter.sh && chmod +x jupyter.sh && bash jupyter.sh

又由于之前玩Linux积攒了很多机器,找了一台腾讯云广州的4C3C80G和OVH法国的4C2C25G的机器测试了一下

共享D盘给同一局域网下的其他电脑(WiFi)

要通过WiFi共享D盘给其他电脑,可以使用以下方法:

1.创建共享文件夹:首先,需要在D盘上创建一个共享文件夹。右键单击D盘上的文件夹,选择"属性",然后切换到"共享"选项卡。点击"高级共享",勾选"共享此文件夹"选项,并为文件夹指定一个共享名称。(或者直接就右键D盘,打开属性)

一键安装PVE并一键开设KVM虚拟化的NAT服务器-带内外网端口转发

PVE

感谢 Proxmox VE 的免费订阅支持

原始仓库:https://github.com/spiritLHLS/pve

说明文档

国内(China):

virt.spiritlhl.net

国际(Global):

www.spiritlhl.net

说明文档中 Proxmox VE 分区内容

https://github.com/oneclickvirt/kvm_images 为对应虚拟机镜像仓库

前言

国内服务器请使用国内命令,国际服务器请使用国际命令

近期码代码的个人心得

近期码代码的个人心得

  1. 尊重他人命运,放弃助人情节,帮得了一次往往意味着帮无数次

  2. 不要让不懂行的人改你的代码,改了最好别再接手代码,往往写的越来越屎,接手了意味着有锅的话你得背,很难辨清

关于手写数字识别的特征工程

只给出个人完成的代码部分与一些简单的结果和说明

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.neighbors import KNeighborsClassifier as KNN
from sklearn.model_selection import cross_val_score
from sklearn import datasets, decomposition,manifold
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import time
import warnings


plt.rcParams['font.family'] = 'SimHei'     ### # matplotlib其实是不支持显示中文的 显示中文需要一行代码设置字体
plt.rcParams['axes.unicode_minus'] = False
warnings.filterwarnings ('ignore')  ### 忽略版本警告
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# # 读取并查看数据
# data = pd.read_csv(r"digit recognizor.csv")
# X = data.iloc[:,1:]
# y = data.iloc[:,0]
# print(X.shape)

#加载数据,显示数据
digits = datasets.load_digits()
X = digits.data
y = digits.target
print (X.shape,y.shape)
(1797, 64) (1797,)
1
2
3
4
5
6
7
# 画累计方差贡献率曲线,找最佳降维后维度的范围
pca_line = PCA().fit(X)
plt.figure(figsize=[20,5])
plt.plot(np.cumsum(pca_line.explained_variance_ratio_))
plt.xlabel("降维后的基组件数量")
plt.ylabel("累计方差贡献率")
plt.show()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#降维后维度的学习曲线,继续缩小最佳维度的范围
time_start = time.time()
score = []
for i in range(1,51):
    X_pca = PCA(i).fit_transform(X)
    once = cross_val_score(RFC(n_estimators=10,random_state=0),X_pca,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(1,51),score)
plt.xlabel("降维后的基组件数量")
plt.ylabel("准确率")
plt.show()
time_end = time.time()
time_sum = time_end - time_start
print(time_sum)
12.560771465301514
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#细化学习曲线,找出降维后的最佳维度
score = []
for i in range(10,20):
    X_pca = PCA(i).fit_transform(X)
    once = cross_val_score(RFC(n_estimators=10,random_state=0),X_pca,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.xlabel("降维后的基组件数量")
plt.ylabel("准确率")
plt.plot(range(10,20),score)
plt.show()
1
2
3
#导入找出的最佳维度进行降维,查看模型效果
X_pca = PCA(16).fit_transform(X) # 64 列特征变为 16 列特征
print(cross_val_score(RFC(n_estimators=100,random_state=0),X_pca,y,cv=5).mean()) # 使用随机森林进行交叉验证
0.9282342927886104
1
2
# 使用默认的KNN参数,看到在交叉验证环节使用KNN是否比随机森林好
print(cross_val_score(KNN(),X_pca,y,cv=5).mean()) # 结果是KNN好
0.9593980191891054
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# KNN的K值学习曲线
time_start = time.time()
score = []
for i in range(10):
    X_dr = PCA(16).fit_transform(X)
    once = cross_val_score(KNN(i+1),X_pca,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.xlabel("K值")
plt.ylabel("准确率")
plt.plot(range(1,11),score)
plt.show()
time_end = time.time()
time_sum = time_end - time_start
print(time_sum)
1.1747395992279053
1
2
#K值优化后的交叉验证
print(cross_val_score(KNN(5),X_pca,y,cv=5).mean())
0.9593980191891054
1
##################################################################################################################################
1
# 由之前的实验可知t-SNE在手写数据集上效果良好
1
2
3
4
5
# 默认参数下的t-SNE - n_components 小于4,维度不能超过4
tsne = manifold.TSNE(n_components=3, init='pca', random_state=0, perplexity=10)
X_tsne = tsne.fit_transform(X)
print (X_tsne.shape)
print(cross_val_score(KNN(),X_tsne,y,cv=5).mean())
(1797, 3)
0.972742185082018
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# KNN的K值学习曲线
time_start = time.time()
score = []
for i in range(10):
    once = cross_val_score(KNN(i+1),X_tsne,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.xlabel("K值")
plt.ylabel("准确率")
plt.plot(range(1,11),score)
plt.show()
time_end = time.time()
time_sum = time_end - time_start
print(time_sum)
0.5395219326019287
1
2
#K值优化后的交叉验证
print(cross_val_score(KNN(3),X_tsne,y,cv=5).mean())
0.9766419065304859
1
#############################################################################################################################
1
2
3
4
# 尝试LLE以下使用10作默认的邻居数
clf = manifold.LocallyLinearEmbedding(n_neighbors=10, n_components=2,method='standard')
X_lle = clf.fit_transform(X)
print(cross_val_score(KNN(),X_lle,y,cv=5).mean())
0.9026385020117612
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 画学习曲线,找出降维后的最佳维数和邻居数
# 单线程太慢,下面使用多线程加速
# best_list = [] #(维数,邻居数,交叉验证的准确率)
# for i in range(2,64): # 维数
#     score = []
#     for j in range(3, 20): # 邻居数
#         clf = manifold.LocallyLinearEmbedding(n_neighbors=j, n_components=i,method='standard')
#         X_lle = clf.fit_transform(X)
#         once = cross_val_score(KNN(),X_lle,y,cv=5).mean()
#         score.append(once)
#     best_list.append((i,score.index(max(score)),max(score)))
# print(best_list)
 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
43
44
45
46
47
48
49
50
51
52
53
54
# 多线程参数调优
# 多线程判断求解
import threading
import queue
from tqdm import tqdm

time_start = time.time()
g = queue.Queue()
result_g = queue.Queue()

count = 0
for i in range(2,64): # 维数
    for j in range(3, 20): # 邻居数
        g.put((i,j))
        count += 1

def temp_g():
    while True:
        if g.qsize() != 0:
            elem = g.get()
            i = elem[0]
            j = elem[1]
            clf = manifold.LocallyLinearEmbedding(n_neighbors=j, n_components=i,method='standard')
            X_lle = clf.fit_transform(X)
            once = cross_val_score(KNN(),X_lle,y,cv=5).mean()
            result_g.put((i, j, once))
        else:
            break

threads = []
for i in tqdm(range(g.qsize())):
    t = threading.Thread(target=temp_g)
    threads.append(t)
    t.start()

print('主程序运行中...')

# 等待所有线程任务结束。
for t in threads:
    t.join()

print("所有线程任务完成")

# 栈反解数据列表
result_list = []
for i in range(result_g.qsize()):
    j = result_g.get()
    result_list.append(j)
result_list.sort(key=lambda x:x[2]) # 乱序排序

print(result_list[0:20])
time_end = time.time()
time_sum = time_end - time_start
print(time_sum) # 结果是跑了2054秒,时间成本很高
100%|██████████████████████████████████████████████████████████████████████████████| 1054/1054 [15:30<00:00,  1.13it/s]


主程序运行中...
所有线程任务完成
[(2, 18, 0.6561173011451562), (2, 19, 0.6845017022593625), (2, 17, 0.6895187248529868), (4, 5, 0.714535747446611), (2, 16, 0.7390560198081089), (2, 13, 0.7585267718972454), (2, 14, 0.7612999071494894), (2, 15, 0.7657582791705355), (3, 19, 0.7663030021665118), (3, 17, 0.7724295883627359), (3, 18, 0.7807520891364902), (4, 17, 0.8069204580625193), (4, 19, 0.8130578768183223), (3, 15, 0.8152615289384091), (3, 16, 0.8202940266171463), (2, 9, 0.8391999380996594), (2, 12, 0.8441906530485916), (4, 18, 0.8441999380996595), (3, 14, 0.8458650572578149), (2, 8, 0.8503265242958836)]
2054.643949985504
1
print(result_list[-1]) #最好的参数配置 维数 邻居数 准确率
(18, 6, 0.9771959145775302)
1
2
3
4
#导入找出的最佳邻居数进行降维,查看模型效果
clf = manifold.LocallyLinearEmbedding(n_neighbors=6, n_components=18,method='standard')
X_lle = clf.fit_transform(X)
print(cross_val_score(KNN(),X_lle,y,cv=5).mean()) # 较未调参好了
0.9771959145775302
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# KNN的K值学习曲线
time_start = time.time()
score = []
for i in range(10):
    once = cross_val_score(KNN(i+1),X_lle,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.xlabel("K值")
plt.ylabel("准确率")
plt.plot(range(1,11),score)
plt.show()
time_end = time.time()
time_sum = time_end - time_start
print(time_sum)
1.074317455291748
1
2
#K值优化后的交叉验证
print(cross_val_score(KNN(5),X_lle,y,cv=5).mean())
0.9771959145775302
1
2
3
# 总结,模型优劣:LLE > t-SNE > PCA ,以上为优化后的结果,实际LLE比t-SNE好0.0017,提升不大
# t-SNE维度受限(3维),PCA(16维)和LLE(18维)会比较适合一点,数据集要保留的数据量更大
# 其中LLE为了调成最优时间成本很高(花了2005秒),综合来看PCA会在准确率,数据量以及时间成本上更合适