让您的数据说话!
使用 matplotlib 和 seaborn 在可视化中从 0 到英雄
Photo by Wynand van Poortvliet on Unsplash
如果TL;博士 : [ Link_To_Note
编辑: 法维奥·巴斯克斯 给这个帖子+4 并回复
“牛逼的文章!恭喜:)”法维奥·巴斯克斯
在推特上!!感谢法维奥·巴斯克斯。
这是我在Tackle
类别的帖子中的一个,可以在我的 github repo 这里找到。此类别的所有帖子:
索引
***NOTE:*** This post goes along with ***Jupyter Notebook*** available in my Repo on Github:[[HowToVisualize](https://nbviewer.jupyter.org/github/PuneetGrov3r/MediumPosts/blob/master/Tackle/HowToVisualize.ipynb)]
1.简介 ^
什么是数据,无非是数字。如果我们不把它形象化来更好地理解它里面的世界,我们就会错过很多东西。也就是说,我们可以把数据理解成数字,但是当你试图把它形象化时,奇迹就发生了。它变得更有意义,突然变得更容易理解。
我们是感性的生物,我们通过感官感知周围的事物。视觉、听觉、嗅觉、味觉和触觉。我们可以在一定程度上根据感官来区分周围的事物。对于数据来说,声音和视觉似乎是表示它的最佳选择,因为它可以很容易地转换。我们大多使用视觉作为感知数据的媒介,因为我们可能习惯于通过这种感觉来区分不同的对象,而且,尽管在较低的层次上,我们也习惯于通过这种感觉来感知更高维度的事物,这在多变量数据集中很方便。
在这篇文章中,我们将探讨 Python 中两个最流行的数据可视化库,并使用它们通过可视化让数据说话:
1.1 Matplotlib
Matplotlib 保持了 MATLAB 的绘图风格,尽管它也有一个面向对象的接口。
- *MATLAB 风格接口:*从 matplotlib 库中导入
pyplot
即可使用,使用类似 MATLAB 的函数。
使用该界面时,方法将自动选择当前图形和轴来显示绘图。在您使用pyplot.show
方法或在 IPython 中执行您的单元之前,它将一直如此(也就是说,对于您的所有方法调用,这个当前数字将被一次又一次地选择)。
2.*面向对象接口:*可以这样用:
import matplotlib.pyplot as pltfigure, axes = **plt**.subplots(2) # for 2 subplots# Now you can configure your plot by using
# functions available for these objects.
这是一个低级的库,你可以完全控制你的地块。
1.2 Seaborn
Seaborn 是一个基于 matplotlib 的高级可视化库。它主要用于制作快速和有吸引力的情节,而没有太多的麻烦。虽然 seaborn 试图以一种奇特的方式控制你的情节,但你仍然不能从中获得你想要的一切。为此,你必须使用 matplotlib 的功能,你也可以使用 seaborn(因为它是建立在 matplotlib 之上的)。
2.分布图 ^
Photo by Daniel Leone on Unsplash
分布图告诉我们一个变量是如何分布的。它给了我们在特定范围内找到变量的概率。也就是说,如果我们从一个变量的总范围内随机选择一个数字,它会给出这个变量在不同范围内的概率。
分布图应Normally
分布,以获得更好的结果。这是所有线性模型的假设之一,即正态性。Normal distribution
看起来像一个中间有光尾巴的中等驼峰。
**Note:** If **TL;DR** (Too Long; Don’t wanna Read), just read initial function used to plot the sub-topic plot and then read through **Tips**. You can easily navigate through tips using **<** and **>** buttons.
Eg: here Tips #1 and plt.hist, below.
(:Tips # 1:)> **1)**在大多数情况下,您可以使用
matplotlib.pyplot
函数为您的绘图提供的参数。请务必查看函数的参数及其描述。
2) 所有matplotlib
的函数甚至seaborn
的函数都返回你的图在字典、列表或对象中的所有组成部分。从那里你也可以改变你的组件的任何属性(用matplotlib
的语言Artist
s)。
箱形图和小提琴图在分类部分中。
- 直方图和核密度估计图(kde):
# Simple hist plot
_ = **plt**.hist(train_df['target'], bins=5, edgecolors='white')
# with seaborn
_ = **sns**.distplot(train_df['target'])
(:Tips # 2:)<**> **3)为了给你的剧情提供一些有用的信息或者引起对剧情中某些东西的注意,你大多可以用
plt.text()
或者plt.annotate()
逃脱。4) 绘图最需要的参数是
*label*
,绘图最需要的方法是*plt.xlabel*
、*plt.ylabel*
、*plt.title*
、*plt.legend*
。为了有效地传达你的信息,你应该从你的图中移除所有不想要的干扰,比如右轴和顶轴,以及你的图中任何其他不想要的结构。
import matplotlib.pyplot as plt_ = **plt**.hist(data, bins=10, color='lightblue',
label=lbl, density=True, ec='white')
**plt**.legend()
**plt**.title("Target variable distribution", fontdict={'fontsize': 19,
'fontweight':0.5 }, pad=15)
**plt**.xlabel("Target Bins")
**plt**.ylabel("Probability");
****
— — — — — — — — — — — — -
import matplotlib.pyplot as plt
from SWMat.SWMat import SWMat**swm** = SWMat(plt) # Initialize your plot**swm**.hist(data, bins=10, ***highlight***=[2, 9])
**swm**.title("Carefully looking at the dependent variable revealed
some problems that might occur!")
**swm**.text("Target is a bi-model dependent feature.\nIt
can be <prop fontsize='18' color='blue'> hard to
predict.<\prop>");**#** **Thats all!** And look at your plot!!
1) Normal Matplotlib, 2) Seaborn, 3) Matplotlib Power, 4) Storytelling With Matplotlib
3.关系图 ^
Photo by Vincent van Zalinge on Unsplash
关系图对于获取两个或多个变量之间的关系非常有用。这些关系可以帮助我们更好地理解我们的数据,并可能帮助我们从现有的变量中产生新的变量。
这是Data Exploration
和Feature Engineering
中的重要一步。
a)线条图: ^
线图对于检查两个变量之间的线性关系,甚至二次关系、指数关系和所有此类关系非常有用。
5) 你可以通过使用参数’
color
’ / ’c
’,'alpha
,'edgecolors
’ / ’edgecolor
’来给你的剧情一个美学的外观。6)
Seaborn
在它的大多数绘图方法中都有一个参数“hue
”,您可以用它来显示这些图中分类变量的不同类别之间的对比。你应该用较浅的颜色来画出你想画的部分,但它们不是你想画的重点。
****plt**.plot('AveRooms', 'AveBedrms', data=data,
label="Average Bedrooms")**plt**.legend() # To show label of y-axis variable inside plot
**plt**.title("Average Rooms vs Average Bedrooms")
**plt**.xlabel("Avg Rooms ->")
**plt**.ylabel("Avg BedRooms ->");**
您也可以像这样手动对它们进行颜色编码:
****plt**.plot('AveRooms', 'AveBedrms', data=data, c='lightgreen')
**plt**.plot('AveRooms', 'AveBedrms', data=data[(data['AveRooms']>20)],
c='y', alpha=0.7)
**plt**.plot('AveRooms', 'AveBedrms', data=data[(data['AveRooms']>50)],
c='r', alpha=0.7)**plt**.title("Average Rooms vs Average Bedrooms")
**plt**.xlabel("Avg Rooms ->")
**plt**.ylabel("Avg BedRooms ->");**
**# with seaborn
_ = **sns**.lineplot(x='AveRooms', y='AveBedrms', data=train_df)**
********
— — — — — — — — — — — — -
****swm** = SWMat(plt)**swm**.line_plot(data_x, data_y, line_labels=[line_lbl], highlight=0,
***label_points_after***=60, xlabel=xlbl, point_label_dist=0.9,
***highlight_label_region_only***=True)
**swm**.title("There are some possible outliers in 'AveRooms' and
'AveBedrms'!", ttype="title+")
**swm**.text("This may affect our results. We should\ncarefully
look into these and <prop color='blue'>finda\n
possible resolution.<\prop>",
position="out-mid-right", fontsize=20,
btw_line_dist=2.2);# '**point_label_dist**' (to adjust distance between points' labels and
# lines) in `.line_plot` method and '**btw_line_dist**' (to adjust lines
# between two lines in text) in `.text` method are only used when
# result given by library is not what you want. Most of the times
# this library tries to give the right format, but still some
# mistakes can happen. I will try to make it fully automatic in
# future.**
1) Normal Matplotlib, 2) Seaborn, 3) Matplotlib Power, 4) Storytelling With Matplotlib
b)散点图: ^
并非两个变量之间的每一种关系都是线性的,实际上只有少数是线性的。这些变量中也有一些随机成分,这使得它们几乎是线性的,而其他情况下有一种完全不同的关系,我们很难用线性图来显示。
此外,如果我们有很多数据点,散点图可以方便地检查大多数数据点是否集中在一个区域,是否有任何异常值 w.r.t .这两个或三个变量,等等。
如果我们对 3D 图中的第四个变量进行颜色编码,我们可以绘制两个或三个甚至四个变量的散点图。
7) 你可以用两种方式设置你的地块的大小。您可以从
matplotlib
中导入figure
并使用类似于:figure(figsize=(width, height))
{它将为当前图形设置该图形大小}的方法,或者您可以在使用类似于figure, plots = plt.subplots(rows, cols, figsize=(x,y))
的面向对象接口时直接指定figsize
。当你试图用数据传达信息时,你应该简明扼要。
**from matplotlib.pyplot import figure
figure(figsize=(10, 7))**plt**.scatter('AveRooms', 'AveBedrms', data=data,
edgecolors='w', linewidths=0.1)**plt**.title("Scatter Plot of Average Rooms and Average Bedrooms")
**plt**.xlabel("Average Bedrooms ->")
**plt**.ylabel("Average Rooms ->");**
**# With Seaborn
from matplotlib.pyplot import figure
figure(figsize=(10, 7))**sns**.scatterplot(x='AveRooms', y='AveBedrms', data=train_df,
label="Average Bedrooms");**
8) 在
.text
和.annotate
方法中有一个参数bbox
,它使用一个字典来设置文本周围的框的属性。对于bbox
,几乎所有情况下都可以用pad
、edgecolor
、facecolor
、alpha
蒙混过关。9) 在
.annotate
方法中有一个用于设置箭头属性的参数,如果设置了xytext
参数,就可以设置这个参数,它就是arrowprops
。它以一个字典作为参数,你可以用arrowstyle
和color
蒙混过关。10) 你可以使用
matplotlib
的fill_between
或fill_betweenx
来填充两条曲线之间的颜色。这可以方便地突出曲线的某些区域。你应该花时间考虑如何绘制数据,以及哪个特定的图能最大程度地传达你的信息。
**from matplotlib.pyplot import figure
figure(figsize=(10, 7))**plt**.scatter('AveRooms', 'AveBedrms', data=data)
**plt**.plot(train_df['AveRooms'], Y, linewidth=1, color='red',
linestyle='-', alpha=0.8)**plt**.xlabel("Avg Rooms ->")
**plt**.ylabel("Avg BedRooms ->")# Adding annotations:
**plt**.annotate("Possible outliers", xy=(144, 31), xytext=(160, 34),
arrowprops={'arrowstyle':'-[,widthB=4.0', 'color':
'black'},
bbox={'pad':4, 'edgecolor':'orange', 'facecolor':
'orange', 'alpha':0.4})**plt**.annotate("Regression Line", xy=(80, 12), xytext=(120, 3),
arrowprops={'arrowstyle':'->', 'color': 'black',
"connectionstyle":"arc3,rad=-0.2"},
bbox={'pad':4, 'edgecolor':'orange', 'facecolor':
'orange', 'alpha':0.4});**
********
— — — — — — — — — — — — -
****swm** = SWMat(plt)
**plt**.scatter(x, y, edgecolors='w', linewidths=0.3)
**swm**.line_plot(x, *Y*, highlight=0, highlight_color="#000088",
alpha=0.7, line_labels=["Regression Line"])
**swm**.title("'AveBedrms' and 'AveRooms' are highly correlated!",
ttype="title+")
**swm**.text("Taking both of them in regressioin process\nmight not be
necessary. We can either\n<prop color='blue'>take one of
them</prop> or <prop color='blue'>take average.</prop>",
position='out-mid-right', btw_line_dist=5)
**swm**.axis(labels=["Average Rooms", "Average Bedrooms"])# 'SWMat' has an `axis` method with which you can set some Axes
# properties such as 'labels', 'color', etc. directly.**
1) Normal Matplotlib, 2) Seaborn, 3) Matplotlib Power, 4) Storytelling With Matplotlib
c)二维直方图、十六进制图和等高线图: ^
2D 直方图和 Hex 图可用于检查特定位置数据的相对密度。
等值线图可用于绘制 2D 的 3D 数据,或绘制 4D 的 3D 数据。轮廓线(或填充轮廓中的色带)告诉我们函数具有常数值的位置。它让我们熟悉绘图中使用的所有变量。例如,它可以用于绘制深度学习中不同θ的成本函数。但是要做到准确,你需要大量的数据。至于绘制整个景观,你需要该景观中所有点的数据。如果你有一个关于那个景观的函数,你可以很容易地通过手动计算值来绘制这些图。
**from matplotlib.pyplot import figure
figure(figsize=(10, 7))**plt**.hist2d('MedInc', 'target', bins=40, data=train_df)
**plt**.xlabel('Median Income ->')
**plt**.ylabel('Target ->')
**plt**.suptitle("Median Income vs Target", fontsize=18);**
但是seaborn
中没有单独的十六进制绘图/2D-历史绘图方法,您可以使用jointplot
方法的kind
参数来制作十六进制绘图。更多信息请查看seaborn
上的联合图。
一个
colorbar
需要一个Mappable
对象。默认情况下,Contour
、Scatter
和hist2d
等图给出了它们。你可以简单地调用plt.colorbar()
,它会在你的图旁边显示一个colorbar
。对于其他图,如果需要,您可以手动制作一个colorbar
。[在 Jupyter 笔记本的“历史”部分提供了一个例子。]****E】总是尽量选择一个简单的,群众容易理解的情节。
**# Hexbin Plot:
from matplotlib.pyplot import figure
figure(figsize=(10, 7))**plt**.hexbin('MedInc', 'target', data=train_df, alpha=1.0,
cmap="inferno_r")**plt**.margins(0)
**plt**.colorbar()
**plt**.xlabel('Median Income ->')
**plt**.ylabel('Target ->')
**plt**.suptitle("Median Income vs Target", fontsize=18);**
**from matplotlib.pyplot import figure
figure(figsize=(10, 7))
**plt**.hist2d('MedInc', 'target', bins=40, data=train_df,
cmap='gist_heat_r')
**plt**.colorbar()
**plt**.xlabel('Median Income ->')
**plt**.ylabel('Target ->')
**plt**.suptitle("Median Income vs Target", fontsize=18)# Adding annotations:
**plt**.annotate("Most Blocks have low med.\nincome and lower target.",
xy=(5, 1.5), xytext=(10, 2),
arrowprops={'arrowstyle': '->', 'color': 'k'},
bbox={'facecolor': 'orange', 'pad':4, 'alpha': 0.5,
'edgecolor': 'orange'});**
等高线图 : 等高线图是在 2D 图上可视化 3D 数据的一种方式。在matplotlib
中有两种方法可用,即.contour
和.contourf
。第一个制作线条轮廓,第二个制作填充轮廓。您可以传递 z 值的 2D 矩阵,也可以为 X 值和 Y 值传递两个 2D 数组 X,Y,为所有相应的 z 值传递一个 2D 数组。
**# For **contour plot**
from matplotlib.pyplot import figure
figure(figsize=(10, 7))**plt**.contourf(Z, levels=30, cmap="gist_heat_r")
**plt**.colorbar()**plt**.suptitle("Target Contour", fontsize=16)
**plt**.title("(with Medium Income and Population)",
position=(0.6, 1.03))
**plt**.xlabel("Medium Income ->")
**plt**.ylabel("Population ->")**
d)配对图: ^
seaborn
提供了一个方法pairplot
,你可以用它一次绘制出所有可能的关系图。它可以用于快速查看数据中所有变量之间的关系,以及每个变量的分布。
**_ = **sns**.pairplot(train_df)**
4.分类图 ^
Photo by Sharon McCutcheon on Unsplash
分类图在数据探索步骤中也是必要的,因为它们告诉我们不同类别的变量在数据集中是如何分布的。如果我们有足够的数据,我们就可以从这些曲线图中得出该变量不同类别的结论。
因为 *seaborn*
我在这里加了箱子剧情和小提琴剧情。在 *seaborn*
中有一些参数,您可以使用这些参数对不同的分类变量使用这些方法。
a) 条形图
b) 方框图
c) 小提琴剧情
一)条形图 ^
条形图可用于类别之间的对比,其高度代表特定于该类别的某些值。
**from matplotlib.pyplot import figure
figure(figsize=(10, 7))**plt**.bar(np.sort(data.unique()), data.value_counts().sort_index(),
alpha=0.7) **#** You might need to sort; Be carefully with
**#** which values are being plotted with each
**#** other.**plt**.xlabel("Target ->")
**plt**.ylabel("Frequency ->");**
12) 如果在每个
matplotlib
和seaborn
函数的输出中有你想要改变属性的补丁或对象,你可以通过使用.set
函数将属性名作为字符串和属性值传递给它来改变它,或者你可以直接对那个属性使用 set 函数,如set_color
、set_lw
等。有近 8%的男性是色盲,近 1/10 的女性是色盲。但你还是应该小心他们。对比对他们中的大多数人都有效。
**# Seaborn
from matplotlib.pyplot import figure
figure(figsize=(10, 7))**sns**.barplot(np.sort(data.unique()),data.value_counts().sort_index())**plt**.xlabel("Target ->")
**plt**.ylabel("Frequency ->");**
**from matplotlib.pyplot import figure
figure(figsize=(10, 7))**plt**.bar(np.sort(train_df['target_int'].unique()),
train_df['target_int'].value_counts().sort_index(),
alpha=0.7, width=0.6)**plt**.grid(True, alpha=0.3)
**plt**.xlabel("Target ->", fontsize=14)
**plt**.ylabel("Frequency ->", fontsize=14)
**plt**.title("Target Frequencies", fontsize=18)# Remove top and left spines:
ax = **plt**.gca() # Get current axis (gca)
**ax**.spines['right'].set_visible(False)
**ax**.spines['top'].set_visible(False)# Adding annotations:
counts = train_df['target_int'].value_counts().sort_index()
**plt**.annotate(str(counts[0]), xy=(0, counts[0]),
xytext=(0,counts[0]+400), ha = 'center',
bbox={'boxstyle': 'round', 'pad': 0.5, 'facecolor':
'orange', 'edgecolor': 'orange', 'alpha': 0.6},
arrowprops={'arrowstyle':"wedge,tail_width=0.5",
'alpha':0.6, 'color': 'orange'})
**plt**.annotate(str(counts[1]), xy=(1, counts[1]),
xytext=(1, counts[1]+400), ha = 'center',
bbox={'boxstyle': 'round', 'pad': 0.5, 'facecolor':
'orange', 'edgecolor': 'orange', 'alpha': 0.6},
arrowprops={'arrowstyle':"wedge,tail_width=0.5",
'alpha':0.6, 'color': 'orange'})
**plt**.annotate(str(counts[2]), xy=(2, counts[2]),
xytext=(2, counts[2]+400), ha = 'center',
bbox={'boxstyle': 'round', 'pad': 0.5, 'facecolor':
'orange', 'edgecolor': 'orange', 'alpha': 0.6},
arrowprops={'arrowstyle':"wedge,tail_width=0.5",
'alpha':0.6, 'color': 'orange'})
**plt**.annotate(str(counts[3]), xy=(3, counts[3]),
xytext=(3, counts[3]+400), ha = 'center',
bbox={'boxstyle': 'round', 'pad': 0.5, 'facecolor':
'orange', 'edgecolor': 'orange', 'alpha': 0.6},
arrowprops={'arrowstyle':"wedge,tail_width=0.5",
'alpha':0.6, 'color': 'orange'})
**plt**.annotate(str(counts[4]), xy=(4, counts[4]),
xytext=(4, counts[4]+400), ha = 'center',
bbox={'boxstyle': 'round', 'pad': 0.5, 'facecolor':
'orange', 'edgecolor': 'orange', 'alpha': 0.6},
arrowprops={'arrowstyle':"wedge,tail_width=0.5",
'alpha':0.6, 'color': 'orange'})
**plt**.xticks(ticks=[0, 1, 2, 3, 4], labels=["0 - 1", "1 - 2", "2 - 3",
"3 - 4", "4 - 5"], fontsize=12)
**plt**.ylim([0, 9500]);**
********
— — — — — — — — — — — — -
****swm** = SWMat(plt)
**swm**.bar(cats, heights, highlight={"cat": [-1]}, highlight_type=
{"data_type": "incrementalDown"}, cat_labels=["0-1", "1-2",
"2-3", "3-4", "4-5"], highlight_color={"cat_color":
"#FF7700"}, annotate=True)
**swm**.axis(labels=["Target values", "Frequency"])
**swm**.title("About most expensive houses in California...")
**swm**.text("California is a sea-side state. As most\nexpensive houses
are at sea-side we\ncan easily predict these values if
we\nsomehow <prop color='blue'>combine 'Latitude'
and\n'Longitude' variables </prop>and separate sea\nside
houses from non-sea-side houses.",
btw_text_dist=.1);**
1) Normal Matplotlib, 2) Seaborn, 3) Matplotlib Power, 4) Storytelling With Matplotlib
b)方框图 ^
箱线图是分布图的统计版本。它给出了不同的四分位数,平均值和极值的范围。一些可能的用例是,如果某些点超出了盒须线的范围,您可以使用它来识别可以发现异常值的变量,或者您可以通过图中中间盒的相对位置来检查分布中的偏斜。
**from matplotlib.pyplot import figure
figure(figsize=(15, 7))**plt**.boxplot(train_df['target'], vert=False)**plt**.xlabel("<- Target Values ->")
**plt**.ylabel("Target");**
**# With Seaborn:
from matplotlib.pyplot import figure
figure(figsize=(15, 7))sns.boxplot(train_df['MedInc']);**
13) 您可以通过使用
plt.xlim
、plt.ylim
、ax.set_xlim
、ax.set_ylim
功能来改变您的Axes
的 x 极限、y 极限。您还可以通过将plt.margings
或ax.margins
用作plt.margins(x=2, y=-3)
来放大和缩小您的绘图。14) 您可以从
plt.style.available
中为您的图形使用不同的样式,为您的图形赋予不同的外观,并将其激活为plt.style.use(stylename)
。最常用的款式是'fivethirtyeight'
和ggplot
。15)
seaborn
和matplotlib
有许多可用的色彩映射表,可用于设置连续变量图的颜色。你可以在这里找他们,在这里找他们。只突出你想引起观众注意的情节部分,只突出那些部分。
**from matplotlib.pyplot import figure
figure(figsize=(20, 7))bp = **plt**.boxplot([x1, x2], vert=False, patch_artist=True,
flierprops={'alpha':0.6, 'markersize': 6,
'markeredgecolor': '#555555','marker': 'd',
'markerfacecolor': "#555555"},
capprops={'color': '#555555', 'linewidth': 2},
boxprops={'color': '#555555', 'linewidth': 2},
whiskerprops={'color': '#555555', 'linewidth': 2},
medianprops={'color': '#555555', 'linewidth': 2},
meanprops={'color': '#555555', 'linewidth': 2})**plt**.grid(True, alpha=0.6)
**plt**.title("Box Plots", fontsize=18)
**plt**.xlabel("Values ->", fontsize=14)
**plt**.ylabel("Features", fontsize=14)
**plt**.yticks(ticks=[1, 2], labels=['MedInc', 'Target'])bp['boxes'][0].set(facecolor='#727FFF')
bp['boxes'][1].set(facecolor="#97FF67")# Adding Text:
**plt**.text(11, 1.5, "There are many potential\nOutliers with respect
to\nMedian Income", fontsize=18,
bbox={'facecolor': 'orange', 'edgecolor': 'orange',
'alpha': 0.4, 'pad': 8});**
********
— — — — — — — — — — — — —
****swm** = SWMat(plt)
bp = **plt**.boxplot([x1, x2], vert=False, patch_artist=True,
flierprops={'alpha':0.6, 'markersize': 6,
'markeredgecolor': '#555555','marker': 'd',
'markerfacecolor': "#555555"},
capprops={'color': '#555555', 'linewidth': 2},
boxprops={'color': '#555555', 'linewidth': 2},
whiskerprops={'color': '#555555', 'linewidth': 2},
medianprops={'color': '#555555', 'linewidth': 2},
meanprops={'color': '#555555', 'linewidth': 2})
**plt**.xlabel("Values ->", fontsize=14)
**plt**.ylabel("Features", fontsize=14)
**plt**.yticks(ticks=[1, 2], labels=['MedInc', 'Target'])
bp['boxes'][0].set(facecolor='#727FFF')
bp['boxes'][1].set(facecolor="#97FF67");**swm**.title("Many unusual outliers in 'MedInc' variable...")
**swm**.text(("It may be because of acquisition of sea side\n"
"places by very wealthy people. This <prop
color='blue'>aquisition\n"
"by many times greater earners</prop> and yet not much\n"
"number has made box plot like this."),btw_line_dist=.15,
btw_text_dist=.01)**
1) Normal Matplotlib, 2) Seaborn, 3) Matplotlib Power, 4) Storytelling With Matplotlib
c)小提琴剧情 ^
小提琴情节是盒子情节的延伸。它也有均值、极值的指标,也可能有不同的四分位数。除此之外,它还显示了两边变量的概率分布。
**from matplotlib.pyplot import figure
figure(figsize=(10, 7))**plt**.violinplot(train_df['target'])**plt**.title("Target Violin Plot")
**plt**.ylabel("Target values ->");**
**# With Seaborn
from matplotlib.pyplot import figure
figure(figsize=(10, 7))**sns**.violinplot(train_df['target']);**
16) 您可以使用
plt.axhline
、plt.axvline
或ax.axline
、ax.axvline
功能在绘图区内绘制垂直线或水平线。做一个善于讲故事的人,用大众容易理解的方式通过故事传达你的发现。
**from matplotlib.pyplot import figure
figure(figsize=(10, 7))vp = **plt**.violinplot(train_df['target'], vert=False, showmeans=True,
showmedians=True)**#** Returns a dictionary with keys : ['bodies', 'cbars', 'cmaxes',
**#** 'cmeans', 'cmedians', 'cmins']
**#** Using these we can tinker with our plot:
vp['bodies'][0].set_edgecolor("k")
vp['bodies'][0].set_linewidth(2)
vp['bodies'][0].set_alpha(1.0)
vp['bodies'][0].set_zorder(10)vp['cmeans'].set_linestyle(":")
vp['cmeans'].set_color("r")
vp['cmeans'].set_zorder(101)
vp['cmeans'].set_segments(np.array([[[2.06855817, 0.7], [2.06855817, 1.3]]]))vp['cmedians'].set_linestyle("--")
vp['cmedians'].set_color("orange")
vp['cmedians'].set_zorder(100)
vp['cmedians'].set_segments(np.array([[[1.797, 0.7], [1.797, 1.3]]]))vp['cbars'].set_zorder(99)
vp['cbars'].set_color("k")
vp['cbars'].set_linewidth(0.5)vp['cmaxes'].set_visible(False)
vp['cmins'].set_visible(False)# Legend:
**plt**.legend(handles=[vp['bodies'][0], vp['cmeans'], vp['cmedians']],
labels=["Target", "Mean", "Median"], handlelength=5)
**plt**.title("Target Violin Plot")
**plt**.xlabel("Target")
**plt**.yticks([])
**plt**.grid(True, alpha=0.8)# Adding Text
**plt**.text(x, y, f"({train_df['target'].median()}) Median",
bbox={'facecolor':'orange', 'edgecolor': 'orange', 'pad':4,
'alpha': 0.7}, zorder=12)
**plt**.text(x2, y2, f"Mean ({np.round(train_df['target'].mean(),3)})",
bbox={'facecolor':'red', 'edgecolor': 'red', 'pad':4,
'alpha': 0.6}, zorder=11);**
********
— — — — — — — — — — — — —
**TK Work in Progress...**
1) Normal Matplotlib, 2) Seaborn, 3) Matplotlib Power, 4) Storytelling With Matplotlib
5.多个地块 ^
Photo by Ricardo Gomez Angel on Unsplash
您可以使用plt.subplots
方法或通过指定方框坐标手动添加Axes
到图形中,或使用plt.GridSpec()
方法,根据需要绘制任意多的图形。即
- 要么使用:
fig, axess = plt.subplots(ncols=2, nrows=4)
然后你可以通过访问这些Axes
中的任何一个作为axess[col_num][row_rum]
来绘制它们,然后使用任何Axes
方法来绘制它们。 - 或通过使用
plt.axes()
方法给出四个百分比值的列表,给出Axes
的【左、下、宽、高】以在figure
中制作。比如:plt.axes([0.1, 0.1, 0.65, 0.65)
。 - 或者使用
plt.GridSpec()
方法。如grid = plt.GridSpec(n_row, n_col)
。现在,当通过plt.subplot()
方法制作Axes
时,您可以使用此grid
作为 2D 阵列来选择使用多少和哪些栅格来制作电流,一个,Axes
。例如plt.subplot(grid[0,:])
将选择整个第一行作为一个Axes
。如果你愿意,你也可以留下一些。
****plt**.figure(1, figsize=(10, 8))
**plt**.suptitle("Hist-Distribution", fontsize=18, y=1)# Now lets make some axes in this figure
axScatter = **plt**.axes([0.1, 0.1, 0.65, 0.65])
**#** [left, bottom, width, height] in percent values
axHistx = **plt**.axes([0.1, 0.755, 0.65, 0.2])
axHisty = **plt**.axes([0.755, 0.1, 0.2, 0.65])**axHistx**.set_xticks([])
**axHistx**.set_yticks([])
**axHisty**.set_xticks([])
**axHisty**.set_yticks([])
**axHistx**.set_frame_on(False)
**axHisty**.set_frame_on(False)
**axScatter**.set_xlabel("MedInc ->")
**axScatter**.set_ylabel("Population ->")# Lets plot in these axes:
**axScatter**.scatter(x, y, edgecolors='w')
**axHistx**.hist(x, bins=30, ec='w', density=True, alpha=0.7)
**axHisty**.hist(y, bins=60, ec='w', density=True, alpha=0.7,
orientation='horizontal')
**axHistx**.set_ylabel("")# Adding annotations:
**axScatter**.annotate("Probably an outlier", xy=(2.6, 35500),
xytext=(7, 28000),
arrowprops={'arrowstyle':'->'},
bbox={'pad':4, 'facecolor':'orange', 'alpha':
0.4, 'edgecolor':'orange'});**
17)
seaborn
有自己的网格/多点对象,即Facet Grid
、Pair Grid
和Joint Grid
。他们有一些方法,如.map
、.map_diag
、.map_upper
、.map_lower
等,你可以研究一下,只在 2D 网格中的那些位置绘制图形。读一读科尔·奈弗利克的《用数据讲故事》。这是一本很好的读物,它用一个著名的数据通信者的例子涵盖了每个方面。
**from matplotlib.pyplot import figure
figure(figsize=(10, 8))**sns**.jointplot(x, y);**
6.互动剧情 ^
Photo by Ricardo Gomez Angel on Unsplash
默认情况下,matplotlib
中的交互式绘图是关闭的。这意味着只有在您发出最后的plt
命令或使用了触发plt.draw
的命令(如plt.show()
)后,该图才会显示给您。您可以通过ion()
功能打开交互式绘图,通过ioff()
功能关闭交互式绘图。打开它,每个plt
功能都会触发plt.draw
。
在现代 Jupyter 笔记本/IPython 世界中,有一个魔法命令可以打开这些笔记本中的交互/动画功能,那就是%matplotlib notebook
,要关闭它,您可以在使用任何plt
功能之前使用魔法命令%matplotlib inline
。
matplotlib
与许多用户界面工具包(wxpython、tkinter、qt4、gtk 和 macosx)配合使用,以显示交互式绘图。对于这些交互图,matplotlib
使用event
和事件处理程序/管理器(fig.canvas.mpl_connect
)通过鼠标或键盘捕捉一些事件。
这个事件管理器用于将一些内置的事件类型查看器连接到一个自定义函数,如果特定类型的事件发生,该函数将被调用。
有许多可用的事件,如’按钮 _ 按压 _ 事件’,‘按钮 _ 释放 _ 事件’,‘绘制 _ 事件’,‘调整大小 _ 事件’,‘图形 _ 输入 _ 事件’,等。可以像fig.canvas.mpl_connect(event_name, func)
一样连接。
对于上面的例子,如果event_name
事件发生,所有与该事件相关的数据都将被发送到您的函数func
中,在这里您应该已经编写了一些代码来使用所提供的数据。该事件数据包含 x 和 y 位置、x 和 y 数据坐标、是否在Axes
内点击等信息。如果它们与您的事件类型event_name
相关。
**%matplotlib notebook
# Example from matplotlib Docs**class** LineBuilder:
**def** __init__(self, line):
self.line = line
self.xs = list(line.get_xdata())
self.ys = list(line.get_ydata())
self.cid = line.figure.\
canvas.mpl_connect('**button_press_event**', self) **def** __call__(self, event):
print('click', event)
if event.inaxes!=self.line.axes: return
self.xs.append(event.xdata)
self.ys.append(event.ydata)
self.line.set_data(self.xs, self.ys)
self.line.figure.canvas.draw()fig = plt.figure()
ax = **fig**.add_subplot(111)
**ax**.set_title('click to build line segments')
line, = **ax**.plot([0], [0]) # empty line
linebuilder = LineBuilder(line)**# It worked with a class because this class has a __call__
# method.****
Random lines drawn using above code (by consecutive clicking)
7.其他人 ^
3D 剧情: ^
matplotlib
的 3D 图不在普通库中。在mpl_toolkits
中是因为matplotlib
开始只有 2D 图,后来在mpl_toolkits
中增加了 3D 图。可以导入为from mpl_toolkits import mplot3d
。
导入后,您可以通过将projection='3d'
传递给任何Axes
初始化器/maker 函数来制作任何Axes
3D 轴。
****ax** = **plt**.gca(projection='3d') # Initialize...# Data for a three-dimensional line
zline = np.linspace(0, 15, 1000)
xline = np.sin(zline)
yline = np.cos(zline)
**ax**.plot3D(xline, yline, zline, 'gray')# Data for three-dimensional scattered points
zdata = 15 * np.random.random(100)
xdata = np.sin(zdata) + 0.1 * np.random.randn(100)
ydata = np.cos(zdata) + 0.1 * np.random.randn(100)
**ax**.scatter3D(xdata, ydata, zdata, c=zdata, cmap='Greens');**
18) 在执行绘图功能之前,您可以通过运行
%matplotlib notebook
来交互查看 3D 绘图。
有许多 3D 绘图可用,如line
、scatter
、wireframe
、surface
、contour
、bar
等,甚至还有subplot
可用。你也可以用text
功能在这些图上写字。
**# This import registers the 3D projection, but is otherwise unused.
from mpl_toolkits.mplot3d import Axes3D# setup the figure and axes
**plt**.figure(figsize=(8, 6))
**ax** = plt.gca(projection='3d')**ax**.bar3d(x, y, bottom, width, depth, top, shade=True)
**ax**.set_title('Bar Plot')**
地理剧情: ^
要用matplotlib
绘制地理图,你必须安装另一个由matplotlib
开发的名为Basemap
的软件包。安装并不容易,在这里寻找官方说明,或者你可以使用conda
命令,如果你已经安装了 Anaconda:conda install -c conda-forge basemap
,或者如果这些对你来说也不起作用,在这里寻找(特别是最后的评论)。
**from mpl_toolkits.basemap import Basemapm = Basemap()
m.drawcoastlines()**
实际上,您可以在这里使用 matplotlib 的大多数原始函数,如text
、plot
、annotate
、bar
、contour
、hexbin
,甚至是这些投影上的 3D 绘图。
它还有一些与地理图相关的功能,如streamplot
、quiver
等。
****m** = Basemap(projection='ortho', lat_0=0, lon_0=0)
# There are a lot of projections available. Choose one you want. **m**.drawmapboundary(fill_color='aqua')
**m**.fillcontinents(color='coral',lake_color='aqua')
**m**.drawcoastlines()x, y = map(0, 0) # Converts lat, lon to plot's x, y coordinates.**m**.plot(x, y, marker='D',color='m')**
***# llcrnr: lower left corner; urcrnr: upper right corner*
**m** = Basemap(llcrnrlon=-10.5, llcrnrlat=33, urcrnrlon=10.,
urcrnrlat=46., resolution='l', projection='cass',
lat_0 = 39.5, lon_0 = 0.)
**m**.bluemarble()
**m**.drawcoastlines()**
**from mpl_toolkits.mplot3d import Axes3D**m** = Basemap(llcrnrlon=-125, llcrnrlat=27, urcrnrlon=-113,
urcrnrlat=43, resolution='i')fig = **plt**.figure(figsize=(20, 15))
ax = **Axes3D**(fig)**ax**.set_axis_off()
**ax**.azim = 270 # Azimuth angle
**ax**.dist = 6 # Distance of eye-viewing point fro object point**ax**.add_collection3d(**m**.drawcoastlines(linewidth=0.25))
**ax**.add_collection3d(**m**.drawcountries(linewidth=0.35))
**ax**.add_collection3d(**m**.drawstates(linewidth=0.30))x, y = m(x, y)
**ax**.bar3d(x, y, np.zeros(len(x)), 30, 30, np.ones(len(x))/10,
color=colors, alpha=0.8)**
‘Target’ distribution (red -> high) in California. [From above used California Dataset]
字云剧情: ^
词云在自然语言处理(NLP)中使用,在可以是云或不是云的某个边界内,显示具有最多频率的词,其大小取决于它们的频率。它将数据中单词之间的相对频率差异绘制为其字体的相对大小。在大多数情况下,仅仅通过查看单词云也很容易找到出现频率最高的单词。但这仍然是一种有趣的方式来传达数据,因为它很好理解和容易理解。
有一个 python 包wordcloud
,你可以把pip
当作pip install wordcloud
来安装。
你可以先设置WordCloud
的一些属性(比如使用mask
参数设置云的形状,指定max_words
,指定stopwords
等。)然后为给定的文本数据生成具有指定属性的云。
**from wordcloud import WordCloud, STOPWORDS# Create and generate a word cloud image:
wordcloud = **WordCloud**()\ # Use default properties
.generate(text) # Display the generated image:
**plt**.imshow(wordcloud, interpolation='bilinear')
**plt**.axis("off")**
**from PIL import Image
mask = np.array(Image.open("jour.jpg")) # Searched "journalism
# black png" on google
# images...
stopwords = set(STOPWORDS)wc = **WordCloud**(background_color="white", max_words=1000, mask=mask,
stopwords=stopwords)# Generate a wordcloud
**wc**.generate(text)# show
**plt**.figure(figsize=[20,10])
**plt**.imshow(wc, interpolation='bilinear')
**plt**.axis("off")
**plt**.show()**
动画: ^
你可以使用这两个类中的一个来轻松制作动画:
FuncAnimatin
:反复调用函数*func*
制作动画。ArtistAnimation
:使用一组固定的Artist
对象的动画。
(:提示# 12:)<
始终保持对实例对象
Animation
的引用,否则将被垃圾回收。20) 使用
Animation.save
或Animation.to_html5_video
方法之一将动画保存到磁盘。21) 您可以使用设置为
True
的参数blit
来加速/优化动画的绘制。但是如果blit=True
你将不得不返回一个由init_func
重画的艺术家列表。
在FuncAnimation
中,你需要传递至少一个当前的fig
和一个将为每一帧调用的函数。除此之外,你还应该查看参数frames
(iterable,int,generator,None 要传递给func
和动画每一帧的数据源】、init_func
(用于绘制清晰帧的函数,否则使用frames
的第一帧)和blit
(是否使用位块传输)。
**%matplotlib notebookfig, ax = **plt**.subplots()
xdata, ydata = [], []
ln, = **plt**.plot([], [], 'ro')**def** init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1, 1)
return ln,**def** update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata)
return ln,
# Always keep reference to `Animation` obj
ani = **FuncAnimation**(fig, update, frames=np.linspace(0, 2*np.pi,
128), init_func=init, blit=True)**
8.延伸阅读 ^
- 用数据讲故事——科尔·n·克纳弗里克(一本关于如何通过知名数据交流者使用图形/图表交流数据的好书)
- Python 数据科学手册— Jake VanderPlas
- 在 Jupyter 中嵌入 Matplotlib 动画作为交互式 JavaScript 小部件— Louis Tiao
- 用 Python 生成单词云— Duong Vu
- 底图教程
9.参考文献 ^
- 用数据讲故事——Cole n . Knaflic(一本关于如何通过知名数据交流者使用图形/图表交流数据的好书)
- Python 数据科学手册——杰克·范德普拉斯
- 在 Jupyter 中嵌入 Matplotlib 动画作为交互式 JavaScript 窗口小部件——Louis Tiao
- 用 Python 生成单词云— Duong Vu
- Matplotlib 教程:Python 绘图— Karlijn Willems
- 底图教程
- Matplotlib 文档
- Matplotlib mplot3d 工具包
- Matplotlib —交互式
- Matplotlib —动画
- Seaborn Docs
**Suggestions and reviews are welcome.
Thank you for reading!**
签名:
制作您自己的智能家庭安全摄像机
Security Camera Set-up
一台可以进行面部识别的相机,成本不到 80 美元。
Demo
不久前,我想买一台好的智能相机,但我的需求与相关成本不相称。所以,我决定用我已经有的零件做一个。
所需零件:
- 树莓 PI 3
- 网络摄像头
- PIR 传感器/超声波传感器
所需知识:
- 计算机编程语言
- OpenCV
- dlib
如果你想要更多关于 OpenCV 和 dlib 的信息,那么请看看我的旧文章。
什么是 PIR 传感器?
[Source: Google]
一个被动红外传感器 ( PIR 传感器)是一个电子传感器,它测量从其视野内的物体发出的红外(IR)光。它们最常用于基于 PIR 的运动检测器。所有温度高于绝对零度的物体都以辐射的形式放出热能。通常这种辐射对人眼是不可见的,因为它以红外波长辐射,但它可以被 PIR 传感器检测到。
什么是超声波传感器?
[Source: Google]
超声波传感器是一种使用超声波测量物体距离的仪器。超声波以高于人类听觉范围的频率振动。它使用单个传感器发送脉冲并接收回波。传感器通过测量发送和接收超声波脉冲之间的时间间隔来确定到目标的距离。
方法
通俗地说,PIR 传感器将检测瞬间,摄像头将捕捉帧,Raspberry PI 将执行面部识别并提供最终输出。
更详细地说,我已经将 PIR 传感器与 Raspberry PI 连接起来,网络摄像头正对着我公寓的前门。我没有使用 AWS 或任何其他云服务来执行推理或发送通知。我正在进行局部推断,并在我的扬声器上播放关于谁进入的声音。
到目前为止,单独的 Raspberry PI 还不是一个理想的执行实时推理的嵌入式平台。因此,我使用 PIR 传感器来确定何时启动推理机并执行面部识别。你也可以使用超声波测距仪,但在我的情况下,我打算用它来完成我的另一个项目。
一旦门被打开,有人进入,PIR 传感器将开始检测。当 PIR 传感器检测到任何类型的移动时,摄像机将开始捕捉 10 秒钟的帧。与此同时,OpenCV 的“ Haar Cascades ”将开始检测人脸,dlib 的“ 68 点人脸标志检测”将检测到的人脸标志与保存的标志进行匹配,以检查它是否是入侵者?
使用 OpenCV,我们可以从网络摄像头捕捉帧,并将每个帧转换为 numpy 数组。这里,我们以 320x240 的速率记录帧。我们也可以录制全高清帧,但在 Raspberry PI 上执行人脸检测将花费大量时间。然后使用“haarcascade _ frontal face _ alt 2 . XML”模型,在给定的帧中检测人脸。一旦我们识别了所有的面孔,我们将把它们存储在一个列表中,以便将它们与保存的面孔进行比较。
我们会用 dlib 进行人脸对比。dlib 68 点人脸标志检测将为您提供给定人脸的标志。我们确实有一些已知的面部标志存储在 numpy 文件中,我们将在比较之前加载这些文件。一旦我们有了所有的地标,我们就能找到这些地标之间的距离。我们使用 0.6 作为阈值。给你阈值以下最小距离的面部标志是进入房间的已知人。如果值不低于阈值,那么它是一个入侵者!!
您可以在下面的 git 资源库中找到完整的代码,
[## smitshilu/AISecurityCamera
在 GitHub 上创建一个帐户,为 smitshilu/AISecurityCamera 开发做出贡献。
github.com](https://github.com/smitshilu/AISecurityCamera)
结论
你可以在家里开发一个智能摄像头来获取入侵者的状态。你也可以使用 AWS 或 Google Cloud 等服务向你的手机或短信发送通知。
如果你喜欢这篇文章,请关注我的或Github或订阅我的 YouTube 频道 。**
使用并行处理让你的熊猫更快地应用函数
蟒蛇短裤
超级熊猫侠
Super Panda
并行化牛逼。
我们数据科学家已经有了四核、八核、睿频的笔记本电脑。我们使用具有更多内核和计算能力的服务器。
但是我们真的利用了我们手头的原始力量吗?
相反,我们等待耗时的过程结束。有时是几个小时,当紧急的交付品就在手边的时候。
我们能做得更好吗?我们能变得更好吗?
在这个名为**'Python Shorts,‘**的系列帖子中,我将解释由 Python 提供的一些简单构造,一些基本的技巧和我在数据科学工作中经常遇到的一些用例。
这篇帖子讲的是利用我们手头的计算能力,把它应用到我们最常用的数据结构上。
问题陈述
我们有一个巨大的熊猫数据框,我们想对它应用一个复杂的函数,这需要很多时间。
在这篇文章中,我将使用 Kaggle 上 Quora 非真诚问题分类的数据,我们需要创建一些数字特征,如长度、标点符号的数量等。这就去。
比赛是基于内核的比赛,代码需要在 2 小时内运行。所以每一分钟都是至关重要的,有太多的时间花在预处理上。
我们可以使用并行化来提高代码的性能吗?
是的,我们可以。
仅使用单个函数的并行化
Can we make all our cores run?
让我首先从定义我想用来创建我们的特征的函数开始。是我们希望应用于数据的玩具函数。
我们可以使用下面的函数来使用并行应用。
def parallelize_dataframe(df, func, n_cores=4):
df_split = np.array_split(df, n_cores)
pool = Pool(n_cores)
df = pd.concat(pool.map(func, df_split))
pool.close()
pool.join()
return df
它是做什么的?它将数据帧分成n_cores
个部分,并产生n_cores
进程,这些进程将函数应用于所有部分。
一旦它将函数应用于所有分割的数据帧,它就将分割的数据帧连接起来,并将完整的数据帧返回给我们。
我们如何使用它?
它使用起来非常简单。
train = parallelize_dataframe(train_df, add_features)
这有用吗?
为了检查这个并行化函数的性能,我在我的 Jupyter 笔记本的 Kaggle 内核中对这个函数运行了%%timeit
magic。
与只使用现有功能相比:
如您所见,我通过使用并行化功能获得了一些性能。它使用的是只有两个 CPU 的 kaggle 内核。
在实际比赛中,涉及到大量的计算,我使用的add_features
函数要复杂得多。这个并行化功能极大地帮助我减少了处理时间,并获得了银牌。
这里是带有完整代码的内核。
结论
并行化不是银弹;这是铅弹。它不会解决你所有的问题,你仍然需要优化你的功能,但是它是你的武器库中的一个很好的工具。
时间一去不复返,有时我们也缺少时间。此时,我们应该能够轻松使用并行化。
并行化不是银弹,而是铅弹
另外,如果你想了解更多关于 Python 3 的知识,我想向密歇根大学推荐一门关于学习中级 Python 的优秀课程。一定要去看看。
将来我也会写更多初学者友好的帖子。让我知道你对这个系列的看法。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系到我。
使用深度学习魔法让您的图片变得美丽
想获得灵感?快来加入我的 超级行情快讯 。😎
摄像技术很美。它给了我们所有人一个保存记忆的机会,当我们在照片中再次看到它们时,我们可以重温它们。
在过去的几年里,这项技术取得了长足的进步。有了各种各样的新功能,如 4K、HDR 和色彩增强,人们可以捕捉到令人惊叹的照片。
但这是有代价的。不是每个人都能买得起最好的相机。消费级 DSLR 相机的价格从几百美元到几千美元不等。不仅如此,并不是每个人都能充分利用这些相机;毕竟我们并不都是专业摄影师!
我们大多数人只是用手机。但与高端数码单反相机相比,智能手机拍摄的照片往往非常平淡。
深度学习改变了这一切。
美化您的照片
来自苏黎世联邦理工学院计算机视觉实验室的研究展示了如何自动增强低质量相机拍摄的照片,使它们看起来像是专业摄影师用 DSLR 拍摄的。
他们是这样做的。
该团队首先收集了一组低质量(来自手机)和高质量(来自 DSLR)的照片,你可以从项目页面下载。这正是我们在这样一个增强任务中想要的数据:输入一个低质量的图像(来自手机),并让深度网络尝试预测高质量的版本(来自 DSLR)会是什么样子。
一幅图像有几个我们可能想要增强的属性:光照、颜色、纹理、对比度和清晰度。深度网络被训练成用四种不同的损失函数来命中所有这些属性:
- **颜色损失:**预测图像和目标图像的模糊版本之间的欧几里德距离。
- **纹理损失:**基于生成对抗网络(GAN)的分类损失。训练 GAN 来预测灰度照片的质量是高还是低。由于使用了灰度,网络将很好地聚焦于图像的纹理而不是颜色。
- **内容损失:**预测图像的 VGG 特征与地面真实之间的差异。这种损失确保了图像中的整体结构和对象(即图像语义)保持不变。
- **总变化损失:**图像中的总垂直和水平梯度。这会增强图像的平滑度,这样最终的结果就不会太粗糙或太嘈杂。
最后,将这些损失加起来,训练一个端到端网络来进行预测!整体 GAN 架构如下所示。如果你也想了解更多,你可以查看的论文了解更多细节。
Architecture from the paper
代码
感谢 AI 社区开源思维的美丽,这里有一个公开可用的照片增强器的实现!这是你如何使用它。
首先克隆存储库
git clone [https://github.com/aiff22/DPED](https://github.com/aiff22/DPED)
安装所需的库
pip install tensorflow-gpu
pip install numpy
pip install scipy
所有预先训练的模型都已经在 models_orig 文件夹中的存储库中,所以没有必要下载它们!
将您要增强的照片放在以下目录中:
dped/iphone/test_data/full_size_test_images/
这是“iphone”的默认目录,但是如果你想改变它,你可以在test_model.py
脚本中改变代码。它之所以说“iphone”是因为作者最初使用 3 部智能手机的照片训练了 3 个不同的模型:iphone、索尼和黑莓,所以这是你的三个选项。但是这个模型在大多数带有这些选项的照片上都能很好地工作,所以我们可以只选择一个并运行它!
最后,为了增强照片,我们只需运行一个简单的脚本:
python test_model.py model=iphone_orig \
test_subset=full \
瞧啊。您增强的专业照片将保存在visual_results
文件夹中!
自己试试代码吧,很好玩的!查看照片增强后的效果。欢迎在下面发布链接,与社区分享您的照片。同时,这里有一些我自己测试的结果。
喜欢学习?
在 twitter 上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!
用 Python 制作 3 张简单的地图
在处理地理空间数据时,我经常需要以最自然的方式将这些数据可视化:**一张地图。**如果我们能够使用 Python 快速、轻松地创建您的数据的交互式地图,岂不是很好?在本教程中,我们将使用洛杉矶县所有星巴克咖啡店的数据集。在这篇介绍性文章结束时,您将能够创建:
- 洛杉矶县所有星巴克店的基本点地图
- 一张 choropleth 地图根据每家星巴克包含多少家星巴克来区分洛杉矶县的邮政编码
- 一张热图,突出了洛杉矶县星巴克的“热点”
我们开始吧!
你将需要…
- 蟒蛇包**熊猫。**这是用来在 Python 中轻松操作数据的
- 蟒蛇包叶子。这是用来非常容易地创建地图
- 洛杉矶县星巴克的经纬度电子表格(在我的 GitHub 上 这里 )
- 一个洛杉矶县的 GeoJSON(基本上是描述复杂形状的 JSON)(此处为)和一个洛杉矶县所有邮政编码的 geo JSON(此处为 )
为了熟悉数据,下面是前几行的快照:
对于这个分析,我们只需要关心纬度、经度和邮政编码字段。
以下是所需的 Python 导入、加载 Starbucks 数据和加载 LA County GeoJSON:
基点地图
从我们的数据框架中的纬度/经度对创建洛杉矶县所有星巴克的基本点地图非常简单。
打开laPointMap.html**,我们看到如下地图:**
我们可以清楚地看到洛杉矶县所有的星巴克都是洛杉矶县区域内的小红点。当然,您可以自定义任何颜色和形状的点。
等值区域图
在用 Python 玩地图之前,我实际上不知道什么是 choropleth 地图,但事实证明它们在可视化聚合地理空间数据方面非常有用。
我们的 choropleth 地图将回答这个问题:“洛杉矶县哪个邮政编码有最多的星巴克?”。choropleth 地图根据其他变量的值(在我们的例子中是星巴克店的数量)对每个邮政编码进行着色。
让我们先来看看创建一个所需的基本代码:
因为我个人发现要理解如何将 choropleth 的所有组件放置到位更加困难,所以让我们来看看一个单独的视觉效果,看看它是如何工作的。
choropleth 需要知道为邮政编码 90001、填充什么颜色。它检查由数据字段引用的熊猫数据帧,搜索邮政编码的 key_on 列,并找到在列中列出的另一列,即 numStores 。然后它知道它需要填充对应于邮政编码为 90001 的 3 商店的颜色。
然后,它在由 geo_path 字段引用的 GeoJSON 中查找,并找到邮政编码 90001 及其关联的形状信息**,这告诉它在地图上为该邮政编码绘制哪个形状。通过这些链接,它拥有所有必要的信息。让我们看看 laChoropleth.html 由此产生的 choropleth!**
我们看到它在顶部有一个漂亮的颜色条供参考。
热图
在上面的 choropleth 地图中,我们看到洛杉矶南部地区似乎有更多的星巴克店,但我们能不能再具体一点?我们能不能找出附近哪里有很多星巴克店?基本上,让我们创建一个热图来突出显示洛杉矶县的星巴克“热点”。
热图中需要一些试错的主要参数是半径和模糊**,前者控制每个星巴克店周围的圆圈有多大,后者控制圆圈“融合”在一起的程度。**
较高的半径意味着任何给定的星巴克影响较宽的区域,而较高的模糊度意味着彼此相距较远的两个星巴克仍然可以对热点有所贡献。参数由你决定!
让我们看看 laHeatmap.html 的天气图。
嗯……很酷,但是看起来好像所有的东西都是红色的。如果放大,热图可能更有价值。让我们放大一点,看看我们是否能确定更具体的热点。
不错!从上面的地图可以很清楚地看出,我们有一些热点和一些非热点(notspots?)在地图里。一个突出的是在洛杉矶市中心的(可以理解)。****
也就这样了!我唯一的遗憾是,我还没有找到一种方法来嵌入这些地图的实际互动版本,所以我只能给你看截图。我强烈鼓励你通过这篇文章运行小代码来为自己玩交互式地图。这是一种完全不同的体验。
我希望这篇文章对你有所帮助,下一篇再见!
包含本分析中使用的所有代码的完整笔记本可以在我的 GitHub 这里找到。
让糟糕的图表不那么糟糕
讲故事是人类相互交流的重要方式之一。为了讲述关于数据的故事,我们使用数据可视化,或者更简单地说,图表。
有一些可怕的图表,我们都见过。但是有更多的图表并不可怕,但仍然很糟糕。
前几天,在浏览我的脸书订阅时,我看到了《南佛罗里达州太阳哨兵报》的一篇关于枪支政治的文章。领先的数据可视化吸引了我的眼球——但不是以一种好的方式。颜色令人讨厌,东西相距太远,无法进行视觉比较,图表的风格也不太理想。
下图是:
Graphic from article in South Florida Sun Sentinel
让我们仔细看看是什么让这个图变得糟糕,看看我们是否可以让它变得不那么糟糕。
颜色
我注意到的关于视觉的第一件事是糟糕的颜色选择。虽然一开始用绿色表示“支持”和用红色表示“反对”可能有意义(就像交通灯的颜色),但应该避免这种颜色组合——这是有充分理由的。众所周知,最常见的色盲类型是红绿色盲,即那些受影响的人不能(或有困难)区分红色和绿色。如果你不能区分这两种颜色,这个图形是没有用的,或者说是令人困惑的。12 个男人中有 1 个,200 个女人中有 1 个患有色盲,红绿组合是一个糟糕的选择。
我开始想象用其他颜色组合的图表会是什么样子。我的第一个想法是:蓝色和橙色怎么样?这是一个常用的数据可视化配对,主要是因为它看起来很简单。但是当我意识到蓝橙色不适合这个图表时,我失望地叹了口气。所代表的数据与攻击性武器禁令的支持程度有关,这是一个不可否认的政治话题。由于蓝色通常用于民主党,红色用于共和党,使用这两种颜色都不是一个好主意。虽然民主党人更可能是支持者,而共和党人更可能是反对者,但用颜色暗示这些事情总是形影不离并不是一个好主意。
所以如果我不能用红色或蓝色,还剩下什么?我可能想待在室内,因为室外的颜色有时会让人分心,所以让我们试试绿色和橙色。从美学角度来看,这不是我最喜欢的选择——但总比不好好。
对比
这个图形恳求观众进行视觉比较,但这并不总是容易做到的。在图中,有三个相关的图形。上面的图表显示了所有佛罗里达人支持和反对攻击性武器禁令的比例,以及不知道或没有答案的人的比例。这是另外两个图表的比较点,这两个图表按性别和政党显示了支持、反对和未决定的比例。但是我的眼睛很难比较。当我试图评估无党派人士的支持水平是高于还是低于所有佛罗里达人的支持水平时,我可以感觉到我的眼球上下跳动。这些项目需要更紧密地结合在一起,以使观众能够合理地做出这些判断。
我也发现比较每个小组中反对者的百分比很有挑战性。比较支持者的百分比要容易得多,因为所有这些棒线都从同一点开始,都是 0%。由于对立类别的棒线都是从稍微不同的点开始,比较它们的长度就更加困难了。支持数据比反对数据更容易比较,这一事实暗示着支持数据可能比反对数据更容易理解,我认为这是一个不公平的假设。
我看到了两种可能的选择,让对立群体之间的比较更容易理解。选项 1:切换每个条形的反对组和未决定组的顺序。该触发器将使观察者能够更快地比较相对条的长度,因为它们都是右对齐的。互换进一步改善了图表,将各组放在一个从积极到消极的尺度上,在支持和反对之间犹豫不决,因为它自然下降。
选项 2:构建一个分组条形图,而不是堆叠条形图。这种类型的图形可能会简化对立物之间的视觉比较,因为所有棒线都从 0%开始。在这个选项中,理解对立数据的重要性与理解支持数据的重要性是同等的。
相同的数据,不同的视觉
下一步是接受不好的事情,让它变得更好(嗯,至少让它变得不那么坏)。我试图改善颜色,让东西更容易比较。这是我的设想:
几个显著的变化:(1)绿色和橙色,而不是绿色和红色,以及(2)两个并排的分组条形图,用水平线显示总体比例,而不是三组堆叠的水平条形图。
我意识到在我的新视野中有些东西丢失了。从表面上看,我的版本不太圆滑。我是一名初露头角的数据科学家,在这一点上,我主要使用 matplotlib 作为我的视觉效果。更实质性的是,关于未决定的群体的信息已经没有了。为了更清楚地比较支持者和反对者,我选择放弃强调每个群体的总和总是 100%。
请让我知道你的想法!我的目标是学习,我将非常感谢任何和所有的反馈。
用 Python 制作一个让孩子学习英语并从中获得乐趣的游戏
目标
为 2-6 岁的孩子建立一个互动游戏,学习英语词汇并从中获得乐趣。(GitHub 链接这里是)。)
这样做的原因
女朋友的姐姐有一个可爱的儿子,是幼儿园的孩子。他喜欢玩,而且精力充沛。像往常一样,就像其他孩子一样,他不喜欢阅读,更不用说说英语了。基于此,我想到为他制作一个游戏,练习他的记忆技巧,教他词汇,最重要的是,享受学习的过程。
游戏流程理念突破
好吧,这是游戏计划。
- 一个单词会显示几秒钟,孩子必须记住这个单词。假设这个词汇是“狗”。
- 将生成六个英文字符,并以随机顺序排列。例如,“A”、“C”、“G”、“D”、“P”和“O”。
- 孩子必须选择所显示的单词的正确顺序。
- 将显示 vocab 的图像并播放发音。
**
Game Design Paper Prototype
第一步——英语词汇列表
老话说,核桃和梨是你为你的继承人种下的。要制作这个游戏,一系列的英语词汇是必须的。除了自己从牛津词典中搜集资料,我们还可以利用他人的成果。所有的荣誉归于 gokhanyavas 。我们可以直接从 这里 下载词表。
*from urllib.request import urlopen
with urlopen('[https://raw.githubusercontent.com/gokhanyavas/Oxford-3000-Word-List/master/Oxford%203000%20Word%20List.txt'](https://raw.githubusercontent.com/gokhanyavas/Oxford-3000-Word-List/master/Oxford%203000%20Word%20List.txt')) as f:
word_list = [x.decode('utf-8') for x in f.read().splitlines()]*
导入词表后,还要做一些预处理工作。
删除带有符号和空格的单词
*import re
# Substitute Symbols with Spaces
word_list= [re.sub('[-.]',' ',word) for word in word_list]# Remove Words with Spaces
word_list= list(filter(lambda x: ' ' not in x, word_list))*
把单词改成小写
*# Change to Lower Cases
word_list= [word.lower() for word in word_list]*
保留 3 到 4 个字符的单词(因为这个游戏是给孩子玩的,我们不能让单词太长,对吗?)
*# Keep the Words with 3 or 4 Characters
word_list = list(filter(lambda x: len(x) in [3, 4], word_list))*
检查单词的词性。我们只保留以下:
CD(基数)/ JJ(形容词)/ NN(名词)/ VB(动词)
*import nltk
# List of Part-of-Speech
pos_list = [nltk.pos_tag([word])[0][1] for word in word_list]
# List of Word Length
len_list = [len(word) for word in word_list]import pandas as pd
# Data Frame
word_df = pd.DataFrame({'Word': word_list,
'POS':pos_list,
'Len': len_list})# Keep CD / JJ / NN / VB
word_df = word_df[word_df['POS'].isin(['CD','JJ','NN','VB'])]*
最终,我们可以得到这样一个数据框:
word_df
第二步——词汇发音
有了单词列表后,我们需要词汇发音 mp3 文件,这样游戏就可以教孩子们正确地发音。简单地说,我们将充分利用谷歌文本到语音包。
*from gtts import gTTS
import os.path
if not(os.path.isdir('Audio')):
os.mkdir('Audio')
print('Audio is downloading. It may take a few minutes.')
for word in list(word_df['Word']):
audio_save_path = 'Audio/'+ word + '.mp3'
gTTS(text=word, lang='en', slow=False).save(audio_save_path)*
English Words Audio Files
第三步——词汇卡通图片
除了声音之外,图像对于留下深刻印象和吸引孩子也至关重要。在这个游戏中,我使用从谷歌下载的图片。您也可以使用 Unsplash 或其他图像源。
*from google_images_download import google_images_download
from shutil import copyfile
from os import listdir
import shutil
if not(os.path.isdir('Image')):
os.mkdir('Image')
print('Audio is downloading. It may take a few minutes.')
for word in list(word_df['Word']):
response = google_images_download.googleimagesdownload()
response.download({"keywords": word,
"limit": 1,
"output_directory":'Temp_Image',
"suffix_keywords":'cartoon image'})
img_dir_list = listdir('Temp_Image')
for img_dir in img_dir_list:
initial_path = os.path.join('Temp_Image', img_dir)
file_name = listdir(initial_path)
if len(file_name) != 0:
file_path = os.path.join(initial_path, file_name[0])
final_path = os.path.join('Image', img_dir[:4].rstrip() + os.path.splitext(file_name[0])[1])
copyfile(file_path, final_path)
shutil.rmtree('Temp_Image')*
English Words Image Files
感谢上帝!所有的准备工作都完成了,接下来是最激动人心的部分——制作游戏。
第四步——智力游戏
在这个例子中,我使用 PyGame 来制作游戏。Pygame 是一套跨平台的 Python 模块,设计用于编写视频游戏。它包括设计用于 Python 编程语言的计算机图形和声音库。
有一些技巧,然后你可以学习和创造自己的游戏。
游戏初始化
*import pygame# Game Init
pygame.init()
win = pygame.display.set_mode((640, 480))
pygame.display.set_caption("KidsWord presented by cyda")run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.update()
pygame.quit()*
要开始游戏,我们需要一个游戏窗口。有两件事情需要设置。
- 窗口大小-示例:(640,480)
- 窗口显示名称-示例:“cyda 提供的童剑”
添加背景颜色
*win.fill((59, 89, 152))*
RGB 颜色-示例:(59,89,152)
添加文本
*font_1 = pygame.font.SysFont('impact', 55)
font_2 = pygame.font.SysFont('Arial', 25)
win.blit(font_1.render('KidsWord', False,(242, 242, 242)),(215, 45))
win.blit(font_2.render('Presented by cyda', False, (212, 216, 232)), (350, 135))*
要添加文本,您必须指定以下参数。
- 字体样式-示例:“影响”
- 字体大小-示例:55
- 字体颜色-示例:(242,242,242)
- 字体位置-示例:(215,45)
添加几何形状
*pygame.draw.rect(win, (255, 255, 255), (270, 250, 85, 40))*
以画矩形为例,我们必须指定
- 形状颜色-示例:(255,255,255)
- 形状位置-示例:(x_upperleft,y_upper_left,x_bottomright,y_bottom_right)= (270,250,85,40)
添加可点击按钮
事实上,没有正式的或官方的功能让你创建一个按钮。因此,我们必须以一种巧妙的方式来做这件事。
1.定义可点击的按钮区域
*button_area = pygame.Rect(270, 250, 85, 40)*
2.定义触发功能
*def button_pressed():
win.fill((255, 255, 255))
win.blit(font_1.render('Page 2', False, (0, 0, 0)), (230, 240))*
3.添加鼠标点击事件
*if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = event.pos
if (button_area.collidepoint(mouse_pos)):
button_pressed()*
添加计时器
在一个游戏中,计时器是你没有机会摆脱的必要元素。例如,如果玩家不能在一定时间内完成任务,他/她可能会输掉游戏。在我的情况下,我会在时间结束后切换页面。
要设置定时器,请遵循以下步骤:
1.初始化时间参数
*font_3 = pygame.font.SysFont('impact', 120)
clock = pygame.time.Clock()
pygame.time.set_timer(pygame.USEREVENT, 1000)
page = 0
time_limit = 3*
2.更改鼠标点击事件
*if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = event.pos
if (button_area.collidepoint(mouse_pos)):
time_count = time_limit
page = 1
button_pressed()
if page == 1:
if event.type == pygame.USEREVENT:
time_count -= 1
time_text = int(time_count)
if time_text > time_limit:
time_text = time_limit
pygame.draw.rect(win, (59, 89, 152), (420, 50, 100, 160))
win.blit(font_3.render(str(time_text), True, (242, 242, 242)), (440, 50))
pygame.display.flip()
clock.tick(60)
if time_count < 0:
win.fill((255, 255, 255))
win.blit(font_1.render('Page 2', False, (0,0,0)), (230,240))*
添加图像
*image = pygame.image.load('car.png')
image = pygame.transform.scale(image, (600, 300))
win.blit(image, (25, 150))*
PyGame 有一个直接加载图片的功能。但是,你要提醒两件事。
- 不允许使用动画图像。
- 你最好转换图像比例,以便更好地适应你的窗口大小。
播放音频
可以导入 PyGame 支持的混音器模块来播放音频文件。
*from pygame import mixer
mixer.init()
mixer.music.load('car.mp3')
mixer.music.play()*
这些都是我用来建造这个奇妙游戏的技术。而现在,女朋友的表妹愿意坐下来,也爱学英语。
编辑的话
写一篇教程文章并不容易,而且费时。如果你喜欢阅读它,并且觉得它很有用,请分享给你的朋友。将来,我们会发布一系列的教程文章,敬请关注!=)
还有,如果你有兴趣了解更多的窍门和技巧,欢迎你浏览我们的网站:【https://cydalytics.blogspot.com/
领英:
杨皇-https://www.linkedin.com/in/yeungwong/
罗嘉丽-https://www.linkedin.com/in/carrielsc/
其他文章
- 数据可视化技巧(Power BI) —将分类变量转换为虚拟变量
- 中文异状字云(Python)
- 数据科学基础®:从 Excel 导入数据— readxl
- 数据科学基础®:从文本文件导入数据— textreadr & readtext
- 数据科学基础®:导入&导出 Excel 中的数据— xlsx
如何制作一个可以查看交易图表的人工智能(并用于交易)
我们生活在一个大多数事情越来越依赖于计算机视觉和深度学习的世界。从自动标记你夏天的照片到安全摄像头的面部检测,感觉我们生活在一个反乌托邦的未来。
虽然人工智能革命仍在我们身边发生,但对我来说,2019 年的春天是有趣的时刻。在完成一门深度学习课程后,我开始修补深度学习的许多不同用例,如图像分类到自然语言处理(NLP)。在花了几个小时使用 Python 和 Keras 库之后,我训练了一个简单的卷积神经网络(CNN ),它能够区分猫和狗的图像。听起来很简单,几年前这是一个巨大的任务,我很难相信简单的神经网络如何解决一个复杂的问题!通常,如果你想使用 CV 库进行图像识别,你必须进行特征工程,开发你自己的过滤器,并将许多特征硬编码到代码中。即使经过多次尝试,你也只能得到一个大约 60-70%准确的算法,这与我们今天用机器学习所能做到的相差甚远。
Deep Learning Methods Looks into Pictures as Matrices
我完全被深度学习的简单性惊呆了。首先,我定义了一个非常简单的 CNN 架构,然后用猫和狗的图像标记我的数据集。之后开始训练,观察训练精度和验证精度的上升,直到达到令人满意的指标。就是这样!!接下来,加载您的模型和权重文件,然后使用您想要预测的文件运行 model.predict 命令。结果是正确的分数!
深度学习的简单性和准确性简直太棒了!
大约在同一时间,我对经济学和当日交易产生了兴趣。我开始阅读雷伊·达里奥的 生活和工作原则。 (如果你还没看,我只能推荐)
Principles by Ray Dalio
在他的书中,他谈到了他的公司如何创造出专有的算法,做出财务决策来管理他的对冲基金,并成为世界上最成功的基金之一。虽然这个故事非常鼓舞人心,但它让我开始思考,我们不要教计算机任何东西,让它自己解决问题怎么样。与过去计算机视觉的特征工程不同,深度学习还可以用于创建算法,这些算法决定何时买卖股票、外汇、石油以及你能想到的任何东西。
如果数据中有一个模式,你不需要自己去发现,它会被深度学习发现,这就是 Inpredo 项目的开始。
Charts, more charts!
第一步。创建培训数据:
所以在我们进去创造一个赚钱机器之前(小心我过于乐观的评论。)我们需要训练数据。很多!
感谢上帝,这不会很难,因为我们已经从上面的链接访问 CSV 数据。我们需要做的只是创建一个算法,该算法能够查看历史数据,并创建图表,然后根据工具(例如欧元/美元)价格在未来是上涨还是下跌对其进行分类。因为我们有历史数据,我们知道在数据时间范围内的任何给定时间价格发生了什么,所以很容易对生成的图表图像进行分类。
创建图表是容易的部分,我们需要几个库和我为此创建的函数,这个函数叫做 graphwerk.py(发电厂乐团,有人知道吗?)
所以 graphwerk 非常简单,你只需要以列表格式插入所选乐器的历史数据。我们将印刷覆盖 12 小时/蜡烛的图表**。**所以你的列表长度必须是 12。如果你想覆盖更大的时间范围,那么你需要增加你的列表长度。关于粒度,您可以选择每小时、每天甚至每分钟的数据。如果你想用更多的蜡烛来打印图表,这是完全没问题的,但是我不想在训练数据中引入太多的噪音。
import matplotlib.pyplot as plt
import mpl_finance
import numpy as npdef graphwerk(open, high, low, close, instrument):
# Create Prefixes for correct data
if instrument == 'XAU/USD':
prefix = 'xau'
elif instrument == 'USOil':
prefix = 'USOil'
elif instrument == 'XAGUSD':
prefix = 'xag'
else:
print('Instrument prefix is not defined in graphwerk')
return
fig = plt.figure(num=1, figsize=(3, 3), dpi=50, facecolor='w', edgecolor='k')
dx = fig.add_subplot(111)
mpl_finance.candlestick2_ochl(dx, open, close, high, low, width=1.5, colorup='g', colordown='r', alpha=0.5)
plt.autoscale()
# Create a moving average overlay
sma = convolve_sma(close, 3)
smb = list(sma)
diff = sma[-1] - sma[-2]
for x in range(len(close) - len(smb)):
smb.append(smb[-1] + diff)
dx2 = dx.twinx()
dx2.plot(smb, color="blue", linewidth=8, alpha=0.5)
dx2.axis('off')
dx.axis('off')
timestamp = int(time.time())
file_name = realtime_data + str(prefix) +str(timestamp) + '.jpg'
plt.savefig(file_name, bbox_inches='tight')
#Uncomment this line to see the plot right after script runs.
#plt.show
plt.close()
return file_name
运行该脚本后,它将创建如下所示的图表:
XAU/USD Chart with the past 12 hours data.
我知道图像尺寸很小,但对于深度学习,你不需要 4K**分辨率的照片或图表。对于大多数人工智能深度学习应用程序来说,大约 200x200 像素已经足够了。事实上,使用较小尺寸的图像是一件好事,因为为深度学习提供 4K 图像最终将需要一个超级昂贵的 GPU 集群,如新的英伟达 DGX,价格约为 2 万美元。**深度学习的酷之处在于,如果你很聪明,你可以使用分辨率较低的图像来大幅降低处理能力,而这些图像仍然携带相同数量的信息:)
如果你也可能注意到了,酒吧看起来并不像现实生活中的样子。原因是我故意操纵它们,在蜡烛之间嵌入额外的信息,降低它们的透明度。这就产生了重叠的蜡烛,这些蜡烛也可以在蜡烛重叠区域的混合颜色中携带信息。
在这个半透明蜡烛的顶部有一个简单的移动平均线(SMA ),当它穿过蜡烛时,透明度也会降低,以创建附加信息。您可以随意改变形状、大小和透明度,以创建完美的训练数据集。
步骤 2:为训练数据集创建 10000 幅图像
所以上面的脚本对于创建单个图像来说是很棒的,但是我们需要更多来训练一个神经网络**。**我说的是这里有几千个。所以作为开发人员,我们不只是点击按钮一千次,对不对?我们需要自动以滚动时间窗口的方式检查整个 csv 文件,并自动将图表图像放置在正确的文件夹中,如“购买”和“出售”。逻辑非常简单,定义时间窗口 12,(这意味着每小时 csv 文件中的 12 小时窗口),并在 for 循环中的每个循环中将窗口向前移动 1 小时。通过这种方式,我们将能够根据历史数据的大小创建足够数量的样本。
为了能够创建足够数量的训练数据,您只需要以下格式的干净 csv 数据,然后剩下的只是等待脚本完成对数据的完整循环。您将需要为此创建 2 个文件夹,最终将填充 2 种类型的数据:购买和出售。当最后一根蜡烛线的收盘价低于下一根蜡烛线的收盘价时,创建的图表将被保存到“买入”文件夹中。换句话说,如果最后一根蜡烛线的收盘价高于下一根蜡烛线的收盘价,那么“卖出”文件夹将包含图表图像。
第三步:训练一个简单的卷积神经网络
在创建数据集之后,我们需要定义一个神经网络架构,然后输入训练数据来训练神经网络,以区分可能的买入或卖出信号之间的差异。
如果你已经注意到,我不是在谈论任何一种策略或某种算法设计来找出这些模式。人工智能的神奇之处在于,它会自己找出模式。
目前,有许多不同种类的卷积网络架构设计用于图像分类。Xception 是获奖产品之一,但我们不会使用目前先进的产品。
我们的模型将是一个基本的卷积网络,具有丢弃层和全连接层,如下所示:
model = Sequential()
model.add(Convolution2D(nb_filters1, conv1_size, conv1_size, border_mode ='same', input_shape=(img_height, img_width , 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(pool_size, pool_size)))
model.add(Convolution2D(nb_filters2, conv2_size, conv2_size, border_mode ="same"))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(pool_size, pool_size), dim_ordering='th'))
model.add(Convolution2D(nb_filters3, conv3_size, conv3_size, border_mode ='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(pool_size, pool_size), dim_ordering='th'))
model.add(Flatten())
model.add(Dense(1024))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(classes_num, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.rmsprop(),
metrics=['accuracy'])
结果
经过无数个小时摆弄参数和创建,减少,过滤训练数据,人工智能模型能够在 2 年的数据集内以 63%的准确率进行“猜测”!
就像所有正常人会做的那样,我把这个人工智能模型插入了 kraken 的实时交易引擎,进行 BTC 对美元的交易,希望能赚些钱,讲述暴富的故事。顺便说一下,如果你想进入 API 交易,我只能推荐北海巨妖。它们是受监管的交易所,拥有安全稳定的 API。
Have an idea regarding to AI and Machine Learning? Book a time with me and let’s see what we can do together!
非常有趣的是,它真的赚了钱在这个时间段内连续 10 天达到了%5.34 的涨幅。与此同时,BTC 兑美元下跌了%3.29!
所以最酷的是,不管市场是涨是跌。它只是根据情况来缩短或拉长乐器。因此,即使在市场上所有东西都在贬值的情况下,这种模式仍然能够赚钱。
Holy sh.t, it works moment
由于 digitalocean 的超级易用的虚拟机部署,在创建此类模型以持续运行 bot 后,我每月的总支出约为 15 美元。你也可以试试下面的促销代码并获得 100 美元的信用点数来启动一台虚拟机。这相当于 3 个月的免费使用。只需选择一个一键部署的 ubuntu 部署,并使用我在文章末尾附上的 github repo。
所以我写这篇文章的原因是想告诉你还有很多事情需要去做。预测一只股票是涨是跌只是故事的一半。如果你不知道股票上涨或下跌的百分比是多少,这不会有多大帮助,因为你不知道何时兑现你的收益。
所以显然这个人工智能模型需要随着时间的推移而改进。考虑到人工智能模型需要定期更新以适应不断变化的市场条件也是很好的。
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
如果你想自己运行代码,看看结果,看看 github 页面:https://github.com/cderinbogaz/inpredo
Have a project idea to discuss? You can book a time with me using the link above.
查看我在 Medium 上的其他项目和文章:
**免责声明:**如果你用我的代码用自己的钱在市场上交易,我不对你的损失负责。注意安全,不要去冒自己没有完全理解的风险。
从 Youtube 视频制作影像数据集
如何用逼真的图像改善你的深度学习数据集?
深度学习模型的好坏取决于你提供给它的数据。这就是为什么花足够的时间收集大量的好数据是非常重要的。我所说的“好”是根据手头的问题而变化的。确定你的数据是否合适的一个有用的技巧是考虑用户的输入会是什么样子。这是一个重要的问题,尤其是在处理图像时。光线、对比度、方向、图像质量和视角可能会有很大差异,不考虑这些差异会在预测中产生巨大的误差。例如,如果你想使用你的模型制作一个手机应用程序,不要只在专业相机拍摄的图像上训练它。尝试减少对训练数据的这种偏向的一组好的技术是数据扩充,但是我在这里不详细说明。
编辑(2021 年 2 月) : Youtube 更改了他们网站的源代码,因此get_urls
功能不再工作。其余的代码工作正常(最新版本在我的 github 上),所以唯一的问题是获得一个视频 URL 列表。以下是一些建议:
- 手动收集一个 URL 列表,用它代替
get_urls
的结果。这样做可能很烦人,但肯定有效。 - 用 Selenium 刮 Youtube,得到一些网址。考虑到网站现在的编码方式,这可能会很复杂,但应该是可行的。
- 使用 Youtube API 获取给定关键字的视频列表。这个 API 非常容易使用。唯一复杂的步骤是使用谷歌账户设置凭证。
如果您需要这些建议的帮助,请联系我:)
抓取图像
这篇长长的介绍说明了数据收集的重要性,并且存在许多工具和数据来源。在这篇文章中,我把重点放在图像上,因为我最熟悉这个话题。当试图收集特定主题的图像时,首先想到的是使用 Beautifulsoup 和 Selenium 等库来抓取谷歌图像。其实我写了这样一个刮刀,你可以在这里找到。然而,在谷歌上可以找到的图片数量是有限的,而且它们通常有相似的风格,如果这种风格不是你感兴趣的风格,这可能是一个问题。
Amateur image of hockey players (left) vs pros (right)
第二个较少被讨论和使用的数据来源是 Youtube。当我从斯坦福大学的人们那里找到一个很好的数据集时,我被激励去研究这个主题,这个数据集可以在这里找到。这是一个超过 100 万个 Youtube 视频链接的集合,涉及近 500 项运动。这在正确的时间落到了我身上,因为我正在研究一个体育分类器,它是根据从谷歌上搜集的图像进行训练的。这个模型有上面提到的问题,它在干净和专业的图片上工作得很好,但在业余爱好者的图片上工作得很差。
因此,这篇文章的想法是描述我如何使用 python 从 Youtube 视频中收集图像。主要步骤是在 Youtube 上搜索一个查询,并收集一部分结果视频作为链接。然后程序下载视频(这可能需要很多时间和数据,取决于你的互联网连接)并保存在本地。然后,在删除视频之前,每个视频被用来提取一定数量的帧,这些帧被保存。这种技术让我能够收集到更真实的图像,但当然,之后还要进行一些手动过滤,因为视频包含了很多额外的视觉效果。显然,这种数据来源更受限制,但它应该对许多主题有用。
代码
这个程序的代码实际上很简单,是由我从互联网上收集的一些小片段组成的。然而,我找不到一个从头到尾都能做我想做的事情的程序,所以我不得不自己连接这些步骤。完整的代码可以在我的 github 上找到并下载。
第一步是导入运行代码所需的所有库。
大部分都是相当标准的,都是 python 自带的。只需使用 pip 就可以获得需要安装的额外组件。分别是:BeautifulSoup 抓取 Youtube 网站并提取链接,pytube 下载视频,OpenCV 从视频中提取图片。
完成后,下一步是创建第一个函数,它在 Youtube 上搜索一个单词或短语,并返回视频的 URL。
构建它的第一步是将查询词/短语转换成 url,以防它包含空格或重音符号之类的东西。Youtube 搜索是通过在 url 中包含查询来完成的,使用 urllib 和 BeautifulSoup 从结果页面中提取 html。后者再次用于查找视频的链接,并将它们添加到列表中,直到达到该函数所请求的最大数量,以便返回该列表。关于 BeautifulSoup 是如何工作的,请看这篇文章。
收集完视频的 URL 后,下一个函数将它们下载到本地系统。再次请注意,这可能会占用你的下载限制很多,如果你有一个。
这是 pytube 库的一个简单应用(参见文档)。该代码只下载特定长度的视频和. mp4。视频的长度隐藏在返回的深处,所以我必须挖掘才能找到它。有很多方法可以获得这类信息,但它们对我不起作用。视频被下载到指定位置或当前工作目录。最后,所有代码都嵌入在 try 语句中,因为有许多视频在被请求时会导致错误。在这种情况下,脚本只是不下载视频并打印错误消息。
一旦视频下载完毕,就可以使用 OpenCV 提取图像了。这是一个相当大的图像处理库,可以做很多事情,但我只用它来做一个非常基本的任务。关于这个强大工具的更多细节,我推荐这个系列教程。
这将 mp4 文件的路径和保存图像的文件夹作为输入,如果还不存在的话就创建一个。使用 OpenCV 打开视频,捕捉图像并保存到正确的位置。通过尝试打开文件进行测试,只是为了确保图像没有损坏,在这种情况下,它会被删除。然后,视频快进指定的时间量,并且该过程继续,直到拍摄了最大数量的图像或视频结束。
图像根据输入中的名称进行标记,起始编号由一个自制函数确定。这是一个非常简单的函数,可以找到像“name_##”这样命名的文件的最大标签。jpg”以便不覆盖现有的图像。代码可以在 github repo 上找到。
该程序的最后一步显然是将所有内容合并到一个函数中,该函数接受一个查询词或短语,并最终将提取的图像保存在一个漂亮的文件夹中。
该函数查找 URL 并将视频下载到当前工作目录。然后,它会检查目录中的所有. mp4 视频,并从每个视频中提取正确数量的图像。使用过的视频之后会被删除,以避免重复使用和浪费磁盘空间。为了达到这篇文章的目的,唯一需要使用的函数是 extract_images_from_word。
Example of image scraped from Youtube about hockey
用网络摄像头制作艺术品
一个风格转移的实现和解释,慢和快。
Starry Stanford
几千年来,人类文化的一个真正重要的特征是我们的艺术。没有其他物种能够创造出甚至有点像利奥·达芬奇或梵高的画的东西。甚至许多人在创作这种质量的艺术时都有困难。直到最近,随着神经风格转移的引入,我们能够获取一幅图像的风格,然后将其应用于另一幅图像的内容。这使得计算机有能力创建如上图所示的图像,这是一张由梵高绘制的斯坦福大学胡佛大楼的照片,以星夜为风格。在这篇文章中,我将谈论神经风格转移,然后是快速风格转移。
(Left: Starry Night by Van Gogh) — (Right: Hoover Tower)
内部运作
在计算机视觉领域,卷积神经网络一直用于从自动驾驶汽车到医疗诊断的各种应用。如果你想了解更多关于它们是如何工作的,请查看我写的关于我如何建立一个皮肤损伤分类工具的文章,这里。一旦你读过这些,你就会知道 CNN 由卷积层(检测图像中的模式和对象)和最终的全连接层(预测)组成。我们在这里真正寻找的是通过卷积层捕获的信息。
在预先训练的 CNN(如 VGG19 网络)中,前 16 层是卷积层,用于捕获特征。
Conv1_1 until Conv5_4 are all used for feature extraction. Source.
最后一对层(FC1、FC2、softmax)仅用于返回图像中存在的不同对象的概率。我们实际上不需要这些图层来进行风格转换,因为我们不会对图像进行分类。靠近网络起点的层可以学习诸如边缘和拐角之类的真正低级的特征。在网络中向上移动,我们得到诸如形状的特征,直到我们最终达到高级特征,这些高级特征是整个对象,例如人的脸或动物的形状。
Features at different levels in a CNN. Source.
我们这里的目标是将某个图像的风格,以及某个图像的内容,转移到一个新的图像风格化的图像。为了实现这种双重优化,我们需要计算两次损失。一次为风格,一次为内容。
Content Loss Function
内容损失是通过测量 CNN 的输出图像与地面真实图像的相似性(欧几里德距离)来计算的,地面真实图像是它试图达到的目标。由于 CNN 中的特征地图只是一大串数字,所以它们可以用高维向量空间来表示。这意味着计算网络输出向量与地面真实向量之间的距离非常简单。我们可以从预先训练的网络(如 VGG16 网络)中检索该特征图。根据我们从网络的哪个部分获取特征地图,输出图像看起来会有所不同。如果我们选择一个真正在网络深处的层,很有可能,我们会得到一个看起来更抽象的输出图像。
Gram Matrix
风格损失依赖于一个叫做 Gram 矩阵的数学对象。Gram 矩阵是一个向量的所有可能内积的矩阵,它非常擅长捕捉非本地化信息。因此,它从图层中的要素地图获取所有信息,并去除该信息在图像中的空间位置。基本上,这是用来提取一个图像的风格。然后,通过再次测量输出图像的 gram 矩阵与风格目标之间的相似性来计算风格损失。
Style Loss Function
我们可以改变风格和内容重建的权重,以获得风格不同的图像。
Changes in weights reflecting on output.
现在快点
很好,现在我们有了一个风格转换的方法,但是速度的问题仍然是一个问题。这是由于模型的架构,减少损失是一个缓慢的迭代过程,无法实时应用。在约翰逊等人的论文中提出了一个解决这个问题的非常聪明的方法。他们没有获得一个图像并将其优化为风格化,而是创建了一个神经网络,可以直接输出风格化的图像。这个流程在几个方面有所不同。不是输入两个图像(内容、风格)并获得风格化图像的迭代输出,而是使用快速风格转换,根据网络的训练内容,输入一个图像并获得预定风格的快速输出。当然,这意味着你仍然要训练一个网络,但是对于你想使用的每一种风格只训练一次。该网络的结构如下图所示。
The architecture of the network.
这里,我们从特定层(3)计算生成的图像和风格化图像之间的内容损失。然后我们计算每个特征图的风格损失。然后,我们将这两个损失结合起来,形成一个整体损失。我们现在可以使用梯度下降来训练这个网络,以最小化这种全局损失。这是一个非常简单的过程,但你可以从中获得一些真正令人惊叹的艺术作品!它还将图像生成过程的速度提高了 1000 倍,同时生成了与标准神经类型转移非常相似的定性结果。你可能已经注意到这个网络有两部分,图像转换网络和损耗网络。
图像变换网络
这是一个简单的 CNN,具有用于网络内下采样和上采样的残差块和步进卷积。这导致输出与输入大小相同。用特征重构感知损失而不是每像素损失来训练该网络。等等…什么是知觉丧失?与更传统的每像素损失相比,它基于从预训练网络中提取的高级图像特征表示之间的差异,而不是图像中单个像素的差异。当我们试图重建图像时,每像素损失有两个问题,它们真的很慢,即使一张照片在视觉上可能与地面真相非常相似,但在数学上它们可能相差很远。这导致在试图修复这些不可见的更改时浪费了大量资源。
损耗网络
这只是一个权重被冻结的亏损网络。我之前解释过了。这个网络基于 VGG16 loss 网络,在微软的 COCO 数据集上训练,该数据集是日常生活中成千上万个常见物体的集合。
如果你想深入了解这一切是如何运作的,你应该阅读提出这个想法的原始研究论文。
这个新网络让我们风格化、实时化。
你可以在我的网站上玩这个游戏。整个事情的代码可以在我的 Github repo 上找到,是用 ML5JS 的风格转换文档制作的,也是基于 deeplearnjs 的。
另一个非常酷的演示是 NVIDIA 的快速照片风格算法,它可以创建照片般逼真的图像,这是风格化的。你可以查看它的源代码,这里。
NVIDIA’s Fast Photo Style Algorithm
后续步骤
虽然这种技术已经很好地工作了,但在我们可以用它做什么方面仍然有一些缺点。仍然没有算法可以接受两幅输入图像并对它们进行风格转换。像这样的技术可能会导致 AR 技术领域的一些疯狂的发展,并可能成为艺术家的宝贵工具!
如果你喜欢我的文章或者学到了新东西,请务必:
- 在 LinkedIn 上与我联系。
- 给我发一些反馈和评论(aryanmisra@outlook.com)。
- 看看这篇文章所基于的两篇论文(这里是这里是,这里是这里是)。
- 去我的网站上玩一个快速风格转换的现场演示吧。
用 Python 制作艺术地图
PYTHON 地图
岩石粉笔 Jayhawk!
Streets of Lawrence, Kansas colored by their length.
**目的:**我们将学习如何使用来自 OpenStreetMap 的数据用 Python 构建地图。
**材料和方法:**为了获取我们的数据,我们将使用 OSMNX Python 包。然后,我们将对检索到的数据进行解包,并根据街道的长度为每条街道分配一种颜色。然后使用 OSMNX 功能将数据可视化。最后,我们应用某些调整,使地图美观。
**注意:**如果你是从零开始,我会建议你按照这篇文章安装所有必要的库。这篇文章的全部内容可以在我的 GitHub 上找到。欢迎你来叉它。最后,为了更好地理解这篇文章,请在 PC 或 Mac 上用大显示器查看,这样你就可以看到地图的细节。
作者的一句话
OSMNX Python 包由 Geoff Boeing 编写,可用于从 OpenStreetMap 中检索、建模、分析和可视化街道网络和其他空间数据。
您可以尝试使用 Anaconda 安装 OSMNX 包,但是,您最终可能会获得一个旧版本的 OSMNX,并且本文中的所有代码都将无法工作。我建议你访问 Geoff Boeing Github 这里并下载这个包的最新版本到你的机器上。完成后,将 OSMNX 文件夹放在工作目录中。您的工作目录应该如下所示:
Figure 1 — Working directory with the OSMNX package.
如果你比我聪明,并且能够使用 conda 或 pip 命令安装 OS mnx 0.11 版,请发表评论。我想把这一步从流程中去掉。
导入库
让我们从导入我们需要的所有库开始。
Script 1 — Importing libraries.
如果你有任何问题,让我们用 Anaconda 安装缺失的包来解决。我将只讨论不常用的包,因为很可能你已经安装了 Pandas、Matplotlib 和其他广泛使用的包。
打开 Anaconda 提示符并导航到所需的 conda 环境。
要安装用于创建、操作和研究复杂网络的网络,请运行:
conda install -c anaconda networkx
要安装 GeoPandas 这是一个开源包,它通过允许对几何类型运行空间操作来扩展 Pandas 数据框的功能:
conda install geopandas
安装 PIL 一个用于图像处理的 Python 包:
conda install -c anaconda pillow
应该可以了。在我们继续之前,让我们运行一个健全性检查,以确保我们使用的是相同版本的包:
Scrip 2 — Checking version of packages.
脚本 2 的输出为:
The NetworkX package is version 2.3
The OSMNX package is version 0.11dev
The Request package is version 2.22.0
The PIL package is version 6.1.0
您可能使用这些包的不同版本而逃脱,但是如果您稍后得到一个讨厌的错误,罪魁祸首可能是您正在使用的不同的包。
获取我们的数据
我们将为堪萨斯州的劳伦斯市制作一张地图——一个我所热爱的城市。
为了制作地图,我们需要一些空间数据。您可以通过访问此站点下载 OpenStreetMap 数据。然而,我发现的最简单的方法是使用 OSMNX 包。让我告诉你这有多简单:
Script 3 — Grabbing spatial data.
因此,通过两行代码,您可以提取任何城市的网络。network_type
变量用来描述你要抓取的网络类型。在脚本 3 中,我们将network_type
变量设置为“全部”。这意味着我们将获取人行道、街道、高速公路等的数据。为了获取可行驶街道的相关数据,将脚本 3 第 8 行的network_type
变量设置为“行驶”。如果您想获取人行道的数据,请将network_type
设置为“步行”。
旁白:如果您想提取德克萨斯州达拉斯和德克萨斯州阿灵顿的数据,您可以运行以下脚本:
Script 3a— Grabbing spatial data for two cities.
脚本 3a 可能需要一些时间来运行,因为达拉斯地区很大。如果您想要更多城市的数据,只需将它们添加到places
列表中。我建议您访问 OSMNX 示例 Jupyter 笔记本来了解关于这个包的更多功能——在本文中我几乎没有展示它的功能。
拆开我们的数据
ox.graph_from_place()
方法返回的G
是来自 NetworkX 类的一个MultiDiGraph
对象。我们可以使用ox.plot_graph()
方法来制作地图,但首先让我们打开它,这样我们就可以为网络中的每条线段分配颜色和宽度。
Script 4 — Unpacks the data from the G MultiDiGraph object.
纸条 4 拆包G
。我们感兴趣的是保存在名为data
的列表中。data
中的每个元素都包含一个字典,该字典指定了一个段的属性,例如唯一 id、街道名称、最大速度、段的长度以及其他规范。下面是存储在data
中的第一个字典的例子:
Figure 2 — The first element of the list named data.
你可以看到第一段是一条名为佛蒙特街的住宅双向街,长 81.54 米。当路段类型为人行道/小道时,公路关键字的值将为“人行道”。人行道类型的线段可能没有名称。
为网络中的每个线段指定颜色和线宽
在我们制作地图之前,我们将为每一段指定一种颜色。为此,我们将遍历data
的元素。对于每个元素/片段,我们将根据其长度指定一种颜色。然后我们将这个颜色添加到一个名为roadColors
的列表中,这个列表稍后将作为变量传递给制作地图的方法。
Script 5 — Assigning colors to each segment based on their length. The length is in meters.
这里是你发挥创造力的地方。例如,您可以更改颜色,添加更多 if 语句,更改每个 if 语句的条件,根据段名或速度限制分配颜色。
最后,我们还将创建一个列表,用于定义每个线段的线条粗细。为此,我们将遍历data
的每个元素。数据中的项目是包含“高速公路”关键字的字典。我们将使用它来确定我们拥有的细分市场的类型。如果“highway”关键字的值是“footway ”,这意味着该线段用于步行,因此我们将为该元素指定线宽 1。任何不是“人行道”的部分,我们将指定 2.5 的线宽。根据你的地图的大小,你需要使用这个值来创建一个好看的地图。
Script 6 — Assign each segment a line width.
制作地图
我们终于准备好制作地图了。
Script 7 —Making a map for Lawrence, Kansas.
制作这张地图似乎需要做很多工作,但让我来解释一下脚本 7 中发生了什么:
第 4–6 行:这里我们指定堪萨斯州劳伦斯市的纬度和经度。这是地图的中心。你可以把地图放在任何你想要的纬度和经度的中心。
第 8–12 行:这里我们决定了地图的边界。您应该使用这条线来控制在地图上显示什么。例如,您可以通过向第 4–6 行中定义的纬度和经度分配较小的偏移量来关注城市中较小的区域,如市中心。
第 14–18 行:这里我们使用 OSMNX 包的ox.plot_graph()
方法制作地图。我建议您阅读 OSMNX 软件包文档,查看所有可用的输入。我将只讨论我在这里使用的。
G
:这是我们在脚本 3 中执行的ox.graph_from_place()
方法的输出。
bbox
:这是一个设置地图边界的元组。下面应该是语法(北界,南界,东界,西界)。
fig_height
和fig_width
:图形的高度和宽度,单位为英寸。
dpi
:每英寸点数。
bgcolor
:用于地图的背景色。默认为白色。
save
:布尔型。如果是,将图形作为图像文件保存到磁盘。我们将此设置为 false,因为我们还没有准备好保存该数字。
edge_colors
:线段的颜色。我们把这个设为等于roadColors
。你也可以只传递你想要的颜色的字符串。
edge_linewidth
:各线段的粗细。我们将其设为等于roadWidths
。你也可以只传递一个你想要的线条粗细的浮点数。
第 21–47 行:这些行组成一个自定义图例。如果你熟悉 Matplotlib,你应该不会感到陌生。
第 49–50 行:我们在这里保存图形。
如果您为堪萨斯州的劳伦斯市制作一张地图,其中每条线段的长度都用颜色进行了编码,那么您应该会看到以下内容:
Figure 3 — Map of Lawrence, Kansas where each segment is colored by length.
结果真的很酷。诀窍是选择正确的颜色、线条粗细、地图边界和背景色来制作一幅好看的地图。
向地图添加边框和文本
我们基本上完成了地图。然而,我想添加一个边界和一些文字地图,使它看起来更艺术一点。我们将首先定义一些我在 StackOverflow 中发现的助手函数:
Script 8 — Helper functions to add border to map.
我们现在准备给图像添加一个边框。我们将只添加一个底部边框图像,但如果你愿意,你可以选择在顶部、左侧、右侧和底部添加边框。阅读 helper 函数的 docstring 以获得更多关于如何做的细节。
Script 9— Adding border to map.
Figure 4 — Map of Lawrence, Kansas with a bottom border.
那看起来真的很好;).
最后,让我们添加一些文本到图像的底部边框。为此,我们首先需要下载字体。游览ShareFonts.net,搜索“PMINGLIU”。下载字体并将其内容解压缩到您的工作目录中。
Script 10 — Add text to the map. The font type and size are define in line 9. The position, the text, font color, and type of font are define in line 12.
Figure 5 — Map of Lawrence, Kansas.
我们到此为止。)
结束语
为你的家乡制作地图,修改剧本 3 中的第 5 行和剧本 7 中的第 5 行和第 6 行。为了给你的城市创建一个好看的地图,你必须调整地图的边界和线条的粗细。如果你不喜欢我用的颜色,欢迎你更换。我很想看看你制作的任何地图。这里是我的 GitHub 的链接,这样你就可以获得这篇文章的全部内容。
欢迎您在 LinkedIn 上与联系。直到下一次,每天编码!
打赌:预测人工智能自动驾驶汽车何时会流行
无人驾驶汽车问世的基本方程式
Defining an equation for predicting when AI self-driving cars will be prevalent
我们都喜欢一个好的等式。你引用或看过多少次爱因斯坦关于物质和能量的著名方程式?
最著名的概率公式之一是著名的德雷克方程,它是由弗兰克·德雷克在 20 世纪 60 年代设计的,旨在帮助激起关于我们银河系其他地方存在生命以及我们可能能够与之交流的可能性的讨论和辩论。
在这些努力中,一个特别有争议的因素是,我们是否应该对可能存在于别处的智慧生命进行被动搜索还是更主动的搜索。被动搜索包括简单地试图捕捉任何信号的行为,然后在地球上得到内部警报,也许有什么东西在那里。主动搜索包括发出信号,让地球之外的听众知道我们在这里,我们这样做是希望引起回应。当然,引起回应对我们来说可能是好的也可能是坏的,著名的斯蒂芬·霍金曾预先警告说,我们可能会捅马蜂窝,最终导致我们自己的毁灭和灭亡。
你可能会想,除了地球以外,在我们银河系的某个地方有智慧生命的可能性有多大?
让我们首先同意,我们主要对智慧生命感兴趣,这意味着如果某个地方存在某种原始生命,而它或它们无法通过任何现代手段进行交流,我们会把这些放在一边,认为不值得去寻找。
据推测,一种智慧生命形式会发出各种各样的电磁辐射,就像我们在地球上所做的那样。20 世纪 50 年代末,天文学家弗兰克·德雷克一直在西弗吉尼亚使用大型射电天文设备扫描从我们星球反射回来的无线电波。
一亿个世界可能可以维持生命
科学家和天文学家不断猜测数字,特别是宇宙中可能有 1 亿个星球可以维持我们所知的生命。一亿这个数字是怎么得出来的?它是基于这样一种信念,即可能有 1000 亿个太阳,这些太阳中可能有百万分之一的太阳有各种各样的行星围绕太阳旋转,这些行星中可能有百万分之一的行星由孕育生命所需的方面组成。如果你把它相乘,你会得到一亿颗理论上可能有生命存在的行星。
弗兰克·德雷克选择组织一个小型会议,召集那些对智能生命的严肃追求非常感兴趣的人,并希望展开热烈的讨论。在为会议做准备时,他决定记下一种方法来预测我们银河系中存在智慧生命的可能性。
弗兰克提出的方程从那以后成为了著名的德雷克方程,这是对他推导出该方程的肯定。多年来,有许多人指出,这个等式没有包括许多其他因素,而这些因素本来应该包括在内。这很好,这不是弗兰克的断言,他的方程是最终的一切。
弗兰克·德雷克的方程式包括试图得出一个数字 N,这个数字据称是我们银河系中可能展示智慧并有可能与之交流的文明的数量。
德雷克方程是这样的:N = R-star x 因子 p x 因子 ne x 因子 1 x 因子 i x 因子 c x 因子 L
本质上,您将七个关键因素相乘,就会得到数字 n。每个因素在逻辑上都是合理的,因为您在进行这种估计时会考虑这些因素。这些因素倾向于相互建立,以考虑一种饼的方式来做,其中你可以分割一个饼,以递增的方式做,直到你得到最后一片。
我希望你能明白,德雷克方程其实很简单,很容易理解。我这样说并不是在贬低这个公式。事实上,我为这个等式易于理解而喝彩。
如果这个公式是神秘的,我怀疑它会获得如此广泛的兴趣和流行。
乘以因子得到 N
另一个有趣的方面是,这些因素都是相乘的。同样,这意味着简单。
这些因素看起来很简单,方程看起来也很简单,这使得它非常适合使用和讨论。与此同时,让我们都同意,得出这些因素的数字有点更具挑战性。事实上,关于德雷克方程的大多数争论并不是方程本身,而是人们可能插入方程中的因素的估计。
德雷克和他的同事在 1961 年根据他的公式得出的 N 是多少?这个小组决定用一个范围来表示 N 更谨慎,他们通常得出一个介于 1000 到 100000000 之间的值。
在为估计范围辩护时,你可以说他们得出了一个大于零的数字,它也小于一些真正大的数字,如估计数十亿。
德雷克方程有点像一个有用的锚。有一个主持人就像种一棵树,然后你可以看着更多的话语围绕着它生长。
这和 AI 自动驾驶汽车有什么关系?
在控制论人工智能自动驾驶汽车研究所,我们正在开发自动驾驶汽车的人工智能软件。最直言不讳的国家和世界范围内的辩论之一涉及人工智能自动驾驶汽车何时可以投入使用。这个问题不断地在会议上出现,不断地被这个领域内的人提出,也不断地被公众、监管者和许多其他利益相关者提出。
我建议我们推导出一种德雷克方程来帮助辩论。请允许我详细说明。
我想首先澄清和介绍一个概念,即人工智能自动驾驶汽车有不同的级别。最顶层被认为是第 5 层。5 级自动驾驶汽车是由人工智能驾驶的汽车,没有人类驾驶员参与。
对于低于 5 级的自动驾驶汽车,必须有一名人类驾驶员在场。人类司机目前被认为是汽车行为的责任方。人工智能和人类司机共同分担驾驶任务。
人工智能自动驾驶汽车的另一个关键方面是,它们也将在人类驾驶的汽车中行驶在我们的道路上。
预测方程的特征
回到预测人工智能自动驾驶汽车到来的话题,让我们考虑一个等式的特征,它可能有助于如此重要的努力。
首先,考虑谁对人工智能自动驾驶汽车的到来做出预测。
有各种各样的技术专家提供他们对人工智能自动驾驶汽车的看法,并提出我们何时能在街道上看到这些车辆。技术专家的一个好处是,他们有望精通技术,并能够判断人工智能和自主能力进展的有效性。
让我们也考虑一下,那些真正精通人工智能自动驾驶汽车并做出预测的技术专家可能会在没有任何有形的韵律或理由的情况下这样做。有时他们会发表“直觉”或本能宣言。
纵观科技的历史,我们肯定看到了相当多过于乐观的预测,但在规定的时间内都没有实现。这是一个容易落入的陷阱。
我们还需要澄清的是,人工智能自动驾驶汽车的技术可以双管齐下,提供实现自主的能力,但也因为缺乏迄今为止已知的方法、技术和计算工具而抑制了自主。因此,我发现考虑技术进步和它们是如何形成的是有用的,同时也考虑已知的技术障碍甚至是未知的,并将在未来的道路上被发现。
许多做出预测的技术专家通常不包括其他看似与技术无关的因素,这些因素可能会极大地影响技术的发展速度。有人可能会说,这是一种疏忽。
什么样的因素会影响 AI 自动驾驶汽车的问世?
目前,投资和监管有利于人工智能自动驾驶汽车的发展
有些经济因素要么会鼓励在人工智能自动驾驶汽车开发上的支出,要么可能会抑制和破坏这种支出,如果这些支出被抽走并用于其他目的的话。
另一个关键因素是社会和社会对人工智能自动驾驶汽车的接受或抵制。人工智能自动驾驶汽车的进展可能会面临一个艰难的选择,即让它们进入我们的公共道路,同时让它们卷入致命的车祸。
考虑监管环境以及它如何影响人工智能自动驾驶汽车的到来也至关重要。目前,关于在公共道路上使用人工智能自动驾驶汽车的法规相对宽松,并鼓励这种萌芽的创新。如果监管机构突然受到压力,要对人工智能自动驾驶汽车采取一些措施,例如当自动驾驶汽车在道路上行驶时发生死亡或受伤时,它可能会迅速转向更严格的监管环境。
不能仅仅依靠技术专家的观点
我相信你现在已经确信,任何试图预测人工智能自动驾驶汽车到来的等式都不应该仅仅依赖于技术专家的观点。我们希望包括经济视角、社会视角和监管视角。这提供了一个混合的视角,当只使用一个单一的因素时,将有望避免被意外地抓住或被暗算。
这些因素中的每一个都不一定相互独立。事实上,它们很可能会一起朝着同一个方向摆动,尽管有时会有延迟。
在探索一系列因素时,你可能会认为每个因素最终都可能成为人工智能自动驾驶汽车的支持者和推动者,或者每个因素都可能成为反对者,往往会对人工智能自动驾驶汽车的到来造成阻力或抑制。这是一种推拉式的紧张。至关重要的是将这种张力包含在用于做出这种预测的等式中的因素中。
除了核心因素之外,还有其他问题需要考虑。为了这个新方程的目的,让我们假设我们正在试图预测真正的人工智能自动驾驶汽车在公认标准的第 5 级的到来。
我还想提一下,我们需要就某个事物的出现意味着什么达成共识。如果你可以制造一辆 5 级的人工智能自动驾驶汽车,你是否已经达到了该项目的“降临”?不,我不这么认为。尽管你可能做得很好,达到了 5 级实例,但在我们有一些人工智能自动驾驶汽车在周围行驶之前,说它们已经出现似乎是有问题的。
有多少是降临?如果有几十辆真正的人工智能自动驾驶汽车在我们的街道上行驶,那将是一个降临,还是我们需要更多,比如数百辆,或者数千辆。真正的人工智能自动驾驶汽车的普及程度是多少?
有各种方法来衡量流行程度。我将使事情简单化,并建议我们用当时在用汽车的百分比来衡量。正如前面提到的,我们将逐渐看到向人工智能自动驾驶汽车的切换,这将看到传统汽车的退役和人工智能自动驾驶汽车的不断增加。
在所有汽车的总人口中,我们可能会同意,一旦某个百分比成为真正的人工智能自动驾驶汽车,我们就达到了普及。假设你愿意接受这个前提,那么我们可以讨论它是 1%,10%,20%,30%,40%,50%,60%,70%,80%,90%,甚至可能是 100%,然后你会把它称为流行率(我使用了十进制的整数,但它当然可以是 1%到 100%之间的任何数字)。
让我们设定 20%为普遍意义
我现在要用 20%。为什么?在各种研究领域,20%经常被用来表示流行程度。这来自于环境和生物学领域的研究。这似乎是一个足够大的百分比,它不是微不足道的,但也没有大到似乎有些不可能达到。
在美国现有的传统汽车数量(如上所述约为 2.5 亿辆)的情况下,人工智能自动驾驶汽车的出现将占 20%,这是一个相当令人生畏的 5000 万辆这样的汽车。这是一个令人望而生畏的数字,因为想想达到这个数字可能需要多长时间。换句话说,即使人工智能自动驾驶汽车明天就准备好了,生产那么多自动驾驶汽车也需要一段时间,这些人工智能自动驾驶汽车也需要一段时间才能购买并投入使用。
我之前预测过,一旦我们实现了真正的人工智能自动驾驶汽车,很可能会有一个相当快的采用率。我这么说是因为那些真正的人工智能自动驾驶汽车将会赚钱。当有钱可赚的时候,需求就会猛增。这不仅仅是汽车车队,正如我所说,将会有一个由个人消费者组成的完整的家庭手工业,他们将购买人工智能自动驾驶汽车,以利用这些车辆作为个人用途和赚钱。
我现在已经为建立一个方程奠定了基础,这个方程可以用来预测人工智能自动驾驶汽车的到来。
这个谜题的最后一部分是关于基督降临的基础。通过使用一个基数,然后你可以用它乘以各种因子,看看得到的 N 是等于、大于还是小于稻草人基数。我将把基地称为 B 星。
请看图 1。
我们正在尝试求解 n。有一个基本的 B 星,然后乘以八个因子。
出于定义目的:
- n 是流行年数(YTP),使用插入式 20%作为 PV(流行)因子
- b 星是基本年数,然后根据每个因素进行调整
关键因素包括:
- 因子 TA: T 技术 A 进步,估计的分数
- 因素到: T 技术Ob 障碍,估计的小数
- 因子 EP:EeconomicPayoff,估计的小数金额
- 因素 ED: E 经济 D 雨,估计的一小部分量
- 因素 SF:So 其他 F 偏好,估计的分数
- 因数 SO:SOCI etalOp position,估计的小数金额
- 因素 RE: R 调节En 平衡,估计的小数金额
- 因子 RR: R 调节 R 限制,估计的小数
该等式由以下内容组成:
- N (PV 为 20%)= B-star x TA x TO x EP x ED x SF x SO x RE x RR
根据我之前的讨论,有四个主要因素涉及技术、经济、社会和监管问题。对于每个因素,都有推-拉因素,这意味着每个因素都可以被解释为促进和推动人工智能自动驾驶汽车问世的一个因素,还有一个伴随因素是拉人工智能自动驾驶汽车问世的拉力。这是四个关键因素,考虑到推拉效应,总共有八个关键因素。
类似于前面关于方程可用性的评论,我将这个方程保持为 9 个元素,这与流行的神奇数字 7 加或减 2 的经验法则相当。这些因素都很容易理解。这个等式很容易理解。
它无意成为终极目标。它旨在提供一种讨论和辩论的基础。如果没有一个支点,关于这个问题的争论和讨论往往是空洞和迂回的。
请看图 2。
如图所示,我填充了一个电子表格来利用这个等式。
首先,我选择展示如果你只考虑单一因素的观点会发生什么。例如,您可能仅使用技术专家的视角,因此这些因素是唯一填充的因素(其余因素被假设为不在等式中,而不是说值为零,这当然会消除计算)。同样,我展示了一个单独的经济视角,然后一个单独的社会视角,一个单独的监管视角。
在电子表格的最后两行,我提供了一个完整的组合。
我还选择展示乐观主义者的观点和悲观主义者的观点,对每个单因素实例和全混合实例都这样做。这与试图得出一个范围的值,而不是一个单独的值是一致的。乐观观点和悲观观点分别提供了估计的下限和估计的上限。
对于基本的 B 星,问题是使用什么数字。因为有许多专家似乎在 15 年左右浮动,所以我在这个说明性的例子中使用了这个数字。我们可以用 5 年、10 年、20 年、25 年或 30 年,所有这些都在媒体上流传。据推测,无论你选择哪一个基数,这些因素最终都会“修正”它,使其趋向于“实际”预测。
我们正在实施德尔菲法,以达到实质性的下限和上限。德尔菲法是一种成熟的预测方法,通常被称为 ETE(估计-谈话-估计)。在这种情况下,一组人工智能自动驾驶汽车领域的专家已经参与了一系列的德尔福轮次。在每一轮中,被选中的专家可以看到其他专家的指示,并在他们认为合适的时候调整他们自己的估计。
虽然德尔菲法通常受到高度重视,但它可能因群体思维的潜力而受到批评,有时也会因过度的共识而被削弱。尽管如此,这很有启发性,也是引发关于这个话题的有益讨论的另一种方式。
结论
什么时候会有 AI 自动驾驶汽车的问世?一些人通过模糊的预感来回答这个问题。通过使用这里提出的等式,希望可以进行更具体和更有条理的讨论和辩论。
你可能不喜欢所用的因子,或者你可能想添加额外的因子,但至少不管怎样,这个等式让树栽下来了。在降临问题上,从这些根将会期待一个广泛复杂的事业。
一些批评人工智能自动驾驶汽车的人说,我们永远不会有真正的人工智能自动驾驶汽车。如果是这样的话,我想 N 的数字要么是零(我们将定义为它永远不会发生),要么可能是无穷大。我想我会更乐观,会断言 N 有一个数,它既不是零,也不是无穷大,更接近于一个小于 100 的值,很可能小于 50。
方程式,我们喜欢它们,但有时我们讨厌它们(比如在考试或测验时记忆它们)。看看我提出的方程,看看你怎么想。插入一些值。仔细考虑将来可能发生的事情。虽然不是水晶球,但它是一种如何思考未来和真正的人工智能自动驾驶汽车出现的剧本。
关于这个故事的免费播客,请访问:http://ai-selfdriving-cars.libsyn.com/website
这些播客也可以在 Spotify、iTunes、iHeartRadio 等网站上下载。
更多关于人工智能自动驾驶汽车的信息,请参见:www . AI-self-driving-cars . guru
版权所有 2019 兰斯·艾略特博士
通过数据驱动的体育博彩策略“赚大钱”
深度剖析
或者如何在自己的号码上击败庄家
几个月前,我开发了一个 ML-free 算法,用一个简单的泊松过程来预测英超联赛的结果。该程序的跟踪记录比我想象的更令人印象深刻,在第一轮比赛中正确预测了 7/10 场比赛的结果(其中 3 场比赛有确切的比分)。
所以我完成了这个项目,把它放在一边,专注于我的功课。
我上周末看了阿森纳和曼联的比赛,在这场比赛中,主队被普遍认为是失败者。
Image by author. Screenshot from Google.
出乎所有人的意料,阿森纳队名列榜首。任何一种情况都有可能发生。联队在上半场两次击中门柱。但是,在这个混乱的赛季中,大卫·德基对查卡突然转身射门的罕见误判和慷慨的点球又增加了一个不可预测的结果。
我有没有提到托特纳姆热刺队在同一个周末被南安普顿队击败了?
随着英超联赛另一轮令人惊讶的结果的展开,我一直在思考我开发的算法。它能在一致的基础上正确预测结果吗?在这个模型中有一些内在的随机性,但这足以成为 PL 诱人的泰然自若的因素吗?在那里,降级区南安普顿队击败了全明星热刺队。
所以我决定把它带回来重新测试。
1。对抗专家的算法
测试一个算法的困难之一是找到一个好的性能基准。比方说,如果我的预测在 200 次匹配中有 50%的准确率,那么它是好的、坏的还是平庸的?这肯定比随机猜测要好(赢、平、输的概率都是 1/3),但听起来没那么好,不是吗?
把我的结果和职业足球专家比较怎么样?
所以我发现,每周,天空体育网站都会发布一个由保罗·默森【1】对那周比赛的预测,他是一位前阿森纳球员,后成为赢得过几个冠军的权威人士。
老实说,我不是保罗·默森的忠实粉丝,因为我认为他对他的前俱乐部进行了无情的批评。
听听阿森纳前主教练温格对他的评价:
我听到的这些辩论是一个笑话,一场闹剧。管理零场比赛的人,他们教每个人你应该如何表现。简直是闹剧。
尽管如此,这对我来说是一个金矿,因为我现在可以将我的算法与“专家”进行比较。不管你对他有什么看法,一个前阿森纳球员对阿森纳对曼联比赛的预测肯定会比一个随机产生数字的模糊模型更可靠。
The confusion matrix that shows how accurate Merson’s and my algorithm’s predictions are, over 273 matches. Left: Merson’s correctly predicts 150 matches or 54.9%. Right: The Poisson process algorithm got 51+7+117 = 175 matches, a whopping 64.1%
在这里,我比较了默森预测的本赛季 273 场比赛的结果。他达到了 54.9%的准确率(T1),而我的泊松过程算法达到了令人惊讶的 64.1%的准确率(T3)。
有趣的是,默森预测了阿森纳和曼联之间的 2-2 平局,他说“两队将会相互较量,并且会有进球。“我的算法,通过平均阿森纳主场的进球数和失球数,给阿森纳分配了 45%的微弱优势和获胜概率,相比之下,曼联为 27%。
2。从预测到体育博彩
结果让我大吃一惊。超过专家意见 10%的优势是巨大的。除了让心爱的泊松过程剔除数字之外,我甚至不用做太多事情。
这是我开始研究体育博彩的时候。而我进入新游戏对阵新对手: 是我对阵庄家 。
3.理解书签:赔率是如何工作的?
如果你曾经认为你信用卡上的条款和报价很复杂,试着去那些博彩网站试试。他们简直是疯了。
以美国的赔率为例。如果你看到一个+300 的赔率,这意味着如果你赌 100 并且赢了,你的收益是 300 美元。这很好,但是他们有负赔率,比如 150 的赔率。搞什么@#!$%那是?*这意味着为了赚取 100 美元的利润,你需要下 150 美元的赌注。因此,美国赔率是一个大于或等于 100 的数字,有时前面加一个+,表示这个数字是你的利润,有时前面加一个——表示你赢得 100 美元需要下注的金额。
我的意思是,他们仍然使用英尺和华氏温度
为了这个项目的目的,我们将使用一个更好的系统:欧洲赔率。很简单:他们告诉我,如果我赌 1 美元,我会赢回多少钱。例如, Bet365 给出阿森纳击败曼联的赔率为 2.4,平局为 3.6,马努获胜为 3。这意味着,如果我为阿森纳下了 1 美元的赌注,我的口袋里会有 2.4 美元(1.4 美元的利润)。
4。肮脏的小秘密
但是事情并不总是美好而简单的。实际上,为了实现利润最大化,博彩公司雇佣数据科学家团队来分析几十年的体育数据,并开发高度准确的模型来预测体育赛事的结果,并给出对他们有利的赔率。
让我们假设博彩公司的赔率是各个球队赢、平或输的概率的完美反映。因此,对于阿森纳和曼联的比赛,由于阿森纳获胜的赔率是 2.4,所以他们获胜的概率是 1/2.4 = 41.6%,出乎意料地接近我预测的 45%。同样,曼联获胜的概率是 1/3.0 = 33.3%,平局的概率是 1/3.6 = 27.8%。
等一下!!!
41.6% + 33.3% + 27.8% = 102.7%! 真是奇怪(没有双关语!!!)
概率加起来不是 100%的原因是几率不公平。那多出来的 2.7%就是庄家的优势。为了得到真实的概率,我们需要通过除以 102.7 来修正利润。所以博彩公司认为阿森纳获胜的真实概率是 41.6/102.7 = 40.5%,曼联获胜的概率是 33.3/102.7 = 32.5%,平局的概率是 27.8/102.7 = 27.06%。对于一个完全有效的博彩公司来说,这些是每种结果的概率。
现在,这是一件有趣的事情:如果赔率完美地反映了现实,那么我赌哪个结果并不重要——我的预期利润总是一样的。
如果我在阿森纳身上赌 1 美元,我希望能赢回来:
如果我为曼联下注,预期利润是一样的:
而且——你猜对了——如果我赌平局,我希望能赢回 97 美分。平均来说,每下 1 美元赌注,庄家会从我这里拿走大约 3 美分。
4.下注策略:
这种理解并没有阻止我试图利用市场中任何潜在的低效率。首先,我设计了一般的下注策略。
- 我列出了 1000 美元的预算,平均分配给前 30 轮英超联赛。所以每个周末我都有大约 33 美元可以下注。
- 对于每场比赛,将通过以下三种方法之一进行预测:(a)保罗·默森预测,(b)我的泊松过程算法,以及©等概率随机分配赢、平、输。
- 通过预测,我找到了 6 家在线投注站中赔率最高的。这意味着如果我赢了,我会得到最高的利润。这将是我下注的赔率。
- 对于每场比赛,赌注的金额将由凯利标准计算,该标准的工作原理是:你应该只投资你财富的一部分。通过保留一些,你不会以破产告终。最佳分数( f )取决于每个单独的赌注:
where p* is the probability that the event occurs and x is an odds
在 R 中实现凯利标准非常简单:
在凯利标准的公式中,问题仍然是什么被认为是事件的真实概率( p* )。*正如我们在前面的部分中所看到的,我们可以对任何特定的博彩公司给出的赔率取倒数,但这不会以很大的优势结束,因为他们倾向于对该公司有利。*然而,如果我们汇总来自许多不同博彩公司的所有赔率,我们应该能更好地反映博彩公司如何看待某个事件的概率,例如阿森纳击败曼联:
where n is the number of betting houses and xi is a given odds by the house i
The result of this betting strategy using the Poisson-process prediction for the last Matchweek, Round 30. This table shows how the max_odd, probabilities of prediction events, Kelly bet fraction, bet_amount are calculated
对于第 30 轮比赛,正确预测了 5 场比赛,从 6 家赌场中选择了最佳赔率,由于我们的下注策略中嵌入了泊松预测,这一轮我们总共净亏损 0.9 美元或 90 美分。我们最大的损失来自于切尔西主场对狼队没能抢下 3 分。
5。下面是最终结果
现在,假设我从英超联赛一开始就使用这个策略,让我们看看我们是如何迅速致富的。
我的算法和默森的预测——当结合凯利标准的最大奇数策略时,到第 30 个比赛周结束时,净正回报,泊松过程预测实现了惊人的 9.1% 回报,每个比赛周的归一化回报为 0.3% 。客观来看,先锋 S & P 500 ETF 的市场价格回报率为4.6%【4】。
随机法第一次迭代净亏 19% 主要是因为这里那里的几个幸运投注(曼联输给西汉姆)无法弥补大量的烂注(莱斯特,哈德斯菲尔德赢了伊蒂哈德,热刺输给伯恩茅斯,像老实说?).即使我多次重新运行随机预测,也足以说我见过随机方法有正回报的情况不到 10%。
显然,这种最优泊松模型存在固有风险。以第 24 轮比赛为例,我们净亏损 14 美元。默森和泊松过程模型(还有我!!!)对利物浦、曼城、曼联、切尔西分别拿下莱斯特、纽卡斯尔、伯恩利、伯恩茅斯 3 分非常有信心,提出总赌注 $19。结果:利物浦和曼联未能全取 3 分,而切尔西和曼城则被击败。都在同一个周末!!!
最后的话:
在你克隆我的 Github 回购协议并为你的体育对冲基金筹集资金之前,我应该明确表示,没有任何担保。你需要一大笔启动资金(我用 1000 美元模拟,但每周我只有 33 美元可以下注),大量的耐心和冷静的头脑。
如果有的话,这篇文章是一个玩具的例子,你可以做什么。但是博彩公司使得任何人都很难获得可持续的利润。如果博彩公司认为赢的概率是 1/6,那么他会通过将赔率设置为小于 5,也许是 4.6 这样的值来保证他的预期收入减去支出是正的。如果仍然有很多人以 4.6 的赔率下注,那么庄家肯定意识到赢的概率肯定高于他自己的估计,并将赔率调整为 4。很有可能当代码推断出最佳几率时,它已经被修改了。
此外,如果你开始定期盈利,博彩公司可以简单地感谢你的业务,支付你的奖金并取消你的账户。这就是发生在东京大学一个研究小组身上的事情。
在我们开始用真钱下注的几个月后,庄家开始严格限制我们的账户。我们的一些赌注被限制在我们可以下注的赌注金额内,庄家有时要求在接受之前对我们的赌注进行“人工检查”
- *** 重要免责声明:**本文纯粹用作教育材料,*不得视为法律或财务建议。也不建议打赌或赌博。请注意,体育博彩在美国的几个州是不合法的。
如果你喜欢这篇文章,你可能也会喜欢我的另一篇关于有趣的统计事实和经验法则的文章
- 迪士尼电影是对的——我们都是特殊的,从统计数据上看也是如此
- 优化生活的统计法则:呼唤效应
- 规则三:计算尚未发生事件的概率
对于其他深潜分析:
这个项目的完整代码可以在我的 Github 简介中找到
[1]https://www . sky sports . com/football/news/15205/11657461/保罗-莫森斯-预测-阿森纳-曼联-切尔西-狼队-还有更多
[2] 凯利,J. L. (1956)。《信息率新解》 (PDF)。 贝尔系统技术期刊 。35(4):917–926。doi:10.1002/j . 1538–7305.1956 . TB 03809 . x
[3] 考尼茨,l .等人(2017)。“用他们自己的数字击败博彩公司——以及在线体育博彩市场是如何被操纵的”(PDF)。阿尔维克斯
[4]https://advisors . vanguard . com/web/C1/Fas-investment products/VOO/performance