Python语法中的模糊语义,你知道吗?
Posted 小小程序员ol
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python语法中的模糊语义,你知道吗?相关的知识,希望对你有一定的参考价值。
1. 切片不执行越界检查和报错
下面代码的输出结果将是什么?
list = [\'a\', \'b\', \'c\', \'d\', \'e\']
print list[10:]
下面的代码将输出空列表 [] ,不会产生IndexError错误。就像所期望的那样,尝试用超出成员的个数的index来获取某个列表的成员。
例如,尝试获取 list[10] 和之后的成员,会导致 IndexError .
然而,尝试获取列表的切片,开始的index超过了成员个数不会产生IndexError,而是仅仅返回一个空列表。
这成为特别让人恶心的疑难杂症,因为运行的时候没有错误产生,导致bug很难被追踪到。
2. 空列表的创建
1ist = [[ ]] * 5
list # output?
list[0].append(10)
list # output?
list[1].append(20)
list # output?
list.append (30)
list # output?
2,4,6,8行将输出什么结果?试解释。
输出的结果如下
[[],[],[],[],[]]
[[10],[10],[10],[10],[10]]
[[10,20],[10,20],[10,20]]
[[10,20],[10,20],[10,20],[10,20],[10,20],30]
第一行的输出结果直觉上很容易理解,例如 list = [ [ ] ] * 5 就是简单的创造了5个空列表。然而,理解表达式 list=[ [ ] ] * 5 的关键一点是它不是创造一个包含五个独立列表的列表,而是它是一个创建了包含对同一个列表五次引用的列表。只有了解了这一点,我们才能更好的理解接下来的输出结果。
3. 重点来了:闭包的延迟绑定
下面这段代码的输出结果将是什么?请解释。
\'\'\'
学习中遇到问题没人解答?小编创建了一个Python学习交流群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
\'\'\'
def multipliers():
return [lambda x : i*x for i in range(4)]
print [m(2) for m in multipliers()]
你如何修改上面的multipliers的定义产生想要的结果?
上面代码输出的结果是 [6, 6, 6, 6] ,而不是我们想的 [0, 2, 4, 6] 。
上述问题产生的原因是Python闭包的延迟绑定。这意味着内部函数被调用时,参数的值在闭包内进行查找。因此,当任何由multipliers()返回的函数被调用时,i的值将在附近的范围进行查找。那时,不管返回的函数是否被调用,for循环已经完成,i被赋予了最终的值3。
因此,每次返回的函数乘以传递过来的值3,因为上段代码传过来的值是2,它们最终返回的都是6(3*2)。碰巧的是,《The Hitchhiker’s Guide to Python》也指出,在与lambdas函数相关也有一个被广泛被误解的知识点,不过跟这个case不一样。由lambda表达式创造的函数没有什么特殊的地方,它其实是和def创造的函数式一样的。
下面是解决这一问题的一些方法。
一种解决方法就是用Python生成器。
def multipliers():
for i in range(4): yield lambda x : i * x
另外一个解决方案就是创造一个闭包,利用默认函数立即绑定。
def multipliers():
return [lambda x, i=i : i * x for i in range(4)]
还有种替代的方案是,使用偏函数:
from functools import partial
from operator import mul
def multipliers():
return [partial(mul, i) for i in range(4)]
模糊 C 均值算法是不是可用于 Python?
【中文标题】模糊 C 均值算法是不是可用于 Python?【英文标题】:Is a Fuzzy C-Means algorithm available for Python?模糊 C 均值算法是否可用于 Python? 【发布时间】:2011-10-07 20:36:18 【问题描述】:我在 3 维空间中有一些点,想将它们聚集在一起。我知道 Pythons 模块“集群”,但它只有 K-Means。你知道有 FCM (Fuzzy C-Means) 的模块吗?
(如果你知道其他一些与集群相关的 python 模块,你可以将它们命名为奖励。但重要的问题是 python 中的 FCM 算法。)
Matlab
在 Matlab 中使用 FCM 似乎很容易(example)。 Python 不能使用类似的东西吗?
NumPy、SciPy 和 Sage
我没有在 NumPy、SciPy 或 Sage 中找到 FCM。我已经下载了文档并进行了搜索。没有结果
Python 集群
集群模块似乎将在下一个版本中添加模糊 C-Means(请参阅Roadmap)。但我现在需要它
【问题讨论】:
我会看看numpy
和scipy
。
this other question 下的一些选项可能对您有用。
【参考方案1】:
Python
PyPI 中有一个fuzzy-c-means 包。查看链接:fuzzy-c-means Python
这是在 python 中使用 FCM 的最简单方法。希望对您有所帮助。
【讨论】:
【参考方案2】:我使用 K++ 初始化从头开始完成(使用固定种子和 5 个质心。将其添加到您想要的质心数量应该不会太难):
# K++ initialization Algorithm:
import random
def initialize(X, K):
C = [X[0]]
for k in range(1, K):
D2 = scipy.array([min([scipy.inner(c-x,c-x) for c in C]) for x in X])
probs = D2/D2.sum()
cumprobs = probs.cumsum()
np.random.seed(20) # fixxing seeds
#random.seed(0) # fixxing seeds
r = scipy.rand()
for j,p in enumerate(cumprobs):
if r < p:
i = j
break
C.append(X[i])
return C
a = initialize(data2,5) # "a" is the centroids initial array... I used 5 centroids
# Now the Fuzzy c means algorithm:
m = 1.5 # Fuzzy parameter (it can be tuned)
r = (2/(m-1))
# Initial centroids:
c1,c2,c3,c4,c5 = a[0],a[1],a[2],a[3],a[4]
# prepare empty lists to add the final centroids:
cc1,cc2,cc3,cc4,cc5 = [],[],[],[],[]
n_iterations = 10000
for j in range(n_iterations):
u1,u2,u3,u4,u5 = [],[],[],[],[]
for i in range(len(data2)):
# Distances (of every point to each centroid):
a = LA.norm(data2[i]-c1)
b = LA.norm(data2[i]-c2)
c = LA.norm(data2[i]-c3)
d = LA.norm(data2[i]-c4)
e = LA.norm(data2[i]-c5)
# Pertenence matrix vectors:
U1 = 1/(1 + (a/b)**r + (a/c)**r + (a/d)**r + (a/e)**r)
U2 = 1/((b/a)**r + 1 + (b/c)**r + (b/d)**r + (b/e)**r)
U3 = 1/((c/a)**r + (c/b)**r + 1 + (c/d)**r + (c/e)**r)
U4 = 1/((d/a)**r + (d/b)**r + (d/c)**r + 1 + (d/e)**r)
U5 = 1/((e/a)**r + (e/b)**r + (e/c)**r + (e/d)**r + 1)
# We will get an array of n row points x K centroids, with their degree of pertenence
u1.append(U1)
u2.append(U2)
u3.append(U3)
u4.append(U4)
u5.append(U5)
# now we calculate new centers:
c1 = (np.array(u1)**2).dot(data2) / np.sum(np.array(u1)**2)
c2 = (np.array(u2)**2).dot(data2) / np.sum(np.array(u2)**2)
c3 = (np.array(u3)**2).dot(data2) / np.sum(np.array(u3)**2)
c4 = (np.array(u4)**2).dot(data2) / np.sum(np.array(u4)**2)
c5 = (np.array(u5)**2).dot(data2) / np.sum(np.array(u5)**2)
cc1.append(c1)
cc2.append(c2)
cc3.append(c3)
cc4.append(c4)
cc5.append(c5)
if (j>5):
change_rate1 = np.sum(3*cc1[j] - cc1[j-1] - cc1[j-2] - cc1[j-3])/3
change_rate2 = np.sum(3*cc2[j] - cc2[j-1] - cc2[j-2] - cc2[j-3])/3
change_rate3 = np.sum(3*cc3[j] - cc3[j-1] - cc3[j-2] - cc3[j-3])/3
change_rate4 = np.sum(3*cc4[j] - cc4[j-1] - cc4[j-2] - cc4[j-3])/3
change_rate5 = np.sum(3*cc5[j] - cc5[j-1] - cc5[j-2] - cc5[j-3])/3
change_rate = np.array([change_rate1,change_rate2,change_rate3,change_rate4,change_rate5])
changed = np.sum(change_rate>0.0000001)
if changed == 0:
break
print(c1) # to check a centroid coordinates c1 - c5 ... they are the last centroids calculated, so supposedly they converged.
print(U) # this is the degree of pertenence to each centroid (so n row points x K centroids columns).
我知道它不是很 Python,但我希望它可以成为您完整的模糊 C 均值算法的起点。我认为“软聚类”是数据不易分离的方式(例如,当“t-SNE 可视化”将所有数据显示在一起而不是清楚地分开显示组时。在这种情况下,强制数据严格属于只有一个集群可能是危险的)。我会尝试将 m = 1.1 改为 m = 2.0,这样您就可以看到模糊参数对 pertenence 矩阵的影响。
【讨论】:
【参考方案3】:看看scikit-fuzzy 包。它具有非常基本的模糊逻辑功能,包括模糊 c-means 聚类。
【讨论】:
【参考方案4】:PEACH 将提供一些模糊 C 均值功能: http://code.google.com/p/peach/
但是,由于 wiki 是空的,因此似乎没有任何可用的文档。可以在其网站上找到example for using FCM with PEACH。
【讨论】:
我刚刚安装了它并调用了帮助: class FuzzyCMeans - 使用这个类来实例化一个模糊的 c-means 对象。必须给对象一个训练集和初始条件。我没有训练集。 你也可以在peach.googlecode.com/svn/trunk/peach/fuzzy/cmeans.py看到代码和帮助,上面说训练集就是你想要聚类的数据。提供的示例显示,您可以随机选择初始条件以上是关于Python语法中的模糊语义,你知道吗?的主要内容,如果未能解决你的问题,请参考以下文章