Форум русскоязычного сообщества Ubuntu


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: Неслучайная случайность, или рандомная последовательность в питоне.  (Прочитано 2537 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Phlya

  • Автор темы
  • Старожил
  • *
  • Сообщений: 2219
  • Фля, Цыганский барон, Винни Пух
    • Просмотр профиля
Делаю рандомную последовательность в питоне:
size = 369930
nuc = 'ATGC'
def rand_seq(nuc, size):
    seq = ''.join([random.choice(nuc) for N in xrange(size)])
    return seq
(Не спрашивайте, почему такое число, это неважно)
После этого анализирую встречаемость двухбуквенных слов типа AG, AC, TG, TT и так далее (всего 16 вариантов). Казалось бы, с точностью до случайного маленького отклонения, все должны встречаться с равной частотой. Однако частота повторов AA, TT, CC и GG заметно ниже (примерно 18500 против 23000). В чем фишка?

Где рандом у меня не совсем рандомный? Или так и должно быть в теории, а я не понимаю? Или все хорошо, а анализирую я неправильно (если есть такое подозрение, покажу как)?
« Последнее редактирование: 26 Января 2013, 00:03:37 от Phlya »
Ubuntu 14.04 (Unity), MSI GE40

Оффлайн Señor_Gaga

  • Забанен
  • Активист
  • *
  • Сообщений: 878
  • Ubuntu 12.04LTS & Linux Mint 13LTS "Maya"
    • Просмотр профиля
size = 369930
nuc = 'ATGC'
def rand_seq(nuc, size):
    seq = ''.join([random.choice(nuc) for N in xrange(size)])
    return seq

Возможно слишком короткая nuc - всего 4, генератор случайных
чисел то программный, не думаю, что но дает идеальное равномерное распределение.
Попробуйте так:
nuc = 'ATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGC'

Отпишитесь если не лень. Вопрос интересный.

Оффлайн Phlya

  • Автор темы
  • Старожил
  • *
  • Сообщений: 2219
  • Фля, Цыганский барон, Винни Пух
    • Просмотр профиля
Ничего не изменилось(
Ubuntu 14.04 (Unity), MSI GE40

toto

  • Гость
Если у тебя 16 вариантов, длина выборки должна быть кратна 16, и количество выборок тоже кратно 16, иначе чего-то будет меньше/больше.

Оффлайн Phlya

  • Автор темы
  • Старожил
  • *
  • Сообщений: 2219
  • Фля, Цыганский барон, Винни Пух
    • Просмотр профиля
Не настолько же. От этого возникнет отличие на единицы.

Провел эксперимент: перемешал эту последовательность и получил то же самое. Меня это напрягает...

Пользователь решил продолжить мысль 26 Января 2013, 01:57:28:
Если у тебя 16 вариантов, длина выборки должна быть кратна 16, и количество выборок тоже кратно 16, иначе чего-то будет меньше/больше.
Чисто для Вас, сделал для 160000, ничего не поменялось.
Ubuntu 14.04 (Unity), MSI GE40

Оффлайн shumtest

  • Активист
  • *
  • Сообщений: 731
  • Это вам просто кажется...
    • Просмотр профиля
    • Блог Шумомера
Последовательность событий АА имеет меньшую вероятность чем последовательность АТ
Почему - изучайте теорию вероятностей.

А распределение генератор дает вполне ровное
import random

def rand_seq(nuc, size):
    return ''.join(random.choice(nuc) for N in xrange(size))

str = rand_seq('ATGC',369930)
print str.count('A')
print str.count('T')

Цитировать
92523
92318

Оффлайн Phlya

  • Автор темы
  • Старожил
  • *
  • Сообщений: 2219
  • Фля, Цыганский барон, Винни Пух
    • Просмотр профиля
На всякий случай, если взять длину слова в 1, то есть посчитать отдельные буквы, то их число одинаковое (это и по той картинке можно понять, но не так очевидно).

Пользователь решил продолжить мысль 26 Января 2013, 02:01:06:
Последовательность событий АА имеет меньшую вероятность чем последовательность АТ
Я не понимаю, почему, если события выбора первой и второй буквы независимые (как и есть в этом случае). Вероятность А - 1/4. Вероятность второй А - 1/4, второй Т - 1/4.

Пользователь решил продолжить мысль 26 Января 2013, 02:02:59:
И разве перемешивание не должно убирать это, если причина в выборе?
« Последнее редактирование: 26 Января 2013, 02:02:59 от Phlya »
Ubuntu 14.04 (Unity), MSI GE40

Оффлайн shumtest

  • Активист
  • *
  • Сообщений: 731
  • Это вам просто кажется...
    • Просмотр профиля
    • Блог Шумомера
В теории вероятностей много таких моментов, которые, на первый взгляд, противоречат логике. Если хотите понять - начните с разбора парадокса мальчика и девочки.

Оффлайн Phlya

  • Автор темы
  • Старожил
  • *
  • Сообщений: 2219
  • Фля, Цыганский барон, Винни Пух
    • Просмотр профиля
Это все ясно, но где ошибка в моих рассуждениях?
Ubuntu 14.04 (Unity), MSI GE40

Оффлайн Señor_Gaga

  • Забанен
  • Активист
  • *
  • Сообщений: 878
  • Ubuntu 12.04LTS & Linux Mint 13LTS "Maya"
    • Просмотр профиля
... а анализирую я неправильно (если есть такое подозрение, покажу как)?

Неплохо бы посмотреть как анализируете полученную последовательность.

Оффлайн Phlya

  • Автор темы
  • Старожил
  • *
  • Сообщений: 2219
  • Фля, Цыганский барон, Винни Пух
    • Просмотр профиля
Ок. Вся программа:

Код: (Python) [Выделить]
import random
from scipy.stats import chisquare

size = 160000
nuc = 'ATGC'

def rand_seq(nuc, size):
    seq = ''.join([random.choice(nuc) for N in xrange(size)])
    return seq

def combine(length):
    strings = [N for N in 'ATGC']
    L=1
    while L < length:
        strings = [string+N for N in 'ATGC' for string in strings] #С каждым циклом удлиняем на одну букву, создавая четыре слова из одного
        L= L+1
    return strings
   
def words(seq, word_length):
    words = [N*word_length for N in 'ATGC'] #Учесть все одинаковые, которые иначе никак не создадутся
    for word in combine(word_length):
        word = ''.join(map(str, word))
        words.append(word) #Добавляем слово
        words.append(word[::-1]) #Добавляем перевернутое слово, чтобы все учесть
    return words

def get_word_dict(seq):
    word_dict = {}
    for length in range(1, 6):
        for word in words(seq, length):
            word_dict[word] = seq.count(word) #Сам подсчет
    return word_dict
#Собственно, начинаем использовать вышенаписанные функции
seq = rand_seq(nuc, size)
word_dict = get_word_dict(seq)
for key in sorted(word_dict.iterkeys()):
    word_dict[key] = (len(key), word_dict[key]) #В значение ключа записываем его длину для удобства, и рассчитанное число.
length = 2

numbers = []
labels = []
for key in sorted(word_dict.iterkeys()):
    if len(key) == length:
        numbers.append(word_dict[key][1])
        labels.append(key)
named = zip(numbers, labels)
named = sorted(named)
chisq = chisquare(numbers)
print 'P-value for uniform ditribution', chisq[1]
pylab.bar([i for i in range(len(numbers))], numbers)
pylab.xticks([i+0.4 for i in range(len(numbers))], labels, rotation='vertical')
pylab.show()

Идея в том, чтобы сгенерировать все варианты слов из этих 4х букв определенной длины, потом посчитать, сколько каждое из них встречается.
« Последнее редактирование: 26 Января 2013, 13:21:09 от Phlya »
Ubuntu 14.04 (Unity), MSI GE40

Оффлайн Señor_Gaga

  • Забанен
  • Активист
  • *
  • Сообщений: 878
  • Ubuntu 12.04LTS & Linux Mint 13LTS "Maya"
    • Просмотр профиля
Пробовал запустить ваш код, но
Traceback (most recent call last):
  File "flya.py", line 50, in <module>
    chisq = chisquare(numbers)
NameError: name 'chisquare' is not defined


Оффлайн Phlya

  • Автор темы
  • Старожил
  • *
  • Сообщений: 2219
  • Фля, Цыганский барон, Винни Пух
    • Просмотр профиля
А, сорри, не скопировал
from scipy.stats import chisquareНо, в принципе, можете просто удалить эту строчку, она проверяет достоверность равномерного распределения всех частот.
http://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test - если интересно
« Последнее редактирование: 26 Января 2013, 13:24:27 от Phlya »
Ubuntu 14.04 (Unity), MSI GE40

Оффлайн Señor_Gaga

  • Забанен
  • Активист
  • *
  • Сообщений: 878
  • Ubuntu 12.04LTS & Linux Mint 13LTS "Maya"
    • Просмотр профиля
Ради интереса набросал небольшую программку. Получил такие результаты:
(Нажмите, чтобы показать/скрыть)
Отклонение в десятых процента.
Если size увеличить в 100 раз, то отклонение будет в сотых процента.
# -*- coding: utf-8 -*-
#!usr/bin/env python

from random import randrange

'''
Цифровые кодировки двухбуквенных сочетаний
AA  0
AT  1
AG  2
AC  3
   
TT  4
TA  5
TG  6
TC  7
 
GG  8
GA  9
GT  10
GC  11

CC  12
CA  13
CT  14
CG  15
'''

size = 160000

result =  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,] # здесь будет частота втречаемости

let2 = ('AA','AT','AG','AC','TT','TA','TG','TC','GG','GA','GT','GC','CC','CA','CT','CG')

def count(): # подсчитывает количество вариантов двухбуквенных сочетаний
    for i in range(size):
        n = randrange(16) # генеруем случайное число от 0 до 15
        result[n] = result[n] + 1 # корректируем result

def putLet2(): # выводит частоту втречаемости двухбуквенных сочетаний в %
    for i in range(16):
        n = result[i]
        x = n*100.0/size
        s = let2[i] + ' = '
        print s, x, " %"

def main():
    count()
    print 'result =  ', result
    putLet2()
   
main()


Оффлайн Phlya

  • Автор темы
  • Старожил
  • *
  • Сообщений: 2219
  • Фля, Цыганский барон, Винни Пух
    • Просмотр профиля
Я что-то туплю, никак не могу понять, чего Ваша программа делает...
Надо позапускать что ли попробовать...
Ubuntu 14.04 (Unity), MSI GE40

 

Страница сгенерирована за 0.031 секунд. Запросов: 24.