慎用AXIS2(续)

http://blog.youkuaiyun.com/mudboy/archive/2006/09/08/1194535.aspx    

一文中说到我使用AXIS2所遇到的一些问题,那是服务端的一些问题,但其实在自动生成客户端代码方面也有一些问题,场景如下:

1、  环境:前后端都是AXIS2,一些操作,部署或代码生成都安默认方式进行。

2、  后端发布SERVICE

3、  前端根据WSDL生成代码

4、  测试客户端,没有问题。

5、  更新服务端的一些东西(甚至只是重启服务端),注意未改变发布的接口。

6、  用上面的客户端测试,抛出异常,错误信息是“意料之外的元素***”,说白了就是解析不了返回的SOAP消息了。

7、  再生成一次代码,测试,OK

 

为了查明此问题,首先当然是看前后的WSDL是不是有变化,结果发现还真有一些变化,但只是一些消息申明的顺序有变化(为什么会有这样的变化,有些莫明其妙,没有深究),应该并不影响最终的SOAP生成,只是同层次的元素可能顺序会有些变化,比如:

从:

<a>

       <a1>a</a1>

<a2>a</a2>

<a3>a</a3>

<a4>a</a4>

</a>

 

变化成:

 

<a>

<a3>a</a3>   

<a1>a</a1>

<a2>a</a2>

<a4>a</a4>

</a>

 

按常理,如果SCHEMA中不规定元素的顺序,客户端不应该因为这种变化而无法成功解析,但看看AXIS2生成的客户端代码,却有些死板,位置变了/少了/多了都不行,必须一模一样,可想而知这样的代码在生产中是没有办法使用的。

最后解决办法是自己改了相应的解析代码,并且尽可能的灵活,即使顺序有变化或是增加了新元素,也不会影响响应的解析工作。

有时间的话干脆把AXIS2生成客户端的代码改造一下,不过,在改造前,还是先去下一个最新版本,看看有没有解决。

不过,用到这,也觉得有些如履薄冰的感觉,劝你还是慎用为妙!!

 
1. 问题描述 (2 points) 利用概率密度表进行概率密度计算,并利用Bayes公式对字符进行识别。 2. 问题的本质和分析 (10 points) 基于贝叶斯方法的手写字符识别是一种统计学习方法,它的本质是通过概率统计来模拟和推断手写字符的识别过程。这种方法利用贝叶斯定理,将观测到的手写字符数据与同字符的概率模型相结合,以确定哪个字符最有可能与给定的手写输入匹配。 公式: 3. 解决问题的思路,方法,思路的可性行和预期结果表现(避免截图和word打入公式)(10 points) 数据收集和预处理:收集手写字符图像数据,清理和标准化图像。 特征提取:从图像中提取有用的特征,如像素值或轮廓信息。 建立模型:使用贝叶斯方法建立字符类别的概率模型,包括特征分布和先验概率。 训练模型:使用训练数据估计模型参数。 分类:对新的手写字符图像,计算每个字符类别的后验概率,选择概率最高的类别作为识别结果。 评估性能:使用测试数据集来评估模型的准确性。 改进和部署:根据性能评估结果改进模型,然后部署到实际应用中。 4. 解决问题中遇到的难点 (3 points) 数据质量佳:手写字符数据可能受到噪音、模糊或变形的影响,导致识别难度增加。 特征提取:选择合适的特征和提取方法对于识别性能至关重要。同字符可能需要同的特征表示,而这通常需要领域知识。 数据平衡:某些字符类别可能具有较少的样本,导致模型训练均匀,影响性能。 参数调整:调整贝叶斯方法的参数,如平滑参数或深度学习模型的超参数,需要耗费时间和经验。 解释性:有时需要解释模型的决策过程,特别是在一些领域,如司法或医疗应用中。 5.与算法对应的关键代码的实现进行文字解释和注释, from sklearn import datasets import numpy as np import gzip def LoadMnistImages(filename): with gzip.open(filename, 'rb') as f: data = np.frombuffer(f.read(), np.uint8, offset=16) data = data.reshape(-1, 28 * 28) / 255.0 return data def LoadMnistLabels(filename): with gzip.open(filename, 'rb') as f: data = np.frombuffer(f.read(), np.uint8, offset=8) return data train_x = LoadMnistImages('train.gz') train_y = LoadMnistLabels('train_label.gz') test_x = LoadMnistImages('test.gz') test_y = LoadMnistLabels('test_label.gz') pz = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] pxz = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] grouped_image = [[], [], [], [], [], [], [], [], [], []] for y in range(10): num = 0 for idx, i in enumerate(train_y): if i == y: num = num + 1 grouped_image[y].append(train_x[idx]) pz[y] = num / len(test_y) accuracies = [] correct = 0 for idx, test in enumerate(test_x): for idx2, group in enumerate(grouped_image): for i in range(784): for g in group: if abs(g[i] - test[i]) < 5: # 阈值 pxz[idx2] = pxz[idx2] + 1 pxz[idx2] = pxz[idx2] / len(group) max = 0 for i in range(10): if pxz[i] + pz[i] > pxz[max] + pz[max]: max = i if max == test_y[idx]: correct = correct + 1 accuracy = correct / len(test_x) print('accuracy: ' + str(accuracy)) 5. 对结果进行分析,提出改进想法的动机,依据、算法设计和预期结果(10 points) 这个代码存在如下问题:比较图片的像素值时,认为只有像素值完全相同才时相同,这样会使准确率有所下降,如下: if g[i] == test[i]: pxz[idx2] = pxz[idx2] + 1 为了解决这个问题,我设定了阈值比较的方法: if abs(g[i] - test[i]) < 5: # 阈值 pxz[idx2] = pxz[idx2] + 1 通过for循环,找到一个最佳的阈值为5,使得准确率最高。 6.撰写格式 2.6.1 一致性的建议 整个项目的开发中,函数和对象的命名保持一致性,尤其是一个模块或者一个函数中的一致性更为重要。命名应遵循驼峰命名规则。 2.6.2 代码逻辑块 2.6.2.1 缩进 众所周知,python是通过缩进来进行代码布局的,使用pycharm可以配置几个空格来代表一个tab,从而来布局代码的缩进。 2.6.2.2 混用Tab键和空格 Python 里有一句话叫“以用空格为荣,以用Tab键为耻”。但全用空格时确实很麻烦。因此,这里限定用 Tab 键还是空格。但记住:可混用! print("Hello world") #Tab换行 2.6.2.3 规范行的最大长度 如果代码的某一行很长,我们需要换行折叠观看代码,这会影响代码的阅读。因此,对顺序排放的大块代码,推荐长度在72个字节以内,另外推荐使用反斜杠行。 if (first_result >=0.5 and second_result >=0.5) or \ #反斜杠(second_result >=0.5 and last_result>=0.5) : last_result = max(first_result,second_result,last_result) 2.6.2.4 用代码块体现程序逻辑 通常,我们用两行分割顶层函数和类的定义, 用一行分割类成员方法的定义。 在一个函数内使用空格时请注意谨慎使用于一个逻辑段。 class A: a = 42 b = list(a + i for i in range(10)) 2.6.3 注释规范 注释是指对一部分代码的文字解释。注释内容必须跟代码保持一致,当你想修改代码时,建议优先修改注释。 注释必须是一个完整的句子。如果注释只有一句话,建议省略句末的句号。 注释块由一个或多个完整句子构成,每个句子应该以句号结尾。 注释阅读统一用英文或中文。使用统一注释格式有助于良好的习惯和团队的进步。 x = 1 # 给x赋值为1 2.6.3.1 注释块 注释块通常应用于跟随着一些(或者全部)代码并和这些代码有着相同的缩进层次。注释块中每行以’#'和一个空格开始(除非他是注释内的缩进文本)。 注释块内的段落以仅含单个’#'的行分割。 注释块上下方最好有一空行包围(或上方两行下方一行,对一个新函数定义段的注释)。 # print(a) # print(b) # # print(c) 2.6.3.2 行内注释 行内注释应该至少用两个空格和语句分开,他们应该以’#'和单个空格开始。 Dict = dict(zip(map(str,range(10)), range(10))) #创建长度为10的字典 图1-45行内注释 如果语意易理解,那么行内注释是必要的,事实上是应该被去掉的,要这样写: x = x + 1 #increment x 图1-46 注释错误示例 2.6.4 命名规范 命名规范在编写代码中起到很重要的作用,使用命名规范可以更加直观地了解代码所代表的含义,让代码具有有可读性、易写性与明义性。骆驼式命名法(Camel-Case)一词来自 Perl 语言中普遍使用的大小写混合格式,又称驼峰式命名法,是电脑程式编写时的一套命名规则(惯例),并无绝对与强制,为的是增加识别和可读性。驼峰式命名法是指混合使用大小写字母来构成变量和函数的名字。  驼峰命名法(CamelCase) 驼峰法(即帕斯卡命名法)单词首字母均大写。 class MyNaiveBayesClassifier:  匈牙利命名法(HN-case) 变量名可依次由属性、类型、描述组成。 iUserName #i为int类型缩写,UserName是描述。  蛇形命名法 函数通常全由小写字母和下划线组成,小写单词间用下划线连接 def use_naivebayes_as_classifier(): 2.6.4.1 命名风格 命名风格应该遵循驼峰命名规则。 class MyNaiveBayesClassifier: 此外,还需要注意: 1)单下划线作为前导,如:_single_begin,这是弱的内部使用标识,例如我们在M文件中定义如下变量: _a = 1 但是在使用"from M import *"的时候变量会被导入; print(_a) # NameError: name '_a' is not defined 2)单下划线作为结尾的,如:single_end_,这一般用于避免跟 python 关键词冲突; class_ = "This is not a class, just a variable." 3)双下划线前导,如:__double_begin,类私有名; class Test: def __init__(self): self.__private_var = 10 4) 双下划线前导+结尾,如:double_begin_and_end,特殊对象或属性,存在于用户控制的命名空间中,如:int,__import__等。有时可以被用户定义,用于触发某个特殊行为,如运算符重载。 class Test: def __str__(self): return "This is a Test class." 2.6.4.2 应避免的对象命名 为了避免文字显示的差异,永远要用: 1)小写字母“l”(小写的"L")2)大写字母“O”; 3)大写字母“I”(读音 eye); 作为单字符的变量名,因为利于跟数字“0”和”1“很好的区分开来。 当要用小写字母“l”时,请用大写字母“L”代替。  变量名必须是一个有效的标识符;  变量名用使用Python中的保留字;  慎用小写字面l和大写字母O;  应选用有意义的词作为变量; 尽量小写, 如有多个单词,用下划线隔开即采用蛇形命名法(snake_case)命名。 i = 0 if i > 0: number = 0 school_name = "Tsinhua" 常量采用全大写,如多个单词,用下划线隔开。 PAI = 3.14 MAX_CONNECTION = 100 CONNECTION_TIMEOUT = 500 2.6.4.3 模块命名 模块尽量使用小写命名,首字母保持小写,尽量要用下划线(除非多个单词,且数量多的情况)(加入下划线可改善可读性)。因为模块名被映射到文件名,有些文件系统大写敏感并且截短长名字,模块名被选为相当短是重要的—这在 Unix 上是问题,但当代码传到 Mac 或 Windows 上就可能是个问题了。 import decoder # 正确的模块名 import html_parser # 正确的模块名 import Decoder # 推荐的模块名 2.6.4.4 类命名 类名总是使用首字母大写式驼峰,例如:ClassName(),命名单词串的约定。 Class ClassName(): #定义一个类 2.6.4.5 全局变量命名 这个的约定跟用于函数的约定差多。那些模块,应该在那些想被导入的全局变量(还有内部函数和类)前加一个下划线。例如:GLOBAL_VAR global GLOBAL_VAR #定义一个全局变量GLOBAL_VAR 2.6.4.6 函数命名 函数命名函数名应该为小写、动宾短语,可能用下划线风格单词以增加可读性。如:open_file()表示打开一个文件, def open_file(): #定义一个打开文件的函数 如果需要表明能快速打开一个文件,命名还可以为 def fast_open_file(): #定义一个快速打开文件的函数 class MyNaiveBayesClassifier: # 驼峰命名法定义一个类 '''定义一个NaiveBayesClassifier的类 #一句话总结这个类的功能和作,文档字符串需要用三引号包括 Attributes: class_probs: 类别先验概率(Numpy) feature_probs: 特征条件概率(Numpy) ''' def __init__(self): self.class_probs = None # 初始化参数 self.feature_probs = None def fit(self, X_train, y_train): '''定义fit函数计算朴素贝叶斯的训练过程 Attributes: X_train:训练使用的数据(Numpy) y_train:训练使用的类别(Numpy) ''' num_samples, num_features = X_train.shape #样本数量,特征数量 self.classes = np.unique(y_train) #类别数量 num_classes = len(self.classes) self.class_probs = np.zeros(num_classes) # 计算类别先验概率P(z) for i, c in enumerate(self.classes): self.class_probs[i] = np.sum(y_train == c) / num_samples # 计算特征条件概率P(x_1,x_2,…,x_784|z) self.feature_probs = np.zeros((num_classes, num_features)) for i, c in enumerate(self.classes): X_c = X_train[y_train == c] self.feature_probs[i] = (np.sum(X_c, axis=0) + 1) / #反斜杠实现换行 (np.sum(X_c) + num_features) def predict(self, X_test): '''定义predict函数计算类别先验概率P(z|X) Attributes: X_test:测试使用的数据(Numpy) return: 预测结果(Numpy) ''' num_samples, _ = X_test.shape num_classes, num_features = self.feature_probs.shape y_pred = np.zeros(num_samples) # 初始化预测结果数组 for i in range(num_samples): posteriors = np.zeros(num_classes) for j in range(num_classes): # 计算后验概率 posteriors[j] = np.log(self.class_probs[j]) + / np.sum(np.log(self.feature_probs[j]) * X_test[i]) y_pred[i] = np.argmax(posteriors) return y_pred 按上述格式撰写报告,且满足撰写格式
最新发布
10-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值