Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет deadbeef ([info]deadbeef)
@ 2004-11-21 07:10:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Вот, сотворил. Может полезно будет.
Сотворил простейшую и кратчайшую программку, которая может помочь людям русским, в одном мутном деле.
Иногда, возникает подозрение, что под разными именами в инете пишет один и тот же человек. Это подозрение бывает достаточно сложно проверить, однако и на такую хитрую задницу с лабиринтом, найдётся русский лом.


Нижеприведённая программка делает очень простую вещь - считает, сколько в тексте есть разных буквосочетаний. Из соображений скорости и простоты она учитывает только 512 наиболее распространённых в русском языке буквосочетаний. На выходе получаем простой список из 512 относительных величин в экспоненциальном формате - количество буквосочетаний одного типа отнесённое к общему количеству буквосочетаний. Теперь остаётся только загнать этот список в какую-нибудь программку для построения графиков, чтобы она нарисовала нам спектр текста (я пользую gnuplot).
А главное, и самое интересное, что этот самый спектр текста будет почти одинаков для разных текстов одного автора и будет отличаться для текстов разных авторов. Нарисовав в одном графике спектры для двух текстов, мы без особого труда можем определить, принадлежат ли тексты разным людям, или они были написаны одним человеком (ну или нелюдем). Тексты, правда, должны быть достаточно длинными, чтобы дать спектр действительно характерный для изучаемого автора - книга, например, или собранные в один файл сотни комментариев.

Вот, например, участок спектра с 100-го по 200-е буквосочетания для двух разных кусков Лукьяненки:
Image

А вот, тот же участок для Лукьяненки и Неведимова (Лукьяненка - красный):
Image

Посмотрев на картинки, разобраться, что на первой картинке - автор один, а на второй - авторы разные, не так уж и сложно.


#include <locale.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <getopt.h>

#define SLOG_COUNT  (512)

char *slog[SLOG_COUNT] = {
"ст","то","ен","но","ни","ов","на","ра","ос","пр","ро","ко","ан","ли","по","во",
"ес","ре","не","от","ол","од","ор","ть","ва","го","ер","ит","ет","ти","об","ел",
"он","та","ри","ль","ны","те","ал","ат","де","ка","ом","ис","тв","ве","ин","ие",
"ло","ми","со","ав","ог","ме","ем","ия","им","ле","ас","из","ив","ла","ак","че",
"мо","да","ии","ед","за","тр","ой","ск","ар","нн","до","ки","ам","оп","ил","ик",
"ви","бо","ма","тс","ьн","ся","ев","аз","оз","ек","ир","же","ои","бы","си","ег",
"ич","ци","вс","еп","ап","зн","ди","ад","ид","ип","сл","вы","вн","ру","ля","ые",
"ей","ое","ок","се","их","оч","вл","ож","ят","хо","эт","пе","тн","ых","ры","уд",
"чт","ио","ще","ку","аб","дн","сп","ьс","ео","ая","чи","ий","му","св","ги","ду",
"ае","йс","це","нт","ча","ше","оо","лю","сс","ют","вр","яв","жн","уп","ез","ус",
"зв","ым","ыл","мы","кр","ян","ну","ее","па","иа","еб","ую","аи","нс","са","ьк",
"га","иг","ыв","еи","еч","кт","жи","аж","ты","ый","уч","ут","ту","иб","яс","мн",
"ач","су","чн","яп","ыс","зм","бе","дл","зо","ац","сь","пи","мп","лу","дс","ах",
"ын","бр","ям","ня","ур","щи","гр","яз","ун","бщ","жд","еж","аю","ши","уж","ыт",
"нк","нь","бу","зд","тк","вп","ьв","яи","гл","йн","сн","вт","би","мс","ды","ук",
"ып","др","ул","зи","рн","вк","кл","ао","хр","ех","кс","юд","ию","аг","тп","уг",
"пл","ву","ьп","ув","бл","см","йв","йп","яо","ьт","як","мв","ьш","ьи","хи","ёт",
"иц","фи","ря","яд","ср","ум","ба","йи","рс","вв","вя","рт","хс","рм","яе","оц",
"жа","ью","оя","йт","иу","гд","ке","нц","ыи","нд","ош","йк","ущ","дв","ау","мм",
"оу","ющ","ша","рп","хп","ьм","лл","эк","зы","бс","иж","рк","уб","мк","вм","тд",
"кн","хв","ык","еа","ьо","рв","ай","уе","еш","ьз","ох","зк","кв","вд","ён","хн",
"яр","аш","ыо","фо","йм","сч","еу","лн","зу","ец","ащ","пу","ца","рг","ьд","оэ",
"зр","йо","тт","мч","йд","ял","лж","иф","ьг","ыр","кп","ыд","гу","чё","йр","иэ",
"вг","мя","юб","хк","яч","ьб","тя","ыш","чк","зе","уи","кц","ыч","ыб","ещ","лы",
"яб","оф","мб","ях","сё","юс","бн","тм","ём","вз","сы","ха","пы","уа","лс","шл",
"рь","сх","рж","рд","нг","хт","рх","сд","ух","мд","ьч","яю","ье","уш","уз","ща",
"ге","еф","аэ","фр","бъ","дя","тч","тб","мт","км","уо","мл","ьр","йб","вш","юп",
"фе","йч","тл","яу","нв","мр","юв","еэ","дё","яц","ыз","сш","дп","аа","ья","зя",
"юч","иш","дь","ху","яэ","бм","гн","кд","шн","вб","хд","йз","ящ","ъе","фа","хл",
"ёр","её","хм","дк","аф","ою","лк","лг","цы","юи","йг","вэ","бх","хг","ьл","ощ",
"зл","яг","йц","щё","оа","тз","ея","юз","аё","бя","ыу","кк","вц","нп","юо","лё",
"чу","нф","чш","йш","ьу","йэ","йа","юр","юн","юк","мг","юц","шк","пн","ыг","мз",
};

int spectrum[SLOG_COUNT];

void usage(char *name)
{
	printf("Usage: %s [--verbose] [--help] [file]\n", name);
}
   
int main(int argc, char *argv[]) {
 char                   c1 = 0, c2 = 0, buf[256], *src, *prog;
 int                    ret, i, verbose = 0, count = 0;
 FILE			*fd;
 static struct option   long_options[] =
 {
   {"verbose", no_argument,       0, 'v'},
   {"help",    no_argument,       0, 'h'},
   {0, 0, 0, 0}
 };

	setlocale(LC_ALL, "" );

	prog = strrchr(argv[0],'/');
	if(!prog) prog = argv[0];
	else      prog++;

	while ((ret = getopt_long (argc, argv, "vh", long_options, NULL)) != -1)
	{
		switch(ret)
		{
			case 'v': verbose = 1; break;
			case 'h': usage(prog); break;
			default: usage(prog); return 1;
		}
	}

	if(verbose) printf("Cleaning spectrum...\n");

	for(i = 0; i < SLOG_COUNT; i++) spectrum[i] = 0;

	if(argc > optind)
	{
		if(verbose) printf("Reading file %s\n",argv[optind]);
		fd = fopen(argv[optind],"r");
	}
	else
	{
		if(verbose) printf("Reading stdin\n");
		fd = stdin;
	}

	while(fgets(buf,sizeof(buf),fd))
	{
		src = buf;
		while(*src)
		{
			c2 = tolower(*src);
			if(c1 && isalpha(c2))
			{
				for(i = 0; i < SLOG_COUNT; i++)
				{
					if(slog[i][0] == c1 && slog[i][1] == c2)
					{
	        				spectrum[i]++;
	        				count++;
						break;
					}
				}
			}
			c1 = c2;
			src++;
		}
	}

	if(count > 0) 
	{
		for(i = 0; i < SLOG_COUNT; i++)
		{
			printf("%e # %s\n", (double)spectrum[i] / (double)count, slog[i]);
		}
	}

	if(fd != stdin) fclose(fd);

	return 0;
}


Вот собственно и всё.

Программка читает либо стандартный ввод, либо файл, если он указан в качестве аргумента. Выдаёт результат на терминал, ну или куда там перенаправишь - в файл, например. А можно сразу скормить рисовалке графиков.

Клоны могут отдыхать.
Лицензия - GNU, автор - я.



(Читать комментарии) - (Добавить комментарий)


[info]vchk@lj
2004-11-21 19:41 (ссылка)
1. Ну и выкладывайте. Ваши картинки - что угодно с ними делайте.
2. Сопоставление какое есть. Считаете его неуместным - считайте, не вопрос.
3. Пост у меня с предложением совершенно конкретного, практического и простого решения проблемы определения авторства текстов. С описанием принципа, наглядными примерами и текстом программы. Всё.
Мнения неких "специалистов в области анализа текстов", которые не способны собрать простейшую программку, меня не интересуют вообще, в связи с их заведомой некомпетентностью.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]trankov@lj
2004-11-21 19:46 (ссылка)
Хе-хе. Принцип-то Ваш гавённенький, много раз залажанный и не нов совсем, компетентный Вы наш. Спецыалист, хе-хе.

Программку Вашу я кстати прекрасно прочитал, не Бог весть что. Уровень начала XX века Ваш метод. Заявите его на Нобелевскую премию.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]vchk@lj
2004-11-21 19:55 (ссылка)
Ну конечно же гавённенький. Даже до древнючих цепей Маркова не дотягивает - ещё более тупой и простой.

Только вот он принцип, вот пример, и вот программка. Всё доступно и работает. Бери и пользуй.

А где другие, не гавённенькие, более новые принципы реализованные в программах, которые можно взять вот прямо и использовать? А может Вы чем-то похвастаетесь, критик любезный? Программку продемонстрируете, может, сравним, у кого лучше работат и надёжнее?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]trankov@lj
2004-11-21 19:58 (ссылка)
(как бы к слову) Сюжет очень волнующий...

(Ответить) (Уровень выше)


(Читать комментарии) -