下午等考科目三的时候想到的一个问题.
给定一定的skill level k,结果的pass的score s与否应该是一个类似:
s = k*p
的关于p的一个概率关系.
也就是固有的技能熟练程度随一个分布的"随机"波动.
考虑把概率p展开为加权w的因素f的多项式看的话.
即类似:
p = w_1*f_1 + w_2*f_2 + ... = \sum w_i*f_i
则s=k*p
->
s = k*\sum w_i*f_i
这个形式好像没什么意义.
但如果换个思路写成
s = k + w_i*f_i + w_2*f_2 + ...
的话,即在给定技能水平的条件下,最终结果取决于跟其他因素的一个某种形式的和.
实际形式可能是
s = c_0(k) + c_1(w_i*f_i) + c_2(w_2*f_2) + ...
的形式.
其中c_n为某种到s的space的mapping functions.
通俗地说,就是给定技能水平的话,实际的结果收到一些f因素的影响.
也就是对分布p的波动性的某种形式的解释.
一个前提假设.
如果是绝对理性/理想的情况下,那么给定一定的k,则有一个相对于的固定的s.
现在引入c(w,f)作为对p的解释的话.
也就是说s的最终取值收到参考因素的影响/贡献.
实际的例子可能是f为紧张程度,或者环境因素.
对s的影响的形式就是比如过于紧张/环境关系造成的发挥失常/超常等的一种波动性的解释.
也就是当c(w,f)为positive的时候,对s的贡献就是正的.
换句话说,就是这个因素对技能水平的观测/评测有着积极的/超常的作用.
反之类似.
那么单从等式的角度来说,就存在一些解,使得最终的s尽可能地最大化.
即,如果能够分清因素对"发挥"这种行为是正面还是负面影响的话,就有可能使得最终的结果收益尽可能地大.
当然,这里c(w,f)可能隐含一种相互的约束.
因为s应该是一个bounded的,所以c(w,f)应该也是bounded的.
基于在这里认为c_0(k)是一个绝对中立/理性的值.
但是实际来说,在结果出来直接可能很难判定一个因素的影响是积极的还是消极的.
就像"紧张"这种因素.
它可能使得人注意力分散,也可能反过来刺激人的肾上腺素对结果造成正面的影响.
也就是说,这种描述更多地像是对一个one shot的东西做的一个事后的补充解释.
而不能在事前发现和重复利用.
类似于可以事后给出一个形如:
s = c_0(k) + c_1(w_i*f_i) + c_2(w_2*f_2) + ...
的表达式.
其中c_n都是"已知"的表示.
即可以有任意的满足
s = s' = r(k,w_1,f_1,w_2,f_2...)的函数.
即使在当时能够分辨地出能够影响结果的因素的f_n.
那么依然有着w_n的free variable.
并不能够确切地做一个确定的描述.
如果有确切的描述的话,那么就是已知w_n和k.
最大化s的问题就变成调整因素f_n的问题了.
也就是相对可控的"紧张"到什么程度能让结果较优/最优.
问题是,实际上并不能在事前得到这么一种表达方式.
换个思路.
既然假设了c_0(k)是一个常量的话.
也就是假设技能水平是固定不变的.
那么对于
s = c_0(k) + c_1(w_i*f_i) + c_2(w_2*f_2) + ...
就存在一个关于s的确定的解,
即
s_0 = c_0(k)
也就是说,如果不做一些诸如maximize的speculate的动作,而是遵循实际的技能水平的话.
那么是有一个确定可预知的结果的.
这个解的约束是\sum c_i(w_i,f_i) = 0.
同样的,如果从general的角度来看的话,因为无法在事前确定c(w,f)的具体形式和描述.
所以事前并不能根据实际的描述,来通过调整相应的f取得满足上面约束的解.
但同样的考虑一个特殊形式.
即所有的c(w,f) = 0的情况.
这是对于上面约束的一个特殊解.
即,如果把能够影响结果的因素的贡献都降低到0.
那么也就相当于实际上把这个影响因素移出等式/排除掉了.
世俗上来说,就是如果能把"紧张"之类的情绪等因素排除掉干扰,那么就存在对结果的一种确定性的预期.
代价则是使得结果不存在变数,也就是不存在着某种程度的投机/优化.
所谓的明镜止水.
2015-12-20
2015-12-13
同一类人
下午看 万万想不到 的时候在想一个问题.
好像很长一段时间以来的笑点都是在一些对所谓梗的理解上.
有时候只是意识到了用某些元素,但镜头还没达到就先笑了.
而有些时候,对于一些努力制造的笑点可能却没什么反应.
即使周围的人都笑了.
这里不是想说笑点高低的问题.
而是似乎很多行为的动机只是在寻找某些熟悉的东西.
包括一些社交网络上的一些动作.
很多时候也就是一些基础元素的延伸反复变化而已.
就像蛤一样.
有些内容其实并没有什么太大的意义.
但是通过某种联想和映射使之跟某些旧有的东西产生共鸣的话,仿佛就会产生一些奇怪的作用.
比如前段时间12306的验证码.
所谓的一个脑洞,就对各个小圈子/领域的人产生了某种群体创作和参与的潮流.
如果去考虑为什么有这种流向度的话.
一方面可能是某种讽刺形式扩散.
但可能更主要的是形式上的可重复性的某种reinforcement.
无论是哪个圈子的验证码组合,其内容也并没有带来什么新的东西.
反而可能是一些该圈子所共知的一个基本常识/事实而已.
一个更通常一些的形式可能就是某些特定的回复模式,或者说管有的吐槽方式.
就像某些账号黑穆斯林产生的关于羊的回复.
或者更常规的,从 跪了 到 这是我的膝盖 之类的同义固形的回复句式的应用.
再典型一点的就是某些所谓的表情所构成的聊天记录.
尤其是表情.
考虑聊天的内容构成是存在一定的上下文连续性的.
而纯表情能构建起来并继续下去,从另一方面看就是说明这些表情构成了一定的内容描述.
换个角度,如果把"表情"考虑为某种语言的基本"单词"呢.
或者更广泛地来说.
在对外部交互的时候,选择一些固有的模式作为回应的行为.
某种形式上就是以这些"旧"的东西作为基本的语言单位,重新"遣词造句"对外部做出反应的一种类语言行为
于是这种某种圈子内的reinforcement的行为,以及某些笑点上的行为实际上就可以考虑为是基于某种"语言"的共鸣交流/反应.
某种程度上来说,就是某种特定文化背景下面的语言交流方式.
即"共同语言".
所以,实际上,所谓的"共同语言"就是对某些事物的基本的共通性的认识.
或者说带有类似的上下文的演绎方式.
在既定的context下面,通过提供有限的几个元素/"基本词汇"的话,双方就存在着一种限定范围内的,对同一事物进行相同或者类似演绎的可能.
也就是通常所说的"一致的思路"或者"相似的想法",从而完成所谓的"交流".
那么考虑,把"梗"作为基本的"词"考虑.
把表述形式不同,但同义的"梗"考虑为同义词的话.
重新审视各个圈子/领域/亚文化.
比如,
"回老家结婚"
和
"已经没有什么好怕的了"
再比如
"PHP是最好的语言"
又比如
"谈笑风生"
"续一秒"
等.
看到的时候可能很快地会有类似的短句或者下一句/下几句的内容.
有时候,与其说这是一种交流,不如说是一种补完.
或者说同义反复.
它并不是在讨论什么具体的内容.
而是只对一个固有的模式/模型进行填充.
就好像人听一些动物比如猫的叫声一样.
可能它确实表达了某种信息.
但是表达的形式却不一定具有固定的形式.
而只是某种模式上的相似感/区别度.
人的语气变化也类似.
不同的语气或者同一语气的不同的句子可能都是某种情绪/内容的表达.
而决定其性质的可能并不是"句子"的词汇构成.
所以,某种程度上来说,"交流"只是一种把自己"所想"/"意愿"通过某种模式replicate出去的方式/方法而已.
或者说是context的传递.
考虑眼神交流或者任何形式的交流.
把context以信息量计量量化的话,把交流时间考虑进来作为效率衡量维度.
"只要你一个眼神肯定"
这种描述的其实就是双方拥有类似context的情况下,传输过程可以以一种optimized的"压缩编码"方式进行.
从而缩短交流时间.
反过来说,沟通效率的高低就在于双方context的对等/交集情况如何.
所谓的同一类人的定义.
好像很长一段时间以来的笑点都是在一些对所谓梗的理解上.
有时候只是意识到了用某些元素,但镜头还没达到就先笑了.
而有些时候,对于一些努力制造的笑点可能却没什么反应.
即使周围的人都笑了.
这里不是想说笑点高低的问题.
而是似乎很多行为的动机只是在寻找某些熟悉的东西.
包括一些社交网络上的一些动作.
很多时候也就是一些基础元素的延伸反复变化而已.
就像蛤一样.
有些内容其实并没有什么太大的意义.
但是通过某种联想和映射使之跟某些旧有的东西产生共鸣的话,仿佛就会产生一些奇怪的作用.
比如前段时间12306的验证码.
所谓的一个脑洞,就对各个小圈子/领域的人产生了某种群体创作和参与的潮流.
如果去考虑为什么有这种流向度的话.
一方面可能是某种讽刺形式扩散.
但可能更主要的是形式上的可重复性的某种reinforcement.
无论是哪个圈子的验证码组合,其内容也并没有带来什么新的东西.
反而可能是一些该圈子所共知的一个基本常识/事实而已.
一个更通常一些的形式可能就是某些特定的回复模式,或者说管有的吐槽方式.
就像某些账号黑穆斯林产生的关于羊的回复.
或者更常规的,从 跪了 到 这是我的膝盖 之类的同义固形的回复句式的应用.
再典型一点的就是某些所谓的表情所构成的聊天记录.
尤其是表情.
考虑聊天的内容构成是存在一定的上下文连续性的.
而纯表情能构建起来并继续下去,从另一方面看就是说明这些表情构成了一定的内容描述.
换个角度,如果把"表情"考虑为某种语言的基本"单词"呢.
或者更广泛地来说.
在对外部交互的时候,选择一些固有的模式作为回应的行为.
某种形式上就是以这些"旧"的东西作为基本的语言单位,重新"遣词造句"对外部做出反应的一种类语言行为
于是这种某种圈子内的reinforcement的行为,以及某些笑点上的行为实际上就可以考虑为是基于某种"语言"的共鸣交流/反应.
某种程度上来说,就是某种特定文化背景下面的语言交流方式.
即"共同语言".
所以,实际上,所谓的"共同语言"就是对某些事物的基本的共通性的认识.
或者说带有类似的上下文的演绎方式.
在既定的context下面,通过提供有限的几个元素/"基本词汇"的话,双方就存在着一种限定范围内的,对同一事物进行相同或者类似演绎的可能.
也就是通常所说的"一致的思路"或者"相似的想法",从而完成所谓的"交流".
那么考虑,把"梗"作为基本的"词"考虑.
把表述形式不同,但同义的"梗"考虑为同义词的话.
重新审视各个圈子/领域/亚文化.
比如,
"回老家结婚"
和
"已经没有什么好怕的了"
再比如
"PHP是最好的语言"
又比如
"谈笑风生"
"续一秒"
等.
看到的时候可能很快地会有类似的短句或者下一句/下几句的内容.
有时候,与其说这是一种交流,不如说是一种补完.
或者说同义反复.
它并不是在讨论什么具体的内容.
而是只对一个固有的模式/模型进行填充.
就好像人听一些动物比如猫的叫声一样.
可能它确实表达了某种信息.
但是表达的形式却不一定具有固定的形式.
而只是某种模式上的相似感/区别度.
人的语气变化也类似.
不同的语气或者同一语气的不同的句子可能都是某种情绪/内容的表达.
而决定其性质的可能并不是"句子"的词汇构成.
所以,某种程度上来说,"交流"只是一种把自己"所想"/"意愿"通过某种模式replicate出去的方式/方法而已.
或者说是context的传递.
考虑眼神交流或者任何形式的交流.
把context以信息量计量量化的话,把交流时间考虑进来作为效率衡量维度.
"只要你一个眼神肯定"
这种描述的其实就是双方拥有类似context的情况下,传输过程可以以一种optimized的"压缩编码"方式进行.
从而缩短交流时间.
反过来说,沟通效率的高低就在于双方context的对等/交集情况如何.
所谓的同一类人的定义.
2015-12-08
由拉格朗日乘数想到
考虑lagrange multiplier的构造.
\mathcal{L}(X) = f(X) + \lambda*g(X)
这里一个比较有趣的地方是constraint function g作为一个余项引入.
根据g的定义,g(X) = 0.
也就是说实际上等价于
\mathcal{L}(X) = f(X)
考虑\mathcal{L}(X)的stationary points.
即满足\nabla \mathcal{L}(X) = 0的集合S.
如果s \in S且g(s) = 0的话,那么就是一个可能的solution.
这里的思路其实是通过构造一个零项保证function的mapping空间/关系不变.
但同时把问题简化为简单的stationary的解.
换个角度考虑的话,其实就是对一个现有space的某种形式的cut/prune/classify.
在保证某种特性不变的前提下,以g做出一定形式的划分.
考虑把f(X)看作是一种feature -> object的函数.
比如X是一组feature,object是一个用户标识.
也就是说假设存在一种描述,使得这个描述对某个用户唯一.
即通过feature vector可以unique地locate到某个用户.
然后考虑有一个对用户的label函数.
使得每个用户对应一个label.
重新如lagrange multiplier的形式的等式.
\mathcal{L}(X) = f(X) + \lambda_a*g_a(X) + \lambda_b*g_b(X) + ...
当X被归类为a的时候,其余的\lambda*g(X) = 0.
即此时的\mathcal{L}(X) - f(X) = \lambda_a*g_a(X) != 0.
如果令lambda都等于1的话,则形式为:
\mathcal{L}(X) = f(X) + g_a(X) + g_b(X) + ...
->
\mathcal{L}(X) = f(X) + col_sum(G*X).
G为一个dim(label)行feature列的matrix,col_sum为对列做的算数和.
那么就有可能解出一个matrix G,使得col_sum(G*X) = 0
对于一个给定的x,apply之后有col_sum(x;G) == 0 意味着什么呢?
意味如果x是在X中,且其对于label a的话,
\lambda_a*g_a(X) + \lambda_b*g_b(X) + ... == 0
->
\lambda_a*g_a(X) == 0即与label a的前提矛盾.
所以如果col_sum(x;G) == 0 的话,则表明x必定不在X中.
那么如果col_sum(x;G) != 0的话呢?
明显也不能说明x就在X中.
因为可能存在g_b(X) != 0等的情况.
如果G*X得到的vector形式V是[1,0,0,0,...]的某个维度值为1的unit vector呢?
也不能.
因为如果把G看作是X向feature space的project的话.
对于某个vector来说,project成unit vector也不足以说明就是在原来的X space.
所以,某种程度上来说,这个只是一个dim(X) -> dim(label)的某种形式的类bloom filter.
即G*X != unit vector的话,则必然不在原来的X中.
\mathcal{L}(X) = f(X) + \lambda*g(X)
这里一个比较有趣的地方是constraint function g作为一个余项引入.
根据g的定义,g(X) = 0.
也就是说实际上等价于
\mathcal{L}(X) = f(X)
考虑\mathcal{L}(X)的stationary points.
即满足\nabla \mathcal{L}(X) = 0的集合S.
如果s \in S且g(s) = 0的话,那么就是一个可能的solution.
这里的思路其实是通过构造一个零项保证function的mapping空间/关系不变.
但同时把问题简化为简单的stationary的解.
换个角度考虑的话,其实就是对一个现有space的某种形式的cut/prune/classify.
在保证某种特性不变的前提下,以g做出一定形式的划分.
考虑把f(X)看作是一种feature -> object的函数.
比如X是一组feature,object是一个用户标识.
也就是说假设存在一种描述,使得这个描述对某个用户唯一.
即通过feature vector可以unique地locate到某个用户.
然后考虑有一个对用户的label函数.
使得每个用户对应一个label.
重新如lagrange multiplier的形式的等式.
\mathcal{L}(X) = f(X) + \lambda_a*g_a(X) + \lambda_b*g_b(X) + ...
当X被归类为a的时候,其余的\lambda*g(X) = 0.
即此时的\mathcal{L}(X) - f(X) = \lambda_a*g_a(X) != 0.
如果令lambda都等于1的话,则形式为:
\mathcal{L}(X) = f(X) + g_a(X) + g_b(X) + ...
->
\mathcal{L}(X) = f(X) + col_sum(G*X).
G为一个dim(label)行feature列的matrix,col_sum为对列做的算数和.
那么就有可能解出一个matrix G,使得col_sum(G*X) = 0
对于一个给定的x,apply之后有col_sum(x;G) == 0 意味着什么呢?
意味如果x是在X中,且其对于label a的话,
\lambda_a*g_a(X) + \lambda_b*g_b(X) + ... == 0
->
\lambda_a*g_a(X) == 0即与label a的前提矛盾.
所以如果col_sum(x;G) == 0 的话,则表明x必定不在X中.
那么如果col_sum(x;G) != 0的话呢?
明显也不能说明x就在X中.
因为可能存在g_b(X) != 0等的情况.
如果G*X得到的vector形式V是[1,0,0,0,...]的某个维度值为1的unit vector呢?
也不能.
因为如果把G看作是X向feature space的project的话.
对于某个vector来说,project成unit vector也不足以说明就是在原来的X space.
所以,某种程度上来说,这个只是一个dim(X) -> dim(label)的某种形式的类bloom filter.
即G*X != unit vector的话,则必然不在原来的X中.
2015-12-06
授人以渔
早上看到条关于微博信息流展示算法调整的解释文章.
大致看了下,基本的思路是通过减少汇入的信息条数达到提高阅读率和互动率.
采用的手段里有个比较矛盾的是通过"时移",也就是把之前时段的内容,通过算法把评断为"用户可能在意而又错过"的"过时"微博重新编入信息流.
后面这个做法大概是为了后来人为操控某些信息,比如广告推广资源留的吧.
不过思路也不算完全自私.
毕竟,也算某种程度上的消息填谷去峰.
但是作为效果衡量的KPI选用阅读率和互动率可能就有失偏颇了.
考虑到阅读率/互动率其实是 交互数/信息流微博 数算出来的.
而调整的基本思路和策略则是减少汇入时间线的微博数.
也就是说,相当于直接调整/缩小基数.
于是,阅读率/互动率这几个KPI出现明显增长也算是自然甚至说理所当然的结果了.
所以,某种程度上来说,以这两个指标来衡量主时间线/信息流质量的话,难免缺乏些说服力.
而且,从比较量化的角度来说,要把这两者作为衡量指标的话,也还得除去基数变化带来的对结果的影响.
即,要以这个指数来证明调整确实有好的作用的话,也得把由基数变化带来的变化的影响部分去掉.
因此,至少从数据上来说,这个调整就算有效果,那么效果也不是里面提到的数字.
而是应该更低些.
那么,应该如何才能比较合适地评定一个信息流的好坏呢?
广义的高互动的内容并不一定就是用户所喜欢或者希望接受的内容.
一个例子就是最近那个猎鸟的事件.
自己的时间线上相关的内容其实不少,但考虑到对国内媒体的节操和舆论作风来说,其实没有什么悬念和值得关注的点了.
但是如果单纯时间线上其他人的互动角度来说,机械的算法可能就会认为这个可能感兴趣的内容.
出现这种bad case的原因在于,对用户的"好的内容"的定义过于局限,或者说维度过于片面.
个人的决策过程中还包含一些认知上的倾向性context.
尤其是对于,"好"/"坏"这种主观意愿性很强的东西.
即使是人本身也很难对喜好做一个准确的划分和定义.
毕竟,这是一个很动态的东西.
客观上来说,所能观测到的只是一个人对某条或者某些微博是否有交互的行为.
而这个交互行为本身是积极的还是消极的信息接受过程是未定的.
就像个转发/评论一条微博并不一定是赞同,也可能是批驳.
即使是 赞 这种设计上是积极倾向的动作,有时候也不一定就是赞同的意思.
比如赞的内容是一条转发微博,而里面可能是夹杂了两个对立观点的.
所以,有时候能做的,更多的只是一种交互意愿性的描述.
而要描述交互意愿,可用的维度就多很多了.
比如点开一个微博的转发/评论列表.
点开某条微博的昵称/头像.
点击了某条链接.
阅读长微博时滚动条的变化速率等.
基本上,所有的交互动作都是有倾向性并且可记录的.
那么,对于个人来说,有强交互意愿的内容,对于其他人来说,就也一定存在强交互意愿么?
或者进一步说,交互的概率就比其他普通信息更高么?
这个可能比较难量化.
毕竟,前面说了,这是个很主观的东西.
对于信息的接受方来说,推送过来的可能各个层面和维度的其他人的强交互意愿内容.
但可能只会对其中的某一些部分有较高的交互概率.
而如何界定这一部分的特征,就涉及到当时的立场/认知甚至于心情了.
所以,原则上来说,干涉调整个人的信息流的内容,可能是一个有作用但未必有效的方式.
实际上,早前Google+的circle/分组/list就有一个调整该circle/分组/list内的人的信息在主信息流出现频率的功能.
但基本上最后就只是看和不看的区别.
而不是看多少的区别.
毕竟分组的存在本身就已经是个人调整的结果了.
有特别想关注的自然会做一些分组方便浏览.
如果一个人的内容多数时候不感兴趣或者反感,就直接取消关注就是了.
某种程度上来说,主时间线信息流只是一个相对来说辅助性的东西.
虽然从使用角度上来说,这个是主要场景.
但如果作为一个信息消费品来说,主信息留只是一个广场集市入口.
它要保证的只是内容和来源的多样性.
立场和观点多了,自然能从转发链中吸收到新的关注点/人.
大致看了下,基本的思路是通过减少汇入的信息条数达到提高阅读率和互动率.
采用的手段里有个比较矛盾的是通过"时移",也就是把之前时段的内容,通过算法把评断为"用户可能在意而又错过"的"过时"微博重新编入信息流.
后面这个做法大概是为了后来人为操控某些信息,比如广告推广资源留的吧.
不过思路也不算完全自私.
毕竟,也算某种程度上的消息填谷去峰.
但是作为效果衡量的KPI选用阅读率和互动率可能就有失偏颇了.
考虑到阅读率/互动率其实是 交互数/信息流微博 数算出来的.
而调整的基本思路和策略则是减少汇入时间线的微博数.
也就是说,相当于直接调整/缩小基数.
于是,阅读率/互动率这几个KPI出现明显增长也算是自然甚至说理所当然的结果了.
所以,某种程度上来说,以这两个指标来衡量主时间线/信息流质量的话,难免缺乏些说服力.
而且,从比较量化的角度来说,要把这两者作为衡量指标的话,也还得除去基数变化带来的对结果的影响.
即,要以这个指数来证明调整确实有好的作用的话,也得把由基数变化带来的变化的影响部分去掉.
因此,至少从数据上来说,这个调整就算有效果,那么效果也不是里面提到的数字.
而是应该更低些.
那么,应该如何才能比较合适地评定一个信息流的好坏呢?
广义的高互动的内容并不一定就是用户所喜欢或者希望接受的内容.
一个例子就是最近那个猎鸟的事件.
自己的时间线上相关的内容其实不少,但考虑到对国内媒体的节操和舆论作风来说,其实没有什么悬念和值得关注的点了.
但是如果单纯时间线上其他人的互动角度来说,机械的算法可能就会认为这个可能感兴趣的内容.
出现这种bad case的原因在于,对用户的"好的内容"的定义过于局限,或者说维度过于片面.
个人的决策过程中还包含一些认知上的倾向性context.
尤其是对于,"好"/"坏"这种主观意愿性很强的东西.
即使是人本身也很难对喜好做一个准确的划分和定义.
毕竟,这是一个很动态的东西.
客观上来说,所能观测到的只是一个人对某条或者某些微博是否有交互的行为.
而这个交互行为本身是积极的还是消极的信息接受过程是未定的.
就像个转发/评论一条微博并不一定是赞同,也可能是批驳.
即使是 赞 这种设计上是积极倾向的动作,有时候也不一定就是赞同的意思.
比如赞的内容是一条转发微博,而里面可能是夹杂了两个对立观点的.
所以,有时候能做的,更多的只是一种交互意愿性的描述.
而要描述交互意愿,可用的维度就多很多了.
比如点开一个微博的转发/评论列表.
点开某条微博的昵称/头像.
点击了某条链接.
阅读长微博时滚动条的变化速率等.
基本上,所有的交互动作都是有倾向性并且可记录的.
那么,对于个人来说,有强交互意愿的内容,对于其他人来说,就也一定存在强交互意愿么?
或者进一步说,交互的概率就比其他普通信息更高么?
这个可能比较难量化.
毕竟,前面说了,这是个很主观的东西.
对于信息的接受方来说,推送过来的可能各个层面和维度的其他人的强交互意愿内容.
但可能只会对其中的某一些部分有较高的交互概率.
而如何界定这一部分的特征,就涉及到当时的立场/认知甚至于心情了.
所以,原则上来说,干涉调整个人的信息流的内容,可能是一个有作用但未必有效的方式.
实际上,早前Google+的circle/分组/list就有一个调整该circle/分组/list内的人的信息在主信息流出现频率的功能.
但基本上最后就只是看和不看的区别.
而不是看多少的区别.
毕竟分组的存在本身就已经是个人调整的结果了.
有特别想关注的自然会做一些分组方便浏览.
如果一个人的内容多数时候不感兴趣或者反感,就直接取消关注就是了.
某种程度上来说,主时间线信息流只是一个相对来说辅助性的东西.
虽然从使用角度上来说,这个是主要场景.
但如果作为一个信息消费品来说,主信息留只是一个广场集市入口.
它要保证的只是内容和来源的多样性.
立场和观点多了,自然能从转发链中吸收到新的关注点/人.
2015-12-04
反编译的一点想法
最近两天在看某券商的Android App.
当然,说看其实不太确切.
只是dex2jar然后再jd回来的混淆代码.
大概是连猜带蒙的看吧.
看的时候发现一些disassemble失败的部分,直接给的是bytecode.
还有一些是比较奇怪的代码分支层次.
前者倒是没想出什么原因.
而且也大致不算影响阅读,毕竟java bytecode其实还是比较简单可读的.
后者的原因想了想,大概是vm结构的区别了.
毕竟,dalvik是基于register,而jvm是stack base的.
register base的话,因为数量限制,加上一些优化策略,涉及到register的复用.
所以在跟源代码对译的时候,难免会出现不一致的地方.
尤其对于Java这种强类型语言来说.
ClassA和ClassB因为"生命周期"的不同可能导致复用同一个register,导致还原的时候,代码效果不是很理想.
而stack base的原则上来说就没有这个问题.
有多少个源代码级别的local variable就有多少个对应的bytecode里的variable.
所以对译起来相对简单得多.
想了下,自己实现JVM bytecode disassembler的话,好像不难.
变量,分支,签名,异常,类型都有.
大概是时间和精力/兴趣问题了.
然后想了下dalvik的情况.
如果搞定变量对应/区分的话,其他应该跟JVM的难度差不多.
考虑,在从source code到bytecode的translate过程中,对register的allocation策略.
一个naive的方式自然是算下source code级别的变量的作用域/生命周期了.
如果到某个点不再被使用,那么其所占用的register自然可以被复用.
某种程度上来说,这是个data dependency的问题.
那么大致的算法过程应该是以数据为中心展开的.
也就是基本的读写操作的序列化和拆分.
换个角度来说,就是以数据/变量为基本symbol的state machine/DAG了.
如果把某个变量v考虑为一个基本basic symbol或者symbol class.
一个赋值或者自增等操作之类的读写之后衍生一个同一symbol class的derivative symbol.
两个symbol之间做个link或者transfer标记.
那么数据之间如果有依赖的话,就是不同的symbol class之间存在link.
于是,一趟parse下来就得到一个大致的forest like的graph了.
这个graph的用处理论上来说可以做一定程度的并行编译.
如果不考虑实际的物理计算代价的话.
毕竟,每个不同symbol class的link intersect point就是实际的synchronize point.
在此之前的都算是独立数据流,可以分配到不同的CPU上执行.
当然,实际代价是另一回事.
而且真考虑的话,优化过程加上一下代价预估,也是顺手的事情.
另一个用途自然是register的allocation了.
如果不考虑dead code elimination的话,那么所有数据流应该都是会汇集到同一个点的.
不管这个点是真实的数据点(return value),还是一个pseudo/dummy.
那么,从这个角度看的话,其实这个graph就退化成tree了.
于是,重新考虑register allocation的策略.
对于基本的单层或者说双层(包含root)的tree来说,所需要的register数量就是root的children的数量.
递归推广下,对于多层的结构来说,就是整个tree structure里面,需要的register的数量就是至少是某个node的直接children的最大值local_max_children.
但实际所需的最大register数并不一定就是这个local_max_children.
因为当把这个subtree eliminate之后,实际上可用的register数为local_max_children-1,即reduce之后的结果要占一个register.
那么怎么算具体需要多少个register呢?
对于一个给定的tree,eliminate的策略应该是首先找leaf node上一层里children数最多的做prune.
因为这时候只能prune这一层的node,且这时所需的register数必然是最大children数.
于是,递归一下,reduce回root的话,实际上就算出了实际需要的register数量了.
而且,如果不关心具体数量的话,那么递归的过程实际上也就是allocation/reuse的过程了.
这个是source code到bytecode的translate过程.
但问题是如何逆向回来.
考虑到正向的过程其实类似某种变种形式的后续遍历形式.
如果正向过程中,对register的选择有固定的顺序或者选择策略的话,那么直觉上这个过程应该是可逆的.
因为每消耗一个register代表的其实是一层max children的leaf tree的elimination.
而每一个被小号的register的读就意味着一次subtree的merge/面向root的propagate.
所以理论上应该是可行的.
当然,说看其实不太确切.
只是dex2jar然后再jd回来的混淆代码.
大概是连猜带蒙的看吧.
看的时候发现一些disassemble失败的部分,直接给的是bytecode.
还有一些是比较奇怪的代码分支层次.
前者倒是没想出什么原因.
而且也大致不算影响阅读,毕竟java bytecode其实还是比较简单可读的.
后者的原因想了想,大概是vm结构的区别了.
毕竟,dalvik是基于register,而jvm是stack base的.
register base的话,因为数量限制,加上一些优化策略,涉及到register的复用.
所以在跟源代码对译的时候,难免会出现不一致的地方.
尤其对于Java这种强类型语言来说.
ClassA和ClassB因为"生命周期"的不同可能导致复用同一个register,导致还原的时候,代码效果不是很理想.
而stack base的原则上来说就没有这个问题.
有多少个源代码级别的local variable就有多少个对应的bytecode里的variable.
所以对译起来相对简单得多.
想了下,自己实现JVM bytecode disassembler的话,好像不难.
变量,分支,签名,异常,类型都有.
大概是时间和精力/兴趣问题了.
然后想了下dalvik的情况.
如果搞定变量对应/区分的话,其他应该跟JVM的难度差不多.
考虑,在从source code到bytecode的translate过程中,对register的allocation策略.
一个naive的方式自然是算下source code级别的变量的作用域/生命周期了.
如果到某个点不再被使用,那么其所占用的register自然可以被复用.
某种程度上来说,这是个data dependency的问题.
那么大致的算法过程应该是以数据为中心展开的.
也就是基本的读写操作的序列化和拆分.
换个角度来说,就是以数据/变量为基本symbol的state machine/DAG了.
如果把某个变量v考虑为一个基本basic symbol或者symbol class.
一个赋值或者自增等操作之类的读写之后衍生一个同一symbol class的derivative symbol.
两个symbol之间做个link或者transfer标记.
那么数据之间如果有依赖的话,就是不同的symbol class之间存在link.
于是,一趟parse下来就得到一个大致的forest like的graph了.
这个graph的用处理论上来说可以做一定程度的并行编译.
如果不考虑实际的物理计算代价的话.
毕竟,每个不同symbol class的link intersect point就是实际的synchronize point.
在此之前的都算是独立数据流,可以分配到不同的CPU上执行.
当然,实际代价是另一回事.
而且真考虑的话,优化过程加上一下代价预估,也是顺手的事情.
另一个用途自然是register的allocation了.
如果不考虑dead code elimination的话,那么所有数据流应该都是会汇集到同一个点的.
不管这个点是真实的数据点(return value),还是一个pseudo/dummy.
那么,从这个角度看的话,其实这个graph就退化成tree了.
于是,重新考虑register allocation的策略.
对于基本的单层或者说双层(包含root)的tree来说,所需要的register数量就是root的children的数量.
递归推广下,对于多层的结构来说,就是整个tree structure里面,需要的register的数量就是至少是某个node的直接children的最大值local_max_children.
但实际所需的最大register数并不一定就是这个local_max_children.
因为当把这个subtree eliminate之后,实际上可用的register数为local_max_children-1,即reduce之后的结果要占一个register.
那么怎么算具体需要多少个register呢?
对于一个给定的tree,eliminate的策略应该是首先找leaf node上一层里children数最多的做prune.
因为这时候只能prune这一层的node,且这时所需的register数必然是最大children数.
于是,递归一下,reduce回root的话,实际上就算出了实际需要的register数量了.
而且,如果不关心具体数量的话,那么递归的过程实际上也就是allocation/reuse的过程了.
这个是source code到bytecode的translate过程.
但问题是如何逆向回来.
考虑到正向的过程其实类似某种变种形式的后续遍历形式.
如果正向过程中,对register的选择有固定的顺序或者选择策略的话,那么直觉上这个过程应该是可逆的.
因为每消耗一个register代表的其实是一层max children的leaf tree的elimination.
而每一个被小号的register的读就意味着一次subtree的merge/面向root的propagate.
所以理论上应该是可行的.
订阅:
博文 (Atom)
爽文
去看了好东西. 坦白说,多少是带着点挑刺的味道去的. 毕竟打着爱情神话和女性题材的气质,多多少少是热度为先了. 看完之后倒是有些新的想法. 某种程度上来说,现在的年轻人或者说声音就像小叶. 只要说点贴心的话就能哄好. 也是那种可以不用很努力了. 留在自己的舒适区避难所小圈子抱团就...
-
最近尝试了下海淘. 当然,方向上来说是从国内到新加坡. 先是买了个iPhone,算上运费和双重征税,到手比官方还是便宜个一两百新的. 换算回来也不多事10%的纯粹价格因素差异. 当然,之类有电商促销的因素. 也有比较基准是新加坡Apple Store售价的原因. 但如果同样比较A...
-
这两天看完了Netflix版的三体. 某种程度上来说,完成度还是不错的. 尽管开始的时候对于第一集片头有些争论,但整体如果带入当下去看的话,还是有些梗的. 比如三体对于地球科技的发展速率的担忧,由此衍生的智子. 以及现有力量对比上的压倒性优势. 如果带入中美关系以及各自的历史阶段...
-
前几天Sora出来后才仔细看了下diffusion,发觉确实算挺取巧的. 按照naive的intuition或者说不那么现代的方式的话,可能需要segmentaion为基础的composite的方式去生成图片,即使扯点deep learning/network的,可能也是类似一些...