一惶翻、知識(shí)點(diǎn)
1.matplotlib圖例legend語(yǔ)法及設(shè)置
loc 設(shè)置圖例位置 其他用法參考
https://blog.csdn.net/helunqu2017/article/details/78641290
2.seek_choice = np.random.choice([0, 1, 2], 80000, p=weights)
是指以p([0.1, 0.2, 0.7])概率隨機(jī)抽取seek_choice的[0,1,2]8000次,形成一個(gè)數(shù)組
seek_ind = seek_choice[2]提取數(shù)組第3個(gè)元素
3.n = numpy.random.random() ?生成一個(gè)0~1隨機(jī)的浮點(diǎn)數(shù)
weights/=np.sum(n) ?依據(jù)上述生成的隨機(jī)數(shù)生成比例
4.scipy 使用文檔https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_bfgs.html
二椭盏、模型
from abcimport ABCMeta, abstractmethod
import matplotlib.pyplotas plt
import six
import numpyas np
import pandasas pd
from mpl_toolkits.mplot3dimport Axes3D
K_INIT_LIVING_DAYS =27375
class Person(object):
def __init__(self):
self.living = K_INIT_LIVING_DAYS
self.happiness =0
? ? ? ? self.wealth =0
? ? ? ? self.fame =0
? ? ? ? self.living_day =0
? ? def live_one_day(self, seek):
consume_living, happiness, wealth, fame = seek.do_seek_day()
self.living -=consume_living
self.happiness += happiness
self.wealth +=wealth
self.fame +=fame
self.living_day +=1
class BaseSeekDay(six.with_metaclass(ABCMeta, object)):
def __init__(self):
self.living_consume =0
? ? ? ? self.happiness_base =0
? ? ? ? self.wealth_base =0
? ? ? ? self.fame_base =0
? ? ? ? self.living_factor = [0]
self.happiness_factor = [0]
self.wealth_factor = [0]
self.fame_factor = [0]
self.do_seek_day_cnt =0
? ? ? ? self._init_self()
@abstractmethod
? ? def _init_self(self, *args, **kwargs):
pass
? ? @abstractmethod
? ? def _gen_living_days(self, *args, **kwargs):
pass
? ? def do_seek_day(self):
if self.do_seek_day_cnt >=len(self.living_factor):
# 超出len(self.living_factor), 就取最后一個(gè)living_factor[-1]
? ? ? ? ? ? consume_living = \
self.living_factor[-1] *self.living_consume
else:
# 每個(gè)類自定義這個(gè)追求的消耗生命常數(shù),以及l(fā)iving_factor,比如
# HealthSeekDay追求健康,living_factor序列的值即由負(fù)值->正值
# 每個(gè)子類living_factor會(huì)有自己特點(diǎn)的變化速度及序列長(zhǎng)度,導(dǎo)致每個(gè)
# 追求對(duì)生命的消耗隨著追求的次數(shù)變化不一
? ? ? ? ? ? consume_living =self.living_factor[self.do_seek_day_cnt] \
*self.living_consume
# 幸福指數(shù)=happiness_base:幸福常數(shù) * happiness_factor:可變序列
? ? ? ? if self.do_seek_day_cnt >=len(self.happiness_factor):
# 超出len(self.happiness_factor), 就取最后一個(gè)
# 由于happiness_factor值由:n—>0 所以happiness_factor[-1]=0
# 即隨著追求一個(gè)事物的次數(shù)過(guò)多后會(huì)變的沒(méi)有幸福感
? ? ? ? ? ? happiness =self.happiness_factor[-1] *self.happiness_base
else:
# 每個(gè)類自定義這個(gè)追求的幸福指數(shù)常數(shù),以及happiness_factor
# happiness_factor子類的定義一般是從高->低變化
? ? ? ? ? ? happiness =self.happiness_factor[self.do_seek_day_cnt] *self.happiness_base
# 財(cái)富積累=wealth_base:積累常數(shù) * wealth_factor:可變序列
? ? ? ? if self.do_seek_day_cnt >=len(self.wealth_factor):
# 超出len(self.wealth_factor), 就取最后一個(gè)
? ? ? ? ? ? wealth =self.wealth_factor[-1] *self.wealth_base
else:
# 每個(gè)類自定義這個(gè)追求的財(cái)富指數(shù)常數(shù)牢屋,以及wealth_factor
? ? ? ? ? ? wealth =self.wealth_factor[self.do_seek_day_cnt] *self.wealth_base
# 權(quán)利積累=fame_base:積累常數(shù) * fame_factor:可變序列
? ? ? ? if self.do_seek_day_cnt >=len(self.fame_factor):
# 超出len(self.fame_factor), 就取最后一個(gè)
? ? ? ? ? ? fame =self.fame_factor[-1] *self.fame_base
else:
# 每個(gè)類自定義這個(gè)追求的名望權(quán)利指數(shù)常數(shù),以及fame_factor
? ? ? ? ? ? fame =self.fame_factor[self.do_seek_day_cnt] *self.fame_base
# 追求了多少天了這一生 + 1
? ? ? ? self.do_seek_day_cnt +=1
? ? ? ? # 返回這個(gè)追求這一天對(duì)生命的消耗槽袄,得到的幸福烙无,財(cái)富,名望權(quán)利
? ? ? ? return consume_living, happiness, wealth, fame
def regular_mm(group):
# 最小-最大規(guī)范化
? ? return (group - group.min()) / (group.max() - group.min())
class HealthSeekDay(BaseSeekDay):
"""
HealthSeekDay追求健康長(zhǎng)壽的一天:
形象:健身遍尺,旅游皱炉,娛樂(lè),做感興趣的事情狮鸭。
抽象:追求健康長(zhǎng)壽合搅。
"""
? ? def _init_self(self):
# 每天對(duì)生命消耗的常數(shù)=1,即代表1天
? ? ? ? self.living_consume =1
? ? ? ? # 每天幸福指數(shù)常數(shù)=1
? ? ? ? self.happiness_base =1
? ? ? ? # 設(shè)定可變因素序列
? ? ? ? self._gen_living_days()
def _gen_living_days(self):
# 只生成12000個(gè)序列歧蕉,因?yàn)橄旅娴膆appiness_factor序列值由1->0
# 所以大于12000次的追求都將只是單純消耗生命灾部,并不增加幸福指數(shù)
# 即隨著做一件事情的次數(shù)越來(lái)越多,幸福感越來(lái)越低惯退,直到完全體會(huì)不到幸福
? ? ? ? days = np.arange(1, 12000)
# 基礎(chǔ)函數(shù)選用sqrt, 影響序列變化速度
? ? ? ? living_days = np.sqrt(days)
"""
對(duì)生命消耗可變因素序列值由-1->1, 也就是這個(gè)追求一開(kāi)始的時(shí)候?qū)ι?/p>
的消耗為負(fù)增長(zhǎng)赌髓,延長(zhǎng)了生命,隨著追求的次數(shù)不斷增多對(duì)生命的消耗轉(zhuǎn)為正
數(shù)因?yàn)榧词挂粋€(gè)人天天鍛煉身體催跪,天天吃營(yíng)養(yǎng)品锁蠕,也還是會(huì)有自然死亡的那
一天
"""
? ? ? ? # *2-1的目的:regular_mm在0-1之間,HealthSeekDay要結(jié)果在-1,1之間
? ? ? ? self.living_factor = regular_mm(living_days) *2 -1
? ? ? ? # 結(jié)果在1-0之間 [::-1]: 將0->1轉(zhuǎn)換到1->0
? ? ? ? self.happiness_factor = regular_mm(days)[::-1]
class StockSeekDay(BaseSeekDay):
"""
StockSeekDay追求財(cái)富金錢的一天:
形象:做股票投資賺錢的事情懊蒸。
抽象:追求財(cái)富金錢
"""
? ? def _init_self(self, show=False):
# 每天對(duì)生命消耗的常數(shù)=2荣倾,即代表2天
? ? ? ? self.living_consume =2
? ? ? ? # 每天幸福指數(shù)常數(shù)=0.5
? ? ? ? self.happiness_base =0.5
? ? ? ? # 財(cái)富積累常數(shù)=10,默認(rèn)=0
? ? ? ? self.wealth_base =10
? ? ? ? # 設(shè)定可變因素序列
? ? ? ? self._gen_living_days()
def _gen_living_days(self):
# 只生成10000個(gè)序列
? ? ? ? days = np.arange(1, 10000)
# 針對(duì)生命消耗living_factor的基礎(chǔ)函數(shù)還是sqrt
? ? ? ? living_days = np.sqrt(days)
# 由于不需要像HealthSeekDay從負(fù)數(shù)開(kāi)始骑丸,所以直接regular_mm 即:0->1
? ? ? ? self.living_factor = regular_mm(living_days)
# 針對(duì)幸福感可變序列使用了np.power4舌仍,即變化速度比sqrt快
? ? ? ? happiness_days = np.power(days, 4)
# 幸福指數(shù)可變因素會(huì)快速遞減由1->0
? ? ? ? self.happiness_factor = regular_mm(happiness_days)[::-1]
"""
這里簡(jiǎn)單設(shè)定wealth_factor=living_factor
living_factor(0-1), 導(dǎo)致wealth_factor(0-1), 即財(cái)富積累越到
后面越有效率妒貌,速度越快,頭一個(gè)100萬(wàn)最難賺
"""
? ? ? ? self.wealth_factor =self.living_factor
class FameSeekDay(BaseSeekDay):
"""
FameTask追求名望權(quán)力的一天:
追求名望權(quán)力
"""
? ? def _init_self(self):
# 每天對(duì)生命消耗的常數(shù)=3铸豁,即代表3天
? ? ? ? self.living_consume =3
? ? ? ? # 每天幸福指數(shù)常數(shù)=0.6
? ? ? ? self.happiness_base =0.6
? ? ? ? # 名望權(quán)利積累常數(shù)=10灌曙,默認(rèn)=0
? ? ? ? self.fame_base =10
? ? ? ? # 設(shè)定可變因素序列
? ? ? ? self._gen_living_days()
def _gen_living_days(self):
# 只生成12000個(gè)序列
? ? ? ? days = np.arange(1, 12000)
# 針對(duì)生命消耗living_factor的基礎(chǔ)函數(shù)還是sqrt
? ? ? ? living_days = np.sqrt(days)
# 由于不需要像HealthSeekDay從負(fù)數(shù)開(kāi)始,所以直接regular_mm 即:0->1
? ? ? ? self.living_factor = regular_mm(living_days)
# 針對(duì)幸福感可變序列使用了np.power2
# 即變化速度比StockSeekDay慢但比HealthSeekDay快
? ? ? ? happiness_days = np.power(days, 2)
# 幸福指數(shù)可變因素遞減由1->0
? ? ? ? self.happiness_factor = regular_mm(happiness_days)[::-1]
# 這里簡(jiǎn)單設(shè)定fame_factor=living_factor
? ? ? ? self.fame_factor =self.living_factor
# 初始化我, 你一生的故事:HealthSeekDay
def my_life(weights):
seek_health = HealthSeekDay()
seek_stock = StockSeekDay()
seek_fame = FameSeekDay()
seek_list = [seek_health, seek_stock, seek_fame]
me = Person()
seek_choice = np.random.choice([0, 1, 2], 80000, p=weights)
while me.living >0:
seek_ind = seek_choice[me.living_day]
seek = seek_list[seek_ind]
me.live_one_day(seek)
return round(me.living_day /365, 2), round(me.happiness, 2), round(me.wealth, 2), round(me.fame, 2)
# living_day, happiness, wealth, fame = my_life([0.4, 0.3, 0.3])
# print('活了{(lán)}年节芥,幸福指數(shù){}, 積累財(cái)富{}, 名望權(quán)力{}'.format(living_day, happiness, wealth, fame))
result = []
for _in range(20):
weights = np.random.random(3)
weights /= np.sum(weights)
result.append((weights, my_life(weights)))
sorted_scores =sorted(result, key=lambda x:x[1][1], reverse=True)
living_day, happiness, wealth, fame = my_life(sorted_scores[0][0])
# print('活了{(lán)}年在刺,幸福指數(shù){}, 積累財(cái)富{}, 名望權(quán)力{}'.format
#? ? ? ? ? (living_day, happiness, wealth, fame))
#
# print('人生最優(yōu)權(quán)重:追求健康{:.3f},追求財(cái)富{:.3f},追求名望{:.3f}'.format(
#? ? ? ? sorted_scores[0][0][0], sorted_scores[0][0][1],
#? ? ? ? sorted_scores[0][0][2]))
result_show = np.array([[r[0][0], r[0][1], r[0][2], r[1][1]]for rin result])
fig = plt.figure(figsize=(9, 6))
ax = fig.gca(projection='3d')
ax.view_init(30, 60)
"""
x:追求健康長(zhǎng)壽快樂(lè)的權(quán)重, y:追求財(cái)富金錢的權(quán)重
z:追求名望權(quán)力的權(quán)重, c:color 幸福指數(shù), 顏色越深越幸福
"""
ax.scatter3D(result_show[:, 0], result_show[:, 1], result_show[:, 2],
? ? ? ? ? ? c=result_show[:, 3], cmap='spring')
ax.set_xlabel('health')
ax.set_ylabel('stock')
ax.set_zlabel('fame')
# 幸福指數(shù)
happiness_result = result_show[:, 3]
# 使用qcut分10份
print(pd.qcut(happiness_result, 10).value_counts())
plt.show()
(本文學(xué)習(xí)自阿布量化https://www.abuquant.com)