数据分析及画图告一段落

This commit is contained in:
wJsJwr 2018-03-20 20:35:36 +08:00
parent da43bcc09a
commit 585ba34a7d
20 changed files with 675 additions and 211 deletions

112
.vscode/.ropeproject/config.py vendored Normal file
View File

@ -0,0 +1,112 @@
# The default ``config.py``
# flake8: noqa
def set_prefs(prefs):
"""This function is called before opening the project"""
# Specify which files and folders to ignore in the project.
# Changes to ignored resources are not added to the history and
# VCSs. Also they are not returned in `Project.get_files()`.
# Note that ``?`` and ``*`` match all characters but slashes.
# '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
# 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
# '.svn': matches 'pkg/.svn' and all of its children
# 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
# 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
'.hg', '.svn', '_svn', '.git', '.tox']
# Specifies which files should be considered python files. It is
# useful when you have scripts inside your project. Only files
# ending with ``.py`` are considered to be python files by
# default.
#prefs['python_files'] = ['*.py']
# Custom source folders: By default rope searches the project
# for finding source folders (folders that should be searched
# for finding modules). You can add paths to that list. Note
# that rope guesses project source folders correctly most of the
# time; use this if you have any problems.
# The folders should be relative to project root and use '/' for
# separating folders regardless of the platform rope is running on.
# 'src/my_source_folder' for instance.
#prefs.add('source_folders', 'src')
# You can extend python path for looking up modules
#prefs.add('python_path', '~/python/')
# Should rope save object information or not.
prefs['save_objectdb'] = True
prefs['compress_objectdb'] = False
# If `True`, rope analyzes each module when it is being saved.
prefs['automatic_soa'] = True
# The depth of calls to follow in static object analysis
prefs['soa_followed_calls'] = 0
# If `False` when running modules or unit tests "dynamic object
# analysis" is turned off. This makes them much faster.
prefs['perform_doa'] = True
# Rope can check the validity of its object DB when running.
prefs['validate_objectdb'] = True
# How many undos to hold?
prefs['max_history_items'] = 32
# Shows whether to save history across sessions.
prefs['save_history'] = True
prefs['compress_history'] = False
# Set the number spaces used for indenting. According to
# :PEP:`8`, it is best to use 4 spaces. Since most of rope's
# unit-tests use 4 spaces it is more reliable, too.
prefs['indent_size'] = 4
# Builtin and c-extension modules that are allowed to be imported
# and inspected by rope.
prefs['extension_modules'] = []
# Add all standard c-extensions to extension_modules list.
prefs['import_dynload_stdmods'] = True
# If `True` modules with syntax errors are considered to be empty.
# The default value is `False`; When `False` syntax errors raise
# `rope.base.exceptions.ModuleSyntaxError` exception.
prefs['ignore_syntax_errors'] = False
# If `True`, rope ignores unresolvable imports. Otherwise, they
# appear in the importing namespace.
prefs['ignore_bad_imports'] = False
# If `True`, rope will insert new module imports as
# `from <package> import <module>` by default.
prefs['prefer_module_from_imports'] = False
# If `True`, rope will transform a comma list of imports into
# multiple separate import statements when organizing
# imports.
prefs['split_imports'] = False
# If `True`, rope will remove all top-level import statements and
# reinsert them at the top of the module when making changes.
prefs['pull_imports_to_top'] = True
# If `True`, rope will sort imports alphabetically by module name instead of
# alphabetically by import statement, with from imports after normal
# imports.
prefs['sort_imports_alphabetically'] = False
# Location of implementation of rope.base.oi.type_hinting.interfaces.ITypeHintingFactory
# In general case, you don't have to change this value, unless you're an rope expert.
# Change this value to inject you own implementations of interfaces
# listed in module rope.base.oi.type_hinting.providers.interfaces
# For example, you can add you own providers for Django Models, or disable the search
# type-hinting in a class hierarchy, etc.
prefs['type_hinting_factory'] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'
def project_opened(project):
"""This function is called after opening the project"""
# Do whatever you like here!

BIN
.vscode/.ropeproject/objectdb vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
{
"python.pythonPath": "/Users/wjsjwr/.pyenv/versions/anaconda3-5.0.1/bin/python"
}

View File

@ -5,42 +5,45 @@ from island.matches import Matches
matches = Matches('wos-data-new')
labels = ['has neighbor', 'no neighbor']
labels = ['Stay Connected', 'Break Tie']
percents = [0.0, 0.0]
op = 'D'
for m in matches.data:
info = m.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
for row in m.query('action', 'done').where(lambda x: x['act_a'] == 'D' or x['act_b'] == 'D').raw_data:
for row in m.query('action', 'done').where(lambda x: x['act_a'] == op or x['act_b'] == op).raw_data:
if row['rno'] == game_end_at:
print(row)
continue
if row['act_a'] == 'D':
if row['act_a'] == op:
a = row['a']
b = row['b']
o = m.query('action', 'done').where(lambda y: (y['b'] == a or y['a'] == a) and y['rno'] == row['rno'] + 1).raw_data
o = m.query('action', 'done').where(lambda y: ((y['b'] == a and y['a'] == b) or (y['a'] == a and y['b'] == b)) and y['rno'] == row['rno'] + 1).raw_data
if o:
percents[0] += 1
else:
percents[1] += 1
if row['act_b'] == 'D':
if row['act_b'] == op:
a = row['a']
b = row['b']
o = m.query('action', 'done').where(lambda y: (y['b'] == b or y['a'] == b) and y['rno'] == row['rno'] + 1).raw_data
o = m.query('action', 'done').where(lambda y: ((y['b'] == a and y['a'] == b) or (y['a'] == a and y['b'] == b)) and y['rno'] == row['rno'] + 1).raw_data
if o:
percents[0] += 1
else:
percents[1] += 1
print(percents)
_all = sum(percents) / 100
percents[0] /= _all
percents[1] /= _all
plt.figure()
plt.pie(percents, labels=labels, autopct='%1.1f%%', startangle=90)
plt.pie(percents, labels=labels, autopct="%1.2f%%", pctdistance=1.1, labeldistance=2,startangle=90, colors=['#00b894', '#fdcb6e'])
plt.legend()
plt.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
# plt.savefig('graph/unlink_has_neighbor.png')
# plt.show()
plt.savefig("graph/break_tie_%s.eps"%op)

6
break_tie_chi2.py Normal file
View File

@ -0,0 +1,6 @@
from scipy.stats import chi2_contingency as chi2
import numpy as np
obs = np.array([[219,113],[661,25]])
chi,p,dof,expected = chi2(obs)
print("%f, %f, %f" % (chi, p, dof))

37
calc_dnc_players.py Normal file
View File

@ -0,0 +1,37 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
import numpy as np
matches = Matches('wos-data-new')
max_round = 15
total_players = 0
dnc_players = 0
survivals = {}
with open('survivals.json', 'r') as f:
survivals = json.load(f)
for j in range(len(matches.data)):
players = set()
for r in matches.data[j].query('player', 'join').raw_data:
players.add(r['pid'])
total_players += len(players)
for i in range(int(matches.data[j].query('game', 'created').first()['info']['game_end_at'])):
actions = matches.data[j].query('action', 'done').where(lambda x: x['rno']==i+1)
for r in actions.raw_data:
if r['a'] in players:
if actions.where(lambda y: (y['a'] == r['a'] and y['b'] != r['b']) or (y['b'] == r['a'] and y['a'] != r['b'])).count() > 0:
dnc_players += 1
players.remove(r['a'])
if r['b'] in players:
if actions.where(lambda y: (y['a'] == r['b'] and y['b'] != r['a']) or (y['b'] == r['b'] and y['a'] != r['a'])).count() > 0:
dnc_players += 1
players.remove(r['b'])
print("dnc=%d, total=%d, frac=%f" % (dnc_players, total_players, dnc_players / total_players))

19
calc_participants.py Normal file
View File

@ -0,0 +1,19 @@
# from G254
import json
from pathlib import Path
from island.match import Match
result = 0
for file in Path('wos-data-new').iterdir():
p = Path(file)
if p.suffix == '.json':
name = p.stem
if int(name[1:]) >= 254:
m = Match.read_from_json(str(file))
result += len(m.query('player', 'join').select('pid').raw_data)
print(result)
# 146 users

View File

@ -4,49 +4,73 @@ from island.match import Match
from island.matches import Matches
import numpy as np
def calc_co(matches):
def calc_co(matches, is_casual):
x = [0,0,0,0,0,0]
count = 0
for j in range(len(matches.data)):
if len(matches.data[j].query('action', 'done').raw_data) < 5:
continue
coop = 0
total = 0
count += 1
players = []
if is_casual:
for row in matches.data[j].query('player', 'join').where(lambda r: 'bot' not in r).raw_data:
players.append(row['pid'])
rows = matches.data[j].query('action', 'done').raw_data
for row in rows:
if row['act_a'] == 'C' and row['act_b'] == 'C':
coop += 1
if is_casual:
for row in rows:
if row['a'] in players:
total += 1
if row['act_a'] == 'C':
coop += 1
if row['b'] in players:
total += 1
if row['act_b'] == 'C':
coop += 1
else:
for row in rows:
if row['act_a'] == 'C':
coop += 1
if row['act_b'] == 'C':
coop += 1
total += 2
if rows:
per = float(coop) / len(rows)
per = float(coop) / total
x[int(per*100)//20] += 1
x[4] += x[5]
x.pop()
s = sum(x)
for i in range(5):
x[i] /= s
print("Match type: %s, Count: %d" % ('Casual' if is_casual else 'Compete', count))
return x
casual = Matches('wos-data-casual')
compete = Matches('wos-data-new')
ca = calc_co(casual)
co = calc_co(compete)
ca = calc_co(casual, True)
co = calc_co(compete, False)
fig = plt.figure(figsize=(5,4))
ax = fig.gca()
index = np.arange(5)
bar_width = 0.35
rects1 = ax.bar(index, ca, bar_width, color='#00b894', label='Casual games')
rects1 = ax.bar(index, ca, bar_width, color='#00b894', label='Casual mode')
# rects2 = ax.bar(index + bar_width, co, bar_width, color='#005CAF', label='Competition')
rects2 = ax.bar(index + bar_width, co, bar_width, color='#6c5ce7', label='Competition')
rects2 = ax.bar(index + bar_width, co, bar_width, color='#6c5ce7', label='Competing mode')
ax.set_xticks(index + bar_width / 2)
ax.set_xticklabels(['0~0.2','0.2~0.4','0.4~0.6','0.6~0.8','0.8~1'])
ax.legend()
# fig.autofmt_xdate()
fig.set_size_inches(5, 4)
plt.xlabel('Frequency of Cooperation Actions per Match')
plt.xlabel('Frequency of Human Cooperations per Match')
plt.ylabel('Fraction of Matches')
fig.tight_layout()
# plt.show()
plt.savefig('graph/comp_co_per_match.eps')
plt.savefig('graph/CompCoPerMatch.eps')

View File

@ -1,3 +1,4 @@
# -*- coding: UTF-8 -*-
import json
from matplotlib import pyplot as plt
import scipy as sp
@ -25,11 +26,13 @@ for j in range(len(matches.data)):
info = matches.data[j].query('game', 'created').select('info').raw_data[0]['info']
ns = int(info['next_start'])
for row in rows:
if row['act_a'] == 'C' and row['act_b'] == 'C':
if row['act_a'] == 'C':
coop += 1
if row['act_b'] == 'C':
coop += 1
if rows:
data[ns] = float(coop) / len(rows)
data[ns] = float(coop) / len(rows) / 2
x.append(ns)
x = sorted(x)
@ -51,5 +54,5 @@ fx = sp.linspace(0,_x[-1],1000)
plt.plot(fx,f1(fx),linewidth=1,color='red')
# plt.show()
plt.savefig('graph/co_per_game.png')
plt.show()
# plt.savefig('graph/co_per_game.png')

View File

@ -1,7 +1,7 @@
import json
import math
from cairo import Context, LineCap, LineJoin, PSSurface, SVGSurface
from pathlib import Path
from cairo import Context, LineCap, LineJoin, PSSurface, SVGSurface, Gradient, LinearGradient
# from scipy.integrate import quad
from island.match import Match
@ -140,6 +140,7 @@ def draw_action_arrow(ctx, cf, ct, w, al, r, c):
ctx.set_source_rgba(c.r, c.g, c.b, c.a)
ctx.set_line_width(w)
ctx.set_line_cap(LineCap.ROUND)
ctx.set_line_join(LineJoin.ROUND)
ltr = 1 if cf.x < ct.x else -1
af = Point(cf.x + ltr * r / SQRT2, cf.y - ltr * r / SQRT2)
at = Point(ct.x - ltr * r / SQRT2, ct.y - ltr * r / SQRT2)
@ -155,6 +156,27 @@ def draw_action_arrow(ctx, cf, ct, w, al, r, c):
ctx.line_to(at.x + al * math.cos(a + math.pi / 12), at.y + al * math.sin(a + math.pi / 12))
ctx.stroke()
def draw_legend_arrow(ctx, cf, ct, w, al, c):
"""
:param ctx: context
:param cf: from the center point
:param ct: to the center point
:param w: line width
:param al: arrow length
:param c: Color
"""
ctx.set_source_rgba(c.r, c.g, c.b, c.a)
ctx.set_line_width(w)
ctx.set_line_cap(LineCap.ROUND)
ctx.set_line_join(LineJoin.ROUND)
ctx.move_to(cf.x, cf.y)
ctx.line_to(ct.x, ct.y)
ctx.line_to(ct.x - al * math.cos(-math.pi / 12), ct.y + al * math.sin(-math.pi / 12))
ctx.move_to(ct.x, ct.y)
ctx.line_to(ct.x - al * math.cos(math.pi / 12), ct.y + al * math.sin(math.pi / 12))
ctx.stroke()
def draw_food_bar(ctx, refp, food, foodi, w, h):
"""
:param ctx: context
@ -176,6 +198,30 @@ def draw_food_bar(ctx, refp, food, foodi, w, h):
ctx.set_source_rgba(0, 0, 0, 1)
ctx.stroke()
def draw_linear_gradient_rect(ctx, tl, br, lw, start, stop, horizonal=True):
"""
:param ctx: context
:param tl: the top-left reference point
:param br: the right-bottom reference point
:param lw: line width
:param start: start color
:param stop: stop color
:param horizonal: if the gradient is horizonal
"""
ctx.set_line_cap(LineCap.SQUARE)
ctx.set_line_join(LineJoin.MITER)
# source = ctx.get_source()
lr = LinearGradient(tl.x, tl.y, br.x, br.y)
lr.add_color_stop_rgba(0, start.r, start.g, start.b, start.a)
lr.add_color_stop_rgba(1, stop.r, stop.g, stop.b, stop.a)
ctx.set_source(lr)
ctx.rectangle(tl.x, tl.y, br.x - tl.x, br.y - tl.y)
ctx.fill()
# ctx.rectangle(tl.x, tl.y, br.x - tl.x, br.y - tl.y)
# ctx.set_line_width(lw)
# ctx.set_source_rgba(0, 0, 0, 1)
# ctx.stroke()
def draw_faces(ctx, p, f, r, lw):
"""
@ -187,22 +233,23 @@ def draw_faces(ctx, p, f, r, lw):
"""
for k in p.keys():
if f[k] > 0:
draw_alive_face(context, p[k], r, lw)
draw_alive_face(ctx, p[k], r, lw)
else:
draw_dead_face(context, p[k], r, lw)
draw_dead_face(ctx, p[k], r, lw)
draw_food_bar(ctx, p[k].new_rel_point(r / SQRT2 + 20, r / SQRT2), f[k], 5, 10, r * SQRT2)
draw_text(ctx, str(k), Point(p[k].x, p[k].y - r - 15), Point(p[k].x, p[k].y - r - 5), CENTER_ALIGNED|MIDDLE_ALIGNED, 12)
def draw_text(ctx, text, tl, rb, align, font_size=None, font_face=None, font_matrix=None, font_options=None):
def draw_text(ctx, text, tl, br, align, font_size=None, color=Color(0,0,0,1), font_face=None, font_matrix=None, font_options=None):
"""
draw text
:param ctx: context
:param text: the text
:param tl: the top-left reference point
:param rb: the right-bottom reference point
:param br: the right-bottom reference point
:param align: alignment
:param font_size: float font size
:param color: text color
:param font_face: font face
:param font_matrix: font matrix
:param font_options: font options
@ -219,19 +266,20 @@ def draw_text(ctx, text, tl, rb, align, font_size=None, font_face=None, font_mat
te = ctx.text_extents(text)
ha = align & 0b00001111
if ha == CENTER_ALIGNED:
x = (rb.x + tl.x - te.width) / 2 - te.x_bearing / 2
x = (br.x + tl.x - te.width) / 2 - te.x_bearing / 2
elif ha == RIGHT_ALIGNED:
x = rb.x - te.width
x = br.x - te.width
else:# ha == LEFT_ALIGNED
x = tl.x - te.x_bearing
va = align & 0b11110000
if va == MIDDLE_ALIGNED:
y = (rb.y + tl.y + te.height) / 2 - (te.height + te.y_bearing) / 2
y = (br.y + tl.y + te.height) / 2 - (te.height + te.y_bearing) / 2
elif va == BOTTOM_ALIGNED:
y = rb.y
y = br.y
else: #va == TOP_ALIGNED:
y = tl.y + te.height - (te.height + te.y_bearing)
ctx.move_to(x, y)
set_color(ctx, color)
ctx.show_text(text)
LEFT_ALIGNED = 0b00000001
@ -249,28 +297,35 @@ FACE_WIDTH = 100
FACE_INTERVAL = 50
ROUND_HEIGHT = 300
LINEWIDTH = 4
ROUND_NO_WIDTH = 75
TAMAMOROKOSHI = Color(0.9098039215686275, 0.7137254901960784, 0.2784313725490196, 1)
AKE = Color(0.8, 0.3294117647058824, 0.2274509803921569, 1)
TOKIWA = Color(0.1058823529411765, 0.5058823529411765, 0.2431372549019608, 1)
if __name__ == '__main__':
M = Match.read_from_json("D:\\code\\python\\swdata\\wos-data-new\\G302.json")
def draw_picture(fin,fout):
M = Match.read_from_json(fin)
info = M.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
P = {}
F = {}
P = {} # position
F = {} # face
R = 30
for r in M.query('player', 'join').raw_data:
P[r['pid']] = Point(len(F) * FACE_WIDTH + FACE_INTERVAL, ROUND_HEIGHT / 2)
P[r['pid']] = Point(len(F) * FACE_WIDTH + FACE_INTERVAL + ROUND_NO_WIDTH, ROUND_HEIGHT / 2)
F[r['pid']] = 5
surface = SVGSurface("example.svg", len(P)*(FACE_WIDTH)+FACE_WIDTH, (game_end_at+2)*ROUND_HEIGHT)
# surface = SVGSurface("example.svg", len(P)*(FACE_WIDTH)+FACE_WIDTH, (game_end_at+2)*ROUND_HEIGHT)
surface = PSSurface(fout, (len(P)+1)*(FACE_WIDTH) + ROUND_NO_WIDTH, (game_end_at+2)*ROUND_HEIGHT)
surface.set_eps(True)
context = Context(surface)
bottom = 0
for i in range(1, game_end_at + 2):
next_f = F.copy()
draw_text(context, "Round %d" % i, Point(5, ROUND_HEIGHT/2+(i-1)*ROUND_HEIGHT), Point(ROUND_NO_WIDTH, ROUND_HEIGHT/2+(i-1)*ROUND_HEIGHT), LEFT_ALIGNED | MIDDLE_ALIGNED, 20)
for r in M.query('action', 'done').where(lambda row: row['rno'] == i).raw_data:
draw_action_arrow(context, P[r['a']], P[r['b']], LINEWIDTH, 15, R, AKE.shade(r['tr'] / 1440) if r['act_a'] == 'D' else TOKIWA.shade(r['tr']/1440))
draw_action_arrow(context, P[r['b']], P[r['a']], LINEWIDTH, 15, R, AKE.shade(r['tr'] / 1440) if r['act_b'] == 'D' else TOKIWA.shade(r['tr']/1440))
@ -281,5 +336,24 @@ if __name__ == '__main__':
F[k] = next_f[k] - conf['rounds']['consumption']
P[k].rel_move_to(0, ROUND_HEIGHT)
# draw legend
draw_legend_arrow(context, Point(50, ROUND_HEIGHT * (game_end_at + 1)), Point(75, ROUND_HEIGHT * (game_end_at + 1)), LINEWIDTH, 15, TOKIWA)
draw_legend_arrow(context, Point(50, ROUND_HEIGHT * (game_end_at + 1) + 30), Point(75, ROUND_HEIGHT * (game_end_at + 1) + 30), LINEWIDTH, 15, AKE)
draw_text(context, 'C', Point(100, ROUND_HEIGHT * (game_end_at + 1)), Point(120, ROUND_HEIGHT * (game_end_at + 1)), LEFT_ALIGNED|TOP_ALIGNED, 30)
draw_text(context, 'D', Point(100, ROUND_HEIGHT * (game_end_at + 1) + 30), Point(120, ROUND_HEIGHT * (game_end_at + 1) + 30), LEFT_ALIGNED|TOP_ALIGNED, 30)
draw_linear_gradient_rect(context, Point(200, ROUND_HEIGHT * (game_end_at + 1)), Point(350, ROUND_HEIGHT * (game_end_at + 1) + 20), 2, TOKIWA, TOKIWA.shade(0))
draw_linear_gradient_rect(context, Point(200, ROUND_HEIGHT * (game_end_at + 1)+30), Point(350, ROUND_HEIGHT * (game_end_at + 1) + 50), 2, AKE, AKE.shade(0))
surface.finish()
if __name__ == '__main__':
# for file in Path('wos-data-new').iterdir():
# p = Path(file)
# if p.suffix == '.json':
# name = p.stem
# draw_picture(str(p), str(p.parent.parent / 'graph' / ("%s.eps"%name)))
draw_picture("wos-data-new/G285.json", "graph/G285.eps")

View File

@ -3,12 +3,11 @@ from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-casual')
matches = Matches('wos-data-new')
labels = ['not enough tr', 'other reason']
percents = [0.0, 0.0]
op = 'D'
op = 'C'
def get_reason(m, i, target):
r = m.query('action', 'request').where(lambda x: x['rno'] == i+1 and x['from'] == target).raw_data
@ -25,7 +24,7 @@ def get_reason(m, i, target):
tr += m.query('action', 'request').where(lambda x: x['rno'] == i+1 and x['from'] == j['to'] and x['to'] == k['from'] and x['log_id'] < k['log_id']).orderby('log_id').raw_data[-1]['tr']
for k in m.query('action', 'approve').where(lambda x: x['rno'] == i+1 and x['from'] == j['to']).raw_data:
tr -= k['tr']
print(tr)
# print(tr)
if tr >= j['tr']:
percents[1] += 1
else:
@ -47,12 +46,17 @@ for m in matches.data:
get_reason(m, i, row['b'])
calced.add(row['b'])
print(percents)
_all = sum(percents) / 100
percents[0] /= _all
percents[1] /= _all
labels = ['Insufficient Time Resource', 'Sufficient Time Resource']
plt.figure()
plt.pie(percents, labels=labels, autopct='%1.2f%%', startangle=90)
plt.pie(percents, labels=labels, autopct="%1.2f%%", pctdistance=1.1, labeldistance=2,startangle=90, colors=['#00b894', '#fdcb6e'])
plt.legend()
plt.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
# plt.savefig('graph/unlink_has_neighbor.png')
# plt.show()
plt.savefig("graph/fail_reason_%s.eps"%op)

6
fail_reason_chi2.py Normal file
View File

@ -0,0 +1,6 @@
from scipy.stats import chi2_contingency as chi2
import numpy as np
obs = np.array([[159,90],[53,24]])
chi,p,dof,expected = chi2(obs)
print("%f, %f, %f" % (chi, p, dof))

64
interactions_per_round.py Normal file
View File

@ -0,0 +1,64 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
import numpy as np
matches = Matches('wos-data-new')
max_round = 15
coopr = []
yerr_min = []
yerr_max = []
x = np.arange(max_round)
bx = []
y = np.zeros((5, max_round))
sy = np.zeros(max_round)
survivals = {}
with open('survivals.json', 'r') as f:
survivals = json.load(f)
for i in range(max_round):
co = {}
for j in range(len(matches.data)):
if str(i+1) not in survivals[matches.names[j]]:
continue
for k in survivals[matches.names[j]][str(i+1)]:
co[k] = 0
rows = matches.data[j].query('action', 'done').where(lambda x: x['rno']==i+1).raw_data
for row in rows:
if row['a'] in co:
co[row['a']] += 1
if row['b'] in co:
co[row['b']] += 1
for j in co.values():
if j <= 4:
y[j][i] += 1
else:
y[4][i] += 1
sy[i] += 1
# bx.append(list(co.values()))
# plt.figure()
# plt.boxplot(bx, showmeans=True, meanline=True)
# plt.show()
labels = ["k = 0 ", "k = 1", "k = 2", "k = 3", "k ⩾ 4"]
colors = ['#0984e3', '#fdcb6e', '#00b894', '#6c5ce7', '#d63031', '#0984e3']
y /= sy
fig = plt.figure(figsize=(6, 4))
ax = fig.gca()
ax.stackplot(x+1, y, labels=labels, colors=colors)
ax.set_xticks(x+1)
ax.set_xticklabels(x+1)
ax.set_xlim(1,15)
ax.set_ylim(0, 1)
ax.set_xlabel('Round')
ax.set_ylabel('Fraction of k')
ax.legend()
plt.tight_layout()
# plt.show()
plt.savefig('graph/interaction_per_round.eps')

View File

@ -78,7 +78,7 @@ class Match:
def first(self):
"""
return first result
return the first result
"""
if self.dtype != 'mid':
raise RuntimeError("first query on raw data.")
@ -86,6 +86,15 @@ class Match:
rawl = len(self.raw_data)
return self.raw_data[0] if rawl > 0 else None
def count(self):
"""
return the amount of results
"""
if self.dtype != 'mid':
raise RuntimeError("count query on raw data.")
return len(self.raw_data)
@staticmethod
def read_from_json(json_path):
"""

View File

@ -7,7 +7,7 @@ import numpy as np
matches = Matches('wos-data-new')
max_round = 17
max_round = 15
survivals = {}
with open('survivals.json', 'r') as f:
@ -21,6 +21,23 @@ cstd = []
dstd = []
def is_defector(rows, pid):
m = 0
mall = 0
for r in rows:
if pid == r['a'] and r['act_a'] == 'C':
m += 1
mall += 1
elif pid == r['a'] and r['act_a'] == 'D':
mall += 1
elif pid == r['b'] and r['act_b'] == 'C':
m += 1
mall += 1
elif pid == r['b'] and r['act_b'] == 'D':
mall += 1
return m*2 >= mall
for i in range(len(matches.data)):
m = matches.data[i]
n = {}
@ -50,7 +67,7 @@ for i in range(max_round):
if k in survivals[matches.names[j]][str(i+1)]:
nn += 1
if row['act_a'] == 'C':
if is_defector(rows, row['a']):
cneigh.append(nn)
else:
dneigh.append(nn)
@ -61,12 +78,10 @@ for i in range(max_round):
for k in neighbors[matches.names[j]][row['b']]:
if k in survivals[matches.names[j]][str(i+1)]:
nn += 1
if row['act_b'] == 'C':
if is_defector(rows, row['b']):
cneigh.append(nn)
else:
dneigh.append(nn)
calced.add(row['b'])
if cneigh:
@ -86,25 +101,27 @@ for i in range(max_round):
dmean.append(dm)
dstd.append(ds)
fig, ax = plt.subplots()
index = np.arange(17)
bar_width = 0.35
opacity = 0.4
error_config = {'ecolor': '0.3', 'capsize': 4}
fig = plt.figure(figsize=(6.4, 3.6))
ax = fig.gca()
index = np.arange(max_round)
bar_width = 0.45
opacity = 1
error_config = dict(ecolor='#2d3436', capsize=0, elinewidth=1)
rects1 = ax.bar(index, cmean, bar_width,
alpha=opacity, color='b',
alpha=opacity, color='#0984e3',
yerr=cstd, error_kw=error_config,
label='C')
label='Cooperator')
rects2 = ax.bar(index + bar_width, dmean, bar_width,
alpha=opacity, color='r',
alpha=opacity, color='#d63031',
yerr=dstd, error_kw=error_config,
label='D')
# ax.set_xlabel('Group')
# ax.set_ylabel('Scores')
label='Defector')
ax.set_xlabel('Round')
ax.set_ylabel('Size of the Neighborhood')
# ax.set_title('Scores by group and gender')
ax.set_xticks(index + bar_width / 2)
ax.set_xticklabels(index+1)
ax.legend()
fig.tight_layout()
plt.show()
# plt.show()
plt.savefig('graph/neigh_per_round.eps')

View File

@ -1,45 +0,0 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-new')
max_round = 17
coopr = []
yerr_min = []
yerr_max = []
x = []
bx = []
survivals = {}
with open('winner.json','r') as f:
survivals = json.load(f)
for i in range(max_round):
co = []
for j in range(len(matches.data)):
nodes = set()
rows = matches.data[j].query('action', 'done').where(lambda x: x['rno']==i+1).raw_data
for row in rows:
nodes.add(row['a'])
nodes.add(row['b'])
if rows:
co.append(float(len(rows) * 2) / float(len(nodes)))
bx.append(co)
if co:
coopr.append(sum(co) / len(co))
yerr_min.append(coopr[-1] - min(co))
yerr_max.append(max(co) - coopr[-1])
print("%f, %f, %f"%(yerr_min[-1], yerr_max[-1], coopr[-1]))
x.append(i+1)
plt.figure()
# plt.errorbar(x, coopr, yerr=[yerr_min, yerr_max], fmt='o', capsize=4)
plt.boxplot(bx, showmeans=True, meanline=True)
plt.show()
# plt.savefig('graph/co_per_round.png')

View File

@ -2,15 +2,17 @@ import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
import numpy as np
matches = Matches('wos-data-new')
max_round = 17
max_round = 15
alive = []
yerr_min = []
yerr_max = []
yerr = []
x = []
al_al = []
d = []
d_sem = []
survivals = {}
with open('winner.json','r') as f:
@ -18,6 +20,7 @@ with open('winner.json','r') as f:
for i in range(max_round):
defects = []
count = []
for j in range(len(matches.data)):
defector = set()
for row in matches.data[j].query('action', 'done').where(lambda x: x['rno']==i+1 and (x['act_a']=='D' or x['act_b']=='D')).raw_data:
@ -34,22 +37,39 @@ for i in range(max_round):
incr += 1
# print(k)
defects.append(float(incr) / float(len(defector)))
count.append(len(defector))
print(i)
print(defects)
print(count)
if defects:
defects = np.array(defects)
al_al.append(defects)
alive.append(sum(defects) / len(defects))
yerr_min.append(alive[-1] - min(defects))
yerr_max.append(max(defects) - alive[-1])
print("%f, %f, %f"%(yerr_min[-1], yerr_max[-1], alive[-1]))
x.append(i+1)
alive.append(np.average(defects))
yerr.append(np.std(defects))
count = np.array(count)
d.append(np.average(count))
d_sem.append(np.std(count))
else:
al_al.append([])
alive.append(0)
yerr.append(0)
d.append(0)
d_sem.append(0)
x.append(i+1)
plt.figure()
fig = plt.figure(figsize=(6.4, 4))
flier_marker = dict(markerfacecolor='w', marker='o', markersize=3, markeredgewidth=0.5)
mean_marker = dict(markerfacecolor='w', marker='s', markeredgecolor='#0984e3', markersize=3, markeredgewidth=1)
ax1 = fig.gca()
# plt.errorbar(x, alive, yerr=[yerr_min, yerr_max], fmt='o', capsize=4)
plt.boxplot(al_al, showmeans=True, meanline=True)
ax1.boxplot(al_al, showmeans=True, meanprops=mean_marker, flierprops=flier_marker)
plt.xlabel('Round')
plt.ylabel('Frequency of Defection Survivals')
# ax2 = ax1.twinx()
# ax2.errorbar(list(range(1, max_round+1)), d, yerr=d_sem, fmt='o-', capsize=2, color='#00b894', alpha=0.5, linewidth=1, zorder=-1)
# ax2.errorbar(x, alive, yerr=yerr, fmt='o-', capsize=2, color='#00b894', alpha=0.5, linewidth=1, zorder=-1)
# ax2.tick_params(axis='y', labelcolor='#00b894')
plt.tight_layout()
plt.show()
# plt.savefig('graph/survive_after_defect.png')

View File

@ -6,24 +6,16 @@ from numpy import mean, std
import numpy as np
matches = Matches('wos-data-casual')
max_round = 17
matches = Matches('wos-data-new')
max_round = 14
c_req_suc_mean = []
d_req_suc_mean = []
c_req_suc_std = []
d_req_suc_std = []
c_req_succ = np.zeros(max_round-2)
c_req = np.zeros(max_round-2)
d_req_succ = np.zeros(max_round-2)
d_req = np.zeros(max_round-2)
c_req_fail_mean = []
d_req_fail_mean = []
c_req_fail_std = []
d_req_fail_std = []
for i in range(max_round):
cReSu = []
cReFa = []
dReSu = []
dReFa = []
for j in range(len(matches.data)):
rows = matches.data[j].query('action', 'done').where(lambda x: x['rno'] == i+1).raw_data
calced = set()
@ -32,90 +24,81 @@ for i in range(max_round):
r = matches.data[j].query('action', 'request').where(lambda x: x['rno'] == i+2 and x['from'] == row['a']).raw_data
rs = matches.data[j].query('action', 'approve').where(lambda x: x['rno'] == i+2 and x['to'] == row['a']).raw_data
if row['act_a'] == 'C':
cReSu.append(len(rs))
cReFa.append(len(r) - len(rs))
c_req_succ[j] += len(rs)
c_req[j] += len(r)
else:
dReSu.append(len(rs))
dReFa.append(len(r) - len(rs))
d_req_succ[j] += len(rs)
d_req[j] += len(r)
calced.add(row['a'])
if row['b'] not in calced:
r = matches.data[j].query('action', 'request').where(lambda x: x['rno'] == i+2 and x['from'] == row['b']).raw_data
rs = matches.data[j].query('action', 'approve').where(lambda x: x['rno'] == i+2 and x['to'] == row['b']).raw_data
if row['act_b'] == 'C':
cReSu.append(len(rs))
cReFa.append(len(r) - len(rs))
c_req_succ[j] += len(rs)
c_req[j] += len(r)
else:
dReSu.append(len(rs))
dReFa.append(len(r) - len(rs))
d_req_succ[j] += len(rs)
d_req[j] += len(r)
calced.add(row['b'])
if cReSu:
cm = mean(cReSu)
cs = std(cReSu)
else:
cm = 0
cs = 0
c_req_suc_mean.append(cm)
c_req_suc_std.append(cs)
if cReFa:
cm = mean(cReFa)
cs = std(cReFa)
else:
cm = 0
cs = 0
c_req_fail_mean.append(cm)
c_req_fail_std.append(cs)
if dReSu:
dm = mean(dReSu)
ds = std(dReSu)
else:
dm = 0
ds = 0
d_req_suc_mean.append(dm)
d_req_suc_std.append(ds)
if dReFa:
dm = mean(dReFa)
ds = std(dReFa)
else:
dm = 0
ds = 0
d_req_fail_mean.append(dm)
d_req_fail_std.append(ds)
c_req_succ_fr = c_req_succ / c_req
d_req_succ_fr = d_req_succ / d_req
fig, ax = plt.subplots()
index = np.arange(17)
bar_width = 0.35
opacity = 0.6
error_config = {'ecolor': '0.3', 'capsize': 4}
rects1 = ax.bar(index, c_req_suc_mean, bar_width,
alpha=opacity, color='g',
# yerr=c_req_suc_std, error_kw=error_config,
label='C-Req-Success')
rects2 = ax.bar(index, c_req_fail_mean, bar_width,
alpha=opacity, color='b',
# yerr=c_req_fail_std, error_kw=error_config,
bottom=c_req_suc_mean,
label='C-Req-Fail')
# print(c_req_succ)
# print(c_req)
# print(c_req_succ_fr)
# print(d_req_succ)
# print(d_req)
# print(d_req_succ_fr)
req_succ_fr_mean = [mean(c_req_succ_fr), mean(d_req_succ_fr)]
req_succ_fr_sem = [std(c_req_succ_fr), std(d_req_succ_fr)]
req_succ = [c_req_succ_fr, d_req_succ_fr]
fig = plt.figure(figsize=(4, 3))
ax = fig.gca()
index = np.arange(2)
bar_width = 0.5
opacity = 1
error_config = {'ecolor': '0.3', 'capsize': 2, 'linewidth': 1}
# rects1 = ax.bar(index, req_succ_fr_mean, bar_width,
# alpha=opacity, color='#0984e3',
# yerr=req_succ_fr_sem, error_kw=error_config,
# label='C-Req-Success')
flier_marker = dict(markerfacecolor='w', marker='o', markersize=4, markeredgewidth=0.5)
mean_marker = dict(markerfacecolor='w', marker='s', markeredgecolor='#0984e3', markersize=5, markeredgewidth=1)
ax.boxplot(req_succ, showmeans=True, notch=True,
meanprops=mean_marker, flierprops=flier_marker,
whis=[0.15,99.85],
widths=0.4,
labels=['Cooperation', 'Defection'])
m1 = np.median(c_req_succ_fr)
m2 = np.median(d_req_succ_fr)
# i1 = np.subtract(*np.percentile(c_req_succ_fr, [75*0.98, 25*0.98]))
# i2 = np.subtract(*np.percentile(d_req_succ_fr, [75*0.98, 25*0.98]))
i1 = np.subtract(*np.percentile(c_req_succ_fr, [75, 25]))
i2 = np.subtract(*np.percentile(d_req_succ_fr, [75, 25]))
print('M=(%f, %f)' % (m1, m2))
print('IQR=(%f, %f)' % (i1, i2))
rects3 = ax.bar(index + bar_width, d_req_suc_mean, bar_width,
alpha=opacity, color='y',
# yerr=d_req_suc_mean, error_kw=error_config,
label='D-Req-Success')
rects4 = ax.bar(index + bar_width, d_req_fail_mean, bar_width,
alpha=opacity, color='r',
# yerr=d_req_fail_mean, error_kw=error_config,
bottom=d_req_suc_mean,
label='D-Req-Fail')
# ax.set_xlabel('Group')
# ax.set_ylabel('Scores')
# ax.set_title('Scores by group and gender')
ax.set_xticks(index + bar_width / 2)
ax.set_xticklabels(index+1)
ax.legend()
ax.set_ylabel('Rate')
ax.set_title('Request Approving Rate after Specific Actions', fontsize='small', weight='semibold')
# ax.set_xticks(index)
# ax.set_ylim(0, 1)
# ax.set_xlim(-0.75, 1.75)
# ax.set_xticklabels(index+2)
# ax.legend()
fig.tight_layout()
plt.show()
# plt.show()
plt.savefig('graph/request_success.eps')

View File

@ -0,0 +1,124 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
from numpy import mean, std
import numpy as np
matches = Matches('wos-data-new')
max_round = 13
c_req_suc_mean = []
d_req_suc_mean = []
c_req_suc_std = []
d_req_suc_std = []
c_req_fail_mean = []
d_req_fail_mean = []
c_req_fail_std = []
d_req_fail_std = []
for i in range(max_round):
cReSu = []
cReFa = []
dReSu = []
dReFa = []
for j in range(len(matches.data)):
rows = matches.data[j].query('action', 'done').where(lambda x: x['rno'] == i+1).raw_data
calced = set()
for row in rows:
if row['a'] not in calced:
r = matches.data[j].query('action', 'request').where(lambda x: x['rno'] == i+2 and x['from'] == row['a']).raw_data
rs = matches.data[j].query('action', 'approve').where(lambda x: x['rno'] == i+2 and x['to'] == row['a']).raw_data
if row['act_a'] == 'C':
cReSu.append(len(rs))
cReFa.append(len(r) - len(rs))
else:
dReSu.append(len(rs))
dReFa.append(len(r) - len(rs))
calced.add(row['a'])
if row['b'] not in calced:
r = matches.data[j].query('action', 'request').where(lambda x: x['rno'] == i+2 and x['from'] == row['b']).raw_data
rs = matches.data[j].query('action', 'approve').where(lambda x: x['rno'] == i+2 and x['to'] == row['b']).raw_data
if row['act_b'] == 'C':
cReSu.append(len(rs))
cReFa.append(len(r) - len(rs))
else:
dReSu.append(len(rs))
dReFa.append(len(r) - len(rs))
calced.add(row['b'])
if cReSu:
cm = mean(cReSu)
cs = std(cReSu)
else:
cm = 0
cs = 0
c_req_suc_mean.append(cm)
c_req_suc_std.append(cs)
if cReFa:
cm = mean(cReFa)
cs = std(cReFa)
else:
cm = 0
cs = 0
c_req_fail_mean.append(cm)
c_req_fail_std.append(cs)
if dReSu:
dm = mean(dReSu)
ds = std(dReSu)
else:
dm = 0
ds = 0
d_req_suc_mean.append(dm)
d_req_suc_std.append(ds)
if dReFa:
dm = mean(dReFa)
ds = std(dReFa)
else:
dm = 0
ds = 0
d_req_fail_mean.append(dm)
d_req_fail_std.append(ds)
fig = plt.figure(figsize=(6.4, 4))
ax = fig.gca()
index = np.arange(max_round)
bar_width = 0.35
opacity = 1
error_config = {'ecolor': '0.3', 'capsize': 4}
rects1 = ax.bar(index, c_req_suc_mean, bar_width,
alpha=opacity, color='#00b894',
# yerr=c_req_suc_std, error_kw=error_config,
label='Approve after Cooperation')
rects2 = ax.bar(index, c_req_fail_mean, bar_width,
alpha=opacity, color='#0984e3',
# yerr=c_req_fail_std, error_kw=error_config,
bottom=c_req_suc_mean,
label='Deny after Cooperation')
rects3 = ax.bar(index + bar_width, d_req_suc_mean, bar_width,
alpha=opacity, color='#fdcb6e',
# yerr=d_req_suc_mean, error_kw=error_config,
label='Approve after Defection')
rects4 = ax.bar(index + bar_width, d_req_fail_mean, bar_width,
alpha=opacity, color='#d63031',
# yerr=d_req_fail_mean, error_kw=error_config,
bottom=d_req_suc_mean,
label='Deny after Defection')
ax.set_xlabel('Round')
ax.set_ylabel('Number of Requests')
# ax.set_title('Scores by group and gender')
ax.set_xticks(index + bar_width / 2)
ax.set_xticklabels(index+2)
ax.legend()
fig.tight_layout()
# plt.show()
plt.savefig('graph/request_success_per_round.eps')

View File

@ -7,17 +7,18 @@ matches = Matches('wos-data-new')
labels = ['has neighbor', 'no neighbor']
percents = [0.0, 0.0]
op = 'C'
for m in matches.data:
info = m.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
for row in m.query('action', 'done').where(lambda x: x['act_a'] == 'D' or x['act_b'] == 'D').raw_data:
for row in m.query('action', 'done').where(lambda x: x['act_a'] == op or x['act_b'] == op).raw_data:
if row['rno'] == game_end_at:
print(row)
continue
if row['act_a'] == 'D':
if row['act_a'] == op:
a = row['a']
b = row['b']
n = m.query('action', 'done').where(lambda y: ((y['a'] == a and y['b'] == b) or (y['a'] == b and y['b'] == a)) and y['rno'] == row['rno'] + 1).raw_data
@ -29,7 +30,7 @@ for m in matches.data:
percents[0] += 1
else:
percents[1] += 1
if row['act_b'] == 'D':
if row['act_b'] == op:
a = row['a']
b = row['b']
n = m.query('action', 'done').where(lambda y: ((y['a'] == a and y['b'] == b) or (y['a'] == b and y['b'] == a)) and y['rno'] == row['rno'] + 1).raw_data