Хабрастистик: сайтын хамгийн их, хамгийн бага зочилсон хэсгүүдийг судлах

Хөөе Хабр.

В өмнөх хэсэг Хабрын урсгалыг үндсэн параметрүүд - нийтлэлийн тоо, тэдний үзэл бодол, үнэлгээний дагуу дүн шинжилгээ хийсэн. Гэсэн хэдий ч сайтын хэсгүүдийн алдар нэрийн асуудал шалгагдаагүй хэвээр байв. Үүнийг илүү нарийвчлан авч үзэх, хамгийн алдартай, хамгийн дургүй төвүүдийг олох нь сонирхолтой болсон. Эцэст нь би geektimes эффектийг илүү нарийвчлан авч үзэх бөгөөд шинэ зэрэглэлд суурилсан шилдэг нийтлэлүүдийн шинэ сонголтоор дуусгах болно.

Хабрастистик: сайтын хамгийн их, хамгийн бага зочилсон хэсгүүдийг судлах

Юу болсныг сонирхож буй хүмүүсийн хувьд үргэлжлэл нь тасалдсан байна.

Статистик, рейтинг нь албан ёсны биш, надад дотоод мэдээлэл байхгүй гэдгийг дахин сануулъя. Мөн би хаа нэгтээ алдаа гаргаагүй, ямар нэг зүйлийг алдаагүй гэсэн баталгаа байхгүй. Гэсэн хэдий ч энэ нь сонирхолтой болсон гэж би бодож байна. Бид эхлээд кодоос эхлэх болно, үүнийг сонирхдоггүй хүмүүс эхний хэсгүүдийг алгасаж болно.

Өгөгдөл цуглуулах

Шинжилгээний эхний хувилбарт зөвхөн үзсэн тоо, сэтгэгдэл, нийтлэлийн үнэлгээг харгалзан үзсэн. Энэ нь аль хэдийн сайн байгаа хэдий ч илүү төвөгтэй асуулга хийх боломжийг танд олгодоггүй. Сайтын сэдэвчилсэн хэсгүүдэд дүн шинжилгээ хийх цаг болжээ, энэ нь танд нэлээд сонирхолтой судалгаа хийх боломжийг олгоно, жишээлбэл, "C++" хэсгийн алдар нэр хэдэн жилийн турш хэрхэн өөрчлөгдсөнийг харах болно.

Өгүүллийн задлан шинжлэгчийг сайжруулсан бөгөөд одоо энэ нь нийтлэлийн харьяалагдах төвүүд, мөн зохиогчийн хоч, түүний үнэлгээг буцааж өгдөг (энд олон сонирхолтой зүйлийг хийх боломжтой, гэхдээ дараа нь ирэх болно). Мэдээллийг csv файлд хадгалсан бөгөөд энэ нь дараах байдалтай байна.

2018-12-18T12:43Z,https://habr.com/ru/post/433550/,"Мессенджер Slack — причины выбора, косяки при внедрении и особенности сервиса, облегчающие жизнь",votes:7,votesplus:8,votesmin:1,bookmarks:32,
views:8300,comments:10,user:ReDisque,karma:5,subscribers:2,hubs:productpm+soft
...

Бид сайтын гол сэдэвчилсэн төвүүдийн жагсаалтыг хүлээн авах болно.

def get_as_str(link: str) -> Str:
    try:
        r = requests.get(link)
        return Str(r.text)
    except Exception as e:
        return Str("")

def get_hubs():
    hubs = []
    for p in range(1, 12):
        page_html = get_as_str("https://habr.com/ru/hubs/page%d/" % p)
        # page_html = get_as_str("https://habr.com/ru/hubs/geektimes/page%d/" % p)  # Geektimes
        # page_html = get_as_str("https://habr.com/ru/hubs/develop/page%d/" % p)  # Develop
        # page_html = get_as_str("https://habr.com/ru/hubs/admin/page%d" % p)  # Admin
        for hub in page_html.split("media-obj media-obj_hub"):
            info = Str(hub).find_between('"https://habr.com/ru/hub', 'list-snippet__tags') 
            if "*</span>" in info:
                hub_name = info.find_between('/', '/"')
                if len(hub_name) > 0 and len(hub_name) < 32:
                    hubs.append(hub_name)
    print(hubs)

find_between функц болон Str класс нь хоёр тагны хоорондох мөрийг сонгоход би тэдгээрийг ашигласан эрт. Сэдвийн зангилаанууд нь "*" тэмдгээр тэмдэглэгдсэн тул тэдгээрийг хялбархан тодруулж болох бөгөөд та бусад ангиллын хэсгүүдийг авахын тулд харгалзах мөрүүдийн тайлбарыг арилгах боломжтой.

get_hubs функцийн гаралт нь нэлээд гайхалтай жагсаалт бөгөөд бид үүнийг толь бичиг болгон хадгалдаг. Хэмжээг нь тооцоолохын тулд би жагсаалтыг бүхэлд нь танилцуулж байна.

hubs_profile = {'infosecurity', 'programming', 'webdev', 'python', 'sys_admin', 'it-infrastructure', 'devops', 'javascript', 'open_source', 'network_technologies', 'gamedev', 'cpp', 'machine_learning', 'pm', 'hr_management', 'linux', 'analysis_design', 'ui', 'net', 'hi', 'maths', 'mobile_dev', 'productpm', 'win_dev', 'it_testing', 'dev_management', 'algorithms', 'go', 'php', 'csharp', 'nix', 'data_visualization', 'web_testing', 's_admin', 'crazydev', 'data_mining', 'bigdata', 'c', 'java', 'usability', 'instant_messaging', 'gtd', 'system_programming', 'ios_dev', 'oop', 'nginx', 'kubernetes', 'sql', '3d_graphics', 'css', 'geo', 'image_processing', 'controllers', 'game_design', 'html5', 'community_management', 'electronics', 'android_dev', 'crypto', 'netdev', 'cisconetworks', 'db_admins', 'funcprog', 'wireless', 'dwh', 'linux_dev', 'assembler', 'reactjs', 'sales', 'microservices', 'search_technologies', 'compilers', 'virtualization', 'client_side_optimization', 'distributed_systems', 'api', 'media_management', 'complete_code', 'typescript', 'postgresql', 'rust', 'agile', 'refactoring', 'parallel_programming', 'mssql', 'game_promotion', 'robo_dev', 'reverse-engineering', 'web_analytics', 'unity', 'symfony', 'build_automation', 'swift', 'raspberrypi', 'web_design', 'kotlin', 'debug', 'pay_system', 'apps_design', 'git', 'shells', 'laravel', 'mobile_testing', 'openstreetmap', 'lua', 'vs', 'yii', 'sport_programming', 'service_desk', 'itstandarts', 'nodejs', 'data_warehouse', 'ctf', 'erp', 'video', 'mobileanalytics', 'ipv6', 'virus', 'crm', 'backup', 'mesh_networking', 'cad_cam', 'patents', 'cloud_computing', 'growthhacking', 'iot_dev', 'server_side_optimization', 'latex', 'natural_language_processing', 'scala', 'unreal_engine', 'mongodb', 'delphi',  'industrial_control_system', 'r', 'fpga', 'oracle', 'arduino', 'magento', 'ruby', 'nosql', 'flutter', 'xml', 'apache', 'sveltejs', 'devmail', 'ecommerce_development', 'opendata', 'Hadoop', 'yandex_api', 'game_monetization', 'ror', 'graph_design', 'scada', 'mobile_monetization', 'sqlite', 'accessibility', 'saas', 'helpdesk', 'matlab', 'julia', 'aws', 'data_recovery', 'erlang', 'angular', 'osx_dev', 'dns', 'dart', 'vector_graphics', 'asp', 'domains', 'cvs', 'asterisk', 'iis', 'it_monetization', 'localization', 'objectivec', 'IPFS', 'jquery', 'lisp', 'arvrdev', 'powershell', 'd', 'conversion', 'animation', 'webgl', 'wordpress', 'elm', 'qt_software', 'google_api', 'groovy_grails', 'Sailfish_dev', 'Atlassian', 'desktop_environment', 'game_testing', 'mysql', 'ecm', 'cms', 'Xamarin', 'haskell', 'prototyping', 'sw', 'django', 'gradle', 'billing', 'tdd', 'openshift', 'canvas', 'map_api', 'vuejs', 'data_compression', 'tizen_dev', 'iptv', 'mono', 'labview', 'perl', 'AJAX', 'ms_access', 'gpgpu', 'infolust', 'microformats', 'facebook_api', 'vba', 'twitter_api', 'twisted', 'phalcon', 'joomla', 'action_script', 'flex', 'gtk', 'meteorjs', 'iconoskaz', 'cobol', 'cocoa', 'fortran', 'uml', 'codeigniter', 'prolog', 'mercurial', 'drupal', 'wp_dev', 'smallbasic', 'webassembly', 'cubrid', 'fido', 'bada_dev', 'cgi', 'extjs', 'zend_framework', 'typography', 'UEFI', 'geo_systems', 'vim', 'creative_commons', 'modx', 'derbyjs', 'xcode', 'greasemonkey', 'i2p', 'flash_platform', 'coffeescript', 'fsharp', 'clojure', 'puppet', 'forth', 'processing_lang', 'firebird', 'javame_dev', 'cakephp', 'google_cloud_vision_api', 'kohanaphp', 'elixirphoenix', 'eclipse', 'xslt', 'smalltalk', 'googlecloud', 'gae', 'mootools', 'emacs', 'flask', 'gwt', 'web_monetization', 'circuit-design', 'office365dev', 'haxe', 'doctrine', 'typo3', 'regex', 'solidity', 'brainfuck', 'sphinx', 'san', 'vk_api', 'ecommerce'}

Харьцуулбал, geektimes хэсгүүд илүү даруухан харагдаж байна:

hubs_gt = {'popular_science', 'history', 'soft', 'lifehacks', 'health', 'finance', 'artificial_intelligence', 'itcompanies', 'DIY', 'energy', 'transport', 'gadgets', 'social_networks', 'space', 'futurenow', 'it_bigraphy', 'antikvariat', 'games', 'hardware', 'learning_languages', 'urban', 'brain', 'internet_of_things', 'easyelectronics', 'cellular', 'physics', 'cryptocurrency', 'interviews', 'biotech', 'network_hardware', 'autogadgets', 'lasers', 'sound', 'home_automation', 'smartphones', 'statistics', 'robot', 'cpu', 'video_tech', 'Ecology', 'presentation', 'desktops', 'wearable_electronics', 'quantum', 'notebooks', 'cyberpunk', 'Peripheral', 'demoscene', 'copyright', 'astronomy', 'arvr', 'medgadgets', '3d-printers', 'Chemistry', 'storages', 'sci-fi', 'logic_games', 'office', 'tablets', 'displays', 'video_conferencing', 'videocards', 'photo', 'multicopters', 'supercomputers', 'telemedicine', 'cybersport', 'nano', 'crowdsourcing', 'infographics'}

Үлдсэн зангилаанууд нь мөн адил хадгалагдан үлджээ. Нийтлэл нь geektimes эсвэл профайлын төвд хамаарах эсэхээс үл хамааран үр дүнг буцаах функцийг бичихэд хялбар боллоо.

def is_geektimes(hubs: List) -> bool:
    return len(set(hubs) & hubs_gt) > 0

def is_geektimes_only(hubs: List) -> bool:
    return is_geektimes(hubs) is True and is_profile(hubs) is False

def is_profile(hubs: List) -> bool:
    return len(set(hubs) & hubs_profile) > 0

Үүнтэй төстэй функцийг бусад хэсгүүдэд ("хөгжил", "захиргаа" гэх мэт) хийсэн.

Боловсруулалт

Шинжилгээ хийж эхлэх цаг болжээ. Бид өгөгдлийн багцыг ачаалж, төвийн өгөгдлийг боловсруулдаг.

def to_list(s: str) -> List[str]:
    # "user:popular_science+astronomy" => [popular_science, astronomy]
    return s.split(':')[1].split('+')

def to_date(dt: datetime) -> datetime.date:
    return dt.date()

df = pd.read_csv("habr_2019.csv", sep=',', encoding='utf-8', error_bad_lines=True, quotechar='"', comment='#')
dates = pd.to_datetime(df['datetime'], format='%Y-%m-%dT%H:%MZ')
dates += datetime.timedelta(hours=3)
df['date'] = dates.map(to_date, na_action=None)
hubs = df["hubs"].map(to_list, na_action=None)
df['hubs'] = hubs
df['is_profile'] = hubs.map(is_profile, na_action=None)
df['is_geektimes'] = hubs.map(is_geektimes, na_action=None)
df['is_geektimes_only'] = hubs.map(is_geektimes_only, na_action=None)
df['is_admin'] = hubs.map(is_admin, na_action=None)
df['is_develop'] = hubs.map(is_develop, na_action=None)

Одоо бид өгөгдлийг өдрөөр нь бүлэглэж, өөр өөр төвүүдэд зориулсан нийтлэлийн тоог харуулах боломжтой.

g = df.groupby(['date'])
days_count = g.size().reset_index(name='counts')
year_days = days_count['date'].values
grouped = g.sum().reset_index()
profile_per_day_avg = grouped['is_profile'].rolling(window=20, min_periods=1).mean()
geektimes_per_day_avg = grouped['is_geektimes'].rolling(window=20, min_periods=1).mean()
geektimesonly_per_day_avg = grouped['is_geektimes_only'].rolling(window=20, min_periods=1).mean()
admin_per_day_avg = grouped['is_admin'].rolling(window=20, min_periods=1).mean()
develop_per_day_avg = grouped['is_develop'].rolling(window=20, min_periods=1).mean()

Бид Matplotlib ашиглан нийтлэгдсэн нийтлэлүүдийн тоог харуулдаг:

Хабрастистик: сайтын хамгийн их, хамгийн бага зочилсон хэсгүүдийг судлах

Би "geektimes" болон "geektimes only" гэсэн өгүүллүүдийг хүснэгтэд хуваасан, учир нь Нийтлэл нь хоёр хэсэгт нэгэн зэрэг багтаж болно (жишээлбэл, "DIY" + "микроконтроллер" + "C++"). Би сайт дээрх профайл нийтлэлүүдийг тодруулахын тулд "профайл" гэсэн тэмдэглэгээг ашигласан боловч англи хэл дээрх профайл гэсэн нэр томъёо нь бүрэн зөв биш байж магадгүй юм.

Өмнөх хэсэгт бид энэ зунаас эхлэн geektimes сэтгүүлийн нийтлэлийн төлбөрийн дүрэм өөрчлөгдсөнтэй холбоотой "geektimes эффект"-ийн талаар асуусан. Geektimes нийтлэлүүдийг тусад нь харуулъя:

df_gt = df[(df['is_geektimes_only'] == True)]
group_gt = df_gt.groupby(['date'])
days_count_gt = group_gt.size().reset_index(name='counts')
grouped = group_gt.sum().reset_index()
year_days_gt = days_count_gt['date'].values
view_gt_per_day_avg = grouped['views'].rolling(window=20, min_periods=1).mean()

Үр дүн нь сонирхолтой юм. Geektimes-ын нийтлэлүүдийн үзэлт, нийт үзсэний ойролцоо харьцаа 1:5 орчим байна. Гэхдээ нийт үзсэн тоо мэдэгдэхүйц хэлбэлзэж байсан ч "зугаа цэнгэлийн" нийтлэлүүдийг үзэх нь ойролцоогоор ижил түвшинд хэвээр байна.

Хабрастистик: сайтын хамгийн их, хамгийн бага зочилсон хэсгүүдийг судлах

Дүрмийг өөрчилсний дараа "geektimes" хэсэгт нийтлэлүүдийг үзсэн нийт тоо буурсан хэвээр байгаа боловч "нүдээр" нийт утгын 5% -иас илүүгүй байгааг та анзаарч болно.

Нийтлэл тус бүрийг үзсэн дундаж тоог харах нь сонирхолтой юм.

Хабрастистик: сайтын хамгийн их, хамгийн бага зочилсон хэсгүүдийг судлах

"Зугаа цэнгэлийн" нийтлэлүүдийн хувьд энэ нь дунджаас 40% илүү байна. Энэ нь магадгүй гайхах зүйл биш юм. Дөрөвдүгээр сарын эхээр бүтэлгүйтсэн нь надад ойлгомжгүй байна, магадгүй ийм зүйл болсон, эсвэл задлан шинжилсэн ямар нэг алдаа байж магадгүй, эсвэл geektimes-ийн зохиолчдын нэг нь амралтаараа явсан байх;).

Дашрамд дурдахад, график нь нийтлэлийг үзсэн тоогоор илүү мэдэгдэхүйц хоёр оргилыг харуулж байна - Шинэ жил, XNUMX-р сарын баяр.

Төв

Хабуудын амласан шинжилгээнд шилжье. Шилдэг 20 төвийг үзсэн тоогоор нь жагсаацгаая.

hubs_info = []
for hub_name in hubs_all:
    mask = df['hubs'].apply(lambda x: hub_name in x)
    df_hub = df[mask]

    count, views = df_hub.shape[0], df_hub['views'].sum()
    hubs_info.append((hub_name, count, views))

# Draw hubs
hubs_top = sorted(hubs_info, key=lambda v: v[2], reverse=True)[:20]
top_views = list(map(lambda x: x[2], hubs_top))
top_names = list(map(lambda x: x[0], hubs_top))

plt.rcParams["figure.figsize"] = (8, 6)
plt.bar(range(0, len(top_views)), top_views)
plt.xticks(range(0, len(top_names)), top_names, rotation=90)
plt.ticklabel_format(style='plain', axis='y')
plt.tight_layout()
plt.show()

Үр дүн:

Хабрастистик: сайтын хамгийн их, хамгийн бага зочилсон хэсгүүдийг судлах

Хачирхалтай нь, үзэл бодлын хувьд хамгийн алдартай төв нь "Мэдээллийн аюулгүй байдал" байсан бөгөөд шилдэг 5 удирдагчид "Програмчлал" болон "Түгээмэл шинжлэх ухаан" багтжээ.

Antitop нь Gtk болон Какаог эзэлдэг.

Хабрастистик: сайтын хамгийн их, хамгийн бага зочилсон хэсгүүдийг судлах

Би танд нэг нууц хэлье, дээд төвүүд бас харагдах болно энд, хэдийгээр үзсэн тоо тэнд харагдахгүй байна.

Үнэлгээ

Эцэст нь амласан үнэлгээ. Төвийн шинжилгээний өгөгдлийг ашиглан бид энэ 2019 оны хамгийн алдартай төвүүдийн хамгийн алдартай нийтлэлүүдийг харуулах боломжтой.

Мэдээллийн аюулгүй байдал

Програмчлал

Түгээмэл шинжлэх ухаан

Ажил мэргэжлийн

Мэдээллийн технологийн салбарын хууль тогтоомж

Вэб хөгжүүлэлт

GTK

Эцэст нь хэн ч гомдоохгүйн тулд би хамгийн бага зочилсон төвийн "gtk" үнэлгээг өгөх болно. Жилийн дотор хэвлэгдсэн нэг Үнэлгээний эхний эгнээнд "автоматаар" орсон нийтлэл.

дүгнэлт

Ямар ч дүгнэлт гарахгүй. Бүгдэд нь баяр хүргэе.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх