1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
* (Вопрос) Как мне построить все возможные уравнения регрессии в SPSS
	(со всевозможными комбинациями предикторов)?
	Тогда как пошаговая (stepwise) регрессия строит одно
	(в некотором смысле - "лучшее", но не обязательно "лучшее") уравнение, моя задача - построить
	регрессии со всевозможными комбинациями предикторов и предоставить пользователю
	возможность выбрать "лучшее" из полного перебора вариантов. 
	Так, если у нас есть зависимая переменная и 5 независимых,
	надо построить сначала 5 простых регрессий - поочерёдно с каждым предиктором,
	затем - все комбинации по 2, и так далее, а в конце - одно уравнение со всеми
	предикторами.
	Пользователю можно выдавать разные статистики по моделям, 
	например, R^2, но я бы для моей задачи предпочёл сохранять
	стандартизированные прогнозные значения.
	
* (Ответ) Автор: rlevesque@videotron.ca, 30.08.2001;
	Сайт, посвящённый SPSS: http://www.spsstools.net.

* Примеч.: Это достаточно сложный синтксис, но достаточно лёгкий в использовании.
	См. примеры в конце файла. Синтаксис определяет 3 макроса. Первый из них (combine)
	записывает новый файл синтаксиса, который, выполняясь, создаёт текстовый файл.
	Этот текстовый файл затем читается в редактор данных и используется для создания
	окончательного синтаксиса, состоящего из серии вызовов макроса. Каждый из вызовов
	макроса создаёт строит одно регрессионное уравнение.


SET MPRINT=no.

*/////////////////////////////.
DEFINE !combine (n=!TOKENS(1) 
	/m=!TOKENS(1)
	/dep=!TOKENS(1) 
	/indepv=!CMDEND).

/* Поиск всех комбинаций по n объектов из m объектов*/
/* 30 августа 2001. Автор: rlevesque@videotron.ca */

!DO !thisn=1 !TO !n
NEW FILE.
INPUT PROGRAM.
LOOP i=1 TO !thisn.
END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
LIST.

!LET !list=!NULL
!DO !cnt=1 !TO !thisn
	!LET !list=!CONCAT(!list," ","j",!cnt)
!DOEND

COMPUTE n=!thisn.

* Формируем имена переменных для цикла LOOP в следующей команде WRITE *.
STRING cntname cntbeg(A8).

COMPUTE cntname=CONCAT('j',LTRIM(STRING(i,F8.0))).

* Вычисляем первый параметр для цикла LOOP в следующей команде WRITE *.
DO IF i=1.
COMPUTE cntbeg="1".
ELSE.
COMPUTE cntbeg=CONCAT('j',LTRIM(STRING(i-1,F8.0))," + 1").
END IF.

* Вычисляем второй параметр для цикла LOOP в следующей команде WRITE *.
COMPUTE k=!m - !thisn + i.
FORMATS i k n(F8.0).

STRING quote(A1) strlist(A255).
COMPUTE quote='"'.
COMPUTE strlist=!QUOTE(!list).

* Пишем синтаксис, который поместит все возможные комбинации в файлы list.txt *.
WRITE OUTFILE "c:\\temp\\macro.sps" 
	/"LOOP "cntname"="cntbeg" TO "k".".
DO IF i=!thisn.
+	WRITE OUTFILE "c:\\temp\\macro.sps" 
	/"WRITE OUTFILE "quote"c:\\temp\\list.txt"quote "/" strlist "." .
+	LOOP cnt=1 TO !thisn.
+		WRITE OUTFILE "c:\\temp\\macro.sps" /"END LOOP.".
+	END LOOP.
+	WRITE OUTFILE "c:\\temp\\macro.sps" /"EXECUTE.". 
END IF.
EXECUTE.
INCLUDE FILE="c:\\temp\\macro.sps".

/* Конвертируем данные из файлов list.txt в соответствующие sav-файлы */.
DATA LIST FILE='c:\\temp\\list.txt' LIST /!list.
SAVE OUTFILE=!QUOTE(!CONCAT('c:\\temp\\list',!thisn,'.sav')).
!DOEND

/* Объединяем все sav-файлы */.
GET FILE='c:\\temp\\list1.sav'.
!DO !nb=2 !TO !n.
ADD FILES FILE=* 
	/FILE=!QUOTE(!CONCAT('c:\\temp\\list',!nb,'.sav.')).
!DOEND

/* Убираем дубликаты  */.
SORT CASES BY ALL.
MATCH FILES FILE=* /BY=ALL /FIRST=first.
SELECT IF first.
SAVE OUTFILE='c:\\temp\\all combinations.sav'.

/* Получем имя последней переменной */
!DO !var !IN (!indepv)
!LET !lastone=!var
!DOEND

VECTOR vnames(!m A8).
!LET !cnt=!BLANK(1)

/* Создаём переменные с именами независимых (indepv) переменных */
!DO !var !IN (!indepv)
COMPUTE vnames(!LEN(!cnt))=!QUOTE(!var).
!LET !cnt=!CONCAT(!cnt,!BLANK(1))
!DOEND

/* Создаём строку, содержащую список назависимых переменных в каждом из уравнений */.
STRING dep (A8) indepv(A255).
COMPUTE dep=!QUOTE(!dep).
VECTOR j=j1 TO !CONCAT('j',!n) /ind=vnames1 TO  !CONCAT('vnames',!m).
COMPUTE nvar=NVALID(j1 TO !CONCAT('j',!n)).
LOOP cnt=1 TO nvar.
COMPUTE indepv=CONCAT(RTRIM(indepv)," ",vnames(j(cnt))).
END LOOP.

* Пишем синтаксис, который будет запускать все регрессии */.
WRITE OUTFILE='c:\\temp\\syntax to do all regressions.sps'
	/"!regres dep=" dep "indepv=" indepv ".".
EXECUTE.

!ENDDEFINE.
*////////////////////////////.


*////////////////////////////.
DEFINE !regres (dep=!TOKENS(1) /indepv=!CMDEND)
REGRESSION
  /MISSING LISTWISE
  /STATISTICS COEFF OUTS R ANOVA
  /CRITERIA=PIN(.05) POUT(.10)
  /NOORIGIN
  /DEPENDENT !dep
  /METHOD=ENTER !indepv
  /SAVE ZPRED .
!ENDDEFINE.
*////////////////////////////.


*************************.
* ПРИМЕР ИСПОЛЬЗОВАНИЯ.
*************************.
* Все изменения в выдаче, которые вам необходимы, внесите в макрос вызова
  команды REGRESSION выше.

SET MPRINT=yes.
****** Выполним следующий макрос для того, чтобы подготовить все сочетания.
!combine n=5 m=5 dep=salary indepv=educ jobcat jobtime prevexp minority.

****** Откроем файл данных и построим все уравнения регрессии.
GET FILE='c:\\Program Files\\SPSS\\Employee data.sav'.
INCLUDE FILE='c:\\temp\\syntax to do all regressions.sps'.