Tag Archives: математика

Як збудувати геодезичний купол?

Я простий програміст, але іноді свербить побути архітектором. Всякий ентерпрайз проектувати ще не пускають, але тут випала нагода зпроектувати проект іграшкової хатинки для донечки. Тому що після покупки меблів в порожню квартиру в нас все ще залишається вільна кімната і в ній куууупа картону.

Картон в меблевій майстерні

Я погуглив які можна робити хатинки і знайшов таке на instructables. Але там виміри подані все ще в імперській системі і я вирішив перерахувати. І взагалі зробити проект правильною водоспадною методологією – поетапно.

3d модель

Перший етап – змоделювати все на комп’ютері.

  1. Запускаємо Blender, вибираємо куб який там за замовчуванням, натискаємо Delete.
  2. Shift+A (додати об’єкт) -> Icosphere, Subdivision: 2, Size: 1.0 location: (0.0, 0.0, 0.0).
  3. Переключаємось на вид з переду, тиснемо Tab і переходимо в Edit mode.
  4. Тиснемо правою кнопкою на якусь вершину аби вибрати лише її. Тиснемо b, аби вибрати вершини рамкою, і вибираємо ті що нижче 0 по осі Z.
  5. Натискаємо Delete і видалаємо половину вершин знизу.

Має вийти щось таке:

Купол в Blender

Це можна експортувати в розгортку для паперової моделі, якщо зробити наступне:

  1. Зайти в меню File -> User preferences, вкладка Add-ons, категорія Import-Export.
  2. Поставити галочку біля Export Paper Model, і натиснути “Save User Settings”.
  3. File -> Export -> Paper Model експортує модель в файл pdf (хоча пише що svg).

Отримаємо таке:

Розгортка

Для деяких розрахунків більшої моделі ще корисно експортувати в .obj файл.

Паперова модель

В паперовій моделі головне акуратно вирізати розгортку по чорних суцільних лініях, зігнути по пунктирних і склеїти сіренькі краї.

Склеєна паперова модель

Паперова модель дає краще уявлення про те скільки трикутників доведеться вирізати, але як різати картон все ще не ясно. Якщо я хочу купол радіусом 1 метр, то якого розміру мають бути трикутники?

Вони здаються правильними, але насправді лише здаються, тому що з правильних трикутників вийде хіба що площина або дельтаедр. Щоб обчислити розміри трикутників, можна використати obj файл.

Розміри

Наступний скрипт якщо йому згодувати наш obj файл зробить дві речі:

import sys
import math
from collections import Counter

# Distance between two vectors (iterables) rounded to 3 digits after comma
def distance(A, B):
    return round(math.sqrt(sum((a - b)**2 for a, b in zip(A,B))), 3)

def obj_fline_to_edges(line, vertices):
    # get indexes of vertices
    face = [int(e.split('/')[0]) - 1 for e in line[2:].split(' ')]

    # compute edge length's
    edges = sorted([
        distance(vertices[face[0]], vertices[face[1]]),
        distance(vertices[face[2]], vertices[face[1]]),
        distance(vertices[face[2]], vertices[face[0]]),
    ])
    return tuple(edges)

def main(filename):
    vertices = []
    faces = []
    face_lines = []
    with open(filename) as f:
        for line in f:
            if line.startswith('v '): # add line to list of vertices
                coords = [float(e) for e in line[2:].split(' ')]
                vertices.append(coords)

            if line.startswith('f '): # it's a face
                face_lines.append(line.strip())
                edges = obj_fline_to_edges(line, vertices)
                faces.append(edges)

    stats = Counter(faces).most_common()
    for i, (edges, count) in enumerate(stats, 1):
        print(f'{i}) {edges} - {count}')

    materials = [
        'redMtl',
        'blueMtl',
    ]
    for i, (edges_type, count) in enumerate(stats):
        print("usemtl", materials[i])
        for line in face_lines:
            edges = obj_fline_to_edges(line, vertices)
            if edges == edges_type:
                print(line)

if __name__ == "__main__":
    main(sys.argv[1])

Напише статистику по трикутнихах, і скаже що в нас їх є два види, 30 рівнобедрених і 10 рівносторонніх. Розміри в міліметрах, якщо купол метровий:
1) (0.547, 0.547, 0.618) – 30
2) (0.618, 0.618, 0.618) – 10

А крім того, додасть матеріали, які в позначать в моделі трикутники різного типу різними кольорами. Кожен рядок що починається на f, в об’єктному файлі треба замінити на той який виводиться нашим скриптом. (Разом з usemtl, вони позначають кольори). В файл *.mtl який Blender експортує поряд з об’єктним, треба додати наприклад такі матеріали:

newmtl redMtl
Ns 18
Ka 0.000000 0.000000 0.000000
Kd 1.0 0.5 0.5
Ks 0.8 0.8 0.8
d 1
illum 2

newmtl blueMtl
Ns 1
Ka 0.000000 0.000000 0.000000
Kd 0.5 0.5 1.0
Ks 0.8 0.8 0.8
d 1
illum 2

Kd означає колір дифузного відбиття за Фонгом.

Тепер, якщо ми експортуємо те що відредагували в текстовому редакторі назад в Blender – отримаємо таке:

Бачимо що рівнобедрені трикутники треба з’єднати по 5 штук коротшими сторонами в п’ятикутні піраміди, тоді до країв піраміди причепити ще 5 рівносторонніх трикутників, тоді поміж кожні два трикутники вліпити ще по 5 п’ятикутних пірамід і між ними вліпити решту рівносторонніх трикутників. Або іншим способом. Якщо тепер експортувати розгортку, і при експорті вибрати в налаштуваннях документа “Textures: From materials”, то розгортка теж буде кольоровою:

Кольорова розгортка геокупола

Картонна модель

Тепер, головне аби картону вистачило. Виявилось що вирізати трикутник зі стороною майже 62 см я не можу, бо той картон що я маю вужчий. (Насправді головне висота, але я хотів вмістити більше трикутників, тому вирішив що довша сторона буде 38 см, помножив всі розміри на 380/618, і загалом вийшло таке:

1) (0.336, 0.336, 0.380) – 30
2) (0.380, 0.380, 0.380) – 10

І добре, бо діаметр оригінального купола – 2 метри, того що в мене 1.23м, і він набагато краще вміщується в кімнаті. Для того щоб під купол було легше заходити, я зробив лише 9 рівносторонніх трикутників, таким чином що один в основі відсутній, і поставив купол на стіну висотою 50 см з 9 прямокутних секцій шириною по 38 см. Загалом зі стіною висота в центрі складає 1.11м.

Найбільша технічна складність – як побудувати трикутник без велетенського циркуля. Але виявляється циркуль легко робиться за допомогою вимірювальної рулетки, смужки картону і викрутки. Пробиваємо в смужці викруткою дірку, тоді на відстанях які нам потрібно ще дірки. Фіксуємо центр кола викруткою, і вставляючи ручку в дірку на потрібній відстані малюємо коло потрібного радіусу.

Краї для склеювання клеєм я вирішив не креслити аби зекономити картон і поклався на скотч.

Картонний циркуль і креслення зроблені ним

Далі можна не морочитись і використати перші трикутники як шаблони для креслення решти. Далі процес тривіальний.

Натисніть, щоби переглянути слайдшоу.

Враховуючи те що трикутники я вирізав криво, вони прилягають не щільно і в хатинку потрапляє світло через те що скотч прозорий.

Чи сподобалась дитині хатинка? Ніби так, вона туди пару раз лазила грати “ку-ку”, але здається не настільки як мені. 🙂

Тому що нові іграшки – то тимчасове задоволення, а вміння робити 3d штуки без 3d принтера – то назавжди. 😉

Рукотворна штучна нейронна мережа

Коли приходить зима часом хочеться щоб домашня машина для перетворення електричної енергії в теплову (так директор ФТЛ називає комп’ютери) працювала на всіх парах. Але крім того хочеться аби вона робила щось цікавіше за обчислення хеш функцій якогось блоку криптовалюти. Часом залишаю комп’ютер на ніч попрацювати над вікіпедією, але це задача скоріше зав’язана на швидкість мережі і диска, тому процесор майже не завантажує.

Публікація про те що прості штучні нейронні мережі не такі вже й складні. Алгоритм їх навчання я ще не ґрокнув але навчився складати їх вручну задаючи топологію і всі коефіцієнти, тому така нібито тавтологічна назва. Насправді нейронні мережі не складаються вручну, а самонавчаються різними методами, бо для типових задач штучного інтелекту вони занадто великі аби це було можливо. Але все одно вони залишаються просто купкою матриць, тільки великих.

Проблема з нейронними мережами в тому, що аби з ними почати робити щось цікаве треба дуже багато прикладів по яких її можна навчати. І на цьому місці я згадав що ще в університеті з Андрієм ми пробували навчити штучну нейронну мережу запам’ятовувати зображення, як функцію з (x, y) -> (r, g, b). Де на вході було два нейрони – координати пікселя в зображенні, а на виході три, збуджені від 0 до 1 які позначають компоненти кольору пікселя. Прикладів по яких можна навчатись купа – просто давай мережі координати кожного пікселя, і хай пробує вгадати колір. І коли ми пробували навчити її запам’ятати зображення якогось символа, на виході отримували щось на зразок цього:

Результат запам’ятовування нейронною мережею картинки

На заняттях зі штучного інтелекту нам замість того щоб пояснити що там могло відбуватись сказали вивчити Lisp або Prolog. І напевне не змогли б пояснити, бо аби це зрозуміти треба добре розуміти матаналіз. Але не переживайте, в цій статті я вас навчу будувати нейронні мережі без матаналізу. Вони не зможуть вчитись, але будуть зразу навчені. Для цього треба лише розуміти трохи дискретки і лінійної алгебри.

Клод Шеннон окрім всього іншого в 1938 році зрозумів що за допомогою простих реле можна реалізувати як завгодно складну функцію булевої алгебри. Зараз ми спробуємо побачити що будь-яку функцію булевої алгебри можна реалізувати комбінацією простих нейронів. Є формальне доведення, що будь-яку неперервну функцію багатьох змінних нейронна мережа з одним прихованим шаром апроксимує з довільною точністю

Blausen 0657 MultipolarNeuron

Нейрон – це функція вигляду f(x_1, x_2, ..., x_n) = \phi{(\sum_{i=1}^{n} x_iw_i + b)}, де \phi{(x)}передавальна функція (функція активації) (що небудь що для маленьких величин дає приблизно 0 чи -1, а для великих – 1), w_i – це вага кожного входу, а b – поріг (bias). Тобто це така штука яка має багато входів, сигнал на кожному вході множить на щось (синаптичу силу?), тоді додає їх всіх разом, застосовує функцію активації до суми щоб визначити наскільки збудитись, і передає своє збудження на аксон. До його аксона можуть бути приєднані входи купи інших нейронів.

Що може нейрон? Ну, скажімо так, небагато. Він просто обчислює зважену суму своїх входів і перевіряє чи вона більша за якийсь поріг. Геометрично це означає що він задає гіперплощину яка ділить гіперпростір входів на дві половини. Для випадку нейрона з двома входами – це пряма що ділить простір на дві половини. Наприклад, якщо w_1 = 1, w_2 = 1, b = -1.5, то нейрон, якщо йому на вхід дати координати на зображенні, а функція активації – функція Гевісайда (f(x) = x > 0)активується якщо x + y - 1.5 > 0. Тобто, якось так:

Зелений – 1, синій – 0

Поки що нічого цікавого. Але, якщо прийняти за 0 – False, а 1 – True, то цей нейрон обчислює логічну кон’юнкцію (активується якщо активовані обидва входи). Чи є нейрон для диз’юнкції? Так, якщо w_1 = 1, w_2 = 1, b = -0.5, то для графіка отримуємо нерівність x + y - 0.5 > 0 і такий нейрон активуватиметься якщо хоча б один на вході активований.

Ось код для matplotlib, який за функцією від двох змінних малює зображення, якщо ви хочете відтворити мої результати:

import matplotlib.pyplot as plt

def draw_image(f):
    """Show image generated by function."""
    image = []
    y = 1
    delta = 0.005
    while y > 0:
        x = 0
        row = []
        while x < 1:
            row.append(f(x, y))
            x += delta
        image.append(row)
        y -= delta

    plt.imshow(image, extent=[0, 1, 0, 1], cmap='winter')
    plt.show()

Чи зможемо ми створити нейрон який буде обчислювати наприклад функцію xor? Відповідь – ні, бо нейрон задає гіперплощину (для 2d – пряму), а графік функції XOR виглядає якось так:

Графік “функції” XOR

Але якщо з’єднати три нейрони? Ми знаємо що виключне або, це коли або а або б, але не а і б зразу, що записується так: x \oplus y = (x \lor y) \lor \neg (x \land y). Цій формулі відповідатиме така нейронна мережа:

З’єднання нейронів для XOR

Сигнали йдуть зліва направо, над зв’язками написані ваги зв’язків, над нейронами – пороги. Можете на листочку перевірити що це дійсно XOR. Нейрон з порогом -0.5 активується коли активні або x або y, а нейрон з порогом +1.5 – коли не обидва зразу. Вихідний нейрон активується коли активуються обидва проміжні.

Ще варто зауважити що наша мережа відповідає популярній топології що має назву “багатошаровий персептрон”. В ній вхідні сигнали передаються на вхід масиву нейронів, тоді активації цього масиву нейронів передаються на вхід наступному шару, і так поки не закінчаться шари. Результат роботи останнього шару – це вихід мережі.

А тепер трохи коду для того щоб полегшити нам побудову складніших мереж:

import math  # без паніки, буде використано лише раз, і то не завжди
import numpy as np  # щоб спростити роботу з векторами і матрицями (звідки вони тут буде пояснено нижче)

def sigmoid(x):
    """Відображає дійсні числа в діапазон 0-1"""
    return 1 / (1 + math.exp(-x))

def heaviside_step_function(x):
    """Просто поріг. True в Python == 1, False == 0"""
    return x > 0


class NeuralNet:
    """Клас що задає топологію і симулює нейронну мережу"""

    # Вибираємо функцію активації.
    # Декоратор np.vectorize - дозволяє застосовувати функцію поелементно до векторів
    # logistic_function = np.vectorize(sigmoid)
    logistic_function = np.vectorize(heaviside_step_function)

    def __init__(self):
        """Початково мережа порожня"""
        self.weights = []
        self.biases = []

    def add_layer(self, *neurons):
        """Додати новий шар нейронів в мережу. Кожен нейрон це список чисел:

        neuron[:-1] - ваги входів
        neuron[-1] - поріг
        """
        weights = []
        biases = []
        assert neurons, 'В шарі очікується хоч один нейрон'
        if self.weights: # якщо в нас вже є шари - перевірити чи новий шар стикується 
            current_output = self.weights[-1].shape[0] # поточна кількість виходів мережі
            assert len(neurons[0]) - 1 == current_output, (
                f'поточна топологія мережі має {current_output} виходів'
                f'але ви намагаєтесь додати шар що має нейрони з {len(neurons[0] - 1)} входів'
            ) # Взагалі то кожен нейрон шару має мати однакову кількість входів,
            # але вистачить перевірок, бо код стане довгим.

        for neuron in neurons: # розбиваємо ваги окремо, пороги окремо
            weights.append(neuron[:-1])
            biases.append(neuron[-1])

        self.weights.append(np.array(weights))
        self.biases.append(np.array(biases))

    def __call__(self, *args):
        """ Мережу можна викликати як функцію, і вона прожене вхідні дані
        через себе і дасть вихід першого нейрона з останнього шару. 
        Поки що картинки будуть мати один канал кольору. 
        """
        output = np.array(args) # ми по черзі застосуємо до цього вектора кожен шар нейронів
        for weights, biases in zip(self.weights, self.biases): # попарно  беремо ваги і пороги
            output = self.logistic_function(weights @ output + biases) # ну власне виконуємо обчислення в нейронах
        return output[0]

Трохи більше ніж 50 рядків коду, і вже нейронна мережа? Тааа, просто вона ще не вміє вчитися. Взагалі то більшість логіки зашита в рядку logistic_function(weights @ output + biases) – решта просто допоміжна, тому можна напевне було б і в 10 вкластися, за рахунок зручності роботи з нею.

Що це за собачка? Це множення матриці на вектор, що дає вектор скалярних добутків кожного рядка матриці на той вектор. Тобто обчисленя зразу всіх сум нейронів. Далі ми додаємо вектор порогів (що просто сумує всі елементи), тобто додає пороги зразу у всіх нейронах. Оце й уся лінійна алгебра. А потім застосовуємо логістичну функцію, яка в нас була logistic_function.

Тепер подивимось як її використовувати. Наприклад для того щоб побудувати мережу яка обчислює XOR (топологію якої я намалював вище), і зобразити результат на картинці, ми пишемо таке:

    xor_net = NeuralNet()
    xor_net.add_layer(
        [1, 1, -0.5], # кожен рядок описує нейрон. Наприклад:
        [-1, -1, 1.5] -x - y + 1.5 > 0 (якщо функція активації - функція Гевісайда)
    )
    xor_net.add_layer(
        [1, 1, -1.5]  # наш давній знайомий нейрон AND
    )
    draw_image(xor_net)

Ну добре, ми бачили прямі лінії, а чи може ця мережа побудувати якусь фігуру?

Я вирішив спробувати таку:

Зображення глайдера

Як таку картинку побудувати з нейронів? Можемо її розбити на три фігури – квадрат вгорі, квадрат посередині справа, і прямокутник внизу, побудувати мережі які активуються якщо координати пікселя на вході знаходяться в фігурі, і з’єднати їх нейроном що активується, якщо активується хоч одна з них.

Найпростіше нижню, для цього досить перевірити що y < 1/3. Для того що посередині справа треба щоб y 2/3. Для тої що вгорі треба перевірити три краї. Таким чином матимемо мережу з трьома шарами. Перший визначатиме з якого боку якоїсь прямої ми знаходимось, другий визначатиме чи ми в середині опуклої області, третій об’єднуватиме окремі фрагменти в одну картинку:

    hacker_net = NeuralNet()
    hacker_net.add_layer(
        [ 0.0, -3.0,  1.0], # y < 1/3
        [ 0.0, -3.0,  2.0], # y < 2/3
        [ 0.0,  3.0, -2.0], # y > 2/3
        [ 3.0,  0.0, -2.0], # x > 2/3
        [-3.0,  0.0,  2.0], # x < 2/3
        [ 3.0,  0.0, -1.0], # x > 1/3
    )
    hacker_net.add_layer(
        [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, -2.5], # y>2/3 && x<2/3 && x>1/3
        [0.0, 1.0, 0.0, 1.0, 0.0, 0.0, -1.5], # y<2/3 && x>2/3
        [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5], # y<1/3
    )
    hacker_net.add_layer(
        [1.0, 1.0, 1.0, -0.5], # хоч щось в попередньому шарі біля 1
    )
   
    draw_image(hacker_net)

Класно правда? Єдина відмінність нашої нейронної мережі від інших – що в інших переважно використовують як функцію активації сигмоїду. Тому що порогова функція не піддається оптимізації методом градієнтного спуску, бо не диференційовна в тому місці де змінюється. А сигмоїду дуже просто диференціювати, якщо вміти диференціювати. 🙂

Що якщо ми нашу мережу перемкнемо на сигмоїду? Вийде таке:

Зображення глайдера з сигмоїдою

Хм, наша нейронна мережа тепер має якесь дуже розмите уявлення про зображення яке вона “вивчила”. Трохи нагадує університетські спроби.

Чого так? Давайте глянемо на графік сигмоїди:

S(x) = \frac{1}{1 + e^{-x}}

Бачимо що для наших сум, значення яких коливаються біля нуля, вона дає значення не біля нуля і одиниці, а десь біля 0.4, 0.6. А за пару шарів таке усереднення накопичується. Щоб це виправити, треба великі значення ваг і порогів, щоб загальна сума що передається в функцію активації була велика. Правда в університеті ми використовували якусь бібліотеку, а вони уникають великих значень ваг, бо вони спричинюють деякі негативні побічні ефекти такі як перенавчання (гарні оцінки на навчальних даних, погані на тестових), і застрягання навчання в місцях де похідна від сигмоїди ~ 1, тому градієнт дуже маленький. Тому напевне таке розмите зображення виходило.

Окрім того, ми можемо додати деякий коефіцієнт в саму сигмоїду:

S(x) = \frac{1}{1 + e^{-10x}}

І тоді зображення вийде значно кращим:

Глайдер з в 10 разів різкішою сигмоїдою

Якщо хочете вчитись далі – є три гарні ресурси:

Я правда перед тим як пробувати осилити два останні, ще трохи намагаюсь гризти граніт матаналізу, бо багато вже з голови вивітрилось, а багато чого там і не було. 🙂

Побудова “скриньок з вусами” львівських квартир що здаються на сьогодні

Я ще минулого року помітив що в питаннях про Python на StackOverflow обговорюють якісь панди. Це, як виявилось обгортка навколо matplotlib, numpy і подібних гарних речей. А ще, лазячи по своїх документах в Google знайшов скачану вже позаминулого року стіну групи пошуку нерухомості вконтакті. І так співпало що я і мій колега-аналітик зараз шукаємо квартиру у Львові. Я йому показав цей файл, і він загорівся бажанням проаналізувати ще якийсь сайт оголошень.

При всій повазі до lun.ua, але тут я прорекламую dom.ria.com. Передовсім, там є українська версія. А ще, можливість скачати результати пошуку як електронну таблицю, хоч і в xls форматі, і лише одну сторінку.

В python читати xls вміє бібліотека xlrd, тому треба доставити ще й її. Pandas взагалі має багато необов’язкових залежностей:

sudo pip3.5 install jupyter pandas xlrd matplotlib
jupyter notebook # дуже модний графічний інтерпретатор

Якщо все поставити як вище і запустити “jupyter”, то можна робити обчислення в отакому документі: https://github.com/bunyk/mypandas/blob/master/dom.ria/dom.ria.ipynb

І можна побудувати графік скринька з вусами:


От, недаремно я деякі лекції з АнДану все таки не проспав! Хоча, який висновок робити з цього графіка – не знаю. Знаю лише що половина квартир потрапляють всередину прямокутника.

А ось гістограми по цінах для однокімнатних і двокімнатних:

Однокімнатні

Однокімнатні

Двокімнатні

Двокімнатні

Який з цих гістограм робити висновок окрім того що квартир дешевших за 2000 грн (окрім викидів) не буває (а я зараз живу за 700 грн/міс, хоча це пів квартири) – теж не знаю. Може ви самі якийсь зробите. І так, до речі, я шукаю одно чи двокімнатну квартиру десь в другому або третьому квартилі цін в районі вулиці Липинського.


Filed under: Інструменти, Кодерство, Павутина Tagged: графіка, математика, Python

Теорія взаємодії процесів (насправді про IT-Arena)

Я не дуже хотів йти на Львів ІТ арену, бо то настільки понтово що задорого. Крім того на вузькоспеціалізованих конференціях на зразок PyCon я мало що розумію, навіть якщо сам доповідаю. 🙂 Хоча, знаєте, ото щойно передивився одну доповідь – і ніби все зрозумів (а що ще краще, виявляється що викладені там ідеї я зараз використовую в Angular, хоч і забув про них). Крім того, нащо йти на платну конференцію, якщо ти навіть не встигаєш читати всі блоги і дивитись всі безкоштовні відео доповідей з інших конференцій в інтернеті?

Але я пішов, і не пожалів. Познайомився з Естер Дайсон. Вона великий фанат здорового способу життя, і інвестор в наш проект.

Пішов на доповідь про мікросервіси оцього чоловіка. Там дізнався що всі системи які містять багато взаємодіючих компонентів можна описувати наприклад пі-численням. Але так як книжки з пі-числення страшенно дорогі, ось вам безкоштовна про математичну теорію названу “Взаємодія послідовних процесів”, і написана не аби-ким, а Сером Чарлзом Ентоні Річардом Гоаром. Тепер залишилось знайти час прочитати.

А ще поміж іншим дізнався про те що програмне забезпечення це лайно (точніше завжди знав), але існує стрібна куля. Називається LangSec, коли ми вхідні параметри описуємо якоюсь формальною мовою. Чим це відрізняється від Логіки Хоара і наприклад статичної типізації з алгебраїчними типами даних – ще треба подумати.

А ще зустрів хлопців з Quintagroup, вони зразу такі “О, це ти той пітонщик з SoftServe що пише на Zope”. Я такий – той, але вже не пітонщик і не з SoftServe. 🙂 Зараз вони багато працюють над проектом Prozorro, і шукають нових людей. Тому якщо знаєте Pyramid (чи який там фреймворк у https://github.com/openprocurement), шукаєте роботу – напишіть їм.


Filed under: Кодерство, Нещоденник Tagged: математика, робота, Python

Шизофазогенератор Маркова

Написав скрипт який на даний момент. Письменник – звертайтесь. Залишилась математика, і що я знаю дещо про керування рекламними кампаніями в Google календар з нагадуванням по SMS, бо думав, що його швидкість зміниться так: Тепер ще один сервіс не буде ніяких порад про побудову сюжету, що ортогональна проекція легко стає ізометричною після здійснення повороту на 45° до чого веду.

Можна подумати що я вже зовсім втратив здатність зрозуміло висловлюватись. Але ні. Це я вибрав досить вдалий абзац з тексту створеного скриптом, який загрібає корпус текстів з певного блогу, робить лексичний аналіз, підраховує частоту послідовностей токенів, і записує їх в базу. Далі, за цими частотами можна порахувати ймовірності з якими після даних конкретних токенів ідуть інші можливі токени. І випадковим чином з поправкою на розподіл імовірностей вибирається один з них.

Написав таку штуку, бо давно нічого не писав (в блог, а не коду), і мені хочеться вияснити можливості MongoDB. Крім того Стенфорд все відкладає свій курс NLP, а в мене на роботі в цьому напрямку вже проходять дослідження. І біля мене навіть сидить один кандитат наук.

А також мені можливо скоро доведеться здавати диплом. А його ще треба написати. Одні студенти з MIT були настільки ліниві, що замість того аби писати дипломні роботи написали програму яка пише дипломні роботи замість них. І непогано пише. Моя програмка теж непогано пише, хоча використовує набагато простішу технологію. Ось згенерований текст в не в моєму стилі:

Ні, я ж ще не знаєш? Хоча відсутність дров передбачити було неважко… Нет, с арифметикой у них, увы, атрофирована полностью. Ну як не згадати його кільця! Приблизно схожий на Юпітер – засмієте. Якщо ви колись побуваєте на ньому, то система вивалюється з грізним повідомленням “опускатись нижче по рівню” У Форті дуже мало внутрішніх перевірок на коректність роботи програми та коректність дій користувача, а я в шинку промок. Зате тепер я розумію конретику, яка в майбутньому навчитись самотужки обмінюватись інформацією між своїми копіями, схожими по роботі програмами та зовсім різними по призначенню. Також потрібно розуміти поняття реальної швидкості, тобто власне довжини вектору руху, неспроектованого.

Теорія відносності каже (якщо чесно, я сам собі так сказав; треба вчити, бо ліньки було розбирати всі варіанти, коли є бабло, то здесь ситуация совершенно иная. Эти части текста, для мене цей недолік несуттєвий =)). Завдяки окулярам ліве око бачить червоний колір однієї довжини хвилі, а не на моїх =) Угадайте, хто при читанні моїх завдань на життя згадав Вікіпедію, ТеХ, інтели, мускли, вольфрамальфа та будь-що інше, але ними користуються тільки ТеХніки ))) F# він уже присутній для користування. Давайте спробуємо уявити собі наскільки потужна обчислювальна система у загальному значенні. Більшість з них дуже маленька і закінчується об”єктами зірками і зірки знаходятся в протифазі. У Земного барицентру дві орбіти. Оскільки окремі моделі можуть зв’язуватись між собою і слідувати певній логіці, обо’єкт типу IEnumerable. Власне задля зручності роботи і було насправді, доки у нас є файлик з кодом). Рекомендую подивитись Пайтон-вставки в асемблерний код.

Вгадайте хто це міг написати?

Правда проблема з блогами які мені цікаво читати – їх текст містить багато комп’ютерного коду. А так як шизофазогенератор внаслідок вродженого порушення психіки не може генерувати хоч трохи структурований код, трапляються такі фрагменти що порівняно з ними всі попередні тексти – поезія:

————————– ;– MAIN ——- ;————————— ;– Макроси FASM-у, для мене це ще не переведено на Python3. import turtle def plotAxes(screen): turtle.reset() turtle.up() turtle.speed(0) turtle.hideturtle() turtle.down() turtle.goto(0,0) turtle.goto(0, 1) ^^^ table.[index] let crcResult = ~~~(Array.fold byteCrc 0xffffffffu (Encoding.Default.GetBytes(s))).

З чимось дівчачо-філологічним виходить набагато краще:

Ні, не чула, що вона заробила свій перший мільйон, треба самому прожити життя, отруєний грибком заздрощів. Рік тягнувся. Не люблю, але дозволь людям, що інші виросли, я не питиму. Тебе морально згвалтували настільки, що всередині”, – чистий бланк, і друге! Проте, коли такі, яких я викрила. Всяке і різне, як коханого чоловіка, інколи така правда вилазить боком. Маленькі і недосвідчені, будуємо собі вимріяний світ, не витираючи ніг. Іншими словами, графоманство. І добре, якби завтра мені витягнулись власне ті питання, які не просто знати. Його треба пропустити крізь себе, залившись алкоголем. По колу. Але я не забила на університет, сиджу вдома та плачу. Плачу, та ж. Гадаю, що надихають на добро тебе. – Чудово. – Про що і до сьогодні люди шукають добре? Зрештою, важко налаштуватись на позитив, коли одного разу, одягну школадного носа. Скажете, доля не любить солодкого?

Зразу видно що текст про почуття і про почуття і про емоції, одним словом потік свідомості. Точнісінько як оригінал…

Я б ще розказав про те яка MongoDB лапочка, розширивши тему попередньої публікації, а також про те як генерувати чистий (ну майже) корпус тексту з певного сайту за допомогою httplib2, BeautifulSoup, soupselect та регулярних виразів. Але я вже стільки награвся своїм шизофазогенератором, що боюсь в неділю через недосипання не зможу розстріляти своїх тім-лідів шариками з фарбою. А хочеться. Тому решту читайте в наступних серіях… Або самі код розбирайте.

А поки що можете почитати афоризми в стилі Канта. Теж не далекі від оригіналу. :)


Filed under: Кодерство, Павутина Tagged: математика