A. GetLength(this string str)参数加this有什么用
文字来源:MSDN---扩展方法(C# 编程指南)扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。仅当您使用 using 指令将命名空间显式导入到源代码中之后,扩展方法才位于范围中。下面的示例演示为 System..::.String 类定义的一个扩展方法。请注意,它是在非嵌套、非泛型静态类内部定义的:namespace ExtensionMethods{public static class MyExtensions{public static int wordCount(this String str){return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;}}} 可使用以下 using 指令将 WordCount 扩展方法放入范围中:using ExtensionMethods;而且,可以在应用程序中使用以下语法对该扩展方法进行调用:string s = "Hello Extension Methods"; int i = s.WordCount();在代码中,可以使用实例方法语法调用该扩展方法。但是,编译器生成的中间语言 (IL) 会将代码转换为对静态方法的调用。因此,并未真正违反封装原则。实际上,扩展方法无法访问它们所扩展的类型中的私有变量。通用准则 通常,建议您只在不得已的情况下才实现扩展方法,并谨慎地实现。只要有可能,必须扩展现有类型的客户端代码都应该通过创建从现有类型派生的新类型来达到这一目的。有关更多信息,请参见继承(C# 编程指南)。在使用扩展方法来扩展您无法更改其源代码的类型时,您需要承受该类型实现中的更改会导致扩展方法失效的风险。如果您确实为给定类型实现了扩展方法,请记住以下两点:如果扩展方法与该类型中定义的方法具有相同的签名,则扩展方法永远不会被调用。扩展方法被在命名空间级别放入范围中。例如,如果您在同一个名为 Extensions 的命名空间中具有多个包含扩展方法的静态类,则这些扩展方法将全部由 using Extensions; 指令放入范围中。类库的实施者不应使用扩展方法来避免创建程序集的新版本。
B. 大家对spark的源码了解多少,sparkshuffle,调度,sparkstreaming的源码
流(Streaming),在大数据时代为数据流处理,就像水流一样,是数据流;既然是数据流处理,就会想到数据的流入、数据的加工、数据的流出。
日常工作、生活中数据来源很多不同的地方。例如:工业时代的汽车制造、监控设备、工业设备会产生很多源数据;信息时代的电商网站、日志服务器、社交网络、金融交易系统、黑客攻击、垃圾邮件、交通监控等;通信时代的手机、平板、智能设备、物联网等会产生很多实时数据,数据流无处不在。
在大数据时代SparkStreaming能做什么?
平时用户都有网上购物的经历,用户在网站上进行的各种操作通过Spark Streaming流处理技术可以被监控,用户的购买爱好、关注度、交易等可以进行行为分析。在金融领域,通过Spark Streaming流处理技术可以对交易量很大的账号进行监控,防止罪犯洗钱、财产转移、防欺诈等。在网络安全性方面,黑客攻击时有发生,通过Spark Streaming流处理技术可以将某类可疑IP进行监控并结合机器学习训练模型匹配出当前请求是否属于黑客攻击。其他方面,如:垃圾邮件监控过滤、交通监控、网络监控、工业设备监控的背后都是Spark Streaming发挥强大流处理的地方。
大数据时代,数据价值一般怎么定义?
所有没经过流处理的数据都是无效数据或没有价值的数据;数据产生之后立即处理产生的价值是最大的,数据放置越久或越滞后其使用价值越低。以前绝大多数电商网站盈利走的是网络流量(即用户的访问量),如今,电商网站不仅仅需要关注流量、交易量,更重要的是要通过数据流技术让电商网站的各种数据流动起来,通过实时流动的数据及时分析、挖掘出各种有价值的数据;比如:对不同交易量的用户指定用户画像,从而提供不同服务质量;准对用户访问电商网站板块爱好及时推荐相关的信息。
SparkStreaming VSHadoopMR:
Spark Streaming是一个准实时流处理框架,而Hadoop MR是一个离线、批处理框架;很显然,在数据的价值性角度,Spark Streaming完胜于Hadoop MR。
SparkStreaming VS Storm:
Spark Streaming是一个准实时流处理框架,处理响应时间一般以分钟为单位,也就是说处理实时数据的延迟时间是秒级别的;Storm是一个实时流处理框架,处理响应是毫秒级的。所以在流框架选型方面要看具体业务场景。需要澄清的是现在很多人认为Spark Streaming流处理运行不稳定、数据丢失、事务性支持不好等等,那是因为很多人不会驾驭Spark Streaming及Spark本身。在Spark Streaming流处理的延迟时间方面,Spark定制版本,会将Spark Streaming的延迟从秒级别推进到100毫秒之内甚至更少。
SparkStreaming优点:
1、提供了丰富的API,企业中能快速实现各种复杂的业务逻辑。
2、流入Spark Streaming的数据流通过和机器学习算法结合,完成机器模拟和图计算。
3、Spark Streaming基于Spark优秀的血统。
SparkStreaming能不能像Storm一样,一条一条处理数据?
Storm处理数据的方式是以条为单位来一条一条处理的,而Spark Streaming基于单位时间处理数据的,SparkStreaming能不能像Storm一样呢?答案是:可以的。
业界一般的做法是Spark Streaming和Kafka搭档即可达到这种效果,入下图:
总结:
使用Spark Streaming可以处理各种数据来源类型,如:数据库、HDFS,服务器log日志、网络流,其强大超越了你想象不到的场景,只是很多时候大家不会用,其真正原因是对Spark、spark streaming本身不了解。
C. hadoop hdfs 源码怎么看
在使用Hadoop的过程中,很容易通过FileSystem类的API来读取HDFS中的文件内容,读取内容的过程是怎样的呢?今天来分析客户端读取HDFS文件的过程,下面的一个小程序完成的功能是读取HDFS中某个目录下的文件内容,然后输出到控制台,代码如下:
[java] view plain
public class LoadDataFromHDFS {
public static void main(String[] args) throws IOException {
new LoadDataFromHDFS().loadFromHdfs("hdfs://localhost:9000/user/wordcount/");
}
public void loadFromHdfs(String hdfsPath) throws IOException {
Configuration conf = new Configuration();
Path hdfs = new Path(hdfsPath);
FileSystem in = FileSystem.get(conf);
//in = FileSystem.get(URI.create(hdfsPath), conf);//这两行都会创建一个DistributedFileSystem对象
FileStatus[] status = in.listStatus(hdfs);
for(int i = 0; i < status.length; i++) {
byte[] buff = new byte[1024];
FSDataInputStream inputStream = in.open(status[i].getPath());
while(inputStream.read(buff) > 0) {
System.out.print(new String(buff));
}
inputStream.close();
}
}
}
FileSystem in = FileSystem.get(conf)这行代码创建一个DistributedFileSystem,如果直接传入一个Configuration类型的参数,那么默认会读取属性fs.default.name的值,根据这个属性的值创建对应的FileSystem子类对象,如果没有配置fs.default.name属性的值,那么默认创建一个org.apache.hadoop.fs.LocalFileSystem类型的对象。但是这里是要读取HDFS中的文件,所以在core-site.xml文件中配置fs.default.name属性的值为hdfs://localhost:9000,这样FileSystem.get(conf)返回的才是一个DistributedFileSystem类的对象。 还有一种创建DistributedFileSystem这种指定文件系统类型对像的方法是使用FileSystem.get(Configuration conf)的一个重载方法FileSystem.get(URI uri, Configuration),其实调用第一个方法时在FileSystem类中先读取conf中的属性fs.default.name的值,再调用的FileSystem.get(URI uri, Configuration)方法。
D. python gensim怎么用word2vect
词向量(word2vec)原始的代码是C写的,python也有对应的版本,被集成在一个非常牛逼的框架gensim中。
我在自己的开源语义网络项目graph-mind(其实是我自己写的小玩具)中使用了这些功能,大家可以直接用我在上面做的进一步的封装傻瓜式地完成一些操作,下面分享调用方法和一些code上的心得。
1.一些类成员变量:
[python]view plain
def__init__(self,modelPath,_size=100,_window=5,_minCount=1,_workers=multiprocessing.cpu_count()):
self.modelPath=modelPath
self._size=_size
self._window=_window
self._minCount=_minCount
self._workers=_workers
modelPath是word2vec训练模型的磁盘存储文件(model在内存中总是不踏实),_size是词向量的维度,_window是词向量训练时的上下文扫描窗口大小,后面那个不知道,按默认来,_workers是训练的进程数(需要更精准的解释,请指正),默认是当前运行机器的处理器核数。这些参数先记住就可以了。
2.初始化并首次训练word2vec模型
完成这个功能的核心函数是initTrainWord2VecModel,传入两个参数:corpusFilePath和safe_model,分别代表训练语料的路径和是否选择“安全模式”进行初次训练。关于这个“安全模式”后面会讲,先看代码:
[python]view plain
definitTrainWord2VecModel(self,corpusFilePath,safe_model=False):
'''''
initandtrainaneww2vmodel
(,
aboutsoft_model:
ifsafe_modelistrue,,
andthiscankeeptheusageofos'smemorysafebutslowly.
andifsafe_modelisfalse,
.)
'''
extraSegOpt().reLoadEncoding()
fileType=localFileOptUnit.checkFileState(corpusFilePath)
iffileType==u'error':
warnings.warn('loadfileerror!')
returnNone
else:
model=None
iffileType==u'opened':
print('trainingmodelfromsingleFile!')
model=Word2Vec(LineSentence(corpusFilePath),size=self._size,window=self._window,min_count=self._minCount,workers=self._workers)
eliffileType==u'file':
corpusFile=open(corpusFilePath,u'r')
print('trainingmodelfromsingleFile!')
model=Word2Vec(LineSentence(corpusFile),size=self._size,window=self._window,min_count=self._minCount,workers=self._workers)
eliffileType==u'directory':
corpusFiles=localFileOptUnit.listAllFileInDirectory(corpusFilePath)
print('!')
ifsafe_model==True:
model=Word2Vec(LineSentence(corpusFiles[0]),size=self._size,window=self._window,min_count=self._minCount,workers=self._workers)
forfileincorpusFiles[1:len(corpusFiles)]:
model=self.updateW2VModelUnit(model,file)
else:
sentences=self.loadSetencesFromFiles(corpusFiles)
model=Word2Vec(sentences,size=self._size,window=self._window,min_count=self._minCount,workers=self._workers)
eliffileType==u'other':
#TODOaddsentenceslistdirectly
pass
model.save(self.modelPath)
model.init_sims()
print('procingword2vecmodel...ok!')
returnmodel
首先是一些杂七杂八的,判断一下输入文件路径下访问结果的类型,根据不同的类型做出不同的文件处理反应,这个大家应该能看懂,以corpusFilePath为一个已经打开的file对象为例,创建word2vec model的代码为:
[python]view plain
model=Word2Vec(LineSentence(corpusFilePath),size=self._size,window=self._window,min_count=self._minCount,workers=self._workers)
其实就是这么简单,但是为了代码健壮一些,就变成了上面那么长。问题是在面对一个路径下的许多训练文档且数目巨大的时候,一次性载入内存可能不太靠谱了(没有细研究gensim在Word2Vec构造方法中有没有考虑这个问题,只是一种习惯性的警惕),于是我设定了一个参数safe_model用于判断初始训练是否开启“安全模式”,所谓安全模式,就是最初只载入一篇语料的内容,后面的初始训练文档通过增量式学习的方式,更新到原先的model中。
上面的代码里,corpusFilePath可以传入一个已经打开的file对象,或是一个单个文件的地址,或一个文件夹的路径,通过函数checkFileState已经做了类型的判断。另外一个函数是updateW2VModelUnit,用于增量式训练更新w2v的model,下面会具体介绍。loadSetencesFromFiles函数用于载入一个文件夹中全部语料的所有句子,这个在源代码里有,很简单,哥就不多说了。
3.增量式训练更新word2vec模型
增量式训练w2v模型,上面提到了一个这么做的原因:避免把全部的训练语料一次性载入到内存中。另一个原因是为了应对语料随时增加的情况。gensim当然给出了这样的solution,调用如下:
[python]view plain
defupdateW2VModelUnit(self,model,corpusSingleFilePath):
'''''
(onlycanbeasingleFile)
'''
fileType=localFileOptUnit.checkFileState(corpusSingleFilePath)
iffileType==u'directory':
warnings.warn('cannotdealadirectory!')
returnmodel
iffileType==u'opened':
trainedWordCount=model.train(LineSentence(corpusSingleFilePath))
print('updatemodel,updatewordsnumis:'+trainedWordCount)
eliffileType==u'file':
corpusSingleFile=open(corpusSingleFilePath,u'r')
trainedWordCount=model.train(LineSentence(corpusSingleFile))
print('updatemodel,updatewordsnumis:'+trainedWordCount)
else:
#TODOaddsentenceslistdirectly(sameaslastfunction)
pass
returnmodel
简单检查文件type之后,调用model对象的train方法就可以实现对model的更新,这个方法传入的是新语料的sentences,会返回模型中新增词汇的数量。函数全部执行完后,return更新后的model,源代码中在这个函数下面有能够处理多类文件参数(同2)的增强方法,这里就不多介绍了。
4.各种基础查询
当你确定model已经训练完成,不会再更新的时候,可以对model进行锁定,并且据说是预载了相似度矩阵能够提高后面的查询速度,但是你的model从此以后就read only了。
[python]view plain
deffinishTrainModel(self,modelFilePath=None):
'''''
warning:afterthis,themodelisread-only(can'tbeupdate)
'''
ifmodelFilePath==None:
modelFilePath=self.modelPath
model=self.loadModelfromFile(modelFilePath)
model.init_sims(replace=True)
可以看到,所谓的锁定模型方法,就是init_sims,并且把里面的replace参数设定为True。
然后是一些word2vec模型的查询方法:
[python]view plain
defgetWordVec(self,model,wordStr):
'''''
gettheword'
'''
returnmodel[wordStr]
[python]view plain
defqueryMostSimilarWordVec(self,model,wordStr,topN=20):
'''''
return2-dimList[0]isword[1]isdouble-prob
'''
similarPairList=model.most_similar(wordStr.decode('utf-8'),topn=topN)
returnsimilarPairList
[python]view plain
defculSimBtwWordVecs(self,model,wordStr1,wordStr2):
'''''
returndouble-prob
'''
similarValue=model.similarity(wordStr1.decode('utf-8'),wordStr2.decode('utf-8'))
returnsimilarValue
上述方法都很简单,基本上一行解决,在源代码中,各个函数下面依然是配套了相应的model文件处理版的函数。其中,getWordVec是得到查询词的word2vec词向量本身,打印出来是一个纯数字的array;queryMostSimilarWordVec是得到与查询词关联度最高的N个词以及对应的相似度,返回是一个二维list(注释里面写的蛮清楚);culSimBtwWordVecs是得到两个给定词的相似度值,直接返回double值。
5.Word2Vec词向量的计算
研究过w2v理论的童鞋肯定知道词向量是可以做加减计算的,基于这个性质,gensim给出了相应的方法,调用如下:
[python]view plain
(self,model,posWordStrList,negWordStrList,topN=20):
'''''
pos-neg
return2-dimList[0]isword[1]isdouble-prob
'''
posWordList=[]
negWordList=[]
forwordStrinposWordStrList:
posWordList.append(wordStr.decode('utf-8'))
forwordStrinnegWordStrList:
negWordList.append(wordStr.decode('utf-8'))
pnSimilarPairList=model.most_similar(positive=posWordList,negative=negWordList,topn=topN)
returnpnSimilarPairList
由于用的是py27,所以之前对传入的词列表数据进行编码过滤,这里面posWordList可以认为是对结果产生正能量的词集,negWordList则是对结果产生负能量的词集,同时送入most_similar方法,在设定return答案的topN,得到的返回结果形式同4中的queryMostSimilarWordVec函数,大家可以这样数学地理解这个操作:
下面一个操作是我自创的,假设我想用上面词向量topN“词-关联度”的形式展现两个词或两组词之间的关联,我是这么做的:
[python]view plain
(self,model,wordStrList1,wordStrList2,topN_rev=20,topN=20):
'''''
-wordListandtag-wordList
first,usethetag-wordListasneg-wordListtogettherev-wordList,
thenusethescr-wordListandtherev-wordListasthenewsrc-tag-wordList
topN_revistopNofrev-
'''
srcWordList=[]
tagWordList=[]
srcWordList.extend(wordStr.decode('utf-8')forwordStrinwordStrList1)
tagWordList.extend(wordStr.decode('utf-8')forwordStrinwordStrList2)
revSimilarPairList=self.queryMSimilarVecswithPosNeg(model,[],tagWordList,topN_rev)
revWordList=[]
revWordList.extend(pair[0].decode('utf-8')forpairinrevSimilarPairList)
stSimilarPairList=self.queryMSimilarVecswithPosNeg(model,srcWordList,revWordList,topN)
returnstSimilarPairList
这个操作的思路就是,首先用两组词中的一组作为negWordList,传入上面的queryMSimilarVecswithPosNeg函数,得到topN一组的中转词,在使用这些中转词与原先的另一组词进行queryMSimilarVecswithPosNeg操作,很容易理解,第一步得到的是一组词作为negWordList的反向结果,再通过这个反向结果与另一组词得到“负负得正”的效果。这样就可以通过一组topN的“词-关联度”配对List表示两组词之间的关系。